diff --git a/.npmrc b/.npmrc index 38f11c6..7549542 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1 @@ -registry=https://registry.npmjs.org +registry=https://registry.npmmirror.com diff --git a/README.md b/README.md new file mode 100644 index 0000000..ca9c259 --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +This is a [Plasmo extension](https://docs.plasmo.com/) project bootstrapped with [`plasmo init`](https://www.npmjs.com/package/plasmo). + +## Getting Started + +First, run the development server: + +```bash +pnpm dev +# or +npm run dev +``` + +Open your browser and load the appropriate development build. For example, if you are developing for the chrome browser, using manifest v3, use: `build/chrome-mv3-dev`. + +You can start editing the popup by modifying `popup.tsx`. It should auto-update as you make changes. To add an options page, simply add a `options.tsx` file to the root of the project, with a react component default exported. Likewise to add a content page, add a `content.ts` file to the root of the project, importing some module and do some logic, then reload the extension on your browser. + +For further guidance, [visit our Documentation](https://docs.plasmo.com/) + +## Making production build + +Run the following: + +```bash +pnpm build +# or +npm run build +``` + +This should create a production bundle for your extension, ready to be zipped and published to the stores. + +## Submit to the webstores + +The easiest way to deploy your Plasmo extension is to use the built-in [bpp](https://bpp.browser.market) GitHub action. Prior to using this action however, make sure to build your extension and upload the first version to the store to establish the basic credentials. Then, simply follow [this setup instruction](https://docs.plasmo.com/framework/workflows/submit) and you should be on your way for automated submission! diff --git a/index.html b/index.html deleted file mode 100644 index b2ab7b1..0000000 --- a/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - WhatsElement 调试开发基础页面 - - -
- - - diff --git a/lib/compute/computeId.ts b/lib/compute/computeId.ts deleted file mode 100644 index d3d2e3a..0000000 --- a/lib/compute/computeId.ts +++ /dev/null @@ -1,256 +0,0 @@ -import {QueryTypes, SPLIT_MODE_CODE} from "../const"; -import getTarget from "../target"; -import {findFirstLevelChildren} from "../utils/helper"; - -export interface WhatsUniqueResult { - wid: string | null; - type: QueryTypes | null; -} - -export interface ClassFilter { - blockClassList?: (string | RegExp)[], - maxLength?: number -} - -// 一些非法的class名,不可作为定位符 -const BASIC_BLOCK_CLASS_RULES = [/[:\[\]\.]/,/\//,/^\d+/] -export function getElementClass(element: HTMLElement, classFilter?:ClassFilter) { - let className = ""; - for(let i=0; i= classFilter.maxLength){ - continue - } - let blocked = false; - const blockList = [...BASIC_BLOCK_CLASS_RULES,...(classFilter?.blockClassList||[])] - - for(let j=0; j0){ - let index = 0; - for(let i=0; i locate by id > by name > by class > type > link > index > parent - * TODO 识别动态生成的ID,规则 长度过长? 含有数字、特殊字符等 - * TODO 增加一种定位方式,按inner文本内容 md5 处理后生成ID - * **/ - const result = getByRoot(element) - || getById(element) - || getByName(element) - || getByClass(element,classFilter) - || getByType(element) - || getByAttr(element) - // TODO 非父节点控制下,不适用于基于索引的定位;取消 - || getByIndex(element,classFilter); - if(result){ - return result; - } - - - /** - * 无法通过自身定位,需要进一步通过父节点定位 location by parent - * */ - const parentNode = element.parentElement; - if(parentNode){ - // 递归定位上一级节点的ID - const parentQueryResult = getUniqueId(parentNode,classFilter); - const parentQueryString = parentQueryResult.wid; - const result = getByParent(element,parentQueryString,classFilter); - if(result){ - return result; - } - } - - // 无法定位的情况,增加 - console.error(element,'无法被唯一定位') - return { - wid: null, - type: null - } -} diff --git a/lib/index.ts b/lib/index.ts deleted file mode 100644 index 5ccf012..0000000 --- a/lib/index.ts +++ /dev/null @@ -1,77 +0,0 @@ -import getTarget, {TargetElement} from "./target"; -import {getUniqueId} from "./compute"; -import {QueryTypes, SPLIT_MODE_CODE} from "./const"; -import {ClassFilter, WhatsUniqueResult} from "./compute/computeId"; - -interface Option { - ignoreClassRule?: ClassFilter - minDeep: number // 生成ID的,最小层级深度,如 #app 为1级, body #app 为2级; #app 变化时,还可以通过上级节点,进一步查找定位 -} - -export default class WhatsElement { - private readonly option: Option; - constructor(option: Option) { - this.option = option - } - - getTarget(queryString: string, type?: QueryTypes, root?: HTMLElement | Document): TargetElement{ - return getTarget(queryString,type,root) - } - - getUniqueId(element: HTMLElement,minDeep=this.option.minDeep): WhatsUniqueResult{ - try{ - const result = getUniqueId(element,this.option.ignoreClassRule); - /**无法定位*/ - if(!result.wid){ - return result - } - const selectorArray = (result.wid || '').split(SPLIT_MODE_CODE); - if(minDeep > selectorArray.length){ - const needDeep = minDeep - selectorArray.length; - // 层级不够的情况下,对一级节点的父节点再定位 - const rootElement = getTarget(selectorArray[0]); - if(rootElement?.target?.parentElement){ - const parentResult = this.getUniqueId(rootElement?.target?.parentElement,needDeep); - const selectorWithParent = ((parentResult.wid || '') + SPLIT_MODE_CODE + result.wid).trim(); - const check = getTarget(selectorWithParent); - if(check.target === element){ - return { - wid: selectorWithParent, - type: QueryTypes.bySplit, - }; - }else{ - // console.warn(check.target,'拼接后,不匹配原始节点',selectorWithParent) - } - } - } - return result; - }catch (e) { - console.error(e,'计算元素信息异常',element) - return { - wid: null, - type: null, - } - } - } - - /**根据wid,查询DOM链*/ - getTargetLine(queryString: string): HTMLElement[]{ - if(!queryString){ - return [] - } - const queryStringArray = queryString.trim().split(/\s+/); - const result: HTMLElement[] = []; - for(let i=0; i1){ - type = QueryTypes.bySplit; - } - } - - let target: HTMLElement | null = null; - let nearest = findRoot - switch (type){ - case QueryTypes.byId: - target = "getElementById" in findRoot ? target = findRoot.getElementById(queryString) : null - break; - case QueryTypes.byName: - target = "getElementsByName" in findRoot ? findRoot.getElementsByName(queryString)[0] : null; - break; - case QueryTypes.bySelector: - try{ - target = findRoot.querySelector ? findRoot.querySelector(queryString) : null; - }catch (e) { - console.warn(e,queryString) - } - break; - /**whats-element 扩展的查找方法**/ - case QueryTypes.bySplit: - const selectors = splitedSelector.filter((item)=>{ - return item ? !!item.trim() : false; - }) - const firstSelector = selectors[0];// 寻找第一级 - - /** - * 1. 在指定根节点的情况下,仅查找直接子节点; - * 2. 未指定根节点的情况下,子、孙节点第一个即为对象。 - * */ - if(root){ - const matchedElements = findFirstLevelChildren(findRoot,firstSelector); - target = matchedElements[0] || null; - if(matchedElements.length !== 1){ - // TODO ? 给一定的提示 - // console.warn(firstSelector,'非唯一子节点,取第0个,可能异常',matchedElements) - } - }else{ - target = getTarget(firstSelector,QueryTypes.bySelector,findRoot).target - } - // 继续查找下一层级节点 - if(target && selectors.length > 1){ - selectors.splice(0,1); - const nextString = (selectors.join(SPLIT_MODE_CODE)).trim(); - const nextResult = getTarget(nextString,QueryTypes.bySplit,target); - target = nextResult.target; - nearest = nextResult.nearest; - } - break; - default: - /**未指定type的情况下,按优先级查找*/ - const result = getTarget(queryString, QueryTypes.byId,findRoot).target - || getTarget(queryString, QueryTypes.byName,findRoot).target - || getTarget(queryString,QueryTypes.bySelector,findRoot).target; - - if(result){ - return { - target: result, - nearest: nearest, - error: '' - } - }else{ - return getTarget(queryString, QueryTypes.byId, findRoot) - } - } - - // TODO 正向查找不到的情况下,进行反向查找,避免因为父节点的DOM 变动导致子节点无法被定位,存在多个节点的时候,按照深度优先返回最终结果。 - return { - nearest: nearest, - target: target, - error: '' - }; -} diff --git a/package.json b/package.json index eaafef8..2e6f869 100644 --- a/package.json +++ b/package.json @@ -1,25 +1,12 @@ { "name": "whats-element", - "version": "3.0.0-rc.b", - "type": "module", - "files": [ - "dist" - ], - "main": "./dist/index.umd.cjs", - "module": "./dist/index.js", - "types": "./index.d.ts", - "exports": { - "types": "./index.d.ts", - "import": "./dist/index.js", - "require": "./dist/index.umd.cjs" - }, - "scripts": { - "dev": "vite", - "build": "vite build && tsc -p ./tsconfig.json -emitDeclarationOnly", - "publish-npm": "npm run build && npm publish --access public" - }, - "devDependencies": { - "typescript": "^4.8.3", - "vite": "^3.1.3" - } + "version": "1.0.0", + "main": "index.js", + "repository": "git@github.com:rowthan/whats-element.git", + "author": "rowthan <12638456+rowthan@users.noreply.github.com>", + "license": "MIT", + "private": true, + "workspaces": [ + "packages/*" + ] } diff --git a/packages/skeleton/skeleton.ts b/packages/skeleton/skeleton.ts new file mode 100644 index 0000000..62dc888 --- /dev/null +++ b/packages/skeleton/skeleton.ts @@ -0,0 +1,168 @@ + + +type Position = 'relative' | 'absolute' | 'fixed' | null + +type Size = { + minWidth: number + maxWidth: number + minHeight: number + maxHeight: number + minInterText?: number // 内部的文本内容超过限制 + minOuterText?: number + typeName: string +} +type Options = { + sizes:Size[], + // minText?: number, + position: Position + ignoreSelector: string, // 忽略的节点匹配 +} + +type Container = { + height: number, + width: number, +} +type MatchedRule = Size & Container + +interface MatchedNode { + node: HTMLElement, + pNode: MatchedNode, + rangeRate: number, + childTotalRate: number, + deep: number, + innerText: string, + styles: Record, + matchedRule: MatchedRule, + child_list: MatchedNode[], +} + +function checkMatched(element:HTMLElement,filter:Options): MatchedRule | null { + // const {minText} = filter; + // if(minText){ + const whiteTags = ['IMG','VIDEO','BODY'] + if(!whiteTags.includes(element.tagName) && element?.innerText?.length<1){ + return null; + } + // } + + const {height,width} = element.getBoundingClientRect(); + const matched = filter.sizes.find(function (size) { + const {minWidth,minHeight,maxHeight,maxWidth,minInterText,minOuterText} = size; + let match = height > minHeight && height < maxHeight && width > minWidth && width < maxWidth; + if(minInterText){ + match = match && getElementText(element).length > minInterText + } + if(minOuterText){ + match = match && element.outerText.length > minOuterText + } + return match; + }) + + if(matched){ + return { + ...matched, + height: height, + width: width + } + } + return null +} + +function diffSize(preNode:HTMLElement,nextNode:HTMLElement){ + if(!preNode || !nextNode){ + return 1 + } + const preWidth = preNode.offsetWidth; + const preHeight = preNode.offsetHeight; + const nextWidth = nextNode.offsetWidth; + const nextHeight = nextNode.offsetHeight; + + + const diffArea = preWidth*preHeight - nextWidth * nextHeight + const parentArea = (Math.max(preWidth,nextWidth) * Math.max(preHeight,nextHeight)) + + return Math.abs(diffArea / parentArea); +} + +function getElementText(root: HTMLElement) { + let str = '' + for(let i=0; iroot.children[i]; + + // const childMatch: Options = { + // ignoreSelector: "", + // maxHeight: Math.min(matched.height,options.maxHeight), + // maxWidth: Math.min(matched.width,options.maxWidth), + // minHeight:options.minHeight, + // minWidth: options.minWidth, + // position: null, + // } + // console.log(childMatch,'child',options) + const tempCheck = skeletonElement(child,options,nextDeep); + if(tempCheck){ + tempCheck.pNode = result + result.child_list.push(tempCheck) + } + } + + // 如果子节点只被切割为1个,则无需再切割 + if(result.child_list.length===1){ + const parent = result.node; + const child = result.child_list[0].node; + const diffRate = diffSize(parent,child) + if(diffRate<0.1){ + return result.child_list[0] + } + } + result.rangeRate = 1 - diffSize(result.node,result.node.parentElement) + let childrenRate = 0; + result.child_list.forEach(function (item) { + childrenRate += item.rangeRate; + }) + result.childTotalRate = childrenRate + return result +} + + +export type { + MatchedNode +} + +export default skeletonElement diff --git a/packages/whats-element/package.json b/packages/whats-element/package.json new file mode 100644 index 0000000..7340f25 --- /dev/null +++ b/packages/whats-element/package.json @@ -0,0 +1,25 @@ +{ + "name": "whats-element", + "version": "3.0.0-rc.b", + "type": "module", + "files": [ + "dist" + ], + "main": "./dist/index.umd.cjs", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "require": "./dist/index.umd.cjs" + }, + "scripts": { + "dev": "vite", + "build": "vite build && tsc -p ./tsconfig.json -emitDeclarationOnly", + "publish-npm": "npm run build && npm publish --access public" + }, + "devDependencies": { + "typescript": "^4.8.3", + "vite": "^3.1.3" + } +} diff --git a/packages/whats-element/src/WhatsElement.ts b/packages/whats-element/src/WhatsElement.ts new file mode 100644 index 0000000..81010e2 --- /dev/null +++ b/packages/whats-element/src/WhatsElement.ts @@ -0,0 +1,102 @@ +import getTarget from "./target"; +import {getUniqueId} from "./uniqueId"; +import {compute} from "./compute"; +import {QueryTypes, SPLIT_MODE_CODE} from "./const"; +import {getKeyStyles, makeRangesForElement} from "./dna/dna"; +import {getDefaultOption} from "./const/data"; +import type {ClassFilter, WhatsUniqueResult} from "./typing"; + +interface Option { + ignoreClassRule?: ClassFilter +} + +export default class WhatsElement { + private readonly option: Option; + constructor(option: Option = getDefaultOption()) { + this.option = option + } + + static getTarget(queryString: string, type?: QueryTypes, root?: HTMLElement | Document){ + return getTarget(queryString,type,root) + } + + getTarget(queryString: string, type?: QueryTypes, root?: HTMLElement | Document){ + return getTarget(queryString,type,root) + } + + /** + * 指定一个元素,计算出可以定位到该元素的唯一特征描述 + * */ + getUniqueId(element: HTMLElement): WhatsUniqueResult{ + if(!element){ + return { + wid: null, + type: null, + } + } + /** + * 该元素的特征描述 + * */ + try{ + return getUniqueId(element,this.option.ignoreClassRule); + }catch (e) { + console.error(e,'计算元素信息异常',element) + return { + wid: null, + type: null, + } + } + } + + static getUniqueId(element: HTMLElement){ + return getUniqueId(element) + } + + compute(element: HTMLElement){ + if(!element){ + return {} + } + const uniqueId = this.getUniqueId(element); + return { + ...compute(element), + ...uniqueId, + } + } + + /** + * 根据wid,查询DOM链 + * 返回可追溯目的元素 过程中的 所有 DOM 节点。最大程度的找到 目的元素的最小范围。缩小目标范围。 + * */ + getElementsLines(queryString: string): HTMLElement[]{ + if(!queryString){ + return [] + } + const queryStringArray = queryString.trim().split(SPLIT_MODE_CODE); + const result = []; + for(let i=0; i0 && viewPosition.left < window.innerWidth && viewPosition.top>0 && viewPosition.top = {} + KEY_STYLES.forEach(function (key) { + //@ts-ignore + result[key] = styleMap[key] + }) + return result; +} + + +/** + * 从叶子节点开始,绘制 fragment 图谱 + * */ +export function getFragmentsFromLeafElement(leafElement: HTMLElement) { + const fragments: HTMLElement[] = []; + + const parent = leafElement.parentElement; + + if(!parent || !parent.parentElement){ + fragments.unshift(leafElement) + return fragments + } + + const canBeFragment = checkCanBeFragmentNode(parent); + + + if(canBeFragment){ + const {height: parentHeight, width: parentWidth} = parent.getBoundingClientRect(); + const parentArea = parentHeight * parentWidth; + + const {height,width} = parent.parentElement.getBoundingClientRect(); + const gradArea = height * width; + + // 有必要作为 fragment 节点 + const areaChanged = parentArea / gradArea < 0.8 + + /**面积突变可以作为独立的 fragment */ + if(areaChanged){ + fragments.unshift(parent) + } else{ + /**特殊样式,可以作为独立的 fragment */ + const style = getComputedStyle(parent); + if(style.display==='none' || style.position==='fixed' || style.position === 'absolute'){ + fragments.unshift(parent) + } + } + } + + /**继续向上寻找*/ + fragments.unshift(...getFragmentsFromLeafElement(parent)) + + + return fragments; +} + diff --git a/packages/whats-element/src/fragment/check.ts b/packages/whats-element/src/fragment/check.ts new file mode 100644 index 0000000..047f716 --- /dev/null +++ b/packages/whats-element/src/fragment/check.ts @@ -0,0 +1,23 @@ +import {getElementClass} from "../uniqueId/computeId"; +import {getValidIdForElement} from "../utils/element"; + +export function checkCanBeFragmentNode(element: HTMLElement) { + const whiteListTag = ['html','body','section','nav','footer','table'] + const tag = element.tagName.toLowerCase(); + if(whiteListTag.includes(tag)){ + return true; + } + + const parentElement = element.parentElement; + /**如果父节点只有一个子节点,则父节点更适合作为 fragment*/ + if(parentElement && parentElement.children && parentElement.children.length<=1){ + return false; + } + + /**元素缺乏标识 class or id,不适合作为 fragment */ + const classNameOrId = getElementClass(element) || getValidIdForElement(element); + if(!classNameOrId){ + return false; + } + return true; +} diff --git a/packages/whats-element/src/index.ts b/packages/whats-element/src/index.ts new file mode 100644 index 0000000..f248cd0 --- /dev/null +++ b/packages/whats-element/src/index.ts @@ -0,0 +1,6 @@ +import WhatsElement from "./WhatsElement"; + + +// @ts-ignore +window.WhatsElementV2 = WhatsElement +export default WhatsElement diff --git a/packages/whats-element/src/target/index.ts b/packages/whats-element/src/target/index.ts new file mode 100644 index 0000000..cb1950a --- /dev/null +++ b/packages/whats-element/src/target/index.ts @@ -0,0 +1,107 @@ +import {QueryTypes, SPLIT_MODE_CODE} from "../const"; + + +/** + * 基于 wid 查找 dom 节点 + * */ +export default function getTarget(queryString: string | undefined = '', type?: QueryTypes, root?: HTMLElement | Document | null): HTMLElement | null{ + const query = queryString ? queryString.trim() : ''; + // @ts-ignore + const findRoot: HTMLElement | Document = root || document || document.documentElement; + + if(!query){ + console.error('wid 不可为空',query) + return null; + } + if(!findRoot){ + console.trace('根节点不可为空',findRoot, queryString) + return null; + } + + // const regex = new RegExp(`${SPLIT_MODE_CODE}`); + const targetQueryArray = query.split(SPLIT_MODE_CODE); + if(!type){ + if(targetQueryArray.length>1){ + type = QueryTypes.bySelector; + } + } + + let target: HTMLElement | null = null; + switch (type){ + case QueryTypes.byId: + target = "getElementById" in findRoot ? target = findRoot.getElementById(queryString) : null + break; + case QueryTypes.byName: + target = "getElementsByName" in findRoot ? findRoot.getElementsByName(queryString)[0] : null; + break; + case QueryTypes.bySelector: + // 这里应该用 querySelectorAll 来判断是否具备唯一性 + try{ + // const matchedList = findRoot.querySelectorAll ? findRoot.querySelectorAll(queryString) : []; + // if(matchedList && matchedList.length === 1){ + // target = matchedList[0] as HTMLElement; + // } + target = findRoot.querySelector(queryString) as HTMLElement; + // if(matchedList.length>1){ + // console.warn('存在多个满足', matchedList) + // } + }catch (e) { + console.warn(e,queryString) + } + break; + /**whats-element 扩展的查找方法**/ + case QueryTypes.bySplit: + const selectors = targetQueryArray.filter((item)=>{ + return item ? !!item.trim() : false; + }) + let root: Document | HTMLElement = document; + /**逐级查找*/ + for(let i=0;i 1){ + // selectors.splice(0,1); + // const nextString = (selectors.join(SPLIT_MODE_CODE)).trim(); + // const nextResult = getTarget(nextString,QueryTypes.bySplit,target); + // target = nextResult.target; + // nearest = nextResult.nearest; + // } + break; + default: + /**未指定type的情况下,按优先级查找*/ + const result = getTarget(queryString, QueryTypes.byId,findRoot) + || getTarget(queryString, QueryTypes.byName,findRoot) + || getTarget(queryString,QueryTypes.bySelector,findRoot); + + if(result){ + return result + }else{ + return getTarget(queryString, QueryTypes.byId, findRoot) + } + } + + // TODO 正向查找不到的情况下,进行反向查找,避免因为父节点的DOM 变动导致子节点无法被定位,存在多个节点的时候,按照深度优先返回最终结果。 + return target +} diff --git a/packages/whats-element/src/typing/index.ts b/packages/whats-element/src/typing/index.ts new file mode 100644 index 0000000..67a4f4c --- /dev/null +++ b/packages/whats-element/src/typing/index.ts @@ -0,0 +1,31 @@ +import {QueryTypes} from "../const"; + +export type Range = { + offset: number, + text: string +} +export interface WhatsUniqueResult { + wid: string | null; + type: QueryTypes | null; +} + +export interface Fragment { + /**节点的抽帧记录片段 + * 当dom id class 变化,或结构微调后,自动化修复节点wid 的依据。 + * start: 文本开始节点 text 文案内容 + * 校验内容是否发生变更 + * 1. offset 对应的偏移量是否有内容变更 + * 2. 两个 offset 之间的差异 + * */ + ranges?: Range[] + + /** + * 样式描述 + * */ + style?: Record +} + +export interface ClassFilter { + blockClassList?: (string | RegExp)[], + maxLength?: number // class 精简控制 +} diff --git a/packages/whats-element/src/uniqueId/computeId.ts b/packages/whats-element/src/uniqueId/computeId.ts new file mode 100644 index 0000000..9953669 --- /dev/null +++ b/packages/whats-element/src/uniqueId/computeId.ts @@ -0,0 +1,332 @@ +import {PARENT_SPLIT_CODE, QueryTypes} from "../const"; +import getTarget from "../target"; +// import {findFirstLevelChildren} from "../utils/helper"; +import type {ClassFilter, WhatsUniqueResult} from "../typing"; +import {getValidIdForElement} from "../utils/element"; + +// 一些非法的class名,不可作为定位符 +const BASIC_BLOCK_CLASS_RULES = [ + /[:\[\]\.]/, + /\//, + /^\d+/, + /-px/, + /\d+rem/, + /**tailwind 语法,边界*/ + /m[tlrbxy]-\d+/, + /p[ltbrxy]-\d+/, + /**tailwind 语法,位置信息*/ + /top-\d+$/, + /left-\d+$/, + /right-\d+$/, + /bottom-\d+$/, + + /^[hw]-\d+$/, + + + /**tailwind 语法,zindex*/ + /z-\d+$/, + /inset-\d+$/, + 'active', +] +export function getElementClass(element: HTMLElement, classFilter:ClassFilter = {blockClassList:[],maxLength:10}) { + const blockList = [...BASIC_BLOCK_CLASS_RULES,...(classFilter?.blockClassList||[])] + + const classNames = []; + for(let i=0; i -1; + if(allowByTagName || isCustomTag){ + const query = tag ? `${tag}` : '' + if(query && getTarget(query,QueryTypes.byTagName, root) === element){ + return{ + wid: query, + type: QueryTypes.byName + } + } + } + + return null +} + +/** + * 基于 tag+class 定位 + * */ +export function getByClass(element: HTMLElement, classFilter: ClassFilter, root?: HTMLElement):WhatsUniqueResult|null { + const className = getElementClass(element,classFilter) + const tag = element.tagName.toLowerCase(); + const wid = tag+className + if(className && getTarget(wid,QueryTypes.bySelector, root)===element){ + return { + wid: wid, + type: QueryTypes.bySelector + } + } + return null; +} + +export function getByType(element: HTMLElement | HTMLInputElement, root?: HTMLElement):WhatsUniqueResult|null { + const type = "type" in element ? (element.type || '')?.toString()?.toLowerCase() : ""; + if(type === "radio"){ + const value = 'value' in element ? element.value : ''; + const tag = element.tagName.toLowerCase(); + const name = "name" in element ? element.name : ''; + let queryString = tag+"[value='"+value+"']" + if(name){ + queryString += "[name='"+name+"']" + } + if(getTarget(queryString,QueryTypes.bySelector,root)===element){ + return { + wid: queryString, + type: QueryTypes.bySelector + } + } + } + return null; +} + +export function getByAttr(element: HTMLElement | HTMLInputElement,root?: HTMLElement):WhatsUniqueResult|null { + const tag = element.tagName.toLowerCase(); + // if(tag === 'a'){ + // const href = element.getAttribute('href'); + // if(href){ + // const queryString = "a[href='"+href+"']"; + // if(getTarget(queryString,QueryTypes.bySelector,root).target===element){ + // return { + // wid: queryString, + // type: QueryTypes.bySelector, + // } + // } + // } + // } + + const types = ['href','src','tabIndex','role'] + for (let i = 0 ; i0){ + let index = 0; + for(let i=0; i locate by id > by name > by class > type > link > index > parent + * TODO 识别动态生成的ID,规则 长度过长? 含有数字、特殊字符等 + * TODO 增加一种定位方式,按inner文本内容 md5 处理后生成ID + * **/ + let result = getUniqueIdInScope(element,classFilter,rootElement) + + /** + * 无法在全局范围内得到唯一ID, + * 需要进一步通过祖/父节点定位。在祖/父节点的范围内得到唯一ID。 + * */ + if(!result){ + const parentUnique = getUniqueIdForPre(element,classFilter); + // todo 选择可以作为 fragment 的定位作为祖先节点 + if(parentUnique){ + /**递归定位上一级节点的ID*/ + const relativeResult = getUniqueIdInScope(element,classFilter,parentUnique.element) + || getByTagName(element,parentUnique.element) + const relativeWid = relativeResult ? relativeResult.wid : ''; + /**父元素能够在全局得到唯一ID时*/ + if(relativeWid){ + result = { + type: QueryTypes.bySplit, + wid: parentUnique.wid + SPLIT_MODE_CODE + relativeWid + } + } + } + } + + /**无法通过祖父节点缩小范围后,得到唯一ID,则必须依靠直系父亲节点通过索引得到*/ + if(!result){ + const parentNode = element.parentElement + const parentUniqueId = parentNode ? getUniqueId(parentNode,classFilter) : ''; + + if(parentUniqueId && parentUniqueId.wid){ + const parentRelatedQuery = getByIndex(element,classFilter,parentUniqueId.wid) + if(parentRelatedQuery && parentRelatedQuery.wid){ + result = { + wid: parentRelatedQuery.wid, + type: QueryTypes.byParent + } + } + } + } + + if(!result){ + console.error('cant unique id for element ', element) + return { + wid: null, + type: null + } + } + + const checkResult = result.wid ? getTarget(result.wid) : {target: null,type: null}; + + if(checkResult === element){ + return result + }else{ + console.warn('检测不通过', element,checkResult,result.wid) + } + + + // 无法定位的情况,增加 + console.error(element,'无法被唯一定位') + return { + wid: null, + type: null, + } +} diff --git a/packages/whats-element/src/utils/element.ts b/packages/whats-element/src/utils/element.ts new file mode 100644 index 0000000..843e10c --- /dev/null +++ b/packages/whats-element/src/utils/element.ts @@ -0,0 +1,19 @@ + + +export function getValidIdForElement(element: HTMLElement) { + const id = element.id; + if(!id){ + return null + } + // id 含有特殊字符 . : 等特殊字符串 不可用 + if(/[\.:!]/.test(id)){ + console.log('忽略含有特殊字符',id) + return null; + } + // 纯数字的 ID ,不可信,可能是系统基于 list 生成,变动性大,可能误判查找。 + if(/^\d+$/.test(id)){ + console.log('忽略纯数字',id) + return null; + } + return id; +} diff --git a/lib/utils/helper.ts b/packages/whats-element/src/utils/helper.ts similarity index 100% rename from lib/utils/helper.ts rename to packages/whats-element/src/utils/helper.ts diff --git a/tsconfig.json b/packages/whats-element/tsconfig.json similarity index 86% rename from tsconfig.json rename to packages/whats-element/tsconfig.json index 66cb1e9..bf72441 100644 --- a/tsconfig.json +++ b/packages/whats-element/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { - "target": "ESNext", + "target": "ES2015", "useDefineForClassFields": true, - "module": "ESNext", + "module": "ES2015", "lib": ["ESNext", "DOM"], "moduleResolution": "Node", "strict": true, @@ -17,5 +17,5 @@ "declaration": true, "outDir": "dist" }, - "include": ["lib"] + "include": ["src"] } diff --git a/packages/whats-element/vite.config.ts b/packages/whats-element/vite.config.ts new file mode 100644 index 0000000..965fafa --- /dev/null +++ b/packages/whats-element/vite.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from 'vite' + +export default defineConfig({ + build: { + lib: { + formats: ['es', 'esm', 'cjs', 'umd', 'iife'], + entry: './src/index.ts', + name: 'WhatsElementV2', + fileName: 'whatsElement' + } + } +}) diff --git a/packages/whats-ext/.gitignore b/packages/whats-ext/.gitignore new file mode 100644 index 0000000..a007fea --- /dev/null +++ b/packages/whats-ext/.gitignore @@ -0,0 +1 @@ +build/* diff --git a/packages/whats-ext/.plasmo/cache/parcel/79a4f14df031f08c b/packages/whats-ext/.plasmo/cache/parcel/79a4f14df031f08c new file mode 100644 index 0000000..ddc8177 Binary files /dev/null and b/packages/whats-ext/.plasmo/cache/parcel/79a4f14df031f08c differ diff --git a/packages/whats-ext/.plasmo/cache/parcel/8981d92e0a78a198 b/packages/whats-ext/.plasmo/cache/parcel/8981d92e0a78a198 new file mode 100644 index 0000000..9a6e8f0 Binary files /dev/null and b/packages/whats-ext/.plasmo/cache/parcel/8981d92e0a78a198 differ diff --git a/packages/whats-ext/.plasmo/cache/parcel/a2b62a5d248d2ad1 b/packages/whats-ext/.plasmo/cache/parcel/a2b62a5d248d2ad1 new file mode 100644 index 0000000..49ea26e Binary files /dev/null and b/packages/whats-ext/.plasmo/cache/parcel/a2b62a5d248d2ad1 differ diff --git a/packages/whats-ext/.plasmo/cache/parcel/cb5322925bb1421d b/packages/whats-ext/.plasmo/cache/parcel/cb5322925bb1421d new file mode 100644 index 0000000..c866a1a Binary files /dev/null and b/packages/whats-ext/.plasmo/cache/parcel/cb5322925bb1421d differ diff --git a/packages/whats-ext/.plasmo/cache/parcel/ce376dd764fd267e b/packages/whats-ext/.plasmo/cache/parcel/ce376dd764fd267e new file mode 100644 index 0000000..50af885 Binary files /dev/null and b/packages/whats-ext/.plasmo/cache/parcel/ce376dd764fd267e differ diff --git a/packages/whats-ext/.plasmo/cache/parcel/data.mdb b/packages/whats-ext/.plasmo/cache/parcel/data.mdb new file mode 100644 index 0000000..95cbaf3 Binary files /dev/null and b/packages/whats-ext/.plasmo/cache/parcel/data.mdb differ diff --git a/packages/whats-ext/.plasmo/cache/parcel/lock.mdb b/packages/whats-ext/.plasmo/cache/parcel/lock.mdb new file mode 100644 index 0000000..3839dc4 Binary files /dev/null and b/packages/whats-ext/.plasmo/cache/parcel/lock.mdb differ diff --git a/packages/whats-ext/.plasmo/cache/plasmo.version.json b/packages/whats-ext/.plasmo/cache/plasmo.version.json new file mode 100644 index 0000000..0ec32d4 --- /dev/null +++ b/packages/whats-ext/.plasmo/cache/plasmo.version.json @@ -0,0 +1 @@ +{"version":"0.84.0"} diff --git a/packages/whats-ext/.plasmo/chrome-mv3.plasmo.manifest.json b/packages/whats-ext/.plasmo/chrome-mv3.plasmo.manifest.json new file mode 100644 index 0000000..0afbced --- /dev/null +++ b/packages/whats-ext/.plasmo/chrome-mv3.plasmo.manifest.json @@ -0,0 +1,40 @@ +{ + "icons": { + "16": "./gen-assets/icon16.plasmo.png", + "32": "./gen-assets/icon32.plasmo.png", + "48": "./gen-assets/icon48.plasmo.png", + "64": "./gen-assets/icon64.plasmo.png", + "128": "./gen-assets/icon128.plasmo.png" + }, + "manifest_version": 3, + "action": { + "default_icon": { + "16": "./gen-assets/icon16.plasmo.png", + "32": "./gen-assets/icon32.plasmo.png", + "48": "./gen-assets/icon48.plasmo.png", + "64": "./gen-assets/icon64.plasmo.png", + "128": "./gen-assets/icon128.plasmo.png" + }, + "default_popup": "./popup.html" + }, + "version": "0.0.1", + "author": "rowthan", + "name": "DEV | Example dir", + "description": "pick-html", + "background": { + "service_worker": "./static/background/index.ts" + }, + "content_scripts": [ + { + "matches": [ + "" + ], + "js": [ + "../content.ts" + ] + } + ], + "host_permissions": [ + "https://*/*" + ] +} diff --git a/packages/whats-ext/.plasmo/devtools.html b/packages/whats-ext/.plasmo/devtools.html new file mode 100644 index 0000000..683cce2 --- /dev/null +++ b/packages/whats-ext/.plasmo/devtools.html @@ -0,0 +1,13 @@ + + + + Example dir + + + + + +
+ + + diff --git a/packages/whats-ext/.plasmo/gen-assets/icon128.plasmo.png b/packages/whats-ext/.plasmo/gen-assets/icon128.plasmo.png new file mode 100644 index 0000000..50af885 Binary files /dev/null and b/packages/whats-ext/.plasmo/gen-assets/icon128.plasmo.png differ diff --git a/packages/whats-ext/.plasmo/gen-assets/icon16.plasmo.png b/packages/whats-ext/.plasmo/gen-assets/icon16.plasmo.png new file mode 100644 index 0000000..49ea26e Binary files /dev/null and b/packages/whats-ext/.plasmo/gen-assets/icon16.plasmo.png differ diff --git a/packages/whats-ext/.plasmo/gen-assets/icon32.plasmo.png b/packages/whats-ext/.plasmo/gen-assets/icon32.plasmo.png new file mode 100644 index 0000000..c866a1a Binary files /dev/null and b/packages/whats-ext/.plasmo/gen-assets/icon32.plasmo.png differ diff --git a/packages/whats-ext/.plasmo/gen-assets/icon48.plasmo.png b/packages/whats-ext/.plasmo/gen-assets/icon48.plasmo.png new file mode 100644 index 0000000..ddc8177 Binary files /dev/null and b/packages/whats-ext/.plasmo/gen-assets/icon48.plasmo.png differ diff --git a/packages/whats-ext/.plasmo/gen-assets/icon64.plasmo.png b/packages/whats-ext/.plasmo/gen-assets/icon64.plasmo.png new file mode 100644 index 0000000..9a6e8f0 Binary files /dev/null and b/packages/whats-ext/.plasmo/gen-assets/icon64.plasmo.png differ diff --git a/packages/whats-ext/.plasmo/index.d.ts b/packages/whats-ext/.plasmo/index.d.ts new file mode 100644 index 0000000..fcfeaa5 --- /dev/null +++ b/packages/whats-ext/.plasmo/index.d.ts @@ -0,0 +1,2 @@ +import "./process.env" +import "./messaging" \ No newline at end of file diff --git a/packages/whats-ext/.plasmo/newtab.html b/packages/whats-ext/.plasmo/newtab.html new file mode 100644 index 0000000..3ebd152 --- /dev/null +++ b/packages/whats-ext/.plasmo/newtab.html @@ -0,0 +1,13 @@ + + + + Example dir + + + + + +
+ + + diff --git a/packages/whats-ext/.plasmo/options.html b/packages/whats-ext/.plasmo/options.html new file mode 100644 index 0000000..da285f5 --- /dev/null +++ b/packages/whats-ext/.plasmo/options.html @@ -0,0 +1,13 @@ + + + + Example dir + + + + + +
+ + + diff --git a/packages/whats-ext/.plasmo/popup.html b/packages/whats-ext/.plasmo/popup.html new file mode 100644 index 0000000..093f032 --- /dev/null +++ b/packages/whats-ext/.plasmo/popup.html @@ -0,0 +1,13 @@ + + + + Example dir + + + + + +
+ + + diff --git a/packages/whats-ext/.plasmo/sidepanel.html b/packages/whats-ext/.plasmo/sidepanel.html new file mode 100644 index 0000000..73e22b6 --- /dev/null +++ b/packages/whats-ext/.plasmo/sidepanel.html @@ -0,0 +1,13 @@ + + + + Example dir + + + + + +
+ + + diff --git a/packages/whats-ext/.plasmo/static/background/index.ts b/packages/whats-ext/.plasmo/static/background/index.ts new file mode 100644 index 0000000..9ee89df --- /dev/null +++ b/packages/whats-ext/.plasmo/static/background/index.ts @@ -0,0 +1 @@ +import "../../../background" \ No newline at end of file diff --git a/packages/whats-ext/.plasmo/static/common/csui-container-react.tsx b/packages/whats-ext/.plasmo/static/common/csui-container-react.tsx new file mode 100644 index 0000000..3d06afe --- /dev/null +++ b/packages/whats-ext/.plasmo/static/common/csui-container-react.tsx @@ -0,0 +1,72 @@ +import React from "react" + +import type { PlasmoCSUIContainerProps } from "~type" + +export const OverlayCSUIContainer = (props: PlasmoCSUIContainerProps) => { + const [top, setTop] = React.useState(0) + const [left, setLeft] = React.useState(0) + + React.useEffect(() => { + // Handle overlay repositioning + if (props.anchor.type !== "overlay") { + return + } + + const updatePosition = async () => { + const rect = props.anchor.element?.getBoundingClientRect() + if (!rect) { + return + } + + const pos = { + left: rect.left + window.scrollX, + top: rect.top + window.scrollY + } + + setLeft(pos.left) + setTop(pos.top) + } + + updatePosition() + + const unwatch = props.watchOverlayAnchor?.(updatePosition) + window.addEventListener("scroll", updatePosition) + window.addEventListener("resize", updatePosition) + + return () => { + if (typeof unwatch === "function") { + unwatch() + } + window.removeEventListener("scroll", updatePosition) + window.removeEventListener("resize", updatePosition) + } + }, [props.anchor.element]) + + return ( +
+ {props.children} +
+ ) +} + +export const InlineCSUIContainer = (props: PlasmoCSUIContainerProps) => ( +
+ {props.children} +
+) diff --git a/packages/whats-ext/.plasmo/static/common/csui-container-vanilla.tsx b/packages/whats-ext/.plasmo/static/common/csui-container-vanilla.tsx new file mode 100644 index 0000000..6f115ae --- /dev/null +++ b/packages/whats-ext/.plasmo/static/common/csui-container-vanilla.tsx @@ -0,0 +1,55 @@ +import type { PlasmoCSUIContainerProps } from "~type" + +export const createOverlayCSUIContainer = (props: PlasmoCSUIContainerProps) => { + const container = document.createElement("div") + container.className = "plasmo-csui-container" + container.id = props.id + + container.style.cssText = ` + display: flex; + position: relative; + top: 0px; + left: 0px; + ` + + if (props.anchor.type === "overlay") { + const updatePosition = async () => { + const rect = props.anchor.element.getBoundingClientRect() + + if (!rect) { + return + } + + const pos = { + left: rect.left + window.scrollX, + top: rect.top + window.scrollY + } + + container.style.top = `${pos.top}px` + container.style.left = `${pos.left}px` + } + + updatePosition() + + props.watchOverlayAnchor?.(updatePosition) + window.addEventListener("scroll", updatePosition) + window.addEventListener("resize", updatePosition) + } + + return container +} + +export const createInlineCSUIContainer = (props: PlasmoCSUIContainerProps) => { + const container = document.createElement("div") + container.className = "plasmo-csui-container" + container.id = "plasmo-inline" + + container.style.cssText = ` + display: flex; + position: relative; + top: 0px; + left: 0px; + ` + + return container +} diff --git a/packages/whats-ext/.plasmo/static/common/csui.ts b/packages/whats-ext/.plasmo/static/common/csui.ts new file mode 100644 index 0000000..118161b --- /dev/null +++ b/packages/whats-ext/.plasmo/static/common/csui.ts @@ -0,0 +1,304 @@ +import type { PlasmoCSUI, PlasmoCSUIAnchor, PlasmoCSUIMountState } from "~type" + +async function createShadowDOM(Mount: PlasmoCSUI) { + const shadowHost = document.createElement("plasmo-csui") + + const shadowRoot = + typeof Mount.createShadowRoot === "function" + ? await Mount.createShadowRoot(shadowHost) + : shadowHost.attachShadow({ mode: "open" }) + + const shadowContainer = document.createElement("div") + + shadowContainer.id = "plasmo-shadow-container" + shadowContainer.style.zIndex = "2147483647" + shadowContainer.style.position = "relative" + + shadowRoot.appendChild(shadowContainer) + + return { + shadowHost, + shadowRoot, + shadowContainer + } +} + +export type PlasmoCSUIShadowDOM = Awaited> + +async function injectAnchor( + Mount: PlasmoCSUI, + anchor: PlasmoCSUIAnchor, + { shadowHost, shadowRoot }: PlasmoCSUIShadowDOM, + mountState?: PlasmoCSUIMountState +) { + if (typeof Mount.getStyle === "function") { + const sfcStyleContent = + typeof Mount.getSfcStyleContent === "function" + ? await Mount.getSfcStyleContent() + : "" + shadowRoot.prepend(await Mount.getStyle({ ...anchor, sfcStyleContent })) + } + + if (typeof Mount.getShadowHostId === "function") { + shadowHost.id = await Mount.getShadowHostId(anchor) + } + + if (typeof Mount.mountShadowHost === "function") { + await Mount.mountShadowHost({ + shadowHost, + anchor, + mountState + }) + } else if (anchor.type === "inline") { + anchor.element.insertAdjacentElement(anchor.insertPosition || "afterend", shadowHost) + } else { + document.documentElement.prepend(shadowHost) + } +} + +export async function createShadowContainer( + Mount: PlasmoCSUI, + anchor: PlasmoCSUIAnchor, + mountState?: PlasmoCSUIMountState +) { + const shadowDom = await createShadowDOM(Mount) + + mountState?.hostSet.add(shadowDom.shadowHost) + mountState?.hostMap.set(shadowDom.shadowHost, anchor) + + await injectAnchor(Mount, anchor, shadowDom, mountState) + + return shadowDom.shadowContainer +} + +const isVisible = (el: Element) => { + if (!el) { + return false + } + const elementRect = el.getBoundingClientRect() + const elementStyle = globalThis.getComputedStyle(el) + + // console.log(elementRect, elementStyle) + + if (elementStyle.display === "none") { + return false + } + + if (elementStyle.visibility === "hidden") { + return false + } + + if (elementStyle.opacity === "0") { + return false + } + + if ( + elementRect.width === 0 && + elementRect.height === 0 && + elementStyle.overflow !== "hidden" + ) { + return false + } + + // Check if the element is irrevocably off-screen: + if ( + elementRect.x + elementRect.width < 0 || + elementRect.y + elementRect.height < 0 + ) { + return false + } + + return true +} + +export function createAnchorObserver(Mount: PlasmoCSUI) { + const mountState: PlasmoCSUIMountState = { + document: document || window.document, + observer: null, + + mountInterval: null, + + isMounting: false, + isMutated: false, + + hostSet: new Set(), + hostMap: new WeakMap(), + + overlayTargetList: [] + } + + const isMounted = (el: Element | null) => + el?.id + ? !!document.getElementById(el.id) + : el?.getRootNode({ composed: true }) === mountState.document + + const hasInlineAnchor = typeof Mount.getInlineAnchor === "function" + const hasOverlayAnchor = typeof Mount.getOverlayAnchor === "function" + + const hasInlineAnchorList = typeof Mount.getInlineAnchorList === "function" + const hasOverlayAnchorList = typeof Mount.getOverlayAnchorList === "function" + + const shouldObserve = + hasInlineAnchor || + hasOverlayAnchor || + hasInlineAnchorList || + hasOverlayAnchorList + + if (!shouldObserve) { + return null + } + + async function mountAnchors(render: (anchor?: PlasmoCSUIAnchor) => void) { + mountState.isMounting = true + + const mountedInlineAnchorSet = new WeakSet() + + // There should only be 1 overlay mount + let overlayHost: Element = null + + // Go through mounted sets and check if they are still mounted + for (const el of mountState.hostSet) { + if (isMounted(el)) { + const anchor = mountState.hostMap.get(el) + if (!!anchor) { + if (anchor.type === "inline") { + mountedInlineAnchorSet.add(anchor.element) + } else if (anchor.type === "overlay") { + overlayHost = el + } + } + } else { + mountState.hostSet.delete(el) + } + } + + const [inlineAnchor, inlineAnchorList, overlayAnchor, overlayAnchorList] = + await Promise.all([ + hasInlineAnchor ? Mount.getInlineAnchor() : null, + hasInlineAnchorList ? Mount.getInlineAnchorList() : null, + hasOverlayAnchor ? Mount.getOverlayAnchor() : null, + hasOverlayAnchorList ? Mount.getOverlayAnchorList() : null + ]) + + const renderList: PlasmoCSUIAnchor[] = [] + + if (!!inlineAnchor && !mountedInlineAnchorSet.has(inlineAnchor)) { + renderList.push({ + element: inlineAnchor, + type: "inline" + }) + } + + if ((inlineAnchorList?.length || 0) > 0) { + inlineAnchorList.forEach((inlineAnchor) => { + if ( + inlineAnchor instanceof Element && + !mountedInlineAnchorSet.has(inlineAnchor) + ) { + renderList.push({ + element: inlineAnchor, + type: "inline" + }) + } + }) + } + + const overlayTargetList = [] + + if (!!overlayAnchor && isVisible(overlayAnchor)) { + overlayTargetList.push(overlayAnchor) + } + + if ((overlayAnchorList?.length || 0) > 0) { + overlayAnchorList.forEach((el) => { + if (el instanceof Element && isVisible(el)) { + overlayTargetList.push(el) + } + }) + } + + if (overlayTargetList.length > 0) { + mountState.overlayTargetList = overlayTargetList + if (!overlayHost) { + renderList.push({ + element: document.documentElement, + type: "overlay" + }) + } else { + // force re-render + } + } else { + overlayHost?.remove() + mountState.hostSet.delete(overlayHost) + } + + await Promise.all(renderList.map(render)) + + if (mountState.isMutated) { + mountState.isMutated = false + await mountAnchors(render) + } + + mountState.isMounting = false + } + + const start = (render: (anchor?: PlasmoCSUIAnchor) => void) => { + mountState.observer = new MutationObserver(() => { + if (mountState.isMounting) { + mountState.isMutated = true + return + } + mountAnchors(render) + }) + + // Need to watch the subtree for shadowDOM + mountState.observer.observe(document.documentElement, { + childList: true, + subtree: true + }) + + mountState.mountInterval = setInterval(() => { + if (mountState.isMounting) { + mountState.isMutated = true + return + } + mountAnchors(render) + }, 142) + } + + return { + start, + mountState + } +} + +export const createRender = ( + Mount: PlasmoCSUI, + containers: [T, T], + mountState?: PlasmoCSUIMountState, + renderFx?: (anchor: PlasmoCSUIAnchor, rootContainer: Element) => Promise +) => { + const createRootContainer = (anchor: PlasmoCSUIAnchor) => + typeof Mount.getRootContainer === "function" + ? Mount.getRootContainer({ + anchor, + mountState + }) + : createShadowContainer(Mount, anchor, mountState) + + if (typeof Mount.render === "function") { + return (anchor: PlasmoCSUIAnchor) => + Mount.render( + { + anchor, + createRootContainer + }, + ...containers + ) + } + + return async (anchor: PlasmoCSUIAnchor) => { + const rootContainer = await createRootContainer(anchor) + return renderFx(anchor, rootContainer) + } +} diff --git a/packages/whats-ext/.plasmo/static/common/react.ts b/packages/whats-ext/.plasmo/static/common/react.ts new file mode 100644 index 0000000..e8c5968 --- /dev/null +++ b/packages/whats-ext/.plasmo/static/common/react.ts @@ -0,0 +1,8 @@ +import { Fragment, type FC, type ReactNode } from "react" + +export const getLayout = (RawImport: any): FC<{ children: ReactNode }> => + typeof RawImport.Layout === "function" + ? RawImport.Layout + : typeof RawImport.getGlobalProvider === "function" + ? RawImport.getGlobalProvider() + : Fragment diff --git a/packages/whats-ext/.plasmo/static/common/vue.ts b/packages/whats-ext/.plasmo/static/common/vue.ts new file mode 100644 index 0000000..05b4628 --- /dev/null +++ b/packages/whats-ext/.plasmo/static/common/vue.ts @@ -0,0 +1,2 @@ +globalThis.__VUE_OPTIONS_API__ = true +globalThis.__VUE_PROD_DEVTOOLS__ = process.env.NODE_ENV !== "production" diff --git a/packages/whats-ext/.plasmo/static/devtools.tsx b/packages/whats-ext/.plasmo/static/devtools.tsx new file mode 100644 index 0000000..8450ed4 --- /dev/null +++ b/packages/whats-ext/.plasmo/static/devtools.tsx @@ -0,0 +1,27 @@ +import React from "react" +import { createRoot } from "react-dom/client" + +import { getLayout } from "@plasmo-static-common/react" + +// @ts-ignore +import * as Component from "~devtools" + +let __plasmoRoot: HTMLElement = null + +document.addEventListener("DOMContentLoaded", () => { + if (!!__plasmoRoot) { + return + } + + __plasmoRoot = document.getElementById("__plasmo") + + const root = createRoot(__plasmoRoot) + + const Layout = getLayout(Component) + + root.render( + + + + ) +}) diff --git a/packages/whats-ext/.plasmo/static/newtab.tsx b/packages/whats-ext/.plasmo/static/newtab.tsx new file mode 100644 index 0000000..c52278b --- /dev/null +++ b/packages/whats-ext/.plasmo/static/newtab.tsx @@ -0,0 +1,27 @@ +import React from "react" +import { createRoot } from "react-dom/client" + +import { getLayout } from "@plasmo-static-common/react" + +// @ts-ignore +import * as Component from "~newtab" + +let __plasmoRoot: HTMLElement = null + +document.addEventListener("DOMContentLoaded", () => { + if (!!__plasmoRoot) { + return + } + + __plasmoRoot = document.getElementById("__plasmo") + + const root = createRoot(__plasmoRoot) + + const Layout = getLayout(Component) + + root.render( + + + + ) +}) diff --git a/packages/whats-ext/.plasmo/static/options.tsx b/packages/whats-ext/.plasmo/static/options.tsx new file mode 100644 index 0000000..908f80c --- /dev/null +++ b/packages/whats-ext/.plasmo/static/options.tsx @@ -0,0 +1,27 @@ +import React from "react" +import { createRoot } from "react-dom/client" + +import { getLayout } from "@plasmo-static-common/react" + +// @ts-ignore +import * as Component from "~options" + +let __plasmoRoot: HTMLElement = null + +document.addEventListener("DOMContentLoaded", () => { + if (!!__plasmoRoot) { + return + } + + __plasmoRoot = document.getElementById("__plasmo") + + const root = createRoot(__plasmoRoot) + + const Layout = getLayout(Component) + + root.render( + + + + ) +}) diff --git a/packages/whats-ext/.plasmo/static/popup.tsx b/packages/whats-ext/.plasmo/static/popup.tsx new file mode 100644 index 0000000..9c4cefd --- /dev/null +++ b/packages/whats-ext/.plasmo/static/popup.tsx @@ -0,0 +1,27 @@ +import React from "react" +import { createRoot } from "react-dom/client" + +import { getLayout } from "@plasmo-static-common/react" + +// @ts-ignore +import * as Component from "../../popup.tsx" + +let __plasmoRoot: HTMLElement = null + +document.addEventListener("DOMContentLoaded", () => { + if (!!__plasmoRoot) { + return + } + + __plasmoRoot = document.getElementById("__plasmo") + + const root = createRoot(__plasmoRoot) + + const Layout = getLayout(Component) + + root.render( + + + + ) +}) diff --git a/packages/whats-ext/.plasmo/static/sidepanel.tsx b/packages/whats-ext/.plasmo/static/sidepanel.tsx new file mode 100644 index 0000000..f11b34b --- /dev/null +++ b/packages/whats-ext/.plasmo/static/sidepanel.tsx @@ -0,0 +1,27 @@ +import React from "react" +import { createRoot } from "react-dom/client" + +import { getLayout } from "@plasmo-static-common/react" + +// @ts-ignore +import * as Component from "~sidepanel" + +let __plasmoRoot: HTMLElement = null + +document.addEventListener("DOMContentLoaded", () => { + if (!!__plasmoRoot) { + return + } + + __plasmoRoot = document.getElementById("__plasmo") + + const root = createRoot(__plasmoRoot) + + const Layout = getLayout(Component) + + root.render( + + + + ) +}) diff --git a/packages/whats-ext/assets/icon.development.png b/packages/whats-ext/assets/icon.development.png new file mode 100644 index 0000000..cfd931b Binary files /dev/null and b/packages/whats-ext/assets/icon.development.png differ diff --git a/packages/whats-ext/assets/icon.png b/packages/whats-ext/assets/icon.png new file mode 100644 index 0000000..cfd931b Binary files /dev/null and b/packages/whats-ext/assets/icon.png differ diff --git a/packages/whats-ext/background.ts b/packages/whats-ext/background.ts new file mode 100644 index 0000000..281561c --- /dev/null +++ b/packages/whats-ext/background.ts @@ -0,0 +1,5 @@ +export {} + +console.log( + "init refresh" +) diff --git a/packages/whats-ext/build/chrome-mv3-dev/content.9573a4e7.js b/packages/whats-ext/build/chrome-mv3-dev/content.9573a4e7.js new file mode 100644 index 0000000..1ed6df3 --- /dev/null +++ b/packages/whats-ext/build/chrome-mv3-dev/content.9573a4e7.js @@ -0,0 +1,1260 @@ +(function(define){var __define; typeof define === "function" && (__define=define,define=null); +// modules are defined as an array +// [ module function, map of requires ] +// +// map of requires is short require name -> numeric require +// +// anything defined in a previous bundle is accessed via the +// orig method which is the require for previous bundles + +(function (modules, entry, mainEntry, parcelRequireName, globalName) { + /* eslint-disable no-undef */ + var globalObject = + typeof globalThis !== 'undefined' + ? globalThis + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : typeof global !== 'undefined' + ? global + : {}; + /* eslint-enable no-undef */ + + // Save the require from previous bundle to this closure if any + var previousRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + + var cache = previousRequire.cache || {}; + // Do not use `require` to prevent Webpack from trying to bundle this call + var nodeRequire = + typeof module !== 'undefined' && + typeof module.require === 'function' && + module.require.bind(module); + + function newRequire(name, jumped) { + if (!cache[name]) { + if (!modules[name]) { + // if we cannot find the module within our internal map or + // cache jump to the current global require ie. the last bundle + // that was added to the page. + var currentRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + if (!jumped && currentRequire) { + return currentRequire(name, true); + } + + // If there are other bundles on this page the require from the + // previous one is saved to 'previousRequire'. Repeat this as + // many times as there are bundles until the module is found or + // we exhaust the require chain. + if (previousRequire) { + return previousRequire(name, true); + } + + // Try the node require function if it exists. + if (nodeRequire && typeof name === 'string') { + return nodeRequire(name); + } + + var err = new Error("Cannot find module '" + name + "'"); + err.code = 'MODULE_NOT_FOUND'; + throw err; + } + + localRequire.resolve = resolve; + localRequire.cache = {}; + + var module = (cache[name] = new newRequire.Module(name)); + + modules[name][0].call( + module.exports, + localRequire, + module, + module.exports, + this + ); + } + + return cache[name].exports; + + function localRequire(x) { + var res = localRequire.resolve(x); + return res === false ? {} : newRequire(res); + } + + function resolve(x) { + var id = modules[name][1][x]; + return id != null ? id : x; + } + } + + function Module(moduleName) { + this.id = moduleName; + this.bundle = newRequire; + this.exports = {}; + } + + newRequire.isParcelRequire = true; + newRequire.Module = Module; + newRequire.modules = modules; + newRequire.cache = cache; + newRequire.parent = previousRequire; + newRequire.register = function (id, exports) { + modules[id] = [ + function (require, module) { + module.exports = exports; + }, + {}, + ]; + }; + + Object.defineProperty(newRequire, 'root', { + get: function () { + return globalObject[parcelRequireName]; + }, + }); + + globalObject[parcelRequireName] = newRequire; + + for (var i = 0; i < entry.length; i++) { + newRequire(entry[i]); + } + + if (mainEntry) { + // Expose entry point to Node, AMD or browser globals + // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js + var mainExports = newRequire(mainEntry); + + // CommonJS + if (typeof exports === 'object' && typeof module !== 'undefined') { + module.exports = mainExports; + + // RequireJS + } else if (typeof define === 'function' && define.amd) { + define(function () { + return mainExports; + }); + + // "; // eslint-disable-line + // This is guaranteed to yield a script element. + var firstChild = div.firstChild; + domElement = div.removeChild(firstChild); + } else if (typeof props.is === "string") // $FlowIssue `createElement` should be updated for Web Components + domElement = ownerDocument.createElement(type, { + is: props.is + }); + else { + // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug. + // See discussion in https://github.com/facebook/react/pull/6896 + // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240 + domElement = ownerDocument.createElement(type); // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size` + // attributes on `select`s needs to be added before `option`s are inserted. + // This prevents: + // - a bug where the `select` does not scroll to the correct option because singular + // `select` elements automatically pick the first item #13222 + // - a bug where the `select` set the first item as selected despite the `size` attribute #14239 + // See https://github.com/facebook/react/issues/13222 + // and https://github.com/facebook/react/issues/14239 + if (type === "select") { + var node = domElement; + if (props.multiple) node.multiple = true; + else if (props.size) // Setting a size greater than 1 causes a select to behave like `multiple=true`, where + // it is possible that no option is selected. + // + // This is only necessary when a select in "single selection mode". + node.size = props.size; + } + } + } else domElement = ownerDocument.createElementNS(namespaceURI, type); + if (namespaceURI === HTML_NAMESPACE) { + if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === "[object HTMLUnknownElement]" && !hasOwnProperty.call(warnedUnknownTags, type)) { + warnedUnknownTags[type] = true; + error("The tag <%s> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.", type); + } + } + return domElement; + } + function createTextNode(text, rootContainerElement) { + return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text); + } + function setInitialProperties(domElement, tag, rawProps, rootContainerElement) { + var isCustomComponentTag = isCustomComponent(tag, rawProps); + validatePropertiesInDevelopment(tag, rawProps); + var props; + switch(tag){ + case "dialog": + listenToNonDelegatedEvent("cancel", domElement); + listenToNonDelegatedEvent("close", domElement); + props = rawProps; + break; + case "iframe": + case "object": + case "embed": + // We listen to this event in case to ensure emulated bubble + // listeners still fire for the load event. + listenToNonDelegatedEvent("load", domElement); + props = rawProps; + break; + case "video": + case "audio": + // We listen to these events in case to ensure emulated bubble + // listeners still fire for all the media events. + for(var i = 0; i < mediaEventTypes.length; i++)listenToNonDelegatedEvent(mediaEventTypes[i], domElement); + props = rawProps; + break; + case "source": + // We listen to this event in case to ensure emulated bubble + // listeners still fire for the error event. + listenToNonDelegatedEvent("error", domElement); + props = rawProps; + break; + case "img": + case "image": + case "link": + // We listen to these events in case to ensure emulated bubble + // listeners still fire for error and load events. + listenToNonDelegatedEvent("error", domElement); + listenToNonDelegatedEvent("load", domElement); + props = rawProps; + break; + case "details": + // We listen to this event in case to ensure emulated bubble + // listeners still fire for the toggle event. + listenToNonDelegatedEvent("toggle", domElement); + props = rawProps; + break; + case "input": + initWrapperState(domElement, rawProps); + props = getHostProps(domElement, rawProps); // We listen to this event in case to ensure emulated bubble + // listeners still fire for the invalid event. + listenToNonDelegatedEvent("invalid", domElement); + break; + case "option": + validateProps(domElement, rawProps); + props = rawProps; + break; + case "select": + initWrapperState$1(domElement, rawProps); + props = getHostProps$1(domElement, rawProps); // We listen to this event in case to ensure emulated bubble + // listeners still fire for the invalid event. + listenToNonDelegatedEvent("invalid", domElement); + break; + case "textarea": + initWrapperState$2(domElement, rawProps); + props = getHostProps$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble + // listeners still fire for the invalid event. + listenToNonDelegatedEvent("invalid", domElement); + break; + default: + props = rawProps; + } + assertValidProps(tag, props); + setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag); + switch(tag){ + case "input": + // TODO: Make sure we check if this is still unmounted or do any clean + // up necessary since we never stop tracking anymore. + track(domElement); + postMountWrapper(domElement, rawProps, false); + break; + case "textarea": + // TODO: Make sure we check if this is still unmounted or do any clean + // up necessary since we never stop tracking anymore. + track(domElement); + postMountWrapper$3(domElement); + break; + case "option": + postMountWrapper$1(domElement, rawProps); + break; + case "select": + postMountWrapper$2(domElement, rawProps); + break; + default: + if (typeof props.onClick === "function") // TODO: This cast may not be sound for SVG, MathML or custom elements. + trapClickOnNonInteractiveElement(domElement); + break; + } + } // Calculate the diff between the two objects. + function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) { + validatePropertiesInDevelopment(tag, nextRawProps); + var updatePayload = null; + var lastProps; + var nextProps; + switch(tag){ + case "input": + lastProps = getHostProps(domElement, lastRawProps); + nextProps = getHostProps(domElement, nextRawProps); + updatePayload = []; + break; + case "select": + lastProps = getHostProps$1(domElement, lastRawProps); + nextProps = getHostProps$1(domElement, nextRawProps); + updatePayload = []; + break; + case "textarea": + lastProps = getHostProps$2(domElement, lastRawProps); + nextProps = getHostProps$2(domElement, nextRawProps); + updatePayload = []; + break; + default: + lastProps = lastRawProps; + nextProps = nextRawProps; + if (typeof lastProps.onClick !== "function" && typeof nextProps.onClick === "function") // TODO: This cast may not be sound for SVG, MathML or custom elements. + trapClickOnNonInteractiveElement(domElement); + break; + } + assertValidProps(tag, nextProps); + var propKey; + var styleName; + var styleUpdates = null; + for(propKey in lastProps){ + if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) continue; + if (propKey === STYLE) { + var lastStyle = lastProps[propKey]; + for(styleName in lastStyle)if (lastStyle.hasOwnProperty(styleName)) { + if (!styleUpdates) styleUpdates = {}; + styleUpdates[styleName] = ""; + } + } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) ; + else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; + else if (propKey === AUTOFOCUS) ; + else if (registrationNameDependencies.hasOwnProperty(propKey)) // This is a special case. If any listener updates we need to ensure + // that the "current" fiber pointer gets updated so we need a commit + // to update this element. + { + if (!updatePayload) updatePayload = []; + } else // For all other deleted properties we add it to the queue. We use + // the allowed property list in the commit phase instead. + (updatePayload = updatePayload || []).push(propKey, null); + } + for(propKey in nextProps){ + var nextProp = nextProps[propKey]; + var lastProp = lastProps != null ? lastProps[propKey] : undefined; + if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) continue; + if (propKey === STYLE) { + if (nextProp) // Freeze the next style object so that we can assume it won't be + // mutated. We have already warned for this in the past. + Object.freeze(nextProp); + if (lastProp) { + // Unset styles on `lastProp` but not on `nextProp`. + for(styleName in lastProp)if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) { + if (!styleUpdates) styleUpdates = {}; + styleUpdates[styleName] = ""; + } + // Update styles that changed since `lastProp`. + for(styleName in nextProp)if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) { + if (!styleUpdates) styleUpdates = {}; + styleUpdates[styleName] = nextProp[styleName]; + } + } else { + // Relies on `updateStylesByID` not mutating `styleUpdates`. + if (!styleUpdates) { + if (!updatePayload) updatePayload = []; + updatePayload.push(propKey, styleUpdates); + } + styleUpdates = nextProp; + } + } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { + var nextHtml = nextProp ? nextProp[HTML$1] : undefined; + var lastHtml = lastProp ? lastProp[HTML$1] : undefined; + if (nextHtml != null) { + if (lastHtml !== nextHtml) (updatePayload = updatePayload || []).push(propKey, nextHtml); + } + } else if (propKey === CHILDREN) { + if (typeof nextProp === "string" || typeof nextProp === "number") (updatePayload = updatePayload || []).push(propKey, "" + nextProp); + } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; + else if (registrationNameDependencies.hasOwnProperty(propKey)) { + if (nextProp != null) { + // We eagerly listen to this even though we haven't committed yet. + if (typeof nextProp !== "function") warnForInvalidEventListener(propKey, nextProp); + if (propKey === "onScroll") listenToNonDelegatedEvent("scroll", domElement); + } + if (!updatePayload && lastProp !== nextProp) // This is a special case. If any listener updates we need to ensure + // that the "current" props pointer gets updated so we need a commit + // to update this element. + updatePayload = []; + } else // For any other property we always add it to the queue and then we + // filter it out using the allowed property list during the commit. + (updatePayload = updatePayload || []).push(propKey, nextProp); + } + if (styleUpdates) { + validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE]); + (updatePayload = updatePayload || []).push(STYLE, styleUpdates); + } + return updatePayload; + } // Apply the diff. + function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) { + // Update checked *before* name. + // In the middle of an update, it is possible to have multiple checked. + // When a checked radio tries to change name, browser makes another radio's checked false. + if (tag === "input" && nextRawProps.type === "radio" && nextRawProps.name != null) updateChecked(domElement, nextRawProps); + var wasCustomComponentTag = isCustomComponent(tag, lastRawProps); + var isCustomComponentTag = isCustomComponent(tag, nextRawProps); // Apply the diff. + updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props + // changed. + switch(tag){ + case "input": + // Update the wrapper around inputs *after* updating props. This has to + // happen after `updateDOMProperties`. Otherwise HTML5 input validations + // raise warnings and prevent the new value from being assigned. + updateWrapper(domElement, nextRawProps); + break; + case "textarea": + updateWrapper$1(domElement, nextRawProps); + break; + case "select": + // + // but + case "option": + return tag === "#text"; + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption + // No special behavior since these rules fall back to "in body" mode for + // all except special table nodes which cause bad parsing behavior anyway. + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr + case "tr": + return tag === "th" || tag === "td" || tag === "style" || tag === "script" || tag === "template"; + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody + case "tbody": + case "thead": + case "tfoot": + return tag === "tr" || tag === "style" || tag === "script" || tag === "template"; + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup + case "colgroup": + return tag === "col" || tag === "template"; + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable + case "table": + return tag === "caption" || tag === "colgroup" || tag === "tbody" || tag === "tfoot" || tag === "thead" || tag === "style" || tag === "script" || tag === "template"; + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead + case "head": + return tag === "base" || tag === "basefont" || tag === "bgsound" || tag === "link" || tag === "meta" || tag === "title" || tag === "noscript" || tag === "noframes" || tag === "style" || tag === "script" || tag === "template"; + // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element + case "html": + return tag === "head" || tag === "body" || tag === "frameset"; + case "frameset": + return tag === "frame"; + case "#document": + return tag === "html"; + } // Probably in the "in body" parsing mode, so we outlaw only tag combos + // where the parsing rules cause implicit opens or closes to be added. + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody + switch(tag){ + case "h1": + case "h2": + case "h3": + case "h4": + case "h5": + case "h6": + return parentTag !== "h1" && parentTag !== "h2" && parentTag !== "h3" && parentTag !== "h4" && parentTag !== "h5" && parentTag !== "h6"; + case "rp": + case "rt": + return impliedEndTags.indexOf(parentTag) === -1; + case "body": + case "caption": + case "col": + case "colgroup": + case "frameset": + case "frame": + case "head": + case "html": + case "tbody": + case "td": + case "tfoot": + case "th": + case "thead": + case "tr": + // These tags are only valid with a few parents that have special child + // parsing rules -- if we're down here, then none of those matched and + // so we allow it only if we don't know what the parent is, as all other + // cases are invalid. + return parentTag == null; + } + return true; + }; + /** + * Returns whether + */ var findInvalidAncestorForTag = function(tag, ancestorInfo) { + switch(tag){ + case "address": + case "article": + case "aside": + case "blockquote": + case "center": + case "details": + case "dialog": + case "dir": + case "div": + case "dl": + case "fieldset": + case "figcaption": + case "figure": + case "footer": + case "header": + case "hgroup": + case "main": + case "menu": + case "nav": + case "ol": + case "p": + case "section": + case "summary": + case "ul": + case "pre": + case "listing": + case "table": + case "hr": + case "xmp": + case "h1": + case "h2": + case "h3": + case "h4": + case "h5": + case "h6": + return ancestorInfo.pTagInButtonScope; + case "form": + return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope; + case "li": + return ancestorInfo.listItemTagAutoclosing; + case "dd": + case "dt": + return ancestorInfo.dlItemTagAutoclosing; + case "button": + return ancestorInfo.buttonTagInScope; + case "a": + // Spec says something about storing a list of markers, but it sounds + // equivalent to this check. + return ancestorInfo.aTagInScope; + case "nobr": + return ancestorInfo.nobrTagInScope; + } + return null; + }; + var didWarn$1 = {}; + validateDOMNesting = function(childTag, childText, ancestorInfo) { + ancestorInfo = ancestorInfo || emptyAncestorInfo; + var parentInfo = ancestorInfo.current; + var parentTag = parentInfo && parentInfo.tag; + if (childText != null) { + if (childTag != null) error("validateDOMNesting: when childText is passed, childTag should be null"); + childTag = "#text"; + } + var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo; + var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo); + var invalidParentOrAncestor = invalidParent || invalidAncestor; + if (!invalidParentOrAncestor) return; + var ancestorTag = invalidParentOrAncestor.tag; + var warnKey = !!invalidParent + "|" + childTag + "|" + ancestorTag; + if (didWarn$1[warnKey]) return; + didWarn$1[warnKey] = true; + var tagDisplayName = childTag; + var whitespaceInfo = ""; + if (childTag === "#text") { + if (/\S/.test(childText)) tagDisplayName = "Text nodes"; + else { + tagDisplayName = "Whitespace text nodes"; + whitespaceInfo = " Make sure you don't have any extra whitespace between tags on each line of your source code."; + } + } else tagDisplayName = "<" + childTag + ">"; + if (invalidParent) { + var info = ""; + if (ancestorTag === "table" && childTag === "tr") info += " Add a , or to your code to match the DOM tree generated by the browser."; + error("validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s", tagDisplayName, ancestorTag, whitespaceInfo, info); + } else error("validateDOMNesting(...): %s cannot appear as a descendant of <%s>.", tagDisplayName, ancestorTag); + }; + var SUPPRESS_HYDRATION_WARNING$1 = "suppressHydrationWarning"; + var SUSPENSE_START_DATA = "$"; + var SUSPENSE_END_DATA = "/$"; + var SUSPENSE_PENDING_START_DATA = "$?"; + var SUSPENSE_FALLBACK_START_DATA = "$!"; + var STYLE$1 = "style"; + var eventsEnabled = null; + var selectionInformation = null; + function getRootHostContext(rootContainerInstance) { + var type; + var namespace; + var nodeType = rootContainerInstance.nodeType; + switch(nodeType){ + case DOCUMENT_NODE: + case DOCUMENT_FRAGMENT_NODE: + type = nodeType === DOCUMENT_NODE ? "#document" : "#fragment"; + var root = rootContainerInstance.documentElement; + namespace = root ? root.namespaceURI : getChildNamespace(null, ""); + break; + default: + var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance; + var ownNamespace = container.namespaceURI || null; + type = container.tagName; + namespace = getChildNamespace(ownNamespace, type); + break; + } + var validatedTag = type.toLowerCase(); + var ancestorInfo = updatedAncestorInfo(null, validatedTag); + return { + namespace: namespace, + ancestorInfo: ancestorInfo + }; + } + function getChildHostContext(parentHostContext, type, rootContainerInstance) { + var parentHostContextDev = parentHostContext; + var namespace = getChildNamespace(parentHostContextDev.namespace, type); + var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type); + return { + namespace: namespace, + ancestorInfo: ancestorInfo + }; + } + function getPublicInstance(instance) { + return instance; + } + function prepareForCommit(containerInfo) { + eventsEnabled = isEnabled(); + selectionInformation = getSelectionInformation(); + var activeInstance = null; + setEnabled(false); + return activeInstance; + } + function resetAfterCommit(containerInfo) { + restoreSelection(selectionInformation); + setEnabled(eventsEnabled); + eventsEnabled = null; + selectionInformation = null; + } + function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) { + var parentNamespace; + // TODO: take namespace into account when validating. + var hostContextDev = hostContext; + validateDOMNesting(type, null, hostContextDev.ancestorInfo); + if (typeof props.children === "string" || typeof props.children === "number") { + var string = "" + props.children; + var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type); + validateDOMNesting(null, string, ownAncestorInfo); + } + parentNamespace = hostContextDev.namespace; + var domElement = createElement(type, props, rootContainerInstance, parentNamespace); + precacheFiberNode(internalInstanceHandle, domElement); + updateFiberProps(domElement, props); + return domElement; + } + function appendInitialChild(parentInstance, child) { + parentInstance.appendChild(child); + } + function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) { + setInitialProperties(domElement, type, props, rootContainerInstance); + switch(type){ + case "button": + case "input": + case "select": + case "textarea": + return !!props.autoFocus; + case "img": + return true; + default: + return false; + } + } + function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) { + var hostContextDev = hostContext; + if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === "string" || typeof newProps.children === "number")) { + var string = "" + newProps.children; + var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type); + validateDOMNesting(null, string, ownAncestorInfo); + } + return diffProperties(domElement, type, oldProps, newProps); + } + function shouldSetTextContent(type, props) { + return type === "textarea" || type === "noscript" || typeof props.children === "string" || typeof props.children === "number" || typeof props.dangerouslySetInnerHTML === "object" && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null; + } + function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) { + var hostContextDev = hostContext; + validateDOMNesting(null, text, hostContextDev.ancestorInfo); + var textNode = createTextNode(text, rootContainerInstance); + precacheFiberNode(internalInstanceHandle, textNode); + return textNode; + } + function getCurrentEventPriority() { + var currentEvent = window.event; + if (currentEvent === undefined) return DefaultEventPriority; + return getEventPriority(currentEvent.type); + } + // if a component just imports ReactDOM (e.g. for findDOMNode). + // Some environments might not have setTimeout or clearTimeout. + var scheduleTimeout = typeof setTimeout === "function" ? setTimeout : undefined; + var cancelTimeout = typeof clearTimeout === "function" ? clearTimeout : undefined; + var noTimeout = -1; + var localPromise = typeof Promise === "function" ? Promise : undefined; // ------------------- + var scheduleMicrotask = typeof queueMicrotask === "function" ? queueMicrotask : typeof localPromise !== "undefined" ? function(callback) { + return localPromise.resolve(null).then(callback).catch(handleErrorInNextTick); + } : scheduleTimeout; // TODO: Determine the best fallback here. + function handleErrorInNextTick(error) { + setTimeout(function() { + throw error; + }); + } // ------------------- + function commitMount(domElement, type, newProps, internalInstanceHandle) { + // Despite the naming that might imply otherwise, this method only + // fires if there is an `Update` effect scheduled during mounting. + // This happens if `finalizeInitialChildren` returns `true` (which it + // does to implement the `autoFocus` attribute on the client). But + // there are also other cases when this might happen (such as patching + // up text content during hydration mismatch). So we'll check this again. + switch(type){ + case "button": + case "input": + case "select": + case "textarea": + if (newProps.autoFocus) domElement.focus(); + return; + case "img": + if (newProps.src) domElement.src = newProps.src; + return; + } + } + function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) { + // Apply the diff to the DOM node. + updateProperties(domElement, updatePayload, type, oldProps, newProps); // Update the props handle so that we know which props are the ones with + // with current event handlers. + updateFiberProps(domElement, newProps); + } + function resetTextContent(domElement) { + setTextContent(domElement, ""); + } + function commitTextUpdate(textInstance, oldText, newText) { + textInstance.nodeValue = newText; + } + function appendChild(parentInstance, child) { + parentInstance.appendChild(child); + } + function appendChildToContainer(container, child) { + var parentNode; + if (container.nodeType === COMMENT_NODE) { + parentNode = container.parentNode; + parentNode.insertBefore(child, container); + } else { + parentNode = container; + parentNode.appendChild(child); + } // This container might be used for a portal. + // If something inside a portal is clicked, that click should bubble + // through the React tree. However, on Mobile Safari the click would + // never bubble through the *DOM* tree unless an ancestor with onclick + // event exists. So we wouldn't see it and dispatch it. + // This is why we ensure that non React root containers have inline onclick + // defined. + // https://github.com/facebook/react/issues/11918 + var reactRootContainer = container._reactRootContainer; + if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) // TODO: This cast may not be sound for SVG, MathML or custom elements. + trapClickOnNonInteractiveElement(parentNode); + } + function insertBefore(parentInstance, child, beforeChild) { + parentInstance.insertBefore(child, beforeChild); + } + function insertInContainerBefore(container, child, beforeChild) { + if (container.nodeType === COMMENT_NODE) container.parentNode.insertBefore(child, beforeChild); + else container.insertBefore(child, beforeChild); + } + function removeChild(parentInstance, child) { + parentInstance.removeChild(child); + } + function removeChildFromContainer(container, child) { + if (container.nodeType === COMMENT_NODE) container.parentNode.removeChild(child); + else container.removeChild(child); + } + function clearSuspenseBoundary(parentInstance, suspenseInstance) { + var node = suspenseInstance; // Delete all nodes within this suspense boundary. + // There might be nested nodes so we need to keep track of how + // deep we are and only break out when we're back on top. + var depth = 0; + do { + var nextNode = node.nextSibling; + parentInstance.removeChild(node); + if (nextNode && nextNode.nodeType === COMMENT_NODE) { + var data = nextNode.data; + if (data === SUSPENSE_END_DATA) { + if (depth === 0) { + parentInstance.removeChild(nextNode); // Retry if any event replaying was blocked on this. + retryIfBlockedOn(suspenseInstance); + return; + } else depth--; + } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_PENDING_START_DATA || data === SUSPENSE_FALLBACK_START_DATA) depth++; + } + node = nextNode; + }while (node); // TODO: Warn, we didn't find the end comment boundary. + // Retry if any event replaying was blocked on this. + retryIfBlockedOn(suspenseInstance); + } + function clearSuspenseBoundaryFromContainer(container, suspenseInstance) { + if (container.nodeType === COMMENT_NODE) clearSuspenseBoundary(container.parentNode, suspenseInstance); + else if (container.nodeType === ELEMENT_NODE) clearSuspenseBoundary(container, suspenseInstance); + // Retry if any event replaying was blocked on this. + retryIfBlockedOn(container); + } + function hideInstance(instance) { + instance; + var style = instance.style; + if (typeof style.setProperty === "function") style.setProperty("display", "none", "important"); + else style.display = "none"; + } + function hideTextInstance(textInstance) { + textInstance.nodeValue = ""; + } + function unhideInstance(instance, props) { + instance; + var styleProp = props[STYLE$1]; + var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty("display") ? styleProp.display : null; + instance.style.display = dangerousStyleValue("display", display); + } + function unhideTextInstance(textInstance, text) { + textInstance.nodeValue = text; + } + function clearContainer(container) { + if (container.nodeType === ELEMENT_NODE) container.textContent = ""; + else if (container.nodeType === DOCUMENT_NODE) { + if (container.documentElement) container.removeChild(container.documentElement); + } + } // ------------------- + function canHydrateInstance(instance, type, props) { + if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) return null; + // This has now been refined to an element node. + return instance; + } + function canHydrateTextInstance(instance, text) { + if (text === "" || instance.nodeType !== TEXT_NODE) // Empty strings are not parsed by HTML so there won't be a correct match here. + return null; + // This has now been refined to a text node. + return instance; + } + function canHydrateSuspenseInstance(instance) { + if (instance.nodeType !== COMMENT_NODE) // Empty strings are not parsed by HTML so there won't be a correct match here. + return null; + // This has now been refined to a suspense node. + return instance; + } + function isSuspenseInstancePending(instance) { + return instance.data === SUSPENSE_PENDING_START_DATA; + } + function isSuspenseInstanceFallback(instance) { + return instance.data === SUSPENSE_FALLBACK_START_DATA; + } + function getSuspenseInstanceFallbackErrorDetails(instance) { + var dataset = instance.nextSibling && instance.nextSibling.dataset; + var digest, message, stack; + if (dataset) { + digest = dataset.dgst; + message = dataset.msg; + stack = dataset.stck; + } + return { + message: message, + digest: digest, + stack: stack + }; + // const nextSibling = instance.nextSibling; + // if (nextSibling) { + // const dataset = ((nextSibling: any): HTMLTemplateElement).dataset; + // value.message = dataset.msg; + // value.hash = dataset.hash; + // if (true) { + // value.stack = dataset.stack; + // } + // } + // return value; + } + function registerSuspenseInstanceRetry(instance, callback) { + instance._reactRetry = callback; + } + function getNextHydratable(node) { + // Skip non-hydratable nodes. + for(; node != null; node = node.nextSibling){ + var nodeType = node.nodeType; + if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) break; + if (nodeType === COMMENT_NODE) { + var nodeData = node.data; + if (nodeData === SUSPENSE_START_DATA || nodeData === SUSPENSE_FALLBACK_START_DATA || nodeData === SUSPENSE_PENDING_START_DATA) break; + if (nodeData === SUSPENSE_END_DATA) return null; + } + } + return node; + } + function getNextHydratableSibling(instance) { + return getNextHydratable(instance.nextSibling); + } + function getFirstHydratableChild(parentInstance) { + return getNextHydratable(parentInstance.firstChild); + } + function getFirstHydratableChildWithinContainer(parentContainer) { + return getNextHydratable(parentContainer.firstChild); + } + function getFirstHydratableChildWithinSuspenseInstance(parentInstance) { + return getNextHydratable(parentInstance.nextSibling); + } + function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle, shouldWarnDev) { + precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events + // get attached. + updateFiberProps(instance, props); + var parentNamespace; + var hostContextDev = hostContext; + parentNamespace = hostContextDev.namespace; + // when the legacy root API is removed. + var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode; + return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance, isConcurrentMode, shouldWarnDev); + } + function hydrateTextInstance(textInstance, text, internalInstanceHandle, shouldWarnDev) { + precacheFiberNode(internalInstanceHandle, textInstance); // TODO: Temporary hack to check if we're in a concurrent root. We can delete + // when the legacy root API is removed. + var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode; + return diffHydratedText(textInstance, text); + } + function hydrateSuspenseInstance(suspenseInstance, internalInstanceHandle) { + precacheFiberNode(internalInstanceHandle, suspenseInstance); + } + function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) { + var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary. + // There might be nested nodes so we need to keep track of how + // deep we are and only break out when we're back on top. + var depth = 0; + while(node){ + if (node.nodeType === COMMENT_NODE) { + var data = node.data; + if (data === SUSPENSE_END_DATA) { + if (depth === 0) return getNextHydratableSibling(node); + else depth--; + } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) depth++; + } + node = node.nextSibling; + } // TODO: Warn, we didn't find the end comment boundary. + return null; + } // Returns the SuspenseInstance if this node is a direct child of a + // SuspenseInstance. I.e. if its previous sibling is a Comment with + // SUSPENSE_x_START_DATA. Otherwise, null. + function getParentSuspenseInstance(targetInstance) { + var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary. + // There might be nested nodes so we need to keep track of how + // deep we are and only break out when we're back on top. + var depth = 0; + while(node){ + if (node.nodeType === COMMENT_NODE) { + var data = node.data; + if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) { + if (depth === 0) return node; + else depth--; + } else if (data === SUSPENSE_END_DATA) depth++; + } + node = node.previousSibling; + } + return null; + } + function commitHydratedContainer(container) { + // Retry if any event replaying was blocked on this. + retryIfBlockedOn(container); + } + function commitHydratedSuspenseInstance(suspenseInstance) { + // Retry if any event replaying was blocked on this. + retryIfBlockedOn(suspenseInstance); + } + function shouldDeleteUnhydratedTailInstances(parentType) { + return parentType !== "head" && parentType !== "body"; + } + function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text, isConcurrentMode) { + var shouldWarnDev = true; + checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev); + } + function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text, isConcurrentMode) { + if (parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) { + var shouldWarnDev = true; + checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev); + } + } + function didNotHydrateInstanceWithinContainer(parentContainer, instance) { + if (instance.nodeType === ELEMENT_NODE) warnForDeletedHydratableElement(parentContainer, instance); + else if (instance.nodeType === COMMENT_NODE) ; + else warnForDeletedHydratableText(parentContainer, instance); + } + function didNotHydrateInstanceWithinSuspenseInstance(parentInstance, instance) { + // $FlowFixMe: Only Element or Document can be parent nodes. + var parentNode = parentInstance.parentNode; + if (parentNode !== null) { + if (instance.nodeType === ELEMENT_NODE) warnForDeletedHydratableElement(parentNode, instance); + else if (instance.nodeType === COMMENT_NODE) ; + else warnForDeletedHydratableText(parentNode, instance); + } + } + function didNotHydrateInstance(parentType, parentProps, parentInstance, instance, isConcurrentMode) { + if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) { + if (instance.nodeType === ELEMENT_NODE) warnForDeletedHydratableElement(parentInstance, instance); + else if (instance.nodeType === COMMENT_NODE) ; + else warnForDeletedHydratableText(parentInstance, instance); + } + } + function didNotFindHydratableInstanceWithinContainer(parentContainer, type, props) { + warnForInsertedHydratedElement(parentContainer, type); + } + function didNotFindHydratableTextInstanceWithinContainer(parentContainer, text) { + warnForInsertedHydratedText(parentContainer, text); + } + function didNotFindHydratableInstanceWithinSuspenseInstance(parentInstance, type, props) { + // $FlowFixMe: Only Element or Document can be parent nodes. + var parentNode = parentInstance.parentNode; + if (parentNode !== null) warnForInsertedHydratedElement(parentNode, type); + } + function didNotFindHydratableTextInstanceWithinSuspenseInstance(parentInstance, text) { + // $FlowFixMe: Only Element or Document can be parent nodes. + var parentNode = parentInstance.parentNode; + if (parentNode !== null) warnForInsertedHydratedText(parentNode, text); + } + function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props, isConcurrentMode) { + if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) warnForInsertedHydratedElement(parentInstance, type); + } + function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text, isConcurrentMode) { + if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) warnForInsertedHydratedText(parentInstance, text); + } + function errorHydratingContainer(parentContainer) { + // TODO: This gets logged by onRecoverableError, too, so we should be + // able to remove it. + error("An error occurred during hydration. The server HTML was replaced with client content in <%s>.", parentContainer.nodeName.toLowerCase()); + } + function preparePortalMount(portalInstance) { + listenToAllSupportedEvents(portalInstance); + } + var randomKey = Math.random().toString(36).slice(2); + var internalInstanceKey = "__reactFiber$" + randomKey; + var internalPropsKey = "__reactProps$" + randomKey; + var internalContainerInstanceKey = "__reactContainer$" + randomKey; + var internalEventHandlersKey = "__reactEvents$" + randomKey; + var internalEventHandlerListenersKey = "__reactListeners$" + randomKey; + var internalEventHandlesSetKey = "__reactHandles$" + randomKey; + function detachDeletedInstance(node) { + // TODO: This function is only called on host components. I don't think all of + // these fields are relevant. + delete node[internalInstanceKey]; + delete node[internalPropsKey]; + delete node[internalEventHandlersKey]; + delete node[internalEventHandlerListenersKey]; + delete node[internalEventHandlesSetKey]; + } + function precacheFiberNode(hostInst, node) { + node[internalInstanceKey] = hostInst; + } + function markContainerAsRoot(hostRoot, node) { + node[internalContainerInstanceKey] = hostRoot; + } + function unmarkContainerAsRoot(node) { + node[internalContainerInstanceKey] = null; + } + function isContainerMarkedAsRoot(node) { + return !!node[internalContainerInstanceKey]; + } // Given a DOM node, return the closest HostComponent or HostText fiber ancestor. + // If the target node is part of a hydrated or not yet rendered subtree, then + // this may also return a SuspenseComponent or HostRoot to indicate that. + // Conceptually the HostRoot fiber is a child of the Container node. So if you + // pass the Container node as the targetNode, you will not actually get the + // HostRoot back. To get to the HostRoot, you need to pass a child of it. + // The same thing applies to Suspense boundaries. + function getClosestInstanceFromNode(targetNode) { + var targetInst = targetNode[internalInstanceKey]; + if (targetInst) // Don't return HostRoot or SuspenseComponent here. + return targetInst; + // If the direct event target isn't a React owned DOM node, we need to look + // to see if one of its parents is a React owned DOM node. + var parentNode = targetNode.parentNode; + while(parentNode){ + // We'll check if this is a container root that could include + // React nodes in the future. We need to check this first because + // if we're a child of a dehydrated container, we need to first + // find that inner container before moving on to finding the parent + // instance. Note that we don't check this field on the targetNode + // itself because the fibers are conceptually between the container + // node and the first child. It isn't surrounding the container node. + // If it's not a container, we check if it's an instance. + targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey]; + if (targetInst) { + // Since this wasn't the direct target of the event, we might have + // stepped past dehydrated DOM nodes to get here. However they could + // also have been non-React nodes. We need to answer which one. + // If we the instance doesn't have any children, then there can't be + // a nested suspense boundary within it. So we can use this as a fast + // bailout. Most of the time, when people add non-React children to + // the tree, it is using a ref to a child-less DOM node. + // Normally we'd only need to check one of the fibers because if it + // has ever gone from having children to deleting them or vice versa + // it would have deleted the dehydrated boundary nested inside already. + // However, since the HostRoot starts out with an alternate it might + // have one on the alternate so we need to check in case this was a + // root. + var alternate = targetInst.alternate; + if (targetInst.child !== null || alternate !== null && alternate.child !== null) { + // Next we need to figure out if the node that skipped past is + // nested within a dehydrated boundary and if so, which one. + var suspenseInstance = getParentSuspenseInstance(targetNode); + while(suspenseInstance !== null){ + // We found a suspense instance. That means that we haven't + // hydrated it yet. Even though we leave the comments in the + // DOM after hydrating, and there are boundaries in the DOM + // that could already be hydrated, we wouldn't have found them + // through this pass since if the target is hydrated it would + // have had an internalInstanceKey on it. + // Let's get the fiber associated with the SuspenseComponent + // as the deepest instance. + var targetSuspenseInst = suspenseInstance[internalInstanceKey]; + if (targetSuspenseInst) return targetSuspenseInst; + // If we don't find a Fiber on the comment, it might be because + // we haven't gotten to hydrate it yet. There might still be a + // parent boundary that hasn't above this one so we need to find + // the outer most that is known. + suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent + // host component also hasn't hydrated yet. We can return it + // below since it will bail out on the isMounted check later. + } + } + return targetInst; + } + targetNode = parentNode; + parentNode = targetNode.parentNode; + } + return null; + } + /** + * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent + * instance, or null if the node was not rendered by this React. + */ function getInstanceFromNode(node) { + var inst = node[internalInstanceKey] || node[internalContainerInstanceKey]; + if (inst) { + if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) return inst; + else return null; + } + return null; + } + /** + * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding + * DOM node. + */ function getNodeFromInstance(inst) { + if (inst.tag === HostComponent || inst.tag === HostText) // In Fiber this, is just the state node right now. We assume it will be + // a host component or host text. + return inst.stateNode; + // Without this first invariant, passing a non-DOM-component triggers the next + // invariant for a missing parent, which is super confusing. + throw new Error("getNodeFromInstance: Invalid argument."); + } + function getFiberCurrentPropsFromNode(node) { + return node[internalPropsKey] || null; + } + function updateFiberProps(node, props) { + node[internalPropsKey] = props; + } + function getEventListenerSet(node) { + var elementListenerSet = node[internalEventHandlersKey]; + if (elementListenerSet === undefined) elementListenerSet = node[internalEventHandlersKey] = new Set(); + return elementListenerSet; + } + var loggedTypeFailures = {}; + var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; + function setCurrentlyValidatingElement(element) { + if (element) { + var owner = element._owner; + var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null); + ReactDebugCurrentFrame$1.setExtraStackFrame(stack); + } else ReactDebugCurrentFrame$1.setExtraStackFrame(null); + } + function checkPropTypes(typeSpecs, values, location, componentName, element) { + // $FlowFixMe This is okay but Flow doesn't know it. + var has = Function.call.bind(hasOwnProperty); + for(var typeSpecName in typeSpecs)if (has(typeSpecs, typeSpecName)) { + var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + if (typeof typeSpecs[typeSpecName] !== "function") { + // eslint-disable-next-line react-internal/prod-error-codes + var err = Error((componentName || "React class") + ": " + location + " type `" + typeSpecName + "` is invalid; " + "it must be a function, usually from the `prop-types` package, but received `" + typeof typeSpecs[typeSpecName] + "`." + "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`."); + err.name = "Invariant Violation"; + throw err; + } + error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"); + } catch (ex) { + error$1 = ex; + } + if (error$1 && !(error$1 instanceof Error)) { + setCurrentlyValidatingElement(element); + error("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", componentName || "React class", location, typeSpecName, typeof error$1); + setCurrentlyValidatingElement(null); + } + if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error$1.message] = true; + setCurrentlyValidatingElement(element); + error("Failed %s type: %s", location, error$1.message); + setCurrentlyValidatingElement(null); + } + } + } + var valueStack = []; + var fiberStack; + fiberStack = []; + var index = -1; + function createCursor(defaultValue) { + return { + current: defaultValue + }; + } + function pop(cursor, fiber) { + if (index < 0) { + error("Unexpected pop."); + return; + } + if (fiber !== fiberStack[index]) error("Unexpected Fiber popped."); + cursor.current = valueStack[index]; + valueStack[index] = null; + fiberStack[index] = null; + index--; + } + function push(cursor, value, fiber) { + index++; + valueStack[index] = cursor.current; + fiberStack[index] = fiber; + cursor.current = value; + } + var warnedAboutMissingGetChildContext; + warnedAboutMissingGetChildContext = {}; + var emptyContextObject = {}; + Object.freeze(emptyContextObject); + var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. + var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. + // We use this to get access to the parent context after we have already + // pushed the next context provider, and now need to merge their contexts. + var previousContext = emptyContextObject; + function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) { + if (didPushOwnContextIfProvider && isContextProvider(Component)) // If the fiber is a context provider itself, when we read its context + // we may have already pushed its own child context on the stack. A context + // provider should not "see" its own child context. Therefore we read the + // previous (parent) context instead for a context provider. + return previousContext; + return contextStackCursor.current; + } + function cacheContext(workInProgress, unmaskedContext, maskedContext) { + var instance = workInProgress.stateNode; + instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; + instance.__reactInternalMemoizedMaskedChildContext = maskedContext; + } + function getMaskedContext(workInProgress, unmaskedContext) { + var type = workInProgress.type; + var contextTypes = type.contextTypes; + if (!contextTypes) return emptyContextObject; + // Avoid recreating masked context unless unmasked context has changed. + // Failing to do this will result in unnecessary calls to componentWillReceiveProps. + // This may trigger infinite loops if componentWillReceiveProps calls setState. + var instance = workInProgress.stateNode; + if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) return instance.__reactInternalMemoizedMaskedChildContext; + var context = {}; + for(var key in contextTypes)context[key] = unmaskedContext[key]; + var name = getComponentNameFromFiber(workInProgress) || "Unknown"; + checkPropTypes(contextTypes, context, "context", name); + // Context is created before the class component is instantiated so check for instance. + if (instance) cacheContext(workInProgress, unmaskedContext, context); + return context; + } + function hasContextChanged() { + return didPerformWorkStackCursor.current; + } + function isContextProvider(type) { + var childContextTypes = type.childContextTypes; + return childContextTypes !== null && childContextTypes !== undefined; + } + function popContext(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); + } + function popTopLevelContextObject(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); + } + function pushTopLevelContextObject(fiber, context, didChange) { + if (contextStackCursor.current !== emptyContextObject) throw new Error("Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue."); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); + } + function processChildContext(fiber, type, parentContext) { + var instance = fiber.stateNode; + var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. + // It has only been added in Fiber to match the (unintentional) behavior in Stack. + if (typeof instance.getChildContext !== "function") { + var componentName = getComponentNameFromFiber(fiber) || "Unknown"; + if (!warnedAboutMissingGetChildContext[componentName]) { + warnedAboutMissingGetChildContext[componentName] = true; + error("%s.childContextTypes is specified but there is no getChildContext() method on the instance. You can either define getChildContext() on %s or remove childContextTypes from it.", componentName, componentName); + } + return parentContext; + } + var childContext = instance.getChildContext(); + for(var contextKey in childContext){ + if (!(contextKey in childContextTypes)) throw new Error((getComponentNameFromFiber(fiber) || "Unknown") + '.getChildContext(): key "' + contextKey + '" is not defined in childContextTypes.'); + } + var name = getComponentNameFromFiber(fiber) || "Unknown"; + checkPropTypes(childContextTypes, childContext, "child context", name); + return assign({}, parentContext, childContext); + } + function pushContextProvider(workInProgress) { + var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. + // If the instance does not exist yet, we will push null at first, + // and replace it on the stack later when invalidating the context. + var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later. + // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. + previousContext = contextStackCursor.current; + push(contextStackCursor, memoizedMergedChildContext, workInProgress); + push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress); + return true; + } + function invalidateContextProvider(workInProgress, type, didChange) { + var instance = workInProgress.stateNode; + if (!instance) throw new Error("Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue."); + if (didChange) { + // Merge parent and own context. + // Skip this if we're not updating due to sCU. + // This avoids unnecessarily recomputing memoized values. + var mergedContext = processChildContext(workInProgress, type, previousContext); + instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. + // It is important to unwind the context in the reverse order. + pop(didPerformWorkStackCursor, workInProgress); + pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. + push(contextStackCursor, mergedContext, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); + } else { + pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); + } + } + function findCurrentUnmaskedContext(fiber) { + // Currently this is only used with renderSubtreeIntoContainer; not sure if it + // makes sense elsewhere + if (!isFiberMounted(fiber) || fiber.tag !== ClassComponent) throw new Error("Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue."); + var node = fiber; + do { + switch(node.tag){ + case HostRoot: + return node.stateNode.context; + case ClassComponent: + var Component = node.type; + if (isContextProvider(Component)) return node.stateNode.__reactInternalMemoizedMergedChildContext; + break; + } + node = node.return; + }while (node !== null); + throw new Error("Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue."); + } + var LegacyRoot = 0; + var ConcurrentRoot = 1; + var syncQueue = null; + var includesLegacySyncCallbacks = false; + var isFlushingSyncQueue = false; + function scheduleSyncCallback(callback) { + // Push this callback into an internal queue. We'll flush these either in + // the next tick, or earlier if something calls `flushSyncCallbackQueue`. + if (syncQueue === null) syncQueue = [ + callback + ]; + else // Push onto existing queue. Don't need to schedule a callback because + // we already scheduled one when we created the queue. + syncQueue.push(callback); + } + function scheduleLegacySyncCallback(callback) { + includesLegacySyncCallbacks = true; + scheduleSyncCallback(callback); + } + function flushSyncCallbacksOnlyInLegacyMode() { + // Only flushes the queue if there's a legacy sync callback scheduled. + // TODO: There's only a single type of callback: performSyncOnWorkOnRoot. So + // it might make more sense for the queue to be a list of roots instead of a + // list of generic callbacks. Then we can have two: one for legacy roots, one + // for concurrent roots. And this method would only flush the legacy ones. + if (includesLegacySyncCallbacks) flushSyncCallbacks(); + } + function flushSyncCallbacks() { + if (!isFlushingSyncQueue && syncQueue !== null) { + // Prevent re-entrance. + isFlushingSyncQueue = true; + var i = 0; + var previousUpdatePriority = getCurrentUpdatePriority(); + try { + var isSync = true; + var queue = syncQueue; // TODO: Is this necessary anymore? The only user code that runs in this + // queue is in the render or commit phases. + setCurrentUpdatePriority(DiscreteEventPriority); + for(; i < queue.length; i++){ + var callback = queue[i]; + do callback = callback(isSync); + while (callback !== null); + } + syncQueue = null; + includesLegacySyncCallbacks = false; + } catch (error) { + // If something throws, leave the remaining callbacks on the queue. + if (syncQueue !== null) syncQueue = syncQueue.slice(i + 1); + // Resume flushing in the next tick + scheduleCallback(ImmediatePriority, flushSyncCallbacks); + throw error; + } finally{ + setCurrentUpdatePriority(previousUpdatePriority); + isFlushingSyncQueue = false; + } + } + return null; + } + // TODO: Use the unified fiber stack module instead of this local one? + // Intentionally not using it yet to derisk the initial implementation, because + // the way we push/pop these values is a bit unusual. If there's a mistake, I'd + // rather the ids be wrong than crash the whole reconciler. + var forkStack = []; + var forkStackIndex = 0; + var treeForkProvider = null; + var treeForkCount = 0; + var idStack = []; + var idStackIndex = 0; + var treeContextProvider = null; + var treeContextId = 1; + var treeContextOverflow = ""; + function isForkedChild(workInProgress) { + warnIfNotHydrating(); + return (workInProgress.flags & Forked) !== NoFlags; + } + function getForksAtLevel(workInProgress) { + warnIfNotHydrating(); + return treeForkCount; + } + function getTreeId() { + var overflow = treeContextOverflow; + var idWithLeadingBit = treeContextId; + var id = idWithLeadingBit & ~getLeadingBit(idWithLeadingBit); + return id.toString(32) + overflow; + } + function pushTreeFork(workInProgress, totalChildren) { + // This is called right after we reconcile an array (or iterator) of child + // fibers, because that's the only place where we know how many children in + // the whole set without doing extra work later, or storing addtional + // information on the fiber. + // + // That's why this function is separate from pushTreeId \u2014 it's called during + // the render phase of the fork parent, not the child, which is where we push + // the other context values. + // + // In the Fizz implementation this is much simpler because the child is + // rendered in the same callstack as the parent. + // + // It might be better to just add a `forks` field to the Fiber type. It would + // make this module simpler. + warnIfNotHydrating(); + forkStack[forkStackIndex++] = treeForkCount; + forkStack[forkStackIndex++] = treeForkProvider; + treeForkProvider = workInProgress; + treeForkCount = totalChildren; + } + function pushTreeId(workInProgress, totalChildren, index) { + warnIfNotHydrating(); + idStack[idStackIndex++] = treeContextId; + idStack[idStackIndex++] = treeContextOverflow; + idStack[idStackIndex++] = treeContextProvider; + treeContextProvider = workInProgress; + var baseIdWithLeadingBit = treeContextId; + var baseOverflow = treeContextOverflow; // The leftmost 1 marks the end of the sequence, non-inclusive. It's not part + // of the id; we use it to account for leading 0s. + var baseLength = getBitLength(baseIdWithLeadingBit) - 1; + var baseId = baseIdWithLeadingBit & ~(1 << baseLength); + var slot = index + 1; + var length = getBitLength(totalChildren) + baseLength; // 30 is the max length we can store without overflowing, taking into + // consideration the leading 1 we use to mark the end of the sequence. + if (length > 30) { + // We overflowed the bitwise-safe range. Fall back to slower algorithm. + // This branch assumes the length of the base id is greater than 5; it won't + // work for smaller ids, because you need 5 bits per character. + // + // We encode the id in multiple steps: first the base id, then the + // remaining digits. + // + // Each 5 bit sequence corresponds to a single base 32 character. So for + // example, if the current id is 23 bits long, we can convert 20 of those + // bits into a string of 4 characters, with 3 bits left over. + // + // First calculate how many bits in the base id represent a complete + // sequence of characters. + var numberOfOverflowBits = baseLength - baseLength % 5; // Then create a bitmask that selects only those bits. + var newOverflowBits = (1 << numberOfOverflowBits) - 1; // Select the bits, and convert them to a base 32 string. + var newOverflow = (baseId & newOverflowBits).toString(32); // Now we can remove those bits from the base id. + var restOfBaseId = baseId >> numberOfOverflowBits; + var restOfBaseLength = baseLength - numberOfOverflowBits; // Finally, encode the rest of the bits using the normal algorithm. Because + // we made more room, this time it won't overflow. + var restOfLength = getBitLength(totalChildren) + restOfBaseLength; + var restOfNewBits = slot << restOfBaseLength; + var id = restOfNewBits | restOfBaseId; + var overflow = newOverflow + baseOverflow; + treeContextId = 1 << restOfLength | id; + treeContextOverflow = overflow; + } else { + // Normal path + var newBits = slot << baseLength; + var _id = newBits | baseId; + var _overflow = baseOverflow; + treeContextId = 1 << length | _id; + treeContextOverflow = _overflow; + } + } + function pushMaterializedTreeId(workInProgress) { + warnIfNotHydrating(); // This component materialized an id. This will affect any ids that appear + // in its children. + var returnFiber = workInProgress.return; + if (returnFiber !== null) { + var numberOfForks = 1; + var slotIndex = 0; + pushTreeFork(workInProgress, numberOfForks); + pushTreeId(workInProgress, numberOfForks, slotIndex); + } + } + function getBitLength(number) { + return 32 - clz32(number); + } + function getLeadingBit(id) { + return 1 << getBitLength(id) - 1; + } + function popTreeContext(workInProgress) { + // Restore the previous values. + // This is a bit more complicated than other context-like modules in Fiber + // because the same Fiber may appear on the stack multiple times and for + // different reasons. We have to keep popping until the work-in-progress is + // no longer at the top of the stack. + while(workInProgress === treeForkProvider){ + treeForkProvider = forkStack[--forkStackIndex]; + forkStack[forkStackIndex] = null; + treeForkCount = forkStack[--forkStackIndex]; + forkStack[forkStackIndex] = null; + } + while(workInProgress === treeContextProvider){ + treeContextProvider = idStack[--idStackIndex]; + idStack[idStackIndex] = null; + treeContextOverflow = idStack[--idStackIndex]; + idStack[idStackIndex] = null; + treeContextId = idStack[--idStackIndex]; + idStack[idStackIndex] = null; + } + } + function getSuspendedTreeContext() { + warnIfNotHydrating(); + if (treeContextProvider !== null) return { + id: treeContextId, + overflow: treeContextOverflow + }; + else return null; + } + function restoreSuspendedTreeContext(workInProgress, suspendedContext) { + warnIfNotHydrating(); + idStack[idStackIndex++] = treeContextId; + idStack[idStackIndex++] = treeContextOverflow; + idStack[idStackIndex++] = treeContextProvider; + treeContextId = suspendedContext.id; + treeContextOverflow = suspendedContext.overflow; + treeContextProvider = workInProgress; + } + function warnIfNotHydrating() { + if (!getIsHydrating()) error("Expected to be hydrating. This is a bug in React. Please file an issue."); + } + // This may have been an insertion or a hydration. + var hydrationParentFiber = null; + var nextHydratableInstance = null; + var isHydrating = false; // This flag allows for warning supression when we expect there to be mismatches + // due to earlier mismatches or a suspended fiber. + var didSuspendOrErrorDEV = false; // Hydration errors that were thrown inside this boundary + var hydrationErrors = null; + function warnIfHydrating() { + if (isHydrating) error("We should not be hydrating here. This is a bug in React. Please file a bug."); + } + function markDidThrowWhileHydratingDEV() { + didSuspendOrErrorDEV = true; + } + function didSuspendOrErrorWhileHydratingDEV() { + return didSuspendOrErrorDEV; + } + function enterHydrationState(fiber) { + var parentInstance = fiber.stateNode.containerInfo; + nextHydratableInstance = getFirstHydratableChildWithinContainer(parentInstance); + hydrationParentFiber = fiber; + isHydrating = true; + hydrationErrors = null; + didSuspendOrErrorDEV = false; + return true; + } + function reenterHydrationStateFromDehydratedSuspenseInstance(fiber, suspenseInstance, treeContext) { + nextHydratableInstance = getFirstHydratableChildWithinSuspenseInstance(suspenseInstance); + hydrationParentFiber = fiber; + isHydrating = true; + hydrationErrors = null; + didSuspendOrErrorDEV = false; + if (treeContext !== null) restoreSuspendedTreeContext(fiber, treeContext); + return true; + } + function warnUnhydratedInstance(returnFiber, instance) { + switch(returnFiber.tag){ + case HostRoot: + didNotHydrateInstanceWithinContainer(returnFiber.stateNode.containerInfo, instance); + break; + case HostComponent: + var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode; + didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance, isConcurrentMode); + break; + case SuspenseComponent: + var suspenseState = returnFiber.memoizedState; + if (suspenseState.dehydrated !== null) didNotHydrateInstanceWithinSuspenseInstance(suspenseState.dehydrated, instance); + break; + } + } + function deleteHydratableInstance(returnFiber, instance) { + warnUnhydratedInstance(returnFiber, instance); + var childToDelete = createFiberFromHostInstanceForDeletion(); + childToDelete.stateNode = instance; + childToDelete.return = returnFiber; + var deletions = returnFiber.deletions; + if (deletions === null) { + returnFiber.deletions = [ + childToDelete + ]; + returnFiber.flags |= ChildDeletion; + } else deletions.push(childToDelete); + } + function warnNonhydratedInstance(returnFiber, fiber) { + if (didSuspendOrErrorDEV) // Inside a boundary that already suspended. We're currently rendering the + // siblings of a suspended node. The mismatch may be due to the missing + // data, so it's probably a false positive. + return; + switch(returnFiber.tag){ + case HostRoot: + var parentContainer = returnFiber.stateNode.containerInfo; + switch(fiber.tag){ + case HostComponent: + var type = fiber.type; + var props = fiber.pendingProps; + didNotFindHydratableInstanceWithinContainer(parentContainer, type); + break; + case HostText: + var text = fiber.pendingProps; + didNotFindHydratableTextInstanceWithinContainer(parentContainer, text); + break; + } + break; + case HostComponent: + var parentType = returnFiber.type; + var parentProps = returnFiber.memoizedProps; + var parentInstance = returnFiber.stateNode; + switch(fiber.tag){ + case HostComponent: + var _type = fiber.type; + var _props = fiber.pendingProps; + var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode; + didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props, isConcurrentMode); + break; + case HostText: + var _text = fiber.pendingProps; + var _isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode; + didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text, _isConcurrentMode); + break; + } + break; + case SuspenseComponent: + var suspenseState = returnFiber.memoizedState; + var _parentInstance = suspenseState.dehydrated; + if (_parentInstance !== null) switch(fiber.tag){ + case HostComponent: + var _type2 = fiber.type; + var _props2 = fiber.pendingProps; + didNotFindHydratableInstanceWithinSuspenseInstance(_parentInstance, _type2); + break; + case HostText: + var _text2 = fiber.pendingProps; + didNotFindHydratableTextInstanceWithinSuspenseInstance(_parentInstance, _text2); + break; + } + break; + default: + return; + } + } + function insertNonHydratedInstance(returnFiber, fiber) { + fiber.flags = fiber.flags & ~Hydrating | Placement; + warnNonhydratedInstance(returnFiber, fiber); + } + function tryHydrate(fiber, nextInstance) { + switch(fiber.tag){ + case HostComponent: + var type = fiber.type; + var props = fiber.pendingProps; + var instance = canHydrateInstance(nextInstance, type); + if (instance !== null) { + fiber.stateNode = instance; + hydrationParentFiber = fiber; + nextHydratableInstance = getFirstHydratableChild(instance); + return true; + } + return false; + case HostText: + var text = fiber.pendingProps; + var textInstance = canHydrateTextInstance(nextInstance, text); + if (textInstance !== null) { + fiber.stateNode = textInstance; + hydrationParentFiber = fiber; // Text Instances don't have children so there's nothing to hydrate. + nextHydratableInstance = null; + return true; + } + return false; + case SuspenseComponent: + var suspenseInstance = canHydrateSuspenseInstance(nextInstance); + if (suspenseInstance !== null) { + var suspenseState = { + dehydrated: suspenseInstance, + treeContext: getSuspendedTreeContext(), + retryLane: OffscreenLane + }; + fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber. + // This simplifies the code for getHostSibling and deleting nodes, + // since it doesn't have to consider all Suspense boundaries and + // check if they're dehydrated ones or not. + var dehydratedFragment = createFiberFromDehydratedFragment(suspenseInstance); + dehydratedFragment.return = fiber; + fiber.child = dehydratedFragment; + hydrationParentFiber = fiber; // While a Suspense Instance does have children, we won't step into + // it during the first pass. Instead, we'll reenter it later. + nextHydratableInstance = null; + return true; + } + return false; + default: + return false; + } + } + function shouldClientRenderOnMismatch(fiber) { + return (fiber.mode & ConcurrentMode) !== NoMode && (fiber.flags & DidCapture) === NoFlags; + } + function throwOnHydrationMismatch(fiber) { + throw new Error("Hydration failed because the initial UI does not match what was rendered on the server."); + } + function tryToClaimNextHydratableInstance(fiber) { + if (!isHydrating) return; + var nextInstance = nextHydratableInstance; + if (!nextInstance) { + if (shouldClientRenderOnMismatch(fiber)) { + warnNonhydratedInstance(hydrationParentFiber, fiber); + throwOnHydrationMismatch(); + } // Nothing to hydrate. Make it an insertion. + insertNonHydratedInstance(hydrationParentFiber, fiber); + isHydrating = false; + hydrationParentFiber = fiber; + return; + } + var firstAttemptedInstance = nextInstance; + if (!tryHydrate(fiber, nextInstance)) { + if (shouldClientRenderOnMismatch(fiber)) { + warnNonhydratedInstance(hydrationParentFiber, fiber); + throwOnHydrationMismatch(); + } // If we can't hydrate this instance let's try the next one. + // We use this as a heuristic. It's based on intuition and not data so it + // might be flawed or unnecessary. + nextInstance = getNextHydratableSibling(firstAttemptedInstance); + var prevHydrationParentFiber = hydrationParentFiber; + if (!nextInstance || !tryHydrate(fiber, nextInstance)) { + // Nothing to hydrate. Make it an insertion. + insertNonHydratedInstance(hydrationParentFiber, fiber); + isHydrating = false; + hydrationParentFiber = fiber; + return; + } // We matched the next one, we'll now assume that the first one was + // superfluous and we'll delete it. Since we can't eagerly delete it + // we'll have to schedule a deletion. To do that, this node needs a dummy + // fiber associated with it. + deleteHydratableInstance(prevHydrationParentFiber, firstAttemptedInstance); + } + } + function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) { + var instance = fiber.stateNode; + var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV; + var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber, shouldWarnIfMismatchDev); // TODO: Type this specific to this type of component. + fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there + // is a new ref we mark this as an update. + if (updatePayload !== null) return true; + return false; + } + function prepareToHydrateHostTextInstance(fiber) { + var textInstance = fiber.stateNode; + var textContent = fiber.memoizedProps; + var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber); + if (shouldUpdate) { + // We assume that prepareToHydrateHostTextInstance is called in a context where the + // hydration parent is the parent host component of this host text. + var returnFiber = hydrationParentFiber; + if (returnFiber !== null) switch(returnFiber.tag){ + case HostRoot: + var parentContainer = returnFiber.stateNode.containerInfo; + var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode; + didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent, isConcurrentMode); + break; + case HostComponent: + var parentType = returnFiber.type; + var parentProps = returnFiber.memoizedProps; + var parentInstance = returnFiber.stateNode; + var _isConcurrentMode2 = (returnFiber.mode & ConcurrentMode) !== NoMode; + didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent, _isConcurrentMode2); + break; + } + } + return shouldUpdate; + } + function prepareToHydrateHostSuspenseInstance(fiber) { + var suspenseState = fiber.memoizedState; + var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null; + if (!suspenseInstance) throw new Error("Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue."); + hydrateSuspenseInstance(suspenseInstance, fiber); + } + function skipPastDehydratedSuspenseInstance(fiber) { + var suspenseState = fiber.memoizedState; + var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null; + if (!suspenseInstance) throw new Error("Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue."); + return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance); + } + function popToNextHostParent(fiber) { + var parent = fiber.return; + while(parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent)parent = parent.return; + hydrationParentFiber = parent; + } + function popHydrationState(fiber) { + if (fiber !== hydrationParentFiber) // We're deeper than the current hydration context, inside an inserted + // tree. + return false; + if (!isHydrating) { + // If we're not currently hydrating but we're in a hydration context, then + // we were an insertion and now need to pop up reenter hydration of our + // siblings. + popToNextHostParent(fiber); + isHydrating = true; + return false; + } // If we have any remaining hydratable nodes, we need to delete them now. + // We only do this deeper than head and body since they tend to have random + // other nodes in them. We also ignore components with pure text content in + // side of them. We also don't delete anything inside the root container. + if (fiber.tag !== HostRoot && (fiber.tag !== HostComponent || shouldDeleteUnhydratedTailInstances(fiber.type) && !shouldSetTextContent(fiber.type, fiber.memoizedProps))) { + var nextInstance = nextHydratableInstance; + if (nextInstance) { + if (shouldClientRenderOnMismatch(fiber)) { + warnIfUnhydratedTailNodes(fiber); + throwOnHydrationMismatch(); + } else while(nextInstance){ + deleteHydratableInstance(fiber, nextInstance); + nextInstance = getNextHydratableSibling(nextInstance); + } + } + } + popToNextHostParent(fiber); + if (fiber.tag === SuspenseComponent) nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber); + else nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null; + return true; + } + function hasUnhydratedTailNodes() { + return isHydrating && nextHydratableInstance !== null; + } + function warnIfUnhydratedTailNodes(fiber) { + var nextInstance = nextHydratableInstance; + while(nextInstance){ + warnUnhydratedInstance(fiber, nextInstance); + nextInstance = getNextHydratableSibling(nextInstance); + } + } + function resetHydrationState() { + hydrationParentFiber = null; + nextHydratableInstance = null; + isHydrating = false; + didSuspendOrErrorDEV = false; + } + function upgradeHydrationErrorsToRecoverable() { + if (hydrationErrors !== null) { + // Successfully completed a forced client render. The errors that occurred + // during the hydration attempt are now recovered. We will log them in + // commit phase, once the entire tree has finished. + queueRecoverableErrors(hydrationErrors); + hydrationErrors = null; + } + } + function getIsHydrating() { + return isHydrating; + } + function queueHydrationError(error) { + if (hydrationErrors === null) hydrationErrors = [ + error + ]; + else hydrationErrors.push(error); + } + var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; + var NoTransition = null; + function requestCurrentTransition() { + return ReactCurrentBatchConfig$1.transition; + } + var ReactStrictModeWarnings = { + recordUnsafeLifecycleWarnings: function(fiber, instance) {}, + flushPendingUnsafeLifecycleWarnings: function() {}, + recordLegacyContextWarning: function(fiber, instance) {}, + flushLegacyContextWarning: function() {}, + discardPendingWarnings: function() {} + }; + var findStrictRoot = function(fiber) { + var maybeStrictRoot = null; + var node = fiber; + while(node !== null){ + if (node.mode & StrictLegacyMode) maybeStrictRoot = node; + node = node.return; + } + return maybeStrictRoot; + }; + var setToSortedString = function(set) { + var array = []; + set.forEach(function(value) { + array.push(value); + }); + return array.sort().join(", "); + }; + var pendingComponentWillMountWarnings = []; + var pendingUNSAFE_ComponentWillMountWarnings = []; + var pendingComponentWillReceivePropsWarnings = []; + var pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + var pendingComponentWillUpdateWarnings = []; + var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about. + var didWarnAboutUnsafeLifecycles = new Set(); + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function(fiber, instance) { + // Dedupe strategy: Warn once per component. + if (didWarnAboutUnsafeLifecycles.has(fiber.type)) return; + if (typeof instance.componentWillMount === "function" && // Don't warn about react-lifecycles-compat polyfilled components. + instance.componentWillMount.__suppressDeprecationWarning !== true) pendingComponentWillMountWarnings.push(fiber); + if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === "function") pendingUNSAFE_ComponentWillMountWarnings.push(fiber); + if (typeof instance.componentWillReceiveProps === "function" && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) pendingComponentWillReceivePropsWarnings.push(fiber); + if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === "function") pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); + if (typeof instance.componentWillUpdate === "function" && instance.componentWillUpdate.__suppressDeprecationWarning !== true) pendingComponentWillUpdateWarnings.push(fiber); + if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === "function") pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); + }; + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() { + // We do an initial pass to gather component names + var componentWillMountUniqueNames = new Set(); + if (pendingComponentWillMountWarnings.length > 0) { + pendingComponentWillMountWarnings.forEach(function(fiber) { + componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || "Component"); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillMountWarnings = []; + } + var UNSAFE_componentWillMountUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { + pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) { + UNSAFE_componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || "Component"); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillMountWarnings = []; + } + var componentWillReceivePropsUniqueNames = new Set(); + if (pendingComponentWillReceivePropsWarnings.length > 0) { + pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { + componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || "Component"); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillReceivePropsWarnings = []; + } + var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) { + UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || "Component"); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + } + var componentWillUpdateUniqueNames = new Set(); + if (pendingComponentWillUpdateWarnings.length > 0) { + pendingComponentWillUpdateWarnings.forEach(function(fiber) { + componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || "Component"); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillUpdateWarnings = []; + } + var UNSAFE_componentWillUpdateUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { + pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) { + UNSAFE_componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || "Component"); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillUpdateWarnings = []; + } // Finally, we flush all the warnings + // UNSAFE_ ones before the deprecated ones, since they'll be 'louder' + if (UNSAFE_componentWillMountUniqueNames.size > 0) { + var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); + error("Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move code with side effects to componentDidMount, and set initial state in the constructor.\n\nPlease update the following components: %s", sortedNames); + } + if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames); + error("Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n\nPlease update the following components: %s", _sortedNames); + } + if (UNSAFE_componentWillUpdateUniqueNames.size > 0) { + var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames); + error("Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n\nPlease update the following components: %s", _sortedNames2); + } + if (componentWillMountUniqueNames.size > 0) { + var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); + warn("componentWillMount has been renamed, and is not recommended for use. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move code with side effects to componentDidMount, and set initial state in the constructor.\n* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", _sortedNames3); + } + if (componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames); + warn("componentWillReceiveProps has been renamed, and is not recommended for use. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", _sortedNames4); + } + if (componentWillUpdateUniqueNames.size > 0) { + var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); + warn("componentWillUpdate has been renamed, and is not recommended for use. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", _sortedNames5); + } + }; + var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about. + var didWarnAboutLegacyContext = new Set(); + ReactStrictModeWarnings.recordLegacyContextWarning = function(fiber, instance) { + var strictRoot = findStrictRoot(fiber); + if (strictRoot === null) { + error("Expected to find a StrictMode component in a strict mode tree. This error is likely caused by a bug in React. Please file an issue."); + return; + } // Dedup strategy: Warn once per component. + if (didWarnAboutLegacyContext.has(fiber.type)) return; + var warningsForRoot = pendingLegacyContextWarning.get(strictRoot); + if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === "function") { + if (warningsForRoot === undefined) { + warningsForRoot = []; + pendingLegacyContextWarning.set(strictRoot, warningsForRoot); + } + warningsForRoot.push(fiber); + } + }; + ReactStrictModeWarnings.flushLegacyContextWarning = function() { + pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { + if (fiberArray.length === 0) return; + var firstFiber = fiberArray[0]; + var uniqueNames = new Set(); + fiberArray.forEach(function(fiber) { + uniqueNames.add(getComponentNameFromFiber(fiber) || "Component"); + didWarnAboutLegacyContext.add(fiber.type); + }); + var sortedNames = setToSortedString(uniqueNames); + try { + setCurrentFiber(firstFiber); + error("Legacy context API has been detected within a strict-mode tree.\n\nThe old API will be supported in all 16.x releases, but applications using it should migrate to the new version.\n\nPlease update the following components: %s\n\nLearn more about this warning here: https://reactjs.org/link/legacy-context", sortedNames); + } finally{ + resetCurrentFiber(); + } + }); + }; + ReactStrictModeWarnings.discardPendingWarnings = function() { + pendingComponentWillMountWarnings = []; + pendingUNSAFE_ComponentWillMountWarnings = []; + pendingComponentWillReceivePropsWarnings = []; + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + pendingComponentWillUpdateWarnings = []; + pendingUNSAFE_ComponentWillUpdateWarnings = []; + pendingLegacyContextWarning = new Map(); + }; + function resolveDefaultProps(Component, baseProps) { + if (Component && Component.defaultProps) { + // Resolve default props. Taken from ReactElement + var props = assign({}, baseProps); + var defaultProps = Component.defaultProps; + for(var propName in defaultProps)if (props[propName] === undefined) props[propName] = defaultProps[propName]; + return props; + } + return baseProps; + } + var valueCursor = createCursor(null); + var rendererSigil; + // Use this to detect multiple renderers using the same context + rendererSigil = {}; + var currentlyRenderingFiber = null; + var lastContextDependency = null; + var lastFullyObservedContext = null; + var isDisallowedContextReadInDEV = false; + function resetContextDependencies() { + // This is called right before React yields execution, to ensure `readContext` + // cannot be called outside the render phase. + currentlyRenderingFiber = null; + lastContextDependency = null; + lastFullyObservedContext = null; + isDisallowedContextReadInDEV = false; + } + function enterDisallowedContextReadInDEV() { + isDisallowedContextReadInDEV = true; + } + function exitDisallowedContextReadInDEV() { + isDisallowedContextReadInDEV = false; + } + function pushProvider(providerFiber, context, nextValue) { + push(valueCursor, context._currentValue, providerFiber); + context._currentValue = nextValue; + if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) error("Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported."); + context._currentRenderer = rendererSigil; + } + function popProvider(context, providerFiber) { + var currentValue = valueCursor.current; + pop(valueCursor, providerFiber); + context._currentValue = currentValue; + } + function scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) { + // Update the child lanes of all the ancestors, including the alternates. + var node = parent; + while(node !== null){ + var alternate = node.alternate; + if (!isSubsetOfLanes(node.childLanes, renderLanes)) { + node.childLanes = mergeLanes(node.childLanes, renderLanes); + if (alternate !== null) alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes); + } else if (alternate !== null && !isSubsetOfLanes(alternate.childLanes, renderLanes)) alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes); + if (node === propagationRoot) break; + node = node.return; + } + if (node !== propagationRoot) error("Expected to find the propagation root when scheduling context work. This error is likely caused by a bug in React. Please file an issue."); + } + function propagateContextChange(workInProgress, context, renderLanes) { + propagateContextChange_eager(workInProgress, context, renderLanes); + } + function propagateContextChange_eager(workInProgress, context, renderLanes) { + var fiber = workInProgress.child; + if (fiber !== null) // Set the return pointer of the child to the work-in-progress fiber. + fiber.return = workInProgress; + while(fiber !== null){ + var nextFiber = void 0; // Visit this fiber. + var list = fiber.dependencies; + if (list !== null) { + nextFiber = fiber.child; + var dependency = list.firstContext; + while(dependency !== null){ + // Check if the context matches. + if (dependency.context === context) { + // Match! Schedule an update on this fiber. + if (fiber.tag === ClassComponent) { + // Schedule a force update on the work-in-progress. + var lane = pickArbitraryLane(renderLanes); + var update = createUpdate(NoTimestamp, lane); + update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the + // update to the current fiber, too, which means it will persist even if + // this render is thrown away. Since it's a race condition, not sure it's + // worth fixing. + // Inlined `enqueueUpdate` to remove interleaved update check + var updateQueue = fiber.updateQueue; + if (updateQueue === null) ; + else { + var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; + if (pending === null) // This is the first update. Create a circular list. + update.next = update; + else { + update.next = pending.next; + pending.next = update; + } + sharedQueue.pending = update; + } + } + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; + if (alternate !== null) alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + scheduleContextWorkOnParentPath(fiber.return, renderLanes, workInProgress); // Mark the updated lanes on the list, too. + list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the + break; + } + dependency = dependency.next; + } + } else if (fiber.tag === ContextProvider) // Don't scan deeper if this is a matching provider + nextFiber = fiber.type === workInProgress.type ? null : fiber.child; + else if (fiber.tag === DehydratedFragment) { + // If a dehydrated suspense boundary is in this subtree, we don't know + // if it will have any context consumers in it. The best we can do is + // mark it as having updates. + var parentSuspense = fiber.return; + if (parentSuspense === null) throw new Error("We just came from a parent so we must have had a parent. This is a bug in React."); + parentSuspense.lanes = mergeLanes(parentSuspense.lanes, renderLanes); + var _alternate = parentSuspense.alternate; + if (_alternate !== null) _alternate.lanes = mergeLanes(_alternate.lanes, renderLanes); + // This is intentionally passing this fiber as the parent + // because we want to schedule this fiber as having work + // on its children. We'll use the childLanes on + // this fiber to indicate that a context has changed. + scheduleContextWorkOnParentPath(parentSuspense, renderLanes, workInProgress); + nextFiber = fiber.sibling; + } else // Traverse down. + nextFiber = fiber.child; + if (nextFiber !== null) // Set the return pointer of the child to the work-in-progress fiber. + nextFiber.return = fiber; + else { + // No child. Traverse to next sibling. + nextFiber = fiber; + while(nextFiber !== null){ + if (nextFiber === workInProgress) { + // We're back to the root of this subtree. Exit. + nextFiber = null; + break; + } + var sibling = nextFiber.sibling; + if (sibling !== null) { + // Set the return pointer of the sibling to the work-in-progress fiber. + sibling.return = nextFiber.return; + nextFiber = sibling; + break; + } // No more siblings. Traverse up. + nextFiber = nextFiber.return; + } + } + fiber = nextFiber; + } + } + function prepareToReadContext(workInProgress, renderLanes) { + currentlyRenderingFiber = workInProgress; + lastContextDependency = null; + lastFullyObservedContext = null; + var dependencies = workInProgress.dependencies; + if (dependencies !== null) { + var firstContext = dependencies.firstContext; + if (firstContext !== null) { + if (includesSomeLane(dependencies.lanes, renderLanes)) // Context list has a pending update. Mark that this fiber performed work. + markWorkInProgressReceivedUpdate(); + // Reset the work-in-progress list + dependencies.firstContext = null; + } + } + } + function readContext(context) { + // This warning would fire if you read context inside a Hook like useMemo. + // Unlike the class check below, it's not enforced in production for perf. + if (isDisallowedContextReadInDEV) error("Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()."); + var value = context._currentValue; + if (lastFullyObservedContext === context) ; + else { + var contextItem = { + context: context, + memoizedValue: value, + next: null + }; + if (lastContextDependency === null) { + if (currentlyRenderingFiber === null) throw new Error("Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()."); + // This is the first dependency for this component. Create a new list. + lastContextDependency = contextItem; + currentlyRenderingFiber.dependencies = { + lanes: NoLanes, + firstContext: contextItem + }; + } else // Append a new context item. + lastContextDependency = lastContextDependency.next = contextItem; + } + return value; + } + // render. When this render exits, either because it finishes or because it is + // interrupted, the interleaved updates will be transferred onto the main part + // of the queue. + var concurrentQueues = null; + function pushConcurrentUpdateQueue(queue) { + if (concurrentQueues === null) concurrentQueues = [ + queue + ]; + else concurrentQueues.push(queue); + } + function finishQueueingConcurrentUpdates() { + // Transfer the interleaved updates onto the main queue. Each queue has a + // `pending` field and an `interleaved` field. When they are not null, they + // point to the last node in a circular linked list. We need to append the + // interleaved list to the end of the pending list by joining them into a + // single, circular list. + if (concurrentQueues !== null) { + for(var i = 0; i < concurrentQueues.length; i++){ + var queue = concurrentQueues[i]; + var lastInterleavedUpdate = queue.interleaved; + if (lastInterleavedUpdate !== null) { + queue.interleaved = null; + var firstInterleavedUpdate = lastInterleavedUpdate.next; + var lastPendingUpdate = queue.pending; + if (lastPendingUpdate !== null) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = firstInterleavedUpdate; + lastInterleavedUpdate.next = firstPendingUpdate; + } + queue.pending = lastInterleavedUpdate; + } + } + concurrentQueues = null; + } + } + function enqueueConcurrentHookUpdate(fiber, queue, update, lane) { + var interleaved = queue.interleaved; + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transferred to the pending queue. + pushConcurrentUpdateQueue(queue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + queue.interleaved = update; + return markUpdateLaneFromFiberToRoot(fiber, lane); + } + function enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update, lane) { + var interleaved = queue.interleaved; + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transferred to the pending queue. + pushConcurrentUpdateQueue(queue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + queue.interleaved = update; + } + function enqueueConcurrentClassUpdate(fiber, queue, update, lane) { + var interleaved = queue.interleaved; + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transferred to the pending queue. + pushConcurrentUpdateQueue(queue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + queue.interleaved = update; + return markUpdateLaneFromFiberToRoot(fiber, lane); + } + function enqueueConcurrentRenderForLane(fiber, lane) { + return markUpdateLaneFromFiberToRoot(fiber, lane); + } // Calling this function outside this module should only be done for backwards + // compatibility and should always be accompanied by a warning. + var unsafe_markUpdateLaneFromFiberToRoot = markUpdateLaneFromFiberToRoot; + function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { + // Update the source fiber's lanes + sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane); + var alternate = sourceFiber.alternate; + if (alternate !== null) alternate.lanes = mergeLanes(alternate.lanes, lane); + if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); + var node = sourceFiber; + var parent = sourceFiber.return; + while(parent !== null){ + parent.childLanes = mergeLanes(parent.childLanes, lane); + alternate = parent.alternate; + if (alternate !== null) alternate.childLanes = mergeLanes(alternate.childLanes, lane); + else if ((parent.flags & (Placement | Hydrating)) !== NoFlags) warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); + node = parent; + parent = parent.return; + } + if (node.tag === HostRoot) { + var root = node.stateNode; + return root; + } else return null; + } + var UpdateState = 0; + var ReplaceState = 1; + var ForceUpdate = 2; + var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`. + // It should only be read right after calling `processUpdateQueue`, via + // `checkHasForceUpdateAfterProcessing`. + var hasForceUpdate = false; + var didWarnUpdateInsideUpdate; + var currentlyProcessingQueue; + didWarnUpdateInsideUpdate = false; + currentlyProcessingQueue = null; + function initializeUpdateQueue(fiber) { + var queue = { + baseState: fiber.memoizedState, + firstBaseUpdate: null, + lastBaseUpdate: null, + shared: { + pending: null, + interleaved: null, + lanes: NoLanes + }, + effects: null + }; + fiber.updateQueue = queue; + } + function cloneUpdateQueue(current, workInProgress) { + // Clone the update queue from current. Unless it's already a clone. + var queue = workInProgress.updateQueue; + var currentQueue = current.updateQueue; + if (queue === currentQueue) { + var clone = { + baseState: currentQueue.baseState, + firstBaseUpdate: currentQueue.firstBaseUpdate, + lastBaseUpdate: currentQueue.lastBaseUpdate, + shared: currentQueue.shared, + effects: currentQueue.effects + }; + workInProgress.updateQueue = clone; + } + } + function createUpdate(eventTime, lane) { + var update = { + eventTime: eventTime, + lane: lane, + tag: UpdateState, + payload: null, + callback: null, + next: null + }; + return update; + } + function enqueueUpdate(fiber, update, lane) { + var updateQueue = fiber.updateQueue; + if (updateQueue === null) // Only occurs if the fiber has been unmounted. + return null; + var sharedQueue = updateQueue.shared; + if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) { + error("An update (setState, replaceState, or forceUpdate) was scheduled from inside an update function. Update functions should be pure, with zero side-effects. Consider using componentDidUpdate or a callback."); + didWarnUpdateInsideUpdate = true; + } + if (isUnsafeClassRenderPhaseUpdate()) { + // This is an unsafe render phase update. Add directly to the update + // queue so we can process it immediately during the current render. + var pending = sharedQueue.pending; + if (pending === null) // This is the first update. Create a circular list. + update.next = update; + else { + update.next = pending.next; + pending.next = update; + } + sharedQueue.pending = update; // Update the childLanes even though we're most likely already rendering + // this fiber. This is for backwards compatibility in the case where you + // update a different component during render phase than the one that is + // currently renderings (a pattern that is accompanied by a warning). + return unsafe_markUpdateLaneFromFiberToRoot(fiber, lane); + } else return enqueueConcurrentClassUpdate(fiber, sharedQueue, update, lane); + } + function entangleTransitions(root, fiber, lane) { + var updateQueue = fiber.updateQueue; + if (updateQueue === null) // Only occurs if the fiber has been unmounted. + return; + var sharedQueue = updateQueue.shared; + if (isTransitionLane(lane)) { + var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must + // have finished. We can remove them from the shared queue, which represents + // a superset of the actually pending lanes. In some cases we may entangle + // more than we need to, but that's OK. In fact it's worse if we *don't* + // entangle when we should. + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + var newQueueLanes = mergeLanes(queueLanes, lane); + sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + markRootEntangled(root, newQueueLanes); + } + } + function enqueueCapturedUpdate(workInProgress, capturedUpdate) { + // Captured updates are updates that are thrown by a child during the render + // phase. They should be discarded if the render is aborted. Therefore, + // we should only put them on the work-in-progress queue, not the current one. + var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone. + var current = workInProgress.alternate; + if (current !== null) { + var currentQueue = current.updateQueue; + if (queue === currentQueue) { + // The work-in-progress queue is the same as current. This happens when + // we bail out on a parent fiber that then captures an error thrown by + // a child. Since we want to append the update only to the work-in + // -progress queue, we need to clone the updates. We usually clone during + // processUpdateQueue, but that didn't happen in this case because we + // skipped over the parent when we bailed out. + var newFirst = null; + var newLast = null; + var firstBaseUpdate = queue.firstBaseUpdate; + if (firstBaseUpdate !== null) { + // Loop through the updates and clone them. + var update = firstBaseUpdate; + do { + var clone = { + eventTime: update.eventTime, + lane: update.lane, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + if (newLast === null) newFirst = newLast = clone; + else { + newLast.next = clone; + newLast = clone; + } + update = update.next; + }while (update !== null); // Append the captured update the end of the cloned list. + if (newLast === null) newFirst = newLast = capturedUpdate; + else { + newLast.next = capturedUpdate; + newLast = capturedUpdate; + } + } else // There are no base updates. + newFirst = newLast = capturedUpdate; + queue = { + baseState: currentQueue.baseState, + firstBaseUpdate: newFirst, + lastBaseUpdate: newLast, + shared: currentQueue.shared, + effects: currentQueue.effects + }; + workInProgress.updateQueue = queue; + return; + } + } // Append the update to the end of the list. + var lastBaseUpdate = queue.lastBaseUpdate; + if (lastBaseUpdate === null) queue.firstBaseUpdate = capturedUpdate; + else lastBaseUpdate.next = capturedUpdate; + queue.lastBaseUpdate = capturedUpdate; + } + function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) { + switch(update.tag){ + case ReplaceState: + var payload = update.payload; + if (typeof payload === "function") { + enterDisallowedContextReadInDEV(); + var nextState = payload.call(instance, prevState, nextProps); + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + try { + payload.call(instance, prevState, nextProps); + } finally{ + setIsStrictModeForDevtools(false); + } + } + exitDisallowedContextReadInDEV(); + return nextState; + } // State object + return payload; + case CaptureUpdate: + workInProgress.flags = workInProgress.flags & ~ShouldCapture | DidCapture; + // Intentional fallthrough + case UpdateState: + var _payload = update.payload; + var partialState; + if (typeof _payload === "function") { + enterDisallowedContextReadInDEV(); + partialState = _payload.call(instance, prevState, nextProps); + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + try { + _payload.call(instance, prevState, nextProps); + } finally{ + setIsStrictModeForDevtools(false); + } + } + exitDisallowedContextReadInDEV(); + } else // Partial state object + partialState = _payload; + if (partialState === null || partialState === undefined) // Null and undefined are treated as no-ops. + return prevState; + // Merge the partial state and the previous state. + return assign({}, prevState, partialState); + case ForceUpdate: + hasForceUpdate = true; + return prevState; + } + return prevState; + } + function processUpdateQueue(workInProgress, props, instance, renderLanes) { + // This is always non-null on a ClassComponent or HostRoot + var queue = workInProgress.updateQueue; + hasForceUpdate = false; + currentlyProcessingQueue = queue.shared; + var firstBaseUpdate = queue.firstBaseUpdate; + var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue. + var pendingQueue = queue.shared.pending; + if (pendingQueue !== null) { + queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first + // and last so that it's non-circular. + var lastPendingUpdate = pendingQueue; + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = null; // Append pending updates to base queue + if (lastBaseUpdate === null) firstBaseUpdate = firstPendingUpdate; + else lastBaseUpdate.next = firstPendingUpdate; + lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then + // we need to transfer the updates to that queue, too. Because the base + // queue is a singly-linked list with no cycles, we can append to both + // lists and take advantage of structural sharing. + // TODO: Pass `current` as argument + var current = workInProgress.alternate; + if (current !== null) { + // This is always non-null on a ClassComponent or HostRoot + var currentQueue = current.updateQueue; + var currentLastBaseUpdate = currentQueue.lastBaseUpdate; + if (currentLastBaseUpdate !== lastBaseUpdate) { + if (currentLastBaseUpdate === null) currentQueue.firstBaseUpdate = firstPendingUpdate; + else currentLastBaseUpdate.next = firstPendingUpdate; + currentQueue.lastBaseUpdate = lastPendingUpdate; + } + } + } // These values may change as we process the queue. + if (firstBaseUpdate !== null) { + // Iterate through the list of updates to compute the result. + var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes + // from the original lanes. + var newLanes = NoLanes; + var newBaseState = null; + var newFirstBaseUpdate = null; + var newLastBaseUpdate = null; + var update = firstBaseUpdate; + do { + var updateLane = update.lane; + var updateEventTime = update.eventTime; + if (!isSubsetOfLanes(renderLanes, updateLane)) { + // Priority is insufficient. Skip this update. If this is the first + // skipped update, the previous update/state is the new base + // update/state. + var clone = { + eventTime: updateEventTime, + lane: updateLane, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + if (newLastBaseUpdate === null) { + newFirstBaseUpdate = newLastBaseUpdate = clone; + newBaseState = newState; + } else newLastBaseUpdate = newLastBaseUpdate.next = clone; + // Update the remaining priority in the queue. + newLanes = mergeLanes(newLanes, updateLane); + } else { + // This update does have sufficient priority. + if (newLastBaseUpdate !== null) { + var _clone = { + eventTime: updateEventTime, + // This update is going to be committed so we never want uncommit + // it. Using NoLane works because 0 is a subset of all bitmasks, so + // this will never be skipped by the check above. + lane: NoLane, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + newLastBaseUpdate = newLastBaseUpdate.next = _clone; + } // Process this update. + newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance); + var callback = update.callback; + if (callback !== null && // If the update was already committed, we should not queue its + // callback again. + update.lane !== NoLane) { + workInProgress.flags |= Callback; + var effects = queue.effects; + if (effects === null) queue.effects = [ + update + ]; + else effects.push(update); + } + } + update = update.next; + if (update === null) { + pendingQueue = queue.shared.pending; + if (pendingQueue === null) break; + else { + // An update was scheduled from inside a reducer. Add the new + // pending updates to the end of the list and keep processing. + var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we + // unravel them when transferring them to the base queue. + var _firstPendingUpdate = _lastPendingUpdate.next; + _lastPendingUpdate.next = null; + update = _firstPendingUpdate; + queue.lastBaseUpdate = _lastPendingUpdate; + queue.shared.pending = null; + } + } + }while (true); + if (newLastBaseUpdate === null) newBaseState = newState; + queue.baseState = newBaseState; + queue.firstBaseUpdate = newFirstBaseUpdate; + queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + var lastInterleaved = queue.shared.interleaved; + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + do { + newLanes = mergeLanes(newLanes, interleaved.lane); + interleaved = interleaved.next; + }while (interleaved !== lastInterleaved); + } else if (firstBaseUpdate === null) // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.shared.lanes = NoLanes; + // Set the remaining expiration time to be whatever is remaining in the queue. + // This should be fine because the only two other things that contribute to + // expiration time are props and context. We're already in the middle of the + // begin phase by the time we start processing the queue, so we've already + // dealt with the props. Context in components that specify + // shouldComponentUpdate is tricky; but we'll have to account for + // that regardless. + markSkippedUpdateLanes(newLanes); + workInProgress.lanes = newLanes; + workInProgress.memoizedState = newState; + } + currentlyProcessingQueue = null; + } + function callCallback(callback, context) { + if (typeof callback !== "function") throw new Error("Invalid argument passed as callback. Expected a function. Instead " + ("received: " + callback)); + callback.call(context); + } + function resetHasForceUpdateBeforeProcessing() { + hasForceUpdate = false; + } + function checkHasForceUpdateAfterProcessing() { + return hasForceUpdate; + } + function commitUpdateQueue(finishedWork, finishedQueue, instance) { + // Commit the effects + var effects = finishedQueue.effects; + finishedQueue.effects = null; + if (effects !== null) for(var i = 0; i < effects.length; i++){ + var effect = effects[i]; + var callback = effect.callback; + if (callback !== null) { + effect.callback = null; + callCallback(callback, instance); + } + } + } + var fakeInternalInstance = {}; // React.Component uses a shared frozen object by default. + // We'll use it to determine whether we need to initialize legacy refs. + var emptyRefsObject = new React.Component().refs; + var didWarnAboutStateAssignmentForComponent; + var didWarnAboutUninitializedState; + var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate; + var didWarnAboutLegacyLifecyclesAndDerivedState; + var didWarnAboutUndefinedDerivedState; + var warnOnUndefinedDerivedState; + var warnOnInvalidCallback; + var didWarnAboutDirectlyAssigningPropsToState; + var didWarnAboutContextTypeAndContextTypes; + var didWarnAboutInvalidateContextType; + didWarnAboutStateAssignmentForComponent = new Set(); + didWarnAboutUninitializedState = new Set(); + didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); + didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); + didWarnAboutDirectlyAssigningPropsToState = new Set(); + didWarnAboutUndefinedDerivedState = new Set(); + didWarnAboutContextTypeAndContextTypes = new Set(); + didWarnAboutInvalidateContextType = new Set(); + var didWarnOnInvalidCallback = new Set(); + warnOnInvalidCallback = function(callback, callerName) { + if (callback === null || typeof callback === "function") return; + var key = callerName + "_" + callback; + if (!didWarnOnInvalidCallback.has(key)) { + didWarnOnInvalidCallback.add(key); + error("%s(...): Expected the last optional `callback` argument to be a function. Instead received: %s.", callerName, callback); + } + }; + warnOnUndefinedDerivedState = function(type, partialState) { + if (partialState === undefined) { + var componentName = getComponentNameFromType(type) || "Component"; + if (!didWarnAboutUndefinedDerivedState.has(componentName)) { + didWarnAboutUndefinedDerivedState.add(componentName); + error("%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. You have returned undefined.", componentName); + } + } + }; // This is so gross but it's at least non-critical and can be removed if + // it causes problems. This is meant to give a nicer error message for + // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component, + // ...)) which otherwise throws a "_processChildContext is not a function" + // exception. + Object.defineProperty(fakeInternalInstance, "_processChildContext", { + enumerable: false, + value: function() { + throw new Error("_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)."); + } + }); + Object.freeze(fakeInternalInstance); + function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) { + var prevState = workInProgress.memoizedState; + var partialState = getDerivedStateFromProps(nextProps, prevState); + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + try { + // Invoke the function an extra time to help detect side-effects. + partialState = getDerivedStateFromProps(nextProps, prevState); + } finally{ + setIsStrictModeForDevtools(false); + } + } + warnOnUndefinedDerivedState(ctor, partialState); + var memoizedState = partialState === null || partialState === undefined ? prevState : assign({}, prevState, partialState); + workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the + // base state. + if (workInProgress.lanes === NoLanes) { + // Queue is always non-null for classes + var updateQueue = workInProgress.updateQueue; + updateQueue.baseState = memoizedState; + } + } + var classComponentUpdater = { + isMounted: isMounted, + enqueueSetState: function(inst, payload, callback) { + var fiber = get(inst); + var eventTime = requestEventTime(); + var lane = requestUpdateLane(fiber); + var update = createUpdate(eventTime, lane); + update.payload = payload; + if (callback !== undefined && callback !== null) { + warnOnInvalidCallback(callback, "setState"); + update.callback = callback; + } + var root = enqueueUpdate(fiber, update, lane); + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, lane, eventTime); + entangleTransitions(root, fiber, lane); + } + markStateUpdateScheduled(fiber, lane); + }, + enqueueReplaceState: function(inst, payload, callback) { + var fiber = get(inst); + var eventTime = requestEventTime(); + var lane = requestUpdateLane(fiber); + var update = createUpdate(eventTime, lane); + update.tag = ReplaceState; + update.payload = payload; + if (callback !== undefined && callback !== null) { + warnOnInvalidCallback(callback, "replaceState"); + update.callback = callback; + } + var root = enqueueUpdate(fiber, update, lane); + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, lane, eventTime); + entangleTransitions(root, fiber, lane); + } + markStateUpdateScheduled(fiber, lane); + }, + enqueueForceUpdate: function(inst, callback) { + var fiber = get(inst); + var eventTime = requestEventTime(); + var lane = requestUpdateLane(fiber); + var update = createUpdate(eventTime, lane); + update.tag = ForceUpdate; + if (callback !== undefined && callback !== null) { + warnOnInvalidCallback(callback, "forceUpdate"); + update.callback = callback; + } + var root = enqueueUpdate(fiber, update, lane); + if (root !== null) { + scheduleUpdateOnFiber(root, fiber, lane, eventTime); + entangleTransitions(root, fiber, lane); + } + markForceUpdateScheduled(fiber, lane); + } + }; + function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) { + var instance = workInProgress.stateNode; + if (typeof instance.shouldComponentUpdate === "function") { + var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext); + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + try { + // Invoke the function an extra time to help detect side-effects. + shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext); + } finally{ + setIsStrictModeForDevtools(false); + } + } + if (shouldUpdate === undefined) error("%s.shouldComponentUpdate(): Returned undefined instead of a boolean value. Make sure to return true or false.", getComponentNameFromType(ctor) || "Component"); + return shouldUpdate; + } + if (ctor.prototype && ctor.prototype.isPureReactComponent) return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState); + return true; + } + function checkClassInstance(workInProgress, ctor, newProps) { + var instance = workInProgress.stateNode; + var name = getComponentNameFromType(ctor) || "Component"; + var renderPresent = instance.render; + if (!renderPresent) { + if (ctor.prototype && typeof ctor.prototype.render === "function") error("%s(...): No `render` method found on the returned component instance: did you accidentally return an object from the constructor?", name); + else error("%s(...): No `render` method found on the returned component instance: you may have forgotten to define `render`.", name); + } + if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) error("getInitialState was defined on %s, a plain JavaScript class. This is only supported for classes created using React.createClass. Did you mean to define a state property instead?", name); + if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) error("getDefaultProps was defined on %s, a plain JavaScript class. This is only supported for classes created using React.createClass. Use a static property to define defaultProps instead.", name); + if (instance.propTypes) error("propTypes was defined as an instance property on %s. Use a static property to define propTypes instead.", name); + if (instance.contextType) error("contextType was defined as an instance property on %s. Use a static property to define contextType instead.", name); + if (instance.contextTypes) error("contextTypes was defined as an instance property on %s. Use a static property to define contextTypes instead.", name); + if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) { + didWarnAboutContextTypeAndContextTypes.add(ctor); + error("%s declares both contextTypes and contextType static properties. The legacy contextTypes property will be ignored.", name); + } + if (typeof instance.componentShouldUpdate === "function") error("%s has a method called componentShouldUpdate(). Did you mean shouldComponentUpdate()? The name is phrased as a question because the function is expected to return a value.", name); + if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined") error("%s has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.", getComponentNameFromType(ctor) || "A pure component"); + if (typeof instance.componentDidUnmount === "function") error("%s has a method called componentDidUnmount(). But there is no such lifecycle method. Did you mean componentWillUnmount()?", name); + if (typeof instance.componentDidReceiveProps === "function") error("%s has a method called componentDidReceiveProps(). But there is no such lifecycle method. If you meant to update the state in response to changing props, use componentWillReceiveProps(). If you meant to fetch data or run side-effects or mutations after React has updated the UI, use componentDidUpdate().", name); + if (typeof instance.componentWillRecieveProps === "function") error("%s has a method called componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", name); + if (typeof instance.UNSAFE_componentWillRecieveProps === "function") error("%s has a method called UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", name); + var hasMutatedProps = instance.props !== newProps; + if (instance.props !== undefined && hasMutatedProps) error("%s(...): When calling super() in `%s`, make sure to pass up the same props that your component's constructor was passed.", name, name); + if (instance.defaultProps) error("Setting defaultProps as an instance property on %s is not supported and will be ignored. Instead, define defaultProps as a static property on %s.", name, name); + if (typeof instance.getSnapshotBeforeUpdate === "function" && typeof instance.componentDidUpdate !== "function" && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) { + didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); + error("%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). This component defines getSnapshotBeforeUpdate() only.", getComponentNameFromType(ctor)); + } + if (typeof instance.getDerivedStateFromProps === "function") error("%s: getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method.", name); + if (typeof instance.getDerivedStateFromError === "function") error("%s: getDerivedStateFromError() is defined as an instance method and will be ignored. Instead, declare it as a static method.", name); + if (typeof ctor.getSnapshotBeforeUpdate === "function") error("%s: getSnapshotBeforeUpdate() is defined as a static method and will be ignored. Instead, declare it as an instance method.", name); + var _state = instance.state; + if (_state && (typeof _state !== "object" || isArray(_state))) error("%s.state: must be set to an object or null", name); + if (typeof instance.getChildContext === "function" && typeof ctor.childContextTypes !== "object") error("%s.getChildContext(): childContextTypes must be defined in order to use getChildContext().", name); + } + function adoptClassInstance(workInProgress, instance) { + instance.updater = classComponentUpdater; + workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates + set(instance, workInProgress); + instance._reactInternalInstance = fakeInternalInstance; + } + function constructClassInstance(workInProgress, ctor, props) { + var isLegacyContextConsumer = false; + var unmaskedContext = emptyContextObject; + var context = emptyContextObject; + var contextType = ctor.contextType; + if ("contextType" in ctor) { + var isValid = contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a + if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) { + didWarnAboutInvalidateContextType.add(ctor); + var addendum = ""; + if (contextType === undefined) addendum = " However, it is set to undefined. This can be caused by a typo or by mixing up named and default imports. This can also happen due to a circular dependency, so try moving the createContext() call to a separate file."; + else if (typeof contextType !== "object") addendum = " However, it is set to a " + typeof contextType + "."; + else if (contextType.$$typeof === REACT_PROVIDER_TYPE) addendum = " Did you accidentally pass the Context.Provider instead?"; + else if (contextType._context !== undefined) // + addendum = " Did you accidentally pass the Context.Consumer instead?"; + else addendum = " However, it is set to an object with keys {" + Object.keys(contextType).join(", ") + "}."; + error("%s defines an invalid contextType. contextType should point to the Context object returned by React.createContext().%s", getComponentNameFromType(ctor) || "Component", addendum); + } + } + if (typeof contextType === "object" && contextType !== null) context = readContext(contextType); + else { + unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); + var contextTypes = ctor.contextTypes; + isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined; + context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject; + } + var instance = new ctor(props, context); // Instantiate twice to help detect side-effects. + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + try { + instance = new ctor(props, context); // eslint-disable-line no-new + } finally{ + setIsStrictModeForDevtools(false); + } + } + var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null; + adoptClassInstance(workInProgress, instance); + if (typeof ctor.getDerivedStateFromProps === "function" && state === null) { + var componentName = getComponentNameFromType(ctor) || "Component"; + if (!didWarnAboutUninitializedState.has(componentName)) { + didWarnAboutUninitializedState.add(componentName); + error("`%s` uses `getDerivedStateFromProps` but its initial state is %s. This is not recommended. Instead, define the initial state by assigning an object to `this.state` in the constructor of `%s`. This ensures that `getDerivedStateFromProps` arguments have a consistent shape.", componentName, instance.state === null ? "null" : "undefined", componentName); + } + } // If new component APIs are defined, "unsafe" lifecycles won't be called. + // Warn about these lifecycles if they are present. + // Don't warn about react-lifecycles-compat polyfilled methods though. + if (typeof ctor.getDerivedStateFromProps === "function" || typeof instance.getSnapshotBeforeUpdate === "function") { + var foundWillMountName = null; + var foundWillReceivePropsName = null; + var foundWillUpdateName = null; + if (typeof instance.componentWillMount === "function" && instance.componentWillMount.__suppressDeprecationWarning !== true) foundWillMountName = "componentWillMount"; + else if (typeof instance.UNSAFE_componentWillMount === "function") foundWillMountName = "UNSAFE_componentWillMount"; + if (typeof instance.componentWillReceiveProps === "function" && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) foundWillReceivePropsName = "componentWillReceiveProps"; + else if (typeof instance.UNSAFE_componentWillReceiveProps === "function") foundWillReceivePropsName = "UNSAFE_componentWillReceiveProps"; + if (typeof instance.componentWillUpdate === "function" && instance.componentWillUpdate.__suppressDeprecationWarning !== true) foundWillUpdateName = "componentWillUpdate"; + else if (typeof instance.UNSAFE_componentWillUpdate === "function") foundWillUpdateName = "UNSAFE_componentWillUpdate"; + if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) { + var _componentName = getComponentNameFromType(ctor) || "Component"; + var newApiName = typeof ctor.getDerivedStateFromProps === "function" ? "getDerivedStateFromProps()" : "getSnapshotBeforeUpdate()"; + if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { + didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); + error("Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\nThe above lifecycles should be removed. Learn more about this warning here:\nhttps://reactjs.org/link/unsafe-component-lifecycles", _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : "", foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : "", foundWillUpdateName !== null ? "\n " + foundWillUpdateName : ""); + } + } + } + // ReactFiberContext usually updates this cache but can't for newly-created instances. + if (isLegacyContextConsumer) cacheContext(workInProgress, unmaskedContext, context); + return instance; + } + function callComponentWillMount(workInProgress, instance) { + var oldState = instance.state; + if (typeof instance.componentWillMount === "function") instance.componentWillMount(); + if (typeof instance.UNSAFE_componentWillMount === "function") instance.UNSAFE_componentWillMount(); + if (oldState !== instance.state) { + error("%s.componentWillMount(): Assigning directly to this.state is deprecated (except inside a component's constructor). Use setState instead.", getComponentNameFromFiber(workInProgress) || "Component"); + classComponentUpdater.enqueueReplaceState(instance, instance.state, null); + } + } + function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) { + var oldState = instance.state; + if (typeof instance.componentWillReceiveProps === "function") instance.componentWillReceiveProps(newProps, nextContext); + if (typeof instance.UNSAFE_componentWillReceiveProps === "function") instance.UNSAFE_componentWillReceiveProps(newProps, nextContext); + if (instance.state !== oldState) { + var componentName = getComponentNameFromFiber(workInProgress) || "Component"; + if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { + didWarnAboutStateAssignmentForComponent.add(componentName); + error("%s.componentWillReceiveProps(): Assigning directly to this.state is deprecated (except inside a component's constructor). Use setState instead.", componentName); + } + classComponentUpdater.enqueueReplaceState(instance, instance.state, null); + } + } // Invokes the mount life-cycles on a previously never rendered instance. + function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { + checkClassInstance(workInProgress, ctor, newProps); + var instance = workInProgress.stateNode; + instance.props = newProps; + instance.state = workInProgress.memoizedState; + instance.refs = emptyRefsObject; + initializeUpdateQueue(workInProgress); + var contextType = ctor.contextType; + if (typeof contextType === "object" && contextType !== null) instance.context = readContext(contextType); + else { + var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); + instance.context = getMaskedContext(workInProgress, unmaskedContext); + } + if (instance.state === newProps) { + var componentName = getComponentNameFromType(ctor) || "Component"; + if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { + didWarnAboutDirectlyAssigningPropsToState.add(componentName); + error("%s: It is not recommended to assign props directly to state because updates to props won't be reflected in state. In most cases, it is better to use props directly.", componentName); + } + } + if (workInProgress.mode & StrictLegacyMode) ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance); + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance); + instance.state = workInProgress.memoizedState; + var getDerivedStateFromProps = ctor.getDerivedStateFromProps; + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); + instance.state = workInProgress.memoizedState; + } // In order to support react-lifecycles-compat polyfilled components, + // Unsafe lifecycles should not be invoked for components using the new APIs. + if (typeof ctor.getDerivedStateFromProps !== "function" && typeof instance.getSnapshotBeforeUpdate !== "function" && (typeof instance.UNSAFE_componentWillMount === "function" || typeof instance.componentWillMount === "function")) { + callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's + // process them now. + processUpdateQueue(workInProgress, newProps, instance, renderLanes); + instance.state = workInProgress.memoizedState; + } + if (typeof instance.componentDidMount === "function") { + var fiberFlags = Update; + fiberFlags |= LayoutStatic; + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) fiberFlags |= MountLayoutDev; + workInProgress.flags |= fiberFlags; + } + } + function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { + var instance = workInProgress.stateNode; + var oldProps = workInProgress.memoizedProps; + instance.props = oldProps; + var oldContext = instance.context; + var contextType = ctor.contextType; + var nextContext = emptyContextObject; + if (typeof contextType === "object" && contextType !== null) nextContext = readContext(contextType); + else { + var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); + nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext); + } + var getDerivedStateFromProps = ctor.getDerivedStateFromProps; + var hasNewLifecycles = typeof getDerivedStateFromProps === "function" || typeof instance.getSnapshotBeforeUpdate === "function"; // Note: During these life-cycles, instance.props/instance.state are what + // ever the previously attempted to render - not the "current". However, + // during componentDidUpdate we pass the "current" props. + // In order to support react-lifecycles-compat polyfilled components, + // Unsafe lifecycles should not be invoked for components using the new APIs. + if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === "function" || typeof instance.componentWillReceiveProps === "function")) { + if (oldProps !== newProps || oldContext !== nextContext) callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext); + } + resetHasForceUpdateBeforeProcessing(); + var oldState = workInProgress.memoizedState; + var newState = instance.state = oldState; + processUpdateQueue(workInProgress, newProps, instance, renderLanes); + newState = workInProgress.memoizedState; + if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) { + // If an update was already in progress, we should schedule an Update + // effect even though we're bailing out, so that cWU/cDU are called. + if (typeof instance.componentDidMount === "function") { + var fiberFlags = Update; + fiberFlags |= LayoutStatic; + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) fiberFlags |= MountLayoutDev; + workInProgress.flags |= fiberFlags; + } + return false; + } + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); + newState = workInProgress.memoizedState; + } + var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext); + if (shouldUpdate) { + // In order to support react-lifecycles-compat polyfilled components, + // Unsafe lifecycles should not be invoked for components using the new APIs. + if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === "function" || typeof instance.componentWillMount === "function")) { + if (typeof instance.componentWillMount === "function") instance.componentWillMount(); + if (typeof instance.UNSAFE_componentWillMount === "function") instance.UNSAFE_componentWillMount(); + } + if (typeof instance.componentDidMount === "function") { + var _fiberFlags = Update; + _fiberFlags |= LayoutStatic; + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) _fiberFlags |= MountLayoutDev; + workInProgress.flags |= _fiberFlags; + } + } else { + // If an update was already in progress, we should schedule an Update + // effect even though we're bailing out, so that cWU/cDU are called. + if (typeof instance.componentDidMount === "function") { + var _fiberFlags2 = Update; + _fiberFlags2 |= LayoutStatic; + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) _fiberFlags2 |= MountLayoutDev; + workInProgress.flags |= _fiberFlags2; + } // If shouldComponentUpdate returned false, we should still update the + // memoized state to indicate that this work can be reused. + workInProgress.memoizedProps = newProps; + workInProgress.memoizedState = newState; + } // Update the existing instance's state, props, and context pointers even + // if shouldComponentUpdate returns false. + instance.props = newProps; + instance.state = newState; + instance.context = nextContext; + return shouldUpdate; + } // Invokes the update life-cycles and returns false if it shouldn't rerender. + function updateClassInstance(current, workInProgress, ctor, newProps, renderLanes) { + var instance = workInProgress.stateNode; + cloneUpdateQueue(current, workInProgress); + var unresolvedOldProps = workInProgress.memoizedProps; + var oldProps = workInProgress.type === workInProgress.elementType ? unresolvedOldProps : resolveDefaultProps(workInProgress.type, unresolvedOldProps); + instance.props = oldProps; + var unresolvedNewProps = workInProgress.pendingProps; + var oldContext = instance.context; + var contextType = ctor.contextType; + var nextContext = emptyContextObject; + if (typeof contextType === "object" && contextType !== null) nextContext = readContext(contextType); + else { + var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); + nextContext = getMaskedContext(workInProgress, nextUnmaskedContext); + } + var getDerivedStateFromProps = ctor.getDerivedStateFromProps; + var hasNewLifecycles = typeof getDerivedStateFromProps === "function" || typeof instance.getSnapshotBeforeUpdate === "function"; // Note: During these life-cycles, instance.props/instance.state are what + // ever the previously attempted to render - not the "current". However, + // during componentDidUpdate we pass the "current" props. + // In order to support react-lifecycles-compat polyfilled components, + // Unsafe lifecycles should not be invoked for components using the new APIs. + if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === "function" || typeof instance.componentWillReceiveProps === "function")) { + if (unresolvedOldProps !== unresolvedNewProps || oldContext !== nextContext) callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext); + } + resetHasForceUpdateBeforeProcessing(); + var oldState = workInProgress.memoizedState; + var newState = instance.state = oldState; + processUpdateQueue(workInProgress, newProps, instance, renderLanes); + newState = workInProgress.memoizedState; + if (unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing() && !enableLazyContextPropagation) { + // If an update was already in progress, we should schedule an Update + // effect even though we're bailing out, so that cWU/cDU are called. + if (typeof instance.componentDidUpdate === "function") { + if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) workInProgress.flags |= Update; + } + if (typeof instance.getSnapshotBeforeUpdate === "function") { + if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) workInProgress.flags |= Snapshot; + } + return false; + } + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps); + newState = workInProgress.memoizedState; + } + var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) || // TODO: In some cases, we'll end up checking if context has changed twice, + // both before and after `shouldComponentUpdate` has been called. Not ideal, + // but I'm loath to refactor this function. This only happens for memoized + // components so it's not that common. + enableLazyContextPropagation; + if (shouldUpdate) { + // In order to support react-lifecycles-compat polyfilled components, + // Unsafe lifecycles should not be invoked for components using the new APIs. + if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === "function" || typeof instance.componentWillUpdate === "function")) { + if (typeof instance.componentWillUpdate === "function") instance.componentWillUpdate(newProps, newState, nextContext); + if (typeof instance.UNSAFE_componentWillUpdate === "function") instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext); + } + if (typeof instance.componentDidUpdate === "function") workInProgress.flags |= Update; + if (typeof instance.getSnapshotBeforeUpdate === "function") workInProgress.flags |= Snapshot; + } else { + // If an update was already in progress, we should schedule an Update + // effect even though we're bailing out, so that cWU/cDU are called. + if (typeof instance.componentDidUpdate === "function") { + if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) workInProgress.flags |= Update; + } + if (typeof instance.getSnapshotBeforeUpdate === "function") { + if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) workInProgress.flags |= Snapshot; + } // If shouldComponentUpdate returned false, we should still update the + // memoized props/state to indicate that this work can be reused. + workInProgress.memoizedProps = newProps; + workInProgress.memoizedState = newState; + } // Update the existing instance's state, props, and context pointers even + // if shouldComponentUpdate returns false. + instance.props = newProps; + instance.state = newState; + instance.context = nextContext; + return shouldUpdate; + } + var didWarnAboutMaps; + var didWarnAboutGenerators; + var didWarnAboutStringRefs; + var ownerHasKeyUseWarning; + var ownerHasFunctionTypeWarning; + var warnForMissingKey = function(child, returnFiber) {}; + didWarnAboutMaps = false; + didWarnAboutGenerators = false; + didWarnAboutStringRefs = {}; + /** + * Warn if there's no key explicitly set on dynamic arrays of children or + * object keys are not valid. This allows us to keep track of children between + * updates. + */ ownerHasKeyUseWarning = {}; + ownerHasFunctionTypeWarning = {}; + warnForMissingKey = function(child, returnFiber) { + if (child === null || typeof child !== "object") return; + if (!child._store || child._store.validated || child.key != null) return; + if (typeof child._store !== "object") throw new Error("React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue."); + child._store.validated = true; + var componentName = getComponentNameFromFiber(returnFiber) || "Component"; + if (ownerHasKeyUseWarning[componentName]) return; + ownerHasKeyUseWarning[componentName] = true; + error('Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.'); + }; + function coerceRef(returnFiber, current, element) { + var mixedRef = element.ref; + if (mixedRef !== null && typeof mixedRef !== "function" && typeof mixedRef !== "object") { + // TODO: Clean this up once we turn on the string ref warning for + // everyone, because the strict mode case will no longer be relevant + if ((returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs + // because these cannot be automatically converted to an arrow function + // using a codemod. Therefore, we don't have to warn about string refs again. + !(element._owner && element._self && element._owner.stateNode !== element._self)) { + var componentName = getComponentNameFromFiber(returnFiber) || "Component"; + if (!didWarnAboutStringRefs[componentName]) { + error('A string ref, "%s", has been found within a strict mode tree. String refs are a source of potential bugs and should be avoided. We recommend using useRef() or createRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref', mixedRef); + didWarnAboutStringRefs[componentName] = true; + } + } + if (element._owner) { + var owner = element._owner; + var inst; + if (owner) { + var ownerFiber = owner; + if (ownerFiber.tag !== ClassComponent) throw new Error("Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref"); + inst = ownerFiber.stateNode; + } + if (!inst) throw new Error("Missing owner for string ref " + mixedRef + ". This error is likely caused by a " + "bug in React. Please file an issue."); + // Assigning this to a const so Flow knows it won't change in the closure + var resolvedInst = inst; + checkPropStringCoercion(mixedRef, "ref"); + var stringRef = "" + mixedRef; // Check if previous string ref matches new string ref + if (current !== null && current.ref !== null && typeof current.ref === "function" && current.ref._stringRef === stringRef) return current.ref; + var ref = function(value) { + var refs = resolvedInst.refs; + if (refs === emptyRefsObject) // This is a lazy pooled frozen object, so we need to initialize. + refs = resolvedInst.refs = {}; + if (value === null) delete refs[stringRef]; + else refs[stringRef] = value; + }; + ref._stringRef = stringRef; + return ref; + } else { + if (typeof mixedRef !== "string") throw new Error("Expected ref to be a function, a string, an object returned by React.createRef(), or null."); + if (!element._owner) throw new Error("Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of" + " the following reasons:\n" + "1. You may be adding a ref to a function component\n" + "2. You may be adding a ref to a component that was not created inside a component's render method\n" + "3. You have multiple copies of React loaded\n" + "See https://reactjs.org/link/refs-must-have-owner for more information."); + } + } + return mixedRef; + } + function throwOnInvalidObjectType(returnFiber, newChild) { + var childString = Object.prototype.toString.call(newChild); + throw new Error("Objects are not valid as a React child (found: " + (childString === "[object Object]" ? "object with keys {" + Object.keys(newChild).join(", ") + "}" : childString) + "). " + "If you meant to render a collection of children, use an array " + "instead."); + } + function warnOnFunctionType(returnFiber) { + var componentName = getComponentNameFromFiber(returnFiber) || "Component"; + if (ownerHasFunctionTypeWarning[componentName]) return; + ownerHasFunctionTypeWarning[componentName] = true; + error("Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it."); + } + function resolveLazy(lazyType) { + var payload = lazyType._payload; + var init = lazyType._init; + return init(payload); + } // This wrapper function exists because I expect to clone the code in each path + // to be able to optimize each path individually by branching early. This needs + // a compiler or we can do it manually. Helpers that don't need this branching + // live outside of this function. + function ChildReconciler(shouldTrackSideEffects) { + function deleteChild(returnFiber, childToDelete) { + if (!shouldTrackSideEffects) // Noop. + return; + var deletions = returnFiber.deletions; + if (deletions === null) { + returnFiber.deletions = [ + childToDelete + ]; + returnFiber.flags |= ChildDeletion; + } else deletions.push(childToDelete); + } + function deleteRemainingChildren(returnFiber, currentFirstChild) { + if (!shouldTrackSideEffects) // Noop. + return null; + // TODO: For the shouldClone case, this could be micro-optimized a bit by + // assuming that after the first child we've already added everything. + var childToDelete = currentFirstChild; + while(childToDelete !== null){ + deleteChild(returnFiber, childToDelete); + childToDelete = childToDelete.sibling; + } + return null; + } + function mapRemainingChildren(returnFiber, currentFirstChild) { + // Add the remaining children to a temporary map so that we can find them by + // keys quickly. Implicit (null) keys get added to this set with their index + // instead. + var existingChildren = new Map(); + var existingChild = currentFirstChild; + while(existingChild !== null){ + if (existingChild.key !== null) existingChildren.set(existingChild.key, existingChild); + else existingChildren.set(existingChild.index, existingChild); + existingChild = existingChild.sibling; + } + return existingChildren; + } + function useFiber(fiber, pendingProps) { + // We currently set sibling to null and index to 0 here because it is easy + // to forget to do before returning it. E.g. for the single child case. + var clone = createWorkInProgress(fiber, pendingProps); + clone.index = 0; + clone.sibling = null; + return clone; + } + function placeChild(newFiber, lastPlacedIndex, newIndex) { + newFiber.index = newIndex; + if (!shouldTrackSideEffects) { + // During hydration, the useId algorithm needs to know which fibers are + // part of a list of children (arrays, iterators). + newFiber.flags |= Forked; + return lastPlacedIndex; + } + var current = newFiber.alternate; + if (current !== null) { + var oldIndex = current.index; + if (oldIndex < lastPlacedIndex) { + // This is a move. + newFiber.flags |= Placement; + return lastPlacedIndex; + } else // This item can stay in place. + return oldIndex; + } else { + // This is an insertion. + newFiber.flags |= Placement; + return lastPlacedIndex; + } + } + function placeSingleChild(newFiber) { + // This is simpler for the single child case. We only need to do a + // placement for inserting new children. + if (shouldTrackSideEffects && newFiber.alternate === null) newFiber.flags |= Placement; + return newFiber; + } + function updateTextNode(returnFiber, current, textContent, lanes) { + if (current === null || current.tag !== HostText) { + // Insert + var created = createFiberFromText(textContent, returnFiber.mode, lanes); + created.return = returnFiber; + return created; + } else { + // Update + var existing = useFiber(current, textContent); + existing.return = returnFiber; + return existing; + } + } + function updateElement(returnFiber, current, element, lanes) { + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) return updateFragment(returnFiber, current, element.props.children, lanes, element.key); + if (current !== null) { + if (current.elementType === elementType || isCompatibleFamilyForHotReloading(current, element) || // Lazy types should reconcile their resolved type. + // We need to do this after the Hot Reloading check above, + // because hot reloading has different semantics than prod because + // it doesn't resuspend. So we can't let the call below suspend. + typeof elementType === "object" && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === current.type) { + // Move based on index + var existing = useFiber(current, element.props); + existing.ref = coerceRef(returnFiber, current, element); + existing.return = returnFiber; + existing._debugSource = element._source; + existing._debugOwner = element._owner; + return existing; + } + } // Insert + var created = createFiberFromElement(element, returnFiber.mode, lanes); + created.ref = coerceRef(returnFiber, current, element); + created.return = returnFiber; + return created; + } + function updatePortal(returnFiber, current, portal, lanes) { + if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) { + // Insert + var created = createFiberFromPortal(portal, returnFiber.mode, lanes); + created.return = returnFiber; + return created; + } else { + // Update + var existing = useFiber(current, portal.children || []); + existing.return = returnFiber; + return existing; + } + } + function updateFragment(returnFiber, current, fragment, lanes, key) { + if (current === null || current.tag !== Fragment) { + // Insert + var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key); + created.return = returnFiber; + return created; + } else { + // Update + var existing = useFiber(current, fragment); + existing.return = returnFiber; + return existing; + } + } + function createChild(returnFiber, newChild, lanes) { + if (typeof newChild === "string" && newChild !== "" || typeof newChild === "number") { + // Text nodes don't have keys. If the previous node is implicitly keyed + // we can continue to replace it without aborting even if it is not a text + // node. + var created = createFiberFromText("" + newChild, returnFiber.mode, lanes); + created.return = returnFiber; + return created; + } + if (typeof newChild === "object" && newChild !== null) { + switch(newChild.$$typeof){ + case REACT_ELEMENT_TYPE: + var _created = createFiberFromElement(newChild, returnFiber.mode, lanes); + _created.ref = coerceRef(returnFiber, null, newChild); + _created.return = returnFiber; + return _created; + case REACT_PORTAL_TYPE: + var _created2 = createFiberFromPortal(newChild, returnFiber.mode, lanes); + _created2.return = returnFiber; + return _created2; + case REACT_LAZY_TYPE: + var payload = newChild._payload; + var init = newChild._init; + return createChild(returnFiber, init(payload), lanes); + } + if (isArray(newChild) || getIteratorFn(newChild)) { + var _created3 = createFiberFromFragment(newChild, returnFiber.mode, lanes, null); + _created3.return = returnFiber; + return _created3; + } + throwOnInvalidObjectType(returnFiber, newChild); + } + if (typeof newChild === "function") warnOnFunctionType(returnFiber); + return null; + } + function updateSlot(returnFiber, oldFiber, newChild, lanes) { + // Update the fiber if the keys match, otherwise return null. + var key = oldFiber !== null ? oldFiber.key : null; + if (typeof newChild === "string" && newChild !== "" || typeof newChild === "number") { + // Text nodes don't have keys. If the previous node is implicitly keyed + // we can continue to replace it without aborting even if it is not a text + // node. + if (key !== null) return null; + return updateTextNode(returnFiber, oldFiber, "" + newChild, lanes); + } + if (typeof newChild === "object" && newChild !== null) { + switch(newChild.$$typeof){ + case REACT_ELEMENT_TYPE: + if (newChild.key === key) return updateElement(returnFiber, oldFiber, newChild, lanes); + else return null; + case REACT_PORTAL_TYPE: + if (newChild.key === key) return updatePortal(returnFiber, oldFiber, newChild, lanes); + else return null; + case REACT_LAZY_TYPE: + var payload = newChild._payload; + var init = newChild._init; + return updateSlot(returnFiber, oldFiber, init(payload), lanes); + } + if (isArray(newChild) || getIteratorFn(newChild)) { + if (key !== null) return null; + return updateFragment(returnFiber, oldFiber, newChild, lanes, null); + } + throwOnInvalidObjectType(returnFiber, newChild); + } + if (typeof newChild === "function") warnOnFunctionType(returnFiber); + return null; + } + function updateFromMap(existingChildren, returnFiber, newIdx, newChild, lanes) { + if (typeof newChild === "string" && newChild !== "" || typeof newChild === "number") { + // Text nodes don't have keys, so we neither have to check the old nor + // new node for the key. If both are text nodes, they match. + var matchedFiber = existingChildren.get(newIdx) || null; + return updateTextNode(returnFiber, matchedFiber, "" + newChild, lanes); + } + if (typeof newChild === "object" && newChild !== null) { + switch(newChild.$$typeof){ + case REACT_ELEMENT_TYPE: + var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null; + return updateElement(returnFiber, _matchedFiber, newChild, lanes); + case REACT_PORTAL_TYPE: + var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null; + return updatePortal(returnFiber, _matchedFiber2, newChild, lanes); + case REACT_LAZY_TYPE: + var payload = newChild._payload; + var init = newChild._init; + return updateFromMap(existingChildren, returnFiber, newIdx, init(payload), lanes); + } + if (isArray(newChild) || getIteratorFn(newChild)) { + var _matchedFiber3 = existingChildren.get(newIdx) || null; + return updateFragment(returnFiber, _matchedFiber3, newChild, lanes, null); + } + throwOnInvalidObjectType(returnFiber, newChild); + } + if (typeof newChild === "function") warnOnFunctionType(returnFiber); + return null; + } + /** + * Warns if there is a duplicate or missing key + */ function warnOnInvalidKey(child, knownKeys, returnFiber) { + if (typeof child !== "object" || child === null) return knownKeys; + switch(child.$$typeof){ + case REACT_ELEMENT_TYPE: + case REACT_PORTAL_TYPE: + warnForMissingKey(child, returnFiber); + var key = child.key; + if (typeof key !== "string") break; + if (knownKeys === null) { + knownKeys = new Set(); + knownKeys.add(key); + break; + } + if (!knownKeys.has(key)) { + knownKeys.add(key); + break; + } + error("Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted \u2014 the behavior is unsupported and could change in a future version.", key); + break; + case REACT_LAZY_TYPE: + var payload = child._payload; + var init = child._init; + warnOnInvalidKey(init(payload), knownKeys, returnFiber); + break; + } + return knownKeys; + } + function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, lanes) { + // First, validate keys. + var knownKeys = null; + for(var i = 0; i < newChildren.length; i++){ + var child = newChildren[i]; + knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); + } + var resultingFirstChild = null; + var previousNewFiber = null; + var oldFiber = currentFirstChild; + var lastPlacedIndex = 0; + var newIdx = 0; + var nextOldFiber = null; + for(; oldFiber !== null && newIdx < newChildren.length; newIdx++){ + if (oldFiber.index > newIdx) { + nextOldFiber = oldFiber; + oldFiber = null; + } else nextOldFiber = oldFiber.sibling; + var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], lanes); + if (newFiber === null) { + // TODO: This breaks on empty slots like null children. That's + // unfortunate because it triggers the slow path all the time. We need + // a better way to communicate whether this was a miss or null, + // boolean, undefined, etc. + if (oldFiber === null) oldFiber = nextOldFiber; + break; + } + if (shouldTrackSideEffects) { + if (oldFiber && newFiber.alternate === null) // We matched the slot, but we didn't reuse the existing fiber, so we + // need to delete the existing child. + deleteChild(returnFiber, oldFiber); + } + lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); + if (previousNewFiber === null) // TODO: Move out of the loop. This only happens for the first run. + resultingFirstChild = newFiber; + else // TODO: Defer siblings if we're not at the right index for this slot. + // I.e. if we had null values before, then we want to defer this + // for each null value. However, we also don't want to call updateSlot + // with the previous one. + previousNewFiber.sibling = newFiber; + previousNewFiber = newFiber; + oldFiber = nextOldFiber; + } + if (newIdx === newChildren.length) { + // We've reached the end of the new children. We can delete the rest. + deleteRemainingChildren(returnFiber, oldFiber); + if (getIsHydrating()) { + var numberOfForks = newIdx; + pushTreeFork(returnFiber, numberOfForks); + } + return resultingFirstChild; + } + if (oldFiber === null) { + // If we don't have any more existing children we can choose a fast path + // since the rest will all be insertions. + for(; newIdx < newChildren.length; newIdx++){ + var _newFiber = createChild(returnFiber, newChildren[newIdx], lanes); + if (_newFiber === null) continue; + lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx); + if (previousNewFiber === null) // TODO: Move out of the loop. This only happens for the first run. + resultingFirstChild = _newFiber; + else previousNewFiber.sibling = _newFiber; + previousNewFiber = _newFiber; + } + if (getIsHydrating()) { + var _numberOfForks = newIdx; + pushTreeFork(returnFiber, _numberOfForks); + } + return resultingFirstChild; + } // Add all children to a key map for quick lookups. + var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves. + for(; newIdx < newChildren.length; newIdx++){ + var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes); + if (_newFiber2 !== null) { + if (shouldTrackSideEffects) { + if (_newFiber2.alternate !== null) // The new fiber is a work in progress, but if there exists a + // current, that means that we reused the fiber. We need to delete + // it from the child list so that we don't add it to the deletion + // list. + existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key); + } + lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx); + if (previousNewFiber === null) resultingFirstChild = _newFiber2; + else previousNewFiber.sibling = _newFiber2; + previousNewFiber = _newFiber2; + } + } + if (shouldTrackSideEffects) // Any existing children that weren't consumed above were deleted. We need + // to add them to the deletion list. + existingChildren.forEach(function(child) { + return deleteChild(returnFiber, child); + }); + if (getIsHydrating()) { + var _numberOfForks2 = newIdx; + pushTreeFork(returnFiber, _numberOfForks2); + } + return resultingFirstChild; + } + function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, lanes) { + // This is the same implementation as reconcileChildrenArray(), + // but using the iterator instead. + var iteratorFn = getIteratorFn(newChildrenIterable); + if (typeof iteratorFn !== "function") throw new Error("An object is not an iterable. This error is likely caused by a bug in React. Please file an issue."); + // We don't support rendering Generators because it's a mutation. + // See https://github.com/facebook/react/issues/12995 + if (typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag + newChildrenIterable[Symbol.toStringTag] === "Generator") { + if (!didWarnAboutGenerators) error("Using Generators as children is unsupported and will likely yield unexpected results because enumerating a generator mutates it. You may convert it to an array with `Array.from()` or the `[...spread]` operator before rendering. Keep in mind you might need to polyfill these features for older browsers."); + didWarnAboutGenerators = true; + } // Warn about using Maps as children + if (newChildrenIterable.entries === iteratorFn) { + if (!didWarnAboutMaps) error("Using Maps as children is not supported. Use an array of keyed ReactElements instead."); + didWarnAboutMaps = true; + } // First, validate keys. + // We'll get a different iterator later for the main pass. + var _newChildren = iteratorFn.call(newChildrenIterable); + if (_newChildren) { + var knownKeys = null; + var _step = _newChildren.next(); + for(; !_step.done; _step = _newChildren.next()){ + var child = _step.value; + knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); + } + } + var newChildren = iteratorFn.call(newChildrenIterable); + if (newChildren == null) throw new Error("An iterable object provided no iterator."); + var resultingFirstChild = null; + var previousNewFiber = null; + var oldFiber = currentFirstChild; + var lastPlacedIndex = 0; + var newIdx = 0; + var nextOldFiber = null; + var step = newChildren.next(); + for(; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()){ + if (oldFiber.index > newIdx) { + nextOldFiber = oldFiber; + oldFiber = null; + } else nextOldFiber = oldFiber.sibling; + var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes); + if (newFiber === null) { + // TODO: This breaks on empty slots like null children. That's + // unfortunate because it triggers the slow path all the time. We need + // a better way to communicate whether this was a miss or null, + // boolean, undefined, etc. + if (oldFiber === null) oldFiber = nextOldFiber; + break; + } + if (shouldTrackSideEffects) { + if (oldFiber && newFiber.alternate === null) // We matched the slot, but we didn't reuse the existing fiber, so we + // need to delete the existing child. + deleteChild(returnFiber, oldFiber); + } + lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx); + if (previousNewFiber === null) // TODO: Move out of the loop. This only happens for the first run. + resultingFirstChild = newFiber; + else // TODO: Defer siblings if we're not at the right index for this slot. + // I.e. if we had null values before, then we want to defer this + // for each null value. However, we also don't want to call updateSlot + // with the previous one. + previousNewFiber.sibling = newFiber; + previousNewFiber = newFiber; + oldFiber = nextOldFiber; + } + if (step.done) { + // We've reached the end of the new children. We can delete the rest. + deleteRemainingChildren(returnFiber, oldFiber); + if (getIsHydrating()) { + var numberOfForks = newIdx; + pushTreeFork(returnFiber, numberOfForks); + } + return resultingFirstChild; + } + if (oldFiber === null) { + // If we don't have any more existing children we can choose a fast path + // since the rest will all be insertions. + for(; !step.done; newIdx++, step = newChildren.next()){ + var _newFiber3 = createChild(returnFiber, step.value, lanes); + if (_newFiber3 === null) continue; + lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx); + if (previousNewFiber === null) // TODO: Move out of the loop. This only happens for the first run. + resultingFirstChild = _newFiber3; + else previousNewFiber.sibling = _newFiber3; + previousNewFiber = _newFiber3; + } + if (getIsHydrating()) { + var _numberOfForks3 = newIdx; + pushTreeFork(returnFiber, _numberOfForks3); + } + return resultingFirstChild; + } // Add all children to a key map for quick lookups. + var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves. + for(; !step.done; newIdx++, step = newChildren.next()){ + var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes); + if (_newFiber4 !== null) { + if (shouldTrackSideEffects) { + if (_newFiber4.alternate !== null) // The new fiber is a work in progress, but if there exists a + // current, that means that we reused the fiber. We need to delete + // it from the child list so that we don't add it to the deletion + // list. + existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key); + } + lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx); + if (previousNewFiber === null) resultingFirstChild = _newFiber4; + else previousNewFiber.sibling = _newFiber4; + previousNewFiber = _newFiber4; + } + } + if (shouldTrackSideEffects) // Any existing children that weren't consumed above were deleted. We need + // to add them to the deletion list. + existingChildren.forEach(function(child) { + return deleteChild(returnFiber, child); + }); + if (getIsHydrating()) { + var _numberOfForks4 = newIdx; + pushTreeFork(returnFiber, _numberOfForks4); + } + return resultingFirstChild; + } + function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, lanes) { + // There's no need to check for keys on text nodes since we don't have a + // way to define them. + if (currentFirstChild !== null && currentFirstChild.tag === HostText) { + // We already have an existing node so let's just update it and delete + // the rest. + deleteRemainingChildren(returnFiber, currentFirstChild.sibling); + var existing = useFiber(currentFirstChild, textContent); + existing.return = returnFiber; + return existing; + } // The existing first child is not a text node so we need to create one + // and delete the existing ones. + deleteRemainingChildren(returnFiber, currentFirstChild); + var created = createFiberFromText(textContent, returnFiber.mode, lanes); + created.return = returnFiber; + return created; + } + function reconcileSingleElement(returnFiber, currentFirstChild, element, lanes) { + var key = element.key; + var child = currentFirstChild; + while(child !== null){ + // TODO: If key === null and child.key === null, then this only applies to + // the first item in the list. + if (child.key === key) { + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) { + if (child.tag === Fragment) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, element.props.children); + existing.return = returnFiber; + existing._debugSource = element._source; + existing._debugOwner = element._owner; + return existing; + } + } else if (child.elementType === elementType || isCompatibleFamilyForHotReloading(child, element) || // Lazy types should reconcile their resolved type. + // We need to do this after the Hot Reloading check above, + // because hot reloading has different semantics than prod because + // it doesn't resuspend. So we can't let the call below suspend. + typeof elementType === "object" && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === child.type) { + deleteRemainingChildren(returnFiber, child.sibling); + var _existing = useFiber(child, element.props); + _existing.ref = coerceRef(returnFiber, child, element); + _existing.return = returnFiber; + _existing._debugSource = element._source; + _existing._debugOwner = element._owner; + return _existing; + } + // Didn't match. + deleteRemainingChildren(returnFiber, child); + break; + } else deleteChild(returnFiber, child); + child = child.sibling; + } + if (element.type === REACT_FRAGMENT_TYPE) { + var created = createFiberFromFragment(element.props.children, returnFiber.mode, lanes, element.key); + created.return = returnFiber; + return created; + } else { + var _created4 = createFiberFromElement(element, returnFiber.mode, lanes); + _created4.ref = coerceRef(returnFiber, currentFirstChild, element); + _created4.return = returnFiber; + return _created4; + } + } + function reconcileSinglePortal(returnFiber, currentFirstChild, portal, lanes) { + var key = portal.key; + var child = currentFirstChild; + while(child !== null){ + // TODO: If key === null and child.key === null, then this only applies to + // the first item in the list. + if (child.key === key) { + if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, portal.children || []); + existing.return = returnFiber; + return existing; + } else { + deleteRemainingChildren(returnFiber, child); + break; + } + } else deleteChild(returnFiber, child); + child = child.sibling; + } + var created = createFiberFromPortal(portal, returnFiber.mode, lanes); + created.return = returnFiber; + return created; + } // This API will tag the children with the side-effect of the reconciliation + // itself. They will be added to the side-effect list as we pass through the + // children and the parent. + function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) { + // This function is not recursive. + // If the top level item is an array, we treat it as a set of children, + // not as a fragment. Nested arrays on the other hand will be treated as + // fragment nodes. Recursion happens at the normal flow. + // Handle top level unkeyed fragments as if they were arrays. + // This leads to an ambiguity between <>{[...]} and <>.... + // We treat the ambiguous cases above the same. + var isUnkeyedTopLevelFragment = typeof newChild === "object" && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null; + if (isUnkeyedTopLevelFragment) newChild = newChild.props.children; + // Handle object types + if (typeof newChild === "object" && newChild !== null) { + switch(newChild.$$typeof){ + case REACT_ELEMENT_TYPE: + return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, lanes)); + case REACT_PORTAL_TYPE: + return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, lanes)); + case REACT_LAZY_TYPE: + var payload = newChild._payload; + var init = newChild._init; // TODO: This function is supposed to be non-recursive. + return reconcileChildFibers(returnFiber, currentFirstChild, init(payload), lanes); + } + if (isArray(newChild)) return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, lanes); + if (getIteratorFn(newChild)) return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, lanes); + throwOnInvalidObjectType(returnFiber, newChild); + } + if (typeof newChild === "string" && newChild !== "" || typeof newChild === "number") return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, "" + newChild, lanes)); + if (typeof newChild === "function") warnOnFunctionType(returnFiber); + return deleteRemainingChildren(returnFiber, currentFirstChild); + } + return reconcileChildFibers; + } + var reconcileChildFibers = ChildReconciler(true); + var mountChildFibers = ChildReconciler(false); + function cloneChildFibers(current, workInProgress) { + if (current !== null && workInProgress.child !== current.child) throw new Error("Resuming work not yet implemented."); + if (workInProgress.child === null) return; + var currentChild = workInProgress.child; + var newChild = createWorkInProgress(currentChild, currentChild.pendingProps); + workInProgress.child = newChild; + newChild.return = workInProgress; + while(currentChild.sibling !== null){ + currentChild = currentChild.sibling; + newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps); + newChild.return = workInProgress; + } + newChild.sibling = null; + } // Reset a workInProgress child set to prepare it for a second pass. + function resetChildFibers(workInProgress, lanes) { + var child = workInProgress.child; + while(child !== null){ + resetWorkInProgress(child, lanes); + child = child.sibling; + } + } + var NO_CONTEXT = {}; + var contextStackCursor$1 = createCursor(NO_CONTEXT); + var contextFiberStackCursor = createCursor(NO_CONTEXT); + var rootInstanceStackCursor = createCursor(NO_CONTEXT); + function requiredContext(c) { + if (c === NO_CONTEXT) throw new Error("Expected host context to exist. This error is likely caused by a bug in React. Please file an issue."); + return c; + } + function getRootHostContainer() { + var rootInstance = requiredContext(rootInstanceStackCursor.current); + return rootInstance; + } + function pushHostContainer(fiber, nextRootInstance) { + // Push current root instance onto the stack; + // This allows us to reset root when portals are popped. + push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it. + // This enables us to pop only Fibers that provide unique contexts. + push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack. + // However, we can't just call getRootHostContext() and push it because + // we'd have a different number of entries on the stack depending on + // whether getRootHostContext() throws somewhere in renderer code or not. + // So we push an empty value first. This lets us safely unwind on errors. + push(contextStackCursor$1, NO_CONTEXT, fiber); + var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it. + pop(contextStackCursor$1, fiber); + push(contextStackCursor$1, nextRootContext, fiber); + } + function popHostContainer(fiber) { + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); + pop(rootInstanceStackCursor, fiber); + } + function getHostContext() { + var context = requiredContext(contextStackCursor$1.current); + return context; + } + function pushHostContext(fiber) { + var rootInstance = requiredContext(rootInstanceStackCursor.current); + var context = requiredContext(contextStackCursor$1.current); + var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. + if (context === nextContext) return; + // Track the context and the Fiber that provided it. + // This enables us to pop only Fibers that provide unique contexts. + push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor$1, nextContext, fiber); + } + function popHostContext(fiber) { + // Do not pop unless this Fiber provided the current context. + // pushHostContext() only pushes Fibers that provide unique contexts. + if (contextFiberStackCursor.current !== fiber) return; + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); + } + var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is + // inherited deeply down the subtree. The upper bits only affect + // this immediate suspense boundary and gets reset each new + // boundary or suspense list. + var SubtreeSuspenseContextMask = 1; // Subtree Flags: + // InvisibleParentSuspenseContext indicates that one of our parent Suspense + // boundaries is not currently showing visible main content. + // Either because it is already showing a fallback or is not mounted at all. + // We can use this to determine if it is desirable to trigger a fallback at + // the parent. If not, then we might need to trigger undesirable boundaries + // and/or suspend the commit to avoid hiding the parent content. + var InvisibleParentSuspenseContext = 1; // Shallow Flags: + // ForceSuspenseFallback can be used by SuspenseList to force newly added + // items into their fallback state during one of the render passes. + var ForceSuspenseFallback = 2; + var suspenseStackCursor = createCursor(DefaultSuspenseContext); + function hasSuspenseContext(parentContext, flag) { + return (parentContext & flag) !== 0; + } + function setDefaultShallowSuspenseContext(parentContext) { + return parentContext & SubtreeSuspenseContextMask; + } + function setShallowSuspenseContext(parentContext, shallowContext) { + return parentContext & SubtreeSuspenseContextMask | shallowContext; + } + function addSubtreeSuspenseContext(parentContext, subtreeContext) { + return parentContext | subtreeContext; + } + function pushSuspenseContext(fiber, newContext) { + push(suspenseStackCursor, newContext, fiber); + } + function popSuspenseContext(fiber) { + pop(suspenseStackCursor, fiber); + } + function shouldCaptureSuspense(workInProgress, hasInvisibleParent) { + // If it was the primary children that just suspended, capture and render the + // fallback. Otherwise, don't capture and bubble to the next boundary. + var nextState = workInProgress.memoizedState; + if (nextState !== null) { + if (nextState.dehydrated !== null) // A dehydrated boundary always captures. + return true; + return false; + } + var props = workInProgress.memoizedProps; // Regular boundaries always capture. + return true; + } + function findFirstSuspended(row) { + var node = row; + while(node !== null){ + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + if (state !== null) { + var dehydrated = state.dehydrated; + if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) return node; + } + } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't + // keep track of whether it suspended or not. + node.memoizedProps.revealOrder !== undefined) { + var didSuspend = (node.flags & DidCapture) !== NoFlags; + if (didSuspend) return node; + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === row) return null; + while(node.sibling === null){ + if (node.return === null || node.return === row) return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return null; + } + var NoFlags$1 = /* */ 0; // Represents whether effect should fire. + var HasEffect = /* */ 1; // Represents the phase in which the effect (not the clean-up) fires. + var Insertion = /* */ 2; + var Layout = /* */ 4; + var Passive$1 = /* */ 8; + // and should be reset before starting a new render. + // This tracks which mutable sources need to be reset after a render. + var workInProgressSources = []; + function resetWorkInProgressVersions() { + for(var i = 0; i < workInProgressSources.length; i++){ + var mutableSource = workInProgressSources[i]; + mutableSource._workInProgressVersionPrimary = null; + } + workInProgressSources.length = 0; + } + // This ensures that the version used for server rendering matches the one + // that is eventually read during hydration. + // If they don't match there's a potential tear and a full deopt render is required. + function registerMutableSourceForHydration(root, mutableSource) { + var getVersion = mutableSource._getVersion; + var version = getVersion(mutableSource._source); // TODO Clear this data once all pending hydration work is finished. + // Retaining it forever may interfere with GC. + if (root.mutableSourceEagerHydrationData == null) root.mutableSourceEagerHydrationData = [ + mutableSource, + version + ]; + else root.mutableSourceEagerHydrationData.push(mutableSource, version); + } + var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig; + var didWarnAboutMismatchedHooksForComponent; + var didWarnUncachedGetSnapshot; + didWarnAboutMismatchedHooksForComponent = new Set(); + // These are set right before calling the component. + var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from + // the work-in-progress hook. + var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The + // current hook list is the list that belongs to the current fiber. The + // work-in-progress hook list is a new list that will be added to the + // work-in-progress fiber. + var currentHook = null; + var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This + // does not get reset if we do another render pass; only when we're completely + // finished evaluating this component. This is an optimization so we know + // whether we need to clear render phase updates after a throw. + var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This + // gets reset after each attempt. + // TODO: Maybe there's some way to consolidate this with + // `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`. + var didScheduleRenderPhaseUpdateDuringThisPass = false; // Counts the number of useId hooks in this component. + var localIdCounter = 0; // Used for ids that are generated completely client-side (i.e. not during + // hydration). This counter is global, so client ids are not stable across + // render attempts. + var globalClientIdCounter = 0; + var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook + var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders. + // The list stores the order of hooks used during the initial render (mount). + // Subsequent renders (updates) reference this list. + var hookTypesDev = null; + var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore + // the dependencies for Hooks that need them (e.g. useEffect or useMemo). + // When true, such Hooks will always be "remounted". Only used during hot reload. + var ignorePreviousDependencies = false; + function mountHookTypesDev() { + var hookName = currentHookNameInDev; + if (hookTypesDev === null) hookTypesDev = [ + hookName + ]; + else hookTypesDev.push(hookName); + } + function updateHookTypesDev() { + var hookName = currentHookNameInDev; + if (hookTypesDev !== null) { + hookTypesUpdateIndexDev++; + if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) warnOnHookMismatchInDev(hookName); + } + } + function checkDepsAreArrayDev(deps) { + if (deps !== undefined && deps !== null && !isArray(deps)) // Verify deps, but only on mount to avoid extra checks. + // It's unlikely their type would change as usually you define them inline. + error("%s received a final argument that is not an array (instead, received `%s`). When specified, the final argument must be an array.", currentHookNameInDev, typeof deps); + } + function warnOnHookMismatchInDev(currentHookName) { + var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1); + if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) { + didWarnAboutMismatchedHooksForComponent.add(componentName); + if (hookTypesDev !== null) { + var table = ""; + var secondColumnStart = 30; + for(var i = 0; i <= hookTypesUpdateIndexDev; i++){ + var oldHookName = hookTypesDev[i]; + var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName; + var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up + // lol @ IE not supporting String#repeat + while(row.length < secondColumnStart)row += " "; + row += newHookName + "\n"; + table += row; + } + error("React has detected a change in the order of Hooks called by %s. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks\n\n Previous render Next render\n ------------------------------------------------------\n%s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", componentName, table); + } + } + } + function throwInvalidHookError() { + throw new Error("Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem."); + } + function areHookInputsEqual(nextDeps, prevDeps) { + if (ignorePreviousDependencies) // Only true when this component is being hot reloaded. + return false; + if (prevDeps === null) { + error("%s received a final argument during this render, but not during the previous render. Even though the final argument is optional, its type cannot change between renders.", currentHookNameInDev); + return false; + } + // Don't bother comparing lengths in prod because these arrays should be + // passed inline. + if (nextDeps.length !== prevDeps.length) error("The final argument passed to %s changed size between renders. The order and size of this array must remain constant.\n\nPrevious: %s\nIncoming: %s", currentHookNameInDev, "[" + prevDeps.join(", ") + "]", "[" + nextDeps.join(", ") + "]"); + for(var i = 0; i < prevDeps.length && i < nextDeps.length; i++){ + if (objectIs(nextDeps[i], prevDeps[i])) continue; + return false; + } + return true; + } + function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes) { + renderLanes = nextRenderLanes; + currentlyRenderingFiber$1 = workInProgress; + hookTypesDev = current !== null ? current._debugHookTypes : null; + hookTypesUpdateIndexDev = -1; // Used for hot reloading: + ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.lanes = NoLanes; // The following should have already been reset + if (current !== null && current.memoizedState !== null) ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + else if (hookTypesDev !== null) // This dispatcher handles an edge case where a component is updating, + // but no stateful hooks have been used. + // We want to match the production code behavior (which will use HooksDispatcherOnMount), + // but with the extra DEV validation to ensure hooks ordering hasn't changed. + // This dispatcher does that. + ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV; + else ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; + var children = Component(props, secondArg); // Check if there was a render phase update + if (didScheduleRenderPhaseUpdateDuringThisPass) { + // Keep rendering in a loop for as long as render phase updates continue to + // be scheduled. Use a counter to prevent infinite loops. + var numberOfReRenders = 0; + do { + didScheduleRenderPhaseUpdateDuringThisPass = false; + localIdCounter = 0; + if (numberOfReRenders >= RE_RENDER_LIMIT) throw new Error("Too many re-renders. React limits the number of renders to prevent an infinite loop."); + numberOfReRenders += 1; + // Even when hot reloading, allow dependencies to stabilize + // after first render to prevent infinite render phase updates. + ignorePreviousDependencies = false; + currentHook = null; + workInProgressHook = null; + workInProgress.updateQueue = null; + // Also validate hook order for cascading updates. + hookTypesUpdateIndexDev = -1; + ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV; + children = Component(props, secondArg); + }while (didScheduleRenderPhaseUpdateDuringThisPass); + } // We can assume the previous dispatcher is always this one, since we set it + // at the beginning of the render phase and there's no re-entrance. + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + workInProgress._debugHookTypes = hookTypesDev; + // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. + var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null; + renderLanes = NoLanes; + currentlyRenderingFiber$1 = null; + currentHook = null; + workInProgressHook = null; + currentHookNameInDev = null; + hookTypesDev = null; + hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last + // render. If this fires, it suggests that we incorrectly reset the static + // flags in some other part of the codebase. This has happened before, for + // example, in the SuspenseList implementation. + if (current !== null && (current.flags & StaticMask) !== (workInProgress.flags & StaticMask) && // Disable this warning in legacy mode, because legacy Suspense is weird + // and creates false positives. To make this work in legacy mode, we'd + // need to mark fibers that commit in an incomplete state, somehow. For + // now I'll disable the warning that most of the bugs that would trigger + // it are either exclusive to concurrent mode or exist in both. + (current.mode & ConcurrentMode) !== NoMode) error("Internal React error: Expected static flag was missing. Please notify the React team."); + didScheduleRenderPhaseUpdate = false; // This is reset by checkDidRenderIdHook + // localIdCounter = 0; + if (didRenderTooFewHooks) throw new Error("Rendered fewer hooks than expected. This may be caused by an accidental early return statement."); + return children; + } + function checkDidRenderIdHook() { + // This should be called immediately after every renderWithHooks call. + // Conceptually, it's part of the return value of renderWithHooks; it's only a + // separate function to avoid using an array tuple. + var didRenderIdHook = localIdCounter !== 0; + localIdCounter = 0; + return didRenderIdHook; + } + function bailoutHooks(current, workInProgress, lanes) { + workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the + // complete phase (bubbleProperties). + if ((workInProgress.mode & StrictEffectsMode) !== NoMode) workInProgress.flags &= ~(MountPassiveDev | MountLayoutDev | Passive | Update); + else workInProgress.flags &= ~(Passive | Update); + current.lanes = removeLanes(current.lanes, lanes); + } + function resetHooksAfterThrow() { + // We can assume the previous dispatcher is always this one, since we set it + // at the beginning of the render phase and there's no re-entrance. + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + if (didScheduleRenderPhaseUpdate) { + // There were render phase updates. These are only valid for this render + // phase, which we are now aborting. Remove the updates from the queues so + // they do not persist to the next render. Do not remove updates from hooks + // that weren't processed. + // + // Only reset the updates from the queue if it has a clone. If it does + // not have a clone, that means it wasn't processed, and the updates were + // scheduled before we entered the render phase. + var hook = currentlyRenderingFiber$1.memoizedState; + while(hook !== null){ + var queue = hook.queue; + if (queue !== null) queue.pending = null; + hook = hook.next; + } + didScheduleRenderPhaseUpdate = false; + } + renderLanes = NoLanes; + currentlyRenderingFiber$1 = null; + currentHook = null; + workInProgressHook = null; + hookTypesDev = null; + hookTypesUpdateIndexDev = -1; + currentHookNameInDev = null; + isUpdatingOpaqueValueInRenderPhase = false; + didScheduleRenderPhaseUpdateDuringThisPass = false; + localIdCounter = 0; + } + function mountWorkInProgressHook() { + var hook = { + memoizedState: null, + baseState: null, + baseQueue: null, + queue: null, + next: null + }; + if (workInProgressHook === null) // This is the first hook in the list + currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; + else // Append to the end of the list + workInProgressHook = workInProgressHook.next = hook; + return workInProgressHook; + } + function updateWorkInProgressHook() { + // This function is used both for updates and for re-renders triggered by a + // render phase update. It assumes there is either a current hook we can + // clone, or a work-in-progress hook from a previous render pass that we can + // use as a base. When we reach the end of the base list, we must switch to + // the dispatcher used for mounts. + var nextCurrentHook; + if (currentHook === null) { + var current = currentlyRenderingFiber$1.alternate; + if (current !== null) nextCurrentHook = current.memoizedState; + else nextCurrentHook = null; + } else nextCurrentHook = currentHook.next; + var nextWorkInProgressHook; + if (workInProgressHook === null) nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState; + else nextWorkInProgressHook = workInProgressHook.next; + if (nextWorkInProgressHook !== null) { + // There's already a work-in-progress. Reuse it. + workInProgressHook = nextWorkInProgressHook; + nextWorkInProgressHook = workInProgressHook.next; + currentHook = nextCurrentHook; + } else { + // Clone from the current hook. + if (nextCurrentHook === null) throw new Error("Rendered more hooks than during the previous render."); + currentHook = nextCurrentHook; + var newHook = { + memoizedState: currentHook.memoizedState, + baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, + queue: currentHook.queue, + next: null + }; + if (workInProgressHook === null) // This is the first hook in the list. + currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; + else // Append to the end of the list. + workInProgressHook = workInProgressHook.next = newHook; + } + return workInProgressHook; + } + function createFunctionComponentUpdateQueue() { + return { + lastEffect: null, + stores: null + }; + } + function basicStateReducer(state, action) { + // $FlowFixMe: Flow doesn't like mixed types + return typeof action === "function" ? action(state) : action; + } + function mountReducer(reducer, initialArg, init) { + var hook = mountWorkInProgressHook(); + var initialState; + if (init !== undefined) initialState = init(initialArg); + else initialState = initialArg; + hook.memoizedState = hook.baseState = initialState; + var queue = { + pending: null, + interleaved: null, + lanes: NoLanes, + dispatch: null, + lastRenderedReducer: reducer, + lastRenderedState: initialState + }; + hook.queue = queue; + var dispatch = queue.dispatch = dispatchReducerAction.bind(null, currentlyRenderingFiber$1, queue); + return [ + hook.memoizedState, + dispatch + ]; + } + function updateReducer(reducer, initialArg, init) { + var hook = updateWorkInProgressHook(); + var queue = hook.queue; + if (queue === null) throw new Error("Should have a queue. This is likely a bug in React. Please file an issue."); + queue.lastRenderedReducer = reducer; + var current = currentHook; // The last rebase update that is NOT part of the base state. + var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. + var pendingQueue = queue.pending; + if (pendingQueue !== null) { + // We have new updates that haven't been processed yet. + // We'll add them to the base queue. + if (baseQueue !== null) { + // Merge the pending queue and the base queue. + var baseFirst = baseQueue.next; + var pendingFirst = pendingQueue.next; + baseQueue.next = pendingFirst; + pendingQueue.next = baseFirst; + } + if (current.baseQueue !== baseQueue) // Internal invariant that should never happen, but feasibly could in + // the future if we implement resuming, or some form of that. + error("Internal error: Expected work-in-progress queue to be a clone. This is a bug in React."); + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; + } + if (baseQueue !== null) { + // We have a queue to process. + var first = baseQueue.next; + var newState = current.baseState; + var newBaseState = null; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; + var update = first; + do { + var updateLane = update.lane; + if (!isSubsetOfLanes(renderLanes, updateLane)) { + // Priority is insufficient. Skip this update. If this is the first + // skipped update, the previous update/state is the new base + // update/state. + var clone = { + lane: updateLane, + action: update.action, + hasEagerState: update.hasEagerState, + eagerState: update.eagerState, + next: null + }; + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; + newBaseState = newState; + } else newBaseQueueLast = newBaseQueueLast.next = clone; + // Update the remaining priority in the queue. + // TODO: Don't need to accumulate this. Instead, we can remove + // renderLanes from the original lanes. + currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane); + markSkippedUpdateLanes(updateLane); + } else { + // This update does have sufficient priority. + if (newBaseQueueLast !== null) { + var _clone = { + // This update is going to be committed so we never want uncommit + // it. Using NoLane works because 0 is a subset of all bitmasks, so + // this will never be skipped by the check above. + lane: NoLane, + action: update.action, + hasEagerState: update.hasEagerState, + eagerState: update.eagerState, + next: null + }; + newBaseQueueLast = newBaseQueueLast.next = _clone; + } // Process this update. + if (update.hasEagerState) // If this update is a state update (not a reducer) and was processed eagerly, + // we can use the eagerly computed state + newState = update.eagerState; + else { + var action = update.action; + newState = reducer(newState, action); + } + } + update = update.next; + }while (update !== null && update !== first); + if (newBaseQueueLast === null) newBaseState = newState; + else newBaseQueueLast.next = newBaseQueueFirst; + // Mark that the fiber performed work, but only if the new state is + // different from the current state. + if (!objectIs(newState, hook.memoizedState)) markWorkInProgressReceivedUpdate(); + hook.memoizedState = newState; + hook.baseState = newBaseState; + hook.baseQueue = newBaseQueueLast; + queue.lastRenderedState = newState; + } // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + var lastInterleaved = queue.interleaved; + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + do { + var interleavedLane = interleaved.lane; + currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, interleavedLane); + markSkippedUpdateLanes(interleavedLane); + interleaved = interleaved.next; + }while (interleaved !== lastInterleaved); + } else if (baseQueue === null) // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.lanes = NoLanes; + var dispatch = queue.dispatch; + return [ + hook.memoizedState, + dispatch + ]; + } + function rerenderReducer(reducer, initialArg, init) { + var hook = updateWorkInProgressHook(); + var queue = hook.queue; + if (queue === null) throw new Error("Should have a queue. This is likely a bug in React. Please file an issue."); + queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous + // work-in-progress hook. + var dispatch = queue.dispatch; + var lastRenderPhaseUpdate = queue.pending; + var newState = hook.memoizedState; + if (lastRenderPhaseUpdate !== null) { + // The queue doesn't persist past this render pass. + queue.pending = null; + var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next; + var update = firstRenderPhaseUpdate; + do { + // Process this render phase update. We don't have to check the + // priority because it will always be the same as the current + // render's. + var action = update.action; + newState = reducer(newState, action); + update = update.next; + }while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is + // different from the current state. + if (!objectIs(newState, hook.memoizedState)) markWorkInProgressReceivedUpdate(); + hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to + // the base state unless the queue is empty. + // TODO: Not sure if this is the desired semantics, but it's what we + // do for gDSFP. I can't remember why. + if (hook.baseQueue === null) hook.baseState = newState; + queue.lastRenderedState = newState; + } + return [ + newState, + dispatch + ]; + } + function mountMutableSource(source, getSnapshot, subscribe) { + return undefined; + } + function updateMutableSource(source, getSnapshot, subscribe) { + return undefined; + } + function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { + var fiber = currentlyRenderingFiber$1; + var hook = mountWorkInProgressHook(); + var nextSnapshot; + var isHydrating = getIsHydrating(); + if (isHydrating) { + if (getServerSnapshot === undefined) throw new Error("Missing getServerSnapshot, which is required for server-rendered content. Will revert to client rendering."); + nextSnapshot = getServerSnapshot(); + if (!didWarnUncachedGetSnapshot) { + if (nextSnapshot !== getServerSnapshot()) { + error("The result of getServerSnapshot should be cached to avoid an infinite loop"); + didWarnUncachedGetSnapshot = true; + } + } + } else { + nextSnapshot = getSnapshot(); + if (!didWarnUncachedGetSnapshot) { + var cachedSnapshot = getSnapshot(); + if (!objectIs(nextSnapshot, cachedSnapshot)) { + error("The result of getSnapshot should be cached to avoid an infinite loop"); + didWarnUncachedGetSnapshot = true; + } + } + // Right before committing, we will walk the tree and check if any of the + // stores were mutated. + // + // We won't do this if we're hydrating server-rendered content, because if + // the content is stale, it's already visible anyway. Instead we'll patch + // it up in a passive effect. + var root = getWorkInProgressRoot(); + if (root === null) throw new Error("Expected a work-in-progress root. This is a bug in React. Please file an issue."); + if (!includesBlockingLane(root, renderLanes)) pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); + } // Read the current snapshot from the store on every render. This breaks the + // normal rules of React, and only works because store updates are + // always synchronous. + hook.memoizedState = nextSnapshot; + var inst = { + value: nextSnapshot, + getSnapshot: getSnapshot + }; + hook.queue = inst; // Schedule an effect to subscribe to the store. + mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ + subscribe + ]); // Schedule an effect to update the mutable instance fields. We will update + // this whenever subscribe, getSnapshot, or value changes. Because there's no + // clean-up function, and we track the deps correctly, we can call pushEffect + // directly, without storing any additional state. For the same reason, we + // don't need to set a static flag, either. + // TODO: We can move this to the passive phase once we add a pre-commit + // consistency check. See the next comment. + fiber.flags |= Passive; + pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null); + return nextSnapshot; + } + function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) { + var fiber = currentlyRenderingFiber$1; + var hook = updateWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the + // normal rules of React, and only works because store updates are + // always synchronous. + var nextSnapshot = getSnapshot(); + if (!didWarnUncachedGetSnapshot) { + var cachedSnapshot = getSnapshot(); + if (!objectIs(nextSnapshot, cachedSnapshot)) { + error("The result of getSnapshot should be cached to avoid an infinite loop"); + didWarnUncachedGetSnapshot = true; + } + } + var prevSnapshot = hook.memoizedState; + var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot); + if (snapshotChanged) { + hook.memoizedState = nextSnapshot; + markWorkInProgressReceivedUpdate(); + } + var inst = hook.queue; + updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [ + subscribe + ]); // Whenever getSnapshot or subscribe changes, we need to check in the + // commit phase if there was an interleaved mutation. In concurrent mode + // this can happen all the time, but even in synchronous mode, an earlier + // effect may have mutated the store. + if (inst.getSnapshot !== getSnapshot || snapshotChanged || // Check if the susbcribe function changed. We can save some memory by + // checking whether we scheduled a subscription effect above. + workInProgressHook !== null && workInProgressHook.memoizedState.tag & HasEffect) { + fiber.flags |= Passive; + pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null); // Unless we're rendering a blocking lane, schedule a consistency check. + // Right before committing, we will walk the tree and check if any of the + // stores were mutated. + var root = getWorkInProgressRoot(); + if (root === null) throw new Error("Expected a work-in-progress root. This is a bug in React. Please file an issue."); + if (!includesBlockingLane(root, renderLanes)) pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot); + } + return nextSnapshot; + } + function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) { + fiber.flags |= StoreConsistency; + var check = { + getSnapshot: getSnapshot, + value: renderedSnapshot + }; + var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; + if (componentUpdateQueue === null) { + componentUpdateQueue = createFunctionComponentUpdateQueue(); + currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; + componentUpdateQueue.stores = [ + check + ]; + } else { + var stores = componentUpdateQueue.stores; + if (stores === null) componentUpdateQueue.stores = [ + check + ]; + else stores.push(check); + } + } + function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) { + // These are updated in the passive phase + inst.value = nextSnapshot; + inst.getSnapshot = getSnapshot; // Something may have been mutated in between render and commit. This could + // have been in an event that fired before the passive effects, or it could + // have been in a layout effect. In that case, we would have used the old + // snapsho and getSnapshot values to bail out. We need to check one more time. + if (checkIfSnapshotChanged(inst)) // Force a re-render. + forceStoreRerender(fiber); + } + function subscribeToStore(fiber, inst, subscribe) { + var handleStoreChange = function() { + // The store changed. Check if the snapshot changed since the last time we + // read from the store. + if (checkIfSnapshotChanged(inst)) // Force a re-render. + forceStoreRerender(fiber); + }; // Subscribe to the store and return a clean-up function. + return subscribe(handleStoreChange); + } + function checkIfSnapshotChanged(inst) { + var latestGetSnapshot = inst.getSnapshot; + var prevValue = inst.value; + try { + var nextValue = latestGetSnapshot(); + return !objectIs(prevValue, nextValue); + } catch (error) { + return true; + } + } + function forceStoreRerender(fiber) { + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); + } + function mountState(initialState) { + var hook = mountWorkInProgressHook(); + if (typeof initialState === "function") // $FlowFixMe: Flow doesn't like mixed types + initialState = initialState(); + hook.memoizedState = hook.baseState = initialState; + var queue = { + pending: null, + interleaved: null, + lanes: NoLanes, + dispatch: null, + lastRenderedReducer: basicStateReducer, + lastRenderedState: initialState + }; + hook.queue = queue; + var dispatch = queue.dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue); + return [ + hook.memoizedState, + dispatch + ]; + } + function updateState(initialState) { + return updateReducer(basicStateReducer); + } + function rerenderState(initialState) { + return rerenderReducer(basicStateReducer); + } + function pushEffect(tag, create, destroy, deps) { + var effect = { + tag: tag, + create: create, + destroy: destroy, + deps: deps, + // Circular + next: null + }; + var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; + if (componentUpdateQueue === null) { + componentUpdateQueue = createFunctionComponentUpdateQueue(); + currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; + componentUpdateQueue.lastEffect = effect.next = effect; + } else { + var lastEffect = componentUpdateQueue.lastEffect; + if (lastEffect === null) componentUpdateQueue.lastEffect = effect.next = effect; + else { + var firstEffect = lastEffect.next; + lastEffect.next = effect; + effect.next = firstEffect; + componentUpdateQueue.lastEffect = effect; + } + } + return effect; + } + function mountRef(initialValue) { + var hook = mountWorkInProgressHook(); + var _ref2 = { + current: initialValue + }; + hook.memoizedState = _ref2; + return _ref2; + } + function updateRef(initialValue) { + var hook = updateWorkInProgressHook(); + return hook.memoizedState; + } + function mountEffectImpl(fiberFlags, hookFlags, create, deps) { + var hook = mountWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + currentlyRenderingFiber$1.flags |= fiberFlags; + hook.memoizedState = pushEffect(HasEffect | hookFlags, create, undefined, nextDeps); + } + function updateEffectImpl(fiberFlags, hookFlags, create, deps) { + var hook = updateWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + var destroy = undefined; + if (currentHook !== null) { + var prevEffect = currentHook.memoizedState; + destroy = prevEffect.destroy; + if (nextDeps !== null) { + var prevDeps = prevEffect.deps; + if (areHookInputsEqual(nextDeps, prevDeps)) { + hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); + return; + } + } + } + currentlyRenderingFiber$1.flags |= fiberFlags; + hook.memoizedState = pushEffect(HasEffect | hookFlags, create, destroy, nextDeps); + } + function mountEffect(create, deps) { + if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) return mountEffectImpl(MountPassiveDev | Passive | PassiveStatic, Passive$1, create, deps); + else return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps); + } + function updateEffect(create, deps) { + return updateEffectImpl(Passive, Passive$1, create, deps); + } + function mountInsertionEffect(create, deps) { + return mountEffectImpl(Update, Insertion, create, deps); + } + function updateInsertionEffect(create, deps) { + return updateEffectImpl(Update, Insertion, create, deps); + } + function mountLayoutEffect(create, deps) { + var fiberFlags = Update; + fiberFlags |= LayoutStatic; + if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) fiberFlags |= MountLayoutDev; + return mountEffectImpl(fiberFlags, Layout, create, deps); + } + function updateLayoutEffect(create, deps) { + return updateEffectImpl(Update, Layout, create, deps); + } + function imperativeHandleEffect(create, ref) { + if (typeof ref === "function") { + var refCallback = ref; + var _inst = create(); + refCallback(_inst); + return function() { + refCallback(null); + }; + } else if (ref !== null && ref !== undefined) { + var refObject = ref; + if (!refObject.hasOwnProperty("current")) error("Expected useImperativeHandle() first argument to either be a ref callback or React.createRef() object. Instead received: %s.", "an object with keys {" + Object.keys(refObject).join(", ") + "}"); + var _inst2 = create(); + refObject.current = _inst2; + return function() { + refObject.current = null; + }; + } + } + function mountImperativeHandle(ref, create, deps) { + if (typeof create !== "function") error("Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: %s.", create !== null ? typeof create : "null"); + var effectDeps = deps !== null && deps !== undefined ? deps.concat([ + ref + ]) : null; + var fiberFlags = Update; + fiberFlags |= LayoutStatic; + if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) fiberFlags |= MountLayoutDev; + return mountEffectImpl(fiberFlags, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps); + } + function updateImperativeHandle(ref, create, deps) { + if (typeof create !== "function") error("Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: %s.", create !== null ? typeof create : "null"); + var effectDeps = deps !== null && deps !== undefined ? deps.concat([ + ref + ]) : null; + return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps); + } + function mountDebugValue(value, formatterFn) { + // The react-debug-hooks package injects its own implementation + // so that e.g. DevTools can display custom hook values. + } + var updateDebugValue = mountDebugValue; + function mountCallback(callback, deps) { + var hook = mountWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + hook.memoizedState = [ + callback, + nextDeps + ]; + return callback; + } + function updateCallback(callback, deps) { + var hook = updateWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + var prevState = hook.memoizedState; + if (prevState !== null) { + if (nextDeps !== null) { + var prevDeps = prevState[1]; + if (areHookInputsEqual(nextDeps, prevDeps)) return prevState[0]; + } + } + hook.memoizedState = [ + callback, + nextDeps + ]; + return callback; + } + function mountMemo(nextCreate, deps) { + var hook = mountWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + var nextValue = nextCreate(); + hook.memoizedState = [ + nextValue, + nextDeps + ]; + return nextValue; + } + function updateMemo(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + var nextDeps = deps === undefined ? null : deps; + var prevState = hook.memoizedState; + if (prevState !== null) // Assume these are defined. If they're not, areHookInputsEqual will warn. + { + if (nextDeps !== null) { + var prevDeps = prevState[1]; + if (areHookInputsEqual(nextDeps, prevDeps)) return prevState[0]; + } + } + var nextValue = nextCreate(); + hook.memoizedState = [ + nextValue, + nextDeps + ]; + return nextValue; + } + function mountDeferredValue(value) { + var hook = mountWorkInProgressHook(); + hook.memoizedState = value; + return value; + } + function updateDeferredValue(value) { + var hook = updateWorkInProgressHook(); + var resolvedCurrentHook = currentHook; + var prevValue = resolvedCurrentHook.memoizedState; + return updateDeferredValueImpl(hook, prevValue, value); + } + function rerenderDeferredValue(value) { + var hook = updateWorkInProgressHook(); + if (currentHook === null) { + // This is a rerender during a mount. + hook.memoizedState = value; + return value; + } else { + // This is a rerender during an update. + var prevValue = currentHook.memoizedState; + return updateDeferredValueImpl(hook, prevValue, value); + } + } + function updateDeferredValueImpl(hook, prevValue, value) { + var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes); + if (shouldDeferValue) { + // This is an urgent update. If the value has changed, keep using the + // previous value and spawn a deferred render to update it later. + if (!objectIs(value, prevValue)) { + // Schedule a deferred render + var deferredLane = claimNextTransitionLane(); + currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, deferredLane); + markSkippedUpdateLanes(deferredLane); // Set this to true to indicate that the rendered value is inconsistent + // from the latest value. The name "baseState" doesn't really match how we + // use it because we're reusing a state hook field instead of creating a + // new one. + hook.baseState = true; + } // Reuse the previous value + return prevValue; + } else { + // This is not an urgent update, so we can use the latest value regardless + // of what it is. No need to defer it. + // However, if we're currently inside a spawned render, then we need to mark + // this as an update to prevent the fiber from bailing out. + // + // `baseState` is true when the current value is different from the rendered + // value. The name doesn't really match how we use it because we're reusing + // a state hook field instead of creating a new one. + if (hook.baseState) { + // Flip this back to false. + hook.baseState = false; + markWorkInProgressReceivedUpdate(); + } + hook.memoizedState = value; + return value; + } + } + function startTransition(setPending, callback, options) { + var previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority(higherEventPriority(previousPriority, ContinuousEventPriority)); + setPending(true); + var prevTransition = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition = {}; + var currentTransition = ReactCurrentBatchConfig$2.transition; + ReactCurrentBatchConfig$2.transition._updatedFibers = new Set(); + try { + setPending(false); + callback(); + } finally{ + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$2.transition = prevTransition; + if (prevTransition === null && currentTransition._updatedFibers) { + var updatedFibersCount = currentTransition._updatedFibers.size; + if (updatedFibersCount > 10) warn("Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table."); + currentTransition._updatedFibers.clear(); + } + } + } + function mountTransition() { + var _mountState = mountState(false), isPending = _mountState[0], setPending = _mountState[1]; // The `start` method never changes. + var start = startTransition.bind(null, setPending); + var hook = mountWorkInProgressHook(); + hook.memoizedState = start; + return [ + isPending, + start + ]; + } + function updateTransition() { + var _updateState = updateState(), isPending = _updateState[0]; + var hook = updateWorkInProgressHook(); + var start = hook.memoizedState; + return [ + isPending, + start + ]; + } + function rerenderTransition() { + var _rerenderState = rerenderState(), isPending = _rerenderState[0]; + var hook = updateWorkInProgressHook(); + var start = hook.memoizedState; + return [ + isPending, + start + ]; + } + var isUpdatingOpaqueValueInRenderPhase = false; + function getIsUpdatingOpaqueValueInRenderPhaseInDEV() { + return isUpdatingOpaqueValueInRenderPhase; + } + function mountId() { + var hook = mountWorkInProgressHook(); + var root = getWorkInProgressRoot(); // TODO: In Fizz, id generation is specific to each server config. Maybe we + // should do this in Fiber, too? Deferring this decision for now because + // there's no other place to store the prefix except for an internal field on + // the public createRoot object, which the fiber tree does not currently have + // a reference to. + var identifierPrefix = root.identifierPrefix; + var id; + if (getIsHydrating()) { + var treeId = getTreeId(); // Use a captial R prefix for server-generated ids. + id = ":" + identifierPrefix + "R" + treeId; // Unless this is the first id at this level, append a number at the end + // that represents the position of this useId hook among all the useId + // hooks for this fiber. + var localId = localIdCounter++; + if (localId > 0) id += "H" + localId.toString(32); + id += ":"; + } else { + // Use a lowercase r prefix for client-generated ids. + var globalClientId = globalClientIdCounter++; + id = ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":"; + } + hook.memoizedState = id; + return id; + } + function updateId() { + var hook = updateWorkInProgressHook(); + var id = hook.memoizedState; + return id; + } + function dispatchReducerAction(fiber, queue, action) { + if (typeof arguments[3] === "function") error("State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect()."); + var lane = requestUpdateLane(fiber); + var update = { + lane: lane, + action: action, + hasEagerState: false, + eagerState: null, + next: null + }; + if (isRenderPhaseUpdate(fiber)) enqueueRenderPhaseUpdate(queue, update); + else { + var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane); + if (root !== null) { + var eventTime = requestEventTime(); + scheduleUpdateOnFiber(root, fiber, lane, eventTime); + entangleTransitionUpdate(root, queue, lane); + } + } + markUpdateInDevTools(fiber, lane); + } + function dispatchSetState(fiber, queue, action) { + if (typeof arguments[3] === "function") error("State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect()."); + var lane = requestUpdateLane(fiber); + var update = { + lane: lane, + action: action, + hasEagerState: false, + eagerState: null, + next: null + }; + if (isRenderPhaseUpdate(fiber)) enqueueRenderPhaseUpdate(queue, update); + else { + var alternate = fiber.alternate; + if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) { + // The queue is currently empty, which means we can eagerly compute the + // next state before entering the render phase. If the new state is the + // same as the current state, we may be able to bail out entirely. + var lastRenderedReducer = queue.lastRenderedReducer; + if (lastRenderedReducer !== null) { + var prevDispatcher; + prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { + var currentState = queue.lastRenderedState; + var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute + // it, on the update object. If the reducer hasn't changed by the + // time we enter the render phase, then the eager state can be used + // without calling the reducer again. + update.hasEagerState = true; + update.eagerState = eagerState; + if (objectIs(eagerState, currentState)) { + // Fast path. We can bail out without scheduling React to re-render. + // It's still possible that we'll need to rebase this update later, + // if the component re-renders for a different reason and by that + // time the reducer has changed. + // TODO: Do we still need to entangle transitions in this case? + enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update, lane); + return; + } + } catch (error) {} finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + } + } + var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane); + if (root !== null) { + var eventTime = requestEventTime(); + scheduleUpdateOnFiber(root, fiber, lane, eventTime); + entangleTransitionUpdate(root, queue, lane); + } + } + markUpdateInDevTools(fiber, lane); + } + function isRenderPhaseUpdate(fiber) { + var alternate = fiber.alternate; + return fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1; + } + function enqueueRenderPhaseUpdate(queue, update) { + // This is a render phase update. Stash it in a lazily-created map of + // queue -> linked list of updates. After this render pass, we'll restart + // and apply the stashed updates on top of the work-in-progress hook. + didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true; + var pending = queue.pending; + if (pending === null) // This is the first update. Create a circular list. + update.next = update; + else { + update.next = pending.next; + pending.next = update; + } + queue.pending = update; + } // TODO: Move to ReactFiberConcurrentUpdates? + function entangleTransitionUpdate(root, queue, lane) { + if (isTransitionLane(lane)) { + var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they + // must have finished. We can remove them from the shared queue, which + // represents a superset of the actually pending lanes. In some cases we + // may entangle more than we need to, but that's OK. In fact it's worse if + // we *don't* entangle when we should. + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + var newQueueLanes = mergeLanes(queueLanes, lane); + queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + markRootEntangled(root, newQueueLanes); + } + } + function markUpdateInDevTools(fiber, lane, action) { + markStateUpdateScheduled(fiber, lane); + } + var ContextOnlyDispatcher = { + readContext: readContext, + useCallback: throwInvalidHookError, + useContext: throwInvalidHookError, + useEffect: throwInvalidHookError, + useImperativeHandle: throwInvalidHookError, + useInsertionEffect: throwInvalidHookError, + useLayoutEffect: throwInvalidHookError, + useMemo: throwInvalidHookError, + useReducer: throwInvalidHookError, + useRef: throwInvalidHookError, + useState: throwInvalidHookError, + useDebugValue: throwInvalidHookError, + useDeferredValue: throwInvalidHookError, + useTransition: throwInvalidHookError, + useMutableSource: throwInvalidHookError, + useSyncExternalStore: throwInvalidHookError, + useId: throwInvalidHookError, + unstable_isNewReconciler: enableNewReconciler + }; + var HooksDispatcherOnMountInDEV = null; + var HooksDispatcherOnMountWithHookTypesInDEV = null; + var HooksDispatcherOnUpdateInDEV = null; + var HooksDispatcherOnRerenderInDEV = null; + var InvalidNestedHooksDispatcherOnMountInDEV = null; + var InvalidNestedHooksDispatcherOnUpdateInDEV = null; + var InvalidNestedHooksDispatcherOnRerenderInDEV = null; + var warnInvalidContextAccess = function() { + error("Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()."); + }; + var warnInvalidHookAccess = function() { + error("Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function. For more information, see https://reactjs.org/link/rules-of-hooks"); + }; + HooksDispatcherOnMountInDEV = { + readContext: function(context) { + return readContext(context); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountCallback(callback, deps); + }, + useContext: function(context) { + currentHookNameInDev = "useContext"; + mountHookTypesDev(); + return readContext(context); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function(create, deps) { + currentHookNameInDev = "useInsertionEffect"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountInsertionEffect(create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + return mountLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + mountHookTypesDev(); + checkDepsAreArrayDev(deps); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { + return mountMemo(create, deps); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { + return mountReducer(reducer, initialArg, init); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + mountHookTypesDev(); + return mountRef(initialValue); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { + return mountState(initialState); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + mountHookTypesDev(); + return mountDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + mountHookTypesDev(); + return mountDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + mountHookTypesDev(); + return mountTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + mountHookTypesDev(); + return mountMutableSource(); + }, + useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) { + currentHookNameInDev = "useSyncExternalStore"; + mountHookTypesDev(); + return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); + }, + useId: function() { + currentHookNameInDev = "useId"; + mountHookTypesDev(); + return mountId(); + }, + unstable_isNewReconciler: enableNewReconciler + }; + HooksDispatcherOnMountWithHookTypesInDEV = { + readContext: function(context) { + return readContext(context); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + updateHookTypesDev(); + return mountCallback(callback, deps); + }, + useContext: function(context) { + currentHookNameInDev = "useContext"; + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + updateHookTypesDev(); + return mountEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + updateHookTypesDev(); + return mountImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function(create, deps) { + currentHookNameInDev = "useInsertionEffect"; + updateHookTypesDev(); + return mountInsertionEffect(create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + updateHookTypesDev(); + return mountLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { + return mountMemo(create, deps); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { + return mountReducer(reducer, initialArg, init); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + updateHookTypesDev(); + return mountRef(initialValue); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { + return mountState(initialState); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + updateHookTypesDev(); + return mountDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + updateHookTypesDev(); + return mountDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + updateHookTypesDev(); + return mountTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + updateHookTypesDev(); + return mountMutableSource(); + }, + useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) { + currentHookNameInDev = "useSyncExternalStore"; + updateHookTypesDev(); + return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); + }, + useId: function() { + currentHookNameInDev = "useId"; + updateHookTypesDev(); + return mountId(); + }, + unstable_isNewReconciler: enableNewReconciler + }; + HooksDispatcherOnUpdateInDEV = { + readContext: function(context) { + return readContext(context); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function(context) { + currentHookNameInDev = "useContext"; + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function(create, deps) { + currentHookNameInDev = "useInsertionEffect"; + updateHookTypesDev(); + return updateInsertionEffect(create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { + return updateMemo(create, deps); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { + return updateReducer(reducer, initialArg, init); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + updateHookTypesDev(); + return updateRef(); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { + return updateState(initialState); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + updateHookTypesDev(); + return updateDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + updateHookTypesDev(); + return updateTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + updateHookTypesDev(); + return updateMutableSource(); + }, + useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) { + currentHookNameInDev = "useSyncExternalStore"; + updateHookTypesDev(); + return updateSyncExternalStore(subscribe, getSnapshot); + }, + useId: function() { + currentHookNameInDev = "useId"; + updateHookTypesDev(); + return updateId(); + }, + unstable_isNewReconciler: enableNewReconciler + }; + HooksDispatcherOnRerenderInDEV = { + readContext: function(context) { + return readContext(context); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function(context) { + currentHookNameInDev = "useContext"; + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function(create, deps) { + currentHookNameInDev = "useInsertionEffect"; + updateHookTypesDev(); + return updateInsertionEffect(create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + try { + return updateMemo(create, deps); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + try { + return rerenderReducer(reducer, initialArg, init); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + updateHookTypesDev(); + return updateRef(); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + try { + return rerenderState(initialState); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + updateHookTypesDev(); + return rerenderDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + updateHookTypesDev(); + return rerenderTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + updateHookTypesDev(); + return updateMutableSource(); + }, + useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) { + currentHookNameInDev = "useSyncExternalStore"; + updateHookTypesDev(); + return updateSyncExternalStore(subscribe, getSnapshot); + }, + useId: function() { + currentHookNameInDev = "useId"; + updateHookTypesDev(); + return updateId(); + }, + unstable_isNewReconciler: enableNewReconciler + }; + InvalidNestedHooksDispatcherOnMountInDEV = { + readContext: function(context) { + warnInvalidContextAccess(); + return readContext(context); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountCallback(callback, deps); + }, + useContext: function(context) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return readContext(context); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function(create, deps) { + currentHookNameInDev = "useInsertionEffect"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountInsertionEffect(create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { + return mountMemo(create, deps); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { + return mountReducer(reducer, initialArg, init); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountRef(initialValue); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { + return mountState(initialState); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountMutableSource(); + }, + useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) { + currentHookNameInDev = "useSyncExternalStore"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); + }, + useId: function() { + currentHookNameInDev = "useId"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountId(); + }, + unstable_isNewReconciler: enableNewReconciler + }; + InvalidNestedHooksDispatcherOnUpdateInDEV = { + readContext: function(context) { + warnInvalidContextAccess(); + return readContext(context); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function(context) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function(create, deps) { + currentHookNameInDev = "useInsertionEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateInsertionEffect(create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { + return updateMemo(create, deps); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { + return updateReducer(reducer, initialArg, init); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { + return updateState(initialState); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateMutableSource(); + }, + useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) { + currentHookNameInDev = "useSyncExternalStore"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateSyncExternalStore(subscribe, getSnapshot); + }, + useId: function() { + currentHookNameInDev = "useId"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateId(); + }, + unstable_isNewReconciler: enableNewReconciler + }; + InvalidNestedHooksDispatcherOnRerenderInDEV = { + readContext: function(context) { + warnInvalidContextAccess(); + return readContext(context); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function(context) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return readContext(context); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useInsertionEffect: function(create, deps) { + currentHookNameInDev = "useInsertionEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateInsertionEffect(create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { + return updateMemo(create, deps); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { + return rerenderReducer(reducer, initialArg, init); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { + return rerenderState(initialState); + } finally{ + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateMutableSource(); + }, + useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) { + currentHookNameInDev = "useSyncExternalStore"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateSyncExternalStore(subscribe, getSnapshot); + }, + useId: function() { + currentHookNameInDev = "useId"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateId(); + }, + unstable_isNewReconciler: enableNewReconciler + }; + var now$1 = Scheduler.unstable_now; + var commitTime = 0; + var layoutEffectStartTime = -1; + var profilerStartTime = -1; + var passiveEffectStartTime = -1; + /** + * Tracks whether the current update was a nested/cascading update (scheduled from a layout effect). + * + * The overall sequence is: + * 1. render + * 2. commit (and call `onRender`, `onCommit`) + * 3. check for nested updates + * 4. flush passive effects (and call `onPostCommit`) + * + * Nested updates are identified in step 3 above, + * but step 4 still applies to the work that was just committed. + * We use two flags to track nested updates then: + * one tracks whether the upcoming update is a nested update, + * and the other tracks whether the current update was a nested update. + * The first value gets synced to the second at the start of the render phase. + */ var currentUpdateIsNested = false; + var nestedUpdateScheduled = false; + function isCurrentUpdateNested() { + return currentUpdateIsNested; + } + function markNestedUpdateScheduled() { + nestedUpdateScheduled = true; + } + function resetNestedUpdateFlag() { + currentUpdateIsNested = false; + nestedUpdateScheduled = false; + } + function syncNestedUpdateFlag() { + currentUpdateIsNested = nestedUpdateScheduled; + nestedUpdateScheduled = false; + } + function getCommitTime() { + return commitTime; + } + function recordCommitTime() { + commitTime = now$1(); + } + function startProfilerTimer(fiber) { + profilerStartTime = now$1(); + if (fiber.actualStartTime < 0) fiber.actualStartTime = now$1(); + } + function stopProfilerTimerIfRunning(fiber) { + profilerStartTime = -1; + } + function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (profilerStartTime >= 0) { + var elapsedTime = now$1() - profilerStartTime; + fiber.actualDuration += elapsedTime; + if (overrideBaseTime) fiber.selfBaseDuration = elapsedTime; + profilerStartTime = -1; + } + } + function recordLayoutEffectDuration(fiber) { + if (layoutEffectStartTime >= 0) { + var elapsedTime = now$1() - layoutEffectStartTime; + layoutEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor + // Or the root (for the DevTools Profiler to read) + var parentFiber = fiber.return; + while(parentFiber !== null){ + switch(parentFiber.tag){ + case HostRoot: + var root = parentFiber.stateNode; + root.effectDuration += elapsedTime; + return; + case Profiler: + var parentStateNode = parentFiber.stateNode; + parentStateNode.effectDuration += elapsedTime; + return; + } + parentFiber = parentFiber.return; + } + } + } + function recordPassiveEffectDuration(fiber) { + if (passiveEffectStartTime >= 0) { + var elapsedTime = now$1() - passiveEffectStartTime; + passiveEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor + // Or the root (for the DevTools Profiler to read) + var parentFiber = fiber.return; + while(parentFiber !== null){ + switch(parentFiber.tag){ + case HostRoot: + var root = parentFiber.stateNode; + if (root !== null) root.passiveEffectDuration += elapsedTime; + return; + case Profiler: + var parentStateNode = parentFiber.stateNode; + if (parentStateNode !== null) // Detached fibers have their state node cleared out. + // In this case, the return pointer is also cleared out, + // so we won't be able to report the time spent in this Profiler's subtree. + parentStateNode.passiveEffectDuration += elapsedTime; + return; + } + parentFiber = parentFiber.return; + } + } + } + function startLayoutEffectTimer() { + layoutEffectStartTime = now$1(); + } + function startPassiveEffectTimer() { + passiveEffectStartTime = now$1(); + } + function transferActualDuration(fiber) { + // Transfer time spent rendering these children so we don't lose it + // after we rerender. This is used as a helper in special cases + // where we should count the work of multiple passes. + var child = fiber.child; + while(child){ + fiber.actualDuration += child.actualDuration; + child = child.sibling; + } + } + function createCapturedValueAtFiber(value, source) { + // If the value is an error, call this function immediately after it is thrown + // so the stack is accurate. + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source), + digest: null + }; + } + function createCapturedValue(value, digest, stack) { + return { + value: value, + source: null, + stack: stack != null ? stack : null, + digest: digest != null ? digest : null + }; + } + // This module is forked in different environments. + // By default, return `true` to log errors to the console. + // Forks can return `false` if this isn't desirable. + function showErrorDialog(boundary, errorInfo) { + return true; + } + function logCapturedError(boundary, errorInfo) { + try { + var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. + if (logError === false) return; + var error = errorInfo.value; + var source = errorInfo.source; + var stack = errorInfo.stack; + var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling + // `preventDefault()` in window `error` handler. + // We record this information as an expando on the error. + if (error != null && error._suppressLogging) { + if (boundary.tag === ClassComponent) // The error is recoverable and was silenced. + // Ignore it and don't print the stack addendum. + // This is handy for testing error boundaries without noise. + return; + // The error is fatal. Since the silencing might have + // been accidental, we'll surface it anyway. + // However, the browser would have silenced the original error + // so we'll print it first, and then print the stack addendum. + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: + // https://github.com/facebook/react/pull/13384 + } + var componentName = source ? getComponentNameFromFiber(source) : null; + var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : "The above error occurred in one of your React components:"; + var errorBoundaryMessage; + if (boundary.tag === HostRoot) errorBoundaryMessage = "Consider adding an error boundary to your tree to customize error handling behavior.\nVisit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; + else { + var errorBoundaryName = getComponentNameFromFiber(boundary) || "Anonymous"; + errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + "."); + } + var combinedMessage = componentNameMessage + "\n" + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. + // We don't include the original error message and JS stack because the browser + // has already printed it. Even if the application swallows the error, it is still + // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. + console["error"](combinedMessage); // Don't transform to our wrapper + } catch (e) { + // This method must not throw, or React internal state will get messed up. + // If console.error is overridden, or logCapturedError() shows a dialog that throws, + // we want to report this error outside of the normal stack as a last resort. + // https://github.com/facebook/react/issues/13188 + setTimeout(function() { + throw e; + }); + } + } + var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; + function createRootErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. + update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property + // being called "element". + update.payload = { + element: null + }; + var error = errorInfo.value; + update.callback = function() { + onUncaughtError(error); + logCapturedError(fiber, errorInfo); + }; + return update; + } + function createClassErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); + update.tag = CaptureUpdate; + var getDerivedStateFromError = fiber.type.getDerivedStateFromError; + if (typeof getDerivedStateFromError === "function") { + var error$1 = errorInfo.value; + update.payload = function() { + return getDerivedStateFromError(error$1); + }; + update.callback = function() { + markFailedErrorBoundaryForHotReloading(fiber); + logCapturedError(fiber, errorInfo); + }; + } + var inst = fiber.stateNode; + if (inst !== null && typeof inst.componentDidCatch === "function") update.callback = function callback() { + markFailedErrorBoundaryForHotReloading(fiber); + logCapturedError(fiber, errorInfo); + if (typeof getDerivedStateFromError !== "function") // To preserve the preexisting retry behavior of error boundaries, + // we keep track of which ones already failed during this batch. + // This gets reset before we yield back to the browser. + // TODO: Warn in strict mode if getDerivedStateFromError is + // not defined. + markLegacyErrorBoundaryAsFailed(this); + var error$1 = errorInfo.value; + var stack = errorInfo.stack; + this.componentDidCatch(error$1, { + componentStack: stack !== null ? stack : "" + }); + if (typeof getDerivedStateFromError !== "function") // If componentDidCatch is the only error boundary method defined, + // then it needs to call setState to recover from errors. + // If no state update is scheduled then the boundary will swallow the error. + { + if (!includesSomeLane(fiber.lanes, SyncLane)) error("%s: Error boundaries should implement getDerivedStateFromError(). In that method, return a state update to display an error message or fallback UI.", getComponentNameFromFiber(fiber) || "Unknown"); + } + }; + return update; + } + function attachPingListener(root, wakeable, lanes) { + // Attach a ping listener + // + // The data might resolve before we have a chance to commit the fallback. Or, + // in the case of a refresh, we'll never commit a fallback. So we need to + // attach a listener now. When it resolves ("pings"), we can decide whether to + // try rendering the tree again. + // + // Only attach a listener if one does not already exist for the lanes + // we're currently rendering (which acts like a "thread ID" here). + // + // We only need to do this in concurrent mode. Legacy Suspense always + // commits fallbacks synchronously, so there are no pings. + var pingCache = root.pingCache; + var threadIDs; + if (pingCache === null) { + pingCache = root.pingCache = new PossiblyWeakMap$1(); + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } else { + threadIDs = pingCache.get(wakeable); + if (threadIDs === undefined) { + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } + } + if (!threadIDs.has(lanes)) { + // Memoize using the thread ID to prevent redundant listeners. + threadIDs.add(lanes); + var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); + if (isDevToolsPresent) // If we have pending work still, restore the original updaters + restorePendingUpdaters(root, lanes); + wakeable.then(ping, ping); + } + } + function attachRetryListener(suspenseBoundary, root, wakeable, lanes) { + // Retry listener + // + // If the fallback does commit, we need to attach a different type of + // listener. This one schedules an update on the Suspense boundary to turn + // the fallback state off. + // + // Stash the wakeable on the boundary fiber so we can access it in the + // commit phase. + // + // When the wakeable resolves, we'll attempt to render the boundary + // again ("retry"). + var wakeables = suspenseBoundary.updateQueue; + if (wakeables === null) { + var updateQueue = new Set(); + updateQueue.add(wakeable); + suspenseBoundary.updateQueue = updateQueue; + } else wakeables.add(wakeable); + } + function resetSuspendedComponent(sourceFiber, rootRenderLanes) { + // A legacy mode Suspense quirk, only relevant to hook components. + var tag = sourceFiber.tag; + if ((sourceFiber.mode & ConcurrentMode) === NoMode && (tag === FunctionComponent || tag === ForwardRef || tag === SimpleMemoComponent)) { + var currentSource = sourceFiber.alternate; + if (currentSource) { + sourceFiber.updateQueue = currentSource.updateQueue; + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.lanes = currentSource.lanes; + } else { + sourceFiber.updateQueue = null; + sourceFiber.memoizedState = null; + } + } + } + function getNearestSuspenseBoundaryToCapture(returnFiber) { + var node = returnFiber; + do { + if (node.tag === SuspenseComponent && shouldCaptureSuspense(node)) return node; + // This boundary already captured during this render. Continue to the next + // boundary. + node = node.return; + }while (node !== null); + return null; + } + function markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes) { + // This marks a Suspense boundary so that when we're unwinding the stack, + // it captures the suspended "exception" and does a second (fallback) pass. + if ((suspenseBoundary.mode & ConcurrentMode) === NoMode) { + // Legacy Mode Suspense + // + // If the boundary is in legacy mode, we should *not* + // suspend the commit. Pretend as if the suspended component rendered + // null and keep rendering. When the Suspense boundary completes, + // we'll do a second pass to render the fallback. + if (suspenseBoundary === returnFiber) // Special case where we suspended while reconciling the children of + // a Suspense boundary's inner Offscreen wrapper fiber. This happens + // when a React.lazy component is a direct child of a + // Suspense boundary. + // + // Suspense boundaries are implemented as multiple fibers, but they + // are a single conceptual unit. The legacy mode behavior where we + // pretend the suspended fiber committed as `null` won't work, + // because in this case the "suspended" fiber is the inner + // Offscreen wrapper. + // + // Because the contents of the boundary haven't started rendering + // yet (i.e. nothing in the tree has partially rendered) we can + // switch to the regular, concurrent mode behavior: mark the + // boundary with ShouldCapture and enter the unwind phase. + suspenseBoundary.flags |= ShouldCapture; + else { + suspenseBoundary.flags |= DidCapture; + sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. + // But we shouldn't call any lifecycle methods or callbacks. Remove + // all lifecycle effect tags. + sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); + if (sourceFiber.tag === ClassComponent) { + var currentSourceFiber = sourceFiber.alternate; + if (currentSourceFiber === null) // This is a new mount. Change the tag so it's not mistaken for a + // completed class component. For example, we should not call + // componentWillUnmount if it is deleted. + sourceFiber.tag = IncompleteClassComponent; + else { + // When we try rendering again, we should not reuse the current fiber, + // since it's known to be in an inconsistent state. Use a force update to + // prevent a bail out. + var update = createUpdate(NoTimestamp, SyncLane); + update.tag = ForceUpdate; + enqueueUpdate(sourceFiber, update, SyncLane); + } + } // The source fiber did not complete. Mark it with Sync priority to + // indicate that it still has pending work. + sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); + } + return suspenseBoundary; + } // Confirmed that the boundary is in a concurrent mode tree. Continue + // with the normal suspend path. + // + // After this we'll use a set of heuristics to determine whether this + // render pass will run to completion or restart or "suspend" the commit. + // The actual logic for this is spread out in different places. + // + // This first principle is that if we're going to suspend when we complete + // a root, then we should also restart if we get an update or ping that + // might unsuspend it, and vice versa. The only reason to suspend is + // because you think you might want to restart before committing. However, + // it doesn't make sense to restart only while in the period we're suspended. + // + // Restarting too aggressively is also not good because it starves out any + // intermediate loading state. So we use heuristics to determine when. + // Suspense Heuristics + // + // If nothing threw a Promise or all the same fallbacks are already showing, + // then don't suspend/restart. + // + // If this is an initial render of a new tree of Suspense boundaries and + // those trigger a fallback, then don't suspend/restart. We want to ensure + // that we can show the initial loading state as quickly as possible. + // + // If we hit a "Delayed" case, such as when we'd switch from content back into + // a fallback, then we should always suspend/restart. Transitions apply + // to this case. If none is defined, JND is used instead. + // + // If we're already showing a fallback and it gets "retried", allowing us to show + // another level, but there's still an inner boundary that would show a fallback, + // then we suspend/restart for 500ms since the last time we showed a fallback + // anywhere in the tree. This effectively throttles progressive loading into a + // consistent train of commits. This also gives us an opportunity to restart to + // get to the completed state slightly earlier. + // + // If there's ambiguity due to batching it's resolved in preference of: + // 1) "delayed", 2) "initial render", 3) "retry". + // + // We want to ensure that a "busy" state doesn't get force committed. We want to + // ensure that new initial loading states can commit as soon as possible. + suspenseBoundary.flags |= ShouldCapture; // TODO: I think we can remove this, since we now use `DidCapture` in + // the begin phase to prevent an early bailout. + suspenseBoundary.lanes = rootRenderLanes; + return suspenseBoundary; + } + function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) { + // The source fiber did not complete. + sourceFiber.flags |= Incomplete; + if (isDevToolsPresent) // If we have pending work still, restore the original updaters + restorePendingUpdaters(root, rootRenderLanes); + if (value !== null && typeof value === "object" && typeof value.then === "function") { + // This is a wakeable. The component suspended. + var wakeable = value; + resetSuspendedComponent(sourceFiber); + if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) markDidThrowWhileHydratingDEV(); + var suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber); + if (suspenseBoundary !== null) { + suspenseBoundary.flags &= ~ForceClientRender; + markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // We only attach ping listeners in concurrent mode. Legacy Suspense always + // commits fallbacks synchronously, so there are no pings. + if (suspenseBoundary.mode & ConcurrentMode) attachPingListener(root, wakeable, rootRenderLanes); + attachRetryListener(suspenseBoundary, root, wakeable); + return; + } else { + // No boundary was found. Unless this is a sync update, this is OK. + // We can suspend and wait for more data to arrive. + if (!includesSyncLane(rootRenderLanes)) { + // This is not a sync update. Suspend. Since we're not activating a + // Suspense boundary, this will unwind all the way to the root without + // performing a second pass to render a fallback. (This is arguably how + // refresh transitions should work, too, since we're not going to commit + // the fallbacks anyway.) + // + // This case also applies to initial hydration. + attachPingListener(root, wakeable, rootRenderLanes); + renderDidSuspendDelayIfPossible(); + return; + } // This is a sync/discrete update. We treat this case like an error + // because discrete renders are expected to produce a complete tree + // synchronously to maintain consistency with external state. + var uncaughtSuspenseError = new Error("A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition."); // If we're outside a transition, fall through to the regular error path. + // The error will be caught by the nearest suspense boundary. + value = uncaughtSuspenseError; + } + } else // This is a regular error, not a Suspense wakeable. + if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) { + markDidThrowWhileHydratingDEV(); + var _suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber); // If the error was thrown during hydration, we may be able to recover by + // discarding the dehydrated content and switching to a client render. + // Instead of surfacing the error, find the nearest Suspense boundary + // and render it again without hydration. + if (_suspenseBoundary !== null) { + if ((_suspenseBoundary.flags & ShouldCapture) === NoFlags) // Set a flag to indicate that we should try rendering the normal + // children again, not the fallback. + _suspenseBoundary.flags |= ForceClientRender; + markSuspenseBoundaryShouldCapture(_suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // Even though the user may not be affected by this error, we should + // still log it so it can be fixed. + queueHydrationError(createCapturedValueAtFiber(value, sourceFiber)); + return; + } + } + value = createCapturedValueAtFiber(value, sourceFiber); + renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start + // over and traverse parent path again, this time treating the exception + // as an error. + var workInProgress = returnFiber; + do { + switch(workInProgress.tag){ + case HostRoot: + var _errorInfo = value; + workInProgress.flags |= ShouldCapture; + var lane = pickArbitraryLane(rootRenderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); + var update = createRootErrorUpdate(workInProgress, _errorInfo, lane); + enqueueCapturedUpdate(workInProgress, update); + return; + case ClassComponent: + // Capture and retry + var errorInfo = value; + var ctor = workInProgress.type; + var instance = workInProgress.stateNode; + if ((workInProgress.flags & DidCapture) === NoFlags && (typeof ctor.getDerivedStateFromError === "function" || instance !== null && typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance))) { + workInProgress.flags |= ShouldCapture; + var _lane = pickArbitraryLane(rootRenderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state + var _update = createClassErrorUpdate(workInProgress, errorInfo, _lane); + enqueueCapturedUpdate(workInProgress, _update); + return; + } + break; + } + workInProgress = workInProgress.return; + }while (workInProgress !== null); + } + function getSuspendedCache() { + return null; + } + var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; + var didReceiveUpdate = false; + var didWarnAboutBadClass; + var didWarnAboutModulePatternComponent; + var didWarnAboutContextTypeOnFunctionComponent; + var didWarnAboutGetDerivedStateOnFunctionComponent; + var didWarnAboutFunctionRefs; + var didWarnAboutReassigningProps; + var didWarnAboutRevealOrder; + var didWarnAboutTailOptions; + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; + function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { + if (current === null) // If this is a fresh new component that hasn't been rendered yet, we + // won't update its child set by applying minimal side-effects. Instead, + // we will add them all to the child before it gets rendered. That means + // we can optimize this reconciliation pass by not tracking side-effects. + workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderLanes); + else // If the current child is the same as the work in progress, it means that + // we haven't yet started any work on these children. Therefore, we use + // the clone algorithm to create a copy of all the current children. + // If we had any progressed work already, that is invalid at this point so + // let's throw it out. + workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderLanes); + } + function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes) { + // This function is fork of reconcileChildren. It's used in cases where we + // want to reconcile without matching against the existing set. This has the + // effect of all current children being unmounted; even if the type and key + // are the same, the old child is unmounted and a new child is created. + // + // To do this, we're going to go through the reconcile algorithm twice. In + // the first pass, we schedule a deletion for all the current children by + // passing null. + workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderLanes); // In the second pass, we mount the new children. The trick here is that we + // pass null in place of where we usually pass the current child set. This has + // the effect of remounting all children regardless of whether their + // identities match. + workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes); + } + function updateForwardRef(current, workInProgress, Component, nextProps, renderLanes) { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; + if (innerPropTypes) checkPropTypes(innerPropTypes, nextProps, "prop", getComponentNameFromType(Component)); + } + var render = Component.render; + var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent + var nextChildren; + var hasId; + prepareToReadContext(workInProgress, renderLanes); + markComponentRenderStarted(workInProgress); + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes); + hasId = checkDidRenderIdHook(); + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + try { + nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes); + hasId = checkDidRenderIdHook(); + } finally{ + setIsStrictModeForDevtools(false); + } + } + setIsRendering(false); + markComponentRenderStopped(); + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + if (getIsHydrating() && hasId) pushMaterializedTreeId(workInProgress); + // React DevTools reads this flag. + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + function updateMemoComponent(current, workInProgress, Component, nextProps, renderLanes) { + if (current === null) { + var type = Component.type; + if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. + Component.defaultProps === undefined) { + var resolvedType = type; + resolvedType = resolveFunctionForHotReloading(type); + // and with only the default shallow comparison, we upgrade it + // to a SimpleMemoComponent to allow fast path updates. + workInProgress.tag = SimpleMemoComponent; + workInProgress.type = resolvedType; + validateFunctionComponentInDev(workInProgress, type); + return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, renderLanes); + } + var innerPropTypes = type.propTypes; + if (innerPropTypes) // Inner memo component props aren't currently validated in createElement. + // We could move it there, but we'd still need this for lazy code path. + checkPropTypes(innerPropTypes, nextProps, "prop", getComponentNameFromType(type)); + var child = createFiberFromTypeAndProps(Component.type, null, nextProps, workInProgress, workInProgress.mode, renderLanes); + child.ref = workInProgress.ref; + child.return = workInProgress; + workInProgress.child = child; + return child; + } + var _type = Component.type; + var _innerPropTypes = _type.propTypes; + if (_innerPropTypes) // Inner memo component props aren't currently validated in createElement. + // We could move it there, but we'd still need this for lazy code path. + checkPropTypes(_innerPropTypes, nextProps, "prop", getComponentNameFromType(_type)); + var currentChild = current.child; // This is always exactly one child + var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes); + if (!hasScheduledUpdateOrContext) { + // This will be the props with resolved defaultProps, + // unlike current.memoizedProps which will be the unresolved ones. + var prevProps = currentChild.memoizedProps; // Default to shallow comparison + var compare = Component.compare; + compare = compare !== null ? compare : shallowEqual; + if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } // React DevTools reads this flag. + workInProgress.flags |= PerformedWork; + var newChild = createWorkInProgress(currentChild, nextProps); + newChild.ref = workInProgress.ref; + newChild.return = workInProgress; + workInProgress.child = newChild; + return newChild; + } + function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, renderLanes) { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var outerMemoType = workInProgress.elementType; + if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { + // We warn when you define propTypes on lazy() + // so let's just skip over it to find memo() outer wrapper. + // Inner props for memo are validated later. + var lazyComponent = outerMemoType; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + try { + outerMemoType = init(payload); + } catch (x) { + outerMemoType = null; + } // Inner propTypes will be validated in the function component path. + var outerPropTypes = outerMemoType && outerMemoType.propTypes; + if (outerPropTypes) checkPropTypes(outerPropTypes, nextProps, "prop", getComponentNameFromType(outerMemoType)); + } + } + if (current !== null) { + var prevProps = current.memoizedProps; + if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && workInProgress.type === current.type) { + didReceiveUpdate = false; // The props are shallowly equal. Reuse the previous props object, like we + // would during a normal fiber bailout. + // + // We don't have strong guarantees that the props object is referentially + // equal during updates where we can't bail out anyway \u2014 like if the props + // are shallowly equal, but there's a local state or context update in the + // same batch. + // + // However, as a principle, we should aim to make the behavior consistent + // across different ways of memoizing a component. For example, React.memo + // has a different internal Fiber layout if you pass a normal function + // component (SimpleMemoComponent) versus if you pass a different type + // like forwardRef (MemoComponent). But this is an implementation detail. + // Wrapping a component in forwardRef (or React.lazy, etc) shouldn't + // affect whether the props object is reused during a bailout. + workInProgress.pendingProps = nextProps = prevProps; + if (!checkScheduledUpdateOrContext(current, renderLanes)) { + // The pending lanes were cleared at the beginning of beginWork. We're + // about to bail out, but there might be other lanes that weren't + // included in the current render. Usually, the priority level of the + // remaining updates is accumulated during the evaluation of the + // component (i.e. when processing the update queue). But since since + // we're bailing out early *without* evaluating the component, we need + // to account for it here, too. Reset to the value of the current fiber. + // NOTE: This only applies to SimpleMemoComponent, not MemoComponent, + // because a MemoComponent fiber does not have hooks or an update queue; + // rather, it wraps around an inner component, which may or may not + // contains hooks. + // TODO: Move the reset at in beginWork out of the common path so that + // this is no longer necessary. + workInProgress.lanes = current.lanes; + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) // This is a special case that only exists for legacy mode. + // See https://github.com/facebook/react/pull/19216. + didReceiveUpdate = true; + } + } + return updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes); + } + function updateOffscreenComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + var prevState = current !== null ? current.memoizedState : null; + if (nextProps.mode === "hidden" || enableLegacyHidden) { + // Rendering a hidden tree. + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + // In legacy sync mode, don't defer the subtree. Render it now. + // TODO: Consider how Offscreen should work with transitions in the future + var nextState = { + baseLanes: NoLanes, + cachePool: null, + transitions: null + }; + workInProgress.memoizedState = nextState; + pushRenderLanes(workInProgress, renderLanes); + } else if (!includesSomeLane(renderLanes, OffscreenLane)) { + var spawnedCachePool = null; // We're hidden, and we're not rendering at Offscreen. We will bail out + // and resume this tree later. + var nextBaseLanes; + if (prevState !== null) { + var prevBaseLanes = prevState.baseLanes; + nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); + } else nextBaseLanes = renderLanes; + // Schedule this fiber to re-render at offscreen priority. Then bailout. + workInProgress.lanes = workInProgress.childLanes = laneToLanes(OffscreenLane); + var _nextState = { + baseLanes: nextBaseLanes, + cachePool: spawnedCachePool, + transitions: null + }; + workInProgress.memoizedState = _nextState; + workInProgress.updateQueue = null; + // to avoid a push/pop misalignment. + pushRenderLanes(workInProgress, nextBaseLanes); + return null; + } else { + // This is the second render. The surrounding visible content has already + // committed. Now we resume rendering the hidden tree. + // Rendering at offscreen, so we can clear the base lanes. + var _nextState2 = { + baseLanes: NoLanes, + cachePool: null, + transitions: null + }; + workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. + var subtreeRenderLanes = prevState !== null ? prevState.baseLanes : renderLanes; + pushRenderLanes(workInProgress, subtreeRenderLanes); + } + } else { + // Rendering a visible tree. + var _subtreeRenderLanes; + if (prevState !== null) { + // We're going from hidden -> visible. + _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); + workInProgress.memoizedState = null; + } else // We weren't previously hidden, and we still aren't, so there's nothing + // special to do. Need to push to the stack regardless, though, to avoid + // a push/pop misalignment. + _subtreeRenderLanes = renderLanes; + pushRenderLanes(workInProgress, _subtreeRenderLanes); + } + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } // Note: These happen to have identical begin phases, for now. We shouldn't hold + function updateFragment(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + function updateMode(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + function updateProfiler(current, workInProgress, renderLanes) { + workInProgress.flags |= Update; + // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + function markRef(current, workInProgress) { + var ref = workInProgress.ref; + if (current === null && ref !== null || current !== null && current.ref !== ref) { + // Schedule a Ref effect + workInProgress.flags |= Ref; + workInProgress.flags |= RefStatic; + } + } + function updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes) { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; + if (innerPropTypes) checkPropTypes(innerPropTypes, nextProps, "prop", getComponentNameFromType(Component)); + } + var context; + var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); + var nextChildren; + var hasId; + prepareToReadContext(workInProgress, renderLanes); + markComponentRenderStarted(workInProgress); + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes); + hasId = checkDidRenderIdHook(); + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + try { + nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes); + hasId = checkDidRenderIdHook(); + } finally{ + setIsStrictModeForDevtools(false); + } + } + setIsRendering(false); + markComponentRenderStopped(); + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + if (getIsHydrating() && hasId) pushMaterializedTreeId(workInProgress); + // React DevTools reads this flag. + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + function updateClassComponent(current, workInProgress, Component, nextProps, renderLanes) { + // This is used by DevTools to force a boundary to error. + switch(shouldError(workInProgress)){ + case false: + var _instance = workInProgress.stateNode; + var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack. + // Is there a better way to do this? + var tempInstance = new ctor(workInProgress.memoizedProps, _instance.context); + var state = tempInstance.state; + _instance.updater.enqueueSetState(_instance, state, null); + break; + case true: + workInProgress.flags |= DidCapture; + workInProgress.flags |= ShouldCapture; // eslint-disable-next-line react-internal/prod-error-codes + var error$1 = new Error("Simulated error coming from DevTools"); + var lane = pickArbitraryLane(renderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state + var update = createClassErrorUpdate(workInProgress, createCapturedValueAtFiber(error$1, workInProgress), lane); + enqueueCapturedUpdate(workInProgress, update); + break; + } + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; + if (innerPropTypes) checkPropTypes(innerPropTypes, nextProps, "prop", getComponentNameFromType(Component)); + } + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. + var hasContext; + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else hasContext = false; + prepareToReadContext(workInProgress, renderLanes); + var instance = workInProgress.stateNode; + var shouldUpdate; + if (instance === null) { + resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); // In the initial pass we might need to construct the instance. + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + shouldUpdate = true; + } else if (current === null) // In a resume, we'll already have an instance we can reuse. + shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderLanes); + else shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderLanes); + var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes); + var inst = workInProgress.stateNode; + if (shouldUpdate && inst.props !== nextProps) { + if (!didWarnAboutReassigningProps) error("It looks like %s is reassigning its own `this.props` while rendering. This is not supported and can lead to confusing bugs.", getComponentNameFromFiber(workInProgress) || "a component"); + didWarnAboutReassigningProps = true; + } + return nextUnitOfWork; + } + function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes) { + // Refs should update even if shouldComponentUpdate returns false + markRef(current, workInProgress); + var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; + if (!shouldUpdate && !didCaptureError) { + // Context providers should defer to sCU for rendering + if (hasContext) invalidateContextProvider(workInProgress, Component, false); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + var instance = workInProgress.stateNode; // Rerender + ReactCurrentOwner$1.current = workInProgress; + var nextChildren; + if (didCaptureError && typeof Component.getDerivedStateFromError !== "function") { + // If we captured an error, but getDerivedStateFromError is not defined, + // unmount all the children. componentDidCatch will schedule an update to + // re-render a fallback. This is temporary until we migrate everyone to + // the new API. + // TODO: Warn in a future release. + nextChildren = null; + stopProfilerTimerIfRunning(); + } else { + markComponentRenderStarted(workInProgress); + setIsRendering(true); + nextChildren = instance.render(); + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + try { + instance.render(); + } finally{ + setIsStrictModeForDevtools(false); + } + } + setIsRendering(false); + markComponentRenderStopped(); + } // React DevTools reads this flag. + workInProgress.flags |= PerformedWork; + if (current !== null && didCaptureError) // If we're recovering from an error, reconcile without reusing any of + // the existing children. Conceptually, the normal children and the children + // that are shown on error are two different sets, so we shouldn't reuse + // normal children even if their identities match. + forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes); + else reconcileChildren(current, workInProgress, nextChildren, renderLanes); + // Memoize state using the values we just used to render. + // TODO: Restructure so we never read values from the instance. + workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + if (hasContext) invalidateContextProvider(workInProgress, Component, true); + return workInProgress.child; + } + function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; + if (root.pendingContext) pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context); + else if (root.context) // Should always be set + pushTopLevelContextObject(workInProgress, root.context, false); + pushHostContainer(workInProgress, root.containerInfo); + } + function updateHostRoot(current, workInProgress, renderLanes) { + pushHostRootContext(workInProgress); + if (current === null) throw new Error("Should have a current fiber. This is a bug in React."); + var nextProps = workInProgress.pendingProps; + var prevState = workInProgress.memoizedState; + var prevChildren = prevState.element; + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderLanes); + var nextState = workInProgress.memoizedState; + var root = workInProgress.stateNode; + // being called "element". + var nextChildren = nextState.element; + if (prevState.isDehydrated) { + // This is a hydration root whose shell has not yet hydrated. We should + // attempt to hydrate. + // Flip isDehydrated to false to indicate that when this render + // finishes, the root will no longer be dehydrated. + var overrideState = { + element: nextChildren, + isDehydrated: false, + cache: nextState.cache, + pendingSuspenseBoundaries: nextState.pendingSuspenseBoundaries, + transitions: nextState.transitions + }; + var updateQueue = workInProgress.updateQueue; // `baseState` can always be the last state because the root doesn't + // have reducer functions so it doesn't need rebasing. + updateQueue.baseState = overrideState; + workInProgress.memoizedState = overrideState; + if (workInProgress.flags & ForceClientRender) { + // Something errored during a previous attempt to hydrate the shell, so we + // forced a client render. + var recoverableError = createCapturedValueAtFiber(new Error("There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering."), workInProgress); + return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, recoverableError); + } else if (nextChildren !== prevChildren) { + var _recoverableError = createCapturedValueAtFiber(new Error("This root received an early update, before anything was able hydrate. Switched the entire root to client rendering."), workInProgress); + return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, _recoverableError); + } else { + // The outermost shell has not hydrated yet. Start hydrating. + enterHydrationState(workInProgress); + var child = mountChildFibers(workInProgress, null, nextChildren, renderLanes); + workInProgress.child = child; + var node = child; + while(node){ + // Mark each child as hydrating. This is a fast path to know whether this + // tree is part of a hydrating tree. This is used to determine if a child + // node has fully mounted yet, and for scheduling event replaying. + // Conceptually this is similar to Placement in that a new subtree is + // inserted into the React tree here. It just happens to not need DOM + // mutations because it already exists. + node.flags = node.flags & ~Placement | Hydrating; + node = node.sibling; + } + } + } else { + // Root is not dehydrated. Either this is a client-only root, or it + // already hydrated. + resetHydrationState(); + if (nextChildren === prevChildren) return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } + return workInProgress.child; + } + function mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, recoverableError) { + // Revert to client rendering. + resetHydrationState(); + queueHydrationError(recoverableError); + workInProgress.flags |= ForceClientRender; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + function updateHostComponent(current, workInProgress, renderLanes) { + pushHostContext(workInProgress); + if (current === null) tryToClaimNextHydratableInstance(workInProgress); + var type = workInProgress.type; + var nextProps = workInProgress.pendingProps; + var prevProps = current !== null ? current.memoizedProps : null; + var nextChildren = nextProps.children; + var isDirectTextChild = shouldSetTextContent(type, nextProps); + if (isDirectTextChild) // We special case a direct text child of a host node. This is a common + // case. We won't handle it as a reified child. We will instead handle + // this in the host environment that also has access to this prop. That + // avoids allocating another HostText fiber and traversing it. + nextChildren = null; + else if (prevProps !== null && shouldSetTextContent(type, prevProps)) // If we're switching from a direct text child to a normal child, or to + // empty, we need to schedule the text content to be reset. + workInProgress.flags |= ContentReset; + markRef(current, workInProgress); + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + function updateHostText(current, workInProgress) { + if (current === null) tryToClaimNextHydratableInstance(workInProgress); + // Nothing to do here. This is terminal. We'll do the completion step + // immediately after. + return null; + } + function mountLazyComponent(_current, workInProgress, elementType, renderLanes) { + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); + var props = workInProgress.pendingProps; + var lazyComponent = elementType; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + var Component = init(payload); // Store the unwrapped component in the type. + workInProgress.type = Component; + var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component); + var resolvedProps = resolveDefaultProps(Component, props); + var child; + switch(resolvedTag){ + case FunctionComponent: + validateFunctionComponentInDev(workInProgress, Component); + workInProgress.type = Component = resolveFunctionForHotReloading(Component); + child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderLanes); + return child; + case ClassComponent: + workInProgress.type = Component = resolveClassForHotReloading(Component); + child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderLanes); + return child; + case ForwardRef: + workInProgress.type = Component = resolveForwardRefForHotReloading(Component); + child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderLanes); + return child; + case MemoComponent: + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; + if (outerPropTypes) checkPropTypes(outerPropTypes, resolvedProps, "prop", getComponentNameFromType(Component)); + } + child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), renderLanes); + return child; + } + var hint = ""; + if (Component !== null && typeof Component === "object" && Component.$$typeof === REACT_LAZY_TYPE) hint = " Did you wrap a component in React.lazy() more than once?"; + // because the fact that it's a separate type of work is an + // implementation detail. + throw new Error("Element type is invalid. Received a promise that resolves to: " + Component + ". " + ("Lazy element type must resolve to a class or function." + hint)); + } + function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderLanes) { + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again. + workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` + // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. + var hasContext; + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else hasContext = false; + prepareToReadContext(workInProgress, renderLanes); + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes); + } + function mountIndeterminateComponent(_current, workInProgress, Component, renderLanes) { + resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); + var props = workInProgress.pendingProps; + var context; + var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); + prepareToReadContext(workInProgress, renderLanes); + var value; + var hasId; + markComponentRenderStarted(workInProgress); + if (Component.prototype && typeof Component.prototype.render === "function") { + var componentName = getComponentNameFromType(Component) || "Unknown"; + if (!didWarnAboutBadClass[componentName]) { + error("The <%s /> component appears to have a render method, but doesn't extend React.Component. This is likely to cause errors. Change %s to extend React.Component instead.", componentName, componentName); + didWarnAboutBadClass[componentName] = true; + } + } + if (workInProgress.mode & StrictLegacyMode) ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + setIsRendering(true); + ReactCurrentOwner$1.current = workInProgress; + value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes); + hasId = checkDidRenderIdHook(); + setIsRendering(false); + markComponentRenderStopped(); + workInProgress.flags |= PerformedWork; + // Support for module components is deprecated and is removed behind a flag. + // Whether or not it would crash later, we want to show a good message in DEV first. + if (typeof value === "object" && value !== null && typeof value.render === "function" && value.$$typeof === undefined) { + var _componentName = getComponentNameFromType(Component) || "Unknown"; + if (!didWarnAboutModulePatternComponent[_componentName]) { + error("The <%s /> component appears to be a function component that returns a class instance. Change %s to a class that extends React.Component instead. If you can't use a class try assigning the prototype on the function as a workaround. `%s.prototype = React.Component.prototype`. Don't use an arrow function since it cannot be called with `new` by React.", _componentName, _componentName, _componentName); + didWarnAboutModulePatternComponent[_componentName] = true; + } + } + if (// Eventually we'll delete this branch altogether. + typeof value === "object" && value !== null && typeof value.render === "function" && value.$$typeof === undefined) { + var _componentName2 = getComponentNameFromType(Component) || "Unknown"; + if (!didWarnAboutModulePatternComponent[_componentName2]) { + error("The <%s /> component appears to be a function component that returns a class instance. Change %s to a class that extends React.Component instead. If you can't use a class try assigning the prototype on the function as a workaround. `%s.prototype = React.Component.prototype`. Don't use an arrow function since it cannot be called with `new` by React.", _componentName2, _componentName2, _componentName2); + didWarnAboutModulePatternComponent[_componentName2] = true; + } + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. + var hasContext = false; + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else hasContext = false; + workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); + adoptClassInstance(workInProgress, value); + mountClassInstance(workInProgress, Component, props, renderLanes); + return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes); + } else { + // Proceed under the assumption that this is a function component + workInProgress.tag = FunctionComponent; + if (workInProgress.mode & StrictLegacyMode) { + setIsStrictModeForDevtools(true); + try { + value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes); + hasId = checkDidRenderIdHook(); + } finally{ + setIsStrictModeForDevtools(false); + } + } + if (getIsHydrating() && hasId) pushMaterializedTreeId(workInProgress); + reconcileChildren(null, workInProgress, value, renderLanes); + validateFunctionComponentInDev(workInProgress, Component); + return workInProgress.child; + } + } + function validateFunctionComponentInDev(workInProgress, Component) { + if (Component) { + if (Component.childContextTypes) error("%s(...): childContextTypes cannot be defined on a function component.", Component.displayName || Component.name || "Component"); + } + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + if (ownerName) info += "\n\nCheck the render method of `" + ownerName + "`."; + var warningKey = ownerName || ""; + var debugSource = workInProgress._debugSource; + if (debugSource) warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; + error("Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?%s", info); + } + } + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName3 = getComponentNameFromType(Component) || "Unknown"; + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { + error("%s: Function components do not support getDerivedStateFromProps.", _componentName3); + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; + } + } + if (typeof Component.contextType === "object" && Component.contextType !== null) { + var _componentName4 = getComponentNameFromType(Component) || "Unknown"; + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { + error("%s: Function components do not support contextType.", _componentName4); + didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; + } + } + } + var SUSPENDED_MARKER = { + dehydrated: null, + treeContext: null, + retryLane: NoLane + }; + function mountSuspenseOffscreenState(renderLanes) { + return { + baseLanes: renderLanes, + cachePool: getSuspendedCache(), + transitions: null + }; + } + function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { + var cachePool = null; + return { + baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), + cachePool: cachePool, + transitions: prevOffscreenState.transitions + }; + } // TODO: Probably should inline this back + function shouldRemainOnFallback(suspenseContext, current, workInProgress, renderLanes) { + // If we're already showing a fallback, there are cases where we need to + // remain on that fallback regardless of whether the content has resolved. + // For example, SuspenseList coordinates when nested content appears. + if (current !== null) { + var suspenseState = current.memoizedState; + if (suspenseState === null) // Currently showing content. Don't hide it, even if ForceSuspenseFallback + // is true. More precise name might be "ForceRemainSuspenseFallback". + // Note: This is a factoring smell. Can't remain on a fallback if there's + // no fallback to remain on. + return false; + } // Not currently showing content. Consult the Suspense context. + return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); + } + function getRemainingWorkInPrimaryTree(current, renderLanes) { + // TODO: Should not remove render lanes that were pinged during this render + return removeLanes(current.childLanes, renderLanes); + } + function updateSuspenseComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + if (shouldSuspend(workInProgress)) workInProgress.flags |= DidCapture; + var suspenseContext = suspenseStackCursor.current; + var showFallback = false; + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; + if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { + // Something in this boundary's subtree already suspended. Switch to + // rendering the fallback children. + showFallback = true; + workInProgress.flags &= ~DidCapture; + } else // Attempting the main content + if (current === null || current.memoizedState !== null) suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext); + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense + // boundary's children. This involves some custom reconciliation logic. Two + // main reasons this is so complicated. + // + // First, Legacy Mode has different semantics for backwards compatibility. The + // primary tree will commit in an inconsistent state, so when we do the + // second pass to render the fallback, we do some exceedingly, uh, clever + // hacks to make that not totally break. Like transferring effects and + // deletions from hidden tree. In Concurrent Mode, it's much simpler, + // because we bailout on the primary tree completely and leave it in its old + // state, no effects. Same as what we do for Offscreen (except that + // Offscreen doesn't have the first render pass). + // + // Second is hydration. During hydration, the Suspense fiber has a slightly + // different layout, where the child points to a dehydrated fragment, which + // contains the DOM rendered by the server. + // + // Third, even if you set all that aside, Suspense is like error boundaries in + // that we first we try to render one tree, and if that fails, we render again + // and switch to a different tree. Like a try/catch block. So we have to track + // which branch we're currently rendering. Ideally we would model this using + // a stack. + if (current === null) { + // Initial mount + // Special path for hydration + // If we're currently hydrating, try to hydrate this boundary. + tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component. + var suspenseState = workInProgress.memoizedState; + if (suspenseState !== null) { + var dehydrated = suspenseState.dehydrated; + if (dehydrated !== null) return mountDehydratedSuspenseComponent(workInProgress, dehydrated); + } + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; + if (showFallback) { + var fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes); + var primaryChildFragment = workInProgress.child; + primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackFragment; + } else return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren); + } else { + // This is an update. + // Special path for hydration + var prevState = current.memoizedState; + if (prevState !== null) { + var _dehydrated = prevState.dehydrated; + if (_dehydrated !== null) return updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, nextProps, _dehydrated, prevState, renderLanes); + } + if (showFallback) { + var _nextFallbackChildren = nextProps.fallback; + var _nextPrimaryChildren = nextProps.children; + var fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren, _nextFallbackChildren, renderLanes); + var _primaryChildFragment2 = workInProgress.child; + var prevOffscreenState = current.child.memoizedState; + _primaryChildFragment2.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); + _primaryChildFragment2.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackChildFragment; + } else { + var _nextPrimaryChildren2 = nextProps.children; + var _primaryChildFragment3 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren2, renderLanes); + workInProgress.memoizedState = null; + return _primaryChildFragment3; + } + } + } + function mountSuspensePrimaryChildren(workInProgress, primaryChildren, renderLanes) { + var mode = workInProgress.mode; + var primaryChildProps = { + mode: "visible", + children: primaryChildren + }; + var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode); + primaryChildFragment.return = workInProgress; + workInProgress.child = primaryChildFragment; + return primaryChildFragment; + } + function mountSuspenseFallbackChildren(workInProgress, primaryChildren, fallbackChildren, renderLanes) { + var mode = workInProgress.mode; + var progressedPrimaryFragment = workInProgress.child; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; + var fallbackChildFragment; + if ((mode & ConcurrentMode) === NoMode && progressedPrimaryFragment !== null) { + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + primaryChildFragment = progressedPrimaryFragment; + primaryChildFragment.childLanes = NoLanes; + primaryChildFragment.pendingProps = primaryChildProps; + if (workInProgress.mode & ProfileMode) { + // Reset the durations from the first pass so they aren't included in the + // final amounts. This seems counterintuitive, since we're intentionally + // not measuring part of the render phase, but this makes it match what we + // do in Concurrent Mode. + primaryChildFragment.actualDuration = 0; + primaryChildFragment.actualStartTime = -1; + primaryChildFragment.selfBaseDuration = 0; + primaryChildFragment.treeBaseDuration = 0; + } + fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); + } else { + primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode); + fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); + } + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; + } + function mountWorkInProgressOffscreenFiber(offscreenProps, mode, renderLanes) { + // The props argument to `createFiberFromOffscreen` is `any` typed, so we use + // this wrapper function to constrain it. + return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null); + } + function updateWorkInProgressOffscreenFiber(current, offscreenProps) { + // The props argument to `createWorkInProgress` is `any` typed, so we use this + // wrapper function to constrain it. + return createWorkInProgress(current, offscreenProps); + } + function updateSuspensePrimaryChildren(current, workInProgress, primaryChildren, renderLanes) { + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, { + mode: "visible", + children: primaryChildren + }); + if ((workInProgress.mode & ConcurrentMode) === NoMode) primaryChildFragment.lanes = renderLanes; + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = null; + if (currentFallbackChildFragment !== null) { + // Delete the fallback child fragment + var deletions = workInProgress.deletions; + if (deletions === null) { + workInProgress.deletions = [ + currentFallbackChildFragment + ]; + workInProgress.flags |= ChildDeletion; + } else deletions.push(currentFallbackChildFragment); + } + workInProgress.child = primaryChildFragment; + return primaryChildFragment; + } + function updateSuspenseFallbackChildren(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) { + var mode = workInProgress.mode; + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; + if (// completed, even though it's in an inconsistent state. + (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was + // already cloned. In legacy mode, the only case where this isn't true is + // when DevTools forces us to display a fallback; we skip the first render + // pass entirely and go straight to rendering the fallback. (In Concurrent + // Mode, SuspenseList can also trigger this scenario, but this is a legacy- + // only codepath.) + workInProgress.child !== currentPrimaryChildFragment) { + var progressedPrimaryFragment = workInProgress.child; + primaryChildFragment = progressedPrimaryFragment; + primaryChildFragment.childLanes = NoLanes; + primaryChildFragment.pendingProps = primaryChildProps; + if (workInProgress.mode & ProfileMode) { + // Reset the durations from the first pass so they aren't included in the + // final amounts. This seems counterintuitive, since we're intentionally + // not measuring part of the render phase, but this makes it match what we + // do in Concurrent Mode. + primaryChildFragment.actualDuration = 0; + primaryChildFragment.actualStartTime = -1; + primaryChildFragment.selfBaseDuration = currentPrimaryChildFragment.selfBaseDuration; + primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration; + } // The fallback fiber was added as a deletion during the first pass. + // However, since we're going to remain on the fallback, we no longer want + // to delete it. + workInProgress.deletions = null; + } else { + primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps); // Since we're reusing a current tree, we need to reuse the flags, too. + // (We don't do this in legacy mode, because in legacy mode we don't re-use + // the current tree; see previous branch.) + primaryChildFragment.subtreeFlags = currentPrimaryChildFragment.subtreeFlags & StaticMask; + } + var fallbackChildFragment; + if (currentFallbackChildFragment !== null) fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, fallbackChildren); + else { + fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); // Needs a placement effect because the parent (the Suspense boundary) already + // mounted but this is a new fiber. + fallbackChildFragment.flags |= Placement; + } + fallbackChildFragment.return = workInProgress; + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; + } + function retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, recoverableError) { + // Falling back to client rendering. Because this has performance + // implications, it's considered a recoverable error, even though the user + // likely won't observe anything wrong with the UI. + // + // The error is passed in as an argument to enforce that every caller provide + // a custom message, or explicitly opt out (currently the only path that opts + // out is legacy mode; every concurrent path provides an error). + if (recoverableError !== null) queueHydrationError(recoverableError); + // This will add the old fiber to the deletion list + reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated. + var nextProps = workInProgress.pendingProps; + var primaryChildren = nextProps.children; + var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Needs a placement effect because the parent (the Suspense boundary) already + // mounted but this is a new fiber. + primaryChildFragment.flags |= Placement; + workInProgress.memoizedState = null; + return primaryChildFragment; + } + function mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) { + var fiberMode = workInProgress.mode; + var primaryChildProps = { + mode: "visible", + children: primaryChildren + }; + var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, fiberMode); + var fallbackChildFragment = createFiberFromFragment(fallbackChildren, fiberMode, renderLanes, null); // Needs a placement effect because the parent (the Suspense + // boundary) already mounted but this is a new fiber. + fallbackChildFragment.flags |= Placement; + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + if ((workInProgress.mode & ConcurrentMode) !== NoMode) // We will have dropped the effect list which contains the + // deletion. We need to reconcile to delete the current child. + reconcileChildFibers(workInProgress, current.child, null, renderLanes); + return fallbackChildFragment; + } + function mountDehydratedSuspenseComponent(workInProgress, suspenseInstance, renderLanes) { + // During the first pass, we'll bail out and not drill into the children. + // Instead, we'll leave the content in place and try to hydrate it later. + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + error("Cannot hydrate Suspense in legacy mode. Switch from ReactDOM.hydrate(element, container) to ReactDOMClient.hydrateRoot(container, ).render(element) or remove the Suspense components from the server rendered components."); + workInProgress.lanes = laneToLanes(SyncLane); + } else if (isSuspenseInstanceFallback(suspenseInstance)) // This is a client-only boundary. Since we won't get any content from the server + // for this, we need to schedule that at a higher priority based on when it would + // have timed out. In theory we could render it in this pass but it would have the + // wrong priority associated with it and will prevent hydration of parent path. + // Instead, we'll leave work left on it to render it in a separate commit. + // TODO This time should be the time at which the server rendered response that is + // a parent to this boundary was displayed. However, since we currently don't have + // a protocol to transfer that time, we'll just estimate it by using the current + // time. This will mean that Suspense timeouts are slightly shifted to later than + // they should be. + // Schedule a normal pri update to render this content. + workInProgress.lanes = laneToLanes(DefaultHydrationLane); + else // We'll continue hydrating the rest at offscreen priority since we'll already + // be showing the right content coming from the server, it is no rush. + workInProgress.lanes = laneToLanes(OffscreenLane); + return null; + } + function updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, nextProps, suspenseInstance, suspenseState, renderLanes) { + if (!didSuspend) { + // This is the first render pass. Attempt to hydrate. + // We should never be hydrating at this point because it is the first pass, + // but after we've already committed once. + warnIfHydrating(); + if ((workInProgress.mode & ConcurrentMode) === NoMode) return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, // required \u2014 every concurrent mode path that causes hydration to + // de-opt to client rendering should have an error message. + null); + if (isSuspenseInstanceFallback(suspenseInstance)) { + // This boundary is in a permanent fallback state. In this case, we'll never + // get an update and we'll never be able to hydrate the final content. Let's just try the + // client side render instead. + var digest, message, stack; + var _getSuspenseInstanceF = getSuspenseInstanceFallbackErrorDetails(suspenseInstance); + digest = _getSuspenseInstanceF.digest; + message = _getSuspenseInstanceF.message; + stack = _getSuspenseInstanceF.stack; + var error; + if (message) // eslint-disable-next-line react-internal/prod-error-codes + error = new Error(message); + else error = new Error("The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering."); + var capturedValue = createCapturedValue(error, digest, stack); + return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, capturedValue); + } + // any context has changed, we need to treat is as if the input might have changed. + var hasContextChanged = includesSomeLane(renderLanes, current.childLanes); + if (didReceiveUpdate || hasContextChanged) { + // This boundary has changed since the first render. This means that we are now unable to + // hydrate it. We might still be able to hydrate it using a higher priority lane. + var root = getWorkInProgressRoot(); + if (root !== null) { + var attemptHydrationAtLane = getBumpedLaneForHydration(root, renderLanes); + if (attemptHydrationAtLane !== NoLane && attemptHydrationAtLane !== suspenseState.retryLane) { + // Intentionally mutating since this render will get interrupted. This + // is one of the very rare times where we mutate the current tree + // during the render phase. + suspenseState.retryLane = attemptHydrationAtLane; // TODO: Ideally this would inherit the event time of the current render + var eventTime = NoTimestamp; + enqueueConcurrentRenderForLane(current, attemptHydrationAtLane); + scheduleUpdateOnFiber(root, current, attemptHydrationAtLane, eventTime); + } + } // If we have scheduled higher pri work above, this will probably just abort the render + // since we now have higher priority work, but in case it doesn't, we need to prepare to + // render something, if we time out. Even if that requires us to delete everything and + // skip hydration. + // Delay having to do this as long as the suspense timeout allows us. + renderDidSuspendDelayIfPossible(); + var _capturedValue = createCapturedValue(new Error("This Suspense boundary received an update before it finished hydrating. This caused the boundary to switch to client rendering. The usual way to fix this is to wrap the original update in startTransition.")); + return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, _capturedValue); + } else if (isSuspenseInstancePending(suspenseInstance)) { + // This component is still pending more data from the server, so we can't hydrate its + // content. We treat it as if this component suspended itself. It might seem as if + // we could just try to render it client-side instead. However, this will perform a + // lot of unnecessary work and is unlikely to complete since it often will suspend + // on missing data anyway. Additionally, the server might be able to render more + // than we can on the client yet. In that case we'd end up with more fallback states + // on the client than if we just leave it alone. If the server times out or errors + // these should update this boundary to the permanent Fallback state instead. + // Mark it as having captured (i.e. suspended). + workInProgress.flags |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment. + workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result. + var retry = retryDehydratedSuspenseBoundary.bind(null, current); + registerSuspenseInstanceRetry(suspenseInstance, retry); + return null; + } else { + // This is the first attempt. + reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress, suspenseInstance, suspenseState.treeContext); + var primaryChildren = nextProps.children; + var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Mark the children as hydrating. This is a fast path to know whether this + // tree is part of a hydrating tree. This is used to determine if a child + // node has fully mounted yet, and for scheduling event replaying. + // Conceptually this is similar to Placement in that a new subtree is + // inserted into the React tree here. It just happens to not need DOM + // mutations because it already exists. + primaryChildFragment.flags |= Hydrating; + return primaryChildFragment; + } + } else { + // This is the second render pass. We already attempted to hydrated, but + // something either suspended or errored. + if (workInProgress.flags & ForceClientRender) { + // Something errored during hydration. Try again without hydrating. + workInProgress.flags &= ~ForceClientRender; + var _capturedValue2 = createCapturedValue(new Error("There was an error while hydrating this Suspense boundary. Switched to client rendering.")); + return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, _capturedValue2); + } else if (workInProgress.memoizedState !== null) { + // Something suspended and we should still be in dehydrated mode. + // Leave the existing child in place. + workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there + // but the normal suspense pass doesn't. + workInProgress.flags |= DidCapture; + return null; + } else { + // Suspended but we should no longer be in dehydrated mode. + // Therefore we now have to render the fallback. + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; + var fallbackChildFragment = mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes); + var _primaryChildFragment4 = workInProgress.child; + _primaryChildFragment4.memoizedState = mountSuspenseOffscreenState(renderLanes); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackChildFragment; + } + } + } + function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) { + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; + if (alternate !== null) alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + scheduleContextWorkOnParentPath(fiber.return, renderLanes, propagationRoot); + } + function propagateSuspenseContextChange(workInProgress, firstChild, renderLanes) { + // Mark any Suspense boundaries with fallbacks as having work to do. + // If they were previously forced into fallbacks, they may now be able + // to unblock. + var node = firstChild; + while(node !== null){ + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + if (state !== null) scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress); + } else if (node.tag === SuspenseListComponent) // If the tail is hidden there might not be an Suspense boundaries + // to schedule work on. In this case we have to schedule it on the + // list itself. + // We don't have to traverse to the children of the list since + // the list will propagate the change when it rerenders. + scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress); + else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) return; + while(node.sibling === null){ + if (node.return === null || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + } + function findLastContentRow(firstChild) { + // This is going to find the last row among these children that is already + // showing content on the screen, as opposed to being in fallback state or + // new. If a row has multiple Suspense boundaries, any of them being in the + // fallback state, counts as the whole row being in a fallback state. + // Note that the "rows" will be workInProgress, but any nested children + // will still be current since we haven't rendered them yet. The mounted + // order may not be the same as the new order. We use the new order. + var row = firstChild; + var lastContentRow = null; + while(row !== null){ + var currentRow = row.alternate; // New rows can't be content rows. + if (currentRow !== null && findFirstSuspended(currentRow) === null) lastContentRow = row; + row = row.sibling; + } + return lastContentRow; + } + function validateRevealOrder(revealOrder) { + if (revealOrder !== undefined && revealOrder !== "forwards" && revealOrder !== "backwards" && revealOrder !== "together" && !didWarnAboutRevealOrder[revealOrder]) { + didWarnAboutRevealOrder[revealOrder] = true; + if (typeof revealOrder === "string") switch(revealOrder.toLowerCase()){ + case "together": + case "forwards": + case "backwards": + error('"%s" is not a valid value for revealOrder on . Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase()); + break; + case "forward": + case "backward": + error('"%s" is not a valid value for revealOrder on . React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase()); + break; + default: + error('"%s" is not a supported revealOrder on . Did you mean "together", "forwards" or "backwards"?', revealOrder); + break; + } + else error('%s is not a supported value for revealOrder on . Did you mean "together", "forwards" or "backwards"?', revealOrder); + } + } + function validateTailOptions(tailMode, revealOrder) { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; + error('"%s" is not a supported value for tail on . Did you mean "collapsed" or "hidden"?', tailMode); + } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { + didWarnAboutTailOptions[tailMode] = true; + error(' is only valid if revealOrder is "forwards" or "backwards". Did you mean to specify revealOrder="forwards"?', tailMode); + } + } + } + function validateSuspenseListNestedChild(childSlot, index) { + var isAnArray = isArray(childSlot); + var isIterable = !isAnArray && typeof getIteratorFn(childSlot) === "function"; + if (isAnArray || isIterable) { + var type = isAnArray ? "array" : "iterable"; + error("A nested %s was passed to row #%s in . Wrap it in an additional SuspenseList to configure its revealOrder: ... {%s} ... ", type, index, type); + return false; + } + return true; + } + function validateSuspenseListChildren(children, revealOrder) { + if ((revealOrder === "forwards" || revealOrder === "backwards") && children !== undefined && children !== null && children !== false) { + if (isArray(children)) for(var i = 0; i < children.length; i++){ + if (!validateSuspenseListNestedChild(children[i], i)) return; + } + else { + var iteratorFn = getIteratorFn(children); + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; + for(; !step.done; step = childrenIterator.next()){ + if (!validateSuspenseListNestedChild(step.value, _i)) return; + _i++; + } + } + } else error('A single row was passed to a . This is not useful since it needs multiple rows. Did you mean to pass multiple children or an array?', revealOrder); + } + } + } + function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) { + var renderState = workInProgress.memoizedState; + if (renderState === null) workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + renderingStartTime: 0, + last: lastContentRow, + tail: tail, + tailMode: tailMode + }; + else { + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.renderingStartTime = 0; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailMode = tailMode; + } + } // This can end up rendering this component multiple passes. + // The first pass splits the children fibers into two sets. A head and tail. + // We first render the head. If anything is in fallback state, we do another + // pass through beginWork to rerender all children (including the tail) with + // the force suspend context. If the first render didn't have anything in + // in fallback state. Then we render each row in the tail one-by-one. + // That happens in the completeWork phase without going back to beginWork. + function updateSuspenseListComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var revealOrder = nextProps.revealOrder; + var tailMode = nextProps.tail; + var newChildren = nextProps.children; + validateRevealOrder(revealOrder); + validateTailOptions(tailMode, revealOrder); + validateSuspenseListChildren(newChildren, revealOrder); + reconcileChildren(current, workInProgress, newChildren, renderLanes); + var suspenseContext = suspenseStackCursor.current; + var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback); + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback); + workInProgress.flags |= DidCapture; + } else { + var didSuspendBefore = current !== null && (current.flags & DidCapture) !== NoFlags; + if (didSuspendBefore) // If we previously forced a fallback, we need to schedule work + // on any nested boundaries to let them know to try to render + // again. This is the same as context updating. + propagateSuspenseContextChange(workInProgress, workInProgress.child, renderLanes); + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } + pushSuspenseContext(workInProgress, suspenseContext); + if ((workInProgress.mode & ConcurrentMode) === NoMode) // In legacy mode, SuspenseList doesn't work so we just + // use make it a noop by treating it as the default revealOrder. + workInProgress.memoizedState = null; + else switch(revealOrder){ + case "forwards": + var lastContentRow = findLastContentRow(workInProgress.child); + var tail; + if (lastContentRow === null) { + // The whole list is part of the tail. + // TODO: We could fast path by just rendering the tail now. + tail = workInProgress.child; + workInProgress.child = null; + } else { + // Disconnect the tail rows after the content row. + // We're going to render them separately later. + tail = lastContentRow.sibling; + lastContentRow.sibling = null; + } + initSuspenseListRenderState(workInProgress, false, tail, lastContentRow, tailMode); + break; + case "backwards": + // We're going to find the first row that has existing content. + // At the same time we're going to reverse the list of everything + // we pass in the meantime. That's going to be our tail in reverse + // order. + var _tail = null; + var row = workInProgress.child; + workInProgress.child = null; + while(row !== null){ + var currentRow = row.alternate; // New rows can't be content rows. + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + // This is the beginning of the main content. + workInProgress.child = row; + break; + } + var nextRow = row.sibling; + row.sibling = _tail; + _tail = row; + row = nextRow; + } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + initSuspenseListRenderState(workInProgress, true, _tail, null, tailMode); + break; + case "together": + initSuspenseListRenderState(workInProgress, false, null, null, undefined); + break; + default: + // The default reveal order is the same as not having + // a boundary. + workInProgress.memoizedState = null; + } + return workInProgress.child; + } + function updatePortalComponent(current, workInProgress, renderLanes) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; + if (current === null) // Portals are special because we don't append the children during mount + // but at commit. Therefore we need to track insertions which the normal + // flow doesn't do during mount. This doesn't happen at the root because + // the root always starts with a "current" with a null child. + // TODO: Consider unifying this with how the root works. + workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes); + else reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } + var hasWarnedAboutUsingNoValuePropOnContextProvider = false; + function updateContextProvider(current, workInProgress, renderLanes) { + var providerType = workInProgress.type; + var context = providerType._context; + var newProps = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps; + var newValue = newProps.value; + if (!("value" in newProps)) { + if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { + hasWarnedAboutUsingNoValuePropOnContextProvider = true; + error("The `value` prop is required for the ``. Did you misspell it or forget to pass it?"); + } + } + var providerPropTypes = workInProgress.type.propTypes; + if (providerPropTypes) checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + pushProvider(workInProgress, context, newValue); + if (oldProps !== null) { + var oldValue = oldProps.value; + if (objectIs(oldValue, newValue)) { + // No change. Bailout early if children are the same. + if (oldProps.children === newProps.children && !hasContextChanged()) return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } else // The context value changed. Search for matching consumers and schedule + // them to update. + propagateContextChange(workInProgress, context, renderLanes); + } + var newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; + } + var hasWarnedAboutUsingContextAsConsumer = false; + function updateContextConsumer(current, workInProgress, renderLanes) { + var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In + if (context._context === undefined) { + // This may be because it's a Context (rather than a Consumer). + // Or it may be because it's older React where they're the same thing. + // We only want to warn if we're sure it's a new React. + if (context !== context.Consumer) { + if (!hasWarnedAboutUsingContextAsConsumer) { + hasWarnedAboutUsingContextAsConsumer = true; + error("Rendering directly is not supported and will be removed in a future major release. Did you mean to render instead?"); + } + } + } else context = context._context; + var newProps = workInProgress.pendingProps; + var render = newProps.children; + if (typeof render !== "function") error("A context consumer was rendered with multiple children, or a child that isn't a function. A context consumer expects a single child that is a function. If you did pass a function, make sure there is no trailing or leading whitespace around it."); + prepareToReadContext(workInProgress, renderLanes); + var newValue = readContext(context); + markComponentRenderStarted(workInProgress); + var newChildren; + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + markComponentRenderStopped(); + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; + } + function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; + } + function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + if (current !== null) { + // A lazy component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + workInProgress.flags |= Placement; + } + } + } + function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { + if (current !== null) // Reuse previous dependencies + workInProgress.dependencies = current.dependencies; + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(); + markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. + if (!includesSomeLane(renderLanes, workInProgress.childLanes)) return null; + // This fiber doesn't have work, but its subtree does. Clone the child + // fibers and continue. + cloneChildFibers(current, workInProgress); + return workInProgress.child; + } + function remountFiber(current, oldWorkInProgress, newWorkInProgress) { + var returnFiber = oldWorkInProgress.return; + if (returnFiber === null) // eslint-disable-next-line react-internal/prod-error-codes + throw new Error("Cannot swap the root fiber."); + // Disconnect from the old current. + // It will get deleted. + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. + if (oldWorkInProgress === returnFiber.child) returnFiber.child = newWorkInProgress; + else { + var prevSibling = returnFiber.child; + if (prevSibling === null) // eslint-disable-next-line react-internal/prod-error-codes + throw new Error("Expected parent to have a child."); + while(prevSibling.sibling !== oldWorkInProgress){ + prevSibling = prevSibling.sibling; + if (prevSibling === null) // eslint-disable-next-line react-internal/prod-error-codes + throw new Error("Expected to find the previous sibling."); + } + prevSibling.sibling = newWorkInProgress; + } // Delete the old fiber and place the new one. + // Since the old fiber is disconnected, we have to schedule it manually. + var deletions = returnFiber.deletions; + if (deletions === null) { + returnFiber.deletions = [ + current + ]; + returnFiber.flags |= ChildDeletion; + } else deletions.push(current); + newWorkInProgress.flags |= Placement; // Restart work from the new fiber. + return newWorkInProgress; + } + function checkScheduledUpdateOrContext(current, renderLanes) { + // Before performing an early bailout, we must check if there are pending + // updates or context. + var updateLanes = current.lanes; + if (includesSomeLane(updateLanes, renderLanes)) return true; + // No pending update, but because context is propagated lazily, we need + return false; + } + function attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes) { + // This fiber does not have any pending work. Bailout without entering + // the begin phase. There's still some bookkeeping we that needs to be done + // in this optimized path, mostly pushing stuff onto the stack. + switch(workInProgress.tag){ + case HostRoot: + pushHostRootContext(workInProgress); + var root = workInProgress.stateNode; + resetHydrationState(); + break; + case HostComponent: + pushHostContext(workInProgress); + break; + case ClassComponent: + var Component = workInProgress.type; + if (isContextProvider(Component)) pushContextProvider(workInProgress); + break; + case HostPortal: + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + break; + case ContextProvider: + var newValue = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + pushProvider(workInProgress, context, newValue); + break; + case Profiler: + // Profiler should only call onRender when one of its descendants actually rendered. + var hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes); + if (hasChildWork) workInProgress.flags |= Update; + // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + break; + case SuspenseComponent: + var state = workInProgress.memoizedState; + if (state !== null) { + if (state.dehydrated !== null) { + pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // We know that this component will suspend again because if it has + // been unsuspended it has committed as a resolved Suspense component. + // If it needs to be retried, it should have work scheduled on it. + workInProgress.flags |= DidCapture; // We should never render the children of a dehydrated boundary until we + // upgrade it. We return null instead of bailoutOnAlreadyFinishedWork. + return null; + } // If this boundary is currently timed out, we need to decide + // whether to retry the primary children, or to skip over it and + // go straight to the fallback. Check the priority of the primary + // child fragment. + var primaryChildFragment = workInProgress.child; + var primaryChildLanes = primaryChildFragment.childLanes; + if (includesSomeLane(renderLanes, primaryChildLanes)) // The primary children have pending work. Use the normal path + // to attempt to render the primary children again. + return updateSuspenseComponent(current, workInProgress, renderLanes); + else { + // The primary child fragment does not have pending work marked + // on it + pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient + // priority. Bailout. + var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + if (child !== null) // The fallback children have pending work. Skip over the + // primary children and work on the fallback. + return child.sibling; + else // Note: We can return `null` here because we already checked + // whether there were nested context consumers, via the call to + // `bailoutOnAlreadyFinishedWork` above. + return null; + } + } else pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); + break; + case SuspenseListComponent: + var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; + var _hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes); + if (didSuspendBefore) { + if (_hasChildWork) // If something was in fallback state last time, and we have all the + // same children then we're still in progressive loading state. + // Something might get unblocked by state updates or retries in the + // tree which will affect the tail. So we need to use the normal + // path to compute the correct tail. + return updateSuspenseListComponent(current, workInProgress, renderLanes); + // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. + workInProgress.flags |= DidCapture; + } // If nothing suspended before and we're rendering the same children, + // then the tail doesn't matter. Anything new that suspends will work + // in the "together" mode, so we can continue from the state we had. + var renderState = workInProgress.memoizedState; + if (renderState !== null) { + // Reset to the "together" mode in case we've started a different + // update in the past but didn't complete it. + renderState.rendering = null; + renderState.tail = null; + renderState.lastEffect = null; + } + pushSuspenseContext(workInProgress, suspenseStackCursor.current); + if (_hasChildWork) break; + else // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. + return null; + case OffscreenComponent: + case LegacyHiddenComponent: + // Need to check if the tree still needs to be deferred. This is + // almost identical to the logic used in the normal update path, + // so we'll just enter that. The only difference is we'll bail out + // at the next level instead of this one, because the child props + // have not changed. Which is fine. + // TODO: Probably should refactor `beginWork` to split the bailout + // path from the normal path. I'm tempted to do a labeled break here + // but I won't :) + workInProgress.lanes = NoLanes; + return updateOffscreenComponent(current, workInProgress, renderLanes); + } + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + function beginWork(current, workInProgress, renderLanes) { + if (workInProgress._debugNeedsRemount && current !== null) // This will restart the begin phase with a new fiber. + return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes)); + if (current !== null) { + var oldProps = current.memoizedProps; + var newProps = workInProgress.pendingProps; + if (oldProps !== newProps || hasContextChanged() || workInProgress.type !== current.type) // If props or context changed, mark the fiber as having performed work. + // This may be unset if the props are determined to be equal later (memo). + didReceiveUpdate = true; + else { + // Neither props nor legacy context changes. Check if there's a pending + // update or context change. + var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes); + if (!hasScheduledUpdateOrContext && // If this is the second pass of an error or suspense boundary, there + // may not be work scheduled on `current`, so we check for this flag. + (workInProgress.flags & DidCapture) === NoFlags) { + // No pending updates or context. Bail out now. + didReceiveUpdate = false; + return attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes); + } + if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) // This is a special case that only exists for legacy mode. + // See https://github.com/facebook/react/pull/19216. + didReceiveUpdate = true; + else // An update was scheduled on this fiber, but there are no new props + // nor legacy context. Set this to false. If an update queue or context + // consumer produces a changed value, it will set this to true. Otherwise, + // the component will assume the children have not changed and bail out. + didReceiveUpdate = false; + } + } else { + didReceiveUpdate = false; + if (getIsHydrating() && isForkedChild(workInProgress)) { + // Check if this child belongs to a list of muliple children in + // its parent. + // + // In a true multi-threaded implementation, we would render children on + // parallel threads. This would represent the beginning of a new render + // thread for this subtree. + // + // We only use this for id generation during hydration, which is why the + // logic is located in this special branch. + var slotIndex = workInProgress.index; + var numberOfForks = getForksAtLevel(); + pushTreeId(workInProgress, numberOfForks, slotIndex); + } + } // Before entering the begin phase, clear pending update priority. + // TODO: This assumes that we're about to evaluate the component and process + // the update queue. However, there's an exception: SimpleMemoComponent + // sometimes bails out later in the begin phase. This indicates that we should + // move this assignment out of the common path and into each branch. + workInProgress.lanes = NoLanes; + switch(workInProgress.tag){ + case IndeterminateComponent: + return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderLanes); + case LazyComponent: + var elementType = workInProgress.elementType; + return mountLazyComponent(current, workInProgress, elementType, renderLanes); + case FunctionComponent: + var Component = workInProgress.type; + var unresolvedProps = workInProgress.pendingProps; + var resolvedProps = workInProgress.elementType === Component ? unresolvedProps : resolveDefaultProps(Component, unresolvedProps); + return updateFunctionComponent(current, workInProgress, Component, resolvedProps, renderLanes); + case ClassComponent: + var _Component = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; + var _resolvedProps = workInProgress.elementType === _Component ? _unresolvedProps : resolveDefaultProps(_Component, _unresolvedProps); + return updateClassComponent(current, workInProgress, _Component, _resolvedProps, renderLanes); + case HostRoot: + return updateHostRoot(current, workInProgress, renderLanes); + case HostComponent: + return updateHostComponent(current, workInProgress, renderLanes); + case HostText: + return updateHostText(current, workInProgress); + case SuspenseComponent: + return updateSuspenseComponent(current, workInProgress, renderLanes); + case HostPortal: + return updatePortalComponent(current, workInProgress, renderLanes); + case ForwardRef: + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; + var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2); + return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderLanes); + case Fragment: + return updateFragment(current, workInProgress, renderLanes); + case Mode: + return updateMode(current, workInProgress, renderLanes); + case Profiler: + return updateProfiler(current, workInProgress, renderLanes); + case ContextProvider: + return updateContextProvider(current, workInProgress, renderLanes); + case ContextConsumer: + return updateContextConsumer(current, workInProgress, renderLanes); + case MemoComponent: + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; + if (outerPropTypes) checkPropTypes(outerPropTypes, _resolvedProps3, "prop", getComponentNameFromType(_type2)); + } + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, renderLanes); + case SimpleMemoComponent: + return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, renderLanes); + case IncompleteClassComponent: + var _Component2 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; + var _resolvedProps4 = workInProgress.elementType === _Component2 ? _unresolvedProps4 : resolveDefaultProps(_Component2, _unresolvedProps4); + return mountIncompleteClassComponent(current, workInProgress, _Component2, _resolvedProps4, renderLanes); + case SuspenseListComponent: + return updateSuspenseListComponent(current, workInProgress, renderLanes); + case ScopeComponent: + break; + case OffscreenComponent: + return updateOffscreenComponent(current, workInProgress, renderLanes); + } + throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + "React. Please file an issue."); + } + function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.flags |= Update; + } + function markRef$1(workInProgress) { + workInProgress.flags |= Ref; + workInProgress.flags |= RefStatic; + } + var appendAllChildren; + var updateHostContainer; + var updateHostComponent$1; + var updateHostText$1; + // Mutation mode + appendAllChildren = function(parent, workInProgress, needsVisibilityToggle, isHidden) { + // We only have the top Fiber that was created but we need recurse down its + // children to find all the terminal nodes. + var node = workInProgress.child; + while(node !== null){ + if (node.tag === HostComponent || node.tag === HostText) appendInitialChild(parent, node.stateNode); + else if (node.tag === HostPortal) ; + else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) return; + while(node.sibling === null){ + if (node.return === null || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + }; + updateHostContainer = function(current, workInProgress) {}; + updateHostComponent$1 = function(current, workInProgress, type, newProps, rootContainerInstance) { + // If we have an alternate, that means this is an update and we need to + // schedule a side-effect to do the updates. + var oldProps = current.memoizedProps; + if (oldProps === newProps) // In mutation mode, this is sufficient for a bailout because + // we won't touch this node even if children changed. + return; + // If we get updated because one of our children updated, we don't + // have newProps so we'll have to reuse them. + // TODO: Split the update API as separate for the props vs. children. + // Even better would be if children weren't special cased at all tho. + var instance = workInProgress.stateNode; + var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host + // component is hitting the resume path. Figure out why. Possibly + // related to `hidden`. + var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component. + workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there + // is a new ref we mark this as an update. All the work is done in commitWork. + if (updatePayload) markUpdate(workInProgress); + }; + updateHostText$1 = function(current, workInProgress, oldText, newText) { + // If the text differs, mark it as an update. All the work in done in commitWork. + if (oldText !== newText) markUpdate(workInProgress); + }; + function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + if (getIsHydrating()) // If we're hydrating, we should consume as many items as we can + // so we don't leave any behind. + return; + switch(renderState.tailMode){ + case "hidden": + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var tailNode = renderState.tail; + var lastTailNode = null; + while(tailNode !== null){ + if (tailNode.alternate !== null) lastTailNode = tailNode; + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. + if (lastTailNode === null) // All remaining items in the tail are insertions. + renderState.tail = null; + else // Detach the insertion after the last node that was already + // inserted. + lastTailNode.sibling = null; + break; + case "collapsed": + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; + while(_tailNode !== null){ + if (_tailNode.alternate !== null) _lastTailNode = _tailNode; + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. + if (_lastTailNode === null) { + // All remaining items in the tail are insertions. + if (!hasRenderedATailFallback && renderState.tail !== null) // We suspended during the head. We want to show at least one + // row at the tail. So we'll keep on and cut off the rest. + renderState.tail.sibling = null; + else renderState.tail = null; + } else // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; + break; + } + } + function bubbleProperties(completedWork) { + var didBailout = completedWork.alternate !== null && completedWork.alternate.child === completedWork.child; + var newChildLanes = NoLanes; + var subtreeFlags = NoFlags; + if (!didBailout) { + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var actualDuration = completedWork.actualDuration; + var treeBaseDuration = completedWork.selfBaseDuration; + var child = completedWork.child; + while(child !== null){ + newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes)); + subtreeFlags |= child.subtreeFlags; + subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will + // only be updated if work is done on the fiber (i.e. it doesn't bailout). + // When work is done, it should bubble to the parent's actualDuration. If + // the fiber has not been cloned though, (meaning no work was done), then + // this value will reflect the amount of time spent working on a previous + // render. In that case it should not bubble. We determine whether it was + // cloned by comparing the child pointer. + actualDuration += child.actualDuration; + treeBaseDuration += child.treeBaseDuration; + child = child.sibling; + } + completedWork.actualDuration = actualDuration; + completedWork.treeBaseDuration = treeBaseDuration; + } else { + var _child = completedWork.child; + while(_child !== null){ + newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes)); + subtreeFlags |= _child.subtreeFlags; + subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. + _child.return = completedWork; + _child = _child.sibling; + } + } + completedWork.subtreeFlags |= subtreeFlags; + } else { + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var _treeBaseDuration = completedWork.selfBaseDuration; + var _child2 = completedWork.child; + while(_child2 !== null){ + newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child2.lanes, _child2.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. + subtreeFlags |= _child2.subtreeFlags & StaticMask; + subtreeFlags |= _child2.flags & StaticMask; + _treeBaseDuration += _child2.treeBaseDuration; + _child2 = _child2.sibling; + } + completedWork.treeBaseDuration = _treeBaseDuration; + } else { + var _child3 = completedWork.child; + while(_child3 !== null){ + newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child3.lanes, _child3.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. + subtreeFlags |= _child3.subtreeFlags & StaticMask; + subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. + _child3.return = completedWork; + _child3 = _child3.sibling; + } + } + completedWork.subtreeFlags |= subtreeFlags; + } + completedWork.childLanes = newChildLanes; + return didBailout; + } + function completeDehydratedSuspenseBoundary(current, workInProgress, nextState) { + if (hasUnhydratedTailNodes() && (workInProgress.mode & ConcurrentMode) !== NoMode && (workInProgress.flags & DidCapture) === NoFlags) { + warnIfUnhydratedTailNodes(workInProgress); + resetHydrationState(); + workInProgress.flags |= ForceClientRender | Incomplete | ShouldCapture; + return false; + } + var wasHydrated = popHydrationState(workInProgress); + if (nextState !== null && nextState.dehydrated !== null) { + // We might be inside a hydration state the first time we're picking up this + // Suspense boundary, and also after we've reentered it for further hydration. + if (current === null) { + if (!wasHydrated) throw new Error("A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React."); + prepareToHydrateHostSuspenseInstance(workInProgress); + bubbleProperties(workInProgress); + if ((workInProgress.mode & ProfileMode) !== NoMode) { + var isTimedOutSuspense = nextState !== null; + if (isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var primaryChildFragment = workInProgress.child; + if (primaryChildFragment !== null) // $FlowFixMe Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration; + } + } + return false; + } else { + // We might have reentered this boundary to hydrate it. If so, we need to reset the hydration + // state since we're now exiting out of it. popHydrationState doesn't do that for us. + resetHydrationState(); + if ((workInProgress.flags & DidCapture) === NoFlags) // This boundary did not suspend so it's now hydrated and unsuspended. + workInProgress.memoizedState = null; + // If nothing suspended, we need to schedule an effect to mark this boundary + // as having hydrated so events know that they're free to be invoked. + // It's also a signal to replay events and the suspense callback. + // If something suspended, schedule an effect to attach retry listeners. + // So we might as well always mark this. + workInProgress.flags |= Update; + bubbleProperties(workInProgress); + if ((workInProgress.mode & ProfileMode) !== NoMode) { + var _isTimedOutSuspense = nextState !== null; + if (_isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var _primaryChildFragment = workInProgress.child; + if (_primaryChildFragment !== null) // $FlowFixMe Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= _primaryChildFragment.treeBaseDuration; + } + } + return false; + } + } else { + // Successfully completed this tree. If this was a forced client render, + // there may have been recoverable errors during first hydration + // attempt. If so, add them to a queue so we can log them in the + // commit phase. + upgradeHydrationErrorsToRecoverable(); // Fall through to normal Suspense path + return true; + } + } + function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing + // to the current tree provider fiber is just as fast and less error-prone. + // Ideally we would have a special version of the work loop only + // for hydration. + popTreeContext(workInProgress); + switch(workInProgress.tag){ + case IndeterminateComponent: + case LazyComponent: + case SimpleMemoComponent: + case FunctionComponent: + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + bubbleProperties(workInProgress); + return null; + case ClassComponent: + var Component = workInProgress.type; + if (isContextProvider(Component)) popContext(workInProgress); + bubbleProperties(workInProgress); + return null; + case HostRoot: + var fiberRoot = workInProgress.stateNode; + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } + if (current === null || current.child === null) { + // If we hydrated, pop so that we can delete any remaining children + // that weren't hydrated. + var wasHydrated = popHydrationState(workInProgress); + if (wasHydrated) // If we hydrated, then we'll need to schedule an update for + // the commit side-effects on the root. + markUpdate(workInProgress); + else if (current !== null) { + var prevState = current.memoizedState; + if (!prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error) + (workInProgress.flags & ForceClientRender) !== NoFlags) { + // Schedule an effect to clear this container at the start of the + // next commit. This handles the case of React rendering into a + // container with previous children. It's also safe to do for + // updates too, because current.child would only be null if the + // previous render was null (so the container would already + // be empty). + workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been + // recoverable errors during first hydration attempt. If so, add + // them to a queue so we can log them in the commit phase. + upgradeHydrationErrorsToRecoverable(); + } + } + } + updateHostContainer(current, workInProgress); + bubbleProperties(workInProgress); + return null; + case HostComponent: + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance); + if (current.ref !== workInProgress.ref) markRef$1(workInProgress); + } else { + if (!newProps) { + if (workInProgress.stateNode === null) throw new Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue."); + // This can happen when we abort work. + bubbleProperties(workInProgress); + return null; + } + var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context + // "stack" as the parent. Then append children as we go in beginWork + // or completeWork depending on whether we want to add them top->down or + // bottom->up. Top->down is faster in IE11. + var _wasHydrated = popHydrationState(workInProgress); + if (_wasHydrated) // TODO: Move this and createInstance step into the beginPhase + // to consolidate. + { + if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) // If changes to the hydrated node need to be applied at the + // commit-phase we mark this as such. + markUpdate(workInProgress); + } else { + var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress); + appendAllChildren(instance, workInProgress, false, false); + workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. + // (eg DOM renderer supports auto-focus for certain elements). + // Make sure such renderers get scheduled for later work. + if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) markUpdate(workInProgress); + } + if (workInProgress.ref !== null) // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); + } + bubbleProperties(workInProgress); + return null; + case HostText: + var newText = newProps; + if (current && workInProgress.stateNode != null) { + var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need + // to schedule a side-effect to do the updates. + updateHostText$1(current, workInProgress, oldText, newText); + } else { + if (typeof newText !== "string") { + if (workInProgress.stateNode === null) throw new Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue."); + // This can happen when we abort work. + } + var _rootContainerInstance = getRootHostContainer(); + var _currentHostContext = getHostContext(); + var _wasHydrated2 = popHydrationState(workInProgress); + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance(workInProgress)) markUpdate(workInProgress); + } else workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress); + } + bubbleProperties(workInProgress); + return null; + case SuspenseComponent: + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; // Special path for dehydrated boundaries. We may eventually move this + // to its own fiber type so that we can add other kinds of hydration + // boundaries that aren't associated with a Suspense tree. In anticipation + // of such a refactor, all the hydration logic is contained in + // this branch. + if (current === null || current.memoizedState !== null && current.memoizedState.dehydrated !== null) { + var fallthroughToNormalSuspensePath = completeDehydratedSuspenseBoundary(current, workInProgress, nextState); + if (!fallthroughToNormalSuspensePath) { + if (workInProgress.flags & ShouldCapture) // Special case. There were remaining unhydrated nodes. We treat + // this as a mismatch. Revert to client rendering. + return workInProgress; + else // Did not finish hydrating, either because this is the initial + // render or because something suspended. + return null; + } // Continue with the normal Suspense path. + } + if ((workInProgress.flags & DidCapture) !== NoFlags) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. + if ((workInProgress.mode & ProfileMode) !== NoMode) transferActualDuration(workInProgress); + // Don't bubble properties in this case. + return workInProgress; + } + var nextDidTimeout = nextState !== null; + var prevDidTimeout = current !== null && current.memoizedState !== null; + // a passive effect, which is when we process the transitions + if (nextDidTimeout !== prevDidTimeout) // an effect to toggle the subtree's visibility. When we switch from + // fallback -> primary, the inner Offscreen fiber schedules this effect + // as part of its normal complete phase. But when we switch from + // primary -> fallback, the inner Offscreen fiber does not have a complete + // phase. So we need to schedule its effect here. + // + // We also use this flag to connect/disconnect the effects, but the same + // logic applies: when re-connecting, the Offscreen fiber's complete + // phase will handle scheduling the effect. It's only when the fallback + // is active that we have to do anything special. + { + if (nextDidTimeout) { + var _offscreenFiber2 = workInProgress.child; + _offscreenFiber2.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything + // in the concurrent tree already suspended during this render. + // This is a known bug. + if ((workInProgress.mode & ConcurrentMode) !== NoMode) { + // TODO: Move this back to throwException because this is too late + // if this is a large tree which is common for initial loads. We + // don't know if we should restart a render or not until we get + // this marker, and this is too late. + // If this render already had a ping or lower pri updates, + // and this is the first time we know we're going to suspend we + // should be able to immediately restart from within throwException. + var hasInvisibleChildContext = current === null && (workInProgress.memoizedProps.unstable_avoidThisFallback !== true || !enableSuspenseAvoidThisFallback); + if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) // If this was in an invisible tree or a new render, then showing + // this boundary is ok. + renderDidSuspend(); + else // Otherwise, we're going to have to hide content so we should + // suspend for longer if possible. + renderDidSuspendDelayIfPossible(); + } + } + } + var wakeables = workInProgress.updateQueue; + if (wakeables !== null) // Schedule an effect to attach a retry listener to the promise. + // TODO: Move to passive phase + workInProgress.flags |= Update; + bubbleProperties(workInProgress); + if ((workInProgress.mode & ProfileMode) !== NoMode) { + if (nextDidTimeout) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var primaryChildFragment = workInProgress.child; + if (primaryChildFragment !== null) // $FlowFixMe Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration; + } + } + return null; + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(current, workInProgress); + if (current === null) preparePortalMount(workInProgress.stateNode.containerInfo); + bubbleProperties(workInProgress); + return null; + case ContextProvider: + // Pop provider fiber + var context = workInProgress.type._context; + popProvider(context, workInProgress); + bubbleProperties(workInProgress); + return null; + case IncompleteClassComponent: + // Same as class component case. I put it down here so that the tags are + // sequential to ensure this switch is compiled to a jump table. + var _Component = workInProgress.type; + if (isContextProvider(_Component)) popContext(workInProgress); + bubbleProperties(workInProgress); + return null; + case SuspenseListComponent: + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + bubbleProperties(workInProgress); + return null; + } + var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; + var renderedTail = renderState.rendering; + if (renderedTail === null) { + // We just rendered the head. + if (!didSuspendAlready) { + // This is the first pass. We need to figure out if anything is still + // suspended in the rendered set. + // If new content unsuspended, but there's still some content that + // didn't. Then we need to do a second pass that forces everything + // to keep showing their fallbacks. + // We might be suspended if something in this render pass suspended, or + // something in the previous committed pass suspended. Otherwise, + // there's no chance so we can skip the expensive call to + // findFirstSuspended. + var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.flags & DidCapture) === NoFlags); + if (!cannotBeSuspended) { + var row = workInProgress.child; + while(row !== null){ + var suspended = findFirstSuspended(row); + if (suspended !== null) { + didSuspendAlready = true; + workInProgress.flags |= DidCapture; + cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as + // part of the second pass. In that case nothing will subscribe to + // its thenables. Instead, we'll transfer its thenables to the + // SuspenseList so that it can retry if they resolve. + // There might be multiple of these in the list but since we're + // going to wait for all of them anyway, it doesn't really matter + // which ones gets to ping. In theory we could get clever and keep + // track of how many dependencies remain but it gets tricky because + // in the meantime, we can add/remove/change items and dependencies. + // We might bail out of the loop before finding any but that + // doesn't matter since that means that the other boundaries that + // we did find already has their listeners attached. + var newThenables = suspended.updateQueue; + if (newThenables !== null) { + workInProgress.updateQueue = newThenables; + workInProgress.flags |= Update; + } // Rerender the whole list, but this time, we'll force fallbacks + // to stay in place. + // Reset the effect flags before doing the second pass since that's now invalid. + // Reset the child fibers to their original state. + workInProgress.subtreeFlags = NoFlags; + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately + // rerender the children. + pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback)); // Don't bubble properties in this case. + return workInProgress.child; + } + row = row.sibling; + } + } + if (renderState.tail !== null && now() > getRenderTargetTime()) { + // We have already passed our CPU deadline but we still have rows + // left in the tail. We'll just give up further attempts to render + // the main content and only render fallbacks. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. + workInProgress.lanes = SomeRetryLane; + } + } else cutOffTailIfNeeded(renderState, false); + // Next we're going to render the tail. + } else { + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); + if (_suspended !== null) { + workInProgress.flags |= DidCapture; + didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't + // get lost if this row ends up dropped during a second pass. + var _newThenables = _suspended.updateQueue; + if (_newThenables !== null) { + workInProgress.updateQueue = _newThenables; + workInProgress.flags |= Update; + } + cutOffTailIfNeeded(renderState, true); // This might have been modified. + if (renderState.tail === null && renderState.tailMode === "hidden" && !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating. + ) { + // We're done. + bubbleProperties(workInProgress); + return null; + } + } else if (// time we have to render. So rendering one more row would likely + // exceed it. + now() * 2 - renderState.renderingStartTime > getRenderTargetTime() && renderLanes !== OffscreenLane) { + // We have now passed our CPU deadline and we'll just give up further + // attempts to render the main content and only render fallbacks. + // The assumption is that this is usually faster. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. + workInProgress.lanes = SomeRetryLane; + } + } + if (renderState.isBackwards) { + // The effect list of the backwards tail will have been added + // to the end. This breaks the guarantee that life-cycles fire in + // sibling order but that isn't a strong guarantee promised by React. + // Especially since these might also just pop in during future commits. + // Append to the beginning of the list. + renderedTail.sibling = workInProgress.child; + workInProgress.child = renderedTail; + } else { + var previousSibling = renderState.last; + if (previousSibling !== null) previousSibling.sibling = renderedTail; + else workInProgress.child = renderedTail; + renderState.last = renderedTail; + } + } + if (renderState.tail !== null) { + // We still have tail rows to render. + // Pop a row. + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.renderingStartTime = now(); + next.sibling = null; // Restore the context. + // TODO: We can probably just avoid popping it instead and only + // setting it the first time we go from not suspended to suspended. + var suspenseContext = suspenseStackCursor.current; + if (didSuspendAlready) suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback); + else suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + // Don't bubble properties in this case. + return next; + } + bubbleProperties(workInProgress); + return null; + case ScopeComponent: + break; + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(workInProgress); + var _nextState = workInProgress.memoizedState; + var nextIsHidden = _nextState !== null; + if (current !== null) { + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; + if (prevIsHidden !== nextIsHidden && !enableLegacyHidden) workInProgress.flags |= Visibility; + } + if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) bubbleProperties(workInProgress); + else // Don't bubble properties for hidden children unless we're rendering + // at offscreen priority. + if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) { + bubbleProperties(workInProgress); + // Check if there was an insertion or update in the hidden subtree. + // If so, we need to hide those nodes in the commit phase, so + // schedule a visibility effect. + if (workInProgress.subtreeFlags & (Placement | Update)) workInProgress.flags |= Visibility; + } + return null; + case CacheComponent: + return null; + case TracingMarkerComponent: + return null; + } + throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + "React. Please file an issue."); + } + function unwindWork(current, workInProgress, renderLanes) { + // Note: This intentionally doesn't check if we're hydrating because comparing + // to the current tree provider fiber is just as fast and less error-prone. + // Ideally we would have a special version of the work loop only + // for hydration. + popTreeContext(workInProgress); + switch(workInProgress.tag){ + case ClassComponent: + var Component = workInProgress.type; + if (isContextProvider(Component)) popContext(workInProgress); + var flags = workInProgress.flags; + if (flags & ShouldCapture) { + workInProgress.flags = flags & ~ShouldCapture | DidCapture; + if ((workInProgress.mode & ProfileMode) !== NoMode) transferActualDuration(workInProgress); + return workInProgress; + } + return null; + case HostRoot: + var root = workInProgress.stateNode; + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); + var _flags = workInProgress.flags; + if ((_flags & ShouldCapture) !== NoFlags && (_flags & DidCapture) === NoFlags) { + // There was an error during render that wasn't captured by a suspense + // boundary. Do a second pass on the root to unmount the children. + workInProgress.flags = _flags & ~ShouldCapture | DidCapture; + return workInProgress; + } // We unwound to the root without completing it. Exit. + return null; + case HostComponent: + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + case SuspenseComponent: + popSuspenseContext(workInProgress); + var suspenseState = workInProgress.memoizedState; + if (suspenseState !== null && suspenseState.dehydrated !== null) { + if (workInProgress.alternate === null) throw new Error("Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue."); + resetHydrationState(); + } + var _flags2 = workInProgress.flags; + if (_flags2 & ShouldCapture) { + workInProgress.flags = _flags2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary. + if ((workInProgress.mode & ProfileMode) !== NoMode) transferActualDuration(workInProgress); + return workInProgress; + } + return null; + case SuspenseListComponent: + popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been + // caught by a nested boundary. If not, it should bubble through. + return null; + case HostPortal: + popHostContainer(workInProgress); + return null; + case ContextProvider: + var context = workInProgress.type._context; + popProvider(context, workInProgress); + return null; + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(workInProgress); + return null; + case CacheComponent: + return null; + default: + return null; + } + } + function unwindInterruptedWork(current, interruptedWork, renderLanes) { + // Note: This intentionally doesn't check if we're hydrating because comparing + // to the current tree provider fiber is just as fast and less error-prone. + // Ideally we would have a special version of the work loop only + // for hydration. + popTreeContext(interruptedWork); + switch(interruptedWork.tag){ + case ClassComponent: + var childContextTypes = interruptedWork.type.childContextTypes; + if (childContextTypes !== null && childContextTypes !== undefined) popContext(interruptedWork); + break; + case HostRoot: + var root = interruptedWork.stateNode; + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + resetWorkInProgressVersions(); + break; + case HostComponent: + popHostContext(interruptedWork); + break; + case HostPortal: + popHostContainer(interruptedWork); + break; + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; + case ContextProvider: + var context = interruptedWork.type._context; + popProvider(context, interruptedWork); + break; + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(interruptedWork); + break; + } + } + var didWarnAboutUndefinedSnapshotBeforeUpdate = null; + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); + // Allows us to avoid traversing the return path to find the nearest Offscreen ancestor. + // Only used when enableSuspenseLayoutEffectSemantics is enabled. + var offscreenSubtreeIsHidden = false; + var offscreenSubtreeWasHidden = false; + var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; + var nextEffect = null; // Used for Profiling builds to track updaters. + var inProgressLanes = null; + var inProgressRoot = null; + function reportUncaughtErrorInDEV(error) { + invokeGuardedCallback(null, function() { + throw error; + }); + clearCaughtError(); + } + var callComponentWillUnmountWithTimer = function(current, instance) { + instance.props = current.memoizedProps; + instance.state = current.memoizedState; + if (current.mode & ProfileMode) try { + startLayoutEffectTimer(); + instance.componentWillUnmount(); + } finally{ + recordLayoutEffectDuration(current); + } + else instance.componentWillUnmount(); + }; // Capture errors so they don't interrupt mounting. + function safelyCallCommitHookLayoutEffectListMount(current, nearestMountedAncestor) { + try { + commitHookEffectListMount(Layout, current); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + } // Capture errors so they don't interrupt unmounting. + function safelyCallComponentWillUnmount(current, nearestMountedAncestor, instance) { + try { + callComponentWillUnmountWithTimer(current, instance); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + } // Capture errors so they don't interrupt mounting. + function safelyCallComponentDidMount(current, nearestMountedAncestor, instance) { + try { + instance.componentDidMount(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + } // Capture errors so they don't interrupt mounting. + function safelyAttachRef(current, nearestMountedAncestor) { + try { + commitAttachRef(current); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + } + function safelyDetachRef(current, nearestMountedAncestor) { + var ref = current.ref; + if (ref !== null) { + if (typeof ref === "function") { + var retVal; + try { + if (enableProfilerTimer && enableProfilerCommitHooks && current.mode & ProfileMode) try { + startLayoutEffectTimer(); + retVal = ref(null); + } finally{ + recordLayoutEffectDuration(current); + } + else retVal = ref(null); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + if (typeof retVal === "function") error("Unexpected return value from a callback ref in %s. A callback ref should not return a function.", getComponentNameFromFiber(current)); + } else ref.current = null; + } + } + function safelyCallDestroy(current, nearestMountedAncestor, destroy) { + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); + } + } + var focusedInstanceHandle = null; + var shouldFireAfterActiveInstanceBlur = false; + function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = prepareForCommit(root.containerInfo); + nextEffect = firstChild; + commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber + var shouldFire = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = false; + focusedInstanceHandle = null; + return shouldFire; + } + function commitBeforeMutationEffects_begin() { + while(nextEffect !== null){ + var fiber = nextEffect; // This phase is only used for beforeActiveInstanceBlur. + var child = fiber.child; + if ((fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && child !== null) { + child.return = fiber; + nextEffect = child; + } else commitBeforeMutationEffects_complete(); + } + } + function commitBeforeMutationEffects_complete() { + while(nextEffect !== null){ + var fiber = nextEffect; + setCurrentFiber(fiber); + try { + commitBeforeMutationEffectsOnFiber(fiber); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + resetCurrentFiber(); + var sibling = fiber.sibling; + if (sibling !== null) { + sibling.return = fiber.return; + nextEffect = sibling; + return; + } + nextEffect = fiber.return; + } + } + function commitBeforeMutationEffectsOnFiber(finishedWork) { + var current = finishedWork.alternate; + var flags = finishedWork.flags; + if ((flags & Snapshot) !== NoFlags) { + setCurrentFiber(finishedWork); + switch(finishedWork.tag){ + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + break; + case ClassComponent: + if (current !== null) { + var prevProps = current.memoizedProps; + var prevState = current.memoizedState; + var instance = finishedWork.stateNode; // We could update instance props and state here, + if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { + if (instance.props !== finishedWork.memoizedProps) error("Expected %s props to match memoized props before getSnapshotBeforeUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance"); + if (instance.state !== finishedWork.memoizedState) error("Expected %s state to match memoized state before getSnapshotBeforeUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.state`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance"); + } + var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState); + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { + didWarnSet.add(finishedWork.type); + error("%s.getSnapshotBeforeUpdate(): A snapshot value (or null) must be returned. You have returned undefined.", getComponentNameFromFiber(finishedWork)); + } + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + break; + case HostRoot: + var root = finishedWork.stateNode; + clearContainer(root.containerInfo); + break; + case HostComponent: + case HostText: + case HostPortal: + case IncompleteClassComponent: + break; + default: + throw new Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."); + } + resetCurrentFiber(); + } + } + function commitHookEffectListUnmount(flags, finishedWork, nearestMountedAncestor) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + do { + if ((effect.tag & flags) === flags) { + // Unmount + var destroy = effect.destroy; + effect.destroy = undefined; + if (destroy !== undefined) { + if ((flags & Passive$1) !== NoFlags$1) markComponentPassiveEffectUnmountStarted(finishedWork); + else if ((flags & Layout) !== NoFlags$1) markComponentLayoutEffectUnmountStarted(finishedWork); + if ((flags & Insertion) !== NoFlags$1) setIsRunningInsertionEffect(true); + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + if ((flags & Insertion) !== NoFlags$1) setIsRunningInsertionEffect(false); + if ((flags & Passive$1) !== NoFlags$1) markComponentPassiveEffectUnmountStopped(); + else if ((flags & Layout) !== NoFlags$1) markComponentLayoutEffectUnmountStopped(); + } + } + effect = effect.next; + }while (effect !== firstEffect); + } + } + function commitHookEffectListMount(flags, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + do { + if ((effect.tag & flags) === flags) { + if ((flags & Passive$1) !== NoFlags$1) markComponentPassiveEffectMountStarted(finishedWork); + else if ((flags & Layout) !== NoFlags$1) markComponentLayoutEffectMountStarted(finishedWork); + var create = effect.create; + if ((flags & Insertion) !== NoFlags$1) setIsRunningInsertionEffect(true); + effect.destroy = create(); + if ((flags & Insertion) !== NoFlags$1) setIsRunningInsertionEffect(false); + if ((flags & Passive$1) !== NoFlags$1) markComponentPassiveEffectMountStopped(); + else if ((flags & Layout) !== NoFlags$1) markComponentLayoutEffectMountStopped(); + var destroy = effect.destroy; + if (destroy !== undefined && typeof destroy !== "function") { + var hookName = void 0; + if ((effect.tag & Layout) !== NoFlags) hookName = "useLayoutEffect"; + else if ((effect.tag & Insertion) !== NoFlags) hookName = "useInsertionEffect"; + else hookName = "useEffect"; + var addendum = void 0; + if (destroy === null) addendum = " You returned null. If your effect does not require clean up, return undefined (or nothing)."; + else if (typeof destroy.then === "function") addendum = "\n\nIt looks like you wrote " + hookName + "(async () => ...) or returned a Promise. " + "Instead, write the async function inside your effect " + "and call it immediately:\n\n" + hookName + "(() => {\n" + " async function fetchData() {\n" + " // You can await here\n" + " const response = await MyAPI.getData(someId);\n" + " // ...\n" + " }\n" + " fetchData();\n" + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; + else addendum = " You returned: " + destroy; + error("%s must not return anything besides a function, which is used for clean-up.%s", hookName, addendum); + } + } + effect = effect.next; + }while (effect !== firstEffect); + } + } + function commitPassiveEffectDurations(finishedRoot, finishedWork) { + // Only Profilers with work in their subtree will have an Update effect scheduled. + if ((finishedWork.flags & Update) !== NoFlags) switch(finishedWork.tag){ + case Profiler: + var passiveEffectDuration = finishedWork.stateNode.passiveEffectDuration; + var _finishedWork$memoize = finishedWork.memoizedProps, id = _finishedWork$memoize.id, onPostCommit = _finishedWork$memoize.onPostCommit; // This value will still reflect the previous commit phase. + // It does not get reset until the start of the next commit phase. + var commitTime = getCommitTime(); + var phase = finishedWork.alternate === null ? "mount" : "update"; + if (isCurrentUpdateNested()) phase = "nested-update"; + if (typeof onPostCommit === "function") onPostCommit(id, phase, passiveEffectDuration, commitTime); + // Bubble times to the next nearest ancestor Profiler. + // After we process that Profiler, we'll bubble further up. + var parentFiber = finishedWork.return; + outer: while(parentFiber !== null){ + switch(parentFiber.tag){ + case HostRoot: + var root = parentFiber.stateNode; + root.passiveEffectDuration += passiveEffectDuration; + break outer; + case Profiler: + var parentStateNode = parentFiber.stateNode; + parentStateNode.passiveEffectDuration += passiveEffectDuration; + break outer; + } + parentFiber = parentFiber.return; + } + break; + } + } + function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork, committedLanes) { + if ((finishedWork.flags & LayoutMask) !== NoFlags) switch(finishedWork.tag){ + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + if (!offscreenSubtreeWasHidden) { + // At this point layout effects have already been destroyed (during mutation phase). + // This is done to prevent sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + if (finishedWork.mode & ProfileMode) try { + startLayoutEffectTimer(); + commitHookEffectListMount(Layout | HasEffect, finishedWork); + } finally{ + recordLayoutEffectDuration(finishedWork); + } + else commitHookEffectListMount(Layout | HasEffect, finishedWork); + } + break; + case ClassComponent: + var instance = finishedWork.stateNode; + if (finishedWork.flags & Update) { + if (!offscreenSubtreeWasHidden) { + if (current === null) { + if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { + if (instance.props !== finishedWork.memoizedProps) error("Expected %s props to match memoized props before componentDidMount. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance"); + if (instance.state !== finishedWork.memoizedState) error("Expected %s state to match memoized state before componentDidMount. This might either be because of a bug in React, or because a component reassigns its own `this.state`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance"); + } + if (finishedWork.mode & ProfileMode) try { + startLayoutEffectTimer(); + instance.componentDidMount(); + } finally{ + recordLayoutEffectDuration(finishedWork); + } + else instance.componentDidMount(); + } else { + var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps); + var prevState = current.memoizedState; // We could update instance props and state here, + if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { + if (instance.props !== finishedWork.memoizedProps) error("Expected %s props to match memoized props before componentDidUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance"); + if (instance.state !== finishedWork.memoizedState) error("Expected %s state to match memoized state before componentDidUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.state`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance"); + } + if (finishedWork.mode & ProfileMode) try { + startLayoutEffectTimer(); + instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate); + } finally{ + recordLayoutEffectDuration(finishedWork); + } + else instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate); + } + } + } // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + var updateQueue = finishedWork.updateQueue; + if (updateQueue !== null) { + if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) { + if (instance.props !== finishedWork.memoizedProps) error("Expected %s props to match memoized props before processing the update queue. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance"); + if (instance.state !== finishedWork.memoizedState) error("Expected %s state to match memoized state before processing the update queue. This might either be because of a bug in React, or because a component reassigns its own `this.state`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance"); + } + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + commitUpdateQueue(finishedWork, updateQueue, instance); + } + break; + case HostRoot: + // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + var _updateQueue = finishedWork.updateQueue; + if (_updateQueue !== null) { + var _instance = null; + if (finishedWork.child !== null) switch(finishedWork.child.tag){ + case HostComponent: + _instance = getPublicInstance(finishedWork.child.stateNode); + break; + case ClassComponent: + _instance = finishedWork.child.stateNode; + break; + } + commitUpdateQueue(finishedWork, _updateQueue, _instance); + } + break; + case HostComponent: + var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted + // (eg DOM renderer may schedule auto-focus for inputs and form controls). + // These effects should only be committed when components are first mounted, + // aka when there is no current/alternate. + if (current === null && finishedWork.flags & Update) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + commitMount(_instance2, type, props); + } + break; + case HostText: + break; + case HostPortal: + break; + case Profiler: + var _finishedWork$memoize2 = finishedWork.memoizedProps, onCommit = _finishedWork$memoize2.onCommit, onRender = _finishedWork$memoize2.onRender; + var effectDuration = finishedWork.stateNode.effectDuration; + var commitTime = getCommitTime(); + var phase = current === null ? "mount" : "update"; + if (isCurrentUpdateNested()) phase = "nested-update"; + if (typeof onRender === "function") onRender(finishedWork.memoizedProps.id, phase, finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, commitTime); + if (typeof onCommit === "function") onCommit(finishedWork.memoizedProps.id, phase, effectDuration, commitTime); + // Schedule a passive effect for this Profiler to call onPostCommit hooks. + // This effect should be scheduled even if there is no onPostCommit callback for this Profiler, + // because the effect is also where times bubble to parent Profilers. + enqueuePendingPassiveProfilerEffect(finishedWork); // Propagate layout effect durations to the next nearest Profiler ancestor. + // Do not reset these values until the next render so DevTools has a chance to read them first. + var parentFiber = finishedWork.return; + outer: while(parentFiber !== null){ + switch(parentFiber.tag){ + case HostRoot: + var root = parentFiber.stateNode; + root.effectDuration += effectDuration; + break outer; + case Profiler: + var parentStateNode = parentFiber.stateNode; + parentStateNode.effectDuration += effectDuration; + break outer; + } + parentFiber = parentFiber.return; + } + break; + case SuspenseComponent: + commitSuspenseHydrationCallbacks(finishedRoot, finishedWork); + break; + case SuspenseListComponent: + case IncompleteClassComponent: + case ScopeComponent: + case OffscreenComponent: + case LegacyHiddenComponent: + case TracingMarkerComponent: + break; + default: + throw new Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue."); + } + if (!offscreenSubtreeWasHidden) { + if (finishedWork.flags & Ref) commitAttachRef(finishedWork); + } + } + function reappearLayoutEffectsOnFiber(node) { + // Turn on layout effects in a tree that previously disappeared. + // TODO (Offscreen) Check: flags & LayoutStatic + switch(node.tag){ + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + if (node.mode & ProfileMode) try { + startLayoutEffectTimer(); + safelyCallCommitHookLayoutEffectListMount(node, node.return); + } finally{ + recordLayoutEffectDuration(node); + } + else safelyCallCommitHookLayoutEffectListMount(node, node.return); + break; + case ClassComponent: + var instance = node.stateNode; + if (typeof instance.componentDidMount === "function") safelyCallComponentDidMount(node, node.return, instance); + safelyAttachRef(node, node.return); + break; + case HostComponent: + safelyAttachRef(node, node.return); + break; + } + } + function hideOrUnhideAllChildren(finishedWork, isHidden) { + // Only hide or unhide the top-most host nodes. + var hostSubtreeRoot = null; + // We only have the top Fiber that was inserted but we need to recurse down its + // children to find all the terminal nodes. + var node = finishedWork; + while(true){ + if (node.tag === HostComponent) { + if (hostSubtreeRoot === null) { + hostSubtreeRoot = node; + try { + var instance = node.stateNode; + if (isHidden) hideInstance(instance); + else unhideInstance(node.stateNode, node.memoizedProps); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } else if (node.tag === HostText) { + if (hostSubtreeRoot === null) try { + var _instance3 = node.stateNode; + if (isHidden) hideTextInstance(_instance3); + else unhideTextInstance(_instance3, node.memoizedProps); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } else if ((node.tag === OffscreenComponent || node.tag === LegacyHiddenComponent) && node.memoizedState !== null && node !== finishedWork) ; + else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === finishedWork) return; + while(node.sibling === null){ + if (node.return === null || node.return === finishedWork) return; + if (hostSubtreeRoot === node) hostSubtreeRoot = null; + node = node.return; + } + if (hostSubtreeRoot === node) hostSubtreeRoot = null; + node.sibling.return = node.return; + node = node.sibling; + } + } + function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; + if (ref !== null) { + var instance = finishedWork.stateNode; + var instanceToUse; + switch(finishedWork.tag){ + case HostComponent: + instanceToUse = getPublicInstance(instance); + break; + default: + instanceToUse = instance; + } // Moved outside to ensure DCE works with this flag + if (typeof ref === "function") { + var retVal; + if (finishedWork.mode & ProfileMode) try { + startLayoutEffectTimer(); + retVal = ref(instanceToUse); + } finally{ + recordLayoutEffectDuration(finishedWork); + } + else retVal = ref(instanceToUse); + if (typeof retVal === "function") error("Unexpected return value from a callback ref in %s. A callback ref should not return a function.", getComponentNameFromFiber(finishedWork)); + } else { + if (!ref.hasOwnProperty("current")) error("Unexpected ref object provided for %s. Use either a ref-setter function or React.createRef().", getComponentNameFromFiber(finishedWork)); + ref.current = instanceToUse; + } + } + } + function detachFiberMutation(fiber) { + // Cut off the return pointer to disconnect it from the tree. + // This enables us to detect and warn against state updates on an unmounted component. + // It also prevents events from bubbling from within disconnected components. + // + // Ideally, we should also clear the child pointer of the parent alternate to let this + // get GC:ed but we don't know which for sure which parent is the current + // one so we'll settle for GC:ing the subtree of this child. + // This child itself will be GC:ed when the parent updates the next time. + // + // Note that we can't clear child or sibling pointers yet. + // They're needed for passive effects and for findDOMNode. + // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects). + // + // Don't reset the alternate yet, either. We need that so we can detach the + // alternate's fields in the passive phase. Clearing the return pointer is + // sufficient for findDOMNode semantics. + var alternate = fiber.alternate; + if (alternate !== null) alternate.return = null; + fiber.return = null; + } + function detachFiberAfterEffects(fiber) { + var alternate = fiber.alternate; + if (alternate !== null) { + fiber.alternate = null; + detachFiberAfterEffects(alternate); + } // Note: Defensively using negation instead of < in case + // Clear cyclical Fiber fields. This level alone is designed to roughly + // approximate the planned Fiber refactor. In that world, `setState` will be + // bound to a special "instance" object instead of a Fiber. The Instance + // object will not have any of these fields. It will only be connected to + // the fiber tree via a single link at the root. So if this level alone is + // sufficient to fix memory issues, that bodes well for our plans. + fiber.child = null; + fiber.deletions = null; + fiber.sibling = null; // The `stateNode` is cyclical because on host nodes it points to the host + // tree, which has its own pointers to children, parents, and siblings. + // The other host nodes also point back to fibers, so we should detach that + // one, too. + if (fiber.tag === HostComponent) { + var hostInstance = fiber.stateNode; + if (hostInstance !== null) detachDeletedInstance(hostInstance); + } + fiber.stateNode = null; // I'm intentionally not clearing the `return` field in this level. We + fiber._debugOwner = null; + // Theoretically, nothing in here should be necessary, because we already + // disconnected the fiber from the tree. So even if something leaks this + // particular fiber, it won't leak anything else + // + // The purpose of this branch is to be super aggressive so we can measure + // if there's any difference in memory impact. If there is, that could + // indicate a React leak we don't know about. + fiber.return = null; + fiber.dependencies = null; + fiber.memoizedProps = null; + fiber.memoizedState = null; + fiber.pendingProps = null; + fiber.stateNode = null; // TODO: Move to `commitPassiveUnmountInsideDeletedTreeOnFiber` instead. + fiber.updateQueue = null; + } + function getHostParentFiber(fiber) { + var parent = fiber.return; + while(parent !== null){ + if (isHostParent(parent)) return parent; + parent = parent.return; + } + throw new Error("Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue."); + } + function isHostParent(fiber) { + return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal; + } + function getHostSibling(fiber) { + // We're going to search forward into the tree until we find a sibling host + // node. Unfortunately, if multiple insertions are done in a row we have to + // search past them. This leads to exponential search for the next sibling. + // TODO: Find a more efficient way to do this. + var node = fiber; + siblings: while(true){ + // If we didn't find anything, let's try the next sibling. + while(node.sibling === null){ + if (node.return === null || isHostParent(node.return)) // If we pop out of the root or hit the parent the fiber we are the + // last sibling. + return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + while(node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment){ + // If it is not host node and, we might have a host node inside it. + // Try to search down until we find one. + if (node.flags & Placement) continue siblings; + // If we don't have a child, try the siblings instead. + // We also skip portals because they are not part of this host tree. + if (node.child === null || node.tag === HostPortal) continue siblings; + else { + node.child.return = node; + node = node.child; + } + } // Check if this host node is stable or about to be placed. + if (!(node.flags & Placement)) // Found it! + return node.stateNode; + } + } + function commitPlacement(finishedWork) { + var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. + switch(parentFiber.tag){ + case HostComponent: + var parent = parentFiber.stateNode; + if (parentFiber.flags & ContentReset) { + // Reset the text content of the parent before doing any insertions + resetTextContent(parent); // Clear ContentReset from the effect tag + parentFiber.flags &= ~ContentReset; + } + var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its + // children to find all the terminal nodes. + insertOrAppendPlacementNode(finishedWork, before, parent); + break; + case HostRoot: + case HostPortal: + var _parent = parentFiber.stateNode.containerInfo; + var _before = getHostSibling(finishedWork); + insertOrAppendPlacementNodeIntoContainer(finishedWork, _before, _parent); + break; + // eslint-disable-next-line-no-fallthrough + default: + throw new Error("Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue."); + } + } + function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; + if (isHost) { + var stateNode = node.stateNode; + if (before) insertInContainerBefore(parent, stateNode, before); + else appendChildToContainer(parent, stateNode); + } else if (tag === HostPortal) ; + else { + var child = node.child; + if (child !== null) { + insertOrAppendPlacementNodeIntoContainer(child, before, parent); + var sibling = child.sibling; + while(sibling !== null){ + insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); + sibling = sibling.sibling; + } + } + } + } + function insertOrAppendPlacementNode(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; + if (isHost) { + var stateNode = node.stateNode; + if (before) insertBefore(parent, stateNode, before); + else appendChild(parent, stateNode); + } else if (tag === HostPortal) ; + else { + var child = node.child; + if (child !== null) { + insertOrAppendPlacementNode(child, before, parent); + var sibling = child.sibling; + while(sibling !== null){ + insertOrAppendPlacementNode(sibling, before, parent); + sibling = sibling.sibling; + } + } + } + } // These are tracked on the stack as we recursively traverse a + // deleted subtree. + // TODO: Update these during the whole mutation phase, not just during + // a deletion. + var hostParent = null; + var hostParentIsContainer = false; + function commitDeletionEffects(root, returnFiber, deletedFiber) { + // We only have the top Fiber that was deleted but we need to recurse down its + // children to find all the terminal nodes. + // Recursively delete all host nodes from the parent, detach refs, clean + // up mounted layout effects, and call componentWillUnmount. + // We only need to remove the topmost host child in each branch. But then we + // still need to keep traversing to unmount effects, refs, and cWU. TODO: We + // could split this into two separate traversals functions, where the second + // one doesn't include any removeChild logic. This is maybe the same + // function as "disappearLayoutEffects" (or whatever that turns into after + // the layout phase is refactored to use recursion). + // Before starting, find the nearest host parent on the stack so we know + // which instance/container to remove the children from. + // TODO: Instead of searching up the fiber return path on every deletion, we + // can track the nearest host component on the JS stack as we traverse the + // tree during the commit phase. This would make insertions faster, too. + var parent = returnFiber; + findParent: while(parent !== null){ + switch(parent.tag){ + case HostComponent: + hostParent = parent.stateNode; + hostParentIsContainer = false; + break findParent; + case HostRoot: + hostParent = parent.stateNode.containerInfo; + hostParentIsContainer = true; + break findParent; + case HostPortal: + hostParent = parent.stateNode.containerInfo; + hostParentIsContainer = true; + break findParent; + } + parent = parent.return; + } + if (hostParent === null) throw new Error("Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue."); + commitDeletionEffectsOnFiber(root, returnFiber, deletedFiber); + hostParent = null; + hostParentIsContainer = false; + detachFiberMutation(deletedFiber); + } + function recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, parent) { + // TODO: Use a static flag to skip trees that don't have unmount effects + var child = parent.child; + while(child !== null){ + commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, child); + child = child.sibling; + } + } + function commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, deletedFiber) { + onCommitUnmount(deletedFiber); // The cases in this outer switch modify the stack before they traverse + // into their subtree. There are simpler cases in the inner switch + // that don't modify the stack. + switch(deletedFiber.tag){ + case HostComponent: + if (!offscreenSubtreeWasHidden) safelyDetachRef(deletedFiber, nearestMountedAncestor); + // Intentional fallthrough to next branch + // eslint-disable-next-line-no-fallthrough + case HostText: + var prevHostParent = hostParent; + var prevHostParentIsContainer = hostParentIsContainer; + hostParent = null; + recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); + hostParent = prevHostParent; + hostParentIsContainer = prevHostParentIsContainer; + if (hostParent !== null) { + // Now that all the child effects have unmounted, we can remove the + // node from the tree. + if (hostParentIsContainer) removeChildFromContainer(hostParent, deletedFiber.stateNode); + else removeChild(hostParent, deletedFiber.stateNode); + } + return; + case DehydratedFragment: + if (hostParent !== null) { + if (hostParentIsContainer) clearSuspenseBoundaryFromContainer(hostParent, deletedFiber.stateNode); + else clearSuspenseBoundary(hostParent, deletedFiber.stateNode); + } + return; + case HostPortal: + // When we go into a portal, it becomes the parent to remove from. + var _prevHostParent = hostParent; + var _prevHostParentIsContainer = hostParentIsContainer; + hostParent = deletedFiber.stateNode.containerInfo; + hostParentIsContainer = true; + recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); + hostParent = _prevHostParent; + hostParentIsContainer = _prevHostParentIsContainer; + return; + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: + if (!offscreenSubtreeWasHidden) { + var updateQueue = deletedFiber.updateQueue; + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + do { + var _effect = effect, destroy = _effect.destroy, tag = _effect.tag; + if (destroy !== undefined) { + if ((tag & Insertion) !== NoFlags$1) safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy); + else if ((tag & Layout) !== NoFlags$1) { + markComponentLayoutEffectUnmountStarted(deletedFiber); + if (deletedFiber.mode & ProfileMode) { + startLayoutEffectTimer(); + safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy); + recordLayoutEffectDuration(deletedFiber); + } else safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy); + markComponentLayoutEffectUnmountStopped(); + } + } + effect = effect.next; + }while (effect !== firstEffect); + } + } + } + recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); + return; + case ClassComponent: + if (!offscreenSubtreeWasHidden) { + safelyDetachRef(deletedFiber, nearestMountedAncestor); + var instance = deletedFiber.stateNode; + if (typeof instance.componentWillUnmount === "function") safelyCallComponentWillUnmount(deletedFiber, nearestMountedAncestor, instance); + } + recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); + return; + case ScopeComponent: + recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); + return; + case OffscreenComponent: + if (deletedFiber.mode & ConcurrentMode) { + // If this offscreen component is hidden, we already unmounted it. Before + // deleting the children, track that it's already unmounted so that we + // don't attempt to unmount the effects again. + // TODO: If the tree is hidden, in most cases we should be able to skip + // over the nested children entirely. An exception is we haven't yet found + // the topmost host node to delete, which we already track on the stack. + // But the other case is portals, which need to be detached no matter how + // deeply they are nested. We should use a subtree flag to track whether a + // subtree includes a nested portal. + var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; + offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || deletedFiber.memoizedState !== null; + recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); + offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; + } else recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); + break; + default: + recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber); + return; + } + } + function commitSuspenseCallback(finishedWork) { + // TODO: Move this to passive phase + var newState = finishedWork.memoizedState; + } + function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) { + var newState = finishedWork.memoizedState; + if (newState === null) { + var current = finishedWork.alternate; + if (current !== null) { + var prevState = current.memoizedState; + if (prevState !== null) { + var suspenseInstance = prevState.dehydrated; + if (suspenseInstance !== null) commitHydratedSuspenseInstance(suspenseInstance); + } + } + } + } + function attachSuspenseRetryListeners(finishedWork) { + // If this boundary just timed out, then it will have a set of wakeables. + // For each wakeable, attach a listener so that when it resolves, React + // attempts to re-render the boundary in the primary (pre-timeout) state. + var wakeables = finishedWork.updateQueue; + if (wakeables !== null) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; + if (retryCache === null) retryCache = finishedWork.stateNode = new PossiblyWeakSet(); + wakeables.forEach(function(wakeable) { + // Memoize using the boundary fiber to prevent redundant listeners. + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + if (!retryCache.has(wakeable)) { + retryCache.add(wakeable); + if (isDevToolsPresent) { + if (inProgressLanes !== null && inProgressRoot !== null) // If we have pending work still, associate the original updaters with it. + restorePendingUpdaters(inProgressRoot, inProgressLanes); + else throw Error("Expected finished root and lanes to be set. This is a bug in React."); + } + wakeable.then(retry, retry); + } + }); + } + } // This function detects when a Suspense boundary goes from visible to hidden. + function commitMutationEffects(root, finishedWork, committedLanes) { + inProgressLanes = committedLanes; + inProgressRoot = root; + setCurrentFiber(finishedWork); + commitMutationEffectsOnFiber(finishedWork, root); + setCurrentFiber(finishedWork); + inProgressLanes = null; + inProgressRoot = null; + } + function recursivelyTraverseMutationEffects(root, parentFiber, lanes) { + // Deletions effects can be scheduled on any fiber type. They need to happen + // before the children effects hae fired. + var deletions = parentFiber.deletions; + if (deletions !== null) for(var i = 0; i < deletions.length; i++){ + var childToDelete = deletions[i]; + try { + commitDeletionEffects(root, parentFiber, childToDelete); + } catch (error) { + captureCommitPhaseError(childToDelete, parentFiber, error); + } + } + var prevDebugFiber = getCurrentFiber(); + if (parentFiber.subtreeFlags & MutationMask) { + var child = parentFiber.child; + while(child !== null){ + setCurrentFiber(child); + commitMutationEffectsOnFiber(child, root); + child = child.sibling; + } + } + setCurrentFiber(prevDebugFiber); + } + function commitMutationEffectsOnFiber(finishedWork, root, lanes) { + var current = finishedWork.alternate; + var flags = finishedWork.flags; // The effect flag should be checked *after* we refine the type of fiber, + // because the fiber tag is more specific. An exception is any flag related + // to reconcilation, because those can be set on all fiber types. + switch(finishedWork.tag){ + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & Update) { + try { + commitHookEffectListUnmount(Insertion | HasEffect, finishedWork, finishedWork.return); + commitHookEffectListMount(Insertion | HasEffect, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } // Layout effects are destroyed during the mutation phase so that all + // destroy functions for all fibers are called before any create functions. + // This prevents sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + if (finishedWork.mode & ProfileMode) { + try { + startLayoutEffectTimer(); + commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + recordLayoutEffectDuration(finishedWork); + } else try { + commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + return; + case ClassComponent: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & Ref) { + if (current !== null) safelyDetachRef(current, current.return); + } + return; + case HostComponent: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & Ref) { + if (current !== null) safelyDetachRef(current, current.return); + } + // TODO: ContentReset gets cleared by the children during the commit + // phase. This is a refactor hazard because it means we must read + // flags the flags after `commitReconciliationEffects` has already run; + // the order matters. We should refactor so that ContentReset does not + // rely on mutating the flag during commit. Like by setting a flag + // during the render phase instead. + if (finishedWork.flags & ContentReset) { + var instance = finishedWork.stateNode; + try { + resetTextContent(instance); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + if (flags & Update) { + var _instance4 = finishedWork.stateNode; + if (_instance4 != null) { + // Commit the work prepared earlier. + var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps + // as the newProps. The updatePayload will contain the real change in + // this case. + var oldProps = current !== null ? current.memoizedProps : newProps; + var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. + var updatePayload = finishedWork.updateQueue; + finishedWork.updateQueue = null; + if (updatePayload !== null) try { + commitUpdate(_instance4, updatePayload, type, oldProps, newProps, finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + return; + case HostText: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & Update) { + if (finishedWork.stateNode === null) throw new Error("This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue."); + var textInstance = finishedWork.stateNode; + var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps + // as the newProps. The updatePayload will contain the real change in + // this case. + var oldText = current !== null ? current.memoizedProps : newText; + try { + commitTextUpdate(textInstance, oldText, newText); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + return; + case HostRoot: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & Update) { + if (current !== null) { + var prevRootState = current.memoizedState; + if (prevRootState.isDehydrated) try { + commitHydratedContainer(root.containerInfo); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + } + } + return; + case HostPortal: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + return; + case SuspenseComponent: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + var offscreenFiber = finishedWork.child; + if (offscreenFiber.flags & Visibility) { + var offscreenInstance = offscreenFiber.stateNode; + var newState = offscreenFiber.memoizedState; + var isHidden = newState !== null; // Track the current state on the Offscreen instance so we can + // read it during an event + offscreenInstance.isHidden = isHidden; + if (isHidden) { + var wasHidden = offscreenFiber.alternate !== null && offscreenFiber.alternate.memoizedState !== null; + if (!wasHidden) // TODO: Move to passive phase + markCommitTimeOfFallback(); + } + } + if (flags & Update) { + try { + commitSuspenseCallback(finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } + attachSuspenseRetryListeners(finishedWork); + } + return; + case OffscreenComponent: + var _wasHidden = current !== null && current.memoizedState !== null; + if (finishedWork.mode & ConcurrentMode) { + // Before committing the children, track on the stack whether this + // offscreen subtree was already hidden, so that we don't unmount the + // effects again. + var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; + offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || _wasHidden; + recursivelyTraverseMutationEffects(root, finishedWork); + offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; + } else recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & Visibility) { + var _offscreenInstance = finishedWork.stateNode; + var _newState = finishedWork.memoizedState; + var _isHidden = _newState !== null; + var offscreenBoundary = finishedWork; // Track the current state on the Offscreen instance so we can + // read it during an event + _offscreenInstance.isHidden = _isHidden; + if (_isHidden) { + if (!_wasHidden) { + if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) { + nextEffect = offscreenBoundary; + var offscreenChild = offscreenBoundary.child; + while(offscreenChild !== null){ + nextEffect = offscreenChild; + disappearLayoutEffects_begin(offscreenChild); + offscreenChild = offscreenChild.sibling; + } + } + } + } + // TODO: This needs to run whenever there's an insertion or update + // inside a hidden Offscreen tree. + hideOrUnhideAllChildren(offscreenBoundary, _isHidden); + } + return; + case SuspenseListComponent: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + if (flags & Update) attachSuspenseRetryListeners(finishedWork); + return; + case ScopeComponent: + return; + default: + recursivelyTraverseMutationEffects(root, finishedWork); + commitReconciliationEffects(finishedWork); + return; + } + } + function commitReconciliationEffects(finishedWork) { + // Placement effects (insertions, reorders) can be scheduled on any fiber + // type. They needs to happen after the children effects have fired, but + // before the effects on this fiber have fired. + var flags = finishedWork.flags; + if (flags & Placement) { + try { + commitPlacement(finishedWork); + } catch (error) { + captureCommitPhaseError(finishedWork, finishedWork.return, error); + } // Clear the "placement" from effect tag so that we know that this is + // inserted, before any life-cycles like componentDidMount gets called. + // TODO: findDOMNode doesn't rely on this any more but isMounted does + // and isMounted is deprecated anyway so we should be able to kill this. + finishedWork.flags &= ~Placement; + } + if (flags & Hydrating) finishedWork.flags &= ~Hydrating; + } + function commitLayoutEffects(finishedWork, root, committedLanes) { + inProgressLanes = committedLanes; + inProgressRoot = root; + nextEffect = finishedWork; + commitLayoutEffects_begin(finishedWork, root, committedLanes); + inProgressLanes = null; + inProgressRoot = null; + } + function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { + // Suspense layout effects semantics don't change for legacy roots. + var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode; + while(nextEffect !== null){ + var fiber = nextEffect; + var firstChild = fiber.child; + if (fiber.tag === OffscreenComponent && isModernRoot) { + // Keep track of the current Offscreen stack's state. + var isHidden = fiber.memoizedState !== null; + var newOffscreenSubtreeIsHidden = isHidden || offscreenSubtreeIsHidden; + if (newOffscreenSubtreeIsHidden) { + // The Offscreen tree is hidden. Skip over its layout effects. + commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); + continue; + } else { + // TODO (Offscreen) Also check: subtreeFlags & LayoutMask + var current = fiber.alternate; + var wasHidden = current !== null && current.memoizedState !== null; + var newOffscreenSubtreeWasHidden = wasHidden || offscreenSubtreeWasHidden; + var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden; + var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; // Traverse the Offscreen subtree with the current Offscreen as the root. + offscreenSubtreeIsHidden = newOffscreenSubtreeIsHidden; + offscreenSubtreeWasHidden = newOffscreenSubtreeWasHidden; + if (offscreenSubtreeWasHidden && !prevOffscreenSubtreeWasHidden) { + // This is the root of a reappearing boundary. Turn its layout effects + // back on. + nextEffect = fiber; + reappearLayoutEffects_begin(fiber); + } + var child = firstChild; + while(child !== null){ + nextEffect = child; + commitLayoutEffects_begin(child, root, committedLanes); + child = child.sibling; + } // Restore Offscreen state and resume in our-progress traversal. + nextEffect = fiber; + offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden; + offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden; + commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); + continue; + } + } + if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) { + firstChild.return = fiber; + nextEffect = firstChild; + } else commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); + } + } + function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { + while(nextEffect !== null){ + var fiber = nextEffect; + if ((fiber.flags & LayoutMask) !== NoFlags) { + var current = fiber.alternate; + setCurrentFiber(fiber); + try { + commitLayoutEffectOnFiber(root, current, fiber, committedLanes); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + resetCurrentFiber(); + } + if (fiber === subtreeRoot) { + nextEffect = null; + return; + } + var sibling = fiber.sibling; + if (sibling !== null) { + sibling.return = fiber.return; + nextEffect = sibling; + return; + } + nextEffect = fiber.return; + } + } + function disappearLayoutEffects_begin(subtreeRoot) { + while(nextEffect !== null){ + var fiber = nextEffect; + var firstChild = fiber.child; // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic) + switch(fiber.tag){ + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: + if (fiber.mode & ProfileMode) try { + startLayoutEffectTimer(); + commitHookEffectListUnmount(Layout, fiber, fiber.return); + } finally{ + recordLayoutEffectDuration(fiber); + } + else commitHookEffectListUnmount(Layout, fiber, fiber.return); + break; + case ClassComponent: + // TODO (Offscreen) Check: flags & RefStatic + safelyDetachRef(fiber, fiber.return); + var instance = fiber.stateNode; + if (typeof instance.componentWillUnmount === "function") safelyCallComponentWillUnmount(fiber, fiber.return, instance); + break; + case HostComponent: + safelyDetachRef(fiber, fiber.return); + break; + case OffscreenComponent: + // Check if this is a + var isHidden = fiber.memoizedState !== null; + if (isHidden) { + // Nested Offscreen tree is already hidden. Don't disappear + // its effects. + disappearLayoutEffects_complete(subtreeRoot); + continue; + } + break; + } // TODO (Offscreen) Check: subtreeFlags & LayoutStatic + if (firstChild !== null) { + firstChild.return = fiber; + nextEffect = firstChild; + } else disappearLayoutEffects_complete(subtreeRoot); + } + } + function disappearLayoutEffects_complete(subtreeRoot) { + while(nextEffect !== null){ + var fiber = nextEffect; + if (fiber === subtreeRoot) { + nextEffect = null; + return; + } + var sibling = fiber.sibling; + if (sibling !== null) { + sibling.return = fiber.return; + nextEffect = sibling; + return; + } + nextEffect = fiber.return; + } + } + function reappearLayoutEffects_begin(subtreeRoot) { + while(nextEffect !== null){ + var fiber = nextEffect; + var firstChild = fiber.child; + if (fiber.tag === OffscreenComponent) { + var isHidden = fiber.memoizedState !== null; + if (isHidden) { + // Nested Offscreen tree is still hidden. Don't re-appear its effects. + reappearLayoutEffects_complete(subtreeRoot); + continue; + } + } // TODO (Offscreen) Check: subtreeFlags & LayoutStatic + if (firstChild !== null) { + // This node may have been reused from a previous render, so we can't + // assume its return pointer is correct. + firstChild.return = fiber; + nextEffect = firstChild; + } else reappearLayoutEffects_complete(subtreeRoot); + } + } + function reappearLayoutEffects_complete(subtreeRoot) { + while(nextEffect !== null){ + var fiber = nextEffect; // TODO (Offscreen) Check: flags & LayoutStatic + setCurrentFiber(fiber); + try { + reappearLayoutEffectsOnFiber(fiber); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + resetCurrentFiber(); + if (fiber === subtreeRoot) { + nextEffect = null; + return; + } + var sibling = fiber.sibling; + if (sibling !== null) { + // This node may have been reused from a previous render, so we can't + // assume its return pointer is correct. + sibling.return = fiber.return; + nextEffect = sibling; + return; + } + nextEffect = fiber.return; + } + } + function commitPassiveMountEffects(root, finishedWork, committedLanes, committedTransitions) { + nextEffect = finishedWork; + commitPassiveMountEffects_begin(finishedWork, root, committedLanes, committedTransitions); + } + function commitPassiveMountEffects_begin(subtreeRoot, root, committedLanes, committedTransitions) { + while(nextEffect !== null){ + var fiber = nextEffect; + var firstChild = fiber.child; + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) { + firstChild.return = fiber; + nextEffect = firstChild; + } else commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes, committedTransitions); + } + } + function commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes, committedTransitions) { + while(nextEffect !== null){ + var fiber = nextEffect; + if ((fiber.flags & Passive) !== NoFlags) { + setCurrentFiber(fiber); + try { + commitPassiveMountOnFiber(root, fiber, committedLanes, committedTransitions); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + resetCurrentFiber(); + } + if (fiber === subtreeRoot) { + nextEffect = null; + return; + } + var sibling = fiber.sibling; + if (sibling !== null) { + sibling.return = fiber.return; + nextEffect = sibling; + return; + } + nextEffect = fiber.return; + } + } + function commitPassiveMountOnFiber(finishedRoot, finishedWork, committedLanes, committedTransitions) { + switch(finishedWork.tag){ + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + if (finishedWork.mode & ProfileMode) { + startPassiveEffectTimer(); + try { + commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); + } finally{ + recordPassiveEffectDuration(finishedWork); + } + } else commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); + break; + } + } + function commitPassiveUnmountEffects(firstChild) { + nextEffect = firstChild; + commitPassiveUnmountEffects_begin(); + } + function commitPassiveUnmountEffects_begin() { + while(nextEffect !== null){ + var fiber = nextEffect; + var child = fiber.child; + if ((nextEffect.flags & ChildDeletion) !== NoFlags) { + var deletions = fiber.deletions; + if (deletions !== null) { + for(var i = 0; i < deletions.length; i++){ + var fiberToDelete = deletions[i]; + nextEffect = fiberToDelete; + commitPassiveUnmountEffectsInsideOfDeletedTree_begin(fiberToDelete, fiber); + } + // A fiber was deleted from this parent fiber, but it's still part of + // the previous (alternate) parent fiber's list of children. Because + // children are a linked list, an earlier sibling that's still alive + // will be connected to the deleted fiber via its `alternate`: + // + // live fiber + // --alternate--> previous live fiber + // --sibling--> deleted fiber + // + // We can't disconnect `alternate` on nodes that haven't been deleted + // yet, but we can disconnect the `sibling` and `child` pointers. + var previousFiber = fiber.alternate; + if (previousFiber !== null) { + var detachedChild = previousFiber.child; + if (detachedChild !== null) { + previousFiber.child = null; + do { + var detachedSibling = detachedChild.sibling; + detachedChild.sibling = null; + detachedChild = detachedSibling; + }while (detachedChild !== null); + } + } + nextEffect = fiber; + } + } + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) { + child.return = fiber; + nextEffect = child; + } else commitPassiveUnmountEffects_complete(); + } + } + function commitPassiveUnmountEffects_complete() { + while(nextEffect !== null){ + var fiber = nextEffect; + if ((fiber.flags & Passive) !== NoFlags) { + setCurrentFiber(fiber); + commitPassiveUnmountOnFiber(fiber); + resetCurrentFiber(); + } + var sibling = fiber.sibling; + if (sibling !== null) { + sibling.return = fiber.return; + nextEffect = sibling; + return; + } + nextEffect = fiber.return; + } + } + function commitPassiveUnmountOnFiber(finishedWork) { + switch(finishedWork.tag){ + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + if (finishedWork.mode & ProfileMode) { + startPassiveEffectTimer(); + commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return); + recordPassiveEffectDuration(finishedWork); + } else commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return); + break; + } + } + function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(deletedSubtreeRoot, nearestMountedAncestor) { + while(nextEffect !== null){ + var fiber = nextEffect; // Deletion effects fire in parent -> child order + // TODO: Check if fiber has a PassiveStatic flag + setCurrentFiber(fiber); + commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor); + resetCurrentFiber(); + var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag. (But, if we + // do this, still need to handle `deletedTreeCleanUpLevel` correctly.) + if (child !== null) { + child.return = fiber; + nextEffect = child; + } else commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot); + } + } + function commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot) { + while(nextEffect !== null){ + var fiber = nextEffect; + var sibling = fiber.sibling; + var returnFiber = fiber.return; + // Recursively traverse the entire deleted tree and clean up fiber fields. + // This is more aggressive than ideal, and the long term goal is to only + // have to detach the deleted tree at the root. + detachFiberAfterEffects(fiber); + if (fiber === deletedSubtreeRoot) { + nextEffect = null; + return; + } + if (sibling !== null) { + sibling.return = returnFiber; + nextEffect = sibling; + return; + } + nextEffect = returnFiber; + } + } + function commitPassiveUnmountInsideDeletedTreeOnFiber(current, nearestMountedAncestor) { + switch(current.tag){ + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + if (current.mode & ProfileMode) { + startPassiveEffectTimer(); + commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor); + recordPassiveEffectDuration(current); + } else commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor); + break; + } + } // TODO: Reuse reappearLayoutEffects traversal here? + function invokeLayoutEffectMountInDEV(fiber) { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + switch(fiber.tag){ + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + try { + commitHookEffectListMount(Layout | HasEffect, fiber); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + break; + case ClassComponent: + var instance = fiber.stateNode; + try { + instance.componentDidMount(); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + break; + } + } + function invokePassiveEffectMountInDEV(fiber) { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + switch(fiber.tag){ + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + try { + commitHookEffectListMount(Passive$1 | HasEffect, fiber); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + break; + } + } + function invokeLayoutEffectUnmountInDEV(fiber) { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + switch(fiber.tag){ + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + try { + commitHookEffectListUnmount(Layout | HasEffect, fiber, fiber.return); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + break; + case ClassComponent: + var instance = fiber.stateNode; + if (typeof instance.componentWillUnmount === "function") safelyCallComponentWillUnmount(fiber, fiber.return, instance); + break; + } + } + function invokePassiveEffectUnmountInDEV(fiber) { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + switch(fiber.tag){ + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + try { + commitHookEffectListUnmount(Passive$1 | HasEffect, fiber, fiber.return); + } catch (error) { + captureCommitPhaseError(fiber, fiber.return, error); + } + } + } + var COMPONENT_TYPE = 0; + var HAS_PSEUDO_CLASS_TYPE = 1; + var ROLE_TYPE = 2; + var TEST_NAME_TYPE = 3; + var TEXT_TYPE = 4; + if (typeof Symbol === "function" && Symbol.for) { + var symbolFor = Symbol.for; + COMPONENT_TYPE = symbolFor("selector.component"); + HAS_PSEUDO_CLASS_TYPE = symbolFor("selector.has_pseudo_class"); + ROLE_TYPE = symbolFor("selector.role"); + TEST_NAME_TYPE = symbolFor("selector.test_id"); + TEXT_TYPE = symbolFor("selector.text"); + } + var commitHooks = []; + function onCommitRoot$1() { + commitHooks.forEach(function(commitHook) { + return commitHook(); + }); + } + var ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue; + function isLegacyActEnvironment(fiber) { + // Legacy mode. We preserve the behavior of React 17's act. It assumes an + // act environment whenever `jest` is defined, but you can still turn off + // spurious warnings by setting IS_REACT_ACT_ENVIRONMENT explicitly + // to false. + var isReactActEnvironmentGlobal = typeof IS_REACT_ACT_ENVIRONMENT !== "undefined" ? IS_REACT_ACT_ENVIRONMENT : undefined; // $FlowExpectedError - Flow doesn't know about jest + var jestIsDefined = typeof jest !== "undefined"; + return jestIsDefined && isReactActEnvironmentGlobal !== false; + } + function isConcurrentActEnvironment() { + var isReactActEnvironmentGlobal = typeof IS_REACT_ACT_ENVIRONMENT !== "undefined" ? IS_REACT_ACT_ENVIRONMENT : undefined; + if (!isReactActEnvironmentGlobal && ReactCurrentActQueue.current !== null) // TODO: Include link to relevant documentation page. + error("The current testing environment is not configured to support act(...)"); + return isReactActEnvironmentGlobal; + } + var ceil = Math.ceil; + var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, ReactCurrentBatchConfig$3 = ReactSharedInternals.ReactCurrentBatchConfig, ReactCurrentActQueue$1 = ReactSharedInternals.ReactCurrentActQueue; + var NoContext = /* */ 0; + var BatchedContext = /* */ 1; + var RenderContext = /* */ 2; + var CommitContext = /* */ 4; + var RootInProgress = 0; + var RootFatalErrored = 1; + var RootErrored = 2; + var RootSuspended = 3; + var RootSuspendedWithDelay = 4; + var RootCompleted = 5; + var RootDidNotComplete = 6; // Describes where we are in the React execution stack + var executionContext = NoContext; // The root we're working on + var workInProgressRoot = null; // The fiber we're working on + var workInProgress = null; // The lanes we're rendering + var workInProgressRootRenderLanes = NoLanes; // Stack that allows components to change the render lanes for its subtree + // This is a superset of the lanes we started working on at the root. The only + // case where it's different from `workInProgressRootRenderLanes` is when we + // enter a subtree that is hidden and needs to be unhidden: Suspense and + // Offscreen component. + // + // Most things in the work loop should deal with workInProgressRootRenderLanes. + // Most things in begin/complete phases should deal with subtreeRenderLanes. + var subtreeRenderLanes = NoLanes; + var subtreeRenderLanesCursor = createCursor(NoLanes); // Whether to root completed, errored, suspended, etc. + var workInProgressRootExitStatus = RootInProgress; // A fatal error, if one is thrown + var workInProgressRootFatalError = null; // "Included" lanes refer to lanes that were worked on during this render. It's + // slightly different than `renderLanes` because `renderLanes` can change as you + // enter and exit an Offscreen tree. This value is the combination of all render + // lanes for the entire render phase. + var workInProgressRootIncludedLanes = NoLanes; // The work left over by components that were visited during this render. Only + // includes unprocessed updates, not work in bailed out children. + var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render. + var workInProgressRootInterleavedUpdatedLanes = NoLanes; // Lanes that were updated during the render phase (*not* an interleaved event). + var workInProgressRootPingedLanes = NoLanes; // Errors that are thrown during the render phase. + var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI. + // We will log them once the tree commits. + var workInProgressRootRecoverableErrors = null; // The most recent time we committed a fallback. This lets us ensure a train + // model where we don't commit new loading states in too quick succession. + var globalMostRecentFallbackTime = 0; + var FALLBACK_THROTTLE_MS = 500; // The absolute time for when we should start giving up on rendering + // more and prefer CPU suspense heuristics instead. + var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU + // suspense heuristics and opt out of rendering more content. + var RENDER_TIMEOUT_MS = 500; + var workInProgressTransitions = null; + function resetRenderTimer() { + workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS; + } + function getRenderTargetTime() { + return workInProgressRootRenderTargetTime; + } + var hasUncaughtError = false; + var firstUncaughtError = null; + var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true; + var rootDoesHavePassiveEffects = false; + var rootWithPendingPassiveEffects = null; + var pendingPassiveEffectsLanes = NoLanes; + var pendingPassiveProfilerEffects = []; + var pendingPassiveTransitions = null; // Use these to prevent an infinite loop of nested updates + var NESTED_UPDATE_LIMIT = 50; + var nestedUpdateCount = 0; + var rootWithNestedUpdates = null; + var isFlushingPassiveEffects = false; + var didScheduleUpdateDuringPassiveEffects = false; + var NESTED_PASSIVE_UPDATE_LIMIT = 50; + var nestedPassiveUpdateCount = 0; + var rootWithPassiveNestedUpdates = null; // If two updates are scheduled within the same event, we should treat their + // event times as simultaneous, even if the actual clock time has advanced + // between the first and second call. + var currentEventTime = NoTimestamp; + var currentEventTransitionLane = NoLanes; + var isRunningInsertionEffect = false; + function getWorkInProgressRoot() { + return workInProgressRoot; + } + function requestEventTime() { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) // We're inside React, so it's fine to read the actual time. + return now(); + // We're not inside React, so we may be in the middle of a browser event. + if (currentEventTime !== NoTimestamp) // Use the same start time for all updates until we enter React again. + return currentEventTime; + // This is the first update since React yielded. Compute a new start time. + currentEventTime = now(); + return currentEventTime; + } + function requestUpdateLane(fiber) { + // Special cases + var mode = fiber.mode; + if ((mode & ConcurrentMode) === NoMode) return SyncLane; + else if ((executionContext & RenderContext) !== NoContext && workInProgressRootRenderLanes !== NoLanes) // This is a render phase update. These are not officially supported. The + // old behavior is to give this the same "thread" (lanes) as + // whatever is currently rendering. So if you call `setState` on a component + // that happens later in the same render, it will flush. Ideally, we want to + // remove the special case and treat them as if they came from an + // interleaved event. Regardless, this pattern is not officially supported. + // This behavior is only a fallback. The flag only exists until we can roll + // out the setState warning, since existing code might accidentally rely on + // the current behavior. + return pickArbitraryLane(workInProgressRootRenderLanes); + var isTransition = requestCurrentTransition() !== NoTransition; + if (isTransition) { + if (ReactCurrentBatchConfig$3.transition !== null) { + var transition = ReactCurrentBatchConfig$3.transition; + if (!transition._updatedFibers) transition._updatedFibers = new Set(); + transition._updatedFibers.add(fiber); + } // The algorithm for assigning an update to a lane should be stable for all + // updates at the same priority within the same event. To do this, the + // inputs to the algorithm must be the same. + // + // The trick we use is to cache the first of each of these inputs within an + // event. Then reset the cached values once we can be sure the event is + // over. Our heuristic for that is whenever we enter a concurrent work loop. + if (currentEventTransitionLane === NoLane) // All transitions within the same event are assigned the same lane. + currentEventTransitionLane = claimNextTransitionLane(); + return currentEventTransitionLane; + } // Updates originating inside certain React methods, like flushSync, have + // their priority set by tracking it with a context variable. + // + // The opaque type returned by the host config is internally a lane, so we can + // use that directly. + // TODO: Move this type conversion to the event priority module. + var updateLane = getCurrentUpdatePriority(); + if (updateLane !== NoLane) return updateLane; + // This update originated outside React. Ask the host environment for an + // appropriate priority, based on the type of event. + // + // The opaque type returned by the host config is internally a lane, so we can + // use that directly. + // TODO: Move this type conversion to the event priority module. + var eventLane = getCurrentEventPriority(); + return eventLane; + } + function requestRetryLane(fiber) { + // This is a fork of `requestUpdateLane` designed specifically for Suspense + // "retries" \u2014 a special update that attempts to flip a Suspense boundary + // from its placeholder state to its primary/resolved state. + // Special cases + var mode = fiber.mode; + if ((mode & ConcurrentMode) === NoMode) return SyncLane; + return claimNextRetryLane(); + } + function scheduleUpdateOnFiber(root, fiber, lane, eventTime) { + checkForNestedUpdates(); + if (isRunningInsertionEffect) error("useInsertionEffect must not schedule updates."); + if (isFlushingPassiveEffects) didScheduleUpdateDuringPassiveEffects = true; + markRootUpdated(root, lane, eventTime); + if ((executionContext & RenderContext) !== NoLanes && root === workInProgressRoot) // This update was dispatched during the render phase. This is a mistake + // if the update originates from user space (with the exception of local + // hook updates, which are handled differently and don't reach this + // function), but there are some internal React features that use this as + // an implementation detail, like selective hydration. + warnAboutRenderPhaseUpdatesInDEV(fiber); // Track lanes that were updated during the render phase + else { + if (isDevToolsPresent) addFiberToLanesMap(root, fiber, lane); + warnIfUpdatesNotWrappedWithActDEV(fiber); + if (root === workInProgressRoot) { + // Received an update to a tree that's in the middle of rendering. Mark + // that there was an interleaved update work on this root. Unless the + // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render + // phase update. In that case, we don't treat render phase updates as if + // they were interleaved, for backwards compat reasons. + if ((executionContext & RenderContext) === NoContext) workInProgressRootInterleavedUpdatedLanes = mergeLanes(workInProgressRootInterleavedUpdatedLanes, lane); + if (workInProgressRootExitStatus === RootSuspendedWithDelay) // The root already suspended with a delay, which means this render + // definitely won't finish. Since we have a new update, let's mark it as + // suspended now, right before marking the incoming update. This has the + // effect of interrupting the current render and switching to the update. + // TODO: Make sure this doesn't override pings that happen while we've + // already started rendering. + markRootSuspended$1(root, workInProgressRootRenderLanes); + } + ensureRootIsScheduled(root, eventTime); + if (lane === SyncLane && executionContext === NoContext && (fiber.mode & ConcurrentMode) === NoMode && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode. + !ReactCurrentActQueue$1.isBatchingLegacy) { + // Flush the synchronous work now, unless we're already working or inside + // a batch. This is intentionally inside scheduleUpdateOnFiber instead of + // scheduleCallbackForFiber to preserve the ability to schedule a callback + // without immediately flushing it. We only do this for user-initiated + // updates, to preserve historical behavior of legacy mode. + resetRenderTimer(); + flushSyncCallbacksOnlyInLegacyMode(); + } + } + } + function scheduleInitialHydrationOnRoot(root, lane, eventTime) { + // This is a special fork of scheduleUpdateOnFiber that is only used to + // schedule the initial hydration of a root that has just been created. Most + // of the stuff in scheduleUpdateOnFiber can be skipped. + // + // The main reason for this separate path, though, is to distinguish the + // initial children from subsequent updates. In fully client-rendered roots + // (createRoot instead of hydrateRoot), all top-level renders are modeled as + // updates, but hydration roots are special because the initial render must + // match what was rendered on the server. + var current = root.current; + current.lanes = lane; + markRootUpdated(root, lane, eventTime); + ensureRootIsScheduled(root, eventTime); + } + function isUnsafeClassRenderPhaseUpdate(fiber) { + // Check if this is a render phase update. Only called by class components, + // which special (deprecated) behavior for UNSAFE_componentWillReceive props. + return(// decided not to enable it. + (executionContext & RenderContext) !== NoContext); + } // Use this function to schedule a task for a root. There's only one task per + // root; if a task was already scheduled, we'll check to make sure the priority + // of the existing task is the same as the priority of the next level that the + // root has work on. This function is called on every update, and right before + // exiting a task. + function ensureRootIsScheduled(root, currentTime) { + var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as + // expired so we know to work on those next. + markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority. + var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes); + if (nextLanes === NoLanes) { + // Special case: There's nothing to work on. + if (existingCallbackNode !== null) cancelCallback$1(existingCallbackNode); + root.callbackNode = null; + root.callbackPriority = NoLane; + return; + } // We use the highest priority lane to represent the priority of the callback. + var newCallbackPriority = getHighestPriorityLane(nextLanes); // Check if there's an existing task. We may be able to reuse it. + var existingCallbackPriority = root.callbackPriority; + if (existingCallbackPriority === newCallbackPriority && // Special case related to `act`. If the currently scheduled task is a + // Scheduler task, rather than an `act` task, cancel it and re-scheduled + // on the `act` queue. + !(ReactCurrentActQueue$1.current !== null && existingCallbackNode !== fakeActCallbackNode)) { + // If we're going to re-use an existing task, it needs to exist. + // Assume that discrete update microtasks are non-cancellable and null. + // TODO: Temporary until we confirm this warning is not fired. + if (existingCallbackNode == null && existingCallbackPriority !== SyncLane) error("Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue."); + return; + } + if (existingCallbackNode != null) // Cancel the existing callback. We'll schedule a new one below. + cancelCallback$1(existingCallbackNode); + // Schedule a new callback. + var newCallbackNode; + if (newCallbackPriority === SyncLane) { + // Special case: Sync React callbacks are scheduled on a special + // internal queue + if (root.tag === LegacyRoot) { + if (ReactCurrentActQueue$1.isBatchingLegacy !== null) ReactCurrentActQueue$1.didScheduleLegacyUpdate = true; + scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root)); + } else scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + // Flush the queue in a microtask. + if (ReactCurrentActQueue$1.current !== null) // Inside `act`, use our internal `act` queue so that these get flushed + // at the end of the current scope even when using the sync version + // of `act`. + ReactCurrentActQueue$1.current.push(flushSyncCallbacks); + else scheduleMicrotask(function() { + // In Safari, appending an iframe forces microtasks to run. + // https://github.com/facebook/react/issues/22459 + // We don't support running callbacks in the middle of render + // or commit so we need to check against that. + if ((executionContext & (RenderContext | CommitContext)) === NoContext) // Note that this would still prematurely flush the callbacks + // if this happens outside render or commit phase (e.g. in an event). + flushSyncCallbacks(); + }); + newCallbackNode = null; + } else { + var schedulerPriorityLevel; + switch(lanesToEventPriority(nextLanes)){ + case DiscreteEventPriority: + schedulerPriorityLevel = ImmediatePriority; + break; + case ContinuousEventPriority: + schedulerPriorityLevel = UserBlockingPriority; + break; + case DefaultEventPriority: + schedulerPriorityLevel = NormalPriority; + break; + case IdleEventPriority: + schedulerPriorityLevel = IdlePriority; + break; + default: + schedulerPriorityLevel = NormalPriority; + break; + } + newCallbackNode = scheduleCallback$1(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root)); + } + root.callbackPriority = newCallbackPriority; + root.callbackNode = newCallbackNode; + } // This is the entry point for every concurrent task, i.e. anything that + // goes through Scheduler. + function performConcurrentWorkOnRoot(root, didTimeout) { + resetNestedUpdateFlag(); + // event time. The next update will compute a new event time. + currentEventTime = NoTimestamp; + currentEventTransitionLane = NoLanes; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw new Error("Should not already be working."); + // Flush any pending passive effects before deciding which lanes to work on, + // in case they schedule additional work. + var originalCallbackNode = root.callbackNode; + var didFlushPassiveEffects = flushPassiveEffects(); + if (didFlushPassiveEffects) { + // Something in the passive effect phase may have canceled the current task. + // Check if the task node for this root was changed. + if (root.callbackNode !== originalCallbackNode) // The current task was canceled. Exit. We don't need to call + // `ensureRootIsScheduled` because the check above implies either that + // there's a new task, or that there's no remaining work on this root. + return null; + } // Determine the next lanes to work on, using the fields stored + // on the root. + var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes); + if (lanes === NoLanes) // Defensive coding. This is never expected to happen. + return null; + // We disable time-slicing in some cases: if the work has been CPU-bound + // for too long ("expired" work, to prevent starvation), or we're in + // sync-updates-by-default mode. + // TODO: We only check `didTimeout` defensively, to account for a Scheduler + // bug we're still investigating. Once the bug in Scheduler is fixed, + // we can remove this, since we track expiration ourselves. + var shouldTimeSlice = !includesBlockingLane(root, lanes) && !includesExpiredLane(root, lanes) && !didTimeout; + var exitStatus = shouldTimeSlice ? renderRootConcurrent(root, lanes) : renderRootSync(root, lanes); + if (exitStatus !== RootInProgress) { + if (exitStatus === RootErrored) { + // If something threw an error, try rendering one more time. We'll + // render synchronously to block concurrent data mutations, and we'll + // includes all pending updates are included. If it still fails after + // the second attempt, we'll give up and commit the resulting tree. + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; + exitStatus = recoverFromConcurrentError(root, errorRetryLanes); + } + } + if (exitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + prepareFreshStack(root, NoLanes); + markRootSuspended$1(root, lanes); + ensureRootIsScheduled(root, now()); + throw fatalError; + } + if (exitStatus === RootDidNotComplete) // The render unwound without completing the tree. This happens in special + // cases where need to exit the current render without producing a + // consistent tree or committing. + // + // This should only happen during a concurrent render, not a discrete or + // synchronous update. We should have already checked for this when we + // unwound the stack. + markRootSuspended$1(root, lanes); + else { + // The render completed. + // Check if this render may have yielded to a concurrent event, and if so, + // confirm that any newly rendered stores are consistent. + // TODO: It's possible that even a concurrent render may never have yielded + // to the main thread, if it was fast enough, or if it expired. We could + // skip the consistency check in that case, too. + var renderWasConcurrent = !includesBlockingLane(root, lanes); + var finishedWork = root.current.alternate; + if (renderWasConcurrent && !isRenderConsistentWithExternalStores(finishedWork)) { + // A store was mutated in an interleaved event. Render again, + // synchronously, to block further mutations. + exitStatus = renderRootSync(root, lanes); // We need to check again if something threw + if (exitStatus === RootErrored) { + var _errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); + if (_errorRetryLanes !== NoLanes) { + lanes = _errorRetryLanes; + exitStatus = recoverFromConcurrentError(root, _errorRetryLanes); // We assume the tree is now consistent because we didn't yield to any + // concurrent events. + } + } + if (exitStatus === RootFatalErrored) { + var _fatalError = workInProgressRootFatalError; + prepareFreshStack(root, NoLanes); + markRootSuspended$1(root, lanes); + ensureRootIsScheduled(root, now()); + throw _fatalError; + } + } // We now have a consistent tree. The next step is either to commit it, + // or, if something suspended, wait to commit it after a timeout. + root.finishedWork = finishedWork; + root.finishedLanes = lanes; + finishConcurrentRender(root, exitStatus, lanes); + } + } + ensureRootIsScheduled(root, now()); + if (root.callbackNode === originalCallbackNode) // The task node scheduled for this root is the same one that's + // currently executed. Need to return a continuation. + return performConcurrentWorkOnRoot.bind(null, root); + return null; + } + function recoverFromConcurrentError(root, errorRetryLanes) { + // If an error occurred during hydration, discard server response and fall + // back to client side render. + // Before rendering again, save the errors from the previous attempt. + var errorsFromFirstAttempt = workInProgressRootConcurrentErrors; + if (isRootDehydrated(root)) { + // The shell failed to hydrate. Set a flag to force a client rendering + // during the next attempt. To do this, we call prepareFreshStack now + // to create the root work-in-progress fiber. This is a bit weird in terms + // of factoring, because it relies on renderRootSync not calling + // prepareFreshStack again in the call below, which happens because the + // root and lanes haven't changed. + // + // TODO: I think what we should do is set ForceClientRender inside + // throwException, like we do for nested Suspense boundaries. The reason + // it's here instead is so we can switch to the synchronous work loop, too. + // Something to consider for a future refactor. + var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes); + rootWorkInProgress.flags |= ForceClientRender; + errorHydratingContainer(root.containerInfo); + } + var exitStatus = renderRootSync(root, errorRetryLanes); + if (exitStatus !== RootErrored) { + // Successfully finished rendering on retry + // The errors from the failed first attempt have been recovered. Add + // them to the collection of recoverable errors. We'll log them in the + // commit phase. + var errorsFromSecondAttempt = workInProgressRootRecoverableErrors; + workInProgressRootRecoverableErrors = errorsFromFirstAttempt; // The errors from the second attempt should be queued after the errors + // from the first attempt, to preserve the causal sequence. + if (errorsFromSecondAttempt !== null) queueRecoverableErrors(errorsFromSecondAttempt); + } + return exitStatus; + } + function queueRecoverableErrors(errors) { + if (workInProgressRootRecoverableErrors === null) workInProgressRootRecoverableErrors = errors; + else workInProgressRootRecoverableErrors.push.apply(workInProgressRootRecoverableErrors, errors); + } + function finishConcurrentRender(root, exitStatus, lanes) { + switch(exitStatus){ + case RootInProgress: + case RootFatalErrored: + throw new Error("Root did not complete. This is a bug in React."); + // Flow knows about invariant, so it complains if I add a break + // statement, but eslint doesn't know about invariant, so it complains + // if I do. eslint-disable-next-line no-fallthrough + case RootErrored: + // We should have already attempted to retry this tree. If we reached + // this point, it errored again. Commit it. + commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); + break; + case RootSuspended: + markRootSuspended$1(root, lanes); // We have an acceptable loading state. We need to figure out if we + // should immediately commit it or wait a bit. + if (includesOnlyRetries(lanes) && // do not delay if we're inside an act() scope + !shouldForceFlushFallbacksInDEV()) { + // This render only included retries, no updates. Throttle committing + // retries so that we don't show too many loading states too quickly. + var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time. + if (msUntilTimeout > 10) { + var nextLanes = getNextLanes(root, NoLanes); + if (nextLanes !== NoLanes) break; + var suspendedLanes = root.suspendedLanes; + if (!isSubsetOfLanes(suspendedLanes, lanes)) { + // We should prefer to render the fallback of at the last + // suspended level. Ping the last suspended level to try + // rendering it again. + // FIXME: What if the suspended lanes are Idle? Should not restart. + var eventTime = requestEventTime(); + markRootPinged(root, suspendedLanes); + break; + } // The render is suspended, it hasn't timed out, and there's no + // lower priority work to do. Instead of committing the fallback + // immediately, wait for more data to arrive. + root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors, workInProgressTransitions), msUntilTimeout); + break; + } + } // The work expired. Commit immediately. + commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); + break; + case RootSuspendedWithDelay: + markRootSuspended$1(root, lanes); + if (includesOnlyTransitions(lanes)) break; + if (!shouldForceFlushFallbacksInDEV()) { + // This is not a transition, but we did trigger an avoided state. + // Schedule a placeholder to display after a short delay, using the Just + // Noticeable Difference. + // TODO: Is the JND optimization worth the added complexity? If this is + // the only reason we track the event time, then probably not. + // Consider removing. + var mostRecentEventTime = getMostRecentEventTime(root, lanes); + var eventTimeMs = mostRecentEventTime; + var timeElapsedMs = now() - eventTimeMs; + var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs; // Don't bother with a very short suspense time. + if (_msUntilTimeout > 10) { + // Instead of committing the fallback immediately, wait for more data + // to arrive. + root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors, workInProgressTransitions), _msUntilTimeout); + break; + } + } // Commit the placeholder. + commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); + break; + case RootCompleted: + // The work completed. Ready to commit. + commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); + break; + default: + throw new Error("Unknown root exit status."); + } + } + function isRenderConsistentWithExternalStores(finishedWork) { + // Search the rendered tree for external store reads, and check whether the + // stores were mutated in a concurrent event. Intentionally using an iterative + // loop instead of recursion so we can exit early. + var node = finishedWork; + while(true){ + if (node.flags & StoreConsistency) { + var updateQueue = node.updateQueue; + if (updateQueue !== null) { + var checks = updateQueue.stores; + if (checks !== null) for(var i = 0; i < checks.length; i++){ + var check = checks[i]; + var getSnapshot = check.getSnapshot; + var renderedValue = check.value; + try { + if (!objectIs(getSnapshot(), renderedValue)) // Found an inconsistent store. + return false; + } catch (error) { + // If `getSnapshot` throws, return `false`. This will schedule + // a re-render, and the error will be rethrown during render. + return false; + } + } + } + } + var child = node.child; + if (node.subtreeFlags & StoreConsistency && child !== null) { + child.return = node; + node = child; + continue; + } + if (node === finishedWork) return true; + while(node.sibling === null){ + if (node.return === null || node.return === finishedWork) return true; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } // Flow doesn't know this is unreachable, but eslint does + // eslint-disable-next-line no-unreachable + return true; + } + function markRootSuspended$1(root, suspendedLanes) { + // When suspending, we should always exclude lanes that were pinged or (more + // rarely, since we try to avoid it) updated during the render phase. + // TODO: Lol maybe there's a better way to factor this besides this + // obnoxiously named function :) + suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes); + suspendedLanes = removeLanes(suspendedLanes, workInProgressRootInterleavedUpdatedLanes); + markRootSuspended(root, suspendedLanes); + } // This is the entry point for synchronous tasks that don't go + // through Scheduler + function performSyncWorkOnRoot(root) { + syncNestedUpdateFlag(); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw new Error("Should not already be working."); + flushPassiveEffects(); + var lanes = getNextLanes(root, NoLanes); + if (!includesSomeLane(lanes, SyncLane)) { + // There's no remaining sync work left. + ensureRootIsScheduled(root, now()); + return null; + } + var exitStatus = renderRootSync(root, lanes); + if (root.tag !== LegacyRoot && exitStatus === RootErrored) { + // If something threw an error, try rendering one more time. We'll render + // synchronously to block concurrent data mutations, and we'll includes + // all pending updates are included. If it still fails after the second + // attempt, we'll give up and commit the resulting tree. + var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root); + if (errorRetryLanes !== NoLanes) { + lanes = errorRetryLanes; + exitStatus = recoverFromConcurrentError(root, errorRetryLanes); + } + } + if (exitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + prepareFreshStack(root, NoLanes); + markRootSuspended$1(root, lanes); + ensureRootIsScheduled(root, now()); + throw fatalError; + } + if (exitStatus === RootDidNotComplete) throw new Error("Root did not complete. This is a bug in React."); + // We now have a consistent tree. Because this is a sync render, we + // will commit it even if something suspended. + var finishedWork = root.current.alternate; + root.finishedWork = finishedWork; + root.finishedLanes = lanes; + commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); // Before exiting, make sure there's a callback scheduled for the next + // pending level. + ensureRootIsScheduled(root, now()); + return null; + } + function flushRoot(root, lanes) { + if (lanes !== NoLanes) { + markRootEntangled(root, mergeLanes(lanes, SyncLane)); + ensureRootIsScheduled(root, now()); + if ((executionContext & (RenderContext | CommitContext)) === NoContext) { + resetRenderTimer(); + flushSyncCallbacks(); + } + } + } + function batchedUpdates$1(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; + try { + return fn(a); + } finally{ + executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer + // most batchedUpdates-like method. + if (executionContext === NoContext && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode. + !ReactCurrentActQueue$1.isBatchingLegacy) { + resetRenderTimer(); + flushSyncCallbacksOnlyInLegacyMode(); + } + } + } + function discreteUpdates(fn, a, b, c, d) { + var previousPriority = getCurrentUpdatePriority(); + var prevTransition = ReactCurrentBatchConfig$3.transition; + try { + ReactCurrentBatchConfig$3.transition = null; + setCurrentUpdatePriority(DiscreteEventPriority); + return fn(a, b, c, d); + } finally{ + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$3.transition = prevTransition; + if (executionContext === NoContext) resetRenderTimer(); + } + } // Overload the definition to the two valid signatures. + // Warning, this opts-out of checking the function body. + // eslint-disable-next-line no-redeclare + function flushSync(fn) { + // In legacy mode, we flush pending passive effects at the beginning of the + // next event, not at the end of the previous one. + if (rootWithPendingPassiveEffects !== null && rootWithPendingPassiveEffects.tag === LegacyRoot && (executionContext & (RenderContext | CommitContext)) === NoContext) flushPassiveEffects(); + var prevExecutionContext = executionContext; + executionContext |= BatchedContext; + var prevTransition = ReactCurrentBatchConfig$3.transition; + var previousPriority = getCurrentUpdatePriority(); + try { + ReactCurrentBatchConfig$3.transition = null; + setCurrentUpdatePriority(DiscreteEventPriority); + if (fn) return fn(); + else return undefined; + } finally{ + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$3.transition = prevTransition; + executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch. + // Note that this will happen even if batchedUpdates is higher up + // the stack. + if ((executionContext & (RenderContext | CommitContext)) === NoContext) flushSyncCallbacks(); + } + } + function isAlreadyRendering() { + // Used by the renderer to print a warning if certain APIs are called from + // the wrong context. + return (executionContext & (RenderContext | CommitContext)) !== NoContext; + } + function pushRenderLanes(fiber, lanes) { + push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber); + subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes); + workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes); + } + function popRenderLanes(fiber) { + subtreeRenderLanes = subtreeRenderLanesCursor.current; + pop(subtreeRenderLanesCursor, fiber); + } + function prepareFreshStack(root, lanes) { + root.finishedWork = null; + root.finishedLanes = NoLanes; + var timeoutHandle = root.timeoutHandle; + if (timeoutHandle !== noTimeout) { + // The root previous suspended and scheduled a timeout to commit a fallback + // state. Now that we have additional work, cancel the timeout. + root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above + cancelTimeout(timeoutHandle); + } + if (workInProgress !== null) { + var interruptedWork = workInProgress.return; + while(interruptedWork !== null){ + var current = interruptedWork.alternate; + unwindInterruptedWork(current, interruptedWork); + interruptedWork = interruptedWork.return; + } + } + workInProgressRoot = root; + var rootWorkInProgress = createWorkInProgress(root.current, null); + workInProgress = rootWorkInProgress; + workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; + workInProgressRootExitStatus = RootInProgress; + workInProgressRootFatalError = null; + workInProgressRootSkippedLanes = NoLanes; + workInProgressRootInterleavedUpdatedLanes = NoLanes; + workInProgressRootPingedLanes = NoLanes; + workInProgressRootConcurrentErrors = null; + workInProgressRootRecoverableErrors = null; + finishQueueingConcurrentUpdates(); + ReactStrictModeWarnings.discardPendingWarnings(); + return rootWorkInProgress; + } + function handleError(root, thrownValue) { + do { + var erroredWork = workInProgress; + try { + // Reset module-level state that was set during the render phase. + resetContextDependencies(); + resetHooksAfterThrow(); + resetCurrentFiber(); // TODO: I found and added this missing line while investigating a + // separate issue. Write a regression test using string refs. + ReactCurrentOwner$2.current = null; + if (erroredWork === null || erroredWork.return === null) { + // Expected to be working on a non-root fiber. This is a fatal error + // because there's no ancestor that can handle it; the root is + // supposed to capture all errors that weren't caught by an error + // boundary. + workInProgressRootExitStatus = RootFatalErrored; + workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next + // sibling, or the parent if there are no siblings. But since the root + // has no siblings nor a parent, we set it to null. Usually this is + // handled by `completeUnitOfWork` or `unwindWork`, but since we're + // intentionally not calling those, we need set it here. + // TODO: Consider calling `unwindWork` to pop the contexts. + workInProgress = null; + return; + } + if (enableProfilerTimer && erroredWork.mode & ProfileMode) // Record the time spent rendering before an error was thrown. This + // avoids inaccurate Profiler durations in the case of a + // suspended render. + stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true); + if (enableSchedulingProfiler) { + markComponentRenderStopped(); + if (thrownValue !== null && typeof thrownValue === "object" && typeof thrownValue.then === "function") { + var wakeable = thrownValue; + markComponentSuspended(erroredWork, wakeable, workInProgressRootRenderLanes); + } else markComponentErrored(erroredWork, thrownValue, workInProgressRootRenderLanes); + } + throwException(root, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes); + completeUnitOfWork(erroredWork); + } catch (yetAnotherThrownValue) { + // Something in the return path also threw. + thrownValue = yetAnotherThrownValue; + if (workInProgress === erroredWork && erroredWork !== null) { + // If this boundary has already errored, then we had trouble processing + // the error. Bubble it to the next boundary. + erroredWork = erroredWork.return; + workInProgress = erroredWork; + } else erroredWork = workInProgress; + continue; + } // Return to the normal work loop. + return; + }while (true); + } + function pushDispatcher() { + var prevDispatcher = ReactCurrentDispatcher$2.current; + ReactCurrentDispatcher$2.current = ContextOnlyDispatcher; + if (prevDispatcher === null) // The React isomorphic package does not include a default dispatcher. + // Instead the first renderer will lazily attach one, in order to give + // nicer error messages. + return ContextOnlyDispatcher; + else return prevDispatcher; + } + function popDispatcher(prevDispatcher) { + ReactCurrentDispatcher$2.current = prevDispatcher; + } + function markCommitTimeOfFallback() { + globalMostRecentFallbackTime = now(); + } + function markSkippedUpdateLanes(lane) { + workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes); + } + function renderDidSuspend() { + if (workInProgressRootExitStatus === RootInProgress) workInProgressRootExitStatus = RootSuspended; + } + function renderDidSuspendDelayIfPossible() { + if (workInProgressRootExitStatus === RootInProgress || workInProgressRootExitStatus === RootSuspended || workInProgressRootExitStatus === RootErrored) workInProgressRootExitStatus = RootSuspendedWithDelay; + // Check if there are updates that we skipped tree that might have unblocked + // this render. + if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes))) // Mark the current render as suspended so that we switch to working on + // the updates that were skipped. Usually we only suspend at the end of + // the render phase. + // TODO: We should probably always mark the root as suspended immediately + // (inside this function), since by suspending at the end of the render + // phase introduces a potential mistake where we suspend lanes that were + // pinged or updated while we were rendering. + markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes); + } + function renderDidError(error) { + if (workInProgressRootExitStatus !== RootSuspendedWithDelay) workInProgressRootExitStatus = RootErrored; + if (workInProgressRootConcurrentErrors === null) workInProgressRootConcurrentErrors = [ + error + ]; + else workInProgressRootConcurrentErrors.push(error); + } // Called during render to determine if anything has suspended. + // Returns false if we're not sure. + function renderHasNotSuspendedYet() { + // If something errored or completed, we can't really be sure, + // so those are false. + return workInProgressRootExitStatus === RootInProgress; + } + function renderRootSync(root, lanes) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. + if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { + if (isDevToolsPresent) { + var memoizedUpdaters = root.memoizedUpdaters; + if (memoizedUpdaters.size > 0) { + restorePendingUpdaters(root, workInProgressRootRenderLanes); + memoizedUpdaters.clear(); + } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set. + // If we bailout on this work, we'll move them back (like above). + // It's important to move them now in case the work spawns more work at the same priority with different updaters. + // That way we can keep the current update and future updates separate. + movePendingFibersToMemoized(root, lanes); + } + workInProgressTransitions = getTransitionsForLanes(); + prepareFreshStack(root, lanes); + } + markRenderStarted(lanes); + for(;;)try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); + if (workInProgress !== null) // This is a sync render, so we should have finished the whole tree. + throw new Error("Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue."); + markRenderStopped(); + workInProgressRoot = null; + workInProgressRootRenderLanes = NoLanes; + return workInProgressRootExitStatus; + } // The work loop is an extremely hot path. Tell Closure not to inline it. + /** @noinline */ function workLoopSync() { + // Already timed out, so perform work without checking if we need to yield. + while(workInProgress !== null)performUnitOfWork(workInProgress); + } + function renderRootConcurrent(root, lanes) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. + if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) { + if (isDevToolsPresent) { + var memoizedUpdaters = root.memoizedUpdaters; + if (memoizedUpdaters.size > 0) { + restorePendingUpdaters(root, workInProgressRootRenderLanes); + memoizedUpdaters.clear(); + } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set. + // If we bailout on this work, we'll move them back (like above). + // It's important to move them now in case the work spawns more work at the same priority with different updaters. + // That way we can keep the current update and future updates separate. + movePendingFibersToMemoized(root, lanes); + } + workInProgressTransitions = getTransitionsForLanes(); + resetRenderTimer(); + prepareFreshStack(root, lanes); + } + markRenderStarted(lanes); + for(;;)try { + workLoopConcurrent(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + resetContextDependencies(); + popDispatcher(prevDispatcher); + executionContext = prevExecutionContext; + if (workInProgress !== null) { + markRenderYielded(); + return RootInProgress; + } else { + markRenderStopped(); + workInProgressRoot = null; + workInProgressRootRenderLanes = NoLanes; // Return the final exit status. + return workInProgressRootExitStatus; + } + } + /** @noinline */ function workLoopConcurrent() { + // Perform work until Scheduler asks us to yield + while(workInProgress !== null && !shouldYield())performUnitOfWork(workInProgress); + } + function performUnitOfWork(unitOfWork) { + // The current, flushed, state of this fiber is the alternate. Ideally + // nothing should rely on this, but relying on it here means that we don't + // need an additional field on the work in progress. + var current = unitOfWork.alternate; + setCurrentFiber(unitOfWork); + var next; + if ((unitOfWork.mode & ProfileMode) !== NoMode) { + startProfilerTimer(unitOfWork); + next = beginWork$1(current, unitOfWork, subtreeRenderLanes); + stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); + } else next = beginWork$1(current, unitOfWork, subtreeRenderLanes); + resetCurrentFiber(); + unitOfWork.memoizedProps = unitOfWork.pendingProps; + if (next === null) // If this doesn't spawn new work, complete the current work. + completeUnitOfWork(unitOfWork); + else workInProgress = next; + ReactCurrentOwner$2.current = null; + } + function completeUnitOfWork(unitOfWork) { + // Attempt to complete the current unit of work, then move to the next + // sibling. If there are no more siblings, return to the parent fiber. + var completedWork = unitOfWork; + do { + // The current, flushed, state of this fiber is the alternate. Ideally + // nothing should rely on this, but relying on it here means that we don't + // need an additional field on the work in progress. + var current = completedWork.alternate; + var returnFiber = completedWork.return; // Check if the work completed or if something threw. + if ((completedWork.flags & Incomplete) === NoFlags) { + setCurrentFiber(completedWork); + var next = void 0; + if ((completedWork.mode & ProfileMode) === NoMode) next = completeWork(current, completedWork, subtreeRenderLanes); + else { + startProfilerTimer(completedWork); + next = completeWork(current, completedWork, subtreeRenderLanes); // Update render duration assuming we didn't error. + stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); + } + resetCurrentFiber(); + if (next !== null) { + // Completing this fiber spawned new work. Work on that next. + workInProgress = next; + return; + } + } else { + // This fiber did not complete because something threw. Pop values off + // the stack without entering the complete phase. If this is a boundary, + // capture values if possible. + var _next = unwindWork(current, completedWork); // Because this fiber did not complete, don't reset its lanes. + if (_next !== null) { + // If completing this work spawned new work, do that next. We'll come + // back here again. + // Since we're restarting, remove anything that is not a host effect + // from the effect tag. + _next.flags &= HostEffectMask; + workInProgress = _next; + return; + } + if ((completedWork.mode & ProfileMode) !== NoMode) { + // Record the render duration for the fiber that errored. + stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); // Include the time spent working on failed children before continuing. + var actualDuration = completedWork.actualDuration; + var child = completedWork.child; + while(child !== null){ + actualDuration += child.actualDuration; + child = child.sibling; + } + completedWork.actualDuration = actualDuration; + } + if (returnFiber !== null) { + // Mark the parent fiber as incomplete and clear its subtree flags. + returnFiber.flags |= Incomplete; + returnFiber.subtreeFlags = NoFlags; + returnFiber.deletions = null; + } else { + // We've unwound all the way to the root. + workInProgressRootExitStatus = RootDidNotComplete; + workInProgress = null; + return; + } + } + var siblingFiber = completedWork.sibling; + if (siblingFiber !== null) { + // If there is more work to do in this returnFiber, do that next. + workInProgress = siblingFiber; + return; + } // Otherwise, return to the parent + completedWork = returnFiber; // Update the next thing we're working on in case something throws. + workInProgress = completedWork; + }while (completedWork !== null); // We've reached the root. + if (workInProgressRootExitStatus === RootInProgress) workInProgressRootExitStatus = RootCompleted; + } + function commitRoot(root, recoverableErrors, transitions) { + // TODO: This no longer makes any sense. We already wrap the mutation and + // layout phases. Should be able to remove. + var previousUpdateLanePriority = getCurrentUpdatePriority(); + var prevTransition = ReactCurrentBatchConfig$3.transition; + try { + ReactCurrentBatchConfig$3.transition = null; + setCurrentUpdatePriority(DiscreteEventPriority); + commitRootImpl(root, recoverableErrors, transitions, previousUpdateLanePriority); + } finally{ + ReactCurrentBatchConfig$3.transition = prevTransition; + setCurrentUpdatePriority(previousUpdateLanePriority); + } + return null; + } + function commitRootImpl(root, recoverableErrors, transitions, renderPriorityLevel) { + do // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which + // means `flushPassiveEffects` will sometimes result in additional + // passive effects. So we need to keep flushing in a loop until there are + // no more pending effects. + // TODO: Might be better if `flushPassiveEffects` did not automatically + // flush synchronous work at the end, to avoid factoring hazards like this. + flushPassiveEffects(); + while (rootWithPendingPassiveEffects !== null); + flushRenderPhaseStrictModeWarningsInDEV(); + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw new Error("Should not already be working."); + var finishedWork = root.finishedWork; + var lanes = root.finishedLanes; + markCommitStarted(lanes); + if (finishedWork === null) { + markCommitStopped(); + return null; + } else if (lanes === NoLanes) error("root.finishedLanes should not be empty during a commit. This is a bug in React."); + root.finishedWork = null; + root.finishedLanes = NoLanes; + if (finishedWork === root.current) throw new Error("Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue."); + // commitRoot never returns a continuation; it always finishes synchronously. + // So we can clear these now to allow a new callback to be scheduled. + root.callbackNode = null; + root.callbackPriority = NoLane; // Update the first and last pending times on this root. The new first + // pending time is whatever is left on the root fiber. + var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes); + markRootFinished(root, remainingLanes); + if (root === workInProgressRoot) { + // We can reset these now that they are finished. + workInProgressRoot = null; + workInProgress = null; + workInProgressRootRenderLanes = NoLanes; + } // If there are pending passive effects, schedule a callback to process them. + // Do this as early as possible, so it is queued before anything else that + // might get scheduled in the commit phase. (See #16714.) + // TODO: Delete all other places that schedule the passive effect callback + // They're redundant. + if ((finishedWork.subtreeFlags & PassiveMask) !== NoFlags || (finishedWork.flags & PassiveMask) !== NoFlags) { + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + // to store it in pendingPassiveTransitions until they get processed + // We need to pass this through as an argument to commitRoot + // because workInProgressTransitions might have changed between + // the previous render and commit if we throttle the commit + // with setTimeout + pendingPassiveTransitions = transitions; + scheduleCallback$1(NormalPriority, function() { + flushPassiveEffects(); // This render triggered passive effects: release the root cache pool + // *after* passive effects fire to avoid freeing a cache pool that may + // be referenced by a node in the tree (HostRoot, Cache boundary etc) + return null; + }); + } + } // Check if there are any effects in the whole tree. + // TODO: This is left over from the effect list implementation, where we had + // to check for the existence of `firstEffect` to satisfy Flow. I think the + // only other reason this optimization exists is because it affects profiling. + // Reconsider whether this is necessary. + var subtreeHasEffects = (finishedWork.subtreeFlags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags; + var rootHasEffect = (finishedWork.flags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags; + if (subtreeHasEffects || rootHasEffect) { + var prevTransition = ReactCurrentBatchConfig$3.transition; + ReactCurrentBatchConfig$3.transition = null; + var previousPriority = getCurrentUpdatePriority(); + setCurrentUpdatePriority(DiscreteEventPriority); + var prevExecutionContext = executionContext; + executionContext |= CommitContext; // Reset this to null before calling lifecycles + ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass + // of the effect list for each phase: all mutation effects come before all + // layout effects, and so on. + // The first phase a "before mutation" phase. We use this phase to read the + // state of the host tree right before we mutate it. This is where + // getSnapshotBeforeUpdate is called. + var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects(root, finishedWork); + // Mark the current commit time to be shared by all Profilers in this + // batch. This enables them to be grouped later. + recordCommitTime(); + commitMutationEffects(root, finishedWork, lanes); + resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after + // the mutation phase, so that the previous tree is still current during + // componentWillUnmount, but before the layout phase, so that the finished + // work is current during componentDidMount/Update. + root.current = finishedWork; // The next phase is the layout phase, where we call effects that read + markLayoutEffectsStarted(lanes); + commitLayoutEffects(finishedWork, root, lanes); + markLayoutEffectsStopped(); + // opportunity to paint. + requestPaint(); + executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value. + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$3.transition = prevTransition; + } else { + // No effects. + root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were + recordCommitTime(); + } + var rootDidHavePassiveEffects = rootDoesHavePassiveEffects; + if (rootDoesHavePassiveEffects) { + // This commit has passive effects. Stash a reference to them. But don't + // schedule a callback until after flushing layout work. + rootDoesHavePassiveEffects = false; + rootWithPendingPassiveEffects = root; + pendingPassiveEffectsLanes = lanes; + } else { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; + } // Read this again, since an effect might have updated it + remainingLanes = root.pendingLanes; // Check if there's remaining work on this root + // TODO: This is part of the `componentDidCatch` implementation. Its purpose + // is to detect whether something might have called setState inside + // `componentDidCatch`. The mechanism is known to be flawed because `setState` + // inside `componentDidCatch` is itself flawed \u2014 that's why we recommend + // `getDerivedStateFromError` instead. However, it could be improved by + // checking if remainingLanes includes Sync work, instead of whether there's + // any work remaining at all (which would also include stuff like Suspense + // retries or transitions). It's been like this for a while, though, so fixing + // it probably isn't that urgent. + if (remainingLanes === NoLanes) // If there's no remaining work, we can clear the set of already failed + // error boundaries. + legacyErrorBoundariesThatAlreadyFailed = null; + if (!rootDidHavePassiveEffects) commitDoubleInvokeEffectsInDEV(root.current, false); + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + if (isDevToolsPresent) root.memoizedUpdaters.clear(); + onCommitRoot$1(); + // additional work on this root is scheduled. + ensureRootIsScheduled(root, now()); + if (recoverableErrors !== null) { + // There were errors during this render, but recovered from them without + // needing to surface it to the UI. We log them here. + var onRecoverableError = root.onRecoverableError; + for(var i = 0; i < recoverableErrors.length; i++){ + var recoverableError = recoverableErrors[i]; + var componentStack = recoverableError.stack; + var digest = recoverableError.digest; + onRecoverableError(recoverableError.value, { + componentStack: componentStack, + digest: digest + }); + } + } + if (hasUncaughtError) { + hasUncaughtError = false; + var error$1 = firstUncaughtError; + firstUncaughtError = null; + throw error$1; + } // If the passive effects are the result of a discrete render, flush them + // synchronously at the end of the current task so that the result is + // immediately observable. Otherwise, we assume that they are not + // order-dependent and do not need to be observed by external systems, so we + // can wait until after paint. + // TODO: We can optimize this by not scheduling the callback earlier. Since we + // currently schedule the callback in multiple places, will wait until those + // are consolidated. + if (includesSomeLane(pendingPassiveEffectsLanes, SyncLane) && root.tag !== LegacyRoot) flushPassiveEffects(); + // Read this again, since a passive effect might have updated it + remainingLanes = root.pendingLanes; + if (includesSomeLane(remainingLanes, SyncLane)) { + markNestedUpdateScheduled(); + // finishing. If there are too many, it indicates an infinite update loop. + if (root === rootWithNestedUpdates) nestedUpdateCount++; + else { + nestedUpdateCount = 0; + rootWithNestedUpdates = root; + } + } else nestedUpdateCount = 0; + // If layout work was scheduled, flush it now. + flushSyncCallbacks(); + markCommitStopped(); + return null; + } + function flushPassiveEffects() { + // Returns whether passive effects were flushed. + // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should + // probably just combine the two functions. I believe they were only separate + // in the first place because we used to wrap it with + // `Scheduler.runWithPriority`, which accepts a function. But now we track the + // priority within React itself, so we can mutate the variable directly. + if (rootWithPendingPassiveEffects !== null) { + var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes); + var priority = lowerEventPriority(DefaultEventPriority, renderPriority); + var prevTransition = ReactCurrentBatchConfig$3.transition; + var previousPriority = getCurrentUpdatePriority(); + try { + ReactCurrentBatchConfig$3.transition = null; + setCurrentUpdatePriority(priority); + return flushPassiveEffectsImpl(); + } finally{ + setCurrentUpdatePriority(previousPriority); + ReactCurrentBatchConfig$3.transition = prevTransition; // Once passive effects have run for the tree - giving components a + } + } + return false; + } + function enqueuePendingPassiveProfilerEffect(fiber) { + pendingPassiveProfilerEffects.push(fiber); + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback$1(NormalPriority, function() { + flushPassiveEffects(); + return null; + }); + } + } + function flushPassiveEffectsImpl() { + if (rootWithPendingPassiveEffects === null) return false; + // Cache and clear the transitions flag + var transitions = pendingPassiveTransitions; + pendingPassiveTransitions = null; + var root = rootWithPendingPassiveEffects; + var lanes = pendingPassiveEffectsLanes; + rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects. + // Figure out why and fix it. It's not causing any known issues (probably + // because it's only used for profiling), but it's a refactor hazard. + pendingPassiveEffectsLanes = NoLanes; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw new Error("Cannot flush passive effects while already rendering."); + isFlushingPassiveEffects = true; + didScheduleUpdateDuringPassiveEffects = false; + markPassiveEffectsStarted(lanes); + var prevExecutionContext = executionContext; + executionContext |= CommitContext; + commitPassiveUnmountEffects(root.current); + commitPassiveMountEffects(root, root.current, lanes, transitions); // TODO: Move to commitPassiveMountEffects + var profilerEffects = pendingPassiveProfilerEffects; + pendingPassiveProfilerEffects = []; + for(var i = 0; i < profilerEffects.length; i++){ + var _fiber = profilerEffects[i]; + commitPassiveEffectDurations(root, _fiber); + } + markPassiveEffectsStopped(); + commitDoubleInvokeEffectsInDEV(root.current, true); + executionContext = prevExecutionContext; + flushSyncCallbacks(); + // If additional passive effects were scheduled, increment a counter. If this + // exceeds the limit, we'll fire a warning. + if (didScheduleUpdateDuringPassiveEffects) { + if (root === rootWithPassiveNestedUpdates) nestedPassiveUpdateCount++; + else { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = root; + } + } else nestedPassiveUpdateCount = 0; + isFlushingPassiveEffects = false; + didScheduleUpdateDuringPassiveEffects = false; + onPostCommitRoot(root); + var stateNode = root.current.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + return true; + } + function isAlreadyFailedLegacyErrorBoundary(instance) { + return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance); + } + function markLegacyErrorBoundaryAsFailed(instance) { + if (legacyErrorBoundariesThatAlreadyFailed === null) legacyErrorBoundariesThatAlreadyFailed = new Set([ + instance + ]); + else legacyErrorBoundariesThatAlreadyFailed.add(instance); + } + function prepareToThrowUncaughtError(error) { + if (!hasUncaughtError) { + hasUncaughtError = true; + firstUncaughtError = error; + } + } + var onUncaughtError = prepareToThrowUncaughtError; + function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { + var errorInfo = createCapturedValueAtFiber(error, sourceFiber); + var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane); + var root = enqueueUpdate(rootFiber, update, SyncLane); + var eventTime = requestEventTime(); + if (root !== null) { + markRootUpdated(root, SyncLane, eventTime); + ensureRootIsScheduled(root, eventTime); + } + } + function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { + reportUncaughtErrorInDEV(error$1); + setIsRunningInsertionEffect(false); + if (sourceFiber.tag === HostRoot) { + // Error was thrown at the root. There is no parent, so the root + // itself should capture it. + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1); + return; + } + var fiber = null; + fiber = nearestMountedAncestor; + while(fiber !== null){ + if (fiber.tag === HostRoot) { + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1); + return; + } else if (fiber.tag === ClassComponent) { + var ctor = fiber.type; + var instance = fiber.stateNode; + if (typeof ctor.getDerivedStateFromError === "function" || typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) { + var errorInfo = createCapturedValueAtFiber(error$1, sourceFiber); + var update = createClassErrorUpdate(fiber, errorInfo, SyncLane); + var root = enqueueUpdate(fiber, update, SyncLane); + var eventTime = requestEventTime(); + if (root !== null) { + markRootUpdated(root, SyncLane, eventTime); + ensureRootIsScheduled(root, eventTime); + } + return; + } + } + fiber = fiber.return; + } + // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning + // will fire for errors that are thrown by destroy functions inside deleted + // trees. What it should instead do is propagate the error to the parent of + // the deleted tree. In the meantime, do not add this warning to the + // allowlist; this is only for our internal use. + error("Internal React error: Attempted to capture a commit phase error inside a detached tree. This indicates a bug in React. Likely causes include deleting the same fiber more than once, committing an already-finished tree, or an inconsistent return pointer.\n\nError message:\n\n%s", error$1); + } + function pingSuspendedRoot(root, wakeable, pingedLanes) { + var pingCache = root.pingCache; + if (pingCache !== null) // The wakeable resolved, so we no longer need to memoize, because it will + // never be thrown again. + pingCache.delete(wakeable); + var eventTime = requestEventTime(); + markRootPinged(root, pingedLanes); + warnIfSuspenseResolutionNotWrappedWithActDEV(root); + if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) { + // Received a ping at the same priority level at which we're currently + // rendering. We might want to restart this render. This should mirror + // the logic of whether or not a root suspends once it completes. + // TODO: If we're rendering sync either due to Sync, Batched or expired, + // we should probably never restart. + // If we're suspended with delay, or if it's a retry, we'll always suspend + // so we can always restart. + if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) // Restart from the root. + prepareFreshStack(root, NoLanes); + else // Even though we can't restart right now, we might get an + // opportunity later. So we mark this render as having a ping. + workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes); + } + ensureRootIsScheduled(root, eventTime); + } + function retryTimedOutBoundary(boundaryFiber, retryLane) { + // The boundary fiber (a Suspense component or SuspenseList component) + // previously was rendered in its fallback state. One of the promises that + // suspended it has resolved, which means at least part of the tree was + // likely unblocked. Try rendering again, at a new lanes. + if (retryLane === NoLane) // TODO: Assign this to `suspenseState.retryLane`? to avoid + // unnecessary entanglement? + retryLane = requestRetryLane(boundaryFiber); + // TODO: Special case idle priority? + var eventTime = requestEventTime(); + var root = enqueueConcurrentRenderForLane(boundaryFiber, retryLane); + if (root !== null) { + markRootUpdated(root, retryLane, eventTime); + ensureRootIsScheduled(root, eventTime); + } + } + function retryDehydratedSuspenseBoundary(boundaryFiber) { + var suspenseState = boundaryFiber.memoizedState; + var retryLane = NoLane; + if (suspenseState !== null) retryLane = suspenseState.retryLane; + retryTimedOutBoundary(boundaryFiber, retryLane); + } + function resolveRetryWakeable(boundaryFiber, wakeable) { + var retryLane = NoLane; // Default + var retryCache; + switch(boundaryFiber.tag){ + case SuspenseComponent: + retryCache = boundaryFiber.stateNode; + var suspenseState = boundaryFiber.memoizedState; + if (suspenseState !== null) retryLane = suspenseState.retryLane; + break; + case SuspenseListComponent: + retryCache = boundaryFiber.stateNode; + break; + default: + throw new Error("Pinged unknown suspense boundary type. This is probably a bug in React."); + } + if (retryCache !== null) // The wakeable resolved, so we no longer need to memoize, because it will + // never be thrown again. + retryCache.delete(wakeable); + retryTimedOutBoundary(boundaryFiber, retryLane); + } // Computes the next Just Noticeable Difference (JND) boundary. + // The theory is that a person can't tell the difference between small differences in time. + // Therefore, if we wait a bit longer than necessary that won't translate to a noticeable + // difference in the experience. However, waiting for longer might mean that we can avoid + // showing an intermediate loading state. The longer we have already waited, the harder it + // is to tell small differences in time. Therefore, the longer we've already waited, + // the longer we can wait additionally. At some point we have to give up though. + // We pick a train model where the next boundary commits at a consistent schedule. + // These particular numbers are vague estimates. We expect to adjust them based on research. + function jnd(timeElapsed) { + return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960; + } + function checkForNestedUpdates() { + if (nestedUpdateCount > NESTED_UPDATE_LIMIT) { + nestedUpdateCount = 0; + rootWithNestedUpdates = null; + throw new Error("Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops."); + } + if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { + nestedPassiveUpdateCount = 0; + rootWithPassiveNestedUpdates = null; + error("Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render."); + } + } + function flushRenderPhaseStrictModeWarningsInDEV() { + ReactStrictModeWarnings.flushLegacyContextWarning(); + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); + } + function commitDoubleInvokeEffectsInDEV(fiber, hasPassiveEffects) { + // TODO (StrictEffects) Should we set a marker on the root if it contains strict effects + // so we don't traverse unnecessarily? similar to subtreeFlags but just at the root level. + // Maybe not a big deal since this is DEV only behavior. + setCurrentFiber(fiber); + invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectUnmountInDEV); + if (hasPassiveEffects) invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectUnmountInDEV); + invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectMountInDEV); + if (hasPassiveEffects) invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectMountInDEV); + resetCurrentFiber(); + } + function invokeEffectsInDev(firstChild, fiberFlags, invokeEffectFn) { + // We don't need to re-check StrictEffectsMode here. + // This function is only called if that check has already passed. + var current = firstChild; + var subtreeRoot = null; + while(current !== null){ + var primarySubtreeFlag = current.subtreeFlags & fiberFlags; + if (current !== subtreeRoot && current.child !== null && primarySubtreeFlag !== NoFlags) current = current.child; + else { + if ((current.flags & fiberFlags) !== NoFlags) invokeEffectFn(current); + if (current.sibling !== null) current = current.sibling; + else current = subtreeRoot = current.return; + } + } + } + var didWarnStateUpdateForNotYetMountedComponent = null; + function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) { + if ((executionContext & RenderContext) !== NoContext) // We let the other warning about render phase updates deal with this one. + return; + if (!(fiber.mode & ConcurrentMode)) return; + var tag = fiber.tag; + if (tag !== IndeterminateComponent && tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) // Only warn for user-defined components, not internal ones like Suspense. + return; + // We show the whole stack but dedupe on the top component's name because + // the problematic code almost always lies inside that component. + var componentName = getComponentNameFromFiber(fiber) || "ReactComponent"; + if (didWarnStateUpdateForNotYetMountedComponent !== null) { + if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) return; + didWarnStateUpdateForNotYetMountedComponent.add(componentName); + } else didWarnStateUpdateForNotYetMountedComponent = new Set([ + componentName + ]); + var previousFiber = current; + try { + setCurrentFiber(fiber); + error("Can't perform a React state update on a component that hasn't mounted yet. This indicates that you have a side-effect in your render function that asynchronously later calls tries to update the component. Move this work to useEffect instead."); + } finally{ + if (previousFiber) setCurrentFiber(fiber); + else resetCurrentFiber(); + } + } + var beginWork$1; + var dummyFiber = null; + beginWork$1 = function(current, unitOfWork, lanes) { + // If a component throws an error, we replay it again in a synchronously + // dispatched event, so that the debugger will treat it as an uncaught + // error See ReactErrorUtils for more information. + // Before entering the begin phase, copy the work-in-progress onto a dummy + // fiber. If beginWork throws, we'll use this to reset the state. + var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork); + try { + return beginWork(current, unitOfWork, lanes); + } catch (originalError) { + if (didSuspendOrErrorWhileHydratingDEV() || originalError !== null && typeof originalError === "object" && typeof originalError.then === "function") // Don't replay promises. + // Don't replay errors if we are hydrating and have already suspended or handled an error + throw originalError; + // Keep this code in sync with handleError; any changes here must have + // corresponding changes there. + resetContextDependencies(); + resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the + // same fiber again. + // Unwind the failed stack frame + unwindInterruptedWork(current, unitOfWork); // Restore the original properties of the fiber. + assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy); + if (unitOfWork.mode & ProfileMode) // Reset the profiler timer. + startProfilerTimer(unitOfWork); + // Run beginWork again. + invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes); + if (hasCaughtError()) { + var replayError = clearCaughtError(); + if (typeof replayError === "object" && replayError !== null && replayError._suppressLogging && typeof originalError === "object" && originalError !== null && !originalError._suppressLogging) // If suppressed, let the flag carry over to the original error which is the one we'll rethrow. + originalError._suppressLogging = true; + } // We always throw the original error in case the second render pass is not idempotent. + // This can happen if a memoized function or CommonJS module doesn't throw after first invocation. + throw originalError; + } + }; + var didWarnAboutUpdateInRender = false; + var didWarnAboutUpdateInRenderForAnotherComponent; + didWarnAboutUpdateInRenderForAnotherComponent = new Set(); + function warnAboutRenderPhaseUpdatesInDEV(fiber) { + if (isRendering && !getIsUpdatingOpaqueValueInRenderPhaseInDEV()) switch(fiber.tag){ + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + var renderingComponentName = workInProgress && getComponentNameFromFiber(workInProgress) || "Unknown"; // Dedupe by the rendering component because it's the one that needs to be fixed. + var dedupeKey = renderingComponentName; + if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) { + didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey); + var setStateComponentName = getComponentNameFromFiber(fiber) || "Unknown"; + error("Cannot update a component (`%s`) while rendering a different component (`%s`). To locate the bad setState() call inside `%s`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render", setStateComponentName, renderingComponentName, renderingComponentName); + } + break; + case ClassComponent: + if (!didWarnAboutUpdateInRender) { + error("Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state."); + didWarnAboutUpdateInRender = true; + } + break; + } + } + function restorePendingUpdaters(root, lanes) { + if (isDevToolsPresent) { + var memoizedUpdaters = root.memoizedUpdaters; + memoizedUpdaters.forEach(function(schedulingFiber) { + addFiberToLanesMap(root, schedulingFiber, lanes); + }); // This function intentionally does not clear memoized updaters. + // Those may still be relevant to the current commit + // and a future one (e.g. Suspense). + } + } + var fakeActCallbackNode = {}; + function scheduleCallback$1(priorityLevel, callback) { + // If we're currently inside an `act` scope, bypass Scheduler and push to + // the `act` queue instead. + var actQueue = ReactCurrentActQueue$1.current; + if (actQueue !== null) { + actQueue.push(callback); + return fakeActCallbackNode; + } else return scheduleCallback(priorityLevel, callback); + } + function cancelCallback$1(callbackNode) { + if (callbackNode === fakeActCallbackNode) return; + // In production, always call Scheduler. This function will be stripped out. + return cancelCallback(callbackNode); + } + function shouldForceFlushFallbacksInDEV() { + // Never force flush in production. This function should get stripped out. + return ReactCurrentActQueue$1.current !== null; + } + function warnIfUpdatesNotWrappedWithActDEV(fiber) { + if (fiber.mode & ConcurrentMode) { + if (!isConcurrentActEnvironment()) // Not in an act environment. No need to warn. + return; + } else { + // Legacy mode has additional cases where we suppress a warning. + if (!isLegacyActEnvironment()) // Not in an act environment. No need to warn. + return; + if (executionContext !== NoContext) // Legacy mode doesn't warn if the update is batched, i.e. + // batchedUpdates or flushSync. + return; + if (fiber.tag !== FunctionComponent && fiber.tag !== ForwardRef && fiber.tag !== SimpleMemoComponent) // For backwards compatibility with pre-hooks code, legacy mode only + // warns for updates that originate from a hook. + return; + } + if (ReactCurrentActQueue$1.current === null) { + var previousFiber = current; + try { + setCurrentFiber(fiber); + error("An update to %s inside a test was not wrapped in act(...).\n\nWhen testing, code that causes React state updates should be wrapped into act(...):\n\nact(() => {\n /* fire events that update state */\n});\n/* assert on the output */\n\nThis ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act", getComponentNameFromFiber(fiber)); + } finally{ + if (previousFiber) setCurrentFiber(fiber); + else resetCurrentFiber(); + } + } + } + function warnIfSuspenseResolutionNotWrappedWithActDEV(root) { + if (root.tag !== LegacyRoot && isConcurrentActEnvironment() && ReactCurrentActQueue$1.current === null) error("A suspended resource finished loading inside a test, but the event was not wrapped in act(...).\n\nWhen testing, code that resolves suspended data should be wrapped into act(...):\n\nact(() => {\n /* finish loading suspended data */\n});\n/* assert on the output */\n\nThis ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act"); + } + function setIsRunningInsertionEffect(isRunning) { + isRunningInsertionEffect = isRunning; + } + /* eslint-disable react-internal/prod-error-codes */ var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below. + var failedBoundaries = null; + var setRefreshHandler = function(handler) { + resolveFamily = handler; + }; + function resolveFunctionForHotReloading(type) { + if (resolveFamily === null) // Hot reloading is disabled. + return type; + var family = resolveFamily(type); + if (family === undefined) return type; + // Use the latest known implementation. + return family.current; + } + function resolveClassForHotReloading(type) { + // No implementation differences. + return resolveFunctionForHotReloading(type); + } + function resolveForwardRefForHotReloading(type) { + if (resolveFamily === null) // Hot reloading is disabled. + return type; + var family = resolveFamily(type); + if (family === undefined) { + // Check if we're dealing with a real forwardRef. Don't want to crash early. + if (type !== null && type !== undefined && typeof type.render === "function") { + // ForwardRef is special because its resolved .type is an object, + // but it's possible that we only have its inner render function in the map. + // If that inner render function is different, we'll build a new forwardRef type. + var currentRender = resolveFunctionForHotReloading(type.render); + if (type.render !== currentRender) { + var syntheticType = { + $$typeof: REACT_FORWARD_REF_TYPE, + render: currentRender + }; + if (type.displayName !== undefined) syntheticType.displayName = type.displayName; + return syntheticType; + } + } + return type; + } // Use the latest known implementation. + return family.current; + } + function isCompatibleFamilyForHotReloading(fiber, element) { + if (resolveFamily === null) // Hot reloading is disabled. + return false; + var prevType = fiber.elementType; + var nextType = element.type; // If we got here, we know types aren't === equal. + var needsCompareFamilies = false; + var $$typeofNextType = typeof nextType === "object" && nextType !== null ? nextType.$$typeof : null; + switch(fiber.tag){ + case ClassComponent: + if (typeof nextType === "function") needsCompareFamilies = true; + break; + case FunctionComponent: + if (typeof nextType === "function") needsCompareFamilies = true; + else if ($$typeofNextType === REACT_LAZY_TYPE) // We don't know the inner type yet. + // We're going to assume that the lazy inner type is stable, + // and so it is sufficient to avoid reconciling it away. + // We're not going to unwrap or actually use the new lazy type. + needsCompareFamilies = true; + break; + case ForwardRef: + if ($$typeofNextType === REACT_FORWARD_REF_TYPE) needsCompareFamilies = true; + else if ($$typeofNextType === REACT_LAZY_TYPE) needsCompareFamilies = true; + break; + case MemoComponent: + case SimpleMemoComponent: + if ($$typeofNextType === REACT_MEMO_TYPE) // TODO: if it was but can no longer be simple, + // we shouldn't set this. + needsCompareFamilies = true; + else if ($$typeofNextType === REACT_LAZY_TYPE) needsCompareFamilies = true; + break; + default: + return false; + } // Check if both types have a family and it's the same one. + if (needsCompareFamilies) { + // Note: memo() and forwardRef() we'll compare outer rather than inner type. + // This means both of them need to be registered to preserve state. + // If we unwrapped and compared the inner types for wrappers instead, + // then we would risk falsely saying two separate memo(Foo) + // calls are equivalent because they wrap the same Foo function. + var prevFamily = resolveFamily(prevType); + if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) return true; + } + return false; + } + function markFailedErrorBoundaryForHotReloading(fiber) { + if (resolveFamily === null) // Hot reloading is disabled. + return; + if (typeof WeakSet !== "function") return; + if (failedBoundaries === null) failedBoundaries = new WeakSet(); + failedBoundaries.add(fiber); + } + var scheduleRefresh = function(root, update) { + if (resolveFamily === null) // Hot reloading is disabled. + return; + var staleFamilies = update.staleFamilies, updatedFamilies = update.updatedFamilies; + flushPassiveEffects(); + flushSync(function() { + scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies); + }); + }; + var scheduleRoot = function(root, element) { + if (root.context !== emptyContextObject) // Super edge case: root has a legacy _renderSubtree context + // but we don't know the parentComponent so we can't pass it. + // Just ignore. We'll delete this with _renderSubtree code path later. + return; + flushPassiveEffects(); + flushSync(function() { + updateContainer(element, root, null, null); + }); + }; + function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) { + var alternate = fiber.alternate, child = fiber.child, sibling = fiber.sibling, tag = fiber.tag, type = fiber.type; + var candidateType = null; + switch(tag){ + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + case ForwardRef: + candidateType = type.render; + break; + } + if (resolveFamily === null) throw new Error("Expected resolveFamily to be set during hot reload."); + var needsRender = false; + var needsRemount = false; + if (candidateType !== null) { + var family = resolveFamily(candidateType); + if (family !== undefined) { + if (staleFamilies.has(family)) needsRemount = true; + else if (updatedFamilies.has(family)) { + if (tag === ClassComponent) needsRemount = true; + else needsRender = true; + } + } + } + if (failedBoundaries !== null) { + if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) needsRemount = true; + } + if (needsRemount) fiber._debugNeedsRemount = true; + if (needsRemount || needsRender) { + var _root = enqueueConcurrentRenderForLane(fiber, SyncLane); + if (_root !== null) scheduleUpdateOnFiber(_root, fiber, SyncLane, NoTimestamp); + } + if (child !== null && !needsRemount) scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies); + if (sibling !== null) scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies); + } + var findHostInstancesForRefresh = function(root, families) { + var hostInstances = new Set(); + var types = new Set(families.map(function(family) { + return family.current; + })); + findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances); + return hostInstances; + }; + function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) { + var child = fiber.child, sibling = fiber.sibling, tag = fiber.tag, type = fiber.type; + var candidateType = null; + switch(tag){ + case FunctionComponent: + case SimpleMemoComponent: + case ClassComponent: + candidateType = type; + break; + case ForwardRef: + candidateType = type.render; + break; + } + var didMatch = false; + if (candidateType !== null) { + if (types.has(candidateType)) didMatch = true; + } + if (didMatch) // We have a match. This only drills down to the closest host components. + // There's no need to search deeper because for the purpose of giving + // visual feedback, "flashing" outermost parent rectangles is sufficient. + findHostInstancesForFiberShallowly(fiber, hostInstances); + else // If there's no match, maybe there will be one further down in the child tree. + if (child !== null) findHostInstancesForMatchingFibersRecursively(child, types, hostInstances); + if (sibling !== null) findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances); + } + function findHostInstancesForFiberShallowly(fiber, hostInstances) { + var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances); + if (foundHostInstances) return; + // If we didn't find any host children, fallback to closest host parent. + var node = fiber; + while(true){ + switch(node.tag){ + case HostComponent: + hostInstances.add(node.stateNode); + return; + case HostPortal: + hostInstances.add(node.stateNode.containerInfo); + return; + case HostRoot: + hostInstances.add(node.stateNode.containerInfo); + return; + } + if (node.return === null) throw new Error("Expected to reach root first."); + node = node.return; + } + } + function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { + var node = fiber; + var foundHostInstances = false; + while(true){ + if (node.tag === HostComponent) { + // We got a match. + foundHostInstances = true; + hostInstances.add(node.stateNode); // There may still be more, so keep searching. + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === fiber) return foundHostInstances; + while(node.sibling === null){ + if (node.return === null || node.return === fiber) return foundHostInstances; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + return false; + } + var hasBadMapPolyfill; + hasBadMapPolyfill = false; + try { + var nonExtensibleObject = Object.preventExtensions({}); + /* eslint-disable no-new */ new Map([ + [ + nonExtensibleObject, + null + ] + ]); + new Set([ + nonExtensibleObject + ]); + /* eslint-enable no-new */ } catch (e) { + // TODO: Consider warning about bad polyfills + hasBadMapPolyfill = true; + } + function FiberNode(tag, pendingProps, key, mode) { + // Instance + this.tag = tag; + this.key = key; + this.elementType = null; + this.type = null; + this.stateNode = null; // Fiber + this.return = null; + this.child = null; + this.sibling = null; + this.index = 0; + this.ref = null; + this.pendingProps = pendingProps; + this.memoizedProps = null; + this.updateQueue = null; + this.memoizedState = null; + this.dependencies = null; + this.mode = mode; // Effects + this.flags = NoFlags; + this.subtreeFlags = NoFlags; + this.deletions = null; + this.lanes = NoLanes; + this.childLanes = NoLanes; + this.alternate = null; + // Note: The following is done to avoid a v8 performance cliff. + // + // Initializing the fields below to smis and later updating them with + // double values will cause Fibers to end up having separate shapes. + // This behavior/bug has something to do with Object.preventExtension(). + // Fortunately this only impacts DEV builds. + // Unfortunately it makes React unusably slow for some applications. + // To work around this, initialize the fields below with doubles. + // + // Learn more about this here: + // https://github.com/facebook/react/issues/14365 + // https://bugs.chromium.org/p/v8/issues/detail?id=8538 + this.actualDuration = Number.NaN; + this.actualStartTime = Number.NaN; + this.selfBaseDuration = Number.NaN; + this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization. + // This won't trigger the performance cliff mentioned above, + // and it simplifies other profiler code (including DevTools). + this.actualDuration = 0; + this.actualStartTime = -1; + this.selfBaseDuration = 0; + this.treeBaseDuration = 0; + // This isn't directly used but is handy for debugging internals: + this._debugSource = null; + this._debugOwner = null; + this._debugNeedsRemount = false; + this._debugHookTypes = null; + if (!hasBadMapPolyfill && typeof Object.preventExtensions === "function") Object.preventExtensions(this); + } // This is a constructor function, rather than a POJO constructor, still + // please ensure we do the following: + // 1) Nobody should add any instance methods on this. Instance methods can be + // more difficult to predict when they get optimized and they are almost + // never inlined properly in static compilers. + // 2) Nobody should rely on `instanceof Fiber` for type testing. We should + // always know when it is a fiber. + // 3) We might want to experiment with using numeric keys since they are easier + // to optimize in a non-JIT environment. + // 4) We can easily go from a constructor to a createFiber object literal if that + // is faster. + // 5) It should be easy to port this to a C struct and keep a C implementation + // compatible. + var createFiber = function(tag, pendingProps, key, mode) { + // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors + return new FiberNode(tag, pendingProps, key, mode); + }; + function shouldConstruct$1(Component) { + var prototype = Component.prototype; + return !!(prototype && prototype.isReactComponent); + } + function isSimpleFunctionComponent(type) { + return typeof type === "function" && !shouldConstruct$1(type) && type.defaultProps === undefined; + } + function resolveLazyComponentTag(Component) { + if (typeof Component === "function") return shouldConstruct$1(Component) ? ClassComponent : FunctionComponent; + else if (Component !== undefined && Component !== null) { + var $$typeof = Component.$$typeof; + if ($$typeof === REACT_FORWARD_REF_TYPE) return ForwardRef; + if ($$typeof === REACT_MEMO_TYPE) return MemoComponent; + } + return IndeterminateComponent; + } // This is used to create an alternate fiber to do work on. + function createWorkInProgress(current, pendingProps) { + var workInProgress = current.alternate; + if (workInProgress === null) { + // We use a double buffering pooling technique because we know that we'll + // only ever need at most two versions of a tree. We pool the "other" unused + // node that we're free to reuse. This is lazily created to avoid allocating + // extra objects for things that are never updated. It also allow us to + // reclaim the extra memory if needed. + workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode); + workInProgress.elementType = current.elementType; + workInProgress.type = current.type; + workInProgress.stateNode = current.stateNode; + // DEV-only fields + workInProgress._debugSource = current._debugSource; + workInProgress._debugOwner = current._debugOwner; + workInProgress._debugHookTypes = current._debugHookTypes; + workInProgress.alternate = current; + current.alternate = workInProgress; + } else { + workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type. + workInProgress.type = current.type; // We already have an alternate. + // Reset the effect tag. + workInProgress.flags = NoFlags; // The effects are no longer valid. + workInProgress.subtreeFlags = NoFlags; + workInProgress.deletions = null; + // We intentionally reset, rather than copy, actualDuration & actualStartTime. + // This prevents time from endlessly accumulating in new commits. + // This has the downside of resetting values for different priority renders, + // But works for yielding (the common case) and should support resuming. + workInProgress.actualDuration = 0; + workInProgress.actualStartTime = -1; + } // Reset all effects except static ones. + // Static effects are not specific to a render. + workInProgress.flags = current.flags & StaticMask; + workInProgress.childLanes = current.childLanes; + workInProgress.lanes = current.lanes; + workInProgress.child = current.child; + workInProgress.memoizedProps = current.memoizedProps; + workInProgress.memoizedState = current.memoizedState; + workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + var currentDependencies = current.dependencies; + workInProgress.dependencies = currentDependencies === null ? null : { + lanes: currentDependencies.lanes, + firstContext: currentDependencies.firstContext + }; // These will be overridden during the parent's reconciliation + workInProgress.sibling = current.sibling; + workInProgress.index = current.index; + workInProgress.ref = current.ref; + workInProgress.selfBaseDuration = current.selfBaseDuration; + workInProgress.treeBaseDuration = current.treeBaseDuration; + workInProgress._debugNeedsRemount = current._debugNeedsRemount; + switch(workInProgress.tag){ + case IndeterminateComponent: + case FunctionComponent: + case SimpleMemoComponent: + workInProgress.type = resolveFunctionForHotReloading(current.type); + break; + case ClassComponent: + workInProgress.type = resolveClassForHotReloading(current.type); + break; + case ForwardRef: + workInProgress.type = resolveForwardRefForHotReloading(current.type); + break; + } + return workInProgress; + } // Used to reuse a Fiber for a second pass. + function resetWorkInProgress(workInProgress, renderLanes) { + // This resets the Fiber to what createFiber or createWorkInProgress would + // have set the values to before during the first pass. Ideally this wouldn't + // be necessary but unfortunately many code paths reads from the workInProgress + // when they should be reading from current and writing to workInProgress. + // We assume pendingProps, index, key, ref, return are still untouched to + // avoid doing another reconciliation. + // Reset the effect flags but keep any Placement tags, since that's something + // that child fiber is setting, not the reconciliation. + workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid. + var current = workInProgress.alternate; + if (current === null) { + // Reset to createFiber's initial values. + workInProgress.childLanes = NoLanes; + workInProgress.lanes = renderLanes; + workInProgress.child = null; + workInProgress.subtreeFlags = NoFlags; + workInProgress.memoizedProps = null; + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.dependencies = null; + workInProgress.stateNode = null; + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = 0; + workInProgress.treeBaseDuration = 0; + } else { + // Reset to the cloned values that createWorkInProgress would've. + workInProgress.childLanes = current.childLanes; + workInProgress.lanes = current.lanes; + workInProgress.child = current.child; + workInProgress.subtreeFlags = NoFlags; + workInProgress.deletions = null; + workInProgress.memoizedProps = current.memoizedProps; + workInProgress.memoizedState = current.memoizedState; + workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type. + workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so + // it cannot be shared with the current fiber. + var currentDependencies = current.dependencies; + workInProgress.dependencies = currentDependencies === null ? null : { + lanes: currentDependencies.lanes, + firstContext: currentDependencies.firstContext + }; + // Note: We don't reset the actualTime counts. It's useful to accumulate + // actual time across multiple render passes. + workInProgress.selfBaseDuration = current.selfBaseDuration; + workInProgress.treeBaseDuration = current.treeBaseDuration; + } + return workInProgress; + } + function createHostRootFiber(tag, isStrictMode, concurrentUpdatesByDefaultOverride) { + var mode; + if (tag === ConcurrentRoot) { + mode = ConcurrentMode; + if (isStrictMode === true) { + mode |= StrictLegacyMode; + mode |= StrictEffectsMode; + } + } else mode = NoMode; + if (isDevToolsPresent) // Always collect profile timings when DevTools are present. + // This enables DevTools to start capturing timing at any point\u2013 + // Without some nodes in the tree having empty base times. + mode |= ProfileMode; + return createFiber(HostRoot, null, null, mode); + } + function createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes) { + var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy. + var resolvedType = type; + if (typeof type === "function") { + if (shouldConstruct$1(type)) { + fiberTag = ClassComponent; + resolvedType = resolveClassForHotReloading(resolvedType); + } else resolvedType = resolveFunctionForHotReloading(resolvedType); + } else if (typeof type === "string") fiberTag = HostComponent; + else getTag: switch(type){ + case REACT_FRAGMENT_TYPE: + return createFiberFromFragment(pendingProps.children, mode, lanes, key); + case REACT_STRICT_MODE_TYPE: + fiberTag = Mode; + mode |= StrictLegacyMode; + if ((mode & ConcurrentMode) !== NoMode) // Strict effects should never run on legacy roots + mode |= StrictEffectsMode; + break; + case REACT_PROFILER_TYPE: + return createFiberFromProfiler(pendingProps, mode, lanes, key); + case REACT_SUSPENSE_TYPE: + return createFiberFromSuspense(pendingProps, mode, lanes, key); + case REACT_SUSPENSE_LIST_TYPE: + return createFiberFromSuspenseList(pendingProps, mode, lanes, key); + case REACT_OFFSCREEN_TYPE: + return createFiberFromOffscreen(pendingProps, mode, lanes, key); + case REACT_LEGACY_HIDDEN_TYPE: + // eslint-disable-next-line no-fallthrough + case REACT_SCOPE_TYPE: + // eslint-disable-next-line no-fallthrough + case REACT_CACHE_TYPE: + // eslint-disable-next-line no-fallthrough + case REACT_TRACING_MARKER_TYPE: + // eslint-disable-next-line no-fallthrough + case REACT_DEBUG_TRACING_MODE_TYPE: + // eslint-disable-next-line no-fallthrough + default: + if (typeof type === "object" && type !== null) switch(type.$$typeof){ + case REACT_PROVIDER_TYPE: + fiberTag = ContextProvider; + break getTag; + case REACT_CONTEXT_TYPE: + // This is a consumer + fiberTag = ContextConsumer; + break getTag; + case REACT_FORWARD_REF_TYPE: + fiberTag = ForwardRef; + resolvedType = resolveForwardRefForHotReloading(resolvedType); + break getTag; + case REACT_MEMO_TYPE: + fiberTag = MemoComponent; + break getTag; + case REACT_LAZY_TYPE: + fiberTag = LazyComponent; + resolvedType = null; + break getTag; + } + var info = ""; + if (type === undefined || typeof type === "object" && type !== null && Object.keys(type).length === 0) info += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."; + var ownerName = owner ? getComponentNameFromFiber(owner) : null; + if (ownerName) info += "\n\nCheck the render method of `" + ownerName + "`."; + throw new Error("Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) " + ("but got: " + (type == null ? type : typeof type) + "." + info)); + } + var fiber = createFiber(fiberTag, pendingProps, key, mode); + fiber.elementType = type; + fiber.type = resolvedType; + fiber.lanes = lanes; + fiber._debugOwner = owner; + return fiber; + } + function createFiberFromElement(element, mode, lanes) { + var owner = null; + owner = element._owner; + var type = element.type; + var key = element.key; + var pendingProps = element.props; + var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes); + fiber._debugSource = element._source; + fiber._debugOwner = element._owner; + return fiber; + } + function createFiberFromFragment(elements, mode, lanes, key) { + var fiber = createFiber(Fragment, elements, key, mode); + fiber.lanes = lanes; + return fiber; + } + function createFiberFromProfiler(pendingProps, mode, lanes, key) { + if (typeof pendingProps.id !== "string") error('Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', typeof pendingProps.id); + var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); + fiber.elementType = REACT_PROFILER_TYPE; + fiber.lanes = lanes; + fiber.stateNode = { + effectDuration: 0, + passiveEffectDuration: 0 + }; + return fiber; + } + function createFiberFromSuspense(pendingProps, mode, lanes, key) { + var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); + fiber.elementType = REACT_SUSPENSE_TYPE; + fiber.lanes = lanes; + return fiber; + } + function createFiberFromSuspenseList(pendingProps, mode, lanes, key) { + var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode); + fiber.elementType = REACT_SUSPENSE_LIST_TYPE; + fiber.lanes = lanes; + return fiber; + } + function createFiberFromOffscreen(pendingProps, mode, lanes, key) { + var fiber = createFiber(OffscreenComponent, pendingProps, key, mode); + fiber.elementType = REACT_OFFSCREEN_TYPE; + fiber.lanes = lanes; + var primaryChildInstance = { + isHidden: false + }; + fiber.stateNode = primaryChildInstance; + return fiber; + } + function createFiberFromText(content, mode, lanes) { + var fiber = createFiber(HostText, content, null, mode); + fiber.lanes = lanes; + return fiber; + } + function createFiberFromHostInstanceForDeletion() { + var fiber = createFiber(HostComponent, null, null, NoMode); + fiber.elementType = "DELETED"; + return fiber; + } + function createFiberFromDehydratedFragment(dehydratedNode) { + var fiber = createFiber(DehydratedFragment, null, null, NoMode); + fiber.stateNode = dehydratedNode; + return fiber; + } + function createFiberFromPortal(portal, mode, lanes) { + var pendingProps = portal.children !== null ? portal.children : []; + var fiber = createFiber(HostPortal, pendingProps, portal.key, mode); + fiber.lanes = lanes; + fiber.stateNode = { + containerInfo: portal.containerInfo, + pendingChildren: null, + // Used by persistent updates + implementation: portal.implementation + }; + return fiber; + } // Used for stashing WIP properties to replay failed work in DEV. + function assignFiberPropertiesInDEV(target, source) { + if (target === null) // This Fiber's initial properties will always be overwritten. + // We only use a Fiber to ensure the same hidden class so DEV isn't slow. + target = createFiber(IndeterminateComponent, null, null, NoMode); + // This is intentionally written as a list of all properties. + // We tried to use Object.assign() instead but this is called in + // the hottest path, and Object.assign() was too slow: + // https://github.com/facebook/react/issues/12502 + // This code is DEV-only so size is not a concern. + target.tag = source.tag; + target.key = source.key; + target.elementType = source.elementType; + target.type = source.type; + target.stateNode = source.stateNode; + target.return = source.return; + target.child = source.child; + target.sibling = source.sibling; + target.index = source.index; + target.ref = source.ref; + target.pendingProps = source.pendingProps; + target.memoizedProps = source.memoizedProps; + target.updateQueue = source.updateQueue; + target.memoizedState = source.memoizedState; + target.dependencies = source.dependencies; + target.mode = source.mode; + target.flags = source.flags; + target.subtreeFlags = source.subtreeFlags; + target.deletions = source.deletions; + target.lanes = source.lanes; + target.childLanes = source.childLanes; + target.alternate = source.alternate; + target.actualDuration = source.actualDuration; + target.actualStartTime = source.actualStartTime; + target.selfBaseDuration = source.selfBaseDuration; + target.treeBaseDuration = source.treeBaseDuration; + target._debugSource = source._debugSource; + target._debugOwner = source._debugOwner; + target._debugNeedsRemount = source._debugNeedsRemount; + target._debugHookTypes = source._debugHookTypes; + return target; + } + function FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError) { + this.tag = tag; + this.containerInfo = containerInfo; + this.pendingChildren = null; + this.current = null; + this.pingCache = null; + this.finishedWork = null; + this.timeoutHandle = noTimeout; + this.context = null; + this.pendingContext = null; + this.callbackNode = null; + this.callbackPriority = NoLane; + this.eventTimes = createLaneMap(NoLanes); + this.expirationTimes = createLaneMap(NoTimestamp); + this.pendingLanes = NoLanes; + this.suspendedLanes = NoLanes; + this.pingedLanes = NoLanes; + this.expiredLanes = NoLanes; + this.mutableReadLanes = NoLanes; + this.finishedLanes = NoLanes; + this.entangledLanes = NoLanes; + this.entanglements = createLaneMap(NoLanes); + this.identifierPrefix = identifierPrefix; + this.onRecoverableError = onRecoverableError; + this.mutableSourceEagerHydrationData = null; + this.effectDuration = 0; + this.passiveEffectDuration = 0; + this.memoizedUpdaters = new Set(); + var pendingUpdatersLaneMap = this.pendingUpdatersLaneMap = []; + for(var _i = 0; _i < TotalLanes; _i++)pendingUpdatersLaneMap.push(new Set()); + switch(tag){ + case ConcurrentRoot: + this._debugRootType = hydrate ? "hydrateRoot()" : "createRoot()"; + break; + case LegacyRoot: + this._debugRootType = hydrate ? "hydrate()" : "render()"; + break; + } + } + function createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, // host config, but because they are passed in at runtime, we have to thread + // them through the root constructor. Perhaps we should put them all into a + // single type, like a DynamicHostConfig that is defined by the renderer. + identifierPrefix, onRecoverableError, transitionCallbacks) { + var root = new FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError); + // stateNode is any. + var uninitializedFiber = createHostRootFiber(tag, isStrictMode); + root.current = uninitializedFiber; + uninitializedFiber.stateNode = root; + var _initialState = { + element: initialChildren, + isDehydrated: hydrate, + cache: null, + // not enabled yet + transitions: null, + pendingSuspenseBoundaries: null + }; + uninitializedFiber.memoizedState = _initialState; + initializeUpdateQueue(uninitializedFiber); + return root; + } + var ReactVersion = "18.2.0"; + function createPortal(children, containerInfo, implementation) { + var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; + checkKeyStringCoercion(key); + return { + // This tag allow us to uniquely identify this as a React Portal + $$typeof: REACT_PORTAL_TYPE, + key: key == null ? null : "" + key, + children: children, + containerInfo: containerInfo, + implementation: implementation + }; + } + var didWarnAboutNestedUpdates; + var didWarnAboutFindNodeInStrictMode; + didWarnAboutNestedUpdates = false; + didWarnAboutFindNodeInStrictMode = {}; + function getContextForSubtree(parentComponent) { + if (!parentComponent) return emptyContextObject; + var fiber = get(parentComponent); + var parentContext = findCurrentUnmaskedContext(fiber); + if (fiber.tag === ClassComponent) { + var Component = fiber.type; + if (isContextProvider(Component)) return processChildContext(fiber, Component, parentContext); + } + return parentContext; + } + function findHostInstanceWithWarning(component, methodName) { + var fiber = get(component); + if (fiber === undefined) { + if (typeof component.render === "function") throw new Error("Unable to find node on an unmounted component."); + else { + var keys = Object.keys(component).join(","); + throw new Error("Argument appears to not be a ReactComponent. Keys: " + keys); + } + } + var hostFiber = findCurrentHostFiber(fiber); + if (hostFiber === null) return null; + if (hostFiber.mode & StrictLegacyMode) { + var componentName = getComponentNameFromFiber(fiber) || "Component"; + if (!didWarnAboutFindNodeInStrictMode[componentName]) { + didWarnAboutFindNodeInStrictMode[componentName] = true; + var previousFiber = current; + try { + setCurrentFiber(hostFiber); + if (fiber.mode & StrictLegacyMode) error("%s is deprecated in StrictMode. %s was passed an instance of %s which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-find-node", methodName, methodName, componentName); + else error("%s is deprecated in StrictMode. %s was passed an instance of %s which renders StrictMode children. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-find-node", methodName, methodName, componentName); + } finally{ + // Ideally this should reset to previous but this shouldn't be called in + // render and there's another warning for that anyway. + if (previousFiber) setCurrentFiber(previousFiber); + else resetCurrentFiber(); + } + } + } + return hostFiber.stateNode; + } + function createContainer(containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) { + var hydrate = false; + var initialChildren = null; + return createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError); + } + function createHydrationContainer(initialChildren, callback, containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) { + var hydrate = true; + var root = createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError); // TODO: Move this to FiberRoot constructor + root.context = getContextForSubtree(null); // Schedule the initial render. In a hydration root, this is different from + // a regular update because the initial render must match was was rendered + // on the server. + // NOTE: This update intentionally doesn't have a payload. We're only using + // the update to schedule work on the root fiber (and, for legacy roots, to + // enqueue the callback if one is provided). + var current = root.current; + var eventTime = requestEventTime(); + var lane = requestUpdateLane(current); + var update = createUpdate(eventTime, lane); + update.callback = callback !== undefined && callback !== null ? callback : null; + enqueueUpdate(current, update, lane); + scheduleInitialHydrationOnRoot(root, lane, eventTime); + return root; + } + function updateContainer(element, container, parentComponent, callback) { + onScheduleRoot(container, element); + var current$1 = container.current; + var eventTime = requestEventTime(); + var lane = requestUpdateLane(current$1); + markRenderScheduled(lane); + var context = getContextForSubtree(parentComponent); + if (container.context === null) container.context = context; + else container.pendingContext = context; + if (isRendering && current !== null && !didWarnAboutNestedUpdates) { + didWarnAboutNestedUpdates = true; + error("Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate.\n\nCheck the render method of %s.", getComponentNameFromFiber(current) || "Unknown"); + } + var update = createUpdate(eventTime, lane); // Caution: React DevTools currently depends on this property + // being called "element". + update.payload = { + element: element + }; + callback = callback === undefined ? null : callback; + if (callback !== null) { + if (typeof callback !== "function") error("render(...): Expected the last optional `callback` argument to be a function. Instead received: %s.", callback); + update.callback = callback; + } + var root = enqueueUpdate(current$1, update, lane); + if (root !== null) { + scheduleUpdateOnFiber(root, current$1, lane, eventTime); + entangleTransitions(root, current$1, lane); + } + return lane; + } + function getPublicRootInstance(container) { + var containerFiber = container.current; + if (!containerFiber.child) return null; + switch(containerFiber.child.tag){ + case HostComponent: + return getPublicInstance(containerFiber.child.stateNode); + default: + return containerFiber.child.stateNode; + } + } + function attemptSynchronousHydration$1(fiber) { + switch(fiber.tag){ + case HostRoot: + var root = fiber.stateNode; + if (isRootDehydrated(root)) { + // Flush the first scheduled "update". + var lanes = getHighestPriorityPendingLanes(root); + flushRoot(root, lanes); + } + break; + case SuspenseComponent: + flushSync(function() { + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + if (root !== null) { + var eventTime = requestEventTime(); + scheduleUpdateOnFiber(root, fiber, SyncLane, eventTime); + } + }); // If we're still blocked after this, we need to increase + // the priority of any promises resolving within this + // boundary so that they next attempt also has higher pri. + var retryLane = SyncLane; + markRetryLaneIfNotHydrated(fiber, retryLane); + break; + } + } + function markRetryLaneImpl(fiber, retryLane) { + var suspenseState = fiber.memoizedState; + if (suspenseState !== null && suspenseState.dehydrated !== null) suspenseState.retryLane = higherPriorityLane(suspenseState.retryLane, retryLane); + } // Increases the priority of thenables when they resolve within this boundary. + function markRetryLaneIfNotHydrated(fiber, retryLane) { + markRetryLaneImpl(fiber, retryLane); + var alternate = fiber.alternate; + if (alternate) markRetryLaneImpl(alternate, retryLane); + } + function attemptContinuousHydration$1(fiber) { + if (fiber.tag !== SuspenseComponent) // We ignore HostRoots here because we can't increase + // their priority and they should not suspend on I/O, + // since you have to wrap anything that might suspend in + // Suspense. + return; + var lane = SelectiveHydrationLane; + var root = enqueueConcurrentRenderForLane(fiber, lane); + if (root !== null) { + var eventTime = requestEventTime(); + scheduleUpdateOnFiber(root, fiber, lane, eventTime); + } + markRetryLaneIfNotHydrated(fiber, lane); + } + function attemptHydrationAtCurrentPriority$1(fiber) { + if (fiber.tag !== SuspenseComponent) // We ignore HostRoots here because we can't increase + // their priority other than synchronously flush it. + return; + var lane = requestUpdateLane(fiber); + var root = enqueueConcurrentRenderForLane(fiber, lane); + if (root !== null) { + var eventTime = requestEventTime(); + scheduleUpdateOnFiber(root, fiber, lane, eventTime); + } + markRetryLaneIfNotHydrated(fiber, lane); + } + function findHostInstanceWithNoPortals(fiber) { + var hostFiber = findCurrentHostFiberWithNoPortals(fiber); + if (hostFiber === null) return null; + return hostFiber.stateNode; + } + var shouldErrorImpl = function(fiber) { + return null; + }; + function shouldError(fiber) { + return shouldErrorImpl(fiber); + } + var shouldSuspendImpl = function(fiber) { + return false; + }; + function shouldSuspend(fiber) { + return shouldSuspendImpl(fiber); + } + var overrideHookState = null; + var overrideHookStateDeletePath = null; + var overrideHookStateRenamePath = null; + var overrideProps = null; + var overridePropsDeletePath = null; + var overridePropsRenamePath = null; + var scheduleUpdate = null; + var setErrorHandler = null; + var setSuspenseHandler = null; + var copyWithDeleteImpl = function(obj, path, index) { + var key = path[index]; + var updated = isArray(obj) ? obj.slice() : assign({}, obj); + if (index + 1 === path.length) { + if (isArray(updated)) updated.splice(key, 1); + else delete updated[key]; + return updated; + } // $FlowFixMe number or string is fine here + updated[key] = copyWithDeleteImpl(obj[key], path, index + 1); + return updated; + }; + var copyWithDelete = function(obj, path) { + return copyWithDeleteImpl(obj, path, 0); + }; + var copyWithRenameImpl = function(obj, oldPath, newPath, index) { + var oldKey = oldPath[index]; + var updated = isArray(obj) ? obj.slice() : assign({}, obj); + if (index + 1 === oldPath.length) { + var newKey = newPath[index]; // $FlowFixMe number or string is fine here + updated[newKey] = updated[oldKey]; + if (isArray(updated)) updated.splice(oldKey, 1); + else delete updated[oldKey]; + } else // $FlowFixMe number or string is fine here + updated[oldKey] = copyWithRenameImpl(obj[oldKey], oldPath, newPath, index + 1); + return updated; + }; + var copyWithRename = function(obj, oldPath, newPath) { + if (oldPath.length !== newPath.length) { + warn("copyWithRename() expects paths of the same length"); + return; + } else { + for(var i = 0; i < newPath.length - 1; i++)if (oldPath[i] !== newPath[i]) { + warn("copyWithRename() expects paths to be the same except for the deepest key"); + return; + } + } + return copyWithRenameImpl(obj, oldPath, newPath, 0); + }; + var copyWithSetImpl = function(obj, path, index, value) { + if (index >= path.length) return value; + var key = path[index]; + var updated = isArray(obj) ? obj.slice() : assign({}, obj); // $FlowFixMe number or string is fine here + updated[key] = copyWithSetImpl(obj[key], path, index + 1, value); + return updated; + }; + var copyWithSet = function(obj, path, value) { + return copyWithSetImpl(obj, path, 0, value); + }; + var findHook = function(fiber, id) { + // For now, the "id" of stateful hooks is just the stateful hook index. + // This may change in the future with e.g. nested hooks. + var currentHook = fiber.memoizedState; + while(currentHook !== null && id > 0){ + currentHook = currentHook.next; + id--; + } + return currentHook; + }; // Support DevTools editable values for useState and useReducer. + overrideHookState = function(fiber, id, path, value) { + var hook = findHook(fiber, id); + if (hook !== null) { + var newState = copyWithSet(hook.memoizedState, path, value); + hook.memoizedState = newState; + hook.baseState = newState; // We aren't actually adding an update to the queue, + // because there is no update we can add for useReducer hooks that won't trigger an error. + // (There's no appropriate action type for DevTools overrides.) + // As a result though, React will see the scheduled update as a noop and bailout. + // Shallow cloning props works as a workaround for now to bypass the bailout check. + fiber.memoizedProps = assign({}, fiber.memoizedProps); + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); + } + }; + overrideHookStateDeletePath = function(fiber, id, path) { + var hook = findHook(fiber, id); + if (hook !== null) { + var newState = copyWithDelete(hook.memoizedState, path); + hook.memoizedState = newState; + hook.baseState = newState; // We aren't actually adding an update to the queue, + // because there is no update we can add for useReducer hooks that won't trigger an error. + // (There's no appropriate action type for DevTools overrides.) + // As a result though, React will see the scheduled update as a noop and bailout. + // Shallow cloning props works as a workaround for now to bypass the bailout check. + fiber.memoizedProps = assign({}, fiber.memoizedProps); + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); + } + }; + overrideHookStateRenamePath = function(fiber, id, oldPath, newPath) { + var hook = findHook(fiber, id); + if (hook !== null) { + var newState = copyWithRename(hook.memoizedState, oldPath, newPath); + hook.memoizedState = newState; + hook.baseState = newState; // We aren't actually adding an update to the queue, + // because there is no update we can add for useReducer hooks that won't trigger an error. + // (There's no appropriate action type for DevTools overrides.) + // As a result though, React will see the scheduled update as a noop and bailout. + // Shallow cloning props works as a workaround for now to bypass the bailout check. + fiber.memoizedProps = assign({}, fiber.memoizedProps); + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); + } + }; // Support DevTools props for function components, forwardRef, memo, host components, etc. + overrideProps = function(fiber, path, value) { + fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); + if (fiber.alternate) fiber.alternate.pendingProps = fiber.pendingProps; + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); + }; + overridePropsDeletePath = function(fiber, path) { + fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path); + if (fiber.alternate) fiber.alternate.pendingProps = fiber.pendingProps; + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); + }; + overridePropsRenamePath = function(fiber, oldPath, newPath) { + fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath); + if (fiber.alternate) fiber.alternate.pendingProps = fiber.pendingProps; + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); + }; + scheduleUpdate = function(fiber) { + var root = enqueueConcurrentRenderForLane(fiber, SyncLane); + if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp); + }; + setErrorHandler = function(newShouldErrorImpl) { + shouldErrorImpl = newShouldErrorImpl; + }; + setSuspenseHandler = function(newShouldSuspendImpl) { + shouldSuspendImpl = newShouldSuspendImpl; + }; + function findHostInstanceByFiber(fiber) { + var hostFiber = findCurrentHostFiber(fiber); + if (hostFiber === null) return null; + return hostFiber.stateNode; + } + function emptyFindFiberByHostInstance(instance) { + return null; + } + function getCurrentFiberForDevTools() { + return current; + } + function injectIntoDevTools(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; + return injectInternals({ + bundleType: devToolsConfig.bundleType, + version: devToolsConfig.version, + rendererPackageName: devToolsConfig.rendererPackageName, + rendererConfig: devToolsConfig.rendererConfig, + overrideHookState: overrideHookState, + overrideHookStateDeletePath: overrideHookStateDeletePath, + overrideHookStateRenamePath: overrideHookStateRenamePath, + overrideProps: overrideProps, + overridePropsDeletePath: overridePropsDeletePath, + overridePropsRenamePath: overridePropsRenamePath, + setErrorHandler: setErrorHandler, + setSuspenseHandler: setSuspenseHandler, + scheduleUpdate: scheduleUpdate, + currentDispatcherRef: ReactCurrentDispatcher, + findHostInstanceByFiber: findHostInstanceByFiber, + findFiberByHostInstance: findFiberByHostInstance || emptyFindFiberByHostInstance, + // React Refresh + findHostInstancesForRefresh: findHostInstancesForRefresh, + scheduleRefresh: scheduleRefresh, + scheduleRoot: scheduleRoot, + setRefreshHandler: setRefreshHandler, + // Enables DevTools to append owner stacks to error messages in DEV mode. + getCurrentFiber: getCurrentFiberForDevTools, + // Enables DevTools to detect reconciler version rather than renderer version + // which may not match for third party renderers. + reconcilerVersion: ReactVersion + }); + } + /* global reportError */ var defaultOnRecoverableError = typeof reportError === "function" ? // emulating an uncaught JavaScript error. + reportError : function(error) { + // In older browsers and test environments, fallback to console.error. + // eslint-disable-next-line react-internal/no-production-logging + console["error"](error); + }; + function ReactDOMRoot(internalRoot) { + this._internalRoot = internalRoot; + } + ReactDOMHydrationRoot.prototype.render = ReactDOMRoot.prototype.render = function(children) { + var root = this._internalRoot; + if (root === null) throw new Error("Cannot update an unmounted root."); + if (typeof arguments[1] === "function") error("render(...): does not support the second callback argument. To execute a side effect after rendering, declare it in a component body with useEffect()."); + else if (isValidContainer(arguments[1])) error("You passed a container to the second argument of root.render(...). You don't need to pass it again since you already passed it to create the root."); + else if (typeof arguments[1] !== "undefined") error("You passed a second argument to root.render(...) but it only accepts one argument."); + var container = root.containerInfo; + if (container.nodeType !== COMMENT_NODE) { + var hostInstance = findHostInstanceWithNoPortals(root.current); + if (hostInstance) { + if (hostInstance.parentNode !== container) error("render(...): It looks like the React-rendered content of the root container was removed without using React. This is not supported and will cause errors. Instead, call root.unmount() to empty a root's container."); + } + } + updateContainer(children, root, null, null); + }; + ReactDOMHydrationRoot.prototype.unmount = ReactDOMRoot.prototype.unmount = function() { + if (typeof arguments[0] === "function") error("unmount(...): does not support a callback argument. To execute a side effect after rendering, declare it in a component body with useEffect()."); + var root = this._internalRoot; + if (root !== null) { + this._internalRoot = null; + var container = root.containerInfo; + if (isAlreadyRendering()) error("Attempted to synchronously unmount a root while React was already rendering. React cannot finish unmounting the root until the current render has completed, which may lead to a race condition."); + flushSync(function() { + updateContainer(null, root, null, null); + }); + unmarkContainerAsRoot(container); + } + }; + function createRoot(container, options) { + if (!isValidContainer(container)) throw new Error("createRoot(...): Target container is not a DOM element."); + warnIfReactDOMContainerInDEV(container); + var isStrictMode = false; + var concurrentUpdatesByDefaultOverride = false; + var identifierPrefix = ""; + var onRecoverableError = defaultOnRecoverableError; + var transitionCallbacks = null; + if (options !== null && options !== undefined) { + if (options.hydrate) warn("hydrate through createRoot is deprecated. Use ReactDOMClient.hydrateRoot(container, ) instead."); + else if (typeof options === "object" && options !== null && options.$$typeof === REACT_ELEMENT_TYPE) error("You passed a JSX element to createRoot. You probably meant to call root.render instead. Example usage:\n\n let root = createRoot(domContainer);\n root.render();"); + if (options.unstable_strictMode === true) isStrictMode = true; + if (options.identifierPrefix !== undefined) identifierPrefix = options.identifierPrefix; + if (options.onRecoverableError !== undefined) onRecoverableError = options.onRecoverableError; + if (options.transitionCallbacks !== undefined) transitionCallbacks = options.transitionCallbacks; + } + var root = createContainer(container, ConcurrentRoot, null, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError); + markContainerAsRoot(root.current, container); + var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container; + listenToAllSupportedEvents(rootContainerElement); + return new ReactDOMRoot(root); + } + function ReactDOMHydrationRoot(internalRoot) { + this._internalRoot = internalRoot; + } + function scheduleHydration(target) { + if (target) queueExplicitHydrationTarget(target); + } + ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = scheduleHydration; + function hydrateRoot(container, initialChildren, options) { + if (!isValidContainer(container)) throw new Error("hydrateRoot(...): Target container is not a DOM element."); + warnIfReactDOMContainerInDEV(container); + if (initialChildren === undefined) error("Must provide initial children as second argument to hydrateRoot. Example usage: hydrateRoot(domContainer, )"); + // the hydration callbacks. + var hydrationCallbacks = options != null ? options : null; // TODO: Delete this option + var mutableSources = options != null && options.hydratedSources || null; + var isStrictMode = false; + var concurrentUpdatesByDefaultOverride = false; + var identifierPrefix = ""; + var onRecoverableError = defaultOnRecoverableError; + if (options !== null && options !== undefined) { + if (options.unstable_strictMode === true) isStrictMode = true; + if (options.identifierPrefix !== undefined) identifierPrefix = options.identifierPrefix; + if (options.onRecoverableError !== undefined) onRecoverableError = options.onRecoverableError; + } + var root = createHydrationContainer(initialChildren, null, container, ConcurrentRoot, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError); + markContainerAsRoot(root.current, container); // This can't be a comment node since hydration doesn't work on comment nodes anyway. + listenToAllSupportedEvents(container); + if (mutableSources) for(var i = 0; i < mutableSources.length; i++){ + var mutableSource = mutableSources[i]; + registerMutableSourceForHydration(root, mutableSource); + } + return new ReactDOMHydrationRoot(root); + } + function isValidContainer(node) { + return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || !disableCommentsAsDOMContainers)); + } // TODO: Remove this function which also includes comment nodes. + // We only use it in places that are currently more relaxed. + function isValidContainerLegacy(node) { + return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || node.nodeType === COMMENT_NODE && node.nodeValue === " react-mount-point-unstable ")); + } + function warnIfReactDOMContainerInDEV(container) { + if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === "BODY") error("createRoot(): Creating roots directly with document.body is discouraged, since its children are often manipulated by third-party scripts and browser extensions. This may lead to subtle reconciliation issues. Try using a container element created for your app."); + if (isContainerMarkedAsRoot(container)) { + if (container._reactRootContainer) error("You are calling ReactDOMClient.createRoot() on a container that was previously passed to ReactDOM.render(). This is not supported."); + else error("You are calling ReactDOMClient.createRoot() on a container that has already been passed to createRoot() before. Instead, call root.render() on the existing root instead if you want to update it."); + } + } + var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; + var topLevelUpdateWarnings; + topLevelUpdateWarnings = function(container) { + if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) { + var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer.current); + if (hostInstance) { + if (hostInstance.parentNode !== container) error("render(...): It looks like the React-rendered content of this container was removed without using React. This is not supported and will cause errors. Instead, call ReactDOM.unmountComponentAtNode to empty a container."); + } + } + var isRootRenderedBySomeReact = !!container._reactRootContainer; + var rootEl = getReactRootElementInContainer(container); + var hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl)); + if (hasNonRootReactChild && !isRootRenderedBySomeReact) error("render(...): Replacing React-rendered children with a new root component. If you intended to update the children of this node, you should instead have the existing children update their state and render the new components instead of calling ReactDOM.render."); + if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === "BODY") error("render(): Rendering components directly into document.body is discouraged, since its children are often manipulated by third-party scripts and browser extensions. This may lead to subtle reconciliation issues. Try rendering into a container element created for your app."); + }; + function getReactRootElementInContainer(container) { + if (!container) return null; + if (container.nodeType === DOCUMENT_NODE) return container.documentElement; + else return container.firstChild; + } + function noopOnRecoverableError() { + // legacy API. + } + function legacyCreateRootFromDOMContainer(container, initialChildren, parentComponent, callback, isHydrationContainer) { + if (isHydrationContainer) { + if (typeof callback === "function") { + var originalCallback = callback; + callback = function() { + var instance = getPublicRootInstance(root); + originalCallback.call(instance); + }; + } + var root = createHydrationContainer(initialChildren, callback, container, LegacyRoot, null, false, false, "", noopOnRecoverableError); + container._reactRootContainer = root; + markContainerAsRoot(root.current, container); + var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container; + listenToAllSupportedEvents(rootContainerElement); + flushSync(); + return root; + } else { + // First clear any existing content. + var rootSibling; + while(rootSibling = container.lastChild)container.removeChild(rootSibling); + if (typeof callback === "function") { + var _originalCallback = callback; + callback = function() { + var instance = getPublicRootInstance(_root); + _originalCallback.call(instance); + }; + } + var _root = createContainer(container, LegacyRoot, null, false, false, "", noopOnRecoverableError); + container._reactRootContainer = _root; + markContainerAsRoot(_root.current, container); + var _rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container; + listenToAllSupportedEvents(_rootContainerElement); // Initial mount should not be batched. + flushSync(function() { + updateContainer(initialChildren, _root, parentComponent, callback); + }); + return _root; + } + } + function warnOnInvalidCallback$1(callback, callerName) { + if (callback !== null && typeof callback !== "function") error("%s(...): Expected the last optional `callback` argument to be a function. Instead received: %s.", callerName, callback); + } + function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) { + topLevelUpdateWarnings(container); + warnOnInvalidCallback$1(callback === undefined ? null : callback, "render"); + var maybeRoot = container._reactRootContainer; + var root; + if (!maybeRoot) // Initial mount + root = legacyCreateRootFromDOMContainer(container, children, parentComponent, callback, forceHydrate); + else { + root = maybeRoot; + if (typeof callback === "function") { + var originalCallback = callback; + callback = function() { + var instance = getPublicRootInstance(root); + originalCallback.call(instance); + }; + } // Update + updateContainer(children, root, parentComponent, callback); + } + return getPublicRootInstance(root); + } + function findDOMNode(componentOrElement) { + var owner = ReactCurrentOwner$3.current; + if (owner !== null && owner.stateNode !== null) { + var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender; + if (!warnedAboutRefsInRender) error("%s is accessing findDOMNode inside its render(). render() should be a pure function of props and state. It should never access something that requires stale data from the previous render, such as refs. Move this logic to componentDidMount and componentDidUpdate instead.", getComponentNameFromType(owner.type) || "A component"); + owner.stateNode._warnedAboutRefsInRender = true; + } + if (componentOrElement == null) return null; + if (componentOrElement.nodeType === ELEMENT_NODE) return componentOrElement; + return findHostInstanceWithWarning(componentOrElement, "findDOMNode"); + } + function hydrate(element, container, callback) { + error("ReactDOM.hydrate is no longer supported in React 18. Use hydrateRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot"); + if (!isValidContainerLegacy(container)) throw new Error("Target container is not a DOM element."); + var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined; + if (isModernRoot) error("You are calling ReactDOM.hydrate() on a container that was previously passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call hydrateRoot(container, element)?"); + return legacyRenderSubtreeIntoContainer(null, element, container, true, callback); + } + function render(element, container, callback) { + error("ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot"); + if (!isValidContainerLegacy(container)) throw new Error("Target container is not a DOM element."); + var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined; + if (isModernRoot) error("You are calling ReactDOM.render() on a container that was previously passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.render(element)?"); + return legacyRenderSubtreeIntoContainer(null, element, container, false, callback); + } + function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) { + error("ReactDOM.unstable_renderSubtreeIntoContainer() is no longer supported in React 18. Consider using a portal instead. Until you switch to the createRoot API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot"); + if (!isValidContainerLegacy(containerNode)) throw new Error("Target container is not a DOM element."); + if (parentComponent == null || !has(parentComponent)) throw new Error("parentComponent must be a valid React Component"); + return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback); + } + function unmountComponentAtNode(container) { + if (!isValidContainerLegacy(container)) throw new Error("unmountComponentAtNode(...): Target container is not a DOM element."); + var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined; + if (isModernRoot) error("You are calling ReactDOM.unmountComponentAtNode() on a container that was previously passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.unmount()?"); + if (container._reactRootContainer) { + var rootEl = getReactRootElementInContainer(container); + var renderedByDifferentReact = rootEl && !getInstanceFromNode(rootEl); + if (renderedByDifferentReact) error("unmountComponentAtNode(): The node you're attempting to unmount was rendered by another copy of React."); + flushSync(function() { + legacyRenderSubtreeIntoContainer(null, null, container, false, function() { + // $FlowFixMe This should probably use `delete container._reactRootContainer` + container._reactRootContainer = null; + unmarkContainerAsRoot(container); + }); + }); // If you call unmountComponentAtNode twice in quick succession, you'll + // get `true` twice. That's probably fine? + return true; + } else { + var _rootEl = getReactRootElementInContainer(container); + var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode(_rootEl)); // Check if the container itself is a React root node. + var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainerLegacy(container.parentNode) && !!container.parentNode._reactRootContainer; + if (hasNonRootReactChild) error("unmountComponentAtNode(): The node you're attempting to unmount was rendered by React and is not a top-level container. %s", isContainerReactRoot ? "You may have accidentally passed in a React root node instead of its container." : "Instead, have the parent component update its state and rerender in order to remove this component."); + return false; + } + } + setAttemptSynchronousHydration(attemptSynchronousHydration$1); + setAttemptContinuousHydration(attemptContinuousHydration$1); + setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1); + setGetCurrentUpdatePriority(getCurrentUpdatePriority); + setAttemptHydrationAtPriority(runWithPriority); + if (typeof Map !== "function" || // $FlowIssue Flow incorrectly thinks Map has no prototype + Map.prototype == null || typeof Map.prototype.forEach !== "function" || typeof Set !== "function" || // $FlowIssue Flow incorrectly thinks Set has no prototype + Set.prototype == null || typeof Set.prototype.clear !== "function" || typeof Set.prototype.forEach !== "function") error("React depends on Map and Set built-in types. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills"); + setRestoreImplementation(restoreControlledState$3); + setBatchingImplementation(batchedUpdates$1, discreteUpdates, flushSync); + function createPortal$1(children, container) { + var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + if (!isValidContainer(container)) throw new Error("Target container is not a DOM element."); + // TODO: pass ReactDOM portal implementation as third argument + // $FlowFixMe The Flow type is opaque but there's no way to actually create it. + return createPortal(children, container, null, key); + } + function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) { + return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback); + } + var Internals = { + usingClientEntryPoint: false, + // Keep in sync with ReactTestUtils.js. + // This is an array for better minification. + Events: [ + getInstanceFromNode, + getNodeFromInstance, + getFiberCurrentPropsFromNode, + enqueueStateRestore, + restoreStateIfNeeded, + batchedUpdates$1 + ] + }; + function createRoot$1(container, options) { + if (!Internals.usingClientEntryPoint && true) error('You are importing createRoot from "react-dom" which is not supported. You should instead import it from "react-dom/client".'); + return createRoot(container, options); + } + function hydrateRoot$1(container, initialChildren, options) { + if (!Internals.usingClientEntryPoint && true) error('You are importing hydrateRoot from "react-dom" which is not supported. You should instead import it from "react-dom/client".'); + return hydrateRoot(container, initialChildren, options); + } // Overload the definition to the two valid signatures. + // Warning, this opts-out of checking the function body. + // eslint-disable-next-line no-redeclare + function flushSync$1(fn) { + if (isAlreadyRendering()) error("flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task."); + return flushSync(fn); + } + var foundDevTools = injectIntoDevTools({ + findFiberByHostInstance: getClosestInstanceFromNode, + bundleType: 1, + version: ReactVersion, + rendererPackageName: "react-dom" + }); + if (!foundDevTools && canUseDOM && window.top === window.self) // If we're in Chrome or Firefox, provide a download link if not installed. + { + if (navigator.userAgent.indexOf("Chrome") > -1 && navigator.userAgent.indexOf("Edge") === -1 || navigator.userAgent.indexOf("Firefox") > -1) { + var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://. + if (/^(https?|file):$/.test(protocol)) // eslint-disable-next-line react-internal/no-production-logging + console.info("%cDownload the React DevTools for a better development experience: https://reactjs.org/link/react-devtools" + (protocol === "file:" ? "\nYou might need to use a local HTTP server (instead of file://): https://reactjs.org/link/react-devtools-faq" : ""), "font-weight:bold"); + } + } + exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals; + exports.createPortal = createPortal$1; + exports.createRoot = createRoot$1; + exports.findDOMNode = findDOMNode; + exports.flushSync = flushSync$1; + exports.hydrate = hydrate; + exports.hydrateRoot = hydrateRoot$1; + exports.render = render; + exports.unmountComponentAtNode = unmountComponentAtNode; + exports.unstable_batchedUpdates = batchedUpdates$1; + exports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer; + exports.version = ReactVersion; + /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function") __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error()); +})(); + +},{"6f0162e9ab224cd4":"ifaUc","8ad4ca65319d28a7":"1SbWp"}],"1SbWp":[function(require,module,exports) { +"use strict"; +module.exports = require("ef03b89c8fe2794e"); + +},{"ef03b89c8fe2794e":"lSn8J"}],"lSn8J":[function(require,module,exports) { +/** + * @license React + * scheduler.development.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ "use strict"; +(function() { + "use strict"; + /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function") __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); + var enableSchedulerDebugging = false; + var enableProfiling = false; + var frameYieldMs = 5; + function push(heap, node) { + var index = heap.length; + heap.push(node); + siftUp(heap, node, index); + } + function peek(heap) { + return heap.length === 0 ? null : heap[0]; + } + function pop(heap) { + if (heap.length === 0) return null; + var first = heap[0]; + var last = heap.pop(); + if (last !== first) { + heap[0] = last; + siftDown(heap, last, 0); + } + return first; + } + function siftUp(heap, node, i) { + var index = i; + while(index > 0){ + var parentIndex = index - 1 >>> 1; + var parent = heap[parentIndex]; + if (compare(parent, node) > 0) { + // The parent is larger. Swap positions. + heap[parentIndex] = node; + heap[index] = parent; + index = parentIndex; + } else // The parent is smaller. Exit. + return; + } + } + function siftDown(heap, node, i) { + var index = i; + var length = heap.length; + var halfLength = length >>> 1; + while(index < halfLength){ + var leftIndex = (index + 1) * 2 - 1; + var left = heap[leftIndex]; + var rightIndex = leftIndex + 1; + var right = heap[rightIndex]; // If the left or right node is smaller, swap with the smaller of those. + if (compare(left, node) < 0) { + if (rightIndex < length && compare(right, left) < 0) { + heap[index] = right; + heap[rightIndex] = node; + index = rightIndex; + } else { + heap[index] = left; + heap[leftIndex] = node; + index = leftIndex; + } + } else if (rightIndex < length && compare(right, node) < 0) { + heap[index] = right; + heap[rightIndex] = node; + index = rightIndex; + } else // Neither child is smaller. Exit. + return; + } + } + function compare(a, b) { + // Compare sort index first, then task id. + var diff = a.sortIndex - b.sortIndex; + return diff !== 0 ? diff : a.id - b.id; + } + // TODO: Use symbols? + var ImmediatePriority = 1; + var UserBlockingPriority = 2; + var NormalPriority = 3; + var LowPriority = 4; + var IdlePriority = 5; + function markTaskErrored(task, ms) {} + /* eslint-disable no-var */ var hasPerformanceNow = typeof performance === "object" && typeof performance.now === "function"; + if (hasPerformanceNow) { + var localPerformance = performance; + exports.unstable_now = function() { + return localPerformance.now(); + }; + } else { + var localDate = Date; + var initialTime = localDate.now(); + exports.unstable_now = function() { + return localDate.now() - initialTime; + }; + } // Max 31 bit integer. The max integer size in V8 for 32-bit systems. + // Math.pow(2, 30) - 1 + // 0b111111111111111111111111111111 + var maxSigned31BitInt = 1073741823; // Times out immediately + var IMMEDIATE_PRIORITY_TIMEOUT = -1; // Eventually times out + var USER_BLOCKING_PRIORITY_TIMEOUT = 250; + var NORMAL_PRIORITY_TIMEOUT = 5000; + var LOW_PRIORITY_TIMEOUT = 10000; // Never times out + var IDLE_PRIORITY_TIMEOUT = maxSigned31BitInt; // Tasks are stored on a min heap + var taskQueue = []; + var timerQueue = []; // Incrementing id counter. Used to maintain insertion order. + var taskIdCounter = 1; // Pausing the scheduler is useful for debugging. + var currentTask = null; + var currentPriorityLevel = NormalPriority; // This is set while performing work, to prevent re-entrance. + var isPerformingWork = false; + var isHostCallbackScheduled = false; + var isHostTimeoutScheduled = false; // Capture local references to native APIs, in case a polyfill overrides them. + var localSetTimeout = typeof setTimeout === "function" ? setTimeout : null; + var localClearTimeout = typeof clearTimeout === "function" ? clearTimeout : null; + var localSetImmediate = typeof setImmediate !== "undefined" ? setImmediate : null; // IE and Node.js + jsdom + var isInputPending = typeof navigator !== "undefined" && navigator.scheduling !== undefined && navigator.scheduling.isInputPending !== undefined ? navigator.scheduling.isInputPending.bind(navigator.scheduling) : null; + function advanceTimers(currentTime) { + // Check for tasks that are no longer delayed and add them to the queue. + var timer = peek(timerQueue); + while(timer !== null){ + if (timer.callback === null) // Timer was cancelled. + pop(timerQueue); + else if (timer.startTime <= currentTime) { + // Timer fired. Transfer to the task queue. + pop(timerQueue); + timer.sortIndex = timer.expirationTime; + push(taskQueue, timer); + } else // Remaining timers are pending. + return; + timer = peek(timerQueue); + } + } + function handleTimeout(currentTime) { + isHostTimeoutScheduled = false; + advanceTimers(currentTime); + if (!isHostCallbackScheduled) { + if (peek(taskQueue) !== null) { + isHostCallbackScheduled = true; + requestHostCallback(flushWork); + } else { + var firstTimer = peek(timerQueue); + if (firstTimer !== null) requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime); + } + } + } + function flushWork(hasTimeRemaining, initialTime) { + isHostCallbackScheduled = false; + if (isHostTimeoutScheduled) { + // We scheduled a timeout but it's no longer needed. Cancel it. + isHostTimeoutScheduled = false; + cancelHostTimeout(); + } + isPerformingWork = true; + var previousPriorityLevel = currentPriorityLevel; + try { + if (enableProfiling) try { + return workLoop(hasTimeRemaining, initialTime); + } catch (error) { + if (currentTask !== null) { + var currentTime = exports.unstable_now(); + markTaskErrored(currentTask, currentTime); + currentTask.isQueued = false; + } + throw error; + } + else // No catch in prod code path. + return workLoop(hasTimeRemaining, initialTime); + } finally{ + currentTask = null; + currentPriorityLevel = previousPriorityLevel; + isPerformingWork = false; + } + } + function workLoop(hasTimeRemaining, initialTime) { + var currentTime = initialTime; + advanceTimers(currentTime); + currentTask = peek(taskQueue); + while(currentTask !== null && !enableSchedulerDebugging){ + if (currentTask.expirationTime > currentTime && (!hasTimeRemaining || shouldYieldToHost())) break; + var callback = currentTask.callback; + if (typeof callback === "function") { + currentTask.callback = null; + currentPriorityLevel = currentTask.priorityLevel; + var didUserCallbackTimeout = currentTask.expirationTime <= currentTime; + var continuationCallback = callback(didUserCallbackTimeout); + currentTime = exports.unstable_now(); + if (typeof continuationCallback === "function") currentTask.callback = continuationCallback; + else if (currentTask === peek(taskQueue)) pop(taskQueue); + advanceTimers(currentTime); + } else pop(taskQueue); + currentTask = peek(taskQueue); + } // Return whether there's additional work + if (currentTask !== null) return true; + else { + var firstTimer = peek(timerQueue); + if (firstTimer !== null) requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime); + return false; + } + } + function unstable_runWithPriority(priorityLevel, eventHandler) { + switch(priorityLevel){ + case ImmediatePriority: + case UserBlockingPriority: + case NormalPriority: + case LowPriority: + case IdlePriority: + break; + default: + priorityLevel = NormalPriority; + } + var previousPriorityLevel = currentPriorityLevel; + currentPriorityLevel = priorityLevel; + try { + return eventHandler(); + } finally{ + currentPriorityLevel = previousPriorityLevel; + } + } + function unstable_next(eventHandler) { + var priorityLevel; + switch(currentPriorityLevel){ + case ImmediatePriority: + case UserBlockingPriority: + case NormalPriority: + // Shift down to normal priority + priorityLevel = NormalPriority; + break; + default: + // Anything lower than normal priority should remain at the current level. + priorityLevel = currentPriorityLevel; + break; + } + var previousPriorityLevel = currentPriorityLevel; + currentPriorityLevel = priorityLevel; + try { + return eventHandler(); + } finally{ + currentPriorityLevel = previousPriorityLevel; + } + } + function unstable_wrapCallback(callback) { + var parentPriorityLevel = currentPriorityLevel; + return function() { + // This is a fork of runWithPriority, inlined for performance. + var previousPriorityLevel = currentPriorityLevel; + currentPriorityLevel = parentPriorityLevel; + try { + return callback.apply(this, arguments); + } finally{ + currentPriorityLevel = previousPriorityLevel; + } + }; + } + function unstable_scheduleCallback(priorityLevel, callback, options) { + var currentTime = exports.unstable_now(); + var startTime; + if (typeof options === "object" && options !== null) { + var delay = options.delay; + if (typeof delay === "number" && delay > 0) startTime = currentTime + delay; + else startTime = currentTime; + } else startTime = currentTime; + var timeout; + switch(priorityLevel){ + case ImmediatePriority: + timeout = IMMEDIATE_PRIORITY_TIMEOUT; + break; + case UserBlockingPriority: + timeout = USER_BLOCKING_PRIORITY_TIMEOUT; + break; + case IdlePriority: + timeout = IDLE_PRIORITY_TIMEOUT; + break; + case LowPriority: + timeout = LOW_PRIORITY_TIMEOUT; + break; + case NormalPriority: + default: + timeout = NORMAL_PRIORITY_TIMEOUT; + break; + } + var expirationTime = startTime + timeout; + var newTask = { + id: taskIdCounter++, + callback: callback, + priorityLevel: priorityLevel, + startTime: startTime, + expirationTime: expirationTime, + sortIndex: -1 + }; + if (startTime > currentTime) { + // This is a delayed task. + newTask.sortIndex = startTime; + push(timerQueue, newTask); + if (peek(taskQueue) === null && newTask === peek(timerQueue)) { + // All tasks are delayed, and this is the task with the earliest delay. + if (isHostTimeoutScheduled) // Cancel an existing timeout. + cancelHostTimeout(); + else isHostTimeoutScheduled = true; + // Schedule a timeout. + requestHostTimeout(handleTimeout, startTime - currentTime); + } + } else { + newTask.sortIndex = expirationTime; + push(taskQueue, newTask); + // wait until the next time we yield. + if (!isHostCallbackScheduled && !isPerformingWork) { + isHostCallbackScheduled = true; + requestHostCallback(flushWork); + } + } + return newTask; + } + function unstable_pauseExecution() {} + function unstable_continueExecution() { + if (!isHostCallbackScheduled && !isPerformingWork) { + isHostCallbackScheduled = true; + requestHostCallback(flushWork); + } + } + function unstable_getFirstCallbackNode() { + return peek(taskQueue); + } + function unstable_cancelCallback(task) { + // remove from the queue because you can't remove arbitrary nodes from an + // array based heap, only the first one.) + task.callback = null; + } + function unstable_getCurrentPriorityLevel() { + return currentPriorityLevel; + } + var isMessageLoopRunning = false; + var scheduledHostCallback = null; + var taskTimeoutID = -1; // Scheduler periodically yields in case there is other work on the main + // thread, like user events. By default, it yields multiple times per frame. + // It does not attempt to align with frame boundaries, since most tasks don't + // need to be frame aligned; for those that do, use requestAnimationFrame. + var frameInterval = frameYieldMs; + var startTime = -1; + function shouldYieldToHost() { + var timeElapsed = exports.unstable_now() - startTime; + if (timeElapsed < frameInterval) // The main thread has only been blocked for a really short amount of time; + // smaller than a single frame. Don't yield yet. + return false; + // The main thread has been blocked for a non-negligible amount of time. We + return true; + } + function requestPaint() {} + function forceFrameRate(fps) { + if (fps < 0 || fps > 125) { + // Using console['error'] to evade Babel and ESLint + console["error"]("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"); + return; + } + if (fps > 0) frameInterval = Math.floor(1000 / fps); + else // reset the framerate + frameInterval = frameYieldMs; + } + var performWorkUntilDeadline = function() { + if (scheduledHostCallback !== null) { + var currentTime = exports.unstable_now(); // Keep track of the start time so we can measure how long the main thread + // has been blocked. + startTime = currentTime; + var hasTimeRemaining = true; // If a scheduler task throws, exit the current browser task so the + // error can be observed. + // + // Intentionally not using a try-catch, since that makes some debugging + // techniques harder. Instead, if `scheduledHostCallback` errors, then + // `hasMoreWork` will remain true, and we'll continue the work loop. + var hasMoreWork = true; + try { + hasMoreWork = scheduledHostCallback(hasTimeRemaining, currentTime); + } finally{ + if (hasMoreWork) // If there's more work, schedule the next message event at the end + // of the preceding one. + schedulePerformWorkUntilDeadline(); + else { + isMessageLoopRunning = false; + scheduledHostCallback = null; + } + } + } else isMessageLoopRunning = false; + // Yielding to the browser will give it a chance to paint, so we can + }; + var schedulePerformWorkUntilDeadline; + if (typeof localSetImmediate === "function") // Node.js and old IE. + // There's a few reasons for why we prefer setImmediate. + // + // Unlike MessageChannel, it doesn't prevent a Node.js process from exiting. + // (Even though this is a DOM fork of the Scheduler, you could get here + // with a mix of Node.js 15+, which has a MessageChannel, and jsdom.) + // https://github.com/facebook/react/issues/20756 + // + // But also, it runs earlier which is the semantic we want. + // If other browsers ever implement it, it's better to use it. + // Although both of these would be inferior to native scheduling. + schedulePerformWorkUntilDeadline = function() { + localSetImmediate(performWorkUntilDeadline); + }; + else if (typeof MessageChannel !== "undefined") { + // DOM and Worker environments. + // We prefer MessageChannel because of the 4ms setTimeout clamping. + var channel = new MessageChannel(); + var port = channel.port2; + channel.port1.onmessage = performWorkUntilDeadline; + schedulePerformWorkUntilDeadline = function() { + port.postMessage(null); + }; + } else // We should only fallback here in non-browser environments. + schedulePerformWorkUntilDeadline = function() { + localSetTimeout(performWorkUntilDeadline, 0); + }; + function requestHostCallback(callback) { + scheduledHostCallback = callback; + if (!isMessageLoopRunning) { + isMessageLoopRunning = true; + schedulePerformWorkUntilDeadline(); + } + } + function requestHostTimeout(callback, ms) { + taskTimeoutID = localSetTimeout(function() { + callback(exports.unstable_now()); + }, ms); + } + function cancelHostTimeout() { + localClearTimeout(taskTimeoutID); + taskTimeoutID = -1; + } + var unstable_requestPaint = requestPaint; + var unstable_Profiling = null; + exports.unstable_IdlePriority = IdlePriority; + exports.unstable_ImmediatePriority = ImmediatePriority; + exports.unstable_LowPriority = LowPriority; + exports.unstable_NormalPriority = NormalPriority; + exports.unstable_Profiling = unstable_Profiling; + exports.unstable_UserBlockingPriority = UserBlockingPriority; + exports.unstable_cancelCallback = unstable_cancelCallback; + exports.unstable_continueExecution = unstable_continueExecution; + exports.unstable_forceFrameRate = forceFrameRate; + exports.unstable_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel; + exports.unstable_getFirstCallbackNode = unstable_getFirstCallbackNode; + exports.unstable_next = unstable_next; + exports.unstable_pauseExecution = unstable_pauseExecution; + exports.unstable_requestPaint = unstable_requestPaint; + exports.unstable_runWithPriority = unstable_runWithPriority; + exports.unstable_scheduleCallback = unstable_scheduleCallback; + exports.unstable_shouldYield = shouldYieldToHost; + exports.unstable_wrapCallback = unstable_wrapCallback; + /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function") __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error()); +})(); + +},{}],"gR4js":[function(require,module,exports) { +var $parcel$ReactRefreshHelpers$3fe9 = require("@parcel/transformer-react-refresh-wrap/lib/helpers/helpers.js"); +var prevRefreshReg = window.$RefreshReg$; +var prevRefreshSig = window.$RefreshSig$; +$parcel$ReactRefreshHelpers$3fe9.prelude(module); + +try { +var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); +parcelHelpers.defineInteropFlag(exports); +parcelHelpers.export(exports, "getLayout", ()=>getLayout); +var _react = require("react"); +const getLayout = (RawImport)=>typeof RawImport.Layout === "function" ? RawImport.Layout : typeof RawImport.getGlobalProvider === "function" ? RawImport.getGlobalProvider() : (0, _react.Fragment); + + $parcel$ReactRefreshHelpers$3fe9.postlude(module); +} finally { + window.$RefreshReg$ = prevRefreshReg; + window.$RefreshSig$ = prevRefreshSig; +} +},{"react":"ifaUc","@parcel/transformer-js/src/esmodule-helpers.js":"boKlo","@parcel/transformer-react-refresh-wrap/lib/helpers/helpers.js":"d37mJ"}],"boKlo":[function(require,module,exports) { +exports.interopDefault = function(a) { + return a && a.__esModule ? a : { + default: a + }; +}; +exports.defineInteropFlag = function(a) { + Object.defineProperty(a, "__esModule", { + value: true + }); +}; +exports.exportAll = function(source, dest) { + Object.keys(source).forEach(function(key) { + if (key === "default" || key === "__esModule" || dest.hasOwnProperty(key)) return; + Object.defineProperty(dest, key, { + enumerable: true, + get: function() { + return source[key]; + } + }); + }); + return dest; +}; +exports.export = function(dest, destName, get) { + Object.defineProperty(dest, destName, { + enumerable: true, + get: get + }); +}; + +},{}],"d37mJ":[function(require,module,exports) { +"use strict"; +var Refresh = require("7422ead32dcc1e6b"); +function debounce(func, delay) { + { + let timeout = undefined; + let lastTime = 0; + return function(args) { + // Call immediately if last call was more than the delay ago. + // Otherwise, set a timeout. This means the first call is fast + // (for the common case of a single update), and subsequent updates + // are batched. + let now = Date.now(); + if (now - lastTime > delay) { + lastTime = now; + func.call(null, args); + } else { + clearTimeout(timeout); + timeout = setTimeout(function() { + timeout = undefined; + lastTime = Date.now(); + func.call(null, args); + }, delay); + } + }; + } +} +var enqueueUpdate = debounce(function() { + Refresh.performReactRefresh(); +}, 30); +// Everthing below is either adapted or copied from +// https://github.com/facebook/metro/blob/61de16bd1edd7e738dd0311c89555a644023ab2d/packages/metro/src/lib/polyfills/require.js +// MIT License - Copyright (c) Facebook, Inc. and its affiliates. +module.exports.prelude = function(module1) { + window.$RefreshReg$ = function(type, id) { + Refresh.register(type, module1.id + " " + id); + }; + window.$RefreshSig$ = Refresh.createSignatureFunctionForTransform; +}; +module.exports.postlude = function(module1) { + if (isReactRefreshBoundary(module1.exports)) { + registerExportsForReactRefresh(module1); + if (module1.hot) { + module1.hot.dispose(function(data) { + if (Refresh.hasUnrecoverableErrors()) window.location.reload(); + data.prevExports = module1.exports; + }); + module1.hot.accept(function(getParents) { + var prevExports = module1.hot.data.prevExports; + var nextExports = module1.exports; + // Since we just executed the code for it, it's possible + // that the new exports make it ineligible for being a boundary. + var isNoLongerABoundary = !isReactRefreshBoundary(nextExports); + // It can also become ineligible if its exports are incompatible + // with the previous exports. + // For example, if you add/remove/change exports, we'll want + // to re-execute the importing modules, and force those components + // to re-render. Similarly, if you convert a class component + // to a function, we want to invalidate the boundary. + var didInvalidate = shouldInvalidateReactRefreshBoundary(prevExports, nextExports); + if (isNoLongerABoundary || didInvalidate) { + // We'll be conservative. The only case in which we won't do a full + // reload is if all parent modules are also refresh boundaries. + // In that case we'll add them to the current queue. + var parents = getParents(); + if (parents.length === 0) { + // Looks like we bubbled to the root. Can't recover from that. + window.location.reload(); + return; + } + return parents; + } + enqueueUpdate(); + }); + } + } +}; +function isReactRefreshBoundary(exports) { + if (Refresh.isLikelyComponentType(exports)) return true; + if (exports == null || typeof exports !== "object") // Exit if we can't iterate over exports. + return false; + var hasExports = false; + var areAllExportsComponents = true; + let isESM = "__esModule" in exports; + for(var key in exports){ + hasExports = true; + if (key === "__esModule") continue; + var desc = Object.getOwnPropertyDescriptor(exports, key); + if (desc && desc.get && !isESM) // Don't invoke getters for CJS as they may have side effects. + return false; + var exportValue = exports[key]; + if (!Refresh.isLikelyComponentType(exportValue)) areAllExportsComponents = false; + } + return hasExports && areAllExportsComponents; +} +function shouldInvalidateReactRefreshBoundary(prevExports, nextExports) { + var prevSignature = getRefreshBoundarySignature(prevExports); + var nextSignature = getRefreshBoundarySignature(nextExports); + if (prevSignature.length !== nextSignature.length) return true; + for(var i = 0; i < nextSignature.length; i++){ + if (prevSignature[i] !== nextSignature[i]) return true; + } + return false; +} +// When this signature changes, it's unsafe to stop at this refresh boundary. +function getRefreshBoundarySignature(exports) { + var signature = []; + signature.push(Refresh.getFamilyByType(exports)); + if (exports == null || typeof exports !== "object") // Exit if we can't iterate over exports. + // (This is important for legacy environments.) + return signature; + let isESM = "__esModule" in exports; + for(var key in exports){ + if (key === "__esModule") continue; + var desc = Object.getOwnPropertyDescriptor(exports, key); + if (desc && desc.get && !isESM) continue; + var exportValue = exports[key]; + signature.push(key); + signature.push(Refresh.getFamilyByType(exportValue)); + } + return signature; +} +function registerExportsForReactRefresh(module1) { + var exports = module1.exports, id = module1.id; + Refresh.register(exports, id + " %exports%"); + if (exports == null || typeof exports !== "object") // Exit if we can't iterate over exports. + // (This is important for legacy environments.) + return; + let isESM = "__esModule" in exports; + for(var key in exports){ + var desc = Object.getOwnPropertyDescriptor(exports, key); + if (desc && desc.get && !isESM) continue; + var exportValue = exports[key]; + var typeID = id + " %exports% " + key; + Refresh.register(exportValue, typeID); + } +} + +},{"7422ead32dcc1e6b":"iZhE1"}],"29e65":[function(require,module,exports) { +var $parcel$ReactRefreshHelpers$e74c = require("@parcel/transformer-react-refresh-wrap/lib/helpers/helpers.js"); +var prevRefreshReg = window.$RefreshReg$; +var prevRefreshSig = window.$RefreshSig$; +$parcel$ReactRefreshHelpers$e74c.prelude(module); + +try { +var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js"); +parcelHelpers.defineInteropFlag(exports); +var _jsxDevRuntime = require("react/jsx-dev-runtime"); +var _react = require("react"); +var _s = $RefreshSig$(); +function IndexPopup() { + _s(); + const [data, setData] = (0, _react.useState)(""); + return /*#__PURE__*/ (0, _jsxDevRuntime.jsxDEV)("div", { + style: { + padding: 16 + }, + children: [ + /*#__PURE__*/ (0, _jsxDevRuntime.jsxDEV)("h2", { + children: [ + "Welcome to your", + " ", + /*#__PURE__*/ (0, _jsxDevRuntime.jsxDEV)("a", { + href: "https://www.plasmo.com", + target: "_blank", + children: "Plasmo" + }, void 0, false, { + fileName: "packages/whats-ext/popup.tsx", + lineNumber: 13, + columnNumber: 9 + }, this), + " ", + "Extension!" + ] + }, void 0, true, { + fileName: "packages/whats-ext/popup.tsx", + lineNumber: 11, + columnNumber: 7 + }, this), + /*#__PURE__*/ (0, _jsxDevRuntime.jsxDEV)("input", { + onChange: (e)=>setData(e.target.value), + value: data + }, void 0, false, { + fileName: "packages/whats-ext/popup.tsx", + lineNumber: 18, + columnNumber: 7 + }, this), + /*#__PURE__*/ (0, _jsxDevRuntime.jsxDEV)("a", { + href: "https://docs.plasmo.com", + target: "_blank", + children: "View Docs" + }, void 0, false, { + fileName: "packages/whats-ext/popup.tsx", + lineNumber: 19, + columnNumber: 7 + }, this) + ] + }, void 0, true, { + fileName: "packages/whats-ext/popup.tsx", + lineNumber: 7, + columnNumber: 5 + }, this); +} +_s(IndexPopup, "avaWeDctHFwWP+lC5+N1mkv/uq8="); +_c = IndexPopup; +exports.default = IndexPopup; +var _c; +$RefreshReg$(_c, "IndexPopup"); + + $parcel$ReactRefreshHelpers$e74c.postlude(module); +} finally { + window.$RefreshReg$ = prevRefreshReg; + window.$RefreshSig$ = prevRefreshSig; +} +},{"react/jsx-dev-runtime":"g2xeO","react":"ifaUc","@parcel/transformer-js/src/esmodule-helpers.js":"boKlo","@parcel/transformer-react-refresh-wrap/lib/helpers/helpers.js":"d37mJ"}]},["gTWK1","5TpEE"], "5TpEE", "parcelRequire8cd9") + +//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUMsQUFBQyxDQUFBLE1BQUksS0FBRyxNQUFNLFFBQVEsTUFBSSxDQUFDLENBQUMsRUFBRSxTQUFPLEVBQUUsS0FBRyxDQUFBLEtBQUksRUFBRSxLQUFLO1FBQUM7UUFBRTtLQUFFO0lBQUUsT0FBTyxFQUFFLFVBQVMsQ0FBQSxJQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUUsUUFBTyxHQUFFLEdBQUc7QUFBQztBQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUM7SUFBRSxJQUFHLEVBQUUsR0FBRSxHQUFFLElBQUcsT0FBTSxDQUFDO0lBQUUsSUFBSSxJQUFFLEVBQUUsT0FBTyxPQUFPLE1BQUssSUFBRyxJQUFFLENBQUM7SUFBRSxNQUFLLEVBQUUsU0FBTyxHQUFHO1FBQUMsSUFBRyxDQUFDLEdBQUUsRUFBRSxHQUFDLEVBQUU7UUFBUSxJQUFHLEVBQUUsR0FBRSxHQUFFLE9BQU0sSUFBRSxDQUFDO2FBQU07WUFBQyxJQUFJLElBQUUsRUFBRSxPQUFPLE9BQU8sTUFBSztZQUFHLElBQUcsRUFBRSxXQUFTLEdBQUU7Z0JBQUMsSUFBRSxDQUFDO2dCQUFFO1lBQUs7WUFBQyxFQUFFLFFBQVE7UUFBRTtJQUFDO0lBQUMsT0FBTztBQUFDO0FBQUMsU0FBUyxFQUFFLENBQUMsRUFBQyxDQUFDLEVBQUMsQ0FBQztJQUFFLElBQUcsRUFBQyxTQUFRLENBQUMsRUFBQyxHQUFDO0lBQUUsSUFBRyxDQUFDLEdBQUUsT0FBTSxDQUFDO0lBQUUsSUFBRyxLQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsY0FBYyxFQUFDLE9BQU8sRUFBRSxTQUFPLEVBQUUsRUFBRSxRQUFPLEdBQUUsS0FBRyxDQUFDO0lBQUUsSUFBRyxFQUFFLGFBQWEsQ0FBQyxFQUFFLEVBQUMsT0FBTSxDQUFDO0lBQUUsRUFBRSxhQUFhLENBQUMsRUFBRSxHQUFDLENBQUM7SUFBRSxJQUFJLElBQUUs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QUMsRUFBRSxHQUFHLENBQUMsRUFBRTtvQkFBQyxJQUFJLElBQUksS0FBSyxFQUFFLElBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFFLENBQUMsQ0FBQyxFQUFFLEtBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBQzt3QkFBQyxJQUFJLElBQUUsQ0FBQyxDQUFDLEVBQUU7d0JBQUMsRUFBRSxPQUFPLE9BQU8sTUFBSyxHQUFHLFdBQVMsS0FBRyxFQUFFLE9BQU8sT0FBTyxNQUFLO29CQUFFO2dCQUFDO2dCQUFDLElBQUksSUFBRSxPQUFPLGVBQWUsQ0FBQyxFQUFFLEdBQUc7Z0JBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxHQUFDO29CQUFDO29CQUFFO2lCQUFFO1lBQUEsT0FBTSxFQUFFLFVBQVEsRUFBRSxFQUFFLFFBQU87UUFBRTtJQUFDO0FBQUM7QUFBQyxTQUFTLEVBQUUsQ0FBQyxFQUFDLENBQUM7SUFBRSxJQUFJLElBQUUsRUFBRTtJQUFRLElBQUc7UUFBRSxJQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUM7WUFBQyxJQUFJLElBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUMsSUFBRSxFQUFFO1lBQUMsSUFBSSxJQUFJLEtBQUssRUFBRSxFQUFFLE9BQU8sT0FBTyxNQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsV0FBUyxLQUFHLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRTtZQUFFLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBQyxFQUFFLFFBQVEsQ0FBQTtnQkFBSSxFQUFFLE9BQU8sT0FBTyxNQUFLO1lBQUU7UUFBRSxPQUFNLEVBQUUsVUFBUSxFQUFFLEVBQUUsUUFBTzs7QUFBRTtBQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUMsQ0FBQztJQUFFLElBQUksSUFBRSxFQUFFLEtBQUssQ0FBQyxFQUFFO0lBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxHQUFDLENBQUMsR0FBRSxLQUFHLEVBQUUsT0FBTSxDQUFBLEVBQUUsSUFBSSxPQUFLLEVBQUUs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S0FBRyxPQUFPLGdCQUFlLEtBQUcsT0FBTyxVQUFVO0FBQWUsSUFBSSxJQUFFLENBQUMsR0FBRSxJQUFJLElBQUssQ0FBQSxLQUFHLEVBQUUsQUFBQyxDQUFBLElBQUU7WUFBQyxTQUFRLENBQUM7UUFBQyxDQUFBLEVBQUcsU0FBUSxJQUFHLEVBQUUsT0FBTSxHQUFHLEtBQUcsQ0FBQyxHQUFFO0lBQUssSUFBSSxJQUFJLEtBQUssRUFBRSxFQUFFLEdBQUUsR0FBRTtRQUFDLEtBQUksQ0FBQyxDQUFDLEVBQUU7UUFBQyxZQUFXLENBQUM7SUFBQztBQUFFLEdBQUUsSUFBRSxDQUFDLEdBQUUsR0FBRSxHQUFFO0lBQUssSUFBRyxLQUFHLE9BQU8sS0FBRyxZQUFVLE9BQU8sS0FBRyxZQUFXLEtBQUksSUFBSSxLQUFLLEdBQUcsR0FBRyxDQUFDLEdBQUcsS0FBSyxHQUFFLE1BQUksTUFBSSxLQUFHLEVBQUUsR0FBRSxHQUFFO1FBQUMsS0FBSSxJQUFJLENBQUMsQ0FBQyxFQUFFO1FBQUMsWUFBVyxDQUFFLENBQUEsSUFBRSxHQUFHLEdBQUUsRUFBQyxLQUFJLEVBQUU7SUFBVTtJQUFHLE9BQU87QUFBQyxHQUFFLElBQUUsQ0FBQyxHQUFFLEdBQUUsSUFBSyxDQUFBLEVBQUUsR0FBRSxHQUFFLFlBQVcsS0FBRyxFQUFFLEdBQUUsR0FBRSxVQUFTLEdBQUcsSUFBRSxDQUFDLEdBQUUsR0FBRSxJQUFLLENBQUEsSUFBRSxLQUFHLE9BQUssR0FBRyxHQUFHLE1BQUksQ0FBQyxHQUFFLEVBQUUsS0FBRyxDQUFDLEtBQUcsQ0FBQyxFQUFFLGFBQVcsRUFBRSxHQUFFLFdBQVU7UUFBQyxPQUFNO1FBQUUsWUFBVyxDQUFDO0lBQUMsS0FBRyxHQUFFLEVBQUMsR0FBRyxLQUFHLENBQUEsSUFBRyxFQUFFLEVBQUUsQ0FBQyxHQUFFLGNBQWE7UUFBQyxPQUFNLENBQUM7SUFBQyxJQUFHO0FBQUcsSUFBSSxJQUFFLEVBQUUsQ0FBQTtJQUFJO0lBQWMsQ0FBQTtRQUFXO1FBQWEsSUFBSSxJQUFFLE9BQU8sSUFBSSxzQkFBcUIsSUFBRSxPQUFPLElBQUksZUFBYyxJQUFFLE9BQU8sV0FBUyxhQUFXLFVBQVEsS0FBSSxJQUFFLElBQUksS0FBSSxJQUFFLElBQUksR0FBRSxJQUFFLElBQUksR0FBRSxJQUFFLElBQUksR0FBRSxJQUFFLEVBQUUsRUFBQyxJQUFFLElBQUksS0FBSSxJQUFFLElBQUksS0FBSSxJQUFFLElBQUksS0FBSSxJQUFFLElBQUksS0FBSSxJQUFFLE9BQU8sV0FBUyxhQUFXLElBQUksVUFBUSxNQUFLLElBQUUsQ0FBQztRQUFFLFNBQVMsRUFBRSxDQUFDO1lBQUUsSUFBRyxFQUFFLFlBQVUsTUFBSyxPQUFPLEVBQUU7WUFBUSxJQUFJLElBQUUsRUFBRSxRQUFPO1lBQUUsSUFBRztnQkFBQyxJQUFFLEVBQUU7WUFBZ0IsRUFBQyxPQUFNLEdBQUU7Z0JBQUMsT0FBTyxFQUFFLGFBQVcsQ0FBQyxHQUFFLEVBQUUsVUFBUSxHQUFFO1lBQUM7WUFBQyxJQUFJLElBQUksSUFBRSxHQUFFLElBQUUsRUFBRSxRQUFPLElBQUk7Z0JBQUMsSUFBSSxJQUFFLENBQUMsQ0FBQyxFQUFFO2dCQUFDLElBQUcsT0FBTyxLQUFHLFlBQVcsT0FBTyxFQUFFLGFBQVcsQ0FBQyxHQUFFLEVBQUUsVUFBUSxHQUFFO2dCQUFFLElBQUksSUFBRSxFQUFFLElBQUk7Z0JBQUcsSUFBRyxNQUFJLEtBQUssR0FBRTtvQkFBQyxJQUFJLElBQUUsRUFBRTtvQkFBRyxFQUFFLGNBQWEsQ0FBQSxFQUFFLGFBQVcsQ0FBQyxDQUFBLEdBQUcsS0FBRyxDQUFDOztBQUUzdkMsQ0FBQyxHQUFDO2dCQUFDO1lBQUM7WUFBQyxPQUFPLEVBQUUsVUFBUSxHQUFFO1FBQUM7UUFBQyxTQUFTLEVBQUUsQ0FBQyxFQUFDLENBQUM7WUFBRSxJQUFJLElBQUUsRUFBRSxJQUFJLElBQUcsSUFBRSxFQUFFLElBQUk7WUFBRyxPQUFPLE1BQUksS0FBSyxLQUFHLE1BQUksS0FBSyxJQUFFLENBQUMsSUFBRSxDQUFFLENBQUEsTUFBSSxLQUFLLEtBQUcsTUFBSSxLQUFLLEtBQUcsRUFBRSxPQUFLLEVBQUUsTUFBSSxFQUFFLFVBQVM7UUFBRTtRQUFDLFNBQVMsRUFBRSxDQUFDO1lBQUUsT0FBTyxFQUFFLGFBQVcsRUFBRSxVQUFVO1FBQWdCO1FBQUMsU0FBUyxFQUFFLENBQUMsRUFBQyxDQUFDO1lBQUUsT0FBTyxFQUFFLE1BQUksRUFBRSxLQUFHLENBQUMsSUFBRSxDQUFDLENBQUMsRUFBRSxHQUFFO1FBQUU7UUFBQyxTQUFTLEVBQUUsQ0FBQztZQUFFLE9BQU8sRUFBRSxJQUFJO1FBQUU7UUFBQyxTQUFTLEVBQUUsQ0FBQztZQUFFLElBQUksSUFBRSxJQUFJO1lBQUksT0FBTyxFQUFFLFFBQVEsU0FBUyxDQUFDLEVBQUMsQ0FBQztnQkFBRSxFQUFFLElBQUksR0FBRTtZQUFFLElBQUc7UUFBQztRQUFDLFNBQVMsRUFBRSxDQUFDO1lBQUUsSUFBSSxJQUFFLElBQUk7WUFBSSxPQUFPLEVBQUUsUUFBUSxTQUFTLENBQUM7Z0JBQUUsRUFBRSxJQUFJO1lBQUUsSUFBRztRQUFDO1FBQUMsU0FBUyxFQUFFLENBQUMsRUFBQyxDQUFDO1lBQUUsSUFBRztnQkFBQyxPQUFPLENBQUMsQ0FBQyxFQUFFO1lBQUEsRUFBQyxPQUFNLEdBQUU7Z0JBQUM7WUFBTTtRQUFDO1FBQUMsU0FBUztZQUFJLElBQUcsRUFBRSxXQUFTLEtBQUcsR0FBRSxPQUFPO1lBQUssSUFBRSxDQUFDO1lBQUUsSUFBRztnQkFBQyxJQUFJLElBQUUsSUFBSSxLQUFJLElBQUUsSUFBSSxLQUFJLElBQUU7Z0JBQUUsSUFBRSxFQUFFLEVBQUMsRUFBRSxRQUFRLFNBQVMsQ0FBQztvQkFBRSxJQUFJLElBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBQyxJQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUMsSUFBRSxFQUFFO29CQUFRLEVBQUUsSUFBSSxHQUFFLElBQUcsRUFBRSxJQUFJLEdBQUUsSUFBRyxFQUFFLFVBQVEsR0FBRSxFQUFFLEdBQUUsS0FBRyxFQUFFLElBQUksS0FBRyxFQUFFLElBQUk7Z0JBQUU7Z0JBQUcsSUFB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QSxlQUFPLEVBQUU7SUFFakMscUJBQ0UsMkJBQUM7UUFDQyxPQUFPO1lBQ0wsU0FBUztRQUNYOzswQkFDQSwyQkFBQzs7b0JBQUc7b0JBQ2M7a0NBQ2hCLDJCQUFDO3dCQUFFLE1BQUs7d0JBQXlCLFFBQU87a0NBQVM7Ozs7OztvQkFFNUM7b0JBQUk7Ozs7Ozs7MEJBR1gsMkJBQUM7Z0JBQU0sVUFBVSxDQUFDLElBQU0sUUFBUSxFQUFFLE9BQU87Z0JBQVEsT0FBTzs7Ozs7OzBCQUN4RCwyQkFBQztnQkFBRSxNQUFLO2dCQUEwQixRQUFPOzBCQUFTOzs7Ozs7Ozs7Ozs7QUFLeEQ7R0FyQlM7S0FBQTtrQkF1Qk0iLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9AcGxhc21vaHEvcGFyY2VsLXJ1bnRpbWUvZGlzdC9ydW50aW1lLWE1N2E5OGM4ZThiODgwZWIuanMiLCJub2RlX21vZHVsZXMvQHBsYXNtb2hxL3BhcmNlbC1yZXNvbHZlci9kaXN0L3BvbHlmaWxscy9yZWFjdC1yZWZyZXNoL3J1bnRpbWUuanMiLCJwYWNrYWdlcy93aGF0cy1leHQvLnBsYXNtby9zdGF0aWMvcG9wdXAudHN4Iiwibm9kZV9tb2R1bGVzL3JlYWN0L2pzeC1kZXYtcnVudGltZS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9janMvcmVhY3QtanN4LWRldi1ydW50aW1lLmRldmVsb3BtZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2Nqcy9yZWFjdC5kZXZlbG9wbWVudC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1kb20vY2xpZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LWRvbS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1kb20vY2pzL3JlYWN0LWRvbS5kZXZlbG9wbWVudC5qcyIsIm5vZGVfbW9kdWxlcy9zY2hlZHVsZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2NoZWR1bGVyL2Nqcy9zY2hlZHVsZXIuZGV2ZWxvcG1lbnQuanMiLCJwYWNrYWdlcy93aGF0cy1leHQvLnBsYXNtby9zdGF0aWMvY29tbW9uL3JlYWN0LnRzIiwibm9kZV9tb2R1bGVzL0BwYXJjZWwvdHJhbnNmb3JtZXItanMvc3JjL2VzbW9kdWxlLWhlbHBlcnMuanMiLCJub2RlX21vZHVsZXMvQHBhcmNlbC90cmFuc2Zvcm1lci1yZWFjdC1yZWZyZXNoLXdyYXAvbGliL2hlbHBlcnMvaGVscGVycy5qcyIsInBhY2thZ2VzL3doYXRzLWV4dC9wb3B1cC50c3giXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFc9T2JqZWN0LmNyZWF0ZTt2YXIgUD1PYmplY3QuZGVmaW5lUHJvcGVydHk7dmFyIFY9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjt2YXIgRz1PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lczt2YXIgWD1PYmplY3QuZ2V0UHJvdG90eXBlT2YsSj1PYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O3ZhciBxPShlLHQsbyxyKT0+e2lmKHQmJnR5cGVvZiB0PT1cIm9iamVjdFwifHx0eXBlb2YgdD09XCJmdW5jdGlvblwiKWZvcihsZXQgbiBvZiBHKHQpKSFKLmNhbGwoZSxuKSYmbiE9PW8mJlAoZSxuLHtnZXQ6KCk9PnRbbl0sZW51bWVyYWJsZTohKHI9Vih0LG4pKXx8ci5lbnVtZXJhYmxlfSk7cmV0dXJuIGV9O3ZhciB6PShlLHQsbyk9PihvPWUhPW51bGw/VyhYKGUpKTp7fSxxKHR8fCFlfHwhZS5fX2VzTW9kdWxlP1AobyxcImRlZmF1bHRcIix7dmFsdWU6ZSxlbnVtZXJhYmxlOiEwfSk6byxlKSk7dmFyIHk9dHlwZW9mIGdsb2JhbFRoaXMucHJvY2VzczxcInVcIj9nbG9iYWxUaGlzLnByb2Nlc3MuYXJndjpbXTt2YXIgSD0oKT0+dHlwZW9mIGdsb2JhbFRoaXMucHJvY2VzczxcInVcIj9nbG9iYWxUaGlzLnByb2Nlc3MuZW52Ont9O3ZhciBLPW5ldyBTZXQoeSksRD1lPT5LLmhhcyhlKSx1ZT15LmZpbHRlcihlPT5lLnN0YXJ0c1dpdGgoXCItLVwiKSYmZS5pbmNsdWRlcyhcIj1cIikpLm1hcChlPT5lLnNwbGl0KFwiPVwiKSkucmVkdWNlKChlLFt0LG9dKT0+KGVbdF09byxlKSx7fSk7dmFyIGRlPUQoXCItLWRyeS1ydW5cIiksXz0oKT0+RChcIi0tdmVyYm9zZVwiKXx8SCgpLlZFUkJPU0U9PT1cInRydWVcIixmZT1fKCk7dmFyIHg9KGU9XCJcIiwuLi50KT0+Y29uc29sZS5sb2coZS5wYWRFbmQoOSksXCJ8XCIsLi4udCk7dmFyIFQ9KC4uLmUpPT5jb25zb2xlLmVycm9yKFwiXFx1ezFGNTM0fSBFUlJPUlwiLnBhZEVuZCg5KSxcInxcIiwuLi5lKSxrPSguLi5lKT0+eChcIlxcdXsxRjUzNX0gSU5GT1wiLC4uLmUpLEE9KC4uLmUpPT54KFwiXFx1ezFGN0UwfSBXQVJOXCIsLi4uZSksUT0wLHA9KC4uLmUpPT5fKCkmJngoYFxcdXsxRjdFMX0gJHtRKyt9YCwuLi5lKTt2YXIgYz17XCJpc0NvbnRlbnRTY3JpcHRcIjpmYWxzZSxcImlzQmFja2dyb3VuZFwiOmZhbHNlLFwiaXNSZWFjdFwiOnRydWUsXCJydW50aW1lc1wiOltcInBhZ2UtcnVudGltZVwiXSxcImhvc3RcIjpcImxvY2FsaG9zdFwiLFwicG9ydFwiOjE4MTUsXCJlbnRyeUZpbGVQYXRoXCI6XCIvVXNlcnMva2VyZW4vRGVza3RvcC93aGF0cy1lbGVtZW50L3BhY2thZ2VzL3doYXRzLWV4dC8ucGxhc21vL3N0YXRpYy9wb3B1cC50c3hcIixcImJ1bmRsZUlkXCI6XCI0ODg5ODY3MzdmZjU4OGYzXCIsXCJlbnZIYXNoXCI6XCJlNzkyZmJiZGFhNzhlZTg0XCIsXCJ2ZXJib3NlXCI6XCJmYWxzZVwiLFwic2VjdXJlXCI6ZmFsc2UsXCJzZXJ2ZXJQb3J0XCI6NDk5OTR9O21vZHVsZS5idW5kbGUuSE1SX0JVTkRMRV9JRD1jLmJ1bmRsZUlkO2dsb2JhbFRoaXMucHJvY2Vzcz17YXJndjpbXSxlbnY6e1ZFUkJPU0U6Yy52ZXJib3NlfX07dmFyIFk9bW9kdWxlLmJ1bmRsZS5Nb2R1bGU7ZnVuY3Rpb24gWihlKXtZLmNhbGwodGhpcyxlKSx0aGlzLmhvdD17ZGF0YTptb2R1bGUuYnVuZGxlLmhvdERhdGFbZV0sX2FjY2VwdENhbGxiYWNrczpbXSxfZGlzcG9zZUNhbGxiYWNrczpbXSxhY2NlcHQ6ZnVuY3Rpb24odCl7dGhpcy5fYWNjZXB0Q2FsbGJhY2tzLnB1c2godHx8ZnVuY3Rpb24oKXt9KX0sZGlzcG9zZTpmdW5jdGlvbih0KXt0aGlzLl9kaXNwb3NlQ2FsbGJhY2tzLnB1c2godCl9fSxtb2R1bGUuYnVuZGxlLmhvdERhdGFbZV09dm9pZCAwfW1vZHVsZS5idW5kbGUuTW9kdWxlPVo7bW9kdWxlLmJ1bmRsZS5ob3REYXRhPXt9O3ZhciBkPWdsb2JhbFRoaXMuYnJvd3Nlcnx8Z2xvYmFsVGhpcy5jaHJvbWV8fG51bGw7YXN5bmMgZnVuY3Rpb24gbShlPSExKXtlPyhwKFwiVHJpZ2dlcmluZyBmdWxsIHJlbG9hZFwiKSxkLnJ1bnRpbWUuc2VuZE1lc3NhZ2Uoe19fcGxhc21vX2Z1bGxfcmVsb2FkX186ITB9KSk6Z2xvYmFsVGhpcy5sb2NhdGlvbj8ucmVsb2FkPy4oKX1mdW5jdGlvbiB3KCl7cmV0dXJuIWMuaG9zdHx8Yy5ob3N0PT09XCIwLjAuMC4wXCI/bG9jYXRpb24ucHJvdG9jb2wuaW5kZXhPZihcImh0dHBcIik9PT0wP2xvY2F0aW9uLmhvc3RuYW1lOlwibG9jYWxob3N0XCI6Yy5ob3N0fWZ1bmN0aW9uIEwoKXtyZXR1cm4hYy5ob3N0fHxjLmhvc3Q9PT1cIjAuMC4wLjBcIj9cImxvY2FsaG9zdFwiOmMuaG9zdH1mdW5jdGlvbiBmKCl7cmV0dXJuIGMucG9ydHx8bG9jYXRpb24ucG9ydH12YXIgUz1cIl9fcGxhc21vX3J1bnRpbWVfcGFnZV9cIjt2YXIgaT17Y2hlY2tlZEFzc2V0czp7fSxhc3NldHNUb0Rpc3Bvc2U6W10sYXNzZXRzVG9BY2NlcHQ6W119LEI9KCk9PntpLmNoZWNrZWRBc3NldHM9e30saS5hc3NldHNUb0Rpc3Bvc2U9W10saS5hc3NldHNUb0FjY2VwdD1bXX07ZnVuY3Rpb24gdShlLHQpe2xldHttb2R1bGVzOm99PWU7aWYoIW8pcmV0dXJuW107bGV0IHI9W10sbixzLGE7Zm9yKG4gaW4gbylmb3IocyBpbiBvW25dWzFdKWE9b1tuXVsxXVtzXSwoYT09PXR8fEFycmF5LmlzQXJyYXkoYSkmJmFbYS5sZW5ndGgtMV09PT10KSYmci5wdXNoKFtlLG5dKTtyZXR1cm4gZS5wYXJlbnQmJihyPXIuY29uY2F0KHUoZS5wYXJlbnQsdCkpKSxyfWZ1bmN0aW9uIFIoZSx0LG8pe2lmKEMoZSx0LG8pKXJldHVybiEwO2xldCByPXUobW9kdWxlLmJ1bmRsZS5yb290LHQpLG49ITE7Zm9yKDtyLmxlbmd0aD4wOyl7bGV0W3MsYV09ci5zaGlmdCgpO2lmKEMocyxhLG51bGwpKW49ITA7ZWxzZXtsZXQgZz11KG1vZHVsZS5idW5kbGUucm9vdCxhKTtpZihnLmxlbmd0aD09PTApe249ITE7YnJlYWt9ci5wdXNoKC4uLmcpfX1yZXR1cm4gbn1mdW5jdGlvbiBDKGUsdCxvKXtsZXR7bW9kdWxlczpyfT1lO2lmKCFyKXJldHVybiExO2lmKG8mJiFvW2UuSE1SX0JVTkRMRV9JRF0pcmV0dXJuIGUucGFyZW50P1IoZS5wYXJlbnQsdCxvKTohMDtpZihpLmNoZWNrZWRBc3NldHNbdF0pcmV0dXJuITA7aS5jaGVja2VkQXNzZXRzW3RdPSEwO2xldCBuPWUuY2FjaGVbdF07cmV0dXJuIGkuYXNzZXRzVG9EaXNwb3NlLnB1c2goW2UsdF0pLCFufHxuLmhvdCYmbi5ob3QuX2FjY2VwdENhbGxiYWNrcy5sZW5ndGg/KGkuYXNzZXRzVG9BY2NlcHQucHVzaChbZSx0XSksITApOiExfWZ1bmN0aW9uIE0oZSx0KXtsZXR7bW9kdWxlczpvfT1lO3JldHVybiBvPyEhb1t0XTohMX1mdW5jdGlvbiBlZShlKXtpZihlLnR5cGU9PT1cImpzXCImJnR5cGVvZiBkb2N1bWVudDxcInVcIilyZXR1cm4gbmV3IFByb21pc2UoKHQsbyk9PntsZXQgcj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpO3Iuc3JjPWAke2UudXJsfT90PSR7RGF0ZS5ub3coKX1gLGUub3V0cHV0Rm9ybWF0PT09XCJlc21vZHVsZVwiJiYoci50eXBlPVwibW9kdWxlXCIpLHIuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwoKT0+dChyKSksci5hZGRFdmVudExpc3RlbmVyKFwiZXJyb3JcIiwoKT0+byhuZXcgRXJyb3IoYEZhaWxlZCB0byBkb3dubG9hZCBhc3NldDogJHtlLmlkfWApKSksZG9jdW1lbnQuaGVhZD8uYXBwZW5kQ2hpbGQocil9KX1hc3luYyBmdW5jdGlvbiBPKGUpe2dsb2JhbC5wYXJjZWxIb3RVcGRhdGU9T2JqZWN0LmNyZWF0ZShudWxsKSxlLmZvckVhY2gobz0+e28udXJsPWQucnVudGltZS5nZXRVUkwoXCIvX19wbGFzbW9faG1yX3Byb3h5X18/dXJsPVwiK2VuY29kZVVSSUNvbXBvbmVudChgJHtvLnVybH0/dD0ke0RhdGUubm93KCl9YCkpfSk7bGV0IHQ9YXdhaXQgUHJvbWlzZS5hbGwoZS5tYXAoZWUpKTt0cnl7ZS5mb3JFYWNoKGZ1bmN0aW9uKG8peyQobW9kdWxlLmJ1bmRsZS5yb290LG8pfSl9ZmluYWxseXtkZWxldGUgZ2xvYmFsLnBhcmNlbEhvdFVwZGF0ZSx0JiZ0LmZvckVhY2gobz0+e28mJmRvY3VtZW50LmhlYWQ/LnJlbW92ZUNoaWxkKG8pfSl9fWZ1bmN0aW9uIHRlKGUpe2xldCB0PWUuY2xvbmVOb2RlKCk7dC5vbmxvYWQ9ZnVuY3Rpb24oKXtlLnBhcmVudE5vZGUhPT1udWxsJiZlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZSl9LHQuc2V0QXR0cmlidXRlKFwiaHJlZlwiLGUuZ2V0QXR0cmlidXRlKFwiaHJlZlwiKS5zcGxpdChcIj9cIilbMF0rXCI/XCIrRGF0ZS5ub3coKSksZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0LGUubmV4dFNpYmxpbmcpfXZhciBiPW51bGw7ZnVuY3Rpb24gb2UoKXtifHwoYj1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7bGV0IGU9ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnbGlua1tyZWw9XCJzdHlsZXNoZWV0XCJdJyk7Zm9yKHZhciB0PTA7dDxlLmxlbmd0aDt0Kyspe2xldCBvPWVbdF0uZ2V0QXR0cmlidXRlKFwiaHJlZlwiKSxyPXcoKSxuPXI9PT1cImxvY2FsaG9zdFwiP25ldyBSZWdFeHAoXCJeKGh0dHBzPzpcXFxcL1xcXFwvKDAuMC4wLjB8MTI3LjAuMC4xKXxsb2NhbGhvc3QpOlwiK2YoKSkudGVzdChvKTpvLmluZGV4T2YocitcIjpcIitmKCkpOy9eaHR0cHM/OlxcL1xcLy9pLnRlc3QobykmJm8uaW5kZXhPZihsb2NhdGlvbi5vcmlnaW4pIT09MCYmIW58fHRlKGVbdF0pfWI9bnVsbH0sNDcpKX1mdW5jdGlvbiAkKGUsdCl7bGV0e21vZHVsZXM6b309ZTtpZihvKXtpZih0LnR5cGU9PT1cImNzc1wiKW9lKCk7ZWxzZSBpZih0LnR5cGU9PT1cImpzXCIpe2xldCByPXQuZGVwc0J5QnVuZGxlW2UuSE1SX0JVTkRMRV9JRF07aWYocil7aWYob1t0LmlkXSl7bGV0IHM9b1t0LmlkXVsxXTtmb3IobGV0IGEgaW4gcylpZighclthXXx8clthXSE9PXNbYV0pe2xldCBsPXNbYV07dShtb2R1bGUuYnVuZGxlLnJvb3QsbCkubGVuZ3RoPT09MSYmRShtb2R1bGUuYnVuZGxlLnJvb3QsbCl9fWxldCBuPWdsb2JhbC5wYXJjZWxIb3RVcGRhdGVbdC5pZF07b1t0LmlkXT1bbixyXX1lbHNlIGUucGFyZW50JiYkKGUucGFyZW50LHQpfX19ZnVuY3Rpb24gRShlLHQpe2xldCBvPWUubW9kdWxlcztpZihvKWlmKG9bdF0pe2xldCByPW9bdF1bMV0sbj1bXTtmb3IobGV0IHMgaW4gcil1KG1vZHVsZS5idW5kbGUucm9vdCxyW3NdKS5sZW5ndGg9PT0xJiZuLnB1c2gocltzXSk7ZGVsZXRlIG9bdF0sZGVsZXRlIGUuY2FjaGVbdF0sbi5mb3JFYWNoKHM9PntFKG1vZHVsZS5idW5kbGUucm9vdCxzKX0pfWVsc2UgZS5wYXJlbnQmJkUoZS5wYXJlbnQsdCl9ZnVuY3Rpb24gdihlLHQpe2xldCBvPWUuY2FjaGVbdF07ZS5ob3REYXRhW3RdPXt9LG8mJm8uaG90JiYoby5ob3QuZGF0YT1lLmhvdERhdGFbdF0pLG8mJm8uaG90JiZvLmhvdC5fZGlzcG9zZUNhbGxiYWNrcy5sZW5ndGgmJm8uaG90Ll9kaXNwb3NlQ2FsbGJhY2tzLmZvckVhY2goZnVuY3Rpb24ocil7cihlLmhvdERhdGFbdF0pfSksZGVsZXRlIGUuY2FjaGVbdF19ZnVuY3Rpb24gSShlLHQpe2UodCk7bGV0IG89ZS5jYWNoZVt0XTtpZihvJiZvLmhvdCYmby5ob3QuX2FjY2VwdENhbGxiYWNrcy5sZW5ndGgpe2xldCByPXUobW9kdWxlLmJ1bmRsZS5yb290LHQpO28uaG90Ll9hY2NlcHRDYWxsYmFja3MuZm9yRWFjaChmdW5jdGlvbihuKXtsZXQgcz1uKCgpPT5yKTtzJiZzLmxlbmd0aCYmKHMuZm9yRWFjaCgoW2EsbF0pPT57dihhLGwpfSksaS5hc3NldHNUb0FjY2VwdC5wdXNoLmFwcGx5KGkuYXNzZXRzVG9BY2NlcHQscykpfSl9fWZ1bmN0aW9uIHJlKGU9ZigpKXtsZXQgdD1MKCk7cmV0dXJuYCR7Yy5zZWN1cmV8fGxvY2F0aW9uLnByb3RvY29sPT09XCJodHRwczpcIiYmIS9sb2NhbGhvc3R8MTI3LjAuMC4xfDAuMC4wLjAvLnRlc3QodCk/XCJ3c3NcIjpcIndzXCJ9Oi8vJHt0fToke2V9L2B9ZnVuY3Rpb24gbmUoZSl7dHlwZW9mIGUubWVzc2FnZT09XCJzdHJpbmdcIiYmVChcIltwbGFzbW8vcGFyY2VsLXJ1bnRpbWVdOiBcIitlLm1lc3NhZ2UpfWZ1bmN0aW9uIE4oZSl7aWYodHlwZW9mIGdsb2JhbFRoaXMuV2ViU29ja2V0PlwidVwiKXJldHVybjtsZXQgdD1uZXcgV2ViU29ja2V0KHJlKCkpO3JldHVybiB0LmFkZEV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsYXN5bmMgZnVuY3Rpb24obyl7bGV0IHI9SlNPTi5wYXJzZShvLmRhdGEpO2lmKHIudHlwZT09PVwidXBkYXRlXCImJmF3YWl0IGUoci5hc3NldHMpLHIudHlwZT09PVwiZXJyb3JcIilmb3IobGV0IG4gb2Ygci5kaWFnbm9zdGljcy5hbnNpKXtsZXQgcz1uLmNvZGVmcmFtZXx8bi5zdGFjaztBKFwiW3BsYXNtby9wYXJjZWwtcnVudGltZV06IFwiK24ubWVzc2FnZStgXG5gK3MrYFxuXG5gK24uaGludHMuam9pbihgXG5gKSl9fSksdC5hZGRFdmVudExpc3RlbmVyKFwiZXJyb3JcIixuZSksdC5hZGRFdmVudExpc3RlbmVyKFwib3BlblwiLCgpPT57ayhgW3BsYXNtby9wYXJjZWwtcnVudGltZV06IENvbm5lY3RlZCB0byBITVIgc2VydmVyIGZvciAke2MuZW50cnlGaWxlUGF0aH1gKX0pLHQuYWRkRXZlbnRMaXN0ZW5lcihcImNsb3NlXCIsKCk9PntBKGBbcGxhc21vL3BhcmNlbC1ydW50aW1lXTogQ29ubmVjdGlvbiB0byB0aGUgSE1SIHNlcnZlciBpcyBjbG9zZWQgZm9yICR7Yy5lbnRyeUZpbGVQYXRofWApfSksdH12YXIgaj16KHJlcXVpcmUoXCJyZWFjdC1yZWZyZXNoL3J1bnRpbWVcIikpO2FzeW5jIGZ1bmN0aW9uIEYoKXtqLmRlZmF1bHQuaW5qZWN0SW50b0dsb2JhbEhvb2sod2luZG93KSx3aW5kb3cuJFJlZnJlc2hSZWckPWZ1bmN0aW9uKCl7fSx3aW5kb3cuJFJlZnJlc2hTaWckPWZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uKGUpe3JldHVybiBlfX19dmFyIHNlPWAke1N9JHttb2R1bGUuaWR9X19gLGgsVT1tb2R1bGUuYnVuZGxlLnBhcmVudDtpZighVXx8IVUuaXNQYXJjZWxSZXF1aXJlKXt0cnl7aD1kPy5ydW50aW1lLmNvbm5lY3Qoe25hbWU6c2V9KSxoLm9uRGlzY29ubmVjdC5hZGRMaXN0ZW5lcigoKT0+e20oKX0pLGMuaXNSZWFjdHx8aC5vbk1lc3NhZ2UuYWRkTGlzdGVuZXIoKCk9PnttKCl9KX1jYXRjaChlKXtwKGUpfU4oYXN5bmMgZT0+e2lmKHAoXCJQYWdlIHJ1bnRpbWUgLSBPbiBITVIgVXBkYXRlXCIpLGMuaXNSZWFjdCl7QigpO2xldCB0PWUuZmlsdGVyKHI9PnIuZW52SGFzaD09PWMuZW52SGFzaCk7aWYodC5zb21lKHI9PnIudHlwZT09PVwiY3NzXCJ8fHIudHlwZT09PVwianNcIiYmUihtb2R1bGUuYnVuZGxlLnJvb3Qsci5pZCxyLmRlcHNCeUJ1bmRsZSkpKXRyeXthd2FpdCBPKHQpO2xldCByPXt9O2ZvcihsZXRbcyxhXW9mIGkuYXNzZXRzVG9EaXNwb3NlKXJbYV18fCh2KHMsYSksclthXT0hMCk7bGV0IG49e307Zm9yKGxldCBzPTA7czxpLmFzc2V0c1RvQWNjZXB0Lmxlbmd0aDtzKyspe2xldFthLGxdPWkuYXNzZXRzVG9BY2NlcHRbc107bltsXXx8KEkoYSxsKSxuW2xdPSEwKX19Y2F0Y2gocil7Yy52ZXJib3NlPT09XCJ0cnVlXCImJihjb25zb2xlLnRyYWNlKHIpLGFsZXJ0KEpTT04uc3RyaW5naWZ5KHIpKSksYXdhaXQgbSghMCl9fWVsc2V7bGV0IHQ9ZS5maWx0ZXIobz0+by5lbnZIYXNoPT09Yy5lbnZIYXNoKS5zb21lKG89Pk0obW9kdWxlLmJ1bmRsZSxvLmlkKSk7cChcIlBhZ2UgcnVudGltZSAtXCIse3NvdXJjZUNoYW5nZWQ6dH0pLHQmJmgucG9zdE1lc3NhZ2Uoe19fcGxhc21vX3BhZ2VfY2hhbmdlZF9fOiEwfSl9fSl9Yy5pc1JlYWN0JiYocChcIkluamVjdGluZyByZWFjdCByZWZyZXNoXCIpLEYoKSk7XG4iLCJ2YXIgb2U9T2JqZWN0LmNyZWF0ZTt2YXIgSD1PYmplY3QuZGVmaW5lUHJvcGVydHk7dmFyIGFlPU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7dmFyIHVlPU9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzO3ZhciBzZT1PYmplY3QuZ2V0UHJvdG90eXBlT2YsbGU9T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTt2YXIgej0obyxmKT0+KCk9PihmfHxvKChmPXtleHBvcnRzOnt9fSkuZXhwb3J0cyxmKSxmLmV4cG9ydHMpLGNlPShvLGYpPT57Zm9yKHZhciBzIGluIGYpSChvLHMse2dldDpmW3NdLGVudW1lcmFibGU6ITB9KX0sRD0obyxmLHMseSk9PntpZihmJiZ0eXBlb2YgZj09XCJvYmplY3RcInx8dHlwZW9mIGY9PVwiZnVuY3Rpb25cIilmb3IobGV0IG0gb2YgdWUoZikpIWxlLmNhbGwobyxtKSYmbSE9PXMmJkgobyxtLHtnZXQ6KCk9PmZbbV0sZW51bWVyYWJsZTohKHk9YWUoZixtKSl8fHkuZW51bWVyYWJsZX0pO3JldHVybiBvfSxTPShvLGYscyk9PihEKG8sZixcImRlZmF1bHRcIikscyYmRChzLGYsXCJkZWZhdWx0XCIpKSxHPShvLGYscyk9PihzPW8hPW51bGw/b2Uoc2UobykpOnt9LEQoZnx8IW98fCFvLl9fZXNNb2R1bGU/SChzLFwiZGVmYXVsdFwiLHt2YWx1ZTpvLGVudW1lcmFibGU6ITB9KTpzLG8pKSxkZT1vPT5EKEgoe30sXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSksbyk7dmFyIE49eihoPT57XCJ1c2Ugc3RyaWN0XCI7KGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIG89U3ltYm9sLmZvcihcInJlYWN0LmZvcndhcmRfcmVmXCIpLGY9U3ltYm9sLmZvcihcInJlYWN0Lm1lbW9cIikscz10eXBlb2YgV2Vha01hcD09XCJmdW5jdGlvblwiP1dlYWtNYXA6TWFwLHk9bmV3IE1hcCxtPW5ldyBzLGI9bmV3IHMsaj1uZXcgcyxFPVtdLEM9bmV3IE1hcCxPPW5ldyBNYXAscD1uZXcgU2V0LF89bmV3IFNldCxGPXR5cGVvZiBXZWFrTWFwPT1cImZ1bmN0aW9uXCI/bmV3IFdlYWtNYXA6bnVsbCxUPSExO2Z1bmN0aW9uIEIoZSl7aWYoZS5mdWxsS2V5IT09bnVsbClyZXR1cm4gZS5mdWxsS2V5O3ZhciByPWUub3duS2V5LG47dHJ5e249ZS5nZXRDdXN0b21Ib29rcygpfWNhdGNoKGkpe3JldHVybiBlLmZvcmNlUmVzZXQ9ITAsZS5mdWxsS2V5PXIscn1mb3IodmFyIHQ9MDt0PG4ubGVuZ3RoO3QrKyl7dmFyIGw9blt0XTtpZih0eXBlb2YgbCE9XCJmdW5jdGlvblwiKXJldHVybiBlLmZvcmNlUmVzZXQ9ITAsZS5mdWxsS2V5PXIscjt2YXIgZD1iLmdldChsKTtpZihkIT09dm9pZCAwKXt2YXIgYT1CKGQpO2QuZm9yY2VSZXNldCYmKGUuZm9yY2VSZXNldD0hMCkscis9YFxuLS0tXG5gK2F9fXJldHVybiBlLmZ1bGxLZXk9cixyfWZ1bmN0aW9uIHEoZSxyKXt2YXIgbj1iLmdldChlKSx0PWIuZ2V0KHIpO3JldHVybiBuPT09dm9pZCAwJiZ0PT09dm9pZCAwPyEwOiEobj09PXZvaWQgMHx8dD09PXZvaWQgMHx8QihuKSE9PUIodCl8fHQuZm9yY2VSZXNldCl9ZnVuY3Rpb24gJChlKXtyZXR1cm4gZS5wcm90b3R5cGUmJmUucHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnR9ZnVuY3Rpb24gayhlLHIpe3JldHVybiAkKGUpfHwkKHIpPyExOiEhcShlLHIpfWZ1bmN0aW9uIFkoZSl7cmV0dXJuIGouZ2V0KGUpfWZ1bmN0aW9uIFooZSl7dmFyIHI9bmV3IE1hcDtyZXR1cm4gZS5mb3JFYWNoKGZ1bmN0aW9uKG4sdCl7ci5zZXQodCxuKX0pLHJ9ZnVuY3Rpb24gVyhlKXt2YXIgcj1uZXcgU2V0O3JldHVybiBlLmZvckVhY2goZnVuY3Rpb24obil7ci5hZGQobil9KSxyfWZ1bmN0aW9uIE0oZSxyKXt0cnl7cmV0dXJuIGVbcl19Y2F0Y2gobil7cmV0dXJufX1mdW5jdGlvbiBKKCl7aWYoRS5sZW5ndGg9PT0wfHxUKXJldHVybiBudWxsO1Q9ITA7dHJ5e3ZhciBlPW5ldyBTZXQscj1uZXcgU2V0LG49RTtFPVtdLG4uZm9yRWFjaChmdW5jdGlvbih1KXt2YXIgYz11WzBdLHY9dVsxXSxSPWMuY3VycmVudDtqLnNldChSLGMpLGouc2V0KHYsYyksYy5jdXJyZW50PXYsayhSLHYpP3IuYWRkKGMpOmUuYWRkKGMpfSk7dmFyIHQ9e3VwZGF0ZWRGYW1pbGllczpyLHN0YWxlRmFtaWxpZXM6ZX07Qy5mb3JFYWNoKGZ1bmN0aW9uKHUpe3Uuc2V0UmVmcmVzaEhhbmRsZXIoWSl9KTt2YXIgbD0hMSxkPW51bGwsYT1XKF8pLGk9VyhwKSxnPVooTyk7aWYoYS5mb3JFYWNoKGZ1bmN0aW9uKHUpe3ZhciBjPWcuZ2V0KHUpO2lmKGM9PT12b2lkIDApdGhyb3cgbmV3IEVycm9yKFwiQ291bGQgbm90IGZpbmQgaGVscGVycyBmb3IgYSByb290LiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0IFJlZnJlc2guXCIpO2lmKF8uaGFzKHUpLEYhPT1udWxsJiZGLmhhcyh1KSl7dmFyIHY9Ri5nZXQodSk7dHJ5e2Muc2NoZWR1bGVSb290KHUsdil9Y2F0Y2goUil7bHx8KGw9ITAsZD1SKX19fSksaS5mb3JFYWNoKGZ1bmN0aW9uKHUpe3ZhciBjPWcuZ2V0KHUpO2lmKGM9PT12b2lkIDApdGhyb3cgbmV3IEVycm9yKFwiQ291bGQgbm90IGZpbmQgaGVscGVycyBmb3IgYSByb290LiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0IFJlZnJlc2guXCIpO3AuaGFzKHUpO3RyeXtjLnNjaGVkdWxlUmVmcmVzaCh1LHQpfWNhdGNoKHYpe2x8fChsPSEwLGQ9dil9fSksbCl0aHJvdyBkO3JldHVybiB0fWZpbmFsbHl7VD0hMX19ZnVuY3Rpb24gUChlLHIpe3tpZihlPT09bnVsbHx8dHlwZW9mIGUhPVwiZnVuY3Rpb25cIiYmdHlwZW9mIGUhPVwib2JqZWN0XCJ8fG0uaGFzKGUpKXJldHVybjt2YXIgbj15LmdldChyKTtpZihuPT09dm9pZCAwPyhuPXtjdXJyZW50OmV9LHkuc2V0KHIsbikpOkUucHVzaChbbixlXSksbS5zZXQoZSxuKSx0eXBlb2YgZT09XCJvYmplY3RcIiYmZSE9PW51bGwpc3dpdGNoKE0oZSxcIiQkdHlwZW9mXCIpKXtjYXNlIG86UChlLnJlbmRlcixyK1wiJHJlbmRlclwiKTticmVhaztjYXNlIGY6UChlLnR5cGUscitcIiR0eXBlXCIpO2JyZWFrfX19ZnVuY3Rpb24gSyhlLHIpe3ZhciBuPWFyZ3VtZW50cy5sZW5ndGg+MiYmYXJndW1lbnRzWzJdIT09dm9pZCAwP2FyZ3VtZW50c1syXTohMSx0PWFyZ3VtZW50cy5sZW5ndGg+Mz9hcmd1bWVudHNbM106dm9pZCAwO2lmKGIuaGFzKGUpfHxiLnNldChlLHtmb3JjZVJlc2V0Om4sb3duS2V5OnIsZnVsbEtleTpudWxsLGdldEN1c3RvbUhvb2tzOnR8fGZ1bmN0aW9uKCl7cmV0dXJuW119fSksdHlwZW9mIGU9PVwib2JqZWN0XCImJmUhPT1udWxsKXN3aXRjaChNKGUsXCIkJHR5cGVvZlwiKSl7Y2FzZSBvOksoZS5yZW5kZXIscixuLHQpO2JyZWFrO2Nhc2UgZjpLKGUudHlwZSxyLG4sdCk7YnJlYWt9fWZ1bmN0aW9uIHgoZSl7e3ZhciByPWIuZ2V0KGUpO3IhPT12b2lkIDAmJkIocil9fWZ1bmN0aW9uIFEoZSl7cmV0dXJuIHkuZ2V0KGUpfWZ1bmN0aW9uIFgoZSl7cmV0dXJuIG0uZ2V0KGUpfWZ1bmN0aW9uIGVlKGUpe3t2YXIgcj1uZXcgU2V0O3JldHVybiBwLmZvckVhY2goZnVuY3Rpb24obil7dmFyIHQ9Ty5nZXQobik7aWYodD09PXZvaWQgMCl0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgZmluZCBoZWxwZXJzIGZvciBhIHJvb3QuIFRoaXMgaXMgYSBidWcgaW4gUmVhY3QgUmVmcmVzaC5cIik7dmFyIGw9dC5maW5kSG9zdEluc3RhbmNlc0ZvclJlZnJlc2gobixlKTtsLmZvckVhY2goZnVuY3Rpb24oZCl7ci5hZGQoZCl9KX0pLHJ9fWZ1bmN0aW9uIHJlKGUpe3t2YXIgcj1lLl9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXztpZihyPT09dm9pZCAwKXt2YXIgbj0wO2UuX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fPXI9e3JlbmRlcmVyczpuZXcgTWFwLHN1cHBvcnRzRmliZXI6ITAsaW5qZWN0OmZ1bmN0aW9uKGEpe3JldHVybiBuKyt9LG9uU2NoZWR1bGVGaWJlclJvb3Q6ZnVuY3Rpb24oYSxpLGcpe30sb25Db21taXRGaWJlclJvb3Q6ZnVuY3Rpb24oYSxpLGcsdSl7fSxvbkNvbW1pdEZpYmVyVW5tb3VudDpmdW5jdGlvbigpe319fWlmKHIuaXNEaXNhYmxlZCl7Y29uc29sZS53YXJuKFwiU29tZXRoaW5nIGhhcyBzaGltbWVkIHRoZSBSZWFjdCBEZXZUb29scyBnbG9iYWwgaG9vayAoX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fKS4gRmFzdCBSZWZyZXNoIGlzIG5vdCBjb21wYXRpYmxlIHdpdGggdGhpcyBzaGltIGFuZCB3aWxsIGJlIGRpc2FibGVkLlwiKTtyZXR1cm59dmFyIHQ9ci5pbmplY3Q7ci5pbmplY3Q9ZnVuY3Rpb24oYSl7dmFyIGk9dC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7cmV0dXJuIHR5cGVvZiBhLnNjaGVkdWxlUmVmcmVzaD09XCJmdW5jdGlvblwiJiZ0eXBlb2YgYS5zZXRSZWZyZXNoSGFuZGxlcj09XCJmdW5jdGlvblwiJiZDLnNldChpLGEpLGl9LHIucmVuZGVyZXJzLmZvckVhY2goZnVuY3Rpb24oYSxpKXt0eXBlb2YgYS5zY2hlZHVsZVJlZnJlc2g9PVwiZnVuY3Rpb25cIiYmdHlwZW9mIGEuc2V0UmVmcmVzaEhhbmRsZXI9PVwiZnVuY3Rpb25cIiYmQy5zZXQoaSxhKX0pO3ZhciBsPXIub25Db21taXRGaWJlclJvb3QsZD1yLm9uU2NoZWR1bGVGaWJlclJvb3R8fGZ1bmN0aW9uKCl7fTtyLm9uU2NoZWR1bGVGaWJlclJvb3Q9ZnVuY3Rpb24oYSxpLGcpe3JldHVybiBUfHwoXy5kZWxldGUoaSksRiE9PW51bGwmJkYuc2V0KGksZykpLGQuYXBwbHkodGhpcyxhcmd1bWVudHMpfSxyLm9uQ29tbWl0RmliZXJSb290PWZ1bmN0aW9uKGEsaSxnLHUpe3ZhciBjPUMuZ2V0KGEpO2lmKGMhPT12b2lkIDApe08uc2V0KGksYyk7dmFyIHY9aS5jdXJyZW50LFI9di5hbHRlcm5hdGU7aWYoUiE9PW51bGwpe3ZhciBMPVIubWVtb2l6ZWRTdGF0ZSE9bnVsbCYmUi5tZW1vaXplZFN0YXRlLmVsZW1lbnQhPW51bGwmJnAuaGFzKGkpLEE9di5tZW1vaXplZFN0YXRlIT1udWxsJiZ2Lm1lbW9pemVkU3RhdGUuZWxlbWVudCE9bnVsbDshTCYmQT8ocC5hZGQoaSksXy5kZWxldGUoaSkpOkwmJkF8fChMJiYhQT8ocC5kZWxldGUoaSksdT9fLmFkZChpKTpPLmRlbGV0ZShpKSk6IUwmJiFBJiZ1JiZfLmFkZChpKSl9ZWxzZSBwLmFkZChpKX1yZXR1cm4gbC5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fX1mdW5jdGlvbiBuZSgpe3JldHVybiExfWZ1bmN0aW9uIHRlKCl7cmV0dXJuIHAuc2l6ZX1mdW5jdGlvbiBmZSgpe3t2YXIgZSxyLG49ITE7cmV0dXJuIGZ1bmN0aW9uKHQsbCxkLGEpe2lmKHR5cGVvZiBsPT1cInN0cmluZ1wiKXJldHVybiBlfHwoZT10LHI9dHlwZW9mIGE9PVwiZnVuY3Rpb25cIiksdCE9bnVsbCYmKHR5cGVvZiB0PT1cImZ1bmN0aW9uXCJ8fHR5cGVvZiB0PT1cIm9iamVjdFwiKSYmSyh0LGwsZCxhKSx0OyFuJiZyJiYobj0hMCx4KGUpKX19fWZ1bmN0aW9uIGllKGUpe3N3aXRjaCh0eXBlb2YgZSl7Y2FzZVwiZnVuY3Rpb25cIjp7aWYoZS5wcm90b3R5cGUhPW51bGwpe2lmKGUucHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnQpcmV0dXJuITA7dmFyIHI9T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoZS5wcm90b3R5cGUpO2lmKHIubGVuZ3RoPjF8fHJbMF0hPT1cImNvbnN0cnVjdG9yXCJ8fGUucHJvdG90eXBlLl9fcHJvdG9fXyE9PU9iamVjdC5wcm90b3R5cGUpcmV0dXJuITF9dmFyIG49ZS5uYW1lfHxlLmRpc3BsYXlOYW1lO3JldHVybiB0eXBlb2Ygbj09XCJzdHJpbmdcIiYmL15bQS1aXS8udGVzdChuKX1jYXNlXCJvYmplY3RcIjp7aWYoZSE9bnVsbClzd2l0Y2goTShlLFwiJCR0eXBlb2ZcIikpe2Nhc2UgbzpjYXNlIGY6cmV0dXJuITA7ZGVmYXVsdDpyZXR1cm4hMX1yZXR1cm4hMX1kZWZhdWx0OnJldHVybiExfX1oLl9nZXRNb3VudGVkUm9vdENvdW50PXRlLGguY29sbGVjdEN1c3RvbUhvb2tzRm9yU2lnbmF0dXJlPXgsaC5jcmVhdGVTaWduYXR1cmVGdW5jdGlvbkZvclRyYW5zZm9ybT1mZSxoLmZpbmRBZmZlY3RlZEhvc3RJbnN0YW5jZXM9ZWUsaC5nZXRGYW1pbHlCeUlEPVEsaC5nZXRGYW1pbHlCeVR5cGU9WCxoLmhhc1VucmVjb3ZlcmFibGVFcnJvcnM9bmUsaC5pbmplY3RJbnRvR2xvYmFsSG9vaz1yZSxoLmlzTGlrZWx5Q29tcG9uZW50VHlwZT1pZSxoLnBlcmZvcm1SZWFjdFJlZnJlc2g9SixoLnJlZ2lzdGVyPVAsaC5zZXRTaWduYXR1cmU9S30pKCl9KTt2YXIgST16KChwZSxWKT0+e1widXNlIHN0cmljdFwiO1YuZXhwb3J0cz1OKCl9KTt2YXIgdz17fTtjZSh3LHtkZWZhdWx0OigpPT5oZX0pO21vZHVsZS5leHBvcnRzPWRlKHcpO3ZhciBVPUcoSSgpKTtTKHcsRyhJKCkpLG1vZHVsZS5leHBvcnRzKTt2YXIgaGU9VS5kZWZhdWx0O1xuLyohIEJ1bmRsZWQgbGljZW5zZSBpbmZvcm1hdGlvbjpcblxucmVhY3QtcmVmcmVzaC9janMvcmVhY3QtcmVmcmVzaC1ydW50aW1lLmRldmVsb3BtZW50LmpzOlxuICAoKipcbiAgICogQGxpY2Vuc2UgUmVhY3RcbiAgICogcmVhY3QtcmVmcmVzaC1ydW50aW1lLmRldmVsb3BtZW50LmpzXG4gICAqXG4gICAqIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLlxuICAgKlxuICAgKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAgICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICAgKilcbiovXG4iLCJpbXBvcnQgUmVhY3QgZnJvbSBcInJlYWN0XCJcbmltcG9ydCB7IGNyZWF0ZVJvb3QgfSBmcm9tIFwicmVhY3QtZG9tL2NsaWVudFwiXG5cbmltcG9ydCB7IGdldExheW91dCB9IGZyb20gXCJAcGxhc21vLXN0YXRpYy1jb21tb24vcmVhY3RcIlxuXG4vLyBAdHMtaWdub3JlXG5pbXBvcnQgKiBhcyBDb21wb25lbnQgZnJvbSBcIi4uLy4uL3BvcHVwLnRzeFwiXG5cbmxldCBfX3BsYXNtb1Jvb3Q6IEhUTUxFbGVtZW50ID0gbnVsbFxuXG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCAoKSA9PiB7XG4gIGlmICghIV9fcGxhc21vUm9vdCkge1xuICAgIHJldHVyblxuICB9XG5cbiAgX19wbGFzbW9Sb290ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJfX3BsYXNtb1wiKVxuXG4gIGNvbnN0IHJvb3QgPSBjcmVhdGVSb290KF9fcGxhc21vUm9vdClcblxuICBjb25zdCBMYXlvdXQgPSBnZXRMYXlvdXQoQ29tcG9uZW50KVxuXG4gIHJvb3QucmVuZGVyKFxuICAgIDxMYXlvdXQ+XG4gICAgICA8Q29tcG9uZW50LmRlZmF1bHQgLz5cbiAgICA8L0xheW91dD5cbiAgKVxufSlcbiIsIid1c2Ugc3RyaWN0JztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC1qc3gtZGV2LXJ1bnRpbWUucHJvZHVjdGlvbi5taW4uanMnKTtcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9janMvcmVhY3QtanN4LWRldi1ydW50aW1lLmRldmVsb3BtZW50LmpzJyk7XG59XG4iLCIvKipcbiAqIEBsaWNlbnNlIFJlYWN0XG4gKiByZWFjdC1qc3gtZGV2LXJ1bnRpbWUuZGV2ZWxvcG1lbnQuanNcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIEZhY2Vib29rLCBJbmMuIGFuZCBpdHMgYWZmaWxpYXRlcy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgKGZ1bmN0aW9uKCkge1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG4vLyBBVFRFTlRJT05cbi8vIFdoZW4gYWRkaW5nIG5ldyBzeW1ib2xzIHRvIHRoaXMgZmlsZSxcbi8vIFBsZWFzZSBjb25zaWRlciBhbHNvIGFkZGluZyB0byAncmVhY3QtZGV2dG9vbHMtc2hhcmVkL3NyYy9iYWNrZW5kL1JlYWN0U3ltYm9scydcbi8vIFRoZSBTeW1ib2wgdXNlZCB0byB0YWcgdGhlIFJlYWN0RWxlbWVudC1saWtlIHR5cGVzLlxudmFyIFJFQUNUX0VMRU1FTlRfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LmVsZW1lbnQnKTtcbnZhciBSRUFDVF9QT1JUQUxfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnBvcnRhbCcpO1xudmFyIFJFQUNUX0ZSQUdNRU5UX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5mcmFnbWVudCcpO1xudmFyIFJFQUNUX1NUUklDVF9NT0RFX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5zdHJpY3RfbW9kZScpO1xudmFyIFJFQUNUX1BST0ZJTEVSX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5wcm9maWxlcicpO1xudmFyIFJFQUNUX1BST1ZJREVSX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5wcm92aWRlcicpO1xudmFyIFJFQUNUX0NPTlRFWFRfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LmNvbnRleHQnKTtcbnZhciBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QuZm9yd2FyZF9yZWYnKTtcbnZhciBSRUFDVF9TVVNQRU5TRV9UWVBFID0gU3ltYm9sLmZvcigncmVhY3Quc3VzcGVuc2UnKTtcbnZhciBSRUFDVF9TVVNQRU5TRV9MSVNUX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5zdXNwZW5zZV9saXN0Jyk7XG52YXIgUkVBQ1RfTUVNT19UWVBFID0gU3ltYm9sLmZvcigncmVhY3QubWVtbycpO1xudmFyIFJFQUNUX0xBWllfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LmxhenknKTtcbnZhciBSRUFDVF9PRkZTQ1JFRU5fVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0Lm9mZnNjcmVlbicpO1xudmFyIE1BWUJFX0lURVJBVE9SX1NZTUJPTCA9IFN5bWJvbC5pdGVyYXRvcjtcbnZhciBGQVVYX0lURVJBVE9SX1NZTUJPTCA9ICdAQGl0ZXJhdG9yJztcbmZ1bmN0aW9uIGdldEl0ZXJhdG9yRm4obWF5YmVJdGVyYWJsZSkge1xuICBpZiAobWF5YmVJdGVyYWJsZSA9PT0gbnVsbCB8fCB0eXBlb2YgbWF5YmVJdGVyYWJsZSAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBtYXliZUl0ZXJhdG9yID0gTUFZQkVfSVRFUkFUT1JfU1lNQk9MICYmIG1heWJlSXRlcmFibGVbTUFZQkVfSVRFUkFUT1JfU1lNQk9MXSB8fCBtYXliZUl0ZXJhYmxlW0ZBVVhfSVRFUkFUT1JfU1lNQk9MXTtcblxuICBpZiAodHlwZW9mIG1heWJlSXRlcmF0b3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gbWF5YmVJdGVyYXRvcjtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG52YXIgUmVhY3RTaGFyZWRJbnRlcm5hbHMgPSBSZWFjdC5fX1NFQ1JFVF9JTlRFUk5BTFNfRE9fTk9UX1VTRV9PUl9ZT1VfV0lMTF9CRV9GSVJFRDtcblxuZnVuY3Rpb24gZXJyb3IoZm9ybWF0KSB7XG4gIHtcbiAgICB7XG4gICAgICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjIgPiAxID8gX2xlbjIgLSAxIDogMCksIF9rZXkyID0gMTsgX2tleTIgPCBfbGVuMjsgX2tleTIrKykge1xuICAgICAgICBhcmdzW19rZXkyIC0gMV0gPSBhcmd1bWVudHNbX2tleTJdO1xuICAgICAgfVxuXG4gICAgICBwcmludFdhcm5pbmcoJ2Vycm9yJywgZm9ybWF0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJpbnRXYXJuaW5nKGxldmVsLCBmb3JtYXQsIGFyZ3MpIHtcbiAgLy8gV2hlbiBjaGFuZ2luZyB0aGlzIGxvZ2ljLCB5b3UgbWlnaHQgd2FudCB0byBhbHNvXG4gIC8vIHVwZGF0ZSBjb25zb2xlV2l0aFN0YWNrRGV2Lnd3dy5qcyBhcyB3ZWxsLlxuICB7XG4gICAgdmFyIFJlYWN0RGVidWdDdXJyZW50RnJhbWUgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdERlYnVnQ3VycmVudEZyYW1lO1xuICAgIHZhciBzdGFjayA9IFJlYWN0RGVidWdDdXJyZW50RnJhbWUuZ2V0U3RhY2tBZGRlbmR1bSgpO1xuXG4gICAgaWYgKHN0YWNrICE9PSAnJykge1xuICAgICAgZm9ybWF0ICs9ICclcyc7XG4gICAgICBhcmdzID0gYXJncy5jb25jYXQoW3N0YWNrXSk7XG4gICAgfSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvc2FmZS1zdHJpbmctY29lcmNpb25cblxuXG4gICAgdmFyIGFyZ3NXaXRoRm9ybWF0ID0gYXJncy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBTdHJpbmcoaXRlbSk7XG4gICAgfSk7IC8vIENhcmVmdWw6IFJOIGN1cnJlbnRseSBkZXBlbmRzIG9uIHRoaXMgcHJlZml4XG5cbiAgICBhcmdzV2l0aEZvcm1hdC51bnNoaWZ0KCdXYXJuaW5nOiAnICsgZm9ybWF0KTsgLy8gV2UgaW50ZW50aW9uYWxseSBkb24ndCB1c2Ugc3ByZWFkIChvciAuYXBwbHkpIGRpcmVjdGx5IGJlY2F1c2UgaXRcbiAgICAvLyBicmVha3MgSUU5OiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzEzNjEwXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZ1xuXG4gICAgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoY29uc29sZVtsZXZlbF0sIGNvbnNvbGUsIGFyZ3NXaXRoRm9ybWF0KTtcbiAgfVxufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG52YXIgZW5hYmxlU2NvcGVBUEkgPSBmYWxzZTsgLy8gRXhwZXJpbWVudGFsIENyZWF0ZSBFdmVudCBIYW5kbGUgQVBJLlxudmFyIGVuYWJsZUNhY2hlRWxlbWVudCA9IGZhbHNlO1xudmFyIGVuYWJsZVRyYW5zaXRpb25UcmFjaW5nID0gZmFsc2U7IC8vIE5vIGtub3duIGJ1Z3MsIGJ1dCBuZWVkcyBwZXJmb3JtYW5jZSB0ZXN0aW5nXG5cbnZhciBlbmFibGVMZWdhY3lIaWRkZW4gPSBmYWxzZTsgLy8gRW5hYmxlcyB1bnN0YWJsZV9hdm9pZFRoaXNGYWxsYmFjayBmZWF0dXJlIGluIEZpYmVyXG4vLyBzdHVmZi4gSW50ZW5kZWQgdG8gZW5hYmxlIFJlYWN0IGNvcmUgbWVtYmVycyB0byBtb3JlIGVhc2lseSBkZWJ1ZyBzY2hlZHVsaW5nXG4vLyBpc3N1ZXMgaW4gREVWIGJ1aWxkcy5cblxudmFyIGVuYWJsZURlYnVnVHJhY2luZyA9IGZhbHNlOyAvLyBUcmFjayB3aGljaCBGaWJlcihzKSBzY2hlZHVsZSByZW5kZXIgd29yay5cblxudmFyIFJFQUNUX01PRFVMRV9SRUZFUkVOQ0U7XG5cbntcbiAgUkVBQ1RfTU9EVUxFX1JFRkVSRU5DRSA9IFN5bWJvbC5mb3IoJ3JlYWN0Lm1vZHVsZS5yZWZlcmVuY2UnKTtcbn1cblxuZnVuY3Rpb24gaXNWYWxpZEVsZW1lbnRUeXBlKHR5cGUpIHtcbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9IC8vIE5vdGU6IHR5cGVvZiBtaWdodCBiZSBvdGhlciB0aGFuICdzeW1ib2wnIG9yICdudW1iZXInIChlLmcuIGlmIGl0J3MgYSBwb2x5ZmlsbCkuXG5cblxuICBpZiAodHlwZSA9PT0gUkVBQ1RfRlJBR01FTlRfVFlQRSB8fCB0eXBlID09PSBSRUFDVF9QUk9GSUxFUl9UWVBFIHx8IGVuYWJsZURlYnVnVHJhY2luZyAgfHwgdHlwZSA9PT0gUkVBQ1RfU1RSSUNUX01PREVfVFlQRSB8fCB0eXBlID09PSBSRUFDVF9TVVNQRU5TRV9UWVBFIHx8IHR5cGUgPT09IFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRSB8fCBlbmFibGVMZWdhY3lIaWRkZW4gIHx8IHR5cGUgPT09IFJFQUNUX09GRlNDUkVFTl9UWVBFIHx8IGVuYWJsZVNjb3BlQVBJICB8fCBlbmFibGVDYWNoZUVsZW1lbnQgIHx8IGVuYWJsZVRyYW5zaXRpb25UcmFjaW5nICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnb2JqZWN0JyAmJiB0eXBlICE9PSBudWxsKSB7XG4gICAgaWYgKHR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX0xBWllfVFlQRSB8fCB0eXBlLiQkdHlwZW9mID09PSBSRUFDVF9NRU1PX1RZUEUgfHwgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfUFJPVklERVJfVFlQRSB8fCB0eXBlLiQkdHlwZW9mID09PSBSRUFDVF9DT05URVhUX1RZUEUgfHwgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRSB8fCAvLyBUaGlzIG5lZWRzIHRvIGluY2x1ZGUgYWxsIHBvc3NpYmxlIG1vZHVsZSByZWZlcmVuY2Ugb2JqZWN0XG4gICAgLy8gdHlwZXMgc3VwcG9ydGVkIGJ5IGFueSBGbGlnaHQgY29uZmlndXJhdGlvbiBhbnl3aGVyZSBzaW5jZVxuICAgIC8vIHdlIGRvbid0IGtub3cgd2hpY2ggRmxpZ2h0IGJ1aWxkIHRoaXMgd2lsbCBlbmQgdXAgYmVpbmcgdXNlZFxuICAgIC8vIHdpdGguXG4gICAgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfTU9EVUxFX1JFRkVSRU5DRSB8fCB0eXBlLmdldE1vZHVsZUlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gZ2V0V3JhcHBlZE5hbWUob3V0ZXJUeXBlLCBpbm5lclR5cGUsIHdyYXBwZXJOYW1lKSB7XG4gIHZhciBkaXNwbGF5TmFtZSA9IG91dGVyVHlwZS5kaXNwbGF5TmFtZTtcblxuICBpZiAoZGlzcGxheU5hbWUpIHtcbiAgICByZXR1cm4gZGlzcGxheU5hbWU7XG4gIH1cblxuICB2YXIgZnVuY3Rpb25OYW1lID0gaW5uZXJUeXBlLmRpc3BsYXlOYW1lIHx8IGlubmVyVHlwZS5uYW1lIHx8ICcnO1xuICByZXR1cm4gZnVuY3Rpb25OYW1lICE9PSAnJyA/IHdyYXBwZXJOYW1lICsgXCIoXCIgKyBmdW5jdGlvbk5hbWUgKyBcIilcIiA6IHdyYXBwZXJOYW1lO1xufSAvLyBLZWVwIGluIHN5bmMgd2l0aCByZWFjdC1yZWNvbmNpbGVyL2dldENvbXBvbmVudE5hbWVGcm9tRmliZXJcblxuXG5mdW5jdGlvbiBnZXRDb250ZXh0TmFtZSh0eXBlKSB7XG4gIHJldHVybiB0eXBlLmRpc3BsYXlOYW1lIHx8ICdDb250ZXh0Jztcbn0gLy8gTm90ZSB0aGF0IHRoZSByZWNvbmNpbGVyIHBhY2thZ2Ugc2hvdWxkIGdlbmVyYWxseSBwcmVmZXIgdG8gdXNlIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoKSBpbnN0ZWFkLlxuXG5cbmZ1bmN0aW9uIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSh0eXBlKSB7XG4gIGlmICh0eXBlID09IG51bGwpIHtcbiAgICAvLyBIb3N0IHJvb3QsIHRleHQgbm9kZSBvciBqdXN0IGludmFsaWQgdHlwZS5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHtcbiAgICBpZiAodHlwZW9mIHR5cGUudGFnID09PSAnbnVtYmVyJykge1xuICAgICAgZXJyb3IoJ1JlY2VpdmVkIGFuIHVuZXhwZWN0ZWQgb2JqZWN0IGluIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSgpLiAnICsgJ1RoaXMgaXMgbGlrZWx5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gdHlwZS5kaXNwbGF5TmFtZSB8fCB0eXBlLm5hbWUgfHwgbnVsbDtcbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdHlwZTtcbiAgfVxuXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgUkVBQ1RfRlJBR01FTlRfVFlQRTpcbiAgICAgIHJldHVybiAnRnJhZ21lbnQnO1xuXG4gICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgIHJldHVybiAnUG9ydGFsJztcblxuICAgIGNhc2UgUkVBQ1RfUFJPRklMRVJfVFlQRTpcbiAgICAgIHJldHVybiAnUHJvZmlsZXInO1xuXG4gICAgY2FzZSBSRUFDVF9TVFJJQ1RfTU9ERV9UWVBFOlxuICAgICAgcmV0dXJuICdTdHJpY3RNb2RlJztcblxuICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfVFlQRTpcbiAgICAgIHJldHVybiAnU3VzcGVuc2UnO1xuXG4gICAgY2FzZSBSRUFDVF9TVVNQRU5TRV9MSVNUX1RZUEU6XG4gICAgICByZXR1cm4gJ1N1c3BlbnNlTGlzdCc7XG5cbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICBzd2l0Y2ggKHR5cGUuJCR0eXBlb2YpIHtcbiAgICAgIGNhc2UgUkVBQ1RfQ09OVEVYVF9UWVBFOlxuICAgICAgICB2YXIgY29udGV4dCA9IHR5cGU7XG4gICAgICAgIHJldHVybiBnZXRDb250ZXh0TmFtZShjb250ZXh0KSArICcuQ29uc3VtZXInO1xuXG4gICAgICBjYXNlIFJFQUNUX1BST1ZJREVSX1RZUEU6XG4gICAgICAgIHZhciBwcm92aWRlciA9IHR5cGU7XG4gICAgICAgIHJldHVybiBnZXRDb250ZXh0TmFtZShwcm92aWRlci5fY29udGV4dCkgKyAnLlByb3ZpZGVyJztcblxuICAgICAgY2FzZSBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFOlxuICAgICAgICByZXR1cm4gZ2V0V3JhcHBlZE5hbWUodHlwZSwgdHlwZS5yZW5kZXIsICdGb3J3YXJkUmVmJyk7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTUVNT19UWVBFOlxuICAgICAgICB2YXIgb3V0ZXJOYW1lID0gdHlwZS5kaXNwbGF5TmFtZSB8fCBudWxsO1xuXG4gICAgICAgIGlmIChvdXRlck5hbWUgIT09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gb3V0ZXJOYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSh0eXBlLnR5cGUpIHx8ICdNZW1vJztcblxuICAgICAgY2FzZSBSRUFDVF9MQVpZX1RZUEU6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgbGF6eUNvbXBvbmVudCA9IHR5cGU7XG4gICAgICAgICAgdmFyIHBheWxvYWQgPSBsYXp5Q29tcG9uZW50Ll9wYXlsb2FkO1xuICAgICAgICAgIHZhciBpbml0ID0gbGF6eUNvbXBvbmVudC5faW5pdDtcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGluaXQocGF5bG9hZCkpO1xuICAgICAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZmFsbHRocm91Z2hcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxudmFyIGFzc2lnbiA9IE9iamVjdC5hc3NpZ247XG5cbi8vIEhlbHBlcnMgdG8gcGF0Y2ggY29uc29sZS5sb2dzIHRvIGF2b2lkIGxvZ2dpbmcgZHVyaW5nIHNpZGUtZWZmZWN0IGZyZWVcbi8vIHJlcGxheWluZyBvbiByZW5kZXIgZnVuY3Rpb24uIFRoaXMgY3VycmVudGx5IG9ubHkgcGF0Y2hlcyB0aGUgb2JqZWN0XG4vLyBsYXppbHkgd2hpY2ggd29uJ3QgY292ZXIgaWYgdGhlIGxvZyBmdW5jdGlvbiB3YXMgZXh0cmFjdGVkIGVhZ2VybHkuXG4vLyBXZSBjb3VsZCBhbHNvIGVhZ2VybHkgcGF0Y2ggdGhlIG1ldGhvZC5cbnZhciBkaXNhYmxlZERlcHRoID0gMDtcbnZhciBwcmV2TG9nO1xudmFyIHByZXZJbmZvO1xudmFyIHByZXZXYXJuO1xudmFyIHByZXZFcnJvcjtcbnZhciBwcmV2R3JvdXA7XG52YXIgcHJldkdyb3VwQ29sbGFwc2VkO1xudmFyIHByZXZHcm91cEVuZDtcblxuZnVuY3Rpb24gZGlzYWJsZWRMb2coKSB7fVxuXG5kaXNhYmxlZExvZy5fX3JlYWN0RGlzYWJsZWRMb2cgPSB0cnVlO1xuZnVuY3Rpb24gZGlzYWJsZUxvZ3MoKSB7XG4gIHtcbiAgICBpZiAoZGlzYWJsZWREZXB0aCA9PT0gMCkge1xuICAgICAgLyogZXNsaW50LWRpc2FibGUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nICovXG4gICAgICBwcmV2TG9nID0gY29uc29sZS5sb2c7XG4gICAgICBwcmV2SW5mbyA9IGNvbnNvbGUuaW5mbztcbiAgICAgIHByZXZXYXJuID0gY29uc29sZS53YXJuO1xuICAgICAgcHJldkVycm9yID0gY29uc29sZS5lcnJvcjtcbiAgICAgIHByZXZHcm91cCA9IGNvbnNvbGUuZ3JvdXA7XG4gICAgICBwcmV2R3JvdXBDb2xsYXBzZWQgPSBjb25zb2xlLmdyb3VwQ29sbGFwc2VkO1xuICAgICAgcHJldkdyb3VwRW5kID0gY29uc29sZS5ncm91cEVuZDsgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xOTA5OVxuXG4gICAgICB2YXIgcHJvcHMgPSB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgdmFsdWU6IGRpc2FibGVkTG9nLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgfTsgLy8gJEZsb3dGaXhNZSBGbG93IHRoaW5rcyBjb25zb2xlIGlzIGltbXV0YWJsZS5cblxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoY29uc29sZSwge1xuICAgICAgICBpbmZvOiBwcm9wcyxcbiAgICAgICAgbG9nOiBwcm9wcyxcbiAgICAgICAgd2FybjogcHJvcHMsXG4gICAgICAgIGVycm9yOiBwcm9wcyxcbiAgICAgICAgZ3JvdXA6IHByb3BzLFxuICAgICAgICBncm91cENvbGxhcHNlZDogcHJvcHMsXG4gICAgICAgIGdyb3VwRW5kOiBwcm9wc1xuICAgICAgfSk7XG4gICAgICAvKiBlc2xpbnQtZW5hYmxlIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZyAqL1xuICAgIH1cblxuICAgIGRpc2FibGVkRGVwdGgrKztcbiAgfVxufVxuZnVuY3Rpb24gcmVlbmFibGVMb2dzKCkge1xuICB7XG4gICAgZGlzYWJsZWREZXB0aC0tO1xuXG4gICAgaWYgKGRpc2FibGVkRGVwdGggPT09IDApIHtcbiAgICAgIC8qIGVzbGludC1kaXNhYmxlIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZyAqL1xuICAgICAgdmFyIHByb3BzID0ge1xuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICB9OyAvLyAkRmxvd0ZpeE1lIEZsb3cgdGhpbmtzIGNvbnNvbGUgaXMgaW1tdXRhYmxlLlxuXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhjb25zb2xlLCB7XG4gICAgICAgIGxvZzogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2TG9nXG4gICAgICAgIH0pLFxuICAgICAgICBpbmZvOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZJbmZvXG4gICAgICAgIH0pLFxuICAgICAgICB3YXJuOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZXYXJuXG4gICAgICAgIH0pLFxuICAgICAgICBlcnJvcjogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2RXJyb3JcbiAgICAgICAgfSksXG4gICAgICAgIGdyb3VwOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZHcm91cFxuICAgICAgICB9KSxcbiAgICAgICAgZ3JvdXBDb2xsYXBzZWQ6IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkdyb3VwQ29sbGFwc2VkXG4gICAgICAgIH0pLFxuICAgICAgICBncm91cEVuZDogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2R3JvdXBFbmRcbiAgICAgICAgfSlcbiAgICAgIH0pO1xuICAgICAgLyogZXNsaW50LWVuYWJsZSByZWFjdC1pbnRlcm5hbC9uby1wcm9kdWN0aW9uLWxvZ2dpbmcgKi9cbiAgICB9XG5cbiAgICBpZiAoZGlzYWJsZWREZXB0aCA8IDApIHtcbiAgICAgIGVycm9yKCdkaXNhYmxlZERlcHRoIGZlbGwgYmVsb3cgemVyby4gJyArICdUaGlzIGlzIGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIFJlYWN0Q3VycmVudERpc3BhdGNoZXIgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnREaXNwYXRjaGVyO1xudmFyIHByZWZpeDtcbmZ1bmN0aW9uIGRlc2NyaWJlQnVpbHRJbkNvbXBvbmVudEZyYW1lKG5hbWUsIHNvdXJjZSwgb3duZXJGbikge1xuICB7XG4gICAgaWYgKHByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBFeHRyYWN0IHRoZSBWTSBzcGVjaWZpYyBwcmVmaXggdXNlZCBieSBlYWNoIGxpbmUuXG4gICAgICB0cnkge1xuICAgICAgICB0aHJvdyBFcnJvcigpO1xuICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICB2YXIgbWF0Y2ggPSB4LnN0YWNrLnRyaW0oKS5tYXRjaCgvXFxuKCAqKGF0ICk/KS8pO1xuICAgICAgICBwcmVmaXggPSBtYXRjaCAmJiBtYXRjaFsxXSB8fCAnJztcbiAgICAgIH1cbiAgICB9IC8vIFdlIHVzZSB0aGUgcHJlZml4IHRvIGVuc3VyZSBvdXIgc3RhY2tzIGxpbmUgdXAgd2l0aCBuYXRpdmUgc3RhY2sgZnJhbWVzLlxuXG5cbiAgICByZXR1cm4gJ1xcbicgKyBwcmVmaXggKyBuYW1lO1xuICB9XG59XG52YXIgcmVlbnRyeSA9IGZhbHNlO1xudmFyIGNvbXBvbmVudEZyYW1lQ2FjaGU7XG5cbntcbiAgdmFyIFBvc3NpYmx5V2Vha01hcCA9IHR5cGVvZiBXZWFrTWFwID09PSAnZnVuY3Rpb24nID8gV2Vha01hcCA6IE1hcDtcbiAgY29tcG9uZW50RnJhbWVDYWNoZSA9IG5ldyBQb3NzaWJseVdlYWtNYXAoKTtcbn1cblxuZnVuY3Rpb24gZGVzY3JpYmVOYXRpdmVDb21wb25lbnRGcmFtZShmbiwgY29uc3RydWN0KSB7XG4gIC8vIElmIHNvbWV0aGluZyBhc2tlZCBmb3IgYSBzdGFjayBpbnNpZGUgYSBmYWtlIHJlbmRlciwgaXQgc2hvdWxkIGdldCBpZ25vcmVkLlxuICBpZiAoICFmbiB8fCByZWVudHJ5KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAge1xuICAgIHZhciBmcmFtZSA9IGNvbXBvbmVudEZyYW1lQ2FjaGUuZ2V0KGZuKTtcblxuICAgIGlmIChmcmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZnJhbWU7XG4gICAgfVxuICB9XG5cbiAgdmFyIGNvbnRyb2w7XG4gIHJlZW50cnkgPSB0cnVlO1xuICB2YXIgcHJldmlvdXNQcmVwYXJlU3RhY2tUcmFjZSA9IEVycm9yLnByZXBhcmVTdGFja1RyYWNlOyAvLyAkRmxvd0ZpeE1lIEl0IGRvZXMgYWNjZXB0IHVuZGVmaW5lZC5cblxuICBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZSA9IHVuZGVmaW5lZDtcbiAgdmFyIHByZXZpb3VzRGlzcGF0Y2hlcjtcblxuICB7XG4gICAgcHJldmlvdXNEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlci5jdXJyZW50OyAvLyBTZXQgdGhlIGRpc3BhdGNoZXIgaW4gREVWIGJlY2F1c2UgdGhpcyBtaWdodCBiZSBjYWxsIGluIHRoZSByZW5kZXIgZnVuY3Rpb25cbiAgICAvLyBmb3Igd2FybmluZ3MuXG5cbiAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyLmN1cnJlbnQgPSBudWxsO1xuICAgIGRpc2FibGVMb2dzKCk7XG4gIH1cblxuICB0cnkge1xuICAgIC8vIFRoaXMgc2hvdWxkIHRocm93LlxuICAgIGlmIChjb25zdHJ1Y3QpIHtcbiAgICAgIC8vIFNvbWV0aGluZyBzaG91bGQgYmUgc2V0dGluZyB0aGUgcHJvcHMgaW4gdGhlIGNvbnN0cnVjdG9yLlxuICAgICAgdmFyIEZha2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRocm93IEVycm9yKCk7XG4gICAgICB9OyAvLyAkRmxvd0ZpeE1lXG5cblxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEZha2UucHJvdG90eXBlLCAncHJvcHMnLCB7XG4gICAgICAgIHNldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIC8vIFdlIHVzZSBhIHRocm93aW5nIHNldHRlciBpbnN0ZWFkIG9mIGZyb3plbiBvciBub24td3JpdGFibGUgcHJvcHNcbiAgICAgICAgICAvLyBiZWNhdXNlIHRoYXQgd29uJ3QgdGhyb3cgaW4gYSBub24tc3RyaWN0IG1vZGUgZnVuY3Rpb24uXG4gICAgICAgICAgdGhyb3cgRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gJ29iamVjdCcgJiYgUmVmbGVjdC5jb25zdHJ1Y3QpIHtcbiAgICAgICAgLy8gV2UgY29uc3RydWN0IGEgZGlmZmVyZW50IGNvbnRyb2wgZm9yIHRoaXMgY2FzZSB0byBpbmNsdWRlIGFueSBleHRyYVxuICAgICAgICAvLyBmcmFtZXMgYWRkZWQgYnkgdGhlIGNvbnN0cnVjdCBjYWxsLlxuICAgICAgICB0cnkge1xuICAgICAgICAgIFJlZmxlY3QuY29uc3RydWN0KEZha2UsIFtdKTtcbiAgICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICAgIGNvbnRyb2wgPSB4O1xuICAgICAgICB9XG5cbiAgICAgICAgUmVmbGVjdC5jb25zdHJ1Y3QoZm4sIFtdLCBGYWtlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgRmFrZS5jYWxsKCk7XG4gICAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgICBjb250cm9sID0geDtcbiAgICAgICAgfVxuXG4gICAgICAgIGZuLmNhbGwoRmFrZS5wcm90b3R5cGUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aHJvdyBFcnJvcigpO1xuICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICBjb250cm9sID0geDtcbiAgICAgIH1cblxuICAgICAgZm4oKTtcbiAgICB9XG4gIH0gY2F0Y2ggKHNhbXBsZSkge1xuICAgIC8vIFRoaXMgaXMgaW5saW5lZCBtYW51YWxseSBiZWNhdXNlIGNsb3N1cmUgZG9lc24ndCBkbyBpdCBmb3IgdXMuXG4gICAgaWYgKHNhbXBsZSAmJiBjb250cm9sICYmIHR5cGVvZiBzYW1wbGUuc3RhY2sgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBUaGlzIGV4dHJhY3RzIHRoZSBmaXJzdCBmcmFtZSBmcm9tIHRoZSBzYW1wbGUgdGhhdCBpc24ndCBhbHNvIGluIHRoZSBjb250cm9sLlxuICAgICAgLy8gU2tpcHBpbmcgb25lIGZyYW1lIHRoYXQgd2UgYXNzdW1lIGlzIHRoZSBmcmFtZSB0aGF0IGNhbGxzIHRoZSB0d28uXG4gICAgICB2YXIgc2FtcGxlTGluZXMgPSBzYW1wbGUuc3RhY2suc3BsaXQoJ1xcbicpO1xuICAgICAgdmFyIGNvbnRyb2xMaW5lcyA9IGNvbnRyb2wuc3RhY2suc3BsaXQoJ1xcbicpO1xuICAgICAgdmFyIHMgPSBzYW1wbGVMaW5lcy5sZW5ndGggLSAxO1xuICAgICAgdmFyIGMgPSBjb250cm9sTGluZXMubGVuZ3RoIC0gMTtcblxuICAgICAgd2hpbGUgKHMgPj0gMSAmJiBjID49IDAgJiYgc2FtcGxlTGluZXNbc10gIT09IGNvbnRyb2xMaW5lc1tjXSkge1xuICAgICAgICAvLyBXZSBleHBlY3QgYXQgbGVhc3Qgb25lIHN0YWNrIGZyYW1lIHRvIGJlIHNoYXJlZC5cbiAgICAgICAgLy8gVHlwaWNhbGx5IHRoaXMgd2lsbCBiZSB0aGUgcm9vdCBtb3N0IG9uZS4gSG93ZXZlciwgc3RhY2sgZnJhbWVzIG1heSBiZVxuICAgICAgICAvLyBjdXQgb2ZmIGR1ZSB0byBtYXhpbXVtIHN0YWNrIGxpbWl0cy4gSW4gdGhpcyBjYXNlLCBvbmUgbWF5YmUgY3V0IG9mZlxuICAgICAgICAvLyBlYXJsaWVyIHRoYW4gdGhlIG90aGVyLiBXZSBhc3N1bWUgdGhhdCB0aGUgc2FtcGxlIGlzIGxvbmdlciBvciB0aGUgc2FtZVxuICAgICAgICAvLyBhbmQgdGhlcmUgZm9yIGN1dCBvZmYgZWFybGllci4gU28gd2Ugc2hvdWxkIGZpbmQgdGhlIHJvb3QgbW9zdCBmcmFtZSBpblxuICAgICAgICAvLyB0aGUgc2FtcGxlIHNvbWV3aGVyZSBpbiB0aGUgY29udHJvbC5cbiAgICAgICAgYy0tO1xuICAgICAgfVxuXG4gICAgICBmb3IgKDsgcyA+PSAxICYmIGMgPj0gMDsgcy0tLCBjLS0pIHtcbiAgICAgICAgLy8gTmV4dCB3ZSBmaW5kIHRoZSBmaXJzdCBvbmUgdGhhdCBpc24ndCB0aGUgc2FtZSB3aGljaCBzaG91bGQgYmUgdGhlXG4gICAgICAgIC8vIGZyYW1lIHRoYXQgY2FsbGVkIG91ciBzYW1wbGUgZnVuY3Rpb24gYW5kIHRoZSBjb250cm9sLlxuICAgICAgICBpZiAoc2FtcGxlTGluZXNbc10gIT09IGNvbnRyb2xMaW5lc1tjXSkge1xuICAgICAgICAgIC8vIEluIFY4LCB0aGUgZmlyc3QgbGluZSBpcyBkZXNjcmliaW5nIHRoZSBtZXNzYWdlIGJ1dCBvdGhlciBWTXMgZG9uJ3QuXG4gICAgICAgICAgLy8gSWYgd2UncmUgYWJvdXQgdG8gcmV0dXJuIHRoZSBmaXJzdCBsaW5lLCBhbmQgdGhlIGNvbnRyb2wgaXMgYWxzbyBvbiB0aGUgc2FtZVxuICAgICAgICAgIC8vIGxpbmUsIHRoYXQncyBhIHByZXR0eSBnb29kIGluZGljYXRvciB0aGF0IG91ciBzYW1wbGUgdGhyZXcgYXQgc2FtZSBsaW5lIGFzXG4gICAgICAgICAgLy8gdGhlIGNvbnRyb2wuIEkuZS4gYmVmb3JlIHdlIGVudGVyZWQgdGhlIHNhbXBsZSBmcmFtZS4gU28gd2UgaWdub3JlIHRoaXMgcmVzdWx0LlxuICAgICAgICAgIC8vIFRoaXMgY2FuIGhhcHBlbiBpZiB5b3UgcGFzc2VkIGEgY2xhc3MgdG8gZnVuY3Rpb24gY29tcG9uZW50LCBvciBub24tZnVuY3Rpb24uXG4gICAgICAgICAgaWYgKHMgIT09IDEgfHwgYyAhPT0gMSkge1xuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICBzLS07XG4gICAgICAgICAgICAgIGMtLTsgLy8gV2UgbWF5IHN0aWxsIGhhdmUgc2ltaWxhciBpbnRlcm1lZGlhdGUgZnJhbWVzIGZyb20gdGhlIGNvbnN0cnVjdCBjYWxsLlxuICAgICAgICAgICAgICAvLyBUaGUgbmV4dCBvbmUgdGhhdCBpc24ndCB0aGUgc2FtZSBzaG91bGQgYmUgb3VyIG1hdGNoIHRob3VnaC5cblxuICAgICAgICAgICAgICBpZiAoYyA8IDAgfHwgc2FtcGxlTGluZXNbc10gIT09IGNvbnRyb2xMaW5lc1tjXSkge1xuICAgICAgICAgICAgICAgIC8vIFY4IGFkZHMgYSBcIm5ld1wiIHByZWZpeCBmb3IgbmF0aXZlIGNsYXNzZXMuIExldCdzIHJlbW92ZSBpdCB0byBtYWtlIGl0IHByZXR0aWVyLlxuICAgICAgICAgICAgICAgIHZhciBfZnJhbWUgPSAnXFxuJyArIHNhbXBsZUxpbmVzW3NdLnJlcGxhY2UoJyBhdCBuZXcgJywgJyBhdCAnKTsgLy8gSWYgb3VyIGNvbXBvbmVudCBmcmFtZSBpcyBsYWJlbGVkIFwiPGFub255bW91cz5cIlxuICAgICAgICAgICAgICAgIC8vIGJ1dCB3ZSBoYXZlIGEgdXNlci1wcm92aWRlZCBcImRpc3BsYXlOYW1lXCJcbiAgICAgICAgICAgICAgICAvLyBzcGxpY2UgaXQgaW4gdG8gbWFrZSB0aGUgc3RhY2sgbW9yZSByZWFkYWJsZS5cblxuXG4gICAgICAgICAgICAgICAgaWYgKGZuLmRpc3BsYXlOYW1lICYmIF9mcmFtZS5pbmNsdWRlcygnPGFub255bW91cz4nKSkge1xuICAgICAgICAgICAgICAgICAgX2ZyYW1lID0gX2ZyYW1lLnJlcGxhY2UoJzxhbm9ueW1vdXM+JywgZm4uZGlzcGxheU5hbWUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50RnJhbWVDYWNoZS5zZXQoZm4sIF9mcmFtZSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSAvLyBSZXR1cm4gdGhlIGxpbmUgd2UgZm91bmQuXG5cblxuICAgICAgICAgICAgICAgIHJldHVybiBfZnJhbWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gd2hpbGUgKHMgPj0gMSAmJiBjID49IDApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIHJlZW50cnkgPSBmYWxzZTtcblxuICAgIHtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIuY3VycmVudCA9IHByZXZpb3VzRGlzcGF0Y2hlcjtcbiAgICAgIHJlZW5hYmxlTG9ncygpO1xuICAgIH1cblxuICAgIEVycm9yLnByZXBhcmVTdGFja1RyYWNlID0gcHJldmlvdXNQcmVwYXJlU3RhY2tUcmFjZTtcbiAgfSAvLyBGYWxsYmFjayB0byBqdXN0IHVzaW5nIHRoZSBuYW1lIGlmIHdlIGNvdWxkbid0IG1ha2UgaXQgdGhyb3cuXG5cblxuICB2YXIgbmFtZSA9IGZuID8gZm4uZGlzcGxheU5hbWUgfHwgZm4ubmFtZSA6ICcnO1xuICB2YXIgc3ludGhldGljRnJhbWUgPSBuYW1lID8gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUobmFtZSkgOiAnJztcblxuICB7XG4gICAgaWYgKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29tcG9uZW50RnJhbWVDYWNoZS5zZXQoZm4sIHN5bnRoZXRpY0ZyYW1lKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3ludGhldGljRnJhbWU7XG59XG5mdW5jdGlvbiBkZXNjcmliZUZ1bmN0aW9uQ29tcG9uZW50RnJhbWUoZm4sIHNvdXJjZSwgb3duZXJGbikge1xuICB7XG4gICAgcmV0dXJuIGRlc2NyaWJlTmF0aXZlQ29tcG9uZW50RnJhbWUoZm4sIGZhbHNlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzaG91bGRDb25zdHJ1Y3QoQ29tcG9uZW50KSB7XG4gIHZhciBwcm90b3R5cGUgPSBDb21wb25lbnQucHJvdG90eXBlO1xuICByZXR1cm4gISEocHJvdG90eXBlICYmIHByb3RvdHlwZS5pc1JlYWN0Q29tcG9uZW50KTtcbn1cblxuZnVuY3Rpb24gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKHR5cGUsIHNvdXJjZSwgb3duZXJGbikge1xuXG4gIGlmICh0eXBlID09IG51bGwpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICB7XG4gICAgICByZXR1cm4gZGVzY3JpYmVOYXRpdmVDb21wb25lbnRGcmFtZSh0eXBlLCBzaG91bGRDb25zdHJ1Y3QodHlwZSkpO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUodHlwZSk7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX1RZUEU6XG4gICAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUoJ1N1c3BlbnNlJyk7XG5cbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRTpcbiAgICAgIHJldHVybiBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZSgnU3VzcGVuc2VMaXN0Jyk7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgc3dpdGNoICh0eXBlLiQkdHlwZW9mKSB7XG4gICAgICBjYXNlIFJFQUNUX0ZPUldBUkRfUkVGX1RZUEU6XG4gICAgICAgIHJldHVybiBkZXNjcmliZUZ1bmN0aW9uQ29tcG9uZW50RnJhbWUodHlwZS5yZW5kZXIpO1xuXG4gICAgICBjYXNlIFJFQUNUX01FTU9fVFlQRTpcbiAgICAgICAgLy8gTWVtbyBtYXkgY29udGFpbiBhbnkgY29tcG9uZW50IHR5cGUgc28gd2UgcmVjdXJzaXZlbHkgcmVzb2x2ZSBpdC5cbiAgICAgICAgcmV0dXJuIGRlc2NyaWJlVW5rbm93bkVsZW1lbnRUeXBlRnJhbWVJbkRFVih0eXBlLnR5cGUsIHNvdXJjZSwgb3duZXJGbik7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIGxhenlDb21wb25lbnQgPSB0eXBlO1xuICAgICAgICAgIHZhciBwYXlsb2FkID0gbGF6eUNvbXBvbmVudC5fcGF5bG9hZDtcbiAgICAgICAgICB2YXIgaW5pdCA9IGxhenlDb21wb25lbnQuX2luaXQ7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gTGF6eSBtYXkgY29udGFpbiBhbnkgY29tcG9uZW50IHR5cGUgc28gd2UgcmVjdXJzaXZlbHkgcmVzb2x2ZSBpdC5cbiAgICAgICAgICAgIHJldHVybiBkZXNjcmliZVVua25vd25FbGVtZW50VHlwZUZyYW1lSW5ERVYoaW5pdChwYXlsb2FkKSwgc291cmNlLCBvd25lckZuKTtcbiAgICAgICAgICB9IGNhdGNoICh4KSB7fVxuICAgICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuICcnO1xufVxuXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgbG9nZ2VkVHlwZUZhaWx1cmVzID0ge307XG52YXIgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0RGVidWdDdXJyZW50RnJhbWU7XG5cbmZ1bmN0aW9uIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KGVsZW1lbnQpIHtcbiAge1xuICAgIGlmIChlbGVtZW50KSB7XG4gICAgICB2YXIgb3duZXIgPSBlbGVtZW50Ll9vd25lcjtcbiAgICAgIHZhciBzdGFjayA9IGRlc2NyaWJlVW5rbm93bkVsZW1lbnRUeXBlRnJhbWVJbkRFVihlbGVtZW50LnR5cGUsIGVsZW1lbnQuX3NvdXJjZSwgb3duZXIgPyBvd25lci50eXBlIDogbnVsbCk7XG4gICAgICBSZWFjdERlYnVnQ3VycmVudEZyYW1lLnNldEV4dHJhU3RhY2tGcmFtZShzdGFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIFJlYWN0RGVidWdDdXJyZW50RnJhbWUuc2V0RXh0cmFTdGFja0ZyYW1lKG51bGwpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjaGVja1Byb3BUeXBlcyh0eXBlU3BlY3MsIHZhbHVlcywgbG9jYXRpb24sIGNvbXBvbmVudE5hbWUsIGVsZW1lbnQpIHtcbiAge1xuICAgIC8vICRGbG93Rml4TWUgVGhpcyBpcyBva2F5IGJ1dCBGbG93IGRvZXNuJ3Qga25vdyBpdC5cbiAgICB2YXIgaGFzID0gRnVuY3Rpb24uY2FsbC5iaW5kKGhhc093blByb3BlcnR5KTtcblxuICAgIGZvciAodmFyIHR5cGVTcGVjTmFtZSBpbiB0eXBlU3BlY3MpIHtcbiAgICAgIGlmIChoYXModHlwZVNwZWNzLCB0eXBlU3BlY05hbWUpKSB7XG4gICAgICAgIHZhciBlcnJvciQxID0gdm9pZCAwOyAvLyBQcm9wIHR5cGUgdmFsaWRhdGlvbiBtYXkgdGhyb3cuIEluIGNhc2UgdGhleSBkbywgd2UgZG9uJ3Qgd2FudCB0b1xuICAgICAgICAvLyBmYWlsIHRoZSByZW5kZXIgcGhhc2Ugd2hlcmUgaXQgZGlkbid0IGZhaWwgYmVmb3JlLiBTbyB3ZSBsb2cgaXQuXG4gICAgICAgIC8vIEFmdGVyIHRoZXNlIGhhdmUgYmVlbiBjbGVhbmVkIHVwLCB3ZSdsbCBsZXQgdGhlbSB0aHJvdy5cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIFRoaXMgaXMgaW50ZW50aW9uYWxseSBhbiBpbnZhcmlhbnQgdGhhdCBnZXRzIGNhdWdodC4gSXQncyB0aGUgc2FtZVxuICAgICAgICAgIC8vIGJlaGF2aW9yIGFzIHdpdGhvdXQgdGhpcyBzdGF0ZW1lbnQgZXhjZXB0IHdpdGggYSBiZXR0ZXIgbWVzc2FnZS5cbiAgICAgICAgICBpZiAodHlwZW9mIHR5cGVTcGVjc1t0eXBlU3BlY05hbWVdICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2Rlc1xuICAgICAgICAgICAgdmFyIGVyciA9IEVycm9yKChjb21wb25lbnROYW1lIHx8ICdSZWFjdCBjbGFzcycpICsgJzogJyArIGxvY2F0aW9uICsgJyB0eXBlIGAnICsgdHlwZVNwZWNOYW1lICsgJ2AgaXMgaW52YWxpZDsgJyArICdpdCBtdXN0IGJlIGEgZnVuY3Rpb24sIHVzdWFsbHkgZnJvbSB0aGUgYHByb3AtdHlwZXNgIHBhY2thZ2UsIGJ1dCByZWNlaXZlZCBgJyArIHR5cGVvZiB0eXBlU3BlY3NbdHlwZVNwZWNOYW1lXSArICdgLicgKyAnVGhpcyBvZnRlbiBoYXBwZW5zIGJlY2F1c2Ugb2YgdHlwb3Mgc3VjaCBhcyBgUHJvcFR5cGVzLmZ1bmN0aW9uYCBpbnN0ZWFkIG9mIGBQcm9wVHlwZXMuZnVuY2AuJyk7XG4gICAgICAgICAgICBlcnIubmFtZSA9ICdJbnZhcmlhbnQgVmlvbGF0aW9uJztcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlcnJvciQxID0gdHlwZVNwZWNzW3R5cGVTcGVjTmFtZV0odmFsdWVzLCB0eXBlU3BlY05hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBudWxsLCAnU0VDUkVUX0RPX05PVF9QQVNTX1RISVNfT1JfWU9VX1dJTExfQkVfRklSRUQnKTtcbiAgICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgICBlcnJvciQxID0gZXg7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXJyb3IkMSAmJiAhKGVycm9yJDEgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChlbGVtZW50KTtcblxuICAgICAgICAgIGVycm9yKCclczogdHlwZSBzcGVjaWZpY2F0aW9uIG9mICVzJyArICcgYCVzYCBpcyBpbnZhbGlkOyB0aGUgdHlwZSBjaGVja2VyICcgKyAnZnVuY3Rpb24gbXVzdCByZXR1cm4gYG51bGxgIG9yIGFuIGBFcnJvcmAgYnV0IHJldHVybmVkIGEgJXMuICcgKyAnWW91IG1heSBoYXZlIGZvcmdvdHRlbiB0byBwYXNzIGFuIGFyZ3VtZW50IHRvIHRoZSB0eXBlIGNoZWNrZXIgJyArICdjcmVhdG9yIChhcnJheU9mLCBpbnN0YW5jZU9mLCBvYmplY3RPZiwgb25lT2YsIG9uZU9mVHlwZSwgYW5kICcgKyAnc2hhcGUgYWxsIHJlcXVpcmUgYW4gYXJndW1lbnQpLicsIGNvbXBvbmVudE5hbWUgfHwgJ1JlYWN0IGNsYXNzJywgbG9jYXRpb24sIHR5cGVTcGVjTmFtZSwgdHlwZW9mIGVycm9yJDEpO1xuXG4gICAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQobnVsbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXJyb3IkMSBpbnN0YW5jZW9mIEVycm9yICYmICEoZXJyb3IkMS5tZXNzYWdlIGluIGxvZ2dlZFR5cGVGYWlsdXJlcykpIHtcbiAgICAgICAgICAvLyBPbmx5IG1vbml0b3IgdGhpcyBmYWlsdXJlIG9uY2UgYmVjYXVzZSB0aGVyZSB0ZW5kcyB0byBiZSBhIGxvdCBvZiB0aGVcbiAgICAgICAgICAvLyBzYW1lIGVycm9yLlxuICAgICAgICAgIGxvZ2dlZFR5cGVGYWlsdXJlc1tlcnJvciQxLm1lc3NhZ2VdID0gdHJ1ZTtcbiAgICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChlbGVtZW50KTtcblxuICAgICAgICAgIGVycm9yKCdGYWlsZWQgJXMgdHlwZTogJXMnLCBsb2NhdGlvbiwgZXJyb3IkMS5tZXNzYWdlKTtcblxuICAgICAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KG51bGwpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBpc0FycmF5SW1wbCA9IEFycmF5LmlzQXJyYXk7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZWRlY2xhcmVcblxuZnVuY3Rpb24gaXNBcnJheShhKSB7XG4gIHJldHVybiBpc0FycmF5SW1wbChhKTtcbn1cblxuLypcbiAqIFRoZSBgJycgKyB2YWx1ZWAgcGF0dGVybiAodXNlZCBpbiBpbiBwZXJmLXNlbnNpdGl2ZSBjb2RlKSB0aHJvd3MgZm9yIFN5bWJvbFxuICogYW5kIFRlbXBvcmFsLiogdHlwZXMuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvcHVsbC8yMjA2NC5cbiAqXG4gKiBUaGUgZnVuY3Rpb25zIGluIHRoaXMgbW9kdWxlIHdpbGwgdGhyb3cgYW4gZWFzaWVyLXRvLXVuZGVyc3RhbmQsXG4gKiBlYXNpZXItdG8tZGVidWcgZXhjZXB0aW9uIHdpdGggYSBjbGVhciBlcnJvcnMgbWVzc2FnZSBtZXNzYWdlIGV4cGxhaW5pbmcgdGhlXG4gKiBwcm9ibGVtLiAoSW5zdGVhZCBvZiBhIGNvbmZ1c2luZyBleGNlcHRpb24gdGhyb3duIGluc2lkZSB0aGUgaW1wbGVtZW50YXRpb25cbiAqIG9mIHRoZSBgdmFsdWVgIG9iamVjdCkuXG4gKi9cbi8vICRGbG93Rml4TWUgb25seSBjYWxsZWQgaW4gREVWLCBzbyB2b2lkIHJldHVybiBpcyBub3QgcG9zc2libGUuXG5mdW5jdGlvbiB0eXBlTmFtZSh2YWx1ZSkge1xuICB7XG4gICAgLy8gdG9TdHJpbmdUYWcgaXMgbmVlZGVkIGZvciBuYW1lc3BhY2VkIHR5cGVzIGxpa2UgVGVtcG9yYWwuSW5zdGFudFxuICAgIHZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgU3ltYm9sLnRvU3RyaW5nVGFnO1xuICAgIHZhciB0eXBlID0gaGFzVG9TdHJpbmdUYWcgJiYgdmFsdWVbU3ltYm9sLnRvU3RyaW5nVGFnXSB8fCB2YWx1ZS5jb25zdHJ1Y3Rvci5uYW1lIHx8ICdPYmplY3QnO1xuICAgIHJldHVybiB0eXBlO1xuICB9XG59IC8vICRGbG93Rml4TWUgb25seSBjYWxsZWQgaW4gREVWLCBzbyB2b2lkIHJldHVybiBpcyBub3QgcG9zc2libGUuXG5cblxuZnVuY3Rpb24gd2lsbENvZXJjaW9uVGhyb3codmFsdWUpIHtcbiAge1xuICAgIHRyeSB7XG4gICAgICB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpIHtcbiAgLy8gSWYgeW91IGVuZGVkIHVwIGhlcmUgYnkgZm9sbG93aW5nIGFuIGV4Y2VwdGlvbiBjYWxsIHN0YWNrLCBoZXJlJ3Mgd2hhdCdzXG4gIC8vIGhhcHBlbmVkOiB5b3Ugc3VwcGxpZWQgYW4gb2JqZWN0IG9yIHN5bWJvbCB2YWx1ZSB0byBSZWFjdCAoYXMgYSBwcm9wLCBrZXksXG4gIC8vIERPTSBhdHRyaWJ1dGUsIENTUyBwcm9wZXJ0eSwgc3RyaW5nIHJlZiwgZXRjLikgYW5kIHdoZW4gUmVhY3QgdHJpZWQgdG9cbiAgLy8gY29lcmNlIGl0IHRvIGEgc3RyaW5nIHVzaW5nIGAnJyArIHZhbHVlYCwgYW4gZXhjZXB0aW9uIHdhcyB0aHJvd24uXG4gIC8vXG4gIC8vIFRoZSBtb3N0IGNvbW1vbiB0eXBlcyB0aGF0IHdpbGwgY2F1c2UgdGhpcyBleGNlcHRpb24gYXJlIGBTeW1ib2xgIGluc3RhbmNlc1xuICAvLyBhbmQgVGVtcG9yYWwgb2JqZWN0cyBsaWtlIGBUZW1wb3JhbC5JbnN0YW50YC4gQnV0IGFueSBvYmplY3QgdGhhdCBoYXMgYVxuICAvLyBgdmFsdWVPZmAgb3IgYFtTeW1ib2wudG9QcmltaXRpdmVdYCBtZXRob2QgdGhhdCB0aHJvd3Mgd2lsbCBhbHNvIGNhdXNlIHRoaXNcbiAgLy8gZXhjZXB0aW9uLiAoTGlicmFyeSBhdXRob3JzIGRvIHRoaXMgdG8gcHJldmVudCB1c2VycyBmcm9tIHVzaW5nIGJ1aWx0LWluXG4gIC8vIG51bWVyaWMgb3BlcmF0b3JzIGxpa2UgYCtgIG9yIGNvbXBhcmlzb24gb3BlcmF0b3JzIGxpa2UgYD49YCBiZWNhdXNlIGN1c3RvbVxuICAvLyBtZXRob2RzIGFyZSBuZWVkZWQgdG8gcGVyZm9ybSBhY2N1cmF0ZSBhcml0aG1ldGljIG9yIGNvbXBhcmlzb24uKVxuICAvL1xuICAvLyBUbyBmaXggdGhlIHByb2JsZW0sIGNvZXJjZSB0aGlzIG9iamVjdCBvciBzeW1ib2wgdmFsdWUgdG8gYSBzdHJpbmcgYmVmb3JlXG4gIC8vIHBhc3NpbmcgaXQgdG8gUmVhY3QuIFRoZSBtb3N0IHJlbGlhYmxlIHdheSBpcyB1c3VhbGx5IGBTdHJpbmcodmFsdWUpYC5cbiAgLy9cbiAgLy8gVG8gZmluZCB3aGljaCB2YWx1ZSBpcyB0aHJvd2luZywgY2hlY2sgdGhlIGJyb3dzZXIgb3IgZGVidWdnZXIgY29uc29sZS5cbiAgLy8gQmVmb3JlIHRoaXMgZXhjZXB0aW9uIHdhcyB0aHJvd24sIHRoZXJlIHNob3VsZCBiZSBgY29uc29sZS5lcnJvcmAgb3V0cHV0XG4gIC8vIHRoYXQgc2hvd3MgdGhlIHR5cGUgKFN5bWJvbCwgVGVtcG9yYWwuUGxhaW5EYXRlLCBldGMuKSB0aGF0IGNhdXNlZCB0aGVcbiAgLy8gcHJvYmxlbSBhbmQgaG93IHRoYXQgdHlwZSB3YXMgdXNlZDoga2V5LCBhdHJyaWJ1dGUsIGlucHV0IHZhbHVlIHByb3AsIGV0Yy5cbiAgLy8gSW4gbW9zdCBjYXNlcywgdGhpcyBjb25zb2xlIG91dHB1dCBhbHNvIHNob3dzIHRoZSBjb21wb25lbnQgYW5kIGl0c1xuICAvLyBhbmNlc3RvciBjb21wb25lbnRzIHdoZXJlIHRoZSBleGNlcHRpb24gaGFwcGVuZWQuXG4gIC8vXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuICByZXR1cm4gJycgKyB2YWx1ZTtcbn1cbmZ1bmN0aW9uIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24odmFsdWUpIHtcbiAge1xuICAgIGlmICh3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkpIHtcbiAgICAgIGVycm9yKCdUaGUgcHJvdmlkZWQga2V5IGlzIGFuIHVuc3VwcG9ydGVkIHR5cGUgJXMuJyArICcgVGhpcyB2YWx1ZSBtdXN0IGJlIGNvZXJjZWQgdG8gYSBzdHJpbmcgYmVmb3JlIGJlZm9yZSB1c2luZyBpdCBoZXJlLicsIHR5cGVOYW1lKHZhbHVlKSk7XG5cbiAgICAgIHJldHVybiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpOyAvLyB0aHJvdyAodG8gaGVscCBjYWxsZXJzIGZpbmQgdHJvdWJsZXNob290aW5nIGNvbW1lbnRzKVxuICAgIH1cbiAgfVxufVxuXG52YXIgUmVhY3RDdXJyZW50T3duZXIgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRPd25lcjtcbnZhciBSRVNFUlZFRF9QUk9QUyA9IHtcbiAga2V5OiB0cnVlLFxuICByZWY6IHRydWUsXG4gIF9fc2VsZjogdHJ1ZSxcbiAgX19zb3VyY2U6IHRydWVcbn07XG52YXIgc3BlY2lhbFByb3BLZXlXYXJuaW5nU2hvd247XG52YXIgc3BlY2lhbFByb3BSZWZXYXJuaW5nU2hvd247XG52YXIgZGlkV2FybkFib3V0U3RyaW5nUmVmcztcblxue1xuICBkaWRXYXJuQWJvdXRTdHJpbmdSZWZzID0ge307XG59XG5cbmZ1bmN0aW9uIGhhc1ZhbGlkUmVmKGNvbmZpZykge1xuICB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoY29uZmlnLCAncmVmJykpIHtcbiAgICAgIHZhciBnZXR0ZXIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGNvbmZpZywgJ3JlZicpLmdldDtcblxuICAgICAgaWYgKGdldHRlciAmJiBnZXR0ZXIuaXNSZWFjdFdhcm5pbmcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjb25maWcucmVmICE9PSB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGhhc1ZhbGlkS2V5KGNvbmZpZykge1xuICB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoY29uZmlnLCAna2V5JykpIHtcbiAgICAgIHZhciBnZXR0ZXIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGNvbmZpZywgJ2tleScpLmdldDtcblxuICAgICAgaWYgKGdldHRlciAmJiBnZXR0ZXIuaXNSZWFjdFdhcm5pbmcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjb25maWcua2V5ICE9PSB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIHdhcm5JZlN0cmluZ1JlZkNhbm5vdEJlQXV0b0NvbnZlcnRlZChjb25maWcsIHNlbGYpIHtcbiAge1xuICAgIGlmICh0eXBlb2YgY29uZmlnLnJlZiA9PT0gJ3N0cmluZycgJiYgUmVhY3RDdXJyZW50T3duZXIuY3VycmVudCAmJiBzZWxmICYmIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQuc3RhdGVOb2RlICE9PSBzZWxmKSB7XG4gICAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50LnR5cGUpO1xuXG4gICAgICBpZiAoIWRpZFdhcm5BYm91dFN0cmluZ1JlZnNbY29tcG9uZW50TmFtZV0pIHtcbiAgICAgICAgZXJyb3IoJ0NvbXBvbmVudCBcIiVzXCIgY29udGFpbnMgdGhlIHN0cmluZyByZWYgXCIlc1wiLiAnICsgJ1N1cHBvcnQgZm9yIHN0cmluZyByZWZzIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSBtYWpvciByZWxlYXNlLiAnICsgJ1RoaXMgY2FzZSBjYW5ub3QgYmUgYXV0b21hdGljYWxseSBjb252ZXJ0ZWQgdG8gYW4gYXJyb3cgZnVuY3Rpb24uICcgKyAnV2UgYXNrIHlvdSB0byBtYW51YWxseSBmaXggdGhpcyBjYXNlIGJ5IHVzaW5nIHVzZVJlZigpIG9yIGNyZWF0ZVJlZigpIGluc3RlYWQuICcgKyAnTGVhcm4gbW9yZSBhYm91dCB1c2luZyByZWZzIHNhZmVseSBoZXJlOiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zdHJpY3QtbW9kZS1zdHJpbmctcmVmJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQudHlwZSksIGNvbmZpZy5yZWYpO1xuXG4gICAgICAgIGRpZFdhcm5BYm91dFN0cmluZ1JlZnNbY29tcG9uZW50TmFtZV0gPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBkZWZpbmVLZXlQcm9wV2FybmluZ0dldHRlcihwcm9wcywgZGlzcGxheU5hbWUpIHtcbiAge1xuICAgIHZhciB3YXJuQWJvdXRBY2Nlc3NpbmdLZXkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoIXNwZWNpYWxQcm9wS2V5V2FybmluZ1Nob3duKSB7XG4gICAgICAgIHNwZWNpYWxQcm9wS2V5V2FybmluZ1Nob3duID0gdHJ1ZTtcblxuICAgICAgICBlcnJvcignJXM6IGBrZXlgIGlzIG5vdCBhIHByb3AuIFRyeWluZyB0byBhY2Nlc3MgaXQgd2lsbCByZXN1bHQgJyArICdpbiBgdW5kZWZpbmVkYCBiZWluZyByZXR1cm5lZC4gSWYgeW91IG5lZWQgdG8gYWNjZXNzIHRoZSBzYW1lICcgKyAndmFsdWUgd2l0aGluIHRoZSBjaGlsZCBjb21wb25lbnQsIHlvdSBzaG91bGQgcGFzcyBpdCBhcyBhIGRpZmZlcmVudCAnICsgJ3Byb3AuIChodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3BlY2lhbC1wcm9wcyknLCBkaXNwbGF5TmFtZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHdhcm5BYm91dEFjY2Vzc2luZ0tleS5pc1JlYWN0V2FybmluZyA9IHRydWU7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3BzLCAna2V5Jywge1xuICAgICAgZ2V0OiB3YXJuQWJvdXRBY2Nlc3NpbmdLZXksXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZWZpbmVSZWZQcm9wV2FybmluZ0dldHRlcihwcm9wcywgZGlzcGxheU5hbWUpIHtcbiAge1xuICAgIHZhciB3YXJuQWJvdXRBY2Nlc3NpbmdSZWYgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoIXNwZWNpYWxQcm9wUmVmV2FybmluZ1Nob3duKSB7XG4gICAgICAgIHNwZWNpYWxQcm9wUmVmV2FybmluZ1Nob3duID0gdHJ1ZTtcblxuICAgICAgICBlcnJvcignJXM6IGByZWZgIGlzIG5vdCBhIHByb3AuIFRyeWluZyB0byBhY2Nlc3MgaXQgd2lsbCByZXN1bHQgJyArICdpbiBgdW5kZWZpbmVkYCBiZWluZyByZXR1cm5lZC4gSWYgeW91IG5lZWQgdG8gYWNjZXNzIHRoZSBzYW1lICcgKyAndmFsdWUgd2l0aGluIHRoZSBjaGlsZCBjb21wb25lbnQsIHlvdSBzaG91bGQgcGFzcyBpdCBhcyBhIGRpZmZlcmVudCAnICsgJ3Byb3AuIChodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3BlY2lhbC1wcm9wcyknLCBkaXNwbGF5TmFtZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHdhcm5BYm91dEFjY2Vzc2luZ1JlZi5pc1JlYWN0V2FybmluZyA9IHRydWU7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3BzLCAncmVmJywge1xuICAgICAgZ2V0OiB3YXJuQWJvdXRBY2Nlc3NpbmdSZWYsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgfVxufVxuLyoqXG4gKiBGYWN0b3J5IG1ldGhvZCB0byBjcmVhdGUgYSBuZXcgUmVhY3QgZWxlbWVudC4gVGhpcyBubyBsb25nZXIgYWRoZXJlcyB0b1xuICogdGhlIGNsYXNzIHBhdHRlcm4sIHNvIGRvIG5vdCB1c2UgbmV3IHRvIGNhbGwgaXQuIEFsc28sIGluc3RhbmNlb2YgY2hlY2tcbiAqIHdpbGwgbm90IHdvcmsuIEluc3RlYWQgdGVzdCAkJHR5cGVvZiBmaWVsZCBhZ2FpbnN0IFN5bWJvbC5mb3IoJ3JlYWN0LmVsZW1lbnQnKSB0byBjaGVja1xuICogaWYgc29tZXRoaW5nIGlzIGEgUmVhY3QgRWxlbWVudC5cbiAqXG4gKiBAcGFyYW0geyp9IHR5cGVcbiAqIEBwYXJhbSB7Kn0gcHJvcHNcbiAqIEBwYXJhbSB7Kn0ga2V5XG4gKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IHJlZlxuICogQHBhcmFtIHsqfSBvd25lclxuICogQHBhcmFtIHsqfSBzZWxmIEEgKnRlbXBvcmFyeSogaGVscGVyIHRvIGRldGVjdCBwbGFjZXMgd2hlcmUgYHRoaXNgIGlzXG4gKiBkaWZmZXJlbnQgZnJvbSB0aGUgYG93bmVyYCB3aGVuIFJlYWN0LmNyZWF0ZUVsZW1lbnQgaXMgY2FsbGVkLCBzbyB0aGF0IHdlXG4gKiBjYW4gd2Fybi4gV2Ugd2FudCB0byBnZXQgcmlkIG9mIG93bmVyIGFuZCByZXBsYWNlIHN0cmluZyBgcmVmYHMgd2l0aCBhcnJvd1xuICogZnVuY3Rpb25zLCBhbmQgYXMgbG9uZyBhcyBgdGhpc2AgYW5kIG93bmVyIGFyZSB0aGUgc2FtZSwgdGhlcmUgd2lsbCBiZSBub1xuICogY2hhbmdlIGluIGJlaGF2aW9yLlxuICogQHBhcmFtIHsqfSBzb3VyY2UgQW4gYW5ub3RhdGlvbiBvYmplY3QgKGFkZGVkIGJ5IGEgdHJhbnNwaWxlciBvciBvdGhlcndpc2UpXG4gKiBpbmRpY2F0aW5nIGZpbGVuYW1lLCBsaW5lIG51bWJlciwgYW5kL29yIG90aGVyIGluZm9ybWF0aW9uLlxuICogQGludGVybmFsXG4gKi9cblxuXG52YXIgUmVhY3RFbGVtZW50ID0gZnVuY3Rpb24gKHR5cGUsIGtleSwgcmVmLCBzZWxmLCBzb3VyY2UsIG93bmVyLCBwcm9wcykge1xuICB2YXIgZWxlbWVudCA9IHtcbiAgICAvLyBUaGlzIHRhZyBhbGxvd3MgdXMgdG8gdW5pcXVlbHkgaWRlbnRpZnkgdGhpcyBhcyBhIFJlYWN0IEVsZW1lbnRcbiAgICAkJHR5cGVvZjogUkVBQ1RfRUxFTUVOVF9UWVBFLFxuICAgIC8vIEJ1aWx0LWluIHByb3BlcnRpZXMgdGhhdCBiZWxvbmcgb24gdGhlIGVsZW1lbnRcbiAgICB0eXBlOiB0eXBlLFxuICAgIGtleToga2V5LFxuICAgIHJlZjogcmVmLFxuICAgIHByb3BzOiBwcm9wcyxcbiAgICAvLyBSZWNvcmQgdGhlIGNvbXBvbmVudCByZXNwb25zaWJsZSBmb3IgY3JlYXRpbmcgdGhpcyBlbGVtZW50LlxuICAgIF9vd25lcjogb3duZXJcbiAgfTtcblxuICB7XG4gICAgLy8gVGhlIHZhbGlkYXRpb24gZmxhZyBpcyBjdXJyZW50bHkgbXV0YXRpdmUuIFdlIHB1dCBpdCBvblxuICAgIC8vIGFuIGV4dGVybmFsIGJhY2tpbmcgc3RvcmUgc28gdGhhdCB3ZSBjYW4gZnJlZXplIHRoZSB3aG9sZSBvYmplY3QuXG4gICAgLy8gVGhpcyBjYW4gYmUgcmVwbGFjZWQgd2l0aCBhIFdlYWtNYXAgb25jZSB0aGV5IGFyZSBpbXBsZW1lbnRlZCBpblxuICAgIC8vIGNvbW1vbmx5IHVzZWQgZGV2ZWxvcG1lbnQgZW52aXJvbm1lbnRzLlxuICAgIGVsZW1lbnQuX3N0b3JlID0ge307IC8vIFRvIG1ha2UgY29tcGFyaW5nIFJlYWN0RWxlbWVudHMgZWFzaWVyIGZvciB0ZXN0aW5nIHB1cnBvc2VzLCB3ZSBtYWtlXG4gICAgLy8gdGhlIHZhbGlkYXRpb24gZmxhZyBub24tZW51bWVyYWJsZSAod2hlcmUgcG9zc2libGUsIHdoaWNoIHNob3VsZFxuICAgIC8vIGluY2x1ZGUgZXZlcnkgZW52aXJvbm1lbnQgd2UgcnVuIHRlc3RzIGluKSwgc28gdGhlIHRlc3QgZnJhbWV3b3JrXG4gICAgLy8gaWdub3JlcyBpdC5cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbGVtZW50Ll9zdG9yZSwgJ3ZhbGlkYXRlZCcsIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgdmFsdWU6IGZhbHNlXG4gICAgfSk7IC8vIHNlbGYgYW5kIHNvdXJjZSBhcmUgREVWIG9ubHkgcHJvcGVydGllcy5cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbGVtZW50LCAnX3NlbGYnLCB7XG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICB2YWx1ZTogc2VsZlxuICAgIH0pOyAvLyBUd28gZWxlbWVudHMgY3JlYXRlZCBpbiB0d28gZGlmZmVyZW50IHBsYWNlcyBzaG91bGQgYmUgY29uc2lkZXJlZFxuICAgIC8vIGVxdWFsIGZvciB0ZXN0aW5nIHB1cnBvc2VzIGFuZCB0aGVyZWZvcmUgd2UgaGlkZSBpdCBmcm9tIGVudW1lcmF0aW9uLlxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGVsZW1lbnQsICdfc291cmNlJywge1xuICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgdmFsdWU6IHNvdXJjZVxuICAgIH0pO1xuXG4gICAgaWYgKE9iamVjdC5mcmVlemUpIHtcbiAgICAgIE9iamVjdC5mcmVlemUoZWxlbWVudC5wcm9wcyk7XG4gICAgICBPYmplY3QuZnJlZXplKGVsZW1lbnQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbGVtZW50O1xufTtcbi8qKlxuICogaHR0cHM6Ly9naXRodWIuY29tL3JlYWN0anMvcmZjcy9wdWxsLzEwN1xuICogQHBhcmFtIHsqfSB0eXBlXG4gKiBAcGFyYW0ge29iamVjdH0gcHJvcHNcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAqL1xuXG5mdW5jdGlvbiBqc3hERVYodHlwZSwgY29uZmlnLCBtYXliZUtleSwgc291cmNlLCBzZWxmKSB7XG4gIHtcbiAgICB2YXIgcHJvcE5hbWU7IC8vIFJlc2VydmVkIG5hbWVzIGFyZSBleHRyYWN0ZWRcblxuICAgIHZhciBwcm9wcyA9IHt9O1xuICAgIHZhciBrZXkgPSBudWxsO1xuICAgIHZhciByZWYgPSBudWxsOyAvLyBDdXJyZW50bHksIGtleSBjYW4gYmUgc3ByZWFkIGluIGFzIGEgcHJvcC4gVGhpcyBjYXVzZXMgYSBwb3RlbnRpYWxcbiAgICAvLyBpc3N1ZSBpZiBrZXkgaXMgYWxzbyBleHBsaWNpdGx5IGRlY2xhcmVkIChpZS4gPGRpdiB7Li4ucHJvcHN9IGtleT1cIkhpXCIgLz5cbiAgICAvLyBvciA8ZGl2IGtleT1cIkhpXCIgey4uLnByb3BzfSAvPiApLiBXZSB3YW50IHRvIGRlcHJlY2F0ZSBrZXkgc3ByZWFkLFxuICAgIC8vIGJ1dCBhcyBhbiBpbnRlcm1lZGlhcnkgc3RlcCwgd2Ugd2lsbCB1c2UganN4REVWIGZvciBldmVyeXRoaW5nIGV4Y2VwdFxuICAgIC8vIDxkaXYgey4uLnByb3BzfSBrZXk9XCJIaVwiIC8+LCBiZWNhdXNlIHdlIGFyZW4ndCBjdXJyZW50bHkgYWJsZSB0byB0ZWxsIGlmXG4gICAgLy8ga2V5IGlzIGV4cGxpY2l0bHkgZGVjbGFyZWQgdG8gYmUgdW5kZWZpbmVkIG9yIG5vdC5cblxuICAgIGlmIChtYXliZUtleSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB7XG4gICAgICAgIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24obWF5YmVLZXkpO1xuICAgICAgfVxuXG4gICAgICBrZXkgPSAnJyArIG1heWJlS2V5O1xuICAgIH1cblxuICAgIGlmIChoYXNWYWxpZEtleShjb25maWcpKSB7XG4gICAgICB7XG4gICAgICAgIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24oY29uZmlnLmtleSk7XG4gICAgICB9XG5cbiAgICAgIGtleSA9ICcnICsgY29uZmlnLmtleTtcbiAgICB9XG5cbiAgICBpZiAoaGFzVmFsaWRSZWYoY29uZmlnKSkge1xuICAgICAgcmVmID0gY29uZmlnLnJlZjtcbiAgICAgIHdhcm5JZlN0cmluZ1JlZkNhbm5vdEJlQXV0b0NvbnZlcnRlZChjb25maWcsIHNlbGYpO1xuICAgIH0gLy8gUmVtYWluaW5nIHByb3BlcnRpZXMgYXJlIGFkZGVkIHRvIGEgbmV3IHByb3BzIG9iamVjdFxuXG5cbiAgICBmb3IgKHByb3BOYW1lIGluIGNvbmZpZykge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoY29uZmlnLCBwcm9wTmFtZSkgJiYgIVJFU0VSVkVEX1BST1BTLmhhc093blByb3BlcnR5KHByb3BOYW1lKSkge1xuICAgICAgICBwcm9wc1twcm9wTmFtZV0gPSBjb25maWdbcHJvcE5hbWVdO1xuICAgICAgfVxuICAgIH0gLy8gUmVzb2x2ZSBkZWZhdWx0IHByb3BzXG5cblxuICAgIGlmICh0eXBlICYmIHR5cGUuZGVmYXVsdFByb3BzKSB7XG4gICAgICB2YXIgZGVmYXVsdFByb3BzID0gdHlwZS5kZWZhdWx0UHJvcHM7XG5cbiAgICAgIGZvciAocHJvcE5hbWUgaW4gZGVmYXVsdFByb3BzKSB7XG4gICAgICAgIGlmIChwcm9wc1twcm9wTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHByb3BzW3Byb3BOYW1lXSA9IGRlZmF1bHRQcm9wc1twcm9wTmFtZV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoa2V5IHx8IHJlZikge1xuICAgICAgdmFyIGRpc3BsYXlOYW1lID0gdHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicgPyB0eXBlLmRpc3BsYXlOYW1lIHx8IHR5cGUubmFtZSB8fCAnVW5rbm93bicgOiB0eXBlO1xuXG4gICAgICBpZiAoa2V5KSB7XG4gICAgICAgIGRlZmluZUtleVByb3BXYXJuaW5nR2V0dGVyKHByb3BzLCBkaXNwbGF5TmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZWYpIHtcbiAgICAgICAgZGVmaW5lUmVmUHJvcFdhcm5pbmdHZXR0ZXIocHJvcHMsIGRpc3BsYXlOYW1lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gUmVhY3RFbGVtZW50KHR5cGUsIGtleSwgcmVmLCBzZWxmLCBzb3VyY2UsIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQsIHByb3BzKTtcbiAgfVxufVxuXG52YXIgUmVhY3RDdXJyZW50T3duZXIkMSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudE93bmVyO1xudmFyIFJlYWN0RGVidWdDdXJyZW50RnJhbWUkMSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0RGVidWdDdXJyZW50RnJhbWU7XG5cbmZ1bmN0aW9uIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEoZWxlbWVudCkge1xuICB7XG4gICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgIHZhciBvd25lciA9IGVsZW1lbnQuX293bmVyO1xuICAgICAgdmFyIHN0YWNrID0gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKGVsZW1lbnQudHlwZSwgZWxlbWVudC5fc291cmNlLCBvd25lciA/IG93bmVyLnR5cGUgOiBudWxsKTtcbiAgICAgIFJlYWN0RGVidWdDdXJyZW50RnJhbWUkMS5zZXRFeHRyYVN0YWNrRnJhbWUoc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICBSZWFjdERlYnVnQ3VycmVudEZyYW1lJDEuc2V0RXh0cmFTdGFja0ZyYW1lKG51bGwpO1xuICAgIH1cbiAgfVxufVxuXG52YXIgcHJvcFR5cGVzTWlzc3BlbGxXYXJuaW5nU2hvd247XG5cbntcbiAgcHJvcFR5cGVzTWlzc3BlbGxXYXJuaW5nU2hvd24gPSBmYWxzZTtcbn1cbi8qKlxuICogVmVyaWZpZXMgdGhlIG9iamVjdCBpcyBhIFJlYWN0RWxlbWVudC5cbiAqIFNlZSBodHRwczovL3JlYWN0anMub3JnL2RvY3MvcmVhY3QtYXBpLmh0bWwjaXN2YWxpZGVsZW1lbnRcbiAqIEBwYXJhbSB7P29iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGBvYmplY3RgIGlzIGEgUmVhY3RFbGVtZW50LlxuICogQGZpbmFsXG4gKi9cblxuXG5mdW5jdGlvbiBpc1ZhbGlkRWxlbWVudChvYmplY3QpIHtcbiAge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJiBvYmplY3QgIT09IG51bGwgJiYgb2JqZWN0LiQkdHlwZW9mID09PSBSRUFDVF9FTEVNRU5UX1RZUEU7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKCkge1xuICB7XG4gICAgaWYgKFJlYWN0Q3VycmVudE93bmVyJDEuY3VycmVudCkge1xuICAgICAgdmFyIG5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoUmVhY3RDdXJyZW50T3duZXIkMS5jdXJyZW50LnR5cGUpO1xuXG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICByZXR1cm4gJ1xcblxcbkNoZWNrIHRoZSByZW5kZXIgbWV0aG9kIG9mIGAnICsgbmFtZSArICdgLic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuICcnO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldFNvdXJjZUluZm9FcnJvckFkZGVuZHVtKHNvdXJjZSkge1xuICB7XG4gICAgaWYgKHNvdXJjZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YXIgZmlsZU5hbWUgPSBzb3VyY2UuZmlsZU5hbWUucmVwbGFjZSgvXi4qW1xcXFxcXC9dLywgJycpO1xuICAgICAgdmFyIGxpbmVOdW1iZXIgPSBzb3VyY2UubGluZU51bWJlcjtcbiAgICAgIHJldHVybiAnXFxuXFxuQ2hlY2sgeW91ciBjb2RlIGF0ICcgKyBmaWxlTmFtZSArICc6JyArIGxpbmVOdW1iZXIgKyAnLic7XG4gICAgfVxuXG4gICAgcmV0dXJuICcnO1xuICB9XG59XG4vKipcbiAqIFdhcm4gaWYgdGhlcmUncyBubyBrZXkgZXhwbGljaXRseSBzZXQgb24gZHluYW1pYyBhcnJheXMgb2YgY2hpbGRyZW4gb3JcbiAqIG9iamVjdCBrZXlzIGFyZSBub3QgdmFsaWQuIFRoaXMgYWxsb3dzIHVzIHRvIGtlZXAgdHJhY2sgb2YgY2hpbGRyZW4gYmV0d2VlblxuICogdXBkYXRlcy5cbiAqL1xuXG5cbnZhciBvd25lckhhc0tleVVzZVdhcm5pbmcgPSB7fTtcblxuZnVuY3Rpb24gZ2V0Q3VycmVudENvbXBvbmVudEVycm9ySW5mbyhwYXJlbnRUeXBlKSB7XG4gIHtcbiAgICB2YXIgaW5mbyA9IGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bSgpO1xuXG4gICAgaWYgKCFpbmZvKSB7XG4gICAgICB2YXIgcGFyZW50TmFtZSA9IHR5cGVvZiBwYXJlbnRUeXBlID09PSAnc3RyaW5nJyA/IHBhcmVudFR5cGUgOiBwYXJlbnRUeXBlLmRpc3BsYXlOYW1lIHx8IHBhcmVudFR5cGUubmFtZTtcblxuICAgICAgaWYgKHBhcmVudE5hbWUpIHtcbiAgICAgICAgaW5mbyA9IFwiXFxuXFxuQ2hlY2sgdGhlIHRvcC1sZXZlbCByZW5kZXIgY2FsbCB1c2luZyA8XCIgKyBwYXJlbnROYW1lICsgXCI+LlwiO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBpbmZvO1xuICB9XG59XG4vKipcbiAqIFdhcm4gaWYgdGhlIGVsZW1lbnQgZG9lc24ndCBoYXZlIGFuIGV4cGxpY2l0IGtleSBhc3NpZ25lZCB0byBpdC5cbiAqIFRoaXMgZWxlbWVudCBpcyBpbiBhbiBhcnJheS4gVGhlIGFycmF5IGNvdWxkIGdyb3cgYW5kIHNocmluayBvciBiZVxuICogcmVvcmRlcmVkLiBBbGwgY2hpbGRyZW4gdGhhdCBoYXZlbid0IGFscmVhZHkgYmVlbiB2YWxpZGF0ZWQgYXJlIHJlcXVpcmVkIHRvXG4gKiBoYXZlIGEgXCJrZXlcIiBwcm9wZXJ0eSBhc3NpZ25lZCB0byBpdC4gRXJyb3Igc3RhdHVzZXMgYXJlIGNhY2hlZCBzbyBhIHdhcm5pbmdcbiAqIHdpbGwgb25seSBiZSBzaG93biBvbmNlLlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIHtSZWFjdEVsZW1lbnR9IGVsZW1lbnQgRWxlbWVudCB0aGF0IHJlcXVpcmVzIGEga2V5LlxuICogQHBhcmFtIHsqfSBwYXJlbnRUeXBlIGVsZW1lbnQncyBwYXJlbnQncyB0eXBlLlxuICovXG5cblxuZnVuY3Rpb24gdmFsaWRhdGVFeHBsaWNpdEtleShlbGVtZW50LCBwYXJlbnRUeXBlKSB7XG4gIHtcbiAgICBpZiAoIWVsZW1lbnQuX3N0b3JlIHx8IGVsZW1lbnQuX3N0b3JlLnZhbGlkYXRlZCB8fCBlbGVtZW50LmtleSAhPSBudWxsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZWxlbWVudC5fc3RvcmUudmFsaWRhdGVkID0gdHJ1ZTtcbiAgICB2YXIgY3VycmVudENvbXBvbmVudEVycm9ySW5mbyA9IGdldEN1cnJlbnRDb21wb25lbnRFcnJvckluZm8ocGFyZW50VHlwZSk7XG5cbiAgICBpZiAob3duZXJIYXNLZXlVc2VXYXJuaW5nW2N1cnJlbnRDb21wb25lbnRFcnJvckluZm9dKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgb3duZXJIYXNLZXlVc2VXYXJuaW5nW2N1cnJlbnRDb21wb25lbnRFcnJvckluZm9dID0gdHJ1ZTsgLy8gVXN1YWxseSB0aGUgY3VycmVudCBvd25lciBpcyB0aGUgb2ZmZW5kZXIsIGJ1dCBpZiBpdCBhY2NlcHRzIGNoaWxkcmVuIGFzIGFcbiAgICAvLyBwcm9wZXJ0eSwgaXQgbWF5IGJlIHRoZSBjcmVhdG9yIG9mIHRoZSBjaGlsZCB0aGF0J3MgcmVzcG9uc2libGUgZm9yXG4gICAgLy8gYXNzaWduaW5nIGl0IGEga2V5LlxuXG4gICAgdmFyIGNoaWxkT3duZXIgPSAnJztcblxuICAgIGlmIChlbGVtZW50ICYmIGVsZW1lbnQuX293bmVyICYmIGVsZW1lbnQuX293bmVyICE9PSBSZWFjdEN1cnJlbnRPd25lciQxLmN1cnJlbnQpIHtcbiAgICAgIC8vIEdpdmUgdGhlIGNvbXBvbmVudCB0aGF0IG9yaWdpbmFsbHkgY3JlYXRlZCB0aGlzIGNoaWxkLlxuICAgICAgY2hpbGRPd25lciA9IFwiIEl0IHdhcyBwYXNzZWQgYSBjaGlsZCBmcm9tIFwiICsgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGVsZW1lbnQuX293bmVyLnR5cGUpICsgXCIuXCI7XG4gICAgfVxuXG4gICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQkMShlbGVtZW50KTtcblxuICAgIGVycm9yKCdFYWNoIGNoaWxkIGluIGEgbGlzdCBzaG91bGQgaGF2ZSBhIHVuaXF1ZSBcImtleVwiIHByb3AuJyArICclcyVzIFNlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvd2FybmluZy1rZXlzIGZvciBtb3JlIGluZm9ybWF0aW9uLicsIGN1cnJlbnRDb21wb25lbnRFcnJvckluZm8sIGNoaWxkT3duZXIpO1xuXG4gICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQkMShudWxsKTtcbiAgfVxufVxuLyoqXG4gKiBFbnN1cmUgdGhhdCBldmVyeSBlbGVtZW50IGVpdGhlciBpcyBwYXNzZWQgaW4gYSBzdGF0aWMgbG9jYXRpb24sIGluIGFuXG4gKiBhcnJheSB3aXRoIGFuIGV4cGxpY2l0IGtleXMgcHJvcGVydHkgZGVmaW5lZCwgb3IgaW4gYW4gb2JqZWN0IGxpdGVyYWxcbiAqIHdpdGggdmFsaWQga2V5IHByb3BlcnR5LlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIHtSZWFjdE5vZGV9IG5vZGUgU3RhdGljYWxseSBwYXNzZWQgY2hpbGQgb2YgYW55IHR5cGUuXG4gKiBAcGFyYW0geyp9IHBhcmVudFR5cGUgbm9kZSdzIHBhcmVudCdzIHR5cGUuXG4gKi9cblxuXG5mdW5jdGlvbiB2YWxpZGF0ZUNoaWxkS2V5cyhub2RlLCBwYXJlbnRUeXBlKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIG5vZGUgIT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGlzQXJyYXkobm9kZSkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgY2hpbGQgPSBub2RlW2ldO1xuXG4gICAgICAgIGlmIChpc1ZhbGlkRWxlbWVudChjaGlsZCkpIHtcbiAgICAgICAgICB2YWxpZGF0ZUV4cGxpY2l0S2V5KGNoaWxkLCBwYXJlbnRUeXBlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNWYWxpZEVsZW1lbnQobm9kZSkpIHtcbiAgICAgIC8vIFRoaXMgZWxlbWVudCB3YXMgcGFzc2VkIGluIGEgdmFsaWQgbG9jYXRpb24uXG4gICAgICBpZiAobm9kZS5fc3RvcmUpIHtcbiAgICAgICAgbm9kZS5fc3RvcmUudmFsaWRhdGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG5vZGUpIHtcbiAgICAgIHZhciBpdGVyYXRvckZuID0gZ2V0SXRlcmF0b3JGbihub2RlKTtcblxuICAgICAgaWYgKHR5cGVvZiBpdGVyYXRvckZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIEVudHJ5IGl0ZXJhdG9ycyB1c2VkIHRvIHByb3ZpZGUgaW1wbGljaXQga2V5cyxcbiAgICAgICAgLy8gYnV0IG5vdyB3ZSBwcmludCBhIHNlcGFyYXRlIHdhcm5pbmcgZm9yIHRoZW0gbGF0ZXIuXG4gICAgICAgIGlmIChpdGVyYXRvckZuICE9PSBub2RlLmVudHJpZXMpIHtcbiAgICAgICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYXRvckZuLmNhbGwobm9kZSk7XG4gICAgICAgICAgdmFyIHN0ZXA7XG5cbiAgICAgICAgICB3aGlsZSAoIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lKSB7XG4gICAgICAgICAgICBpZiAoaXNWYWxpZEVsZW1lbnQoc3RlcC52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgdmFsaWRhdGVFeHBsaWNpdEtleShzdGVwLnZhbHVlLCBwYXJlbnRUeXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbi8qKlxuICogR2l2ZW4gYW4gZWxlbWVudCwgdmFsaWRhdGUgdGhhdCBpdHMgcHJvcHMgZm9sbG93IHRoZSBwcm9wVHlwZXMgZGVmaW5pdGlvbixcbiAqIHByb3ZpZGVkIGJ5IHRoZSB0eXBlLlxuICpcbiAqIEBwYXJhbSB7UmVhY3RFbGVtZW50fSBlbGVtZW50XG4gKi9cblxuXG5mdW5jdGlvbiB2YWxpZGF0ZVByb3BUeXBlcyhlbGVtZW50KSB7XG4gIHtcbiAgICB2YXIgdHlwZSA9IGVsZW1lbnQudHlwZTtcblxuICAgIGlmICh0eXBlID09PSBudWxsIHx8IHR5cGUgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcHJvcFR5cGVzO1xuXG4gICAgaWYgKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcm9wVHlwZXMgPSB0eXBlLnByb3BUeXBlcztcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB0eXBlID09PSAnb2JqZWN0JyAmJiAodHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRSB8fCAvLyBOb3RlOiBNZW1vIG9ubHkgY2hlY2tzIG91dGVyIHByb3BzIGhlcmUuXG4gICAgLy8gSW5uZXIgcHJvcHMgYXJlIGNoZWNrZWQgaW4gdGhlIHJlY29uY2lsZXIuXG4gICAgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfTUVNT19UWVBFKSkge1xuICAgICAgcHJvcFR5cGVzID0gdHlwZS5wcm9wVHlwZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocHJvcFR5cGVzKSB7XG4gICAgICAvLyBJbnRlbnRpb25hbGx5IGluc2lkZSB0byBhdm9pZCB0cmlnZ2VyaW5nIGxhenkgaW5pdGlhbGl6ZXJzOlxuICAgICAgdmFyIG5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZSk7XG4gICAgICBjaGVja1Byb3BUeXBlcyhwcm9wVHlwZXMsIGVsZW1lbnQucHJvcHMsICdwcm9wJywgbmFtZSwgZWxlbWVudCk7XG4gICAgfSBlbHNlIGlmICh0eXBlLlByb3BUeXBlcyAhPT0gdW5kZWZpbmVkICYmICFwcm9wVHlwZXNNaXNzcGVsbFdhcm5pbmdTaG93bikge1xuICAgICAgcHJvcFR5cGVzTWlzc3BlbGxXYXJuaW5nU2hvd24gPSB0cnVlOyAvLyBJbnRlbnRpb25hbGx5IGluc2lkZSB0byBhdm9pZCB0cmlnZ2VyaW5nIGxhenkgaW5pdGlhbGl6ZXJzOlxuXG4gICAgICB2YXIgX25hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZSk7XG5cbiAgICAgIGVycm9yKCdDb21wb25lbnQgJXMgZGVjbGFyZWQgYFByb3BUeXBlc2AgaW5zdGVhZCBvZiBgcHJvcFR5cGVzYC4gRGlkIHlvdSBtaXNzcGVsbCB0aGUgcHJvcGVydHkgYXNzaWdubWVudD8nLCBfbmFtZSB8fCAnVW5rbm93bicpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdHlwZS5nZXREZWZhdWx0UHJvcHMgPT09ICdmdW5jdGlvbicgJiYgIXR5cGUuZ2V0RGVmYXVsdFByb3BzLmlzUmVhY3RDbGFzc0FwcHJvdmVkKSB7XG4gICAgICBlcnJvcignZ2V0RGVmYXVsdFByb3BzIGlzIG9ubHkgdXNlZCBvbiBjbGFzc2ljIFJlYWN0LmNyZWF0ZUNsYXNzICcgKyAnZGVmaW5pdGlvbnMuIFVzZSBhIHN0YXRpYyBwcm9wZXJ0eSBuYW1lZCBgZGVmYXVsdFByb3BzYCBpbnN0ZWFkLicpO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBHaXZlbiBhIGZyYWdtZW50LCB2YWxpZGF0ZSB0aGF0IGl0IGNhbiBvbmx5IGJlIHByb3ZpZGVkIHdpdGggZnJhZ21lbnQgcHJvcHNcbiAqIEBwYXJhbSB7UmVhY3RFbGVtZW50fSBmcmFnbWVudFxuICovXG5cblxuZnVuY3Rpb24gdmFsaWRhdGVGcmFnbWVudFByb3BzKGZyYWdtZW50KSB7XG4gIHtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGZyYWdtZW50LnByb3BzKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGtleSA9IGtleXNbaV07XG5cbiAgICAgIGlmIChrZXkgIT09ICdjaGlsZHJlbicgJiYga2V5ICE9PSAna2V5Jykge1xuICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudCQxKGZyYWdtZW50KTtcblxuICAgICAgICBlcnJvcignSW52YWxpZCBwcm9wIGAlc2Agc3VwcGxpZWQgdG8gYFJlYWN0LkZyYWdtZW50YC4gJyArICdSZWFjdC5GcmFnbWVudCBjYW4gb25seSBoYXZlIGBrZXlgIGFuZCBgY2hpbGRyZW5gIHByb3BzLicsIGtleSk7XG5cbiAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQkMShudWxsKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGZyYWdtZW50LnJlZiAhPT0gbnVsbCkge1xuICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQkMShmcmFnbWVudCk7XG5cbiAgICAgIGVycm9yKCdJbnZhbGlkIGF0dHJpYnV0ZSBgcmVmYCBzdXBwbGllZCB0byBgUmVhY3QuRnJhZ21lbnRgLicpO1xuXG4gICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudCQxKG51bGwpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBqc3hXaXRoVmFsaWRhdGlvbih0eXBlLCBwcm9wcywga2V5LCBpc1N0YXRpY0NoaWxkcmVuLCBzb3VyY2UsIHNlbGYpIHtcbiAge1xuICAgIHZhciB2YWxpZFR5cGUgPSBpc1ZhbGlkRWxlbWVudFR5cGUodHlwZSk7IC8vIFdlIHdhcm4gaW4gdGhpcyBjYXNlIGJ1dCBkb24ndCB0aHJvdy4gV2UgZXhwZWN0IHRoZSBlbGVtZW50IGNyZWF0aW9uIHRvXG4gICAgLy8gc3VjY2VlZCBhbmQgdGhlcmUgd2lsbCBsaWtlbHkgYmUgZXJyb3JzIGluIHJlbmRlci5cblxuICAgIGlmICghdmFsaWRUeXBlKSB7XG4gICAgICB2YXIgaW5mbyA9ICcnO1xuXG4gICAgICBpZiAodHlwZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiB0eXBlID09PSAnb2JqZWN0JyAmJiB0eXBlICE9PSBudWxsICYmIE9iamVjdC5rZXlzKHR5cGUpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpbmZvICs9ICcgWW91IGxpa2VseSBmb3Jnb3QgdG8gZXhwb3J0IHlvdXIgY29tcG9uZW50IGZyb20gdGhlIGZpbGUgJyArIFwiaXQncyBkZWZpbmVkIGluLCBvciB5b3UgbWlnaHQgaGF2ZSBtaXhlZCB1cCBkZWZhdWx0IGFuZCBuYW1lZCBpbXBvcnRzLlwiO1xuICAgICAgfVxuXG4gICAgICB2YXIgc291cmNlSW5mbyA9IGdldFNvdXJjZUluZm9FcnJvckFkZGVuZHVtKHNvdXJjZSk7XG5cbiAgICAgIGlmIChzb3VyY2VJbmZvKSB7XG4gICAgICAgIGluZm8gKz0gc291cmNlSW5mbztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGluZm8gKz0gZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKCk7XG4gICAgICB9XG5cbiAgICAgIHZhciB0eXBlU3RyaW5nO1xuXG4gICAgICBpZiAodHlwZSA9PT0gbnVsbCkge1xuICAgICAgICB0eXBlU3RyaW5nID0gJ251bGwnO1xuICAgICAgfSBlbHNlIGlmIChpc0FycmF5KHR5cGUpKSB7XG4gICAgICAgIHR5cGVTdHJpbmcgPSAnYXJyYXknO1xuICAgICAgfSBlbHNlIGlmICh0eXBlICE9PSB1bmRlZmluZWQgJiYgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfRUxFTUVOVF9UWVBFKSB7XG4gICAgICAgIHR5cGVTdHJpbmcgPSBcIjxcIiArIChnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZS50eXBlKSB8fCAnVW5rbm93bicpICsgXCIgLz5cIjtcbiAgICAgICAgaW5mbyA9ICcgRGlkIHlvdSBhY2NpZGVudGFsbHkgZXhwb3J0IGEgSlNYIGxpdGVyYWwgaW5zdGVhZCBvZiBhIGNvbXBvbmVudD8nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHlwZVN0cmluZyA9IHR5cGVvZiB0eXBlO1xuICAgICAgfVxuXG4gICAgICBlcnJvcignUmVhY3QuanN4OiB0eXBlIGlzIGludmFsaWQgLS0gZXhwZWN0ZWQgYSBzdHJpbmcgKGZvciAnICsgJ2J1aWx0LWluIGNvbXBvbmVudHMpIG9yIGEgY2xhc3MvZnVuY3Rpb24gKGZvciBjb21wb3NpdGUgJyArICdjb21wb25lbnRzKSBidXQgZ290OiAlcy4lcycsIHR5cGVTdHJpbmcsIGluZm8pO1xuICAgIH1cblxuICAgIHZhciBlbGVtZW50ID0ganN4REVWKHR5cGUsIHByb3BzLCBrZXksIHNvdXJjZSwgc2VsZik7IC8vIFRoZSByZXN1bHQgY2FuIGJlIG51bGxpc2ggaWYgYSBtb2NrIG9yIGEgY3VzdG9tIGZ1bmN0aW9uIGlzIHVzZWQuXG4gICAgLy8gVE9ETzogRHJvcCB0aGlzIHdoZW4gdGhlc2UgYXJlIG5vIGxvbmdlciBhbGxvd2VkIGFzIHRoZSB0eXBlIGFyZ3VtZW50LlxuXG4gICAgaWYgKGVsZW1lbnQgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfSAvLyBTa2lwIGtleSB3YXJuaW5nIGlmIHRoZSB0eXBlIGlzbid0IHZhbGlkIHNpbmNlIG91ciBrZXkgdmFsaWRhdGlvbiBsb2dpY1xuICAgIC8vIGRvZXNuJ3QgZXhwZWN0IGEgbm9uLXN0cmluZy9mdW5jdGlvbiB0eXBlIGFuZCBjYW4gdGhyb3cgY29uZnVzaW5nIGVycm9ycy5cbiAgICAvLyBXZSBkb24ndCB3YW50IGV4Y2VwdGlvbiBiZWhhdmlvciB0byBkaWZmZXIgYmV0d2VlbiBkZXYgYW5kIHByb2QuXG4gICAgLy8gKFJlbmRlcmluZyB3aWxsIHRocm93IHdpdGggYSBoZWxwZnVsIG1lc3NhZ2UgYW5kIGFzIHNvb24gYXMgdGhlIHR5cGUgaXNcbiAgICAvLyBmaXhlZCwgdGhlIGtleSB3YXJuaW5ncyB3aWxsIGFwcGVhci4pXG5cblxuICAgIGlmICh2YWxpZFR5cGUpIHtcbiAgICAgIHZhciBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuO1xuXG4gICAgICBpZiAoY2hpbGRyZW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoaXNTdGF0aWNDaGlsZHJlbikge1xuICAgICAgICAgIGlmIChpc0FycmF5KGNoaWxkcmVuKSkge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICB2YWxpZGF0ZUNoaWxkS2V5cyhjaGlsZHJlbltpXSwgdHlwZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChPYmplY3QuZnJlZXplKSB7XG4gICAgICAgICAgICAgIE9iamVjdC5mcmVlemUoY2hpbGRyZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlcnJvcignUmVhY3QuanN4OiBTdGF0aWMgY2hpbGRyZW4gc2hvdWxkIGFsd2F5cyBiZSBhbiBhcnJheS4gJyArICdZb3UgYXJlIGxpa2VseSBleHBsaWNpdGx5IGNhbGxpbmcgUmVhY3QuanN4cyBvciBSZWFjdC5qc3hERVYuICcgKyAnVXNlIHRoZSBCYWJlbCB0cmFuc2Zvcm0gaW5zdGVhZC4nKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsaWRhdGVDaGlsZEtleXMoY2hpbGRyZW4sIHR5cGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09IFJFQUNUX0ZSQUdNRU5UX1RZUEUpIHtcbiAgICAgIHZhbGlkYXRlRnJhZ21lbnRQcm9wcyhlbGVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsaWRhdGVQcm9wVHlwZXMoZWxlbWVudCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cbn0gLy8gVGhlc2UgdHdvIGZ1bmN0aW9ucyBleGlzdCB0byBzdGlsbCBnZXQgY2hpbGQgd2FybmluZ3MgaW4gZGV2XG5cbnZhciBqc3hERVYkMSA9ICBqc3hXaXRoVmFsaWRhdGlvbiA7XG5cbmV4cG9ydHMuRnJhZ21lbnQgPSBSRUFDVF9GUkFHTUVOVF9UWVBFO1xuZXhwb3J0cy5qc3hERVYgPSBqc3hERVYkMTtcbiAgfSkoKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC5wcm9kdWN0aW9uLm1pbi5qcycpO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC5kZXZlbG9wbWVudC5qcycpO1xufVxuIiwiLyoqXG4gKiBAbGljZW5zZSBSZWFjdFxuICogcmVhY3QuZGV2ZWxvcG1lbnQuanNcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIEZhY2Vib29rLCBJbmMuIGFuZCBpdHMgYWZmaWxpYXRlcy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgKGZ1bmN0aW9uKCkge1xuXG4gICAgICAgICAgJ3VzZSBzdHJpY3QnO1xuXG4vKiBnbG9iYWwgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fICovXG5pZiAoXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gIT09ICd1bmRlZmluZWQnICYmXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18ucmVnaXN0ZXJJbnRlcm5hbE1vZHVsZVN0YXJ0ID09PVxuICAgICdmdW5jdGlvbidcbikge1xuICBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18ucmVnaXN0ZXJJbnRlcm5hbE1vZHVsZVN0YXJ0KG5ldyBFcnJvcigpKTtcbn1cbiAgICAgICAgICB2YXIgUmVhY3RWZXJzaW9uID0gJzE4LjIuMCc7XG5cbi8vIEFUVEVOVElPTlxuLy8gV2hlbiBhZGRpbmcgbmV3IHN5bWJvbHMgdG8gdGhpcyBmaWxlLFxuLy8gUGxlYXNlIGNvbnNpZGVyIGFsc28gYWRkaW5nIHRvICdyZWFjdC1kZXZ0b29scy1zaGFyZWQvc3JjL2JhY2tlbmQvUmVhY3RTeW1ib2xzJ1xuLy8gVGhlIFN5bWJvbCB1c2VkIHRvIHRhZyB0aGUgUmVhY3RFbGVtZW50LWxpa2UgdHlwZXMuXG52YXIgUkVBQ1RfRUxFTUVOVF9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QuZWxlbWVudCcpO1xudmFyIFJFQUNUX1BPUlRBTF9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QucG9ydGFsJyk7XG52YXIgUkVBQ1RfRlJBR01FTlRfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LmZyYWdtZW50Jyk7XG52YXIgUkVBQ1RfU1RSSUNUX01PREVfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnN0cmljdF9tb2RlJyk7XG52YXIgUkVBQ1RfUFJPRklMRVJfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnByb2ZpbGVyJyk7XG52YXIgUkVBQ1RfUFJPVklERVJfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnByb3ZpZGVyJyk7XG52YXIgUkVBQ1RfQ09OVEVYVF9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QuY29udGV4dCcpO1xudmFyIFJFQUNUX0ZPUldBUkRfUkVGX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5mb3J3YXJkX3JlZicpO1xudmFyIFJFQUNUX1NVU1BFTlNFX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5zdXNwZW5zZScpO1xudmFyIFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnN1c3BlbnNlX2xpc3QnKTtcbnZhciBSRUFDVF9NRU1PX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5tZW1vJyk7XG52YXIgUkVBQ1RfTEFaWV9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QubGF6eScpO1xudmFyIFJFQUNUX09GRlNDUkVFTl9UWVBFID0gU3ltYm9sLmZvcigncmVhY3Qub2Zmc2NyZWVuJyk7XG52YXIgTUFZQkVfSVRFUkFUT1JfU1lNQk9MID0gU3ltYm9sLml0ZXJhdG9yO1xudmFyIEZBVVhfSVRFUkFUT1JfU1lNQk9MID0gJ0BAaXRlcmF0b3InO1xuZnVuY3Rpb24gZ2V0SXRlcmF0b3JGbihtYXliZUl0ZXJhYmxlKSB7XG4gIGlmIChtYXliZUl0ZXJhYmxlID09PSBudWxsIHx8IHR5cGVvZiBtYXliZUl0ZXJhYmxlICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIG1heWJlSXRlcmF0b3IgPSBNQVlCRV9JVEVSQVRPUl9TWU1CT0wgJiYgbWF5YmVJdGVyYWJsZVtNQVlCRV9JVEVSQVRPUl9TWU1CT0xdIHx8IG1heWJlSXRlcmFibGVbRkFVWF9JVEVSQVRPUl9TWU1CT0xdO1xuXG4gIGlmICh0eXBlb2YgbWF5YmVJdGVyYXRvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBtYXliZUl0ZXJhdG9yO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogS2VlcHMgdHJhY2sgb2YgdGhlIGN1cnJlbnQgZGlzcGF0Y2hlci5cbiAqL1xudmFyIFJlYWN0Q3VycmVudERpc3BhdGNoZXIgPSB7XG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICogQHR5cGUge1JlYWN0Q29tcG9uZW50fVxuICAgKi9cbiAgY3VycmVudDogbnVsbFxufTtcblxuLyoqXG4gKiBLZWVwcyB0cmFjayBvZiB0aGUgY3VycmVudCBiYXRjaCdzIGNvbmZpZ3VyYXRpb24gc3VjaCBhcyBob3cgbG9uZyBhbiB1cGRhdGVcbiAqIHNob3VsZCBzdXNwZW5kIGZvciBpZiBpdCBuZWVkcyB0by5cbiAqL1xudmFyIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnID0ge1xuICB0cmFuc2l0aW9uOiBudWxsXG59O1xuXG52YXIgUmVhY3RDdXJyZW50QWN0UXVldWUgPSB7XG4gIGN1cnJlbnQ6IG51bGwsXG4gIC8vIFVzZWQgdG8gcmVwcm9kdWNlIGJlaGF2aW9yIG9mIGBiYXRjaGVkVXBkYXRlc2AgaW4gbGVnYWN5IG1vZGUuXG4gIGlzQmF0Y2hpbmdMZWdhY3k6IGZhbHNlLFxuICBkaWRTY2hlZHVsZUxlZ2FjeVVwZGF0ZTogZmFsc2Vcbn07XG5cbi8qKlxuICogS2VlcHMgdHJhY2sgb2YgdGhlIGN1cnJlbnQgb3duZXIuXG4gKlxuICogVGhlIGN1cnJlbnQgb3duZXIgaXMgdGhlIGNvbXBvbmVudCB3aG8gc2hvdWxkIG93biBhbnkgY29tcG9uZW50cyB0aGF0IGFyZVxuICogY3VycmVudGx5IGJlaW5nIGNvbnN0cnVjdGVkLlxuICovXG52YXIgUmVhY3RDdXJyZW50T3duZXIgPSB7XG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICogQHR5cGUge1JlYWN0Q29tcG9uZW50fVxuICAgKi9cbiAgY3VycmVudDogbnVsbFxufTtcblxudmFyIFJlYWN0RGVidWdDdXJyZW50RnJhbWUgPSB7fTtcbnZhciBjdXJyZW50RXh0cmFTdGFja0ZyYW1lID0gbnVsbDtcbmZ1bmN0aW9uIHNldEV4dHJhU3RhY2tGcmFtZShzdGFjaykge1xuICB7XG4gICAgY3VycmVudEV4dHJhU3RhY2tGcmFtZSA9IHN0YWNrO1xuICB9XG59XG5cbntcbiAgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZS5zZXRFeHRyYVN0YWNrRnJhbWUgPSBmdW5jdGlvbiAoc3RhY2spIHtcbiAgICB7XG4gICAgICBjdXJyZW50RXh0cmFTdGFja0ZyYW1lID0gc3RhY2s7XG4gICAgfVxuICB9OyAvLyBTdGFjayBpbXBsZW1lbnRhdGlvbiBpbmplY3RlZCBieSB0aGUgY3VycmVudCByZW5kZXJlci5cblxuXG4gIFJlYWN0RGVidWdDdXJyZW50RnJhbWUuZ2V0Q3VycmVudFN0YWNrID0gbnVsbDtcblxuICBSZWFjdERlYnVnQ3VycmVudEZyYW1lLmdldFN0YWNrQWRkZW5kdW0gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0YWNrID0gJyc7IC8vIEFkZCBhbiBleHRyYSB0b3AgZnJhbWUgd2hpbGUgYW4gZWxlbWVudCBpcyBiZWluZyB2YWxpZGF0ZWRcblxuICAgIGlmIChjdXJyZW50RXh0cmFTdGFja0ZyYW1lKSB7XG4gICAgICBzdGFjayArPSBjdXJyZW50RXh0cmFTdGFja0ZyYW1lO1xuICAgIH0gLy8gRGVsZWdhdGUgdG8gdGhlIGluamVjdGVkIHJlbmRlcmVyLXNwZWNpZmljIGltcGxlbWVudGF0aW9uXG5cblxuICAgIHZhciBpbXBsID0gUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZS5nZXRDdXJyZW50U3RhY2s7XG5cbiAgICBpZiAoaW1wbCkge1xuICAgICAgc3RhY2sgKz0gaW1wbCgpIHx8ICcnO1xuICAgIH1cblxuICAgIHJldHVybiBzdGFjaztcbiAgfTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxudmFyIGVuYWJsZVNjb3BlQVBJID0gZmFsc2U7IC8vIEV4cGVyaW1lbnRhbCBDcmVhdGUgRXZlbnQgSGFuZGxlIEFQSS5cbnZhciBlbmFibGVDYWNoZUVsZW1lbnQgPSBmYWxzZTtcbnZhciBlbmFibGVUcmFuc2l0aW9uVHJhY2luZyA9IGZhbHNlOyAvLyBObyBrbm93biBidWdzLCBidXQgbmVlZHMgcGVyZm9ybWFuY2UgdGVzdGluZ1xuXG52YXIgZW5hYmxlTGVnYWN5SGlkZGVuID0gZmFsc2U7IC8vIEVuYWJsZXMgdW5zdGFibGVfYXZvaWRUaGlzRmFsbGJhY2sgZmVhdHVyZSBpbiBGaWJlclxuLy8gc3R1ZmYuIEludGVuZGVkIHRvIGVuYWJsZSBSZWFjdCBjb3JlIG1lbWJlcnMgdG8gbW9yZSBlYXNpbHkgZGVidWcgc2NoZWR1bGluZ1xuLy8gaXNzdWVzIGluIERFViBidWlsZHMuXG5cbnZhciBlbmFibGVEZWJ1Z1RyYWNpbmcgPSBmYWxzZTsgLy8gVHJhY2sgd2hpY2ggRmliZXIocykgc2NoZWR1bGUgcmVuZGVyIHdvcmsuXG5cbnZhciBSZWFjdFNoYXJlZEludGVybmFscyA9IHtcbiAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlcjogUmVhY3RDdXJyZW50RGlzcGF0Y2hlcixcbiAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWc6IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLFxuICBSZWFjdEN1cnJlbnRPd25lcjogUmVhY3RDdXJyZW50T3duZXJcbn07XG5cbntcbiAgUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSA9IFJlYWN0RGVidWdDdXJyZW50RnJhbWU7XG4gIFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudEFjdFF1ZXVlID0gUmVhY3RDdXJyZW50QWN0UXVldWU7XG59XG5cbi8vIGJ5IGNhbGxzIHRvIHRoZXNlIG1ldGhvZHMgYnkgYSBCYWJlbCBwbHVnaW4uXG4vL1xuLy8gSW4gUFJPRCAob3IgaW4gcGFja2FnZXMgd2l0aG91dCBhY2Nlc3MgdG8gUmVhY3QgaW50ZXJuYWxzKSxcbi8vIHRoZXkgYXJlIGxlZnQgYXMgdGhleSBhcmUgaW5zdGVhZC5cblxuZnVuY3Rpb24gd2Fybihmb3JtYXQpIHtcbiAge1xuICAgIHtcbiAgICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4gPiAxID8gX2xlbiAtIDEgOiAwKSwgX2tleSA9IDE7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgICAgYXJnc1tfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgICB9XG5cbiAgICAgIHByaW50V2FybmluZygnd2FybicsIGZvcm1hdCwgYXJncyk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBlcnJvcihmb3JtYXQpIHtcbiAge1xuICAgIHtcbiAgICAgIGZvciAodmFyIF9sZW4yID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuMiA+IDEgPyBfbGVuMiAtIDEgOiAwKSwgX2tleTIgPSAxOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgICAgIGFyZ3NbX2tleTIgLSAxXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gICAgICB9XG5cbiAgICAgIHByaW50V2FybmluZygnZXJyb3InLCBmb3JtYXQsIGFyZ3MpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBwcmludFdhcm5pbmcobGV2ZWwsIGZvcm1hdCwgYXJncykge1xuICAvLyBXaGVuIGNoYW5naW5nIHRoaXMgbG9naWMsIHlvdSBtaWdodCB3YW50IHRvIGFsc29cbiAgLy8gdXBkYXRlIGNvbnNvbGVXaXRoU3RhY2tEZXYud3d3LmpzIGFzIHdlbGwuXG4gIHtcbiAgICB2YXIgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0RGVidWdDdXJyZW50RnJhbWU7XG4gICAgdmFyIHN0YWNrID0gUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZS5nZXRTdGFja0FkZGVuZHVtKCk7XG5cbiAgICBpZiAoc3RhY2sgIT09ICcnKSB7XG4gICAgICBmb3JtYXQgKz0gJyVzJztcbiAgICAgIGFyZ3MgPSBhcmdzLmNvbmNhdChbc3RhY2tdKTtcbiAgICB9IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuXG5cbiAgICB2YXIgYXJnc1dpdGhGb3JtYXQgPSBhcmdzLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgcmV0dXJuIFN0cmluZyhpdGVtKTtcbiAgICB9KTsgLy8gQ2FyZWZ1bDogUk4gY3VycmVudGx5IGRlcGVuZHMgb24gdGhpcyBwcmVmaXhcblxuICAgIGFyZ3NXaXRoRm9ybWF0LnVuc2hpZnQoJ1dhcm5pbmc6ICcgKyBmb3JtYXQpOyAvLyBXZSBpbnRlbnRpb25hbGx5IGRvbid0IHVzZSBzcHJlYWQgKG9yIC5hcHBseSkgZGlyZWN0bHkgYmVjYXVzZSBpdFxuICAgIC8vIGJyZWFrcyBJRTk6IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTM2MTBcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nXG5cbiAgICBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbChjb25zb2xlW2xldmVsXSwgY29uc29sZSwgYXJnc1dpdGhGb3JtYXQpO1xuICB9XG59XG5cbnZhciBkaWRXYXJuU3RhdGVVcGRhdGVGb3JVbm1vdW50ZWRDb21wb25lbnQgPSB7fTtcblxuZnVuY3Rpb24gd2Fybk5vb3AocHVibGljSW5zdGFuY2UsIGNhbGxlck5hbWUpIHtcbiAge1xuICAgIHZhciBfY29uc3RydWN0b3IgPSBwdWJsaWNJbnN0YW5jZS5jb25zdHJ1Y3RvcjtcbiAgICB2YXIgY29tcG9uZW50TmFtZSA9IF9jb25zdHJ1Y3RvciAmJiAoX2NvbnN0cnVjdG9yLmRpc3BsYXlOYW1lIHx8IF9jb25zdHJ1Y3Rvci5uYW1lKSB8fCAnUmVhY3RDbGFzcyc7XG4gICAgdmFyIHdhcm5pbmdLZXkgPSBjb21wb25lbnROYW1lICsgXCIuXCIgKyBjYWxsZXJOYW1lO1xuXG4gICAgaWYgKGRpZFdhcm5TdGF0ZVVwZGF0ZUZvclVubW91bnRlZENvbXBvbmVudFt3YXJuaW5nS2V5XSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGVycm9yKFwiQ2FuJ3QgY2FsbCAlcyBvbiBhIGNvbXBvbmVudCB0aGF0IGlzIG5vdCB5ZXQgbW91bnRlZC4gXCIgKyAnVGhpcyBpcyBhIG5vLW9wLCBidXQgaXQgbWlnaHQgaW5kaWNhdGUgYSBidWcgaW4geW91ciBhcHBsaWNhdGlvbi4gJyArICdJbnN0ZWFkLCBhc3NpZ24gdG8gYHRoaXMuc3RhdGVgIGRpcmVjdGx5IG9yIGRlZmluZSBhIGBzdGF0ZSA9IHt9O2AgJyArICdjbGFzcyBwcm9wZXJ0eSB3aXRoIHRoZSBkZXNpcmVkIHN0YXRlIGluIHRoZSAlcyBjb21wb25lbnQuJywgY2FsbGVyTmFtZSwgY29tcG9uZW50TmFtZSk7XG5cbiAgICBkaWRXYXJuU3RhdGVVcGRhdGVGb3JVbm1vdW50ZWRDb21wb25lbnRbd2FybmluZ0tleV0gPSB0cnVlO1xuICB9XG59XG4vKipcbiAqIFRoaXMgaXMgdGhlIGFic3RyYWN0IEFQSSBmb3IgYW4gdXBkYXRlIHF1ZXVlLlxuICovXG5cblxudmFyIFJlYWN0Tm9vcFVwZGF0ZVF1ZXVlID0ge1xuICAvKipcbiAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoaXMgY29tcG9zaXRlIGNvbXBvbmVudCBpcyBtb3VudGVkLlxuICAgKiBAcGFyYW0ge1JlYWN0Q2xhc3N9IHB1YmxpY0luc3RhbmNlIFRoZSBpbnN0YW5jZSB3ZSB3YW50IHRvIHRlc3QuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgbW91bnRlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBmaW5hbFxuICAgKi9cbiAgaXNNb3VudGVkOiBmdW5jdGlvbiAocHVibGljSW5zdGFuY2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEZvcmNlcyBhbiB1cGRhdGUuIFRoaXMgc2hvdWxkIG9ubHkgYmUgaW52b2tlZCB3aGVuIGl0IGlzIGtub3duIHdpdGhcbiAgICogY2VydGFpbnR5IHRoYXQgd2UgYXJlICoqbm90KiogaW4gYSBET00gdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIFlvdSBtYXkgd2FudCB0byBjYWxsIHRoaXMgd2hlbiB5b3Uga25vdyB0aGF0IHNvbWUgZGVlcGVyIGFzcGVjdCBvZiB0aGVcbiAgICogY29tcG9uZW50J3Mgc3RhdGUgaGFzIGNoYW5nZWQgYnV0IGBzZXRTdGF0ZWAgd2FzIG5vdCBjYWxsZWQuXG4gICAqXG4gICAqIFRoaXMgd2lsbCBub3QgaW52b2tlIGBzaG91bGRDb21wb25lbnRVcGRhdGVgLCBidXQgaXQgd2lsbCBpbnZva2VcbiAgICogYGNvbXBvbmVudFdpbGxVcGRhdGVgIGFuZCBgY29tcG9uZW50RGlkVXBkYXRlYC5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdENsYXNzfSBwdWJsaWNJbnN0YW5jZSBUaGUgaW5zdGFuY2UgdGhhdCBzaG91bGQgcmVyZW5kZXIuXG4gICAqIEBwYXJhbSB7P2Z1bmN0aW9ufSBjYWxsYmFjayBDYWxsZWQgYWZ0ZXIgY29tcG9uZW50IGlzIHVwZGF0ZWQuXG4gICAqIEBwYXJhbSB7P3N0cmluZ30gY2FsbGVyTmFtZSBuYW1lIG9mIHRoZSBjYWxsaW5nIGZ1bmN0aW9uIGluIHRoZSBwdWJsaWMgQVBJLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGVucXVldWVGb3JjZVVwZGF0ZTogZnVuY3Rpb24gKHB1YmxpY0luc3RhbmNlLCBjYWxsYmFjaywgY2FsbGVyTmFtZSkge1xuICAgIHdhcm5Ob29wKHB1YmxpY0luc3RhbmNlLCAnZm9yY2VVcGRhdGUnKTtcbiAgfSxcblxuICAvKipcbiAgICogUmVwbGFjZXMgYWxsIG9mIHRoZSBzdGF0ZS4gQWx3YXlzIHVzZSB0aGlzIG9yIGBzZXRTdGF0ZWAgdG8gbXV0YXRlIHN0YXRlLlxuICAgKiBZb3Ugc2hvdWxkIHRyZWF0IGB0aGlzLnN0YXRlYCBhcyBpbW11dGFibGUuXG4gICAqXG4gICAqIFRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IGB0aGlzLnN0YXRlYCB3aWxsIGJlIGltbWVkaWF0ZWx5IHVwZGF0ZWQsIHNvXG4gICAqIGFjY2Vzc2luZyBgdGhpcy5zdGF0ZWAgYWZ0ZXIgY2FsbGluZyB0aGlzIG1ldGhvZCBtYXkgcmV0dXJuIHRoZSBvbGQgdmFsdWUuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RDbGFzc30gcHVibGljSW5zdGFuY2UgVGhlIGluc3RhbmNlIHRoYXQgc2hvdWxkIHJlcmVuZGVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gY29tcGxldGVTdGF0ZSBOZXh0IHN0YXRlLlxuICAgKiBAcGFyYW0gez9mdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIGFmdGVyIGNvbXBvbmVudCBpcyB1cGRhdGVkLlxuICAgKiBAcGFyYW0gez9zdHJpbmd9IGNhbGxlck5hbWUgbmFtZSBvZiB0aGUgY2FsbGluZyBmdW5jdGlvbiBpbiB0aGUgcHVibGljIEFQSS5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBlbnF1ZXVlUmVwbGFjZVN0YXRlOiBmdW5jdGlvbiAocHVibGljSW5zdGFuY2UsIGNvbXBsZXRlU3RhdGUsIGNhbGxiYWNrLCBjYWxsZXJOYW1lKSB7XG4gICAgd2Fybk5vb3AocHVibGljSW5zdGFuY2UsICdyZXBsYWNlU3RhdGUnKTtcbiAgfSxcblxuICAvKipcbiAgICogU2V0cyBhIHN1YnNldCBvZiB0aGUgc3RhdGUuIFRoaXMgb25seSBleGlzdHMgYmVjYXVzZSBfcGVuZGluZ1N0YXRlIGlzXG4gICAqIGludGVybmFsLiBUaGlzIHByb3ZpZGVzIGEgbWVyZ2luZyBzdHJhdGVneSB0aGF0IGlzIG5vdCBhdmFpbGFibGUgdG8gZGVlcFxuICAgKiBwcm9wZXJ0aWVzIHdoaWNoIGlzIGNvbmZ1c2luZy4gVE9ETzogRXhwb3NlIHBlbmRpbmdTdGF0ZSBvciBkb24ndCB1c2UgaXRcbiAgICogZHVyaW5nIHRoZSBtZXJnZS5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdENsYXNzfSBwdWJsaWNJbnN0YW5jZSBUaGUgaW5zdGFuY2UgdGhhdCBzaG91bGQgcmVyZW5kZXIuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBwYXJ0aWFsU3RhdGUgTmV4dCBwYXJ0aWFsIHN0YXRlIHRvIGJlIG1lcmdlZCB3aXRoIHN0YXRlLlxuICAgKiBAcGFyYW0gez9mdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIGFmdGVyIGNvbXBvbmVudCBpcyB1cGRhdGVkLlxuICAgKiBAcGFyYW0gez9zdHJpbmd9IE5hbWUgb2YgdGhlIGNhbGxpbmcgZnVuY3Rpb24gaW4gdGhlIHB1YmxpYyBBUEkuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgZW5xdWV1ZVNldFN0YXRlOiBmdW5jdGlvbiAocHVibGljSW5zdGFuY2UsIHBhcnRpYWxTdGF0ZSwgY2FsbGJhY2ssIGNhbGxlck5hbWUpIHtcbiAgICB3YXJuTm9vcChwdWJsaWNJbnN0YW5jZSwgJ3NldFN0YXRlJyk7XG4gIH1cbn07XG5cbnZhciBhc3NpZ24gPSBPYmplY3QuYXNzaWduO1xuXG52YXIgZW1wdHlPYmplY3QgPSB7fTtcblxue1xuICBPYmplY3QuZnJlZXplKGVtcHR5T2JqZWN0KTtcbn1cbi8qKlxuICogQmFzZSBjbGFzcyBoZWxwZXJzIGZvciB0aGUgdXBkYXRpbmcgc3RhdGUgb2YgYSBjb21wb25lbnQuXG4gKi9cblxuXG5mdW5jdGlvbiBDb21wb25lbnQocHJvcHMsIGNvbnRleHQsIHVwZGF0ZXIpIHtcbiAgdGhpcy5wcm9wcyA9IHByb3BzO1xuICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OyAvLyBJZiBhIGNvbXBvbmVudCBoYXMgc3RyaW5nIHJlZnMsIHdlIHdpbGwgYXNzaWduIGEgZGlmZmVyZW50IG9iamVjdCBsYXRlci5cblxuICB0aGlzLnJlZnMgPSBlbXB0eU9iamVjdDsgLy8gV2UgaW5pdGlhbGl6ZSB0aGUgZGVmYXVsdCB1cGRhdGVyIGJ1dCB0aGUgcmVhbCBvbmUgZ2V0cyBpbmplY3RlZCBieSB0aGVcbiAgLy8gcmVuZGVyZXIuXG5cbiAgdGhpcy51cGRhdGVyID0gdXBkYXRlciB8fCBSZWFjdE5vb3BVcGRhdGVRdWV1ZTtcbn1cblxuQ29tcG9uZW50LnByb3RvdHlwZS5pc1JlYWN0Q29tcG9uZW50ID0ge307XG4vKipcbiAqIFNldHMgYSBzdWJzZXQgb2YgdGhlIHN0YXRlLiBBbHdheXMgdXNlIHRoaXMgdG8gbXV0YXRlXG4gKiBzdGF0ZS4gWW91IHNob3VsZCB0cmVhdCBgdGhpcy5zdGF0ZWAgYXMgaW1tdXRhYmxlLlxuICpcbiAqIFRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IGB0aGlzLnN0YXRlYCB3aWxsIGJlIGltbWVkaWF0ZWx5IHVwZGF0ZWQsIHNvXG4gKiBhY2Nlc3NpbmcgYHRoaXMuc3RhdGVgIGFmdGVyIGNhbGxpbmcgdGhpcyBtZXRob2QgbWF5IHJldHVybiB0aGUgb2xkIHZhbHVlLlxuICpcbiAqIFRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IGNhbGxzIHRvIGBzZXRTdGF0ZWAgd2lsbCBydW4gc3luY2hyb25vdXNseSxcbiAqIGFzIHRoZXkgbWF5IGV2ZW50dWFsbHkgYmUgYmF0Y2hlZCB0b2dldGhlci4gIFlvdSBjYW4gcHJvdmlkZSBhbiBvcHRpb25hbFxuICogY2FsbGJhY2sgdGhhdCB3aWxsIGJlIGV4ZWN1dGVkIHdoZW4gdGhlIGNhbGwgdG8gc2V0U3RhdGUgaXMgYWN0dWFsbHlcbiAqIGNvbXBsZXRlZC5cbiAqXG4gKiBXaGVuIGEgZnVuY3Rpb24gaXMgcHJvdmlkZWQgdG8gc2V0U3RhdGUsIGl0IHdpbGwgYmUgY2FsbGVkIGF0IHNvbWUgcG9pbnQgaW5cbiAqIHRoZSBmdXR1cmUgKG5vdCBzeW5jaHJvbm91c2x5KS4gSXQgd2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUgdXAgdG8gZGF0ZVxuICogY29tcG9uZW50IGFyZ3VtZW50cyAoc3RhdGUsIHByb3BzLCBjb250ZXh0KS4gVGhlc2UgdmFsdWVzIGNhbiBiZSBkaWZmZXJlbnRcbiAqIGZyb20gdGhpcy4qIGJlY2F1c2UgeW91ciBmdW5jdGlvbiBtYXkgYmUgY2FsbGVkIGFmdGVyIHJlY2VpdmVQcm9wcyBidXQgYmVmb3JlXG4gKiBzaG91bGRDb21wb25lbnRVcGRhdGUsIGFuZCB0aGlzIG5ldyBzdGF0ZSwgcHJvcHMsIGFuZCBjb250ZXh0IHdpbGwgbm90IHlldCBiZVxuICogYXNzaWduZWQgdG8gdGhpcy5cbiAqXG4gKiBAcGFyYW0ge29iamVjdHxmdW5jdGlvbn0gcGFydGlhbFN0YXRlIE5leHQgcGFydGlhbCBzdGF0ZSBvciBmdW5jdGlvbiB0b1xuICogICAgICAgIHByb2R1Y2UgbmV4dCBwYXJ0aWFsIHN0YXRlIHRvIGJlIG1lcmdlZCB3aXRoIGN1cnJlbnQgc3RhdGUuXG4gKiBAcGFyYW0gez9mdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIGFmdGVyIHN0YXRlIGlzIHVwZGF0ZWQuXG4gKiBAZmluYWxcbiAqIEBwcm90ZWN0ZWRcbiAqL1xuXG5Db21wb25lbnQucHJvdG90eXBlLnNldFN0YXRlID0gZnVuY3Rpb24gKHBhcnRpYWxTdGF0ZSwgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBwYXJ0aWFsU3RhdGUgIT09ICdvYmplY3QnICYmIHR5cGVvZiBwYXJ0aWFsU3RhdGUgIT09ICdmdW5jdGlvbicgJiYgcGFydGlhbFN0YXRlICE9IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFN0YXRlKC4uLik6IHRha2VzIGFuIG9iamVjdCBvZiBzdGF0ZSB2YXJpYWJsZXMgdG8gdXBkYXRlIG9yIGEgJyArICdmdW5jdGlvbiB3aGljaCByZXR1cm5zIGFuIG9iamVjdCBvZiBzdGF0ZSB2YXJpYWJsZXMuJyk7XG4gIH1cblxuICB0aGlzLnVwZGF0ZXIuZW5xdWV1ZVNldFN0YXRlKHRoaXMsIHBhcnRpYWxTdGF0ZSwgY2FsbGJhY2ssICdzZXRTdGF0ZScpO1xufTtcbi8qKlxuICogRm9yY2VzIGFuIHVwZGF0ZS4gVGhpcyBzaG91bGQgb25seSBiZSBpbnZva2VkIHdoZW4gaXQgaXMga25vd24gd2l0aFxuICogY2VydGFpbnR5IHRoYXQgd2UgYXJlICoqbm90KiogaW4gYSBET00gdHJhbnNhY3Rpb24uXG4gKlxuICogWW91IG1heSB3YW50IHRvIGNhbGwgdGhpcyB3aGVuIHlvdSBrbm93IHRoYXQgc29tZSBkZWVwZXIgYXNwZWN0IG9mIHRoZVxuICogY29tcG9uZW50J3Mgc3RhdGUgaGFzIGNoYW5nZWQgYnV0IGBzZXRTdGF0ZWAgd2FzIG5vdCBjYWxsZWQuXG4gKlxuICogVGhpcyB3aWxsIG5vdCBpbnZva2UgYHNob3VsZENvbXBvbmVudFVwZGF0ZWAsIGJ1dCBpdCB3aWxsIGludm9rZVxuICogYGNvbXBvbmVudFdpbGxVcGRhdGVgIGFuZCBgY29tcG9uZW50RGlkVXBkYXRlYC5cbiAqXG4gKiBAcGFyYW0gez9mdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIGFmdGVyIHVwZGF0ZSBpcyBjb21wbGV0ZS5cbiAqIEBmaW5hbFxuICogQHByb3RlY3RlZFxuICovXG5cblxuQ29tcG9uZW50LnByb3RvdHlwZS5mb3JjZVVwZGF0ZSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICB0aGlzLnVwZGF0ZXIuZW5xdWV1ZUZvcmNlVXBkYXRlKHRoaXMsIGNhbGxiYWNrLCAnZm9yY2VVcGRhdGUnKTtcbn07XG4vKipcbiAqIERlcHJlY2F0ZWQgQVBJcy4gVGhlc2UgQVBJcyB1c2VkIHRvIGV4aXN0IG9uIGNsYXNzaWMgUmVhY3QgY2xhc3NlcyBidXQgc2luY2VcbiAqIHdlIHdvdWxkIGxpa2UgdG8gZGVwcmVjYXRlIHRoZW0sIHdlJ3JlIG5vdCBnb2luZyB0byBtb3ZlIHRoZW0gb3ZlciB0byB0aGlzXG4gKiBtb2Rlcm4gYmFzZSBjbGFzcy4gSW5zdGVhZCwgd2UgZGVmaW5lIGEgZ2V0dGVyIHRoYXQgd2FybnMgaWYgaXQncyBhY2Nlc3NlZC5cbiAqL1xuXG5cbntcbiAgdmFyIGRlcHJlY2F0ZWRBUElzID0ge1xuICAgIGlzTW91bnRlZDogWydpc01vdW50ZWQnLCAnSW5zdGVhZCwgbWFrZSBzdXJlIHRvIGNsZWFuIHVwIHN1YnNjcmlwdGlvbnMgYW5kIHBlbmRpbmcgcmVxdWVzdHMgaW4gJyArICdjb21wb25lbnRXaWxsVW5tb3VudCB0byBwcmV2ZW50IG1lbW9yeSBsZWFrcy4nXSxcbiAgICByZXBsYWNlU3RhdGU6IFsncmVwbGFjZVN0YXRlJywgJ1JlZmFjdG9yIHlvdXIgY29kZSB0byB1c2Ugc2V0U3RhdGUgaW5zdGVhZCAoc2VlICcgKyAnaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8zMjM2KS4nXVxuICB9O1xuXG4gIHZhciBkZWZpbmVEZXByZWNhdGlvbldhcm5pbmcgPSBmdW5jdGlvbiAobWV0aG9kTmFtZSwgaW5mbykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShDb21wb25lbnQucHJvdG90eXBlLCBtZXRob2ROYW1lLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2FybignJXMoLi4uKSBpcyBkZXByZWNhdGVkIGluIHBsYWluIEphdmFTY3JpcHQgUmVhY3QgY2xhc3Nlcy4gJXMnLCBpbmZvWzBdLCBpbmZvWzFdKTtcblxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIGZvciAodmFyIGZuTmFtZSBpbiBkZXByZWNhdGVkQVBJcykge1xuICAgIGlmIChkZXByZWNhdGVkQVBJcy5oYXNPd25Qcm9wZXJ0eShmbk5hbWUpKSB7XG4gICAgICBkZWZpbmVEZXByZWNhdGlvbldhcm5pbmcoZm5OYW1lLCBkZXByZWNhdGVkQVBJc1tmbk5hbWVdKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gQ29tcG9uZW50RHVtbXkoKSB7fVxuXG5Db21wb25lbnREdW1teS5wcm90b3R5cGUgPSBDb21wb25lbnQucHJvdG90eXBlO1xuLyoqXG4gKiBDb252ZW5pZW5jZSBjb21wb25lbnQgd2l0aCBkZWZhdWx0IHNoYWxsb3cgZXF1YWxpdHkgY2hlY2sgZm9yIHNDVS5cbiAqL1xuXG5mdW5jdGlvbiBQdXJlQ29tcG9uZW50KHByb3BzLCBjb250ZXh0LCB1cGRhdGVyKSB7XG4gIHRoaXMucHJvcHMgPSBwcm9wcztcbiAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsgLy8gSWYgYSBjb21wb25lbnQgaGFzIHN0cmluZyByZWZzLCB3ZSB3aWxsIGFzc2lnbiBhIGRpZmZlcmVudCBvYmplY3QgbGF0ZXIuXG5cbiAgdGhpcy5yZWZzID0gZW1wdHlPYmplY3Q7XG4gIHRoaXMudXBkYXRlciA9IHVwZGF0ZXIgfHwgUmVhY3ROb29wVXBkYXRlUXVldWU7XG59XG5cbnZhciBwdXJlQ29tcG9uZW50UHJvdG90eXBlID0gUHVyZUNvbXBvbmVudC5wcm90b3R5cGUgPSBuZXcgQ29tcG9uZW50RHVtbXkoKTtcbnB1cmVDb21wb25lbnRQcm90b3R5cGUuY29uc3RydWN0b3IgPSBQdXJlQ29tcG9uZW50OyAvLyBBdm9pZCBhbiBleHRyYSBwcm90b3R5cGUganVtcCBmb3IgdGhlc2UgbWV0aG9kcy5cblxuYXNzaWduKHB1cmVDb21wb25lbnRQcm90b3R5cGUsIENvbXBvbmVudC5wcm90b3R5cGUpO1xucHVyZUNvbXBvbmVudFByb3RvdHlwZS5pc1B1cmVSZWFjdENvbXBvbmVudCA9IHRydWU7XG5cbi8vIGFuIGltbXV0YWJsZSBvYmplY3Qgd2l0aCBhIHNpbmdsZSBtdXRhYmxlIHZhbHVlXG5mdW5jdGlvbiBjcmVhdGVSZWYoKSB7XG4gIHZhciByZWZPYmplY3QgPSB7XG4gICAgY3VycmVudDogbnVsbFxuICB9O1xuXG4gIHtcbiAgICBPYmplY3Quc2VhbChyZWZPYmplY3QpO1xuICB9XG5cbiAgcmV0dXJuIHJlZk9iamVjdDtcbn1cblxudmFyIGlzQXJyYXlJbXBsID0gQXJyYXkuaXNBcnJheTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlZGVjbGFyZVxuXG5mdW5jdGlvbiBpc0FycmF5KGEpIHtcbiAgcmV0dXJuIGlzQXJyYXlJbXBsKGEpO1xufVxuXG4vKlxuICogVGhlIGAnJyArIHZhbHVlYCBwYXR0ZXJuICh1c2VkIGluIGluIHBlcmYtc2Vuc2l0aXZlIGNvZGUpIHRocm93cyBmb3IgU3ltYm9sXG4gKiBhbmQgVGVtcG9yYWwuKiB0eXBlcy4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzIyMDY0LlxuICpcbiAqIFRoZSBmdW5jdGlvbnMgaW4gdGhpcyBtb2R1bGUgd2lsbCB0aHJvdyBhbiBlYXNpZXItdG8tdW5kZXJzdGFuZCxcbiAqIGVhc2llci10by1kZWJ1ZyBleGNlcHRpb24gd2l0aCBhIGNsZWFyIGVycm9ycyBtZXNzYWdlIG1lc3NhZ2UgZXhwbGFpbmluZyB0aGVcbiAqIHByb2JsZW0uIChJbnN0ZWFkIG9mIGEgY29uZnVzaW5nIGV4Y2VwdGlvbiB0aHJvd24gaW5zaWRlIHRoZSBpbXBsZW1lbnRhdGlvblxuICogb2YgdGhlIGB2YWx1ZWAgb2JqZWN0KS5cbiAqL1xuLy8gJEZsb3dGaXhNZSBvbmx5IGNhbGxlZCBpbiBERVYsIHNvIHZvaWQgcmV0dXJuIGlzIG5vdCBwb3NzaWJsZS5cbmZ1bmN0aW9uIHR5cGVOYW1lKHZhbHVlKSB7XG4gIHtcbiAgICAvLyB0b1N0cmluZ1RhZyBpcyBuZWVkZWQgZm9yIG5hbWVzcGFjZWQgdHlwZXMgbGlrZSBUZW1wb3JhbC5JbnN0YW50XG4gICAgdmFyIGhhc1RvU3RyaW5nVGFnID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wudG9TdHJpbmdUYWc7XG4gICAgdmFyIHR5cGUgPSBoYXNUb1N0cmluZ1RhZyAmJiB2YWx1ZVtTeW1ib2wudG9TdHJpbmdUYWddIHx8IHZhbHVlLmNvbnN0cnVjdG9yLm5hbWUgfHwgJ09iamVjdCc7XG4gICAgcmV0dXJuIHR5cGU7XG4gIH1cbn0gLy8gJEZsb3dGaXhNZSBvbmx5IGNhbGxlZCBpbiBERVYsIHNvIHZvaWQgcmV0dXJuIGlzIG5vdCBwb3NzaWJsZS5cblxuXG5mdW5jdGlvbiB3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkge1xuICB7XG4gICAgdHJ5IHtcbiAgICAgIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSkge1xuICAvLyBJZiB5b3UgZW5kZWQgdXAgaGVyZSBieSBmb2xsb3dpbmcgYW4gZXhjZXB0aW9uIGNhbGwgc3RhY2ssIGhlcmUncyB3aGF0J3NcbiAgLy8gaGFwcGVuZWQ6IHlvdSBzdXBwbGllZCBhbiBvYmplY3Qgb3Igc3ltYm9sIHZhbHVlIHRvIFJlYWN0IChhcyBhIHByb3AsIGtleSxcbiAgLy8gRE9NIGF0dHJpYnV0ZSwgQ1NTIHByb3BlcnR5LCBzdHJpbmcgcmVmLCBldGMuKSBhbmQgd2hlbiBSZWFjdCB0cmllZCB0b1xuICAvLyBjb2VyY2UgaXQgdG8gYSBzdHJpbmcgdXNpbmcgYCcnICsgdmFsdWVgLCBhbiBleGNlcHRpb24gd2FzIHRocm93bi5cbiAgLy9cbiAgLy8gVGhlIG1vc3QgY29tbW9uIHR5cGVzIHRoYXQgd2lsbCBjYXVzZSB0aGlzIGV4Y2VwdGlvbiBhcmUgYFN5bWJvbGAgaW5zdGFuY2VzXG4gIC8vIGFuZCBUZW1wb3JhbCBvYmplY3RzIGxpa2UgYFRlbXBvcmFsLkluc3RhbnRgLiBCdXQgYW55IG9iamVjdCB0aGF0IGhhcyBhXG4gIC8vIGB2YWx1ZU9mYCBvciBgW1N5bWJvbC50b1ByaW1pdGl2ZV1gIG1ldGhvZCB0aGF0IHRocm93cyB3aWxsIGFsc28gY2F1c2UgdGhpc1xuICAvLyBleGNlcHRpb24uIChMaWJyYXJ5IGF1dGhvcnMgZG8gdGhpcyB0byBwcmV2ZW50IHVzZXJzIGZyb20gdXNpbmcgYnVpbHQtaW5cbiAgLy8gbnVtZXJpYyBvcGVyYXRvcnMgbGlrZSBgK2Agb3IgY29tcGFyaXNvbiBvcGVyYXRvcnMgbGlrZSBgPj1gIGJlY2F1c2UgY3VzdG9tXG4gIC8vIG1ldGhvZHMgYXJlIG5lZWRlZCB0byBwZXJmb3JtIGFjY3VyYXRlIGFyaXRobWV0aWMgb3IgY29tcGFyaXNvbi4pXG4gIC8vXG4gIC8vIFRvIGZpeCB0aGUgcHJvYmxlbSwgY29lcmNlIHRoaXMgb2JqZWN0IG9yIHN5bWJvbCB2YWx1ZSB0byBhIHN0cmluZyBiZWZvcmVcbiAgLy8gcGFzc2luZyBpdCB0byBSZWFjdC4gVGhlIG1vc3QgcmVsaWFibGUgd2F5IGlzIHVzdWFsbHkgYFN0cmluZyh2YWx1ZSlgLlxuICAvL1xuICAvLyBUbyBmaW5kIHdoaWNoIHZhbHVlIGlzIHRocm93aW5nLCBjaGVjayB0aGUgYnJvd3NlciBvciBkZWJ1Z2dlciBjb25zb2xlLlxuICAvLyBCZWZvcmUgdGhpcyBleGNlcHRpb24gd2FzIHRocm93biwgdGhlcmUgc2hvdWxkIGJlIGBjb25zb2xlLmVycm9yYCBvdXRwdXRcbiAgLy8gdGhhdCBzaG93cyB0aGUgdHlwZSAoU3ltYm9sLCBUZW1wb3JhbC5QbGFpbkRhdGUsIGV0Yy4pIHRoYXQgY2F1c2VkIHRoZVxuICAvLyBwcm9ibGVtIGFuZCBob3cgdGhhdCB0eXBlIHdhcyB1c2VkOiBrZXksIGF0cnJpYnV0ZSwgaW5wdXQgdmFsdWUgcHJvcCwgZXRjLlxuICAvLyBJbiBtb3N0IGNhc2VzLCB0aGlzIGNvbnNvbGUgb3V0cHV0IGFsc28gc2hvd3MgdGhlIGNvbXBvbmVudCBhbmQgaXRzXG4gIC8vIGFuY2VzdG9yIGNvbXBvbmVudHMgd2hlcmUgdGhlIGV4Y2VwdGlvbiBoYXBwZW5lZC5cbiAgLy9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3NhZmUtc3RyaW5nLWNvZXJjaW9uXG4gIHJldHVybiAnJyArIHZhbHVlO1xufVxuZnVuY3Rpb24gY2hlY2tLZXlTdHJpbmdDb2VyY2lvbih2YWx1ZSkge1xuICB7XG4gICAgaWYgKHdpbGxDb2VyY2lvblRocm93KHZhbHVlKSkge1xuICAgICAgZXJyb3IoJ1RoZSBwcm92aWRlZCBrZXkgaXMgYW4gdW5zdXBwb3J0ZWQgdHlwZSAlcy4nICsgJyBUaGlzIHZhbHVlIG11c3QgYmUgY29lcmNlZCB0byBhIHN0cmluZyBiZWZvcmUgYmVmb3JlIHVzaW5nIGl0IGhlcmUuJywgdHlwZU5hbWUodmFsdWUpKTtcblxuICAgICAgcmV0dXJuIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSk7IC8vIHRocm93ICh0byBoZWxwIGNhbGxlcnMgZmluZCB0cm91Ymxlc2hvb3RpbmcgY29tbWVudHMpXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldFdyYXBwZWROYW1lKG91dGVyVHlwZSwgaW5uZXJUeXBlLCB3cmFwcGVyTmFtZSkge1xuICB2YXIgZGlzcGxheU5hbWUgPSBvdXRlclR5cGUuZGlzcGxheU5hbWU7XG5cbiAgaWYgKGRpc3BsYXlOYW1lKSB7XG4gICAgcmV0dXJuIGRpc3BsYXlOYW1lO1xuICB9XG5cbiAgdmFyIGZ1bmN0aW9uTmFtZSA9IGlubmVyVHlwZS5kaXNwbGF5TmFtZSB8fCBpbm5lclR5cGUubmFtZSB8fCAnJztcbiAgcmV0dXJuIGZ1bmN0aW9uTmFtZSAhPT0gJycgPyB3cmFwcGVyTmFtZSArIFwiKFwiICsgZnVuY3Rpb25OYW1lICsgXCIpXCIgOiB3cmFwcGVyTmFtZTtcbn0gLy8gS2VlcCBpbiBzeW5jIHdpdGggcmVhY3QtcmVjb25jaWxlci9nZXRDb21wb25lbnROYW1lRnJvbUZpYmVyXG5cblxuZnVuY3Rpb24gZ2V0Q29udGV4dE5hbWUodHlwZSkge1xuICByZXR1cm4gdHlwZS5kaXNwbGF5TmFtZSB8fCAnQ29udGV4dCc7XG59IC8vIE5vdGUgdGhhdCB0aGUgcmVjb25jaWxlciBwYWNrYWdlIHNob3VsZCBnZW5lcmFsbHkgcHJlZmVyIHRvIHVzZSBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKCkgaW5zdGVhZC5cblxuXG5mdW5jdGlvbiBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZSkge1xuICBpZiAodHlwZSA9PSBudWxsKSB7XG4gICAgLy8gSG9zdCByb290LCB0ZXh0IG5vZGUgb3IganVzdCBpbnZhbGlkIHR5cGUuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB7XG4gICAgaWYgKHR5cGVvZiB0eXBlLnRhZyA9PT0gJ251bWJlcicpIHtcbiAgICAgIGVycm9yKCdSZWNlaXZlZCBhbiB1bmV4cGVjdGVkIG9iamVjdCBpbiBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoKS4gJyArICdUaGlzIGlzIGxpa2VseSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHR5cGUuZGlzcGxheU5hbWUgfHwgdHlwZS5uYW1lIHx8IG51bGw7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHR5cGU7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIFJFQUNUX0ZSQUdNRU5UX1RZUEU6XG4gICAgICByZXR1cm4gJ0ZyYWdtZW50JztcblxuICAgIGNhc2UgUkVBQ1RfUE9SVEFMX1RZUEU6XG4gICAgICByZXR1cm4gJ1BvcnRhbCc7XG5cbiAgICBjYXNlIFJFQUNUX1BST0ZJTEVSX1RZUEU6XG4gICAgICByZXR1cm4gJ1Byb2ZpbGVyJztcblxuICAgIGNhc2UgUkVBQ1RfU1RSSUNUX01PREVfVFlQRTpcbiAgICAgIHJldHVybiAnU3RyaWN0TW9kZSc7XG5cbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX1RZUEU6XG4gICAgICByZXR1cm4gJ1N1c3BlbnNlJztcblxuICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfTElTVF9UWVBFOlxuICAgICAgcmV0dXJuICdTdXNwZW5zZUxpc3QnO1xuXG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgc3dpdGNoICh0eXBlLiQkdHlwZW9mKSB7XG4gICAgICBjYXNlIFJFQUNUX0NPTlRFWFRfVFlQRTpcbiAgICAgICAgdmFyIGNvbnRleHQgPSB0eXBlO1xuICAgICAgICByZXR1cm4gZ2V0Q29udGV4dE5hbWUoY29udGV4dCkgKyAnLkNvbnN1bWVyJztcblxuICAgICAgY2FzZSBSRUFDVF9QUk9WSURFUl9UWVBFOlxuICAgICAgICB2YXIgcHJvdmlkZXIgPSB0eXBlO1xuICAgICAgICByZXR1cm4gZ2V0Q29udGV4dE5hbWUocHJvdmlkZXIuX2NvbnRleHQpICsgJy5Qcm92aWRlcic7XG5cbiAgICAgIGNhc2UgUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRTpcbiAgICAgICAgcmV0dXJuIGdldFdyYXBwZWROYW1lKHR5cGUsIHR5cGUucmVuZGVyLCAnRm9yd2FyZFJlZicpO1xuXG4gICAgICBjYXNlIFJFQUNUX01FTU9fVFlQRTpcbiAgICAgICAgdmFyIG91dGVyTmFtZSA9IHR5cGUuZGlzcGxheU5hbWUgfHwgbnVsbDtcblxuICAgICAgICBpZiAob3V0ZXJOYW1lICE9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIG91dGVyTmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZS50eXBlKSB8fCAnTWVtbyc7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIGxhenlDb21wb25lbnQgPSB0eXBlO1xuICAgICAgICAgIHZhciBwYXlsb2FkID0gbGF6eUNvbXBvbmVudC5fcGF5bG9hZDtcbiAgICAgICAgICB2YXIgaW5pdCA9IGxhenlDb21wb25lbnQuX2luaXQ7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShpbml0KHBheWxvYWQpKTtcbiAgICAgICAgICB9IGNhdGNoICh4KSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWZhbGx0aHJvdWdoXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbnZhciBSRVNFUlZFRF9QUk9QUyA9IHtcbiAga2V5OiB0cnVlLFxuICByZWY6IHRydWUsXG4gIF9fc2VsZjogdHJ1ZSxcbiAgX19zb3VyY2U6IHRydWVcbn07XG52YXIgc3BlY2lhbFByb3BLZXlXYXJuaW5nU2hvd24sIHNwZWNpYWxQcm9wUmVmV2FybmluZ1Nob3duLCBkaWRXYXJuQWJvdXRTdHJpbmdSZWZzO1xuXG57XG4gIGRpZFdhcm5BYm91dFN0cmluZ1JlZnMgPSB7fTtcbn1cblxuZnVuY3Rpb24gaGFzVmFsaWRSZWYoY29uZmlnKSB7XG4gIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChjb25maWcsICdyZWYnKSkge1xuICAgICAgdmFyIGdldHRlciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoY29uZmlnLCAncmVmJykuZ2V0O1xuXG4gICAgICBpZiAoZ2V0dGVyICYmIGdldHRlci5pc1JlYWN0V2FybmluZykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvbmZpZy5yZWYgIT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaGFzVmFsaWRLZXkoY29uZmlnKSB7XG4gIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChjb25maWcsICdrZXknKSkge1xuICAgICAgdmFyIGdldHRlciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoY29uZmlnLCAna2V5JykuZ2V0O1xuXG4gICAgICBpZiAoZ2V0dGVyICYmIGdldHRlci5pc1JlYWN0V2FybmluZykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvbmZpZy5rZXkgIT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gZGVmaW5lS2V5UHJvcFdhcm5pbmdHZXR0ZXIocHJvcHMsIGRpc3BsYXlOYW1lKSB7XG4gIHZhciB3YXJuQWJvdXRBY2Nlc3NpbmdLZXkgPSBmdW5jdGlvbiAoKSB7XG4gICAge1xuICAgICAgaWYgKCFzcGVjaWFsUHJvcEtleVdhcm5pbmdTaG93bikge1xuICAgICAgICBzcGVjaWFsUHJvcEtleVdhcm5pbmdTaG93biA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJyVzOiBga2V5YCBpcyBub3QgYSBwcm9wLiBUcnlpbmcgdG8gYWNjZXNzIGl0IHdpbGwgcmVzdWx0ICcgKyAnaW4gYHVuZGVmaW5lZGAgYmVpbmcgcmV0dXJuZWQuIElmIHlvdSBuZWVkIHRvIGFjY2VzcyB0aGUgc2FtZSAnICsgJ3ZhbHVlIHdpdGhpbiB0aGUgY2hpbGQgY29tcG9uZW50LCB5b3Ugc2hvdWxkIHBhc3MgaXQgYXMgYSBkaWZmZXJlbnQgJyArICdwcm9wLiAoaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3NwZWNpYWwtcHJvcHMpJywgZGlzcGxheU5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB3YXJuQWJvdXRBY2Nlc3NpbmdLZXkuaXNSZWFjdFdhcm5pbmcgPSB0cnVlO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvcHMsICdrZXknLCB7XG4gICAgZ2V0OiB3YXJuQWJvdXRBY2Nlc3NpbmdLZXksXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBkZWZpbmVSZWZQcm9wV2FybmluZ0dldHRlcihwcm9wcywgZGlzcGxheU5hbWUpIHtcbiAgdmFyIHdhcm5BYm91dEFjY2Vzc2luZ1JlZiA9IGZ1bmN0aW9uICgpIHtcbiAgICB7XG4gICAgICBpZiAoIXNwZWNpYWxQcm9wUmVmV2FybmluZ1Nob3duKSB7XG4gICAgICAgIHNwZWNpYWxQcm9wUmVmV2FybmluZ1Nob3duID0gdHJ1ZTtcblxuICAgICAgICBlcnJvcignJXM6IGByZWZgIGlzIG5vdCBhIHByb3AuIFRyeWluZyB0byBhY2Nlc3MgaXQgd2lsbCByZXN1bHQgJyArICdpbiBgdW5kZWZpbmVkYCBiZWluZyByZXR1cm5lZC4gSWYgeW91IG5lZWQgdG8gYWNjZXNzIHRoZSBzYW1lICcgKyAndmFsdWUgd2l0aGluIHRoZSBjaGlsZCBjb21wb25lbnQsIHlvdSBzaG91bGQgcGFzcyBpdCBhcyBhIGRpZmZlcmVudCAnICsgJ3Byb3AuIChodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3BlY2lhbC1wcm9wcyknLCBkaXNwbGF5TmFtZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHdhcm5BYm91dEFjY2Vzc2luZ1JlZi5pc1JlYWN0V2FybmluZyA9IHRydWU7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm9wcywgJ3JlZicsIHtcbiAgICBnZXQ6IHdhcm5BYm91dEFjY2Vzc2luZ1JlZixcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHdhcm5JZlN0cmluZ1JlZkNhbm5vdEJlQXV0b0NvbnZlcnRlZChjb25maWcpIHtcbiAge1xuICAgIGlmICh0eXBlb2YgY29uZmlnLnJlZiA9PT0gJ3N0cmluZycgJiYgUmVhY3RDdXJyZW50T3duZXIuY3VycmVudCAmJiBjb25maWcuX19zZWxmICYmIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQuc3RhdGVOb2RlICE9PSBjb25maWcuX19zZWxmKSB7XG4gICAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50LnR5cGUpO1xuXG4gICAgICBpZiAoIWRpZFdhcm5BYm91dFN0cmluZ1JlZnNbY29tcG9uZW50TmFtZV0pIHtcbiAgICAgICAgZXJyb3IoJ0NvbXBvbmVudCBcIiVzXCIgY29udGFpbnMgdGhlIHN0cmluZyByZWYgXCIlc1wiLiAnICsgJ1N1cHBvcnQgZm9yIHN0cmluZyByZWZzIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSBtYWpvciByZWxlYXNlLiAnICsgJ1RoaXMgY2FzZSBjYW5ub3QgYmUgYXV0b21hdGljYWxseSBjb252ZXJ0ZWQgdG8gYW4gYXJyb3cgZnVuY3Rpb24uICcgKyAnV2UgYXNrIHlvdSB0byBtYW51YWxseSBmaXggdGhpcyBjYXNlIGJ5IHVzaW5nIHVzZVJlZigpIG9yIGNyZWF0ZVJlZigpIGluc3RlYWQuICcgKyAnTGVhcm4gbW9yZSBhYm91dCB1c2luZyByZWZzIHNhZmVseSBoZXJlOiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zdHJpY3QtbW9kZS1zdHJpbmctcmVmJywgY29tcG9uZW50TmFtZSwgY29uZmlnLnJlZik7XG5cbiAgICAgICAgZGlkV2FybkFib3V0U3RyaW5nUmVmc1tjb21wb25lbnROYW1lXSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEZhY3RvcnkgbWV0aG9kIHRvIGNyZWF0ZSBhIG5ldyBSZWFjdCBlbGVtZW50LiBUaGlzIG5vIGxvbmdlciBhZGhlcmVzIHRvXG4gKiB0aGUgY2xhc3MgcGF0dGVybiwgc28gZG8gbm90IHVzZSBuZXcgdG8gY2FsbCBpdC4gQWxzbywgaW5zdGFuY2VvZiBjaGVja1xuICogd2lsbCBub3Qgd29yay4gSW5zdGVhZCB0ZXN0ICQkdHlwZW9mIGZpZWxkIGFnYWluc3QgU3ltYm9sLmZvcigncmVhY3QuZWxlbWVudCcpIHRvIGNoZWNrXG4gKiBpZiBzb21ldGhpbmcgaXMgYSBSZWFjdCBFbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7Kn0gdHlwZVxuICogQHBhcmFtIHsqfSBwcm9wc1xuICogQHBhcmFtIHsqfSBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdH0gcmVmXG4gKiBAcGFyYW0geyp9IG93bmVyXG4gKiBAcGFyYW0geyp9IHNlbGYgQSAqdGVtcG9yYXJ5KiBoZWxwZXIgdG8gZGV0ZWN0IHBsYWNlcyB3aGVyZSBgdGhpc2AgaXNcbiAqIGRpZmZlcmVudCBmcm9tIHRoZSBgb3duZXJgIHdoZW4gUmVhY3QuY3JlYXRlRWxlbWVudCBpcyBjYWxsZWQsIHNvIHRoYXQgd2VcbiAqIGNhbiB3YXJuLiBXZSB3YW50IHRvIGdldCByaWQgb2Ygb3duZXIgYW5kIHJlcGxhY2Ugc3RyaW5nIGByZWZgcyB3aXRoIGFycm93XG4gKiBmdW5jdGlvbnMsIGFuZCBhcyBsb25nIGFzIGB0aGlzYCBhbmQgb3duZXIgYXJlIHRoZSBzYW1lLCB0aGVyZSB3aWxsIGJlIG5vXG4gKiBjaGFuZ2UgaW4gYmVoYXZpb3IuXG4gKiBAcGFyYW0geyp9IHNvdXJjZSBBbiBhbm5vdGF0aW9uIG9iamVjdCAoYWRkZWQgYnkgYSB0cmFuc3BpbGVyIG9yIG90aGVyd2lzZSlcbiAqIGluZGljYXRpbmcgZmlsZW5hbWUsIGxpbmUgbnVtYmVyLCBhbmQvb3Igb3RoZXIgaW5mb3JtYXRpb24uXG4gKiBAaW50ZXJuYWxcbiAqL1xuXG5cbnZhciBSZWFjdEVsZW1lbnQgPSBmdW5jdGlvbiAodHlwZSwga2V5LCByZWYsIHNlbGYsIHNvdXJjZSwgb3duZXIsIHByb3BzKSB7XG4gIHZhciBlbGVtZW50ID0ge1xuICAgIC8vIFRoaXMgdGFnIGFsbG93cyB1cyB0byB1bmlxdWVseSBpZGVudGlmeSB0aGlzIGFzIGEgUmVhY3QgRWxlbWVudFxuICAgICQkdHlwZW9mOiBSRUFDVF9FTEVNRU5UX1RZUEUsXG4gICAgLy8gQnVpbHQtaW4gcHJvcGVydGllcyB0aGF0IGJlbG9uZyBvbiB0aGUgZWxlbWVudFxuICAgIHR5cGU6IHR5cGUsXG4gICAga2V5OiBrZXksXG4gICAgcmVmOiByZWYsXG4gICAgcHJvcHM6IHByb3BzLFxuICAgIC8vIFJlY29yZCB0aGUgY29tcG9uZW50IHJlc3BvbnNpYmxlIGZvciBjcmVhdGluZyB0aGlzIGVsZW1lbnQuXG4gICAgX293bmVyOiBvd25lclxuICB9O1xuXG4gIHtcbiAgICAvLyBUaGUgdmFsaWRhdGlvbiBmbGFnIGlzIGN1cnJlbnRseSBtdXRhdGl2ZS4gV2UgcHV0IGl0IG9uXG4gICAgLy8gYW4gZXh0ZXJuYWwgYmFja2luZyBzdG9yZSBzbyB0aGF0IHdlIGNhbiBmcmVlemUgdGhlIHdob2xlIG9iamVjdC5cbiAgICAvLyBUaGlzIGNhbiBiZSByZXBsYWNlZCB3aXRoIGEgV2Vha01hcCBvbmNlIHRoZXkgYXJlIGltcGxlbWVudGVkIGluXG4gICAgLy8gY29tbW9ubHkgdXNlZCBkZXZlbG9wbWVudCBlbnZpcm9ubWVudHMuXG4gICAgZWxlbWVudC5fc3RvcmUgPSB7fTsgLy8gVG8gbWFrZSBjb21wYXJpbmcgUmVhY3RFbGVtZW50cyBlYXNpZXIgZm9yIHRlc3RpbmcgcHVycG9zZXMsIHdlIG1ha2VcbiAgICAvLyB0aGUgdmFsaWRhdGlvbiBmbGFnIG5vbi1lbnVtZXJhYmxlICh3aGVyZSBwb3NzaWJsZSwgd2hpY2ggc2hvdWxkXG4gICAgLy8gaW5jbHVkZSBldmVyeSBlbnZpcm9ubWVudCB3ZSBydW4gdGVzdHMgaW4pLCBzbyB0aGUgdGVzdCBmcmFtZXdvcmtcbiAgICAvLyBpZ25vcmVzIGl0LlxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGVsZW1lbnQuX3N0b3JlLCAndmFsaWRhdGVkJywge1xuICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICB2YWx1ZTogZmFsc2VcbiAgICB9KTsgLy8gc2VsZiBhbmQgc291cmNlIGFyZSBERVYgb25seSBwcm9wZXJ0aWVzLlxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGVsZW1lbnQsICdfc2VsZicsIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIHZhbHVlOiBzZWxmXG4gICAgfSk7IC8vIFR3byBlbGVtZW50cyBjcmVhdGVkIGluIHR3byBkaWZmZXJlbnQgcGxhY2VzIHNob3VsZCBiZSBjb25zaWRlcmVkXG4gICAgLy8gZXF1YWwgZm9yIHRlc3RpbmcgcHVycG9zZXMgYW5kIHRoZXJlZm9yZSB3ZSBoaWRlIGl0IGZyb20gZW51bWVyYXRpb24uXG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZWxlbWVudCwgJ19zb3VyY2UnLCB7XG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICB2YWx1ZTogc291cmNlXG4gICAgfSk7XG5cbiAgICBpZiAoT2JqZWN0LmZyZWV6ZSkge1xuICAgICAgT2JqZWN0LmZyZWV6ZShlbGVtZW50LnByb3BzKTtcbiAgICAgIE9iamVjdC5mcmVlemUoZWxlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59O1xuLyoqXG4gKiBDcmVhdGUgYW5kIHJldHVybiBhIG5ldyBSZWFjdEVsZW1lbnQgb2YgdGhlIGdpdmVuIHR5cGUuXG4gKiBTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9kb2NzL3JlYWN0LWFwaS5odG1sI2NyZWF0ZWVsZW1lbnRcbiAqL1xuXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50KHR5cGUsIGNvbmZpZywgY2hpbGRyZW4pIHtcbiAgdmFyIHByb3BOYW1lOyAvLyBSZXNlcnZlZCBuYW1lcyBhcmUgZXh0cmFjdGVkXG5cbiAgdmFyIHByb3BzID0ge307XG4gIHZhciBrZXkgPSBudWxsO1xuICB2YXIgcmVmID0gbnVsbDtcbiAgdmFyIHNlbGYgPSBudWxsO1xuICB2YXIgc291cmNlID0gbnVsbDtcblxuICBpZiAoY29uZmlnICE9IG51bGwpIHtcbiAgICBpZiAoaGFzVmFsaWRSZWYoY29uZmlnKSkge1xuICAgICAgcmVmID0gY29uZmlnLnJlZjtcblxuICAgICAge1xuICAgICAgICB3YXJuSWZTdHJpbmdSZWZDYW5ub3RCZUF1dG9Db252ZXJ0ZWQoY29uZmlnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaGFzVmFsaWRLZXkoY29uZmlnKSkge1xuICAgICAge1xuICAgICAgICBjaGVja0tleVN0cmluZ0NvZXJjaW9uKGNvbmZpZy5rZXkpO1xuICAgICAgfVxuXG4gICAgICBrZXkgPSAnJyArIGNvbmZpZy5rZXk7XG4gICAgfVxuXG4gICAgc2VsZiA9IGNvbmZpZy5fX3NlbGYgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBjb25maWcuX19zZWxmO1xuICAgIHNvdXJjZSA9IGNvbmZpZy5fX3NvdXJjZSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGNvbmZpZy5fX3NvdXJjZTsgLy8gUmVtYWluaW5nIHByb3BlcnRpZXMgYXJlIGFkZGVkIHRvIGEgbmV3IHByb3BzIG9iamVjdFxuXG4gICAgZm9yIChwcm9wTmFtZSBpbiBjb25maWcpIHtcbiAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGNvbmZpZywgcHJvcE5hbWUpICYmICFSRVNFUlZFRF9QUk9QUy5oYXNPd25Qcm9wZXJ0eShwcm9wTmFtZSkpIHtcbiAgICAgICAgcHJvcHNbcHJvcE5hbWVdID0gY29uZmlnW3Byb3BOYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gIH0gLy8gQ2hpbGRyZW4gY2FuIGJlIG1vcmUgdGhhbiBvbmUgYXJndW1lbnQsIGFuZCB0aG9zZSBhcmUgdHJhbnNmZXJyZWQgb250b1xuICAvLyB0aGUgbmV3bHkgYWxsb2NhdGVkIHByb3BzIG9iamVjdC5cblxuXG4gIHZhciBjaGlsZHJlbkxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGggLSAyO1xuXG4gIGlmIChjaGlsZHJlbkxlbmd0aCA9PT0gMSkge1xuICAgIHByb3BzLmNoaWxkcmVuID0gY2hpbGRyZW47XG4gIH0gZWxzZSBpZiAoY2hpbGRyZW5MZW5ndGggPiAxKSB7XG4gICAgdmFyIGNoaWxkQXJyYXkgPSBBcnJheShjaGlsZHJlbkxlbmd0aCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuTGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoaWxkQXJyYXlbaV0gPSBhcmd1bWVudHNbaSArIDJdO1xuICAgIH1cblxuICAgIHtcbiAgICAgIGlmIChPYmplY3QuZnJlZXplKSB7XG4gICAgICAgIE9iamVjdC5mcmVlemUoY2hpbGRBcnJheSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJvcHMuY2hpbGRyZW4gPSBjaGlsZEFycmF5O1xuICB9IC8vIFJlc29sdmUgZGVmYXVsdCBwcm9wc1xuXG5cbiAgaWYgKHR5cGUgJiYgdHlwZS5kZWZhdWx0UHJvcHMpIHtcbiAgICB2YXIgZGVmYXVsdFByb3BzID0gdHlwZS5kZWZhdWx0UHJvcHM7XG5cbiAgICBmb3IgKHByb3BOYW1lIGluIGRlZmF1bHRQcm9wcykge1xuICAgICAgaWYgKHByb3BzW3Byb3BOYW1lXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHByb3BzW3Byb3BOYW1lXSA9IGRlZmF1bHRQcm9wc1twcm9wTmFtZV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAge1xuICAgIGlmIChrZXkgfHwgcmVmKSB7XG4gICAgICB2YXIgZGlzcGxheU5hbWUgPSB0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJyA/IHR5cGUuZGlzcGxheU5hbWUgfHwgdHlwZS5uYW1lIHx8ICdVbmtub3duJyA6IHR5cGU7XG5cbiAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgZGVmaW5lS2V5UHJvcFdhcm5pbmdHZXR0ZXIocHJvcHMsIGRpc3BsYXlOYW1lKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlZikge1xuICAgICAgICBkZWZpbmVSZWZQcm9wV2FybmluZ0dldHRlcihwcm9wcywgZGlzcGxheU5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBSZWFjdEVsZW1lbnQodHlwZSwga2V5LCByZWYsIHNlbGYsIHNvdXJjZSwgUmVhY3RDdXJyZW50T3duZXIuY3VycmVudCwgcHJvcHMpO1xufVxuZnVuY3Rpb24gY2xvbmVBbmRSZXBsYWNlS2V5KG9sZEVsZW1lbnQsIG5ld0tleSkge1xuICB2YXIgbmV3RWxlbWVudCA9IFJlYWN0RWxlbWVudChvbGRFbGVtZW50LnR5cGUsIG5ld0tleSwgb2xkRWxlbWVudC5yZWYsIG9sZEVsZW1lbnQuX3NlbGYsIG9sZEVsZW1lbnQuX3NvdXJjZSwgb2xkRWxlbWVudC5fb3duZXIsIG9sZEVsZW1lbnQucHJvcHMpO1xuICByZXR1cm4gbmV3RWxlbWVudDtcbn1cbi8qKlxuICogQ2xvbmUgYW5kIHJldHVybiBhIG5ldyBSZWFjdEVsZW1lbnQgdXNpbmcgZWxlbWVudCBhcyB0aGUgc3RhcnRpbmcgcG9pbnQuXG4gKiBTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9kb2NzL3JlYWN0LWFwaS5odG1sI2Nsb25lZWxlbWVudFxuICovXG5cbmZ1bmN0aW9uIGNsb25lRWxlbWVudChlbGVtZW50LCBjb25maWcsIGNoaWxkcmVuKSB7XG4gIGlmIChlbGVtZW50ID09PSBudWxsIHx8IGVsZW1lbnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlJlYWN0LmNsb25lRWxlbWVudCguLi4pOiBUaGUgYXJndW1lbnQgbXVzdCBiZSBhIFJlYWN0IGVsZW1lbnQsIGJ1dCB5b3UgcGFzc2VkIFwiICsgZWxlbWVudCArIFwiLlwiKTtcbiAgfVxuXG4gIHZhciBwcm9wTmFtZTsgLy8gT3JpZ2luYWwgcHJvcHMgYXJlIGNvcGllZFxuXG4gIHZhciBwcm9wcyA9IGFzc2lnbih7fSwgZWxlbWVudC5wcm9wcyk7IC8vIFJlc2VydmVkIG5hbWVzIGFyZSBleHRyYWN0ZWRcblxuICB2YXIga2V5ID0gZWxlbWVudC5rZXk7XG4gIHZhciByZWYgPSBlbGVtZW50LnJlZjsgLy8gU2VsZiBpcyBwcmVzZXJ2ZWQgc2luY2UgdGhlIG93bmVyIGlzIHByZXNlcnZlZC5cblxuICB2YXIgc2VsZiA9IGVsZW1lbnQuX3NlbGY7IC8vIFNvdXJjZSBpcyBwcmVzZXJ2ZWQgc2luY2UgY2xvbmVFbGVtZW50IGlzIHVubGlrZWx5IHRvIGJlIHRhcmdldGVkIGJ5IGFcbiAgLy8gdHJhbnNwaWxlciwgYW5kIHRoZSBvcmlnaW5hbCBzb3VyY2UgaXMgcHJvYmFibHkgYSBiZXR0ZXIgaW5kaWNhdG9yIG9mIHRoZVxuICAvLyB0cnVlIG93bmVyLlxuXG4gIHZhciBzb3VyY2UgPSBlbGVtZW50Ll9zb3VyY2U7IC8vIE93bmVyIHdpbGwgYmUgcHJlc2VydmVkLCB1bmxlc3MgcmVmIGlzIG92ZXJyaWRkZW5cblxuICB2YXIgb3duZXIgPSBlbGVtZW50Ll9vd25lcjtcblxuICBpZiAoY29uZmlnICE9IG51bGwpIHtcbiAgICBpZiAoaGFzVmFsaWRSZWYoY29uZmlnKSkge1xuICAgICAgLy8gU2lsZW50bHkgc3RlYWwgdGhlIHJlZiBmcm9tIHRoZSBwYXJlbnQuXG4gICAgICByZWYgPSBjb25maWcucmVmO1xuICAgICAgb3duZXIgPSBSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50O1xuICAgIH1cblxuICAgIGlmIChoYXNWYWxpZEtleShjb25maWcpKSB7XG4gICAgICB7XG4gICAgICAgIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24oY29uZmlnLmtleSk7XG4gICAgICB9XG5cbiAgICAgIGtleSA9ICcnICsgY29uZmlnLmtleTtcbiAgICB9IC8vIFJlbWFpbmluZyBwcm9wZXJ0aWVzIG92ZXJyaWRlIGV4aXN0aW5nIHByb3BzXG5cblxuICAgIHZhciBkZWZhdWx0UHJvcHM7XG5cbiAgICBpZiAoZWxlbWVudC50eXBlICYmIGVsZW1lbnQudHlwZS5kZWZhdWx0UHJvcHMpIHtcbiAgICAgIGRlZmF1bHRQcm9wcyA9IGVsZW1lbnQudHlwZS5kZWZhdWx0UHJvcHM7XG4gICAgfVxuXG4gICAgZm9yIChwcm9wTmFtZSBpbiBjb25maWcpIHtcbiAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGNvbmZpZywgcHJvcE5hbWUpICYmICFSRVNFUlZFRF9QUk9QUy5oYXNPd25Qcm9wZXJ0eShwcm9wTmFtZSkpIHtcbiAgICAgICAgaWYgKGNvbmZpZ1twcm9wTmFtZV0gPT09IHVuZGVmaW5lZCAmJiBkZWZhdWx0UHJvcHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vIFJlc29sdmUgZGVmYXVsdCBwcm9wc1xuICAgICAgICAgIHByb3BzW3Byb3BOYW1lXSA9IGRlZmF1bHRQcm9wc1twcm9wTmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJvcHNbcHJvcE5hbWVdID0gY29uZmlnW3Byb3BOYW1lXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSAvLyBDaGlsZHJlbiBjYW4gYmUgbW9yZSB0aGFuIG9uZSBhcmd1bWVudCwgYW5kIHRob3NlIGFyZSB0cmFuc2ZlcnJlZCBvbnRvXG4gIC8vIHRoZSBuZXdseSBhbGxvY2F0ZWQgcHJvcHMgb2JqZWN0LlxuXG5cbiAgdmFyIGNoaWxkcmVuTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCAtIDI7XG5cbiAgaWYgKGNoaWxkcmVuTGVuZ3RoID09PSAxKSB7XG4gICAgcHJvcHMuY2hpbGRyZW4gPSBjaGlsZHJlbjtcbiAgfSBlbHNlIGlmIChjaGlsZHJlbkxlbmd0aCA+IDEpIHtcbiAgICB2YXIgY2hpbGRBcnJheSA9IEFycmF5KGNoaWxkcmVuTGVuZ3RoKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW5MZW5ndGg7IGkrKykge1xuICAgICAgY2hpbGRBcnJheVtpXSA9IGFyZ3VtZW50c1tpICsgMl07XG4gICAgfVxuXG4gICAgcHJvcHMuY2hpbGRyZW4gPSBjaGlsZEFycmF5O1xuICB9XG5cbiAgcmV0dXJuIFJlYWN0RWxlbWVudChlbGVtZW50LnR5cGUsIGtleSwgcmVmLCBzZWxmLCBzb3VyY2UsIG93bmVyLCBwcm9wcyk7XG59XG4vKipcbiAqIFZlcmlmaWVzIHRoZSBvYmplY3QgaXMgYSBSZWFjdEVsZW1lbnQuXG4gKiBTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9kb2NzL3JlYWN0LWFwaS5odG1sI2lzdmFsaWRlbGVtZW50XG4gKiBAcGFyYW0gez9vYmplY3R9IG9iamVjdFxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBgb2JqZWN0YCBpcyBhIFJlYWN0RWxlbWVudC5cbiAqIEBmaW5hbFxuICovXG5cbmZ1bmN0aW9uIGlzVmFsaWRFbGVtZW50KG9iamVjdCkge1xuICByZXR1cm4gdHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiYgb2JqZWN0ICE9PSBudWxsICYmIG9iamVjdC4kJHR5cGVvZiA9PT0gUkVBQ1RfRUxFTUVOVF9UWVBFO1xufVxuXG52YXIgU0VQQVJBVE9SID0gJy4nO1xudmFyIFNVQlNFUEFSQVRPUiA9ICc6Jztcbi8qKlxuICogRXNjYXBlIGFuZCB3cmFwIGtleSBzbyBpdCBpcyBzYWZlIHRvIHVzZSBhcyBhIHJlYWN0aWRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IHRvIGJlIGVzY2FwZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSBlc2NhcGVkIGtleS5cbiAqL1xuXG5mdW5jdGlvbiBlc2NhcGUoa2V5KSB7XG4gIHZhciBlc2NhcGVSZWdleCA9IC9bPTpdL2c7XG4gIHZhciBlc2NhcGVyTG9va3VwID0ge1xuICAgICc9JzogJz0wJyxcbiAgICAnOic6ICc9MidcbiAgfTtcbiAgdmFyIGVzY2FwZWRTdHJpbmcgPSBrZXkucmVwbGFjZShlc2NhcGVSZWdleCwgZnVuY3Rpb24gKG1hdGNoKSB7XG4gICAgcmV0dXJuIGVzY2FwZXJMb29rdXBbbWF0Y2hdO1xuICB9KTtcbiAgcmV0dXJuICckJyArIGVzY2FwZWRTdHJpbmc7XG59XG4vKipcbiAqIFRPRE86IFRlc3QgdGhhdCBhIHNpbmdsZSBjaGlsZCBhbmQgYW4gYXJyYXkgd2l0aCBvbmUgaXRlbSBoYXZlIHRoZSBzYW1lIGtleVxuICogcGF0dGVybi5cbiAqL1xuXG5cbnZhciBkaWRXYXJuQWJvdXRNYXBzID0gZmFsc2U7XG52YXIgdXNlclByb3ZpZGVkS2V5RXNjYXBlUmVnZXggPSAvXFwvKy9nO1xuXG5mdW5jdGlvbiBlc2NhcGVVc2VyUHJvdmlkZWRLZXkodGV4dCkge1xuICByZXR1cm4gdGV4dC5yZXBsYWNlKHVzZXJQcm92aWRlZEtleUVzY2FwZVJlZ2V4LCAnJCYvJyk7XG59XG4vKipcbiAqIEdlbmVyYXRlIGEga2V5IHN0cmluZyB0aGF0IGlkZW50aWZpZXMgYSBlbGVtZW50IHdpdGhpbiBhIHNldC5cbiAqXG4gKiBAcGFyYW0geyp9IGVsZW1lbnQgQSBlbGVtZW50IHRoYXQgY291bGQgY29udGFpbiBhIG1hbnVhbCBrZXkuXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXggSW5kZXggdGhhdCBpcyB1c2VkIGlmIGEgbWFudWFsIGtleSBpcyBub3QgcHJvdmlkZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cblxuXG5mdW5jdGlvbiBnZXRFbGVtZW50S2V5KGVsZW1lbnQsIGluZGV4KSB7XG4gIC8vIERvIHNvbWUgdHlwZWNoZWNraW5nIGhlcmUgc2luY2Ugd2UgY2FsbCB0aGlzIGJsaW5kbHkuIFdlIHdhbnQgdG8gZW5zdXJlXG4gIC8vIHRoYXQgd2UgZG9uJ3QgYmxvY2sgcG90ZW50aWFsIGZ1dHVyZSBFUyBBUElzLlxuICBpZiAodHlwZW9mIGVsZW1lbnQgPT09ICdvYmplY3QnICYmIGVsZW1lbnQgIT09IG51bGwgJiYgZWxlbWVudC5rZXkgIT0gbnVsbCkge1xuICAgIC8vIEV4cGxpY2l0IGtleVxuICAgIHtcbiAgICAgIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24oZWxlbWVudC5rZXkpO1xuICAgIH1cblxuICAgIHJldHVybiBlc2NhcGUoJycgKyBlbGVtZW50LmtleSk7XG4gIH0gLy8gSW1wbGljaXQga2V5IGRldGVybWluZWQgYnkgdGhlIGluZGV4IGluIHRoZSBzZXRcblxuXG4gIHJldHVybiBpbmRleC50b1N0cmluZygzNik7XG59XG5cbmZ1bmN0aW9uIG1hcEludG9BcnJheShjaGlsZHJlbiwgYXJyYXksIGVzY2FwZWRQcmVmaXgsIG5hbWVTb0ZhciwgY2FsbGJhY2spIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgY2hpbGRyZW47XG5cbiAgaWYgKHR5cGUgPT09ICd1bmRlZmluZWQnIHx8IHR5cGUgPT09ICdib29sZWFuJykge1xuICAgIC8vIEFsbCBvZiB0aGUgYWJvdmUgYXJlIHBlcmNlaXZlZCBhcyBudWxsLlxuICAgIGNoaWxkcmVuID0gbnVsbDtcbiAgfVxuXG4gIHZhciBpbnZva2VDYWxsYmFjayA9IGZhbHNlO1xuXG4gIGlmIChjaGlsZHJlbiA9PT0gbnVsbCkge1xuICAgIGludm9rZUNhbGxiYWNrID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICBjYXNlICdudW1iZXInOlxuICAgICAgICBpbnZva2VDYWxsYmFjayA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdvYmplY3QnOlxuICAgICAgICBzd2l0Y2ggKGNoaWxkcmVuLiQkdHlwZW9mKSB7XG4gICAgICAgICAgY2FzZSBSRUFDVF9FTEVNRU5UX1RZUEU6XG4gICAgICAgICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgICAgICAgIGludm9rZUNhbGxiYWNrID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgfVxuICB9XG5cbiAgaWYgKGludm9rZUNhbGxiYWNrKSB7XG4gICAgdmFyIF9jaGlsZCA9IGNoaWxkcmVuO1xuICAgIHZhciBtYXBwZWRDaGlsZCA9IGNhbGxiYWNrKF9jaGlsZCk7IC8vIElmIGl0J3MgdGhlIG9ubHkgY2hpbGQsIHRyZWF0IHRoZSBuYW1lIGFzIGlmIGl0IHdhcyB3cmFwcGVkIGluIGFuIGFycmF5XG4gICAgLy8gc28gdGhhdCBpdCdzIGNvbnNpc3RlbnQgaWYgdGhlIG51bWJlciBvZiBjaGlsZHJlbiBncm93czpcblxuICAgIHZhciBjaGlsZEtleSA9IG5hbWVTb0ZhciA9PT0gJycgPyBTRVBBUkFUT1IgKyBnZXRFbGVtZW50S2V5KF9jaGlsZCwgMCkgOiBuYW1lU29GYXI7XG5cbiAgICBpZiAoaXNBcnJheShtYXBwZWRDaGlsZCkpIHtcbiAgICAgIHZhciBlc2NhcGVkQ2hpbGRLZXkgPSAnJztcblxuICAgICAgaWYgKGNoaWxkS2V5ICE9IG51bGwpIHtcbiAgICAgICAgZXNjYXBlZENoaWxkS2V5ID0gZXNjYXBlVXNlclByb3ZpZGVkS2V5KGNoaWxkS2V5KSArICcvJztcbiAgICAgIH1cblxuICAgICAgbWFwSW50b0FycmF5KG1hcHBlZENoaWxkLCBhcnJheSwgZXNjYXBlZENoaWxkS2V5LCAnJywgZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgcmV0dXJuIGM7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKG1hcHBlZENoaWxkICE9IG51bGwpIHtcbiAgICAgIGlmIChpc1ZhbGlkRWxlbWVudChtYXBwZWRDaGlsZCkpIHtcbiAgICAgICAge1xuICAgICAgICAgIC8vIFRoZSBgaWZgIHN0YXRlbWVudCBoZXJlIHByZXZlbnRzIGF1dG8tZGlzYWJsaW5nIG9mIHRoZSBzYWZlXG4gICAgICAgICAgLy8gY29lcmNpb24gRVNMaW50IHJ1bGUsIHNvIHdlIG11c3QgbWFudWFsbHkgZGlzYWJsZSBpdCBiZWxvdy5cbiAgICAgICAgICAvLyAkRmxvd0ZpeE1lIEZsb3cgaW5jb3JyZWN0bHkgdGhpbmtzIFJlYWN0LlBvcnRhbCBkb2Vzbid0IGhhdmUgYSBrZXlcbiAgICAgICAgICBpZiAobWFwcGVkQ2hpbGQua2V5ICYmICghX2NoaWxkIHx8IF9jaGlsZC5rZXkgIT09IG1hcHBlZENoaWxkLmtleSkpIHtcbiAgICAgICAgICAgIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24obWFwcGVkQ2hpbGQua2V5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBtYXBwZWRDaGlsZCA9IGNsb25lQW5kUmVwbGFjZUtleShtYXBwZWRDaGlsZCwgLy8gS2VlcCBib3RoIHRoZSAobWFwcGVkKSBhbmQgb2xkIGtleXMgaWYgdGhleSBkaWZmZXIsIGp1c3QgYXNcbiAgICAgICAgLy8gdHJhdmVyc2VBbGxDaGlsZHJlbiB1c2VkIHRvIGRvIGZvciBvYmplY3RzIGFzIGNoaWxkcmVuXG4gICAgICAgIGVzY2FwZWRQcmVmaXggKyAoIC8vICRGbG93Rml4TWUgRmxvdyBpbmNvcnJlY3RseSB0aGlua3MgUmVhY3QuUG9ydGFsIGRvZXNuJ3QgaGF2ZSBhIGtleVxuICAgICAgICBtYXBwZWRDaGlsZC5rZXkgJiYgKCFfY2hpbGQgfHwgX2NoaWxkLmtleSAhPT0gbWFwcGVkQ2hpbGQua2V5KSA/IC8vICRGbG93Rml4TWUgRmxvdyBpbmNvcnJlY3RseSB0aGlua3MgZXhpc3RpbmcgZWxlbWVudCdzIGtleSBjYW4gYmUgYSBudW1iZXJcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3NhZmUtc3RyaW5nLWNvZXJjaW9uXG4gICAgICAgIGVzY2FwZVVzZXJQcm92aWRlZEtleSgnJyArIG1hcHBlZENoaWxkLmtleSkgKyAnLycgOiAnJykgKyBjaGlsZEtleSk7XG4gICAgICB9XG5cbiAgICAgIGFycmF5LnB1c2gobWFwcGVkQ2hpbGQpO1xuICAgIH1cblxuICAgIHJldHVybiAxO1xuICB9XG5cbiAgdmFyIGNoaWxkO1xuICB2YXIgbmV4dE5hbWU7XG4gIHZhciBzdWJ0cmVlQ291bnQgPSAwOyAvLyBDb3VudCBvZiBjaGlsZHJlbiBmb3VuZCBpbiB0aGUgY3VycmVudCBzdWJ0cmVlLlxuXG4gIHZhciBuZXh0TmFtZVByZWZpeCA9IG5hbWVTb0ZhciA9PT0gJycgPyBTRVBBUkFUT1IgOiBuYW1lU29GYXIgKyBTVUJTRVBBUkFUT1I7XG5cbiAgaWYgKGlzQXJyYXkoY2hpbGRyZW4pKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcbiAgICAgIG5leHROYW1lID0gbmV4dE5hbWVQcmVmaXggKyBnZXRFbGVtZW50S2V5KGNoaWxkLCBpKTtcbiAgICAgIHN1YnRyZWVDb3VudCArPSBtYXBJbnRvQXJyYXkoY2hpbGQsIGFycmF5LCBlc2NhcGVkUHJlZml4LCBuZXh0TmFtZSwgY2FsbGJhY2spO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgaXRlcmF0b3JGbiA9IGdldEl0ZXJhdG9yRm4oY2hpbGRyZW4pO1xuXG4gICAgaWYgKHR5cGVvZiBpdGVyYXRvckZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgaXRlcmFibGVDaGlsZHJlbiA9IGNoaWxkcmVuO1xuXG4gICAgICB7XG4gICAgICAgIC8vIFdhcm4gYWJvdXQgdXNpbmcgTWFwcyBhcyBjaGlsZHJlblxuICAgICAgICBpZiAoaXRlcmF0b3JGbiA9PT0gaXRlcmFibGVDaGlsZHJlbi5lbnRyaWVzKSB7XG4gICAgICAgICAgaWYgKCFkaWRXYXJuQWJvdXRNYXBzKSB7XG4gICAgICAgICAgICB3YXJuKCdVc2luZyBNYXBzIGFzIGNoaWxkcmVuIGlzIG5vdCBzdXBwb3J0ZWQuICcgKyAnVXNlIGFuIGFycmF5IG9mIGtleWVkIFJlYWN0RWxlbWVudHMgaW5zdGVhZC4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkaWRXYXJuQWJvdXRNYXBzID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYXRvckZuLmNhbGwoaXRlcmFibGVDaGlsZHJlbik7XG4gICAgICB2YXIgc3RlcDtcbiAgICAgIHZhciBpaSA9IDA7XG5cbiAgICAgIHdoaWxlICghKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgICAgY2hpbGQgPSBzdGVwLnZhbHVlO1xuICAgICAgICBuZXh0TmFtZSA9IG5leHROYW1lUHJlZml4ICsgZ2V0RWxlbWVudEtleShjaGlsZCwgaWkrKyk7XG4gICAgICAgIHN1YnRyZWVDb3VudCArPSBtYXBJbnRvQXJyYXkoY2hpbGQsIGFycmF5LCBlc2NhcGVkUHJlZml4LCBuZXh0TmFtZSwgY2FsbGJhY2spO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuICAgICAgdmFyIGNoaWxkcmVuU3RyaW5nID0gU3RyaW5nKGNoaWxkcmVuKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk9iamVjdHMgYXJlIG5vdCB2YWxpZCBhcyBhIFJlYWN0IGNoaWxkIChmb3VuZDogXCIgKyAoY2hpbGRyZW5TdHJpbmcgPT09ICdbb2JqZWN0IE9iamVjdF0nID8gJ29iamVjdCB3aXRoIGtleXMgeycgKyBPYmplY3Qua2V5cyhjaGlsZHJlbikuam9pbignLCAnKSArICd9JyA6IGNoaWxkcmVuU3RyaW5nKSArIFwiKS4gXCIgKyAnSWYgeW91IG1lYW50IHRvIHJlbmRlciBhIGNvbGxlY3Rpb24gb2YgY2hpbGRyZW4sIHVzZSBhbiBhcnJheSAnICsgJ2luc3RlYWQuJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHN1YnRyZWVDb3VudDtcbn1cblxuLyoqXG4gKiBNYXBzIGNoaWxkcmVuIHRoYXQgYXJlIHR5cGljYWxseSBzcGVjaWZpZWQgYXMgYHByb3BzLmNoaWxkcmVuYC5cbiAqXG4gKiBTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9kb2NzL3JlYWN0LWFwaS5odG1sI3JlYWN0Y2hpbGRyZW5tYXBcbiAqXG4gKiBUaGUgcHJvdmlkZWQgbWFwRnVuY3Rpb24oY2hpbGQsIGluZGV4KSB3aWxsIGJlIGNhbGxlZCBmb3IgZWFjaFxuICogbGVhZiBjaGlsZC5cbiAqXG4gKiBAcGFyYW0gez8qfSBjaGlsZHJlbiBDaGlsZHJlbiB0cmVlIGNvbnRhaW5lci5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKiwgaW50KX0gZnVuYyBUaGUgbWFwIGZ1bmN0aW9uLlxuICogQHBhcmFtIHsqfSBjb250ZXh0IENvbnRleHQgZm9yIG1hcEZ1bmN0aW9uLlxuICogQHJldHVybiB7b2JqZWN0fSBPYmplY3QgY29udGFpbmluZyB0aGUgb3JkZXJlZCBtYXAgb2YgcmVzdWx0cy5cbiAqL1xuZnVuY3Rpb24gbWFwQ2hpbGRyZW4oY2hpbGRyZW4sIGZ1bmMsIGNvbnRleHQpIHtcbiAgaWYgKGNoaWxkcmVuID09IG51bGwpIHtcbiAgICByZXR1cm4gY2hpbGRyZW47XG4gIH1cblxuICB2YXIgcmVzdWx0ID0gW107XG4gIHZhciBjb3VudCA9IDA7XG4gIG1hcEludG9BcnJheShjaGlsZHJlbiwgcmVzdWx0LCAnJywgJycsIGZ1bmN0aW9uIChjaGlsZCkge1xuICAgIHJldHVybiBmdW5jLmNhbGwoY29udGV4dCwgY2hpbGQsIGNvdW50KyspO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbi8qKlxuICogQ291bnQgdGhlIG51bWJlciBvZiBjaGlsZHJlbiB0aGF0IGFyZSB0eXBpY2FsbHkgc3BlY2lmaWVkIGFzXG4gKiBgcHJvcHMuY2hpbGRyZW5gLlxuICpcbiAqIFNlZSBodHRwczovL3JlYWN0anMub3JnL2RvY3MvcmVhY3QtYXBpLmh0bWwjcmVhY3RjaGlsZHJlbmNvdW50XG4gKlxuICogQHBhcmFtIHs/Kn0gY2hpbGRyZW4gQ2hpbGRyZW4gdHJlZSBjb250YWluZXIuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBudW1iZXIgb2YgY2hpbGRyZW4uXG4gKi9cblxuXG5mdW5jdGlvbiBjb3VudENoaWxkcmVuKGNoaWxkcmVuKSB7XG4gIHZhciBuID0gMDtcbiAgbWFwQ2hpbGRyZW4oY2hpbGRyZW4sIGZ1bmN0aW9uICgpIHtcbiAgICBuKys7IC8vIERvbid0IHJldHVybiBhbnl0aGluZ1xuICB9KTtcbiAgcmV0dXJuIG47XG59XG5cbi8qKlxuICogSXRlcmF0ZXMgdGhyb3VnaCBjaGlsZHJlbiB0aGF0IGFyZSB0eXBpY2FsbHkgc3BlY2lmaWVkIGFzIGBwcm9wcy5jaGlsZHJlbmAuXG4gKlxuICogU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvZG9jcy9yZWFjdC1hcGkuaHRtbCNyZWFjdGNoaWxkcmVuZm9yZWFjaFxuICpcbiAqIFRoZSBwcm92aWRlZCBmb3JFYWNoRnVuYyhjaGlsZCwgaW5kZXgpIHdpbGwgYmUgY2FsbGVkIGZvciBlYWNoXG4gKiBsZWFmIGNoaWxkLlxuICpcbiAqIEBwYXJhbSB7Pyp9IGNoaWxkcmVuIENoaWxkcmVuIHRyZWUgY29udGFpbmVyLlxuICogQHBhcmFtIHtmdW5jdGlvbigqLCBpbnQpfSBmb3JFYWNoRnVuY1xuICogQHBhcmFtIHsqfSBmb3JFYWNoQ29udGV4dCBDb250ZXh0IGZvciBmb3JFYWNoQ29udGV4dC5cbiAqL1xuZnVuY3Rpb24gZm9yRWFjaENoaWxkcmVuKGNoaWxkcmVuLCBmb3JFYWNoRnVuYywgZm9yRWFjaENvbnRleHQpIHtcbiAgbWFwQ2hpbGRyZW4oY2hpbGRyZW4sIGZ1bmN0aW9uICgpIHtcbiAgICBmb3JFYWNoRnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyAvLyBEb24ndCByZXR1cm4gYW55dGhpbmcuXG4gIH0sIGZvckVhY2hDb250ZXh0KTtcbn1cbi8qKlxuICogRmxhdHRlbiBhIGNoaWxkcmVuIG9iamVjdCAodHlwaWNhbGx5IHNwZWNpZmllZCBhcyBgcHJvcHMuY2hpbGRyZW5gKSBhbmRcbiAqIHJldHVybiBhbiBhcnJheSB3aXRoIGFwcHJvcHJpYXRlbHkgcmUta2V5ZWQgY2hpbGRyZW4uXG4gKlxuICogU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvZG9jcy9yZWFjdC1hcGkuaHRtbCNyZWFjdGNoaWxkcmVudG9hcnJheVxuICovXG5cblxuZnVuY3Rpb24gdG9BcnJheShjaGlsZHJlbikge1xuICByZXR1cm4gbWFwQ2hpbGRyZW4oY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkge1xuICAgIHJldHVybiBjaGlsZDtcbiAgfSkgfHwgW107XG59XG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IGNoaWxkIGluIGEgY29sbGVjdGlvbiBvZiBjaGlsZHJlbiBhbmQgdmVyaWZpZXMgdGhhdCB0aGVyZVxuICogaXMgb25seSBvbmUgY2hpbGQgaW4gdGhlIGNvbGxlY3Rpb24uXG4gKlxuICogU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvZG9jcy9yZWFjdC1hcGkuaHRtbCNyZWFjdGNoaWxkcmVub25seVxuICpcbiAqIFRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgZnVuY3Rpb24gYXNzdW1lcyB0aGF0IGEgc2luZ2xlIGNoaWxkIGdldHNcbiAqIHBhc3NlZCB3aXRob3V0IGEgd3JhcHBlciwgYnV0IHRoZSBwdXJwb3NlIG9mIHRoaXMgaGVscGVyIGZ1bmN0aW9uIGlzIHRvXG4gKiBhYnN0cmFjdCBhd2F5IHRoZSBwYXJ0aWN1bGFyIHN0cnVjdHVyZSBvZiBjaGlsZHJlbi5cbiAqXG4gKiBAcGFyYW0gez9vYmplY3R9IGNoaWxkcmVuIENoaWxkIGNvbGxlY3Rpb24gc3RydWN0dXJlLlxuICogQHJldHVybiB7UmVhY3RFbGVtZW50fSBUaGUgZmlyc3QgYW5kIG9ubHkgYFJlYWN0RWxlbWVudGAgY29udGFpbmVkIGluIHRoZVxuICogc3RydWN0dXJlLlxuICovXG5cblxuZnVuY3Rpb24gb25seUNoaWxkKGNoaWxkcmVuKSB7XG4gIGlmICghaXNWYWxpZEVsZW1lbnQoY2hpbGRyZW4pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdSZWFjdC5DaGlsZHJlbi5vbmx5IGV4cGVjdGVkIHRvIHJlY2VpdmUgYSBzaW5nbGUgUmVhY3QgZWxlbWVudCBjaGlsZC4nKTtcbiAgfVxuXG4gIHJldHVybiBjaGlsZHJlbjtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29udGV4dChkZWZhdWx0VmFsdWUpIHtcbiAgLy8gVE9ETzogU2Vjb25kIGFyZ3VtZW50IHVzZWQgdG8gYmUgYW4gb3B0aW9uYWwgYGNhbGN1bGF0ZUNoYW5nZWRCaXRzYFxuICAvLyBmdW5jdGlvbi4gV2FybiB0byByZXNlcnZlIGZvciBmdXR1cmUgdXNlP1xuICB2YXIgY29udGV4dCA9IHtcbiAgICAkJHR5cGVvZjogUkVBQ1RfQ09OVEVYVF9UWVBFLFxuICAgIC8vIEFzIGEgd29ya2Fyb3VuZCB0byBzdXBwb3J0IG11bHRpcGxlIGNvbmN1cnJlbnQgcmVuZGVyZXJzLCB3ZSBjYXRlZ29yaXplXG4gICAgLy8gc29tZSByZW5kZXJlcnMgYXMgcHJpbWFyeSBhbmQgb3RoZXJzIGFzIHNlY29uZGFyeS4gV2Ugb25seSBleHBlY3RcbiAgICAvLyB0aGVyZSB0byBiZSB0d28gY29uY3VycmVudCByZW5kZXJlcnMgYXQgbW9zdDogUmVhY3QgTmF0aXZlIChwcmltYXJ5KSBhbmRcbiAgICAvLyBGYWJyaWMgKHNlY29uZGFyeSk7IFJlYWN0IERPTSAocHJpbWFyeSkgYW5kIFJlYWN0IEFSVCAoc2Vjb25kYXJ5KS5cbiAgICAvLyBTZWNvbmRhcnkgcmVuZGVyZXJzIHN0b3JlIHRoZWlyIGNvbnRleHQgdmFsdWVzIG9uIHNlcGFyYXRlIGZpZWxkcy5cbiAgICBfY3VycmVudFZhbHVlOiBkZWZhdWx0VmFsdWUsXG4gICAgX2N1cnJlbnRWYWx1ZTI6IGRlZmF1bHRWYWx1ZSxcbiAgICAvLyBVc2VkIHRvIHRyYWNrIGhvdyBtYW55IGNvbmN1cnJlbnQgcmVuZGVyZXJzIHRoaXMgY29udGV4dCBjdXJyZW50bHlcbiAgICAvLyBzdXBwb3J0cyB3aXRoaW4gaW4gYSBzaW5nbGUgcmVuZGVyZXIuIFN1Y2ggYXMgcGFyYWxsZWwgc2VydmVyIHJlbmRlcmluZy5cbiAgICBfdGhyZWFkQ291bnQ6IDAsXG4gICAgLy8gVGhlc2UgYXJlIGNpcmN1bGFyXG4gICAgUHJvdmlkZXI6IG51bGwsXG4gICAgQ29uc3VtZXI6IG51bGwsXG4gICAgLy8gQWRkIHRoZXNlIHRvIHVzZSBzYW1lIGhpZGRlbiBjbGFzcyBpbiBWTSBhcyBTZXJ2ZXJDb250ZXh0XG4gICAgX2RlZmF1bHRWYWx1ZTogbnVsbCxcbiAgICBfZ2xvYmFsTmFtZTogbnVsbFxuICB9O1xuICBjb250ZXh0LlByb3ZpZGVyID0ge1xuICAgICQkdHlwZW9mOiBSRUFDVF9QUk9WSURFUl9UWVBFLFxuICAgIF9jb250ZXh0OiBjb250ZXh0XG4gIH07XG4gIHZhciBoYXNXYXJuZWRBYm91dFVzaW5nTmVzdGVkQ29udGV4dENvbnN1bWVycyA9IGZhbHNlO1xuICB2YXIgaGFzV2FybmVkQWJvdXRVc2luZ0NvbnN1bWVyUHJvdmlkZXIgPSBmYWxzZTtcbiAgdmFyIGhhc1dhcm5lZEFib3V0RGlzcGxheU5hbWVPbkNvbnN1bWVyID0gZmFsc2U7XG5cbiAge1xuICAgIC8vIEEgc2VwYXJhdGUgb2JqZWN0LCBidXQgcHJveGllcyBiYWNrIHRvIHRoZSBvcmlnaW5hbCBjb250ZXh0IG9iamVjdCBmb3JcbiAgICAvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS4gSXQgaGFzIGEgZGlmZmVyZW50ICQkdHlwZW9mLCBzbyB3ZSBjYW4gcHJvcGVybHlcbiAgICAvLyB3YXJuIGZvciB0aGUgaW5jb3JyZWN0IHVzYWdlIG9mIENvbnRleHQgYXMgYSBDb25zdW1lci5cbiAgICB2YXIgQ29uc3VtZXIgPSB7XG4gICAgICAkJHR5cGVvZjogUkVBQ1RfQ09OVEVYVF9UWVBFLFxuICAgICAgX2NvbnRleHQ6IGNvbnRleHRcbiAgICB9OyAvLyAkRmxvd0ZpeE1lOiBGbG93IGNvbXBsYWlucyBhYm91dCBub3Qgc2V0dGluZyBhIHZhbHVlLCB3aGljaCBpcyBpbnRlbnRpb25hbCBoZXJlXG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhDb25zdW1lciwge1xuICAgICAgUHJvdmlkZXI6IHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKCFoYXNXYXJuZWRBYm91dFVzaW5nQ29uc3VtZXJQcm92aWRlcikge1xuICAgICAgICAgICAgaGFzV2FybmVkQWJvdXRVc2luZ0NvbnN1bWVyUHJvdmlkZXIgPSB0cnVlO1xuXG4gICAgICAgICAgICBlcnJvcignUmVuZGVyaW5nIDxDb250ZXh0LkNvbnN1bWVyLlByb3ZpZGVyPiBpcyBub3Qgc3VwcG9ydGVkIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gJyArICdhIGZ1dHVyZSBtYWpvciByZWxlYXNlLiBEaWQgeW91IG1lYW4gdG8gcmVuZGVyIDxDb250ZXh0LlByb3ZpZGVyPiBpbnN0ZWFkPycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBjb250ZXh0LlByb3ZpZGVyO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChfUHJvdmlkZXIpIHtcbiAgICAgICAgICBjb250ZXh0LlByb3ZpZGVyID0gX1Byb3ZpZGVyO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgX2N1cnJlbnRWYWx1ZToge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gY29udGV4dC5fY3VycmVudFZhbHVlO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChfY3VycmVudFZhbHVlKSB7XG4gICAgICAgICAgY29udGV4dC5fY3VycmVudFZhbHVlID0gX2N1cnJlbnRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIF9jdXJyZW50VmFsdWUyOiB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBjb250ZXh0Ll9jdXJyZW50VmFsdWUyO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChfY3VycmVudFZhbHVlMikge1xuICAgICAgICAgIGNvbnRleHQuX2N1cnJlbnRWYWx1ZTIgPSBfY3VycmVudFZhbHVlMjtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIF90aHJlYWRDb3VudDoge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gY29udGV4dC5fdGhyZWFkQ291bnQ7XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogZnVuY3Rpb24gKF90aHJlYWRDb3VudCkge1xuICAgICAgICAgIGNvbnRleHQuX3RocmVhZENvdW50ID0gX3RocmVhZENvdW50O1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgQ29uc3VtZXI6IHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKCFoYXNXYXJuZWRBYm91dFVzaW5nTmVzdGVkQ29udGV4dENvbnN1bWVycykge1xuICAgICAgICAgICAgaGFzV2FybmVkQWJvdXRVc2luZ05lc3RlZENvbnRleHRDb25zdW1lcnMgPSB0cnVlO1xuXG4gICAgICAgICAgICBlcnJvcignUmVuZGVyaW5nIDxDb250ZXh0LkNvbnN1bWVyLkNvbnN1bWVyPiBpcyBub3Qgc3VwcG9ydGVkIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gJyArICdhIGZ1dHVyZSBtYWpvciByZWxlYXNlLiBEaWQgeW91IG1lYW4gdG8gcmVuZGVyIDxDb250ZXh0LkNvbnN1bWVyPiBpbnN0ZWFkPycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBjb250ZXh0LkNvbnN1bWVyO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZGlzcGxheU5hbWU6IHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbnRleHQuZGlzcGxheU5hbWU7XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogZnVuY3Rpb24gKGRpc3BsYXlOYW1lKSB7XG4gICAgICAgICAgaWYgKCFoYXNXYXJuZWRBYm91dERpc3BsYXlOYW1lT25Db25zdW1lcikge1xuICAgICAgICAgICAgd2FybignU2V0dGluZyBgZGlzcGxheU5hbWVgIG9uIENvbnRleHQuQ29uc3VtZXIgaGFzIG5vIGVmZmVjdC4gJyArIFwiWW91IHNob3VsZCBzZXQgaXQgZGlyZWN0bHkgb24gdGhlIGNvbnRleHQgd2l0aCBDb250ZXh0LmRpc3BsYXlOYW1lID0gJyVzJy5cIiwgZGlzcGxheU5hbWUpO1xuXG4gICAgICAgICAgICBoYXNXYXJuZWRBYm91dERpc3BsYXlOYW1lT25Db25zdW1lciA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7IC8vICRGbG93Rml4TWU6IEZsb3cgY29tcGxhaW5zIGFib3V0IG1pc3NpbmcgcHJvcGVydGllcyBiZWNhdXNlIGl0IGRvZXNuJ3QgdW5kZXJzdGFuZCBkZWZpbmVQcm9wZXJ0eVxuXG4gICAgY29udGV4dC5Db25zdW1lciA9IENvbnN1bWVyO1xuICB9XG5cbiAge1xuICAgIGNvbnRleHQuX2N1cnJlbnRSZW5kZXJlciA9IG51bGw7XG4gICAgY29udGV4dC5fY3VycmVudFJlbmRlcmVyMiA9IG51bGw7XG4gIH1cblxuICByZXR1cm4gY29udGV4dDtcbn1cblxudmFyIFVuaW5pdGlhbGl6ZWQgPSAtMTtcbnZhciBQZW5kaW5nID0gMDtcbnZhciBSZXNvbHZlZCA9IDE7XG52YXIgUmVqZWN0ZWQgPSAyO1xuXG5mdW5jdGlvbiBsYXp5SW5pdGlhbGl6ZXIocGF5bG9hZCkge1xuICBpZiAocGF5bG9hZC5fc3RhdHVzID09PSBVbmluaXRpYWxpemVkKSB7XG4gICAgdmFyIGN0b3IgPSBwYXlsb2FkLl9yZXN1bHQ7XG4gICAgdmFyIHRoZW5hYmxlID0gY3RvcigpOyAvLyBUcmFuc2l0aW9uIHRvIHRoZSBuZXh0IHN0YXRlLlxuICAgIC8vIFRoaXMgbWlnaHQgdGhyb3cgZWl0aGVyIGJlY2F1c2UgaXQncyBtaXNzaW5nIG9yIHRocm93cy4gSWYgc28sIHdlIHRyZWF0IGl0XG4gICAgLy8gYXMgc3RpbGwgdW5pbml0aWFsaXplZCBhbmQgdHJ5IGFnYWluIG5leHQgdGltZS4gV2hpY2ggaXMgdGhlIHNhbWUgYXMgd2hhdFxuICAgIC8vIGhhcHBlbnMgaWYgdGhlIGN0b3Igb3IgYW55IHdyYXBwZXJzIHByb2Nlc3NpbmcgdGhlIGN0b3IgdGhyb3dzLiBUaGlzIG1pZ2h0XG4gICAgLy8gZW5kIHVwIGZpeGluZyBpdCBpZiB0aGUgcmVzb2x1dGlvbiB3YXMgYSBjb25jdXJyZW5jeSBidWcuXG5cbiAgICB0aGVuYWJsZS50aGVuKGZ1bmN0aW9uIChtb2R1bGVPYmplY3QpIHtcbiAgICAgIGlmIChwYXlsb2FkLl9zdGF0dXMgPT09IFBlbmRpbmcgfHwgcGF5bG9hZC5fc3RhdHVzID09PSBVbmluaXRpYWxpemVkKSB7XG4gICAgICAgIC8vIFRyYW5zaXRpb24gdG8gdGhlIG5leHQgc3RhdGUuXG4gICAgICAgIHZhciByZXNvbHZlZCA9IHBheWxvYWQ7XG4gICAgICAgIHJlc29sdmVkLl9zdGF0dXMgPSBSZXNvbHZlZDtcbiAgICAgICAgcmVzb2x2ZWQuX3Jlc3VsdCA9IG1vZHVsZU9iamVjdDtcbiAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGlmIChwYXlsb2FkLl9zdGF0dXMgPT09IFBlbmRpbmcgfHwgcGF5bG9hZC5fc3RhdHVzID09PSBVbmluaXRpYWxpemVkKSB7XG4gICAgICAgIC8vIFRyYW5zaXRpb24gdG8gdGhlIG5leHQgc3RhdGUuXG4gICAgICAgIHZhciByZWplY3RlZCA9IHBheWxvYWQ7XG4gICAgICAgIHJlamVjdGVkLl9zdGF0dXMgPSBSZWplY3RlZDtcbiAgICAgICAgcmVqZWN0ZWQuX3Jlc3VsdCA9IGVycm9yO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHBheWxvYWQuX3N0YXR1cyA9PT0gVW5pbml0aWFsaXplZCkge1xuICAgICAgLy8gSW4gY2FzZSwgd2UncmUgc3RpbGwgdW5pbml0aWFsaXplZCwgdGhlbiB3ZSdyZSB3YWl0aW5nIGZvciB0aGUgdGhlbmFibGVcbiAgICAgIC8vIHRvIHJlc29sdmUuIFNldCBpdCBhcyBwZW5kaW5nIGluIHRoZSBtZWFudGltZS5cbiAgICAgIHZhciBwZW5kaW5nID0gcGF5bG9hZDtcbiAgICAgIHBlbmRpbmcuX3N0YXR1cyA9IFBlbmRpbmc7XG4gICAgICBwZW5kaW5nLl9yZXN1bHQgPSB0aGVuYWJsZTtcbiAgICB9XG4gIH1cblxuICBpZiAocGF5bG9hZC5fc3RhdHVzID09PSBSZXNvbHZlZCkge1xuICAgIHZhciBtb2R1bGVPYmplY3QgPSBwYXlsb2FkLl9yZXN1bHQ7XG5cbiAgICB7XG4gICAgICBpZiAobW9kdWxlT2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZXJyb3IoJ2xhenk6IEV4cGVjdGVkIHRoZSByZXN1bHQgb2YgYSBkeW5hbWljIGltcCcgKyAnb3J0KCkgY2FsbC4gJyArICdJbnN0ZWFkIHJlY2VpdmVkOiAlc1xcblxcbllvdXIgY29kZSBzaG91bGQgbG9vayBsaWtlOiBcXG4gICcgKyAvLyBCcmVhayB1cCBpbXBvcnRzIHRvIGF2b2lkIGFjY2lkZW50YWxseSBwYXJzaW5nIHRoZW0gYXMgZGVwZW5kZW5jaWVzLlxuICAgICAgICAnY29uc3QgTXlDb21wb25lbnQgPSBsYXp5KCgpID0+IGltcCcgKyBcIm9ydCgnLi9NeUNvbXBvbmVudCcpKVxcblxcblwiICsgJ0RpZCB5b3UgYWNjaWRlbnRhbGx5IHB1dCBjdXJseSBicmFjZXMgYXJvdW5kIHRoZSBpbXBvcnQ/JywgbW9kdWxlT2JqZWN0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB7XG4gICAgICBpZiAoISgnZGVmYXVsdCcgaW4gbW9kdWxlT2JqZWN0KSkge1xuICAgICAgICBlcnJvcignbGF6eTogRXhwZWN0ZWQgdGhlIHJlc3VsdCBvZiBhIGR5bmFtaWMgaW1wJyArICdvcnQoKSBjYWxsLiAnICsgJ0luc3RlYWQgcmVjZWl2ZWQ6ICVzXFxuXFxuWW91ciBjb2RlIHNob3VsZCBsb29rIGxpa2U6IFxcbiAgJyArIC8vIEJyZWFrIHVwIGltcG9ydHMgdG8gYXZvaWQgYWNjaWRlbnRhbGx5IHBhcnNpbmcgdGhlbSBhcyBkZXBlbmRlbmNpZXMuXG4gICAgICAgICdjb25zdCBNeUNvbXBvbmVudCA9IGxhenkoKCkgPT4gaW1wJyArIFwib3J0KCcuL015Q29tcG9uZW50JykpXCIsIG1vZHVsZU9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZHVsZU9iamVjdC5kZWZhdWx0O1xuICB9IGVsc2Uge1xuICAgIHRocm93IHBheWxvYWQuX3Jlc3VsdDtcbiAgfVxufVxuXG5mdW5jdGlvbiBsYXp5KGN0b3IpIHtcbiAgdmFyIHBheWxvYWQgPSB7XG4gICAgLy8gV2UgdXNlIHRoZXNlIGZpZWxkcyB0byBzdG9yZSB0aGUgcmVzdWx0LlxuICAgIF9zdGF0dXM6IFVuaW5pdGlhbGl6ZWQsXG4gICAgX3Jlc3VsdDogY3RvclxuICB9O1xuICB2YXIgbGF6eVR5cGUgPSB7XG4gICAgJCR0eXBlb2Y6IFJFQUNUX0xBWllfVFlQRSxcbiAgICBfcGF5bG9hZDogcGF5bG9hZCxcbiAgICBfaW5pdDogbGF6eUluaXRpYWxpemVyXG4gIH07XG5cbiAge1xuICAgIC8vIEluIHByb2R1Y3Rpb24sIHRoaXMgd291bGQganVzdCBzZXQgaXQgb24gdGhlIG9iamVjdC5cbiAgICB2YXIgZGVmYXVsdFByb3BzO1xuICAgIHZhciBwcm9wVHlwZXM7IC8vICRGbG93Rml4TWVcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGxhenlUeXBlLCB7XG4gICAgICBkZWZhdWx0UHJvcHM6IHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gZGVmYXVsdFByb3BzO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuZXdEZWZhdWx0UHJvcHMpIHtcbiAgICAgICAgICBlcnJvcignUmVhY3QubGF6eSguLi4pOiBJdCBpcyBub3Qgc3VwcG9ydGVkIHRvIGFzc2lnbiBgZGVmYXVsdFByb3BzYCB0byAnICsgJ2EgbGF6eSBjb21wb25lbnQgaW1wb3J0LiBFaXRoZXIgc3BlY2lmeSB0aGVtIHdoZXJlIHRoZSBjb21wb25lbnQgJyArICdpcyBkZWZpbmVkLCBvciBjcmVhdGUgYSB3cmFwcGluZyBjb21wb25lbnQgYXJvdW5kIGl0LicpO1xuXG4gICAgICAgICAgZGVmYXVsdFByb3BzID0gbmV3RGVmYXVsdFByb3BzOyAvLyBNYXRjaCBwcm9kdWN0aW9uIGJlaGF2aW9yIG1vcmUgY2xvc2VseTpcbiAgICAgICAgICAvLyAkRmxvd0ZpeE1lXG5cbiAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobGF6eVR5cGUsICdkZWZhdWx0UHJvcHMnLCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gcHJvcFR5cGVzO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuZXdQcm9wVHlwZXMpIHtcbiAgICAgICAgICBlcnJvcignUmVhY3QubGF6eSguLi4pOiBJdCBpcyBub3Qgc3VwcG9ydGVkIHRvIGFzc2lnbiBgcHJvcFR5cGVzYCB0byAnICsgJ2EgbGF6eSBjb21wb25lbnQgaW1wb3J0LiBFaXRoZXIgc3BlY2lmeSB0aGVtIHdoZXJlIHRoZSBjb21wb25lbnQgJyArICdpcyBkZWZpbmVkLCBvciBjcmVhdGUgYSB3cmFwcGluZyBjb21wb25lbnQgYXJvdW5kIGl0LicpO1xuXG4gICAgICAgICAgcHJvcFR5cGVzID0gbmV3UHJvcFR5cGVzOyAvLyBNYXRjaCBwcm9kdWN0aW9uIGJlaGF2aW9yIG1vcmUgY2xvc2VseTpcbiAgICAgICAgICAvLyAkRmxvd0ZpeE1lXG5cbiAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobGF6eVR5cGUsICdwcm9wVHlwZXMnLCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBsYXp5VHlwZTtcbn1cblxuZnVuY3Rpb24gZm9yd2FyZFJlZihyZW5kZXIpIHtcbiAge1xuICAgIGlmIChyZW5kZXIgIT0gbnVsbCAmJiByZW5kZXIuJCR0eXBlb2YgPT09IFJFQUNUX01FTU9fVFlQRSkge1xuICAgICAgZXJyb3IoJ2ZvcndhcmRSZWYgcmVxdWlyZXMgYSByZW5kZXIgZnVuY3Rpb24gYnV0IHJlY2VpdmVkIGEgYG1lbW9gICcgKyAnY29tcG9uZW50LiBJbnN0ZWFkIG9mIGZvcndhcmRSZWYobWVtbyguLi4pKSwgdXNlICcgKyAnbWVtbyhmb3J3YXJkUmVmKC4uLikpLicpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHJlbmRlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJ2ZvcndhcmRSZWYgcmVxdWlyZXMgYSByZW5kZXIgZnVuY3Rpb24gYnV0IHdhcyBnaXZlbiAlcy4nLCByZW5kZXIgPT09IG51bGwgPyAnbnVsbCcgOiB0eXBlb2YgcmVuZGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHJlbmRlci5sZW5ndGggIT09IDAgJiYgcmVuZGVyLmxlbmd0aCAhPT0gMikge1xuICAgICAgICBlcnJvcignZm9yd2FyZFJlZiByZW5kZXIgZnVuY3Rpb25zIGFjY2VwdCBleGFjdGx5IHR3byBwYXJhbWV0ZXJzOiBwcm9wcyBhbmQgcmVmLiAlcycsIHJlbmRlci5sZW5ndGggPT09IDEgPyAnRGlkIHlvdSBmb3JnZXQgdG8gdXNlIHRoZSByZWYgcGFyYW1ldGVyPycgOiAnQW55IGFkZGl0aW9uYWwgcGFyYW1ldGVyIHdpbGwgYmUgdW5kZWZpbmVkLicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyZW5kZXIgIT0gbnVsbCkge1xuICAgICAgaWYgKHJlbmRlci5kZWZhdWx0UHJvcHMgIT0gbnVsbCB8fCByZW5kZXIucHJvcFR5cGVzICE9IG51bGwpIHtcbiAgICAgICAgZXJyb3IoJ2ZvcndhcmRSZWYgcmVuZGVyIGZ1bmN0aW9ucyBkbyBub3Qgc3VwcG9ydCBwcm9wVHlwZXMgb3IgZGVmYXVsdFByb3BzLiAnICsgJ0RpZCB5b3UgYWNjaWRlbnRhbGx5IHBhc3MgYSBSZWFjdCBjb21wb25lbnQ/Jyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIGVsZW1lbnRUeXBlID0ge1xuICAgICQkdHlwZW9mOiBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFLFxuICAgIHJlbmRlcjogcmVuZGVyXG4gIH07XG5cbiAge1xuICAgIHZhciBvd25OYW1lO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbGVtZW50VHlwZSwgJ2Rpc3BsYXlOYW1lJywge1xuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG93bk5hbWU7XG4gICAgICB9LFxuICAgICAgc2V0OiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICBvd25OYW1lID0gbmFtZTsgLy8gVGhlIGlubmVyIGNvbXBvbmVudCBzaG91bGRuJ3QgaW5oZXJpdCB0aGlzIGRpc3BsYXkgbmFtZSBpbiBtb3N0IGNhc2VzLFxuICAgICAgICAvLyBiZWNhdXNlIHRoZSBjb21wb25lbnQgbWF5IGJlIHVzZWQgZWxzZXdoZXJlLlxuICAgICAgICAvLyBCdXQgaXQncyBuaWNlIGZvciBhbm9ueW1vdXMgZnVuY3Rpb25zIHRvIGluaGVyaXQgdGhlIG5hbWUsXG4gICAgICAgIC8vIHNvIHRoYXQgb3VyIGNvbXBvbmVudC1zdGFjayBnZW5lcmF0aW9uIGxvZ2ljIHdpbGwgZGlzcGxheSB0aGVpciBmcmFtZXMuXG4gICAgICAgIC8vIEFuIGFub255bW91cyBmdW5jdGlvbiBnZW5lcmFsbHkgc3VnZ2VzdHMgYSBwYXR0ZXJuIGxpa2U6XG4gICAgICAgIC8vICAgUmVhY3QuZm9yd2FyZFJlZigocHJvcHMsIHJlZikgPT4gey4uLn0pO1xuICAgICAgICAvLyBUaGlzIGtpbmQgb2YgaW5uZXIgZnVuY3Rpb24gaXMgbm90IHVzZWQgZWxzZXdoZXJlIHNvIHRoZSBzaWRlIGVmZmVjdCBpcyBva2F5LlxuXG4gICAgICAgIGlmICghcmVuZGVyLm5hbWUgJiYgIXJlbmRlci5kaXNwbGF5TmFtZSkge1xuICAgICAgICAgIHJlbmRlci5kaXNwbGF5TmFtZSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBlbGVtZW50VHlwZTtcbn1cblxudmFyIFJFQUNUX01PRFVMRV9SRUZFUkVOQ0U7XG5cbntcbiAgUkVBQ1RfTU9EVUxFX1JFRkVSRU5DRSA9IFN5bWJvbC5mb3IoJ3JlYWN0Lm1vZHVsZS5yZWZlcmVuY2UnKTtcbn1cblxuZnVuY3Rpb24gaXNWYWxpZEVsZW1lbnRUeXBlKHR5cGUpIHtcbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9IC8vIE5vdGU6IHR5cGVvZiBtaWdodCBiZSBvdGhlciB0aGFuICdzeW1ib2wnIG9yICdudW1iZXInIChlLmcuIGlmIGl0J3MgYSBwb2x5ZmlsbCkuXG5cblxuICBpZiAodHlwZSA9PT0gUkVBQ1RfRlJBR01FTlRfVFlQRSB8fCB0eXBlID09PSBSRUFDVF9QUk9GSUxFUl9UWVBFIHx8IGVuYWJsZURlYnVnVHJhY2luZyAgfHwgdHlwZSA9PT0gUkVBQ1RfU1RSSUNUX01PREVfVFlQRSB8fCB0eXBlID09PSBSRUFDVF9TVVNQRU5TRV9UWVBFIHx8IHR5cGUgPT09IFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRSB8fCBlbmFibGVMZWdhY3lIaWRkZW4gIHx8IHR5cGUgPT09IFJFQUNUX09GRlNDUkVFTl9UWVBFIHx8IGVuYWJsZVNjb3BlQVBJICB8fCBlbmFibGVDYWNoZUVsZW1lbnQgIHx8IGVuYWJsZVRyYW5zaXRpb25UcmFjaW5nICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnb2JqZWN0JyAmJiB0eXBlICE9PSBudWxsKSB7XG4gICAgaWYgKHR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX0xBWllfVFlQRSB8fCB0eXBlLiQkdHlwZW9mID09PSBSRUFDVF9NRU1PX1RZUEUgfHwgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfUFJPVklERVJfVFlQRSB8fCB0eXBlLiQkdHlwZW9mID09PSBSRUFDVF9DT05URVhUX1RZUEUgfHwgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRSB8fCAvLyBUaGlzIG5lZWRzIHRvIGluY2x1ZGUgYWxsIHBvc3NpYmxlIG1vZHVsZSByZWZlcmVuY2Ugb2JqZWN0XG4gICAgLy8gdHlwZXMgc3VwcG9ydGVkIGJ5IGFueSBGbGlnaHQgY29uZmlndXJhdGlvbiBhbnl3aGVyZSBzaW5jZVxuICAgIC8vIHdlIGRvbid0IGtub3cgd2hpY2ggRmxpZ2h0IGJ1aWxkIHRoaXMgd2lsbCBlbmQgdXAgYmVpbmcgdXNlZFxuICAgIC8vIHdpdGguXG4gICAgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfTU9EVUxFX1JFRkVSRU5DRSB8fCB0eXBlLmdldE1vZHVsZUlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gbWVtbyh0eXBlLCBjb21wYXJlKSB7XG4gIHtcbiAgICBpZiAoIWlzVmFsaWRFbGVtZW50VHlwZSh0eXBlKSkge1xuICAgICAgZXJyb3IoJ21lbW86IFRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgY29tcG9uZW50LiBJbnN0ZWFkICcgKyAncmVjZWl2ZWQ6ICVzJywgdHlwZSA9PT0gbnVsbCA/ICdudWxsJyA6IHR5cGVvZiB0eXBlKTtcbiAgICB9XG4gIH1cblxuICB2YXIgZWxlbWVudFR5cGUgPSB7XG4gICAgJCR0eXBlb2Y6IFJFQUNUX01FTU9fVFlQRSxcbiAgICB0eXBlOiB0eXBlLFxuICAgIGNvbXBhcmU6IGNvbXBhcmUgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBjb21wYXJlXG4gIH07XG5cbiAge1xuICAgIHZhciBvd25OYW1lO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbGVtZW50VHlwZSwgJ2Rpc3BsYXlOYW1lJywge1xuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG93bk5hbWU7XG4gICAgICB9LFxuICAgICAgc2V0OiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICBvd25OYW1lID0gbmFtZTsgLy8gVGhlIGlubmVyIGNvbXBvbmVudCBzaG91bGRuJ3QgaW5oZXJpdCB0aGlzIGRpc3BsYXkgbmFtZSBpbiBtb3N0IGNhc2VzLFxuICAgICAgICAvLyBiZWNhdXNlIHRoZSBjb21wb25lbnQgbWF5IGJlIHVzZWQgZWxzZXdoZXJlLlxuICAgICAgICAvLyBCdXQgaXQncyBuaWNlIGZvciBhbm9ueW1vdXMgZnVuY3Rpb25zIHRvIGluaGVyaXQgdGhlIG5hbWUsXG4gICAgICAgIC8vIHNvIHRoYXQgb3VyIGNvbXBvbmVudC1zdGFjayBnZW5lcmF0aW9uIGxvZ2ljIHdpbGwgZGlzcGxheSB0aGVpciBmcmFtZXMuXG4gICAgICAgIC8vIEFuIGFub255bW91cyBmdW5jdGlvbiBnZW5lcmFsbHkgc3VnZ2VzdHMgYSBwYXR0ZXJuIGxpa2U6XG4gICAgICAgIC8vICAgUmVhY3QubWVtbygocHJvcHMpID0+IHsuLi59KTtcbiAgICAgICAgLy8gVGhpcyBraW5kIG9mIGlubmVyIGZ1bmN0aW9uIGlzIG5vdCB1c2VkIGVsc2V3aGVyZSBzbyB0aGUgc2lkZSBlZmZlY3QgaXMgb2theS5cblxuICAgICAgICBpZiAoIXR5cGUubmFtZSAmJiAhdHlwZS5kaXNwbGF5TmFtZSkge1xuICAgICAgICAgIHR5cGUuZGlzcGxheU5hbWUgPSBuYW1lO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudFR5cGU7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVEaXNwYXRjaGVyKCkge1xuICB2YXIgZGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIuY3VycmVudDtcblxuICB7XG4gICAgaWYgKGRpc3BhdGNoZXIgPT09IG51bGwpIHtcbiAgICAgIGVycm9yKCdJbnZhbGlkIGhvb2sgY2FsbC4gSG9va3MgY2FuIG9ubHkgYmUgY2FsbGVkIGluc2lkZSBvZiB0aGUgYm9keSBvZiBhIGZ1bmN0aW9uIGNvbXBvbmVudC4gVGhpcyBjb3VsZCBoYXBwZW4gZm9yJyArICcgb25lIG9mIHRoZSBmb2xsb3dpbmcgcmVhc29uczpcXG4nICsgJzEuIFlvdSBtaWdodCBoYXZlIG1pc21hdGNoaW5nIHZlcnNpb25zIG9mIFJlYWN0IGFuZCB0aGUgcmVuZGVyZXIgKHN1Y2ggYXMgUmVhY3QgRE9NKVxcbicgKyAnMi4gWW91IG1pZ2h0IGJlIGJyZWFraW5nIHRoZSBSdWxlcyBvZiBIb29rc1xcbicgKyAnMy4gWW91IG1pZ2h0IGhhdmUgbW9yZSB0aGFuIG9uZSBjb3B5IG9mIFJlYWN0IGluIHRoZSBzYW1lIGFwcFxcbicgKyAnU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9pbnZhbGlkLWhvb2stY2FsbCBmb3IgdGlwcyBhYm91dCBob3cgdG8gZGVidWcgYW5kIGZpeCB0aGlzIHByb2JsZW0uJyk7XG4gICAgfVxuICB9IC8vIFdpbGwgcmVzdWx0IGluIGEgbnVsbCBhY2Nlc3MgZXJyb3IgaWYgYWNjZXNzZWQgb3V0c2lkZSByZW5kZXIgcGhhc2UuIFdlXG4gIC8vIGludGVudGlvbmFsbHkgZG9uJ3QgdGhyb3cgb3VyIG93biBlcnJvciBiZWNhdXNlIHRoaXMgaXMgaW4gYSBob3QgcGF0aC5cbiAgLy8gQWxzbyBoZWxwcyBlbnN1cmUgdGhpcyBpcyBpbmxpbmVkLlxuXG5cbiAgcmV0dXJuIGRpc3BhdGNoZXI7XG59XG5mdW5jdGlvbiB1c2VDb250ZXh0KENvbnRleHQpIHtcbiAgdmFyIGRpc3BhdGNoZXIgPSByZXNvbHZlRGlzcGF0Y2hlcigpO1xuXG4gIHtcbiAgICAvLyBUT0RPOiBhZGQgYSBtb3JlIGdlbmVyaWMgd2FybmluZyBmb3IgaW52YWxpZCB2YWx1ZXMuXG4gICAgaWYgKENvbnRleHQuX2NvbnRleHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIHJlYWxDb250ZXh0ID0gQ29udGV4dC5fY29udGV4dDsgLy8gRG9uJ3QgZGVkdXBsaWNhdGUgYmVjYXVzZSB0aGlzIGxlZ2l0aW1hdGVseSBjYXVzZXMgYnVnc1xuICAgICAgLy8gYW5kIG5vYm9keSBzaG91bGQgYmUgdXNpbmcgdGhpcyBpbiBleGlzdGluZyBjb2RlLlxuXG4gICAgICBpZiAocmVhbENvbnRleHQuQ29uc3VtZXIgPT09IENvbnRleHQpIHtcbiAgICAgICAgZXJyb3IoJ0NhbGxpbmcgdXNlQ29udGV4dChDb250ZXh0LkNvbnN1bWVyKSBpcyBub3Qgc3VwcG9ydGVkLCBtYXkgY2F1c2UgYnVncywgYW5kIHdpbGwgYmUgJyArICdyZW1vdmVkIGluIGEgZnV0dXJlIG1ham9yIHJlbGVhc2UuIERpZCB5b3UgbWVhbiB0byBjYWxsIHVzZUNvbnRleHQoQ29udGV4dCkgaW5zdGVhZD8nKTtcbiAgICAgIH0gZWxzZSBpZiAocmVhbENvbnRleHQuUHJvdmlkZXIgPT09IENvbnRleHQpIHtcbiAgICAgICAgZXJyb3IoJ0NhbGxpbmcgdXNlQ29udGV4dChDb250ZXh0LlByb3ZpZGVyKSBpcyBub3Qgc3VwcG9ydGVkLiAnICsgJ0RpZCB5b3UgbWVhbiB0byBjYWxsIHVzZUNvbnRleHQoQ29udGV4dCkgaW5zdGVhZD8nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZGlzcGF0Y2hlci51c2VDb250ZXh0KENvbnRleHQpO1xufVxuZnVuY3Rpb24gdXNlU3RhdGUoaW5pdGlhbFN0YXRlKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlU3RhdGUoaW5pdGlhbFN0YXRlKTtcbn1cbmZ1bmN0aW9uIHVzZVJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCkge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZVJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCk7XG59XG5mdW5jdGlvbiB1c2VSZWYoaW5pdGlhbFZhbHVlKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlUmVmKGluaXRpYWxWYWx1ZSk7XG59XG5mdW5jdGlvbiB1c2VFZmZlY3QoY3JlYXRlLCBkZXBzKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG59XG5mdW5jdGlvbiB1c2VJbnNlcnRpb25FZmZlY3QoY3JlYXRlLCBkZXBzKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlSW5zZXJ0aW9uRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG59XG5mdW5jdGlvbiB1c2VMYXlvdXRFZmZlY3QoY3JlYXRlLCBkZXBzKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlTGF5b3V0RWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG59XG5mdW5jdGlvbiB1c2VDYWxsYmFjayhjYWxsYmFjaywgZGVwcykge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZUNhbGxiYWNrKGNhbGxiYWNrLCBkZXBzKTtcbn1cbmZ1bmN0aW9uIHVzZU1lbW8oY3JlYXRlLCBkZXBzKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlTWVtbyhjcmVhdGUsIGRlcHMpO1xufVxuZnVuY3Rpb24gdXNlSW1wZXJhdGl2ZUhhbmRsZShyZWYsIGNyZWF0ZSwgZGVwcykge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZUltcGVyYXRpdmVIYW5kbGUocmVmLCBjcmVhdGUsIGRlcHMpO1xufVxuZnVuY3Rpb24gdXNlRGVidWdWYWx1ZSh2YWx1ZSwgZm9ybWF0dGVyRm4pIHtcbiAge1xuICAgIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgICByZXR1cm4gZGlzcGF0Y2hlci51c2VEZWJ1Z1ZhbHVlKHZhbHVlLCBmb3JtYXR0ZXJGbik7XG4gIH1cbn1cbmZ1bmN0aW9uIHVzZVRyYW5zaXRpb24oKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlVHJhbnNpdGlvbigpO1xufVxuZnVuY3Rpb24gdXNlRGVmZXJyZWRWYWx1ZSh2YWx1ZSkge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZURlZmVycmVkVmFsdWUodmFsdWUpO1xufVxuZnVuY3Rpb24gdXNlSWQoKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlSWQoKTtcbn1cbmZ1bmN0aW9uIHVzZVN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlU3luY0V4dGVybmFsU3RvcmUoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpO1xufVxuXG4vLyBIZWxwZXJzIHRvIHBhdGNoIGNvbnNvbGUubG9ncyB0byBhdm9pZCBsb2dnaW5nIGR1cmluZyBzaWRlLWVmZmVjdCBmcmVlXG4vLyByZXBsYXlpbmcgb24gcmVuZGVyIGZ1bmN0aW9uLiBUaGlzIGN1cnJlbnRseSBvbmx5IHBhdGNoZXMgdGhlIG9iamVjdFxuLy8gbGF6aWx5IHdoaWNoIHdvbid0IGNvdmVyIGlmIHRoZSBsb2cgZnVuY3Rpb24gd2FzIGV4dHJhY3RlZCBlYWdlcmx5LlxuLy8gV2UgY291bGQgYWxzbyBlYWdlcmx5IHBhdGNoIHRoZSBtZXRob2QuXG52YXIgZGlzYWJsZWREZXB0aCA9IDA7XG52YXIgcHJldkxvZztcbnZhciBwcmV2SW5mbztcbnZhciBwcmV2V2FybjtcbnZhciBwcmV2RXJyb3I7XG52YXIgcHJldkdyb3VwO1xudmFyIHByZXZHcm91cENvbGxhcHNlZDtcbnZhciBwcmV2R3JvdXBFbmQ7XG5cbmZ1bmN0aW9uIGRpc2FibGVkTG9nKCkge31cblxuZGlzYWJsZWRMb2cuX19yZWFjdERpc2FibGVkTG9nID0gdHJ1ZTtcbmZ1bmN0aW9uIGRpc2FibGVMb2dzKCkge1xuICB7XG4gICAgaWYgKGRpc2FibGVkRGVwdGggPT09IDApIHtcbiAgICAgIC8qIGVzbGludC1kaXNhYmxlIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZyAqL1xuICAgICAgcHJldkxvZyA9IGNvbnNvbGUubG9nO1xuICAgICAgcHJldkluZm8gPSBjb25zb2xlLmluZm87XG4gICAgICBwcmV2V2FybiA9IGNvbnNvbGUud2FybjtcbiAgICAgIHByZXZFcnJvciA9IGNvbnNvbGUuZXJyb3I7XG4gICAgICBwcmV2R3JvdXAgPSBjb25zb2xlLmdyb3VwO1xuICAgICAgcHJldkdyb3VwQ29sbGFwc2VkID0gY29uc29sZS5ncm91cENvbGxhcHNlZDtcbiAgICAgIHByZXZHcm91cEVuZCA9IGNvbnNvbGUuZ3JvdXBFbmQ7IC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTkwOTlcblxuICAgICAgdmFyIHByb3BzID0ge1xuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIHZhbHVlOiBkaXNhYmxlZExvZyxcbiAgICAgICAgd3JpdGFibGU6IHRydWVcbiAgICAgIH07IC8vICRGbG93Rml4TWUgRmxvdyB0aGlua3MgY29uc29sZSBpcyBpbW11dGFibGUuXG5cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGNvbnNvbGUsIHtcbiAgICAgICAgaW5mbzogcHJvcHMsXG4gICAgICAgIGxvZzogcHJvcHMsXG4gICAgICAgIHdhcm46IHByb3BzLFxuICAgICAgICBlcnJvcjogcHJvcHMsXG4gICAgICAgIGdyb3VwOiBwcm9wcyxcbiAgICAgICAgZ3JvdXBDb2xsYXBzZWQ6IHByb3BzLFxuICAgICAgICBncm91cEVuZDogcHJvcHNcbiAgICAgIH0pO1xuICAgICAgLyogZXNsaW50LWVuYWJsZSByZWFjdC1pbnRlcm5hbC9uby1wcm9kdWN0aW9uLWxvZ2dpbmcgKi9cbiAgICB9XG5cbiAgICBkaXNhYmxlZERlcHRoKys7XG4gIH1cbn1cbmZ1bmN0aW9uIHJlZW5hYmxlTG9ncygpIHtcbiAge1xuICAgIGRpc2FibGVkRGVwdGgtLTtcblxuICAgIGlmIChkaXNhYmxlZERlcHRoID09PSAwKSB7XG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSByZWFjdC1pbnRlcm5hbC9uby1wcm9kdWN0aW9uLWxvZ2dpbmcgKi9cbiAgICAgIHZhciBwcm9wcyA9IHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgfTsgLy8gJEZsb3dGaXhNZSBGbG93IHRoaW5rcyBjb25zb2xlIGlzIGltbXV0YWJsZS5cblxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoY29uc29sZSwge1xuICAgICAgICBsb2c6IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkxvZ1xuICAgICAgICB9KSxcbiAgICAgICAgaW5mbzogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2SW5mb1xuICAgICAgICB9KSxcbiAgICAgICAgd2FybjogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2V2FyblxuICAgICAgICB9KSxcbiAgICAgICAgZXJyb3I6IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkVycm9yXG4gICAgICAgIH0pLFxuICAgICAgICBncm91cDogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2R3JvdXBcbiAgICAgICAgfSksXG4gICAgICAgIGdyb3VwQ29sbGFwc2VkOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZHcm91cENvbGxhcHNlZFxuICAgICAgICB9KSxcbiAgICAgICAgZ3JvdXBFbmQ6IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkdyb3VwRW5kXG4gICAgICAgIH0pXG4gICAgICB9KTtcbiAgICAgIC8qIGVzbGludC1lbmFibGUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nICovXG4gICAgfVxuXG4gICAgaWYgKGRpc2FibGVkRGVwdGggPCAwKSB7XG4gICAgICBlcnJvcignZGlzYWJsZWREZXB0aCBmZWxsIGJlbG93IHplcm8uICcgKyAnVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuICB9XG59XG5cbnZhciBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnREaXNwYXRjaGVyO1xudmFyIHByZWZpeDtcbmZ1bmN0aW9uIGRlc2NyaWJlQnVpbHRJbkNvbXBvbmVudEZyYW1lKG5hbWUsIHNvdXJjZSwgb3duZXJGbikge1xuICB7XG4gICAgaWYgKHByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBFeHRyYWN0IHRoZSBWTSBzcGVjaWZpYyBwcmVmaXggdXNlZCBieSBlYWNoIGxpbmUuXG4gICAgICB0cnkge1xuICAgICAgICB0aHJvdyBFcnJvcigpO1xuICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICB2YXIgbWF0Y2ggPSB4LnN0YWNrLnRyaW0oKS5tYXRjaCgvXFxuKCAqKGF0ICk/KS8pO1xuICAgICAgICBwcmVmaXggPSBtYXRjaCAmJiBtYXRjaFsxXSB8fCAnJztcbiAgICAgIH1cbiAgICB9IC8vIFdlIHVzZSB0aGUgcHJlZml4IHRvIGVuc3VyZSBvdXIgc3RhY2tzIGxpbmUgdXAgd2l0aCBuYXRpdmUgc3RhY2sgZnJhbWVzLlxuXG5cbiAgICByZXR1cm4gJ1xcbicgKyBwcmVmaXggKyBuYW1lO1xuICB9XG59XG52YXIgcmVlbnRyeSA9IGZhbHNlO1xudmFyIGNvbXBvbmVudEZyYW1lQ2FjaGU7XG5cbntcbiAgdmFyIFBvc3NpYmx5V2Vha01hcCA9IHR5cGVvZiBXZWFrTWFwID09PSAnZnVuY3Rpb24nID8gV2Vha01hcCA6IE1hcDtcbiAgY29tcG9uZW50RnJhbWVDYWNoZSA9IG5ldyBQb3NzaWJseVdlYWtNYXAoKTtcbn1cblxuZnVuY3Rpb24gZGVzY3JpYmVOYXRpdmVDb21wb25lbnRGcmFtZShmbiwgY29uc3RydWN0KSB7XG4gIC8vIElmIHNvbWV0aGluZyBhc2tlZCBmb3IgYSBzdGFjayBpbnNpZGUgYSBmYWtlIHJlbmRlciwgaXQgc2hvdWxkIGdldCBpZ25vcmVkLlxuICBpZiAoICFmbiB8fCByZWVudHJ5KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAge1xuICAgIHZhciBmcmFtZSA9IGNvbXBvbmVudEZyYW1lQ2FjaGUuZ2V0KGZuKTtcblxuICAgIGlmIChmcmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZnJhbWU7XG4gICAgfVxuICB9XG5cbiAgdmFyIGNvbnRyb2w7XG4gIHJlZW50cnkgPSB0cnVlO1xuICB2YXIgcHJldmlvdXNQcmVwYXJlU3RhY2tUcmFjZSA9IEVycm9yLnByZXBhcmVTdGFja1RyYWNlOyAvLyAkRmxvd0ZpeE1lIEl0IGRvZXMgYWNjZXB0IHVuZGVmaW5lZC5cblxuICBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZSA9IHVuZGVmaW5lZDtcbiAgdmFyIHByZXZpb3VzRGlzcGF0Y2hlcjtcblxuICB7XG4gICAgcHJldmlvdXNEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7IC8vIFNldCB0aGUgZGlzcGF0Y2hlciBpbiBERVYgYmVjYXVzZSB0aGlzIG1pZ2h0IGJlIGNhbGwgaW4gdGhlIHJlbmRlciBmdW5jdGlvblxuICAgIC8vIGZvciB3YXJuaW5ncy5cblxuICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gbnVsbDtcbiAgICBkaXNhYmxlTG9ncygpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBUaGlzIHNob3VsZCB0aHJvdy5cbiAgICBpZiAoY29uc3RydWN0KSB7XG4gICAgICAvLyBTb21ldGhpbmcgc2hvdWxkIGJlIHNldHRpbmcgdGhlIHByb3BzIGluIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgIHZhciBGYWtlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aHJvdyBFcnJvcigpO1xuICAgICAgfTsgLy8gJEZsb3dGaXhNZVxuXG5cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWtlLnByb3RvdHlwZSwgJ3Byb3BzJywge1xuICAgICAgICBzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAvLyBXZSB1c2UgYSB0aHJvd2luZyBzZXR0ZXIgaW5zdGVhZCBvZiBmcm96ZW4gb3Igbm9uLXdyaXRhYmxlIHByb3BzXG4gICAgICAgICAgLy8gYmVjYXVzZSB0aGF0IHdvbid0IHRocm93IGluIGEgbm9uLXN0cmljdCBtb2RlIGZ1bmN0aW9uLlxuICAgICAgICAgIHRocm93IEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnICYmIFJlZmxlY3QuY29uc3RydWN0KSB7XG4gICAgICAgIC8vIFdlIGNvbnN0cnVjdCBhIGRpZmZlcmVudCBjb250cm9sIGZvciB0aGlzIGNhc2UgdG8gaW5jbHVkZSBhbnkgZXh0cmFcbiAgICAgICAgLy8gZnJhbWVzIGFkZGVkIGJ5IHRoZSBjb25zdHJ1Y3QgY2FsbC5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBSZWZsZWN0LmNvbnN0cnVjdChGYWtlLCBbXSk7XG4gICAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgICBjb250cm9sID0geDtcbiAgICAgICAgfVxuXG4gICAgICAgIFJlZmxlY3QuY29uc3RydWN0KGZuLCBbXSwgRmFrZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIEZha2UuY2FsbCgpO1xuICAgICAgICB9IGNhdGNoICh4KSB7XG4gICAgICAgICAgY29udHJvbCA9IHg7XG4gICAgICAgIH1cblxuICAgICAgICBmbi5jYWxsKEZha2UucHJvdG90eXBlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdGhyb3cgRXJyb3IoKTtcbiAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgY29udHJvbCA9IHg7XG4gICAgICB9XG5cbiAgICAgIGZuKCk7XG4gICAgfVxuICB9IGNhdGNoIChzYW1wbGUpIHtcbiAgICAvLyBUaGlzIGlzIGlubGluZWQgbWFudWFsbHkgYmVjYXVzZSBjbG9zdXJlIGRvZXNuJ3QgZG8gaXQgZm9yIHVzLlxuICAgIGlmIChzYW1wbGUgJiYgY29udHJvbCAmJiB0eXBlb2Ygc2FtcGxlLnN0YWNrID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gVGhpcyBleHRyYWN0cyB0aGUgZmlyc3QgZnJhbWUgZnJvbSB0aGUgc2FtcGxlIHRoYXQgaXNuJ3QgYWxzbyBpbiB0aGUgY29udHJvbC5cbiAgICAgIC8vIFNraXBwaW5nIG9uZSBmcmFtZSB0aGF0IHdlIGFzc3VtZSBpcyB0aGUgZnJhbWUgdGhhdCBjYWxscyB0aGUgdHdvLlxuICAgICAgdmFyIHNhbXBsZUxpbmVzID0gc2FtcGxlLnN0YWNrLnNwbGl0KCdcXG4nKTtcbiAgICAgIHZhciBjb250cm9sTGluZXMgPSBjb250cm9sLnN0YWNrLnNwbGl0KCdcXG4nKTtcbiAgICAgIHZhciBzID0gc2FtcGxlTGluZXMubGVuZ3RoIC0gMTtcbiAgICAgIHZhciBjID0gY29udHJvbExpbmVzLmxlbmd0aCAtIDE7XG5cbiAgICAgIHdoaWxlIChzID49IDEgJiYgYyA+PSAwICYmIHNhbXBsZUxpbmVzW3NdICE9PSBjb250cm9sTGluZXNbY10pIHtcbiAgICAgICAgLy8gV2UgZXhwZWN0IGF0IGxlYXN0IG9uZSBzdGFjayBmcmFtZSB0byBiZSBzaGFyZWQuXG4gICAgICAgIC8vIFR5cGljYWxseSB0aGlzIHdpbGwgYmUgdGhlIHJvb3QgbW9zdCBvbmUuIEhvd2V2ZXIsIHN0YWNrIGZyYW1lcyBtYXkgYmVcbiAgICAgICAgLy8gY3V0IG9mZiBkdWUgdG8gbWF4aW11bSBzdGFjayBsaW1pdHMuIEluIHRoaXMgY2FzZSwgb25lIG1heWJlIGN1dCBvZmZcbiAgICAgICAgLy8gZWFybGllciB0aGFuIHRoZSBvdGhlci4gV2UgYXNzdW1lIHRoYXQgdGhlIHNhbXBsZSBpcyBsb25nZXIgb3IgdGhlIHNhbWVcbiAgICAgICAgLy8gYW5kIHRoZXJlIGZvciBjdXQgb2ZmIGVhcmxpZXIuIFNvIHdlIHNob3VsZCBmaW5kIHRoZSByb290IG1vc3QgZnJhbWUgaW5cbiAgICAgICAgLy8gdGhlIHNhbXBsZSBzb21ld2hlcmUgaW4gdGhlIGNvbnRyb2wuXG4gICAgICAgIGMtLTtcbiAgICAgIH1cblxuICAgICAgZm9yICg7IHMgPj0gMSAmJiBjID49IDA7IHMtLSwgYy0tKSB7XG4gICAgICAgIC8vIE5leHQgd2UgZmluZCB0aGUgZmlyc3Qgb25lIHRoYXQgaXNuJ3QgdGhlIHNhbWUgd2hpY2ggc2hvdWxkIGJlIHRoZVxuICAgICAgICAvLyBmcmFtZSB0aGF0IGNhbGxlZCBvdXIgc2FtcGxlIGZ1bmN0aW9uIGFuZCB0aGUgY29udHJvbC5cbiAgICAgICAgaWYgKHNhbXBsZUxpbmVzW3NdICE9PSBjb250cm9sTGluZXNbY10pIHtcbiAgICAgICAgICAvLyBJbiBWOCwgdGhlIGZpcnN0IGxpbmUgaXMgZGVzY3JpYmluZyB0aGUgbWVzc2FnZSBidXQgb3RoZXIgVk1zIGRvbid0LlxuICAgICAgICAgIC8vIElmIHdlJ3JlIGFib3V0IHRvIHJldHVybiB0aGUgZmlyc3QgbGluZSwgYW5kIHRoZSBjb250cm9sIGlzIGFsc28gb24gdGhlIHNhbWVcbiAgICAgICAgICAvLyBsaW5lLCB0aGF0J3MgYSBwcmV0dHkgZ29vZCBpbmRpY2F0b3IgdGhhdCBvdXIgc2FtcGxlIHRocmV3IGF0IHNhbWUgbGluZSBhc1xuICAgICAgICAgIC8vIHRoZSBjb250cm9sLiBJLmUuIGJlZm9yZSB3ZSBlbnRlcmVkIHRoZSBzYW1wbGUgZnJhbWUuIFNvIHdlIGlnbm9yZSB0aGlzIHJlc3VsdC5cbiAgICAgICAgICAvLyBUaGlzIGNhbiBoYXBwZW4gaWYgeW91IHBhc3NlZCBhIGNsYXNzIHRvIGZ1bmN0aW9uIGNvbXBvbmVudCwgb3Igbm9uLWZ1bmN0aW9uLlxuICAgICAgICAgIGlmIChzICE9PSAxIHx8IGMgIT09IDEpIHtcbiAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgcy0tO1xuICAgICAgICAgICAgICBjLS07IC8vIFdlIG1heSBzdGlsbCBoYXZlIHNpbWlsYXIgaW50ZXJtZWRpYXRlIGZyYW1lcyBmcm9tIHRoZSBjb25zdHJ1Y3QgY2FsbC5cbiAgICAgICAgICAgICAgLy8gVGhlIG5leHQgb25lIHRoYXQgaXNuJ3QgdGhlIHNhbWUgc2hvdWxkIGJlIG91ciBtYXRjaCB0aG91Z2guXG5cbiAgICAgICAgICAgICAgaWYgKGMgPCAwIHx8IHNhbXBsZUxpbmVzW3NdICE9PSBjb250cm9sTGluZXNbY10pIHtcbiAgICAgICAgICAgICAgICAvLyBWOCBhZGRzIGEgXCJuZXdcIiBwcmVmaXggZm9yIG5hdGl2ZSBjbGFzc2VzLiBMZXQncyByZW1vdmUgaXQgdG8gbWFrZSBpdCBwcmV0dGllci5cbiAgICAgICAgICAgICAgICB2YXIgX2ZyYW1lID0gJ1xcbicgKyBzYW1wbGVMaW5lc1tzXS5yZXBsYWNlKCcgYXQgbmV3ICcsICcgYXQgJyk7IC8vIElmIG91ciBjb21wb25lbnQgZnJhbWUgaXMgbGFiZWxlZCBcIjxhbm9ueW1vdXM+XCJcbiAgICAgICAgICAgICAgICAvLyBidXQgd2UgaGF2ZSBhIHVzZXItcHJvdmlkZWQgXCJkaXNwbGF5TmFtZVwiXG4gICAgICAgICAgICAgICAgLy8gc3BsaWNlIGl0IGluIHRvIG1ha2UgdGhlIHN0YWNrIG1vcmUgcmVhZGFibGUuXG5cblxuICAgICAgICAgICAgICAgIGlmIChmbi5kaXNwbGF5TmFtZSAmJiBfZnJhbWUuaW5jbHVkZXMoJzxhbm9ueW1vdXM+JykpIHtcbiAgICAgICAgICAgICAgICAgIF9mcmFtZSA9IF9mcmFtZS5yZXBsYWNlKCc8YW5vbnltb3VzPicsIGZuLmRpc3BsYXlOYW1lKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudEZyYW1lQ2FjaGUuc2V0KGZuLCBfZnJhbWUpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gLy8gUmV0dXJuIHRoZSBsaW5lIHdlIGZvdW5kLlxuXG5cbiAgICAgICAgICAgICAgICByZXR1cm4gX2ZyYW1lO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IHdoaWxlIChzID49IDEgJiYgYyA+PSAwKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICByZWVudHJ5ID0gZmFsc2U7XG5cbiAgICB7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZpb3VzRGlzcGF0Y2hlcjtcbiAgICAgIHJlZW5hYmxlTG9ncygpO1xuICAgIH1cblxuICAgIEVycm9yLnByZXBhcmVTdGFja1RyYWNlID0gcHJldmlvdXNQcmVwYXJlU3RhY2tUcmFjZTtcbiAgfSAvLyBGYWxsYmFjayB0byBqdXN0IHVzaW5nIHRoZSBuYW1lIGlmIHdlIGNvdWxkbid0IG1ha2UgaXQgdGhyb3cuXG5cblxuICB2YXIgbmFtZSA9IGZuID8gZm4uZGlzcGxheU5hbWUgfHwgZm4ubmFtZSA6ICcnO1xuICB2YXIgc3ludGhldGljRnJhbWUgPSBuYW1lID8gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUobmFtZSkgOiAnJztcblxuICB7XG4gICAgaWYgKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29tcG9uZW50RnJhbWVDYWNoZS5zZXQoZm4sIHN5bnRoZXRpY0ZyYW1lKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3ludGhldGljRnJhbWU7XG59XG5mdW5jdGlvbiBkZXNjcmliZUZ1bmN0aW9uQ29tcG9uZW50RnJhbWUoZm4sIHNvdXJjZSwgb3duZXJGbikge1xuICB7XG4gICAgcmV0dXJuIGRlc2NyaWJlTmF0aXZlQ29tcG9uZW50RnJhbWUoZm4sIGZhbHNlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzaG91bGRDb25zdHJ1Y3QoQ29tcG9uZW50KSB7XG4gIHZhciBwcm90b3R5cGUgPSBDb21wb25lbnQucHJvdG90eXBlO1xuICByZXR1cm4gISEocHJvdG90eXBlICYmIHByb3RvdHlwZS5pc1JlYWN0Q29tcG9uZW50KTtcbn1cblxuZnVuY3Rpb24gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKHR5cGUsIHNvdXJjZSwgb3duZXJGbikge1xuXG4gIGlmICh0eXBlID09IG51bGwpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICB7XG4gICAgICByZXR1cm4gZGVzY3JpYmVOYXRpdmVDb21wb25lbnRGcmFtZSh0eXBlLCBzaG91bGRDb25zdHJ1Y3QodHlwZSkpO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUodHlwZSk7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX1RZUEU6XG4gICAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUoJ1N1c3BlbnNlJyk7XG5cbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRTpcbiAgICAgIHJldHVybiBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZSgnU3VzcGVuc2VMaXN0Jyk7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgc3dpdGNoICh0eXBlLiQkdHlwZW9mKSB7XG4gICAgICBjYXNlIFJFQUNUX0ZPUldBUkRfUkVGX1RZUEU6XG4gICAgICAgIHJldHVybiBkZXNjcmliZUZ1bmN0aW9uQ29tcG9uZW50RnJhbWUodHlwZS5yZW5kZXIpO1xuXG4gICAgICBjYXNlIFJFQUNUX01FTU9fVFlQRTpcbiAgICAgICAgLy8gTWVtbyBtYXkgY29udGFpbiBhbnkgY29tcG9uZW50IHR5cGUgc28gd2UgcmVjdXJzaXZlbHkgcmVzb2x2ZSBpdC5cbiAgICAgICAgcmV0dXJuIGRlc2NyaWJlVW5rbm93bkVsZW1lbnRUeXBlRnJhbWVJbkRFVih0eXBlLnR5cGUsIHNvdXJjZSwgb3duZXJGbik7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIGxhenlDb21wb25lbnQgPSB0eXBlO1xuICAgICAgICAgIHZhciBwYXlsb2FkID0gbGF6eUNvbXBvbmVudC5fcGF5bG9hZDtcbiAgICAgICAgICB2YXIgaW5pdCA9IGxhenlDb21wb25lbnQuX2luaXQ7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gTGF6eSBtYXkgY29udGFpbiBhbnkgY29tcG9uZW50IHR5cGUgc28gd2UgcmVjdXJzaXZlbHkgcmVzb2x2ZSBpdC5cbiAgICAgICAgICAgIHJldHVybiBkZXNjcmliZVVua25vd25FbGVtZW50VHlwZUZyYW1lSW5ERVYoaW5pdChwYXlsb2FkKSwgc291cmNlLCBvd25lckZuKTtcbiAgICAgICAgICB9IGNhdGNoICh4KSB7fVxuICAgICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuICcnO1xufVxuXG52YXIgbG9nZ2VkVHlwZUZhaWx1cmVzID0ge307XG52YXIgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSQxID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZTtcblxuZnVuY3Rpb24gc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQoZWxlbWVudCkge1xuICB7XG4gICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgIHZhciBvd25lciA9IGVsZW1lbnQuX293bmVyO1xuICAgICAgdmFyIHN0YWNrID0gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKGVsZW1lbnQudHlwZSwgZWxlbWVudC5fc291cmNlLCBvd25lciA/IG93bmVyLnR5cGUgOiBudWxsKTtcbiAgICAgIFJlYWN0RGVidWdDdXJyZW50RnJhbWUkMS5zZXRFeHRyYVN0YWNrRnJhbWUoc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICBSZWFjdERlYnVnQ3VycmVudEZyYW1lJDEuc2V0RXh0cmFTdGFja0ZyYW1lKG51bGwpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjaGVja1Byb3BUeXBlcyh0eXBlU3BlY3MsIHZhbHVlcywgbG9jYXRpb24sIGNvbXBvbmVudE5hbWUsIGVsZW1lbnQpIHtcbiAge1xuICAgIC8vICRGbG93Rml4TWUgVGhpcyBpcyBva2F5IGJ1dCBGbG93IGRvZXNuJ3Qga25vdyBpdC5cbiAgICB2YXIgaGFzID0gRnVuY3Rpb24uY2FsbC5iaW5kKGhhc093blByb3BlcnR5KTtcblxuICAgIGZvciAodmFyIHR5cGVTcGVjTmFtZSBpbiB0eXBlU3BlY3MpIHtcbiAgICAgIGlmIChoYXModHlwZVNwZWNzLCB0eXBlU3BlY05hbWUpKSB7XG4gICAgICAgIHZhciBlcnJvciQxID0gdm9pZCAwOyAvLyBQcm9wIHR5cGUgdmFsaWRhdGlvbiBtYXkgdGhyb3cuIEluIGNhc2UgdGhleSBkbywgd2UgZG9uJ3Qgd2FudCB0b1xuICAgICAgICAvLyBmYWlsIHRoZSByZW5kZXIgcGhhc2Ugd2hlcmUgaXQgZGlkbid0IGZhaWwgYmVmb3JlLiBTbyB3ZSBsb2cgaXQuXG4gICAgICAgIC8vIEFmdGVyIHRoZXNlIGhhdmUgYmVlbiBjbGVhbmVkIHVwLCB3ZSdsbCBsZXQgdGhlbSB0aHJvdy5cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIFRoaXMgaXMgaW50ZW50aW9uYWxseSBhbiBpbnZhcmlhbnQgdGhhdCBnZXRzIGNhdWdodC4gSXQncyB0aGUgc2FtZVxuICAgICAgICAgIC8vIGJlaGF2aW9yIGFzIHdpdGhvdXQgdGhpcyBzdGF0ZW1lbnQgZXhjZXB0IHdpdGggYSBiZXR0ZXIgbWVzc2FnZS5cbiAgICAgICAgICBpZiAodHlwZW9mIHR5cGVTcGVjc1t0eXBlU3BlY05hbWVdICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2Rlc1xuICAgICAgICAgICAgdmFyIGVyciA9IEVycm9yKChjb21wb25lbnROYW1lIHx8ICdSZWFjdCBjbGFzcycpICsgJzogJyArIGxvY2F0aW9uICsgJyB0eXBlIGAnICsgdHlwZVNwZWNOYW1lICsgJ2AgaXMgaW52YWxpZDsgJyArICdpdCBtdXN0IGJlIGEgZnVuY3Rpb24sIHVzdWFsbHkgZnJvbSB0aGUgYHByb3AtdHlwZXNgIHBhY2thZ2UsIGJ1dCByZWNlaXZlZCBgJyArIHR5cGVvZiB0eXBlU3BlY3NbdHlwZVNwZWNOYW1lXSArICdgLicgKyAnVGhpcyBvZnRlbiBoYXBwZW5zIGJlY2F1c2Ugb2YgdHlwb3Mgc3VjaCBhcyBgUHJvcFR5cGVzLmZ1bmN0aW9uYCBpbnN0ZWFkIG9mIGBQcm9wVHlwZXMuZnVuY2AuJyk7XG4gICAgICAgICAgICBlcnIubmFtZSA9ICdJbnZhcmlhbnQgVmlvbGF0aW9uJztcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlcnJvciQxID0gdHlwZVNwZWNzW3R5cGVTcGVjTmFtZV0odmFsdWVzLCB0eXBlU3BlY05hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBudWxsLCAnU0VDUkVUX0RPX05PVF9QQVNTX1RISVNfT1JfWU9VX1dJTExfQkVfRklSRUQnKTtcbiAgICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgICBlcnJvciQxID0gZXg7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXJyb3IkMSAmJiAhKGVycm9yJDEgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChlbGVtZW50KTtcblxuICAgICAgICAgIGVycm9yKCclczogdHlwZSBzcGVjaWZpY2F0aW9uIG9mICVzJyArICcgYCVzYCBpcyBpbnZhbGlkOyB0aGUgdHlwZSBjaGVja2VyICcgKyAnZnVuY3Rpb24gbXVzdCByZXR1cm4gYG51bGxgIG9yIGFuIGBFcnJvcmAgYnV0IHJldHVybmVkIGEgJXMuICcgKyAnWW91IG1heSBoYXZlIGZvcmdvdHRlbiB0byBwYXNzIGFuIGFyZ3VtZW50IHRvIHRoZSB0eXBlIGNoZWNrZXIgJyArICdjcmVhdG9yIChhcnJheU9mLCBpbnN0YW5jZU9mLCBvYmplY3RPZiwgb25lT2YsIG9uZU9mVHlwZSwgYW5kICcgKyAnc2hhcGUgYWxsIHJlcXVpcmUgYW4gYXJndW1lbnQpLicsIGNvbXBvbmVudE5hbWUgfHwgJ1JlYWN0IGNsYXNzJywgbG9jYXRpb24sIHR5cGVTcGVjTmFtZSwgdHlwZW9mIGVycm9yJDEpO1xuXG4gICAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQobnVsbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXJyb3IkMSBpbnN0YW5jZW9mIEVycm9yICYmICEoZXJyb3IkMS5tZXNzYWdlIGluIGxvZ2dlZFR5cGVGYWlsdXJlcykpIHtcbiAgICAgICAgICAvLyBPbmx5IG1vbml0b3IgdGhpcyBmYWlsdXJlIG9uY2UgYmVjYXVzZSB0aGVyZSB0ZW5kcyB0byBiZSBhIGxvdCBvZiB0aGVcbiAgICAgICAgICAvLyBzYW1lIGVycm9yLlxuICAgICAgICAgIGxvZ2dlZFR5cGVGYWlsdXJlc1tlcnJvciQxLm1lc3NhZ2VdID0gdHJ1ZTtcbiAgICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChlbGVtZW50KTtcblxuICAgICAgICAgIGVycm9yKCdGYWlsZWQgJXMgdHlwZTogJXMnLCBsb2NhdGlvbiwgZXJyb3IkMS5tZXNzYWdlKTtcblxuICAgICAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KG51bGwpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEoZWxlbWVudCkge1xuICB7XG4gICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgIHZhciBvd25lciA9IGVsZW1lbnQuX293bmVyO1xuICAgICAgdmFyIHN0YWNrID0gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKGVsZW1lbnQudHlwZSwgZWxlbWVudC5fc291cmNlLCBvd25lciA/IG93bmVyLnR5cGUgOiBudWxsKTtcbiAgICAgIHNldEV4dHJhU3RhY2tGcmFtZShzdGFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldEV4dHJhU3RhY2tGcmFtZShudWxsKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIHByb3BUeXBlc01pc3NwZWxsV2FybmluZ1Nob3duO1xuXG57XG4gIHByb3BUeXBlc01pc3NwZWxsV2FybmluZ1Nob3duID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bSgpIHtcbiAgaWYgKFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQpIHtcbiAgICB2YXIgbmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50LnR5cGUpO1xuXG4gICAgaWYgKG5hbWUpIHtcbiAgICAgIHJldHVybiAnXFxuXFxuQ2hlY2sgdGhlIHJlbmRlciBtZXRob2Qgb2YgYCcgKyBuYW1lICsgJ2AuJztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gJyc7XG59XG5cbmZ1bmN0aW9uIGdldFNvdXJjZUluZm9FcnJvckFkZGVuZHVtKHNvdXJjZSkge1xuICBpZiAoc291cmNlICE9PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgZmlsZU5hbWUgPSBzb3VyY2UuZmlsZU5hbWUucmVwbGFjZSgvXi4qW1xcXFxcXC9dLywgJycpO1xuICAgIHZhciBsaW5lTnVtYmVyID0gc291cmNlLmxpbmVOdW1iZXI7XG4gICAgcmV0dXJuICdcXG5cXG5DaGVjayB5b3VyIGNvZGUgYXQgJyArIGZpbGVOYW1lICsgJzonICsgbGluZU51bWJlciArICcuJztcbiAgfVxuXG4gIHJldHVybiAnJztcbn1cblxuZnVuY3Rpb24gZ2V0U291cmNlSW5mb0Vycm9yQWRkZW5kdW1Gb3JQcm9wcyhlbGVtZW50UHJvcHMpIHtcbiAgaWYgKGVsZW1lbnRQcm9wcyAhPT0gbnVsbCAmJiBlbGVtZW50UHJvcHMgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBnZXRTb3VyY2VJbmZvRXJyb3JBZGRlbmR1bShlbGVtZW50UHJvcHMuX19zb3VyY2UpO1xuICB9XG5cbiAgcmV0dXJuICcnO1xufVxuLyoqXG4gKiBXYXJuIGlmIHRoZXJlJ3Mgbm8ga2V5IGV4cGxpY2l0bHkgc2V0IG9uIGR5bmFtaWMgYXJyYXlzIG9mIGNoaWxkcmVuIG9yXG4gKiBvYmplY3Qga2V5cyBhcmUgbm90IHZhbGlkLiBUaGlzIGFsbG93cyB1cyB0byBrZWVwIHRyYWNrIG9mIGNoaWxkcmVuIGJldHdlZW5cbiAqIHVwZGF0ZXMuXG4gKi9cblxuXG52YXIgb3duZXJIYXNLZXlVc2VXYXJuaW5nID0ge307XG5cbmZ1bmN0aW9uIGdldEN1cnJlbnRDb21wb25lbnRFcnJvckluZm8ocGFyZW50VHlwZSkge1xuICB2YXIgaW5mbyA9IGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bSgpO1xuXG4gIGlmICghaW5mbykge1xuICAgIHZhciBwYXJlbnROYW1lID0gdHlwZW9mIHBhcmVudFR5cGUgPT09ICdzdHJpbmcnID8gcGFyZW50VHlwZSA6IHBhcmVudFR5cGUuZGlzcGxheU5hbWUgfHwgcGFyZW50VHlwZS5uYW1lO1xuXG4gICAgaWYgKHBhcmVudE5hbWUpIHtcbiAgICAgIGluZm8gPSBcIlxcblxcbkNoZWNrIHRoZSB0b3AtbGV2ZWwgcmVuZGVyIGNhbGwgdXNpbmcgPFwiICsgcGFyZW50TmFtZSArIFwiPi5cIjtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaW5mbztcbn1cbi8qKlxuICogV2FybiBpZiB0aGUgZWxlbWVudCBkb2Vzbid0IGhhdmUgYW4gZXhwbGljaXQga2V5IGFzc2lnbmVkIHRvIGl0LlxuICogVGhpcyBlbGVtZW50IGlzIGluIGFuIGFycmF5LiBUaGUgYXJyYXkgY291bGQgZ3JvdyBhbmQgc2hyaW5rIG9yIGJlXG4gKiByZW9yZGVyZWQuIEFsbCBjaGlsZHJlbiB0aGF0IGhhdmVuJ3QgYWxyZWFkeSBiZWVuIHZhbGlkYXRlZCBhcmUgcmVxdWlyZWQgdG9cbiAqIGhhdmUgYSBcImtleVwiIHByb3BlcnR5IGFzc2lnbmVkIHRvIGl0LiBFcnJvciBzdGF0dXNlcyBhcmUgY2FjaGVkIHNvIGEgd2FybmluZ1xuICogd2lsbCBvbmx5IGJlIHNob3duIG9uY2UuXG4gKlxuICogQGludGVybmFsXG4gKiBAcGFyYW0ge1JlYWN0RWxlbWVudH0gZWxlbWVudCBFbGVtZW50IHRoYXQgcmVxdWlyZXMgYSBrZXkuXG4gKiBAcGFyYW0geyp9IHBhcmVudFR5cGUgZWxlbWVudCdzIHBhcmVudCdzIHR5cGUuXG4gKi9cblxuXG5mdW5jdGlvbiB2YWxpZGF0ZUV4cGxpY2l0S2V5KGVsZW1lbnQsIHBhcmVudFR5cGUpIHtcbiAgaWYgKCFlbGVtZW50Ll9zdG9yZSB8fCBlbGVtZW50Ll9zdG9yZS52YWxpZGF0ZWQgfHwgZWxlbWVudC5rZXkgIT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGVsZW1lbnQuX3N0b3JlLnZhbGlkYXRlZCA9IHRydWU7XG4gIHZhciBjdXJyZW50Q29tcG9uZW50RXJyb3JJbmZvID0gZ2V0Q3VycmVudENvbXBvbmVudEVycm9ySW5mbyhwYXJlbnRUeXBlKTtcblxuICBpZiAob3duZXJIYXNLZXlVc2VXYXJuaW5nW2N1cnJlbnRDb21wb25lbnRFcnJvckluZm9dKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgb3duZXJIYXNLZXlVc2VXYXJuaW5nW2N1cnJlbnRDb21wb25lbnRFcnJvckluZm9dID0gdHJ1ZTsgLy8gVXN1YWxseSB0aGUgY3VycmVudCBvd25lciBpcyB0aGUgb2ZmZW5kZXIsIGJ1dCBpZiBpdCBhY2NlcHRzIGNoaWxkcmVuIGFzIGFcbiAgLy8gcHJvcGVydHksIGl0IG1heSBiZSB0aGUgY3JlYXRvciBvZiB0aGUgY2hpbGQgdGhhdCdzIHJlc3BvbnNpYmxlIGZvclxuICAvLyBhc3NpZ25pbmcgaXQgYSBrZXkuXG5cbiAgdmFyIGNoaWxkT3duZXIgPSAnJztcblxuICBpZiAoZWxlbWVudCAmJiBlbGVtZW50Ll9vd25lciAmJiBlbGVtZW50Ll9vd25lciAhPT0gUmVhY3RDdXJyZW50T3duZXIuY3VycmVudCkge1xuICAgIC8vIEdpdmUgdGhlIGNvbXBvbmVudCB0aGF0IG9yaWdpbmFsbHkgY3JlYXRlZCB0aGlzIGNoaWxkLlxuICAgIGNoaWxkT3duZXIgPSBcIiBJdCB3YXMgcGFzc2VkIGEgY2hpbGQgZnJvbSBcIiArIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShlbGVtZW50Ll9vd25lci50eXBlKSArIFwiLlwiO1xuICB9XG5cbiAge1xuICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEoZWxlbWVudCk7XG5cbiAgICBlcnJvcignRWFjaCBjaGlsZCBpbiBhIGxpc3Qgc2hvdWxkIGhhdmUgYSB1bmlxdWUgXCJrZXlcIiBwcm9wLicgKyAnJXMlcyBTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3dhcm5pbmcta2V5cyBmb3IgbW9yZSBpbmZvcm1hdGlvbi4nLCBjdXJyZW50Q29tcG9uZW50RXJyb3JJbmZvLCBjaGlsZE93bmVyKTtcblxuICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEobnVsbCk7XG4gIH1cbn1cbi8qKlxuICogRW5zdXJlIHRoYXQgZXZlcnkgZWxlbWVudCBlaXRoZXIgaXMgcGFzc2VkIGluIGEgc3RhdGljIGxvY2F0aW9uLCBpbiBhblxuICogYXJyYXkgd2l0aCBhbiBleHBsaWNpdCBrZXlzIHByb3BlcnR5IGRlZmluZWQsIG9yIGluIGFuIG9iamVjdCBsaXRlcmFsXG4gKiB3aXRoIHZhbGlkIGtleSBwcm9wZXJ0eS5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqIEBwYXJhbSB7UmVhY3ROb2RlfSBub2RlIFN0YXRpY2FsbHkgcGFzc2VkIGNoaWxkIG9mIGFueSB0eXBlLlxuICogQHBhcmFtIHsqfSBwYXJlbnRUeXBlIG5vZGUncyBwYXJlbnQncyB0eXBlLlxuICovXG5cblxuZnVuY3Rpb24gdmFsaWRhdGVDaGlsZEtleXMobm9kZSwgcGFyZW50VHlwZSkge1xuICBpZiAodHlwZW9mIG5vZGUgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGlzQXJyYXkobm9kZSkpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGUubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBjaGlsZCA9IG5vZGVbaV07XG5cbiAgICAgIGlmIChpc1ZhbGlkRWxlbWVudChjaGlsZCkpIHtcbiAgICAgICAgdmFsaWRhdGVFeHBsaWNpdEtleShjaGlsZCwgcGFyZW50VHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzVmFsaWRFbGVtZW50KG5vZGUpKSB7XG4gICAgLy8gVGhpcyBlbGVtZW50IHdhcyBwYXNzZWQgaW4gYSB2YWxpZCBsb2NhdGlvbi5cbiAgICBpZiAobm9kZS5fc3RvcmUpIHtcbiAgICAgIG5vZGUuX3N0b3JlLnZhbGlkYXRlZCA9IHRydWU7XG4gICAgfVxuICB9IGVsc2UgaWYgKG5vZGUpIHtcbiAgICB2YXIgaXRlcmF0b3JGbiA9IGdldEl0ZXJhdG9yRm4obm9kZSk7XG5cbiAgICBpZiAodHlwZW9mIGl0ZXJhdG9yRm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIEVudHJ5IGl0ZXJhdG9ycyB1c2VkIHRvIHByb3ZpZGUgaW1wbGljaXQga2V5cyxcbiAgICAgIC8vIGJ1dCBub3cgd2UgcHJpbnQgYSBzZXBhcmF0ZSB3YXJuaW5nIGZvciB0aGVtIGxhdGVyLlxuICAgICAgaWYgKGl0ZXJhdG9yRm4gIT09IG5vZGUuZW50cmllcykge1xuICAgICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYXRvckZuLmNhbGwobm9kZSk7XG4gICAgICAgIHZhciBzdGVwO1xuXG4gICAgICAgIHdoaWxlICghKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgICAgICBpZiAoaXNWYWxpZEVsZW1lbnQoc3RlcC52YWx1ZSkpIHtcbiAgICAgICAgICAgIHZhbGlkYXRlRXhwbGljaXRLZXkoc3RlcC52YWx1ZSwgcGFyZW50VHlwZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEdpdmVuIGFuIGVsZW1lbnQsIHZhbGlkYXRlIHRoYXQgaXRzIHByb3BzIGZvbGxvdyB0aGUgcHJvcFR5cGVzIGRlZmluaXRpb24sXG4gKiBwcm92aWRlZCBieSB0aGUgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge1JlYWN0RWxlbWVudH0gZWxlbWVudFxuICovXG5cblxuZnVuY3Rpb24gdmFsaWRhdGVQcm9wVHlwZXMoZWxlbWVudCkge1xuICB7XG4gICAgdmFyIHR5cGUgPSBlbGVtZW50LnR5cGU7XG5cbiAgICBpZiAodHlwZSA9PT0gbnVsbCB8fCB0eXBlID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHByb3BUeXBlcztcblxuICAgIGlmICh0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcHJvcFR5cGVzID0gdHlwZS5wcm9wVHlwZXM7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcgJiYgKHR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX0ZPUldBUkRfUkVGX1RZUEUgfHwgLy8gTm90ZTogTWVtbyBvbmx5IGNoZWNrcyBvdXRlciBwcm9wcyBoZXJlLlxuICAgIC8vIElubmVyIHByb3BzIGFyZSBjaGVja2VkIGluIHRoZSByZWNvbmNpbGVyLlxuICAgIHR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX01FTU9fVFlQRSkpIHtcbiAgICAgIHByb3BUeXBlcyA9IHR5cGUucHJvcFR5cGVzO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHByb3BUeXBlcykge1xuICAgICAgLy8gSW50ZW50aW9uYWxseSBpbnNpZGUgdG8gYXZvaWQgdHJpZ2dlcmluZyBsYXp5IGluaXRpYWxpemVyczpcbiAgICAgIHZhciBuYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKHR5cGUpO1xuICAgICAgY2hlY2tQcm9wVHlwZXMocHJvcFR5cGVzLCBlbGVtZW50LnByb3BzLCAncHJvcCcsIG5hbWUsIGVsZW1lbnQpO1xuICAgIH0gZWxzZSBpZiAodHlwZS5Qcm9wVHlwZXMgIT09IHVuZGVmaW5lZCAmJiAhcHJvcFR5cGVzTWlzc3BlbGxXYXJuaW5nU2hvd24pIHtcbiAgICAgIHByb3BUeXBlc01pc3NwZWxsV2FybmluZ1Nob3duID0gdHJ1ZTsgLy8gSW50ZW50aW9uYWxseSBpbnNpZGUgdG8gYXZvaWQgdHJpZ2dlcmluZyBsYXp5IGluaXRpYWxpemVyczpcblxuICAgICAgdmFyIF9uYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKHR5cGUpO1xuXG4gICAgICBlcnJvcignQ29tcG9uZW50ICVzIGRlY2xhcmVkIGBQcm9wVHlwZXNgIGluc3RlYWQgb2YgYHByb3BUeXBlc2AuIERpZCB5b3UgbWlzc3BlbGwgdGhlIHByb3BlcnR5IGFzc2lnbm1lbnQ/JywgX25hbWUgfHwgJ1Vua25vd24nKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHR5cGUuZ2V0RGVmYXVsdFByb3BzID09PSAnZnVuY3Rpb24nICYmICF0eXBlLmdldERlZmF1bHRQcm9wcy5pc1JlYWN0Q2xhc3NBcHByb3ZlZCkge1xuICAgICAgZXJyb3IoJ2dldERlZmF1bHRQcm9wcyBpcyBvbmx5IHVzZWQgb24gY2xhc3NpYyBSZWFjdC5jcmVhdGVDbGFzcyAnICsgJ2RlZmluaXRpb25zLiBVc2UgYSBzdGF0aWMgcHJvcGVydHkgbmFtZWQgYGRlZmF1bHRQcm9wc2AgaW5zdGVhZC4nKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogR2l2ZW4gYSBmcmFnbWVudCwgdmFsaWRhdGUgdGhhdCBpdCBjYW4gb25seSBiZSBwcm92aWRlZCB3aXRoIGZyYWdtZW50IHByb3BzXG4gKiBAcGFyYW0ge1JlYWN0RWxlbWVudH0gZnJhZ21lbnRcbiAqL1xuXG5cbmZ1bmN0aW9uIHZhbGlkYXRlRnJhZ21lbnRQcm9wcyhmcmFnbWVudCkge1xuICB7XG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhmcmFnbWVudC5wcm9wcyk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuXG4gICAgICBpZiAoa2V5ICE9PSAnY2hpbGRyZW4nICYmIGtleSAhPT0gJ2tleScpIHtcbiAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQkMShmcmFnbWVudCk7XG5cbiAgICAgICAgZXJyb3IoJ0ludmFsaWQgcHJvcCBgJXNgIHN1cHBsaWVkIHRvIGBSZWFjdC5GcmFnbWVudGAuICcgKyAnUmVhY3QuRnJhZ21lbnQgY2FuIG9ubHkgaGF2ZSBga2V5YCBhbmQgYGNoaWxkcmVuYCBwcm9wcy4nLCBrZXkpO1xuXG4gICAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEobnVsbCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChmcmFnbWVudC5yZWYgIT09IG51bGwpIHtcbiAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEoZnJhZ21lbnQpO1xuXG4gICAgICBlcnJvcignSW52YWxpZCBhdHRyaWJ1dGUgYHJlZmAgc3VwcGxpZWQgdG8gYFJlYWN0LkZyYWdtZW50YC4nKTtcblxuICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQkMShudWxsKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnRXaXRoVmFsaWRhdGlvbih0eXBlLCBwcm9wcywgY2hpbGRyZW4pIHtcbiAgdmFyIHZhbGlkVHlwZSA9IGlzVmFsaWRFbGVtZW50VHlwZSh0eXBlKTsgLy8gV2Ugd2FybiBpbiB0aGlzIGNhc2UgYnV0IGRvbid0IHRocm93LiBXZSBleHBlY3QgdGhlIGVsZW1lbnQgY3JlYXRpb24gdG9cbiAgLy8gc3VjY2VlZCBhbmQgdGhlcmUgd2lsbCBsaWtlbHkgYmUgZXJyb3JzIGluIHJlbmRlci5cblxuICBpZiAoIXZhbGlkVHlwZSkge1xuICAgIHZhciBpbmZvID0gJyc7XG5cbiAgICBpZiAodHlwZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiB0eXBlID09PSAnb2JqZWN0JyAmJiB0eXBlICE9PSBudWxsICYmIE9iamVjdC5rZXlzKHR5cGUpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaW5mbyArPSAnIFlvdSBsaWtlbHkgZm9yZ290IHRvIGV4cG9ydCB5b3VyIGNvbXBvbmVudCBmcm9tIHRoZSBmaWxlICcgKyBcIml0J3MgZGVmaW5lZCBpbiwgb3IgeW91IG1pZ2h0IGhhdmUgbWl4ZWQgdXAgZGVmYXVsdCBhbmQgbmFtZWQgaW1wb3J0cy5cIjtcbiAgICB9XG5cbiAgICB2YXIgc291cmNlSW5mbyA9IGdldFNvdXJjZUluZm9FcnJvckFkZGVuZHVtRm9yUHJvcHMocHJvcHMpO1xuXG4gICAgaWYgKHNvdXJjZUluZm8pIHtcbiAgICAgIGluZm8gKz0gc291cmNlSW5mbztcbiAgICB9IGVsc2Uge1xuICAgICAgaW5mbyArPSBnZXREZWNsYXJhdGlvbkVycm9yQWRkZW5kdW0oKTtcbiAgICB9XG5cbiAgICB2YXIgdHlwZVN0cmluZztcblxuICAgIGlmICh0eXBlID09PSBudWxsKSB7XG4gICAgICB0eXBlU3RyaW5nID0gJ251bGwnO1xuICAgIH0gZWxzZSBpZiAoaXNBcnJheSh0eXBlKSkge1xuICAgICAgdHlwZVN0cmluZyA9ICdhcnJheSc7XG4gICAgfSBlbHNlIGlmICh0eXBlICE9PSB1bmRlZmluZWQgJiYgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfRUxFTUVOVF9UWVBFKSB7XG4gICAgICB0eXBlU3RyaW5nID0gXCI8XCIgKyAoZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKHR5cGUudHlwZSkgfHwgJ1Vua25vd24nKSArIFwiIC8+XCI7XG4gICAgICBpbmZvID0gJyBEaWQgeW91IGFjY2lkZW50YWxseSBleHBvcnQgYSBKU1ggbGl0ZXJhbCBpbnN0ZWFkIG9mIGEgY29tcG9uZW50Pyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHR5cGVTdHJpbmcgPSB0eXBlb2YgdHlwZTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBlcnJvcignUmVhY3QuY3JlYXRlRWxlbWVudDogdHlwZSBpcyBpbnZhbGlkIC0tIGV4cGVjdGVkIGEgc3RyaW5nIChmb3IgJyArICdidWlsdC1pbiBjb21wb25lbnRzKSBvciBhIGNsYXNzL2Z1bmN0aW9uIChmb3IgY29tcG9zaXRlICcgKyAnY29tcG9uZW50cykgYnV0IGdvdDogJXMuJXMnLCB0eXBlU3RyaW5nLCBpbmZvKTtcbiAgICB9XG4gIH1cblxuICB2YXIgZWxlbWVudCA9IGNyZWF0ZUVsZW1lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gVGhlIHJlc3VsdCBjYW4gYmUgbnVsbGlzaCBpZiBhIG1vY2sgb3IgYSBjdXN0b20gZnVuY3Rpb24gaXMgdXNlZC5cbiAgLy8gVE9ETzogRHJvcCB0aGlzIHdoZW4gdGhlc2UgYXJlIG5vIGxvbmdlciBhbGxvd2VkIGFzIHRoZSB0eXBlIGFyZ3VtZW50LlxuXG4gIGlmIChlbGVtZW50ID09IG51bGwpIHtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfSAvLyBTa2lwIGtleSB3YXJuaW5nIGlmIHRoZSB0eXBlIGlzbid0IHZhbGlkIHNpbmNlIG91ciBrZXkgdmFsaWRhdGlvbiBsb2dpY1xuICAvLyBkb2Vzbid0IGV4cGVjdCBhIG5vbi1zdHJpbmcvZnVuY3Rpb24gdHlwZSBhbmQgY2FuIHRocm93IGNvbmZ1c2luZyBlcnJvcnMuXG4gIC8vIFdlIGRvbid0IHdhbnQgZXhjZXB0aW9uIGJlaGF2aW9yIHRvIGRpZmZlciBiZXR3ZWVuIGRldiBhbmQgcHJvZC5cbiAgLy8gKFJlbmRlcmluZyB3aWxsIHRocm93IHdpdGggYSBoZWxwZnVsIG1lc3NhZ2UgYW5kIGFzIHNvb24gYXMgdGhlIHR5cGUgaXNcbiAgLy8gZml4ZWQsIHRoZSBrZXkgd2FybmluZ3Mgd2lsbCBhcHBlYXIuKVxuXG5cbiAgaWYgKHZhbGlkVHlwZSkge1xuICAgIGZvciAodmFyIGkgPSAyOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YWxpZGF0ZUNoaWxkS2V5cyhhcmd1bWVudHNbaV0sIHR5cGUpO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0eXBlID09PSBSRUFDVF9GUkFHTUVOVF9UWVBFKSB7XG4gICAgdmFsaWRhdGVGcmFnbWVudFByb3BzKGVsZW1lbnQpO1xuICB9IGVsc2Uge1xuICAgIHZhbGlkYXRlUHJvcFR5cGVzKGVsZW1lbnQpO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59XG52YXIgZGlkV2FybkFib3V0RGVwcmVjYXRlZENyZWF0ZUZhY3RvcnkgPSBmYWxzZTtcbmZ1bmN0aW9uIGNyZWF0ZUZhY3RvcnlXaXRoVmFsaWRhdGlvbih0eXBlKSB7XG4gIHZhciB2YWxpZGF0ZWRGYWN0b3J5ID0gY3JlYXRlRWxlbWVudFdpdGhWYWxpZGF0aW9uLmJpbmQobnVsbCwgdHlwZSk7XG4gIHZhbGlkYXRlZEZhY3RvcnkudHlwZSA9IHR5cGU7XG5cbiAge1xuICAgIGlmICghZGlkV2FybkFib3V0RGVwcmVjYXRlZENyZWF0ZUZhY3RvcnkpIHtcbiAgICAgIGRpZFdhcm5BYm91dERlcHJlY2F0ZWRDcmVhdGVGYWN0b3J5ID0gdHJ1ZTtcblxuICAgICAgd2FybignUmVhY3QuY3JlYXRlRmFjdG9yeSgpIGlzIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiAnICsgJ2EgZnV0dXJlIG1ham9yIHJlbGVhc2UuIENvbnNpZGVyIHVzaW5nIEpTWCAnICsgJ29yIHVzZSBSZWFjdC5jcmVhdGVFbGVtZW50KCkgZGlyZWN0bHkgaW5zdGVhZC4nKTtcbiAgICB9IC8vIExlZ2FjeSBob29rOiByZW1vdmUgaXRcblxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHZhbGlkYXRlZEZhY3RvcnksICd0eXBlJywge1xuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2FybignRmFjdG9yeS50eXBlIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB0aGUgY2xhc3MgZGlyZWN0bHkgJyArICdiZWZvcmUgcGFzc2luZyBpdCB0byBjcmVhdGVGYWN0b3J5LicpO1xuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHlwZScsIHtcbiAgICAgICAgICB2YWx1ZTogdHlwZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHR5cGU7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gdmFsaWRhdGVkRmFjdG9yeTtcbn1cbmZ1bmN0aW9uIGNsb25lRWxlbWVudFdpdGhWYWxpZGF0aW9uKGVsZW1lbnQsIHByb3BzLCBjaGlsZHJlbikge1xuICB2YXIgbmV3RWxlbWVudCA9IGNsb25lRWxlbWVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gIGZvciAodmFyIGkgPSAyOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFsaWRhdGVDaGlsZEtleXMoYXJndW1lbnRzW2ldLCBuZXdFbGVtZW50LnR5cGUpO1xuICB9XG5cbiAgdmFsaWRhdGVQcm9wVHlwZXMobmV3RWxlbWVudCk7XG4gIHJldHVybiBuZXdFbGVtZW50O1xufVxuXG5mdW5jdGlvbiBzdGFydFRyYW5zaXRpb24oc2NvcGUsIG9wdGlvbnMpIHtcbiAgdmFyIHByZXZUcmFuc2l0aW9uID0gUmVhY3RDdXJyZW50QmF0Y2hDb25maWcudHJhbnNpdGlvbjtcbiAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWcudHJhbnNpdGlvbiA9IHt9O1xuICB2YXIgY3VycmVudFRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZy50cmFuc2l0aW9uO1xuXG4gIHtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZy50cmFuc2l0aW9uLl91cGRhdGVkRmliZXJzID0gbmV3IFNldCgpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBzY29wZSgpO1xuICB9IGZpbmFsbHkge1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb24gPSBwcmV2VHJhbnNpdGlvbjtcblxuICAgIHtcbiAgICAgIGlmIChwcmV2VHJhbnNpdGlvbiA9PT0gbnVsbCAmJiBjdXJyZW50VHJhbnNpdGlvbi5fdXBkYXRlZEZpYmVycykge1xuICAgICAgICB2YXIgdXBkYXRlZEZpYmVyc0NvdW50ID0gY3VycmVudFRyYW5zaXRpb24uX3VwZGF0ZWRGaWJlcnMuc2l6ZTtcblxuICAgICAgICBpZiAodXBkYXRlZEZpYmVyc0NvdW50ID4gMTApIHtcbiAgICAgICAgICB3YXJuKCdEZXRlY3RlZCBhIGxhcmdlIG51bWJlciBvZiB1cGRhdGVzIGluc2lkZSBzdGFydFRyYW5zaXRpb24uICcgKyAnSWYgdGhpcyBpcyBkdWUgdG8gYSBzdWJzY3JpcHRpb24gcGxlYXNlIHJlLXdyaXRlIGl0IHRvIHVzZSBSZWFjdCBwcm92aWRlZCBob29rcy4gJyArICdPdGhlcndpc2UgY29uY3VycmVudCBtb2RlIGd1YXJhbnRlZXMgYXJlIG9mZiB0aGUgdGFibGUuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50VHJhbnNpdGlvbi5fdXBkYXRlZEZpYmVycy5jbGVhcigpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG52YXIgZGlkV2FybkFib3V0TWVzc2FnZUNoYW5uZWwgPSBmYWxzZTtcbnZhciBlbnF1ZXVlVGFza0ltcGwgPSBudWxsO1xuZnVuY3Rpb24gZW5xdWV1ZVRhc2sodGFzaykge1xuICBpZiAoZW5xdWV1ZVRhc2tJbXBsID09PSBudWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIHJlYWQgcmVxdWlyZSBvZmYgdGhlIG1vZHVsZSBvYmplY3QgdG8gZ2V0IGFyb3VuZCB0aGUgYnVuZGxlcnMuXG4gICAgICAvLyB3ZSBkb24ndCB3YW50IHRoZW0gdG8gZGV0ZWN0IGEgcmVxdWlyZSBhbmQgYnVuZGxlIGEgTm9kZSBwb2x5ZmlsbC5cbiAgICAgIHZhciByZXF1aXJlU3RyaW5nID0gKCdyZXF1aXJlJyArIE1hdGgucmFuZG9tKCkpLnNsaWNlKDAsIDcpO1xuICAgICAgdmFyIG5vZGVSZXF1aXJlID0gbW9kdWxlICYmIG1vZHVsZVtyZXF1aXJlU3RyaW5nXTsgLy8gYXNzdW1pbmcgd2UncmUgaW4gbm9kZSwgbGV0J3MgdHJ5IHRvIGdldCBub2RlJ3NcbiAgICAgIC8vIHZlcnNpb24gb2Ygc2V0SW1tZWRpYXRlLCBieXBhc3NpbmcgZmFrZSB0aW1lcnMgaWYgYW55LlxuXG4gICAgICBlbnF1ZXVlVGFza0ltcGwgPSBub2RlUmVxdWlyZS5jYWxsKG1vZHVsZSwgJ3RpbWVycycpLnNldEltbWVkaWF0ZTtcbiAgICB9IGNhdGNoIChfZXJyKSB7XG4gICAgICAvLyB3ZSdyZSBpbiBhIGJyb3dzZXJcbiAgICAgIC8vIHdlIGNhbid0IHVzZSByZWd1bGFyIHRpbWVycyBiZWNhdXNlIHRoZXkgbWF5IHN0aWxsIGJlIGZha2VkXG4gICAgICAvLyBzbyB3ZSB0cnkgTWVzc2FnZUNoYW5uZWwrcG9zdE1lc3NhZ2UgaW5zdGVhZFxuICAgICAgZW5xdWV1ZVRhc2tJbXBsID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoZGlkV2FybkFib3V0TWVzc2FnZUNoYW5uZWwgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBkaWRXYXJuQWJvdXRNZXNzYWdlQ2hhbm5lbCA9IHRydWU7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgTWVzc2FnZUNoYW5uZWwgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgIGVycm9yKCdUaGlzIGJyb3dzZXIgZG9lcyBub3QgaGF2ZSBhIE1lc3NhZ2VDaGFubmVsIGltcGxlbWVudGF0aW9uLCAnICsgJ3NvIGVucXVldWluZyB0YXNrcyB2aWEgYXdhaXQgYWN0KGFzeW5jICgpID0+IC4uLikgd2lsbCBmYWlsLiAnICsgJ1BsZWFzZSBmaWxlIGFuIGlzc3VlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMgJyArICdpZiB5b3UgZW5jb3VudGVyIHRoaXMgd2FybmluZy4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGNhbGxiYWNrO1xuICAgICAgICBjaGFubmVsLnBvcnQyLnBvc3RNZXNzYWdlKHVuZGVmaW5lZCk7XG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbnF1ZXVlVGFza0ltcGwodGFzayk7XG59XG5cbnZhciBhY3RTY29wZURlcHRoID0gMDtcbnZhciBkaWRXYXJuTm9Bd2FpdEFjdCA9IGZhbHNlO1xuZnVuY3Rpb24gYWN0KGNhbGxiYWNrKSB7XG4gIHtcbiAgICAvLyBgYWN0YCBjYWxscyBjYW4gYmUgbmVzdGVkLCBzbyB3ZSB0cmFjayB0aGUgZGVwdGguIFRoaXMgcmVwcmVzZW50cyB0aGVcbiAgICAvLyBudW1iZXIgb2YgYGFjdGAgc2NvcGVzIG9uIHRoZSBzdGFjay5cbiAgICB2YXIgcHJldkFjdFNjb3BlRGVwdGggPSBhY3RTY29wZURlcHRoO1xuICAgIGFjdFNjb3BlRGVwdGgrKztcblxuICAgIGlmIChSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50ID09PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIGlzIHRoZSBvdXRlcm1vc3QgYGFjdGAgc2NvcGUuIEluaXRpYWxpemUgdGhlIHF1ZXVlLiBUaGUgcmVjb25jaWxlclxuICAgICAgLy8gd2lsbCBkZXRlY3QgdGhlIHF1ZXVlIGFuZCB1c2UgaXQgaW5zdGVhZCBvZiBTY2hlZHVsZXIuXG4gICAgICBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50ID0gW107XG4gICAgfVxuXG4gICAgdmFyIHByZXZJc0JhdGNoaW5nTGVnYWN5ID0gUmVhY3RDdXJyZW50QWN0UXVldWUuaXNCYXRjaGluZ0xlZ2FjeTtcbiAgICB2YXIgcmVzdWx0O1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFVzZWQgdG8gcmVwcm9kdWNlIGJlaGF2aW9yIG9mIGBiYXRjaGVkVXBkYXRlc2AgaW4gbGVnYWN5IG1vZGUuIE9ubHlcbiAgICAgIC8vIHNldCB0byBgdHJ1ZWAgd2hpbGUgdGhlIGdpdmVuIGNhbGxiYWNrIGlzIGV4ZWN1dGVkLCBub3QgZm9yIHVwZGF0ZXNcbiAgICAgIC8vIHRyaWdnZXJlZCBkdXJpbmcgYW4gYXN5bmMgZXZlbnQsIGJlY2F1c2UgdGhpcyBpcyBob3cgdGhlIGxlZ2FjeVxuICAgICAgLy8gaW1wbGVtZW50YXRpb24gb2YgYGFjdGAgYmVoYXZlZC5cbiAgICAgIFJlYWN0Q3VycmVudEFjdFF1ZXVlLmlzQmF0Y2hpbmdMZWdhY3kgPSB0cnVlO1xuICAgICAgcmVzdWx0ID0gY2FsbGJhY2soKTsgLy8gUmVwbGljYXRlIGJlaGF2aW9yIG9mIG9yaWdpbmFsIGBhY3RgIGltcGxlbWVudGF0aW9uIGluIGxlZ2FjeSBtb2RlLFxuICAgICAgLy8gd2hpY2ggZmx1c2hlZCB1cGRhdGVzIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBzY29wZSBmdW5jdGlvbiBleGl0cywgZXZlblxuICAgICAgLy8gaWYgaXQncyBhbiBhc3luYyBmdW5jdGlvbi5cblxuICAgICAgaWYgKCFwcmV2SXNCYXRjaGluZ0xlZ2FjeSAmJiBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5kaWRTY2hlZHVsZUxlZ2FjeVVwZGF0ZSkge1xuICAgICAgICB2YXIgcXVldWUgPSBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50O1xuXG4gICAgICAgIGlmIChxdWV1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIFJlYWN0Q3VycmVudEFjdFF1ZXVlLmRpZFNjaGVkdWxlTGVnYWN5VXBkYXRlID0gZmFsc2U7XG4gICAgICAgICAgZmx1c2hBY3RRdWV1ZShxdWV1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcG9wQWN0U2NvcGUocHJldkFjdFNjb3BlRGVwdGgpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIFJlYWN0Q3VycmVudEFjdFF1ZXVlLmlzQmF0Y2hpbmdMZWdhY3kgPSBwcmV2SXNCYXRjaGluZ0xlZ2FjeTtcbiAgICB9XG5cbiAgICBpZiAocmVzdWx0ICE9PSBudWxsICYmIHR5cGVvZiByZXN1bHQgPT09ICdvYmplY3QnICYmIHR5cGVvZiByZXN1bHQudGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIHRoZW5hYmxlUmVzdWx0ID0gcmVzdWx0OyAvLyBUaGUgY2FsbGJhY2sgaXMgYW4gYXN5bmMgZnVuY3Rpb24gKGkuZS4gcmV0dXJuZWQgYSBwcm9taXNlKS4gV2FpdFxuICAgICAgLy8gZm9yIGl0IHRvIHJlc29sdmUgYmVmb3JlIGV4aXRpbmcgdGhlIGN1cnJlbnQgc2NvcGUuXG5cbiAgICAgIHZhciB3YXNBd2FpdGVkID0gZmFsc2U7XG4gICAgICB2YXIgdGhlbmFibGUgPSB7XG4gICAgICAgIHRoZW46IGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICB3YXNBd2FpdGVkID0gdHJ1ZTtcbiAgICAgICAgICB0aGVuYWJsZVJlc3VsdC50aGVuKGZ1bmN0aW9uIChyZXR1cm5WYWx1ZSkge1xuICAgICAgICAgICAgcG9wQWN0U2NvcGUocHJldkFjdFNjb3BlRGVwdGgpO1xuXG4gICAgICAgICAgICBpZiAoYWN0U2NvcGVEZXB0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAvLyBXZSd2ZSBleGl0ZWQgdGhlIG91dGVybW9zdCBhY3Qgc2NvcGUuIFJlY3Vyc2l2ZWx5IGZsdXNoIHRoZVxuICAgICAgICAgICAgICAvLyBxdWV1ZSB1bnRpbCB0aGVyZSdzIG5vIHJlbWFpbmluZyB3b3JrLlxuICAgICAgICAgICAgICByZWN1cnNpdmVseUZsdXNoQXN5bmNBY3RXb3JrKHJldHVyblZhbHVlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShyZXR1cm5WYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICAvLyBUaGUgY2FsbGJhY2sgdGhyZXcgYW4gZXJyb3IuXG4gICAgICAgICAgICBwb3BBY3RTY29wZShwcmV2QWN0U2NvcGVEZXB0aCk7XG4gICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICB7XG4gICAgICAgIGlmICghZGlkV2Fybk5vQXdhaXRBY3QgJiYgdHlwZW9mIFByb21pc2UgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7fSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoIXdhc0F3YWl0ZWQpIHtcbiAgICAgICAgICAgICAgZGlkV2Fybk5vQXdhaXRBY3QgPSB0cnVlO1xuXG4gICAgICAgICAgICAgIGVycm9yKCdZb3UgY2FsbGVkIGFjdChhc3luYyAoKSA9PiAuLi4pIHdpdGhvdXQgYXdhaXQuICcgKyAnVGhpcyBjb3VsZCBsZWFkIHRvIHVuZXhwZWN0ZWQgdGVzdGluZyBiZWhhdmlvdXIsICcgKyAnaW50ZXJsZWF2aW5nIG11bHRpcGxlIGFjdCBjYWxscyBhbmQgbWl4aW5nIHRoZWlyICcgKyAnc2NvcGVzLiAnICsgJ1lvdSBzaG91bGQgLSBhd2FpdCBhY3QoYXN5bmMgKCkgPT4gLi4uKTsnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhlbmFibGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciByZXR1cm5WYWx1ZSA9IHJlc3VsdDsgLy8gVGhlIGNhbGxiYWNrIGlzIG5vdCBhbiBhc3luYyBmdW5jdGlvbi4gRXhpdCB0aGUgY3VycmVudCBzY29wZVxuICAgICAgLy8gaW1tZWRpYXRlbHksIHdpdGhvdXQgYXdhaXRpbmcuXG5cbiAgICAgIHBvcEFjdFNjb3BlKHByZXZBY3RTY29wZURlcHRoKTtcblxuICAgICAgaWYgKGFjdFNjb3BlRGVwdGggPT09IDApIHtcbiAgICAgICAgLy8gRXhpdGluZyB0aGUgb3V0ZXJtb3N0IGFjdCBzY29wZS4gRmx1c2ggdGhlIHF1ZXVlLlxuICAgICAgICB2YXIgX3F1ZXVlID0gUmVhY3RDdXJyZW50QWN0UXVldWUuY3VycmVudDtcblxuICAgICAgICBpZiAoX3F1ZXVlICE9PSBudWxsKSB7XG4gICAgICAgICAgZmx1c2hBY3RRdWV1ZShfcXVldWUpO1xuICAgICAgICAgIFJlYWN0Q3VycmVudEFjdFF1ZXVlLmN1cnJlbnQgPSBudWxsO1xuICAgICAgICB9IC8vIFJldHVybiBhIHRoZW5hYmxlLiBJZiB0aGUgdXNlciBhd2FpdHMgaXQsIHdlJ2xsIGZsdXNoIGFnYWluIGluXG4gICAgICAgIC8vIGNhc2UgYWRkaXRpb25hbCB3b3JrIHdhcyBzY2hlZHVsZWQgYnkgYSBtaWNyb3Rhc2suXG5cblxuICAgICAgICB2YXIgX3RoZW5hYmxlID0ge1xuICAgICAgICAgIHRoZW46IGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIC8vIENvbmZpcm0gd2UgaGF2ZW4ndCByZS1lbnRlcmVkIGFub3RoZXIgYGFjdGAgc2NvcGUsIGluIGNhc2VcbiAgICAgICAgICAgIC8vIHRoZSB1c2VyIGRvZXMgc29tZXRoaW5nIHdlaXJkIGxpa2UgYXdhaXQgdGhlIHRoZW5hYmxlXG4gICAgICAgICAgICAvLyBtdWx0aXBsZSB0aW1lcy5cbiAgICAgICAgICAgIGlmIChSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGZsdXNoIHRoZSBxdWV1ZSB1bnRpbCB0aGVyZSdzIG5vIHJlbWFpbmluZyB3b3JrLlxuICAgICAgICAgICAgICBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50ID0gW107XG4gICAgICAgICAgICAgIHJlY3Vyc2l2ZWx5Rmx1c2hBc3luY0FjdFdvcmsocmV0dXJuVmFsdWUsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXNvbHZlKHJldHVyblZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBfdGhlbmFibGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBTaW5jZSB3ZSdyZSBpbnNpZGUgYSBuZXN0ZWQgYGFjdGAgc2NvcGUsIHRoZSByZXR1cm5lZCB0aGVuYWJsZVxuICAgICAgICAvLyBpbW1lZGlhdGVseSByZXNvbHZlcy4gVGhlIG91dGVyIHNjb3BlIHdpbGwgZmx1c2ggdGhlIHF1ZXVlLlxuICAgICAgICB2YXIgX3RoZW5hYmxlMiA9IHtcbiAgICAgICAgICB0aGVuOiBmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICByZXNvbHZlKHJldHVyblZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBfdGhlbmFibGUyO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBwb3BBY3RTY29wZShwcmV2QWN0U2NvcGVEZXB0aCkge1xuICB7XG4gICAgaWYgKHByZXZBY3RTY29wZURlcHRoICE9PSBhY3RTY29wZURlcHRoIC0gMSkge1xuICAgICAgZXJyb3IoJ1lvdSBzZWVtIHRvIGhhdmUgb3ZlcmxhcHBpbmcgYWN0KCkgY2FsbHMsIHRoaXMgaXMgbm90IHN1cHBvcnRlZC4gJyArICdCZSBzdXJlIHRvIGF3YWl0IHByZXZpb3VzIGFjdCgpIGNhbGxzIGJlZm9yZSBtYWtpbmcgYSBuZXcgb25lLiAnKTtcbiAgICB9XG5cbiAgICBhY3RTY29wZURlcHRoID0gcHJldkFjdFNjb3BlRGVwdGg7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVjdXJzaXZlbHlGbHVzaEFzeW5jQWN0V29yayhyZXR1cm5WYWx1ZSwgcmVzb2x2ZSwgcmVqZWN0KSB7XG4gIHtcbiAgICB2YXIgcXVldWUgPSBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50O1xuXG4gICAgaWYgKHF1ZXVlICE9PSBudWxsKSB7XG4gICAgICB0cnkge1xuICAgICAgICBmbHVzaEFjdFF1ZXVlKHF1ZXVlKTtcbiAgICAgICAgZW5xdWV1ZVRhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIE5vIGFkZGl0aW9uYWwgd29yayB3YXMgc2NoZWR1bGVkLiBGaW5pc2guXG4gICAgICAgICAgICBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50ID0gbnVsbDtcbiAgICAgICAgICAgIHJlc29sdmUocmV0dXJuVmFsdWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBLZWVwIGZsdXNoaW5nIHdvcmsgdW50aWwgdGhlcmUncyBub25lIGxlZnQuXG4gICAgICAgICAgICByZWN1cnNpdmVseUZsdXNoQXN5bmNBY3RXb3JrKHJldHVyblZhbHVlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXNvbHZlKHJldHVyblZhbHVlKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIGlzRmx1c2hpbmcgPSBmYWxzZTtcblxuZnVuY3Rpb24gZmx1c2hBY3RRdWV1ZShxdWV1ZSkge1xuICB7XG4gICAgaWYgKCFpc0ZsdXNoaW5nKSB7XG4gICAgICAvLyBQcmV2ZW50IHJlLWVudHJhbmNlLlxuICAgICAgaXNGbHVzaGluZyA9IHRydWU7XG4gICAgICB2YXIgaSA9IDA7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGZvciAoOyBpIDwgcXVldWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2YXIgY2FsbGJhY2sgPSBxdWV1ZVtpXTtcblxuICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gY2FsbGJhY2sodHJ1ZSk7XG4gICAgICAgICAgfSB3aGlsZSAoY2FsbGJhY2sgIT09IG51bGwpO1xuICAgICAgICB9XG5cbiAgICAgICAgcXVldWUubGVuZ3RoID0gMDtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIElmIHNvbWV0aGluZyB0aHJvd3MsIGxlYXZlIHRoZSByZW1haW5pbmcgY2FsbGJhY2tzIG9uIHRoZSBxdWV1ZS5cbiAgICAgICAgcXVldWUgPSBxdWV1ZS5zbGljZShpICsgMSk7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaXNGbHVzaGluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG52YXIgY3JlYXRlRWxlbWVudCQxID0gIGNyZWF0ZUVsZW1lbnRXaXRoVmFsaWRhdGlvbiA7XG52YXIgY2xvbmVFbGVtZW50JDEgPSAgY2xvbmVFbGVtZW50V2l0aFZhbGlkYXRpb24gO1xudmFyIGNyZWF0ZUZhY3RvcnkgPSAgY3JlYXRlRmFjdG9yeVdpdGhWYWxpZGF0aW9uIDtcbnZhciBDaGlsZHJlbiA9IHtcbiAgbWFwOiBtYXBDaGlsZHJlbixcbiAgZm9yRWFjaDogZm9yRWFjaENoaWxkcmVuLFxuICBjb3VudDogY291bnRDaGlsZHJlbixcbiAgdG9BcnJheTogdG9BcnJheSxcbiAgb25seTogb25seUNoaWxkXG59O1xuXG5leHBvcnRzLkNoaWxkcmVuID0gQ2hpbGRyZW47XG5leHBvcnRzLkNvbXBvbmVudCA9IENvbXBvbmVudDtcbmV4cG9ydHMuRnJhZ21lbnQgPSBSRUFDVF9GUkFHTUVOVF9UWVBFO1xuZXhwb3J0cy5Qcm9maWxlciA9IFJFQUNUX1BST0ZJTEVSX1RZUEU7XG5leHBvcnRzLlB1cmVDb21wb25lbnQgPSBQdXJlQ29tcG9uZW50O1xuZXhwb3J0cy5TdHJpY3RNb2RlID0gUkVBQ1RfU1RSSUNUX01PREVfVFlQRTtcbmV4cG9ydHMuU3VzcGVuc2UgPSBSRUFDVF9TVVNQRU5TRV9UWVBFO1xuZXhwb3J0cy5fX1NFQ1JFVF9JTlRFUk5BTFNfRE9fTk9UX1VTRV9PUl9ZT1VfV0lMTF9CRV9GSVJFRCA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzO1xuZXhwb3J0cy5jbG9uZUVsZW1lbnQgPSBjbG9uZUVsZW1lbnQkMTtcbmV4cG9ydHMuY3JlYXRlQ29udGV4dCA9IGNyZWF0ZUNvbnRleHQ7XG5leHBvcnRzLmNyZWF0ZUVsZW1lbnQgPSBjcmVhdGVFbGVtZW50JDE7XG5leHBvcnRzLmNyZWF0ZUZhY3RvcnkgPSBjcmVhdGVGYWN0b3J5O1xuZXhwb3J0cy5jcmVhdGVSZWYgPSBjcmVhdGVSZWY7XG5leHBvcnRzLmZvcndhcmRSZWYgPSBmb3J3YXJkUmVmO1xuZXhwb3J0cy5pc1ZhbGlkRWxlbWVudCA9IGlzVmFsaWRFbGVtZW50O1xuZXhwb3J0cy5sYXp5ID0gbGF6eTtcbmV4cG9ydHMubWVtbyA9IG1lbW87XG5leHBvcnRzLnN0YXJ0VHJhbnNpdGlvbiA9IHN0YXJ0VHJhbnNpdGlvbjtcbmV4cG9ydHMudW5zdGFibGVfYWN0ID0gYWN0O1xuZXhwb3J0cy51c2VDYWxsYmFjayA9IHVzZUNhbGxiYWNrO1xuZXhwb3J0cy51c2VDb250ZXh0ID0gdXNlQ29udGV4dDtcbmV4cG9ydHMudXNlRGVidWdWYWx1ZSA9IHVzZURlYnVnVmFsdWU7XG5leHBvcnRzLnVzZURlZmVycmVkVmFsdWUgPSB1c2VEZWZlcnJlZFZhbHVlO1xuZXhwb3J0cy51c2VFZmZlY3QgPSB1c2VFZmZlY3Q7XG5leHBvcnRzLnVzZUlkID0gdXNlSWQ7XG5leHBvcnRzLnVzZUltcGVyYXRpdmVIYW5kbGUgPSB1c2VJbXBlcmF0aXZlSGFuZGxlO1xuZXhwb3J0cy51c2VJbnNlcnRpb25FZmZlY3QgPSB1c2VJbnNlcnRpb25FZmZlY3Q7XG5leHBvcnRzLnVzZUxheW91dEVmZmVjdCA9IHVzZUxheW91dEVmZmVjdDtcbmV4cG9ydHMudXNlTWVtbyA9IHVzZU1lbW87XG5leHBvcnRzLnVzZVJlZHVjZXIgPSB1c2VSZWR1Y2VyO1xuZXhwb3J0cy51c2VSZWYgPSB1c2VSZWY7XG5leHBvcnRzLnVzZVN0YXRlID0gdXNlU3RhdGU7XG5leHBvcnRzLnVzZVN5bmNFeHRlcm5hbFN0b3JlID0gdXNlU3luY0V4dGVybmFsU3RvcmU7XG5leHBvcnRzLnVzZVRyYW5zaXRpb24gPSB1c2VUcmFuc2l0aW9uO1xuZXhwb3J0cy52ZXJzaW9uID0gUmVhY3RWZXJzaW9uO1xuICAgICAgICAgIC8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbmlmIChcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RvcCA9PT1cbiAgICAnZnVuY3Rpb24nXG4pIHtcbiAgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fLnJlZ2lzdGVySW50ZXJuYWxNb2R1bGVTdG9wKG5ldyBFcnJvcigpKTtcbn1cbiAgICAgICAgXG4gIH0pKCk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBtID0gcmVxdWlyZSgncmVhY3QtZG9tJyk7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykge1xuICBleHBvcnRzLmNyZWF0ZVJvb3QgPSBtLmNyZWF0ZVJvb3Q7XG4gIGV4cG9ydHMuaHlkcmF0ZVJvb3QgPSBtLmh5ZHJhdGVSb290O1xufSBlbHNlIHtcbiAgdmFyIGkgPSBtLl9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVEO1xuICBleHBvcnRzLmNyZWF0ZVJvb3QgPSBmdW5jdGlvbihjLCBvKSB7XG4gICAgaS51c2luZ0NsaWVudEVudHJ5UG9pbnQgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gbS5jcmVhdGVSb290KGMsIG8pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IGZhbHNlO1xuICAgIH1cbiAgfTtcbiAgZXhwb3J0cy5oeWRyYXRlUm9vdCA9IGZ1bmN0aW9uKGMsIGgsIG8pIHtcbiAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBtLmh5ZHJhdGVSb290KGMsIGgsIG8pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IGZhbHNlO1xuICAgIH1cbiAgfTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gY2hlY2tEQ0UoKSB7XG4gIC8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbiAgaWYgKFxuICAgIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gPT09ICd1bmRlZmluZWQnIHx8XG4gICAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5jaGVja0RDRSAhPT0gJ2Z1bmN0aW9uJ1xuICApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAvLyBUaGlzIGJyYW5jaCBpcyB1bnJlYWNoYWJsZSBiZWNhdXNlIHRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWRcbiAgICAvLyBpbiBwcm9kdWN0aW9uLCBidXQgdGhlIGNvbmRpdGlvbiBpcyB0cnVlIG9ubHkgaW4gZGV2ZWxvcG1lbnQuXG4gICAgLy8gVGhlcmVmb3JlIGlmIHRoZSBicmFuY2ggaXMgc3RpbGwgaGVyZSwgZGVhZCBjb2RlIGVsaW1pbmF0aW9uIHdhc24ndFxuICAgIC8vIHByb3Blcmx5IGFwcGxpZWQuXG4gICAgLy8gRG9uJ3QgY2hhbmdlIHRoZSBtZXNzYWdlLiBSZWFjdCBEZXZUb29scyByZWxpZXMgb24gaXQuIEFsc28gbWFrZSBzdXJlXG4gICAgLy8gdGhpcyBtZXNzYWdlIGRvZXNuJ3Qgb2NjdXIgZWxzZXdoZXJlIGluIHRoaXMgZnVuY3Rpb24sIG9yIGl0IHdpbGwgY2F1c2VcbiAgICAvLyBhIGZhbHNlIHBvc2l0aXZlLlxuICAgIHRocm93IG5ldyBFcnJvcignXl9eJyk7XG4gIH1cbiAgdHJ5IHtcbiAgICAvLyBWZXJpZnkgdGhhdCB0aGUgY29kZSBhYm92ZSBoYXMgYmVlbiBkZWFkIGNvZGUgZWxpbWluYXRlZCAoRENFJ2QpLlxuICAgIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5jaGVja0RDRShjaGVja0RDRSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIC8vIERldlRvb2xzIHNob3VsZG4ndCBjcmFzaCBSZWFjdCwgbm8gbWF0dGVyIHdoYXQuXG4gICAgLy8gV2Ugc2hvdWxkIHN0aWxsIHJlcG9ydCBpbiBjYXNlIHdlIGJyZWFrIHRoaXMgY29kZS5cbiAgICBjb25zb2xlLmVycm9yKGVycik7XG4gIH1cbn1cblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHtcbiAgLy8gRENFIGNoZWNrIHNob3VsZCBoYXBwZW4gYmVmb3JlIFJlYWN0RE9NIGJ1bmRsZSBleGVjdXRlcyBzbyB0aGF0XG4gIC8vIERldlRvb2xzIGNhbiByZXBvcnQgYmFkIG1pbmlmaWNhdGlvbiBkdXJpbmcgaW5qZWN0aW9uLlxuICBjaGVja0RDRSgpO1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vY2pzL3JlYWN0LWRvbS5wcm9kdWN0aW9uLm1pbi5qcycpO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC1kb20uZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiIsIi8qKlxuICogQGxpY2Vuc2UgUmVhY3RcbiAqIHJlYWN0LWRvbS5kZXZlbG9wbWVudC5qc1xuICpcbiAqIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgICAndXNlIHN0cmljdCc7XG5cbi8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbmlmIChcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RhcnQgPT09XG4gICAgJ2Z1bmN0aW9uJ1xuKSB7XG4gIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RhcnQobmV3IEVycm9yKCkpO1xufVxuICAgICAgICAgIHZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG52YXIgU2NoZWR1bGVyID0gcmVxdWlyZSgnc2NoZWR1bGVyJyk7XG5cbnZhciBSZWFjdFNoYXJlZEludGVybmFscyA9IFJlYWN0Ll9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVEO1xuXG52YXIgc3VwcHJlc3NXYXJuaW5nID0gZmFsc2U7XG5mdW5jdGlvbiBzZXRTdXBwcmVzc1dhcm5pbmcobmV3U3VwcHJlc3NXYXJuaW5nKSB7XG4gIHtcbiAgICBzdXBwcmVzc1dhcm5pbmcgPSBuZXdTdXBwcmVzc1dhcm5pbmc7XG4gIH1cbn0gLy8gSW4gREVWLCBjYWxscyB0byBjb25zb2xlLndhcm4gYW5kIGNvbnNvbGUuZXJyb3IgZ2V0IHJlcGxhY2VkXG4vLyBieSBjYWxscyB0byB0aGVzZSBtZXRob2RzIGJ5IGEgQmFiZWwgcGx1Z2luLlxuLy9cbi8vIEluIFBST0QgKG9yIGluIHBhY2thZ2VzIHdpdGhvdXQgYWNjZXNzIHRvIFJlYWN0IGludGVybmFscyksXG4vLyB0aGV5IGFyZSBsZWZ0IGFzIHRoZXkgYXJlIGluc3RlYWQuXG5cbmZ1bmN0aW9uIHdhcm4oZm9ybWF0KSB7XG4gIHtcbiAgICBpZiAoIXN1cHByZXNzV2FybmluZykge1xuICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiA+IDEgPyBfbGVuIC0gMSA6IDApLCBfa2V5ID0gMTsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgICBhcmdzW19rZXkgLSAxXSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICAgIH1cblxuICAgICAgcHJpbnRXYXJuaW5nKCd3YXJuJywgZm9ybWF0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGVycm9yKGZvcm1hdCkge1xuICB7XG4gICAgaWYgKCFzdXBwcmVzc1dhcm5pbmcpIHtcbiAgICAgIGZvciAodmFyIF9sZW4yID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuMiA+IDEgPyBfbGVuMiAtIDEgOiAwKSwgX2tleTIgPSAxOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgICAgIGFyZ3NbX2tleTIgLSAxXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gICAgICB9XG5cbiAgICAgIHByaW50V2FybmluZygnZXJyb3InLCBmb3JtYXQsIGFyZ3MpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBwcmludFdhcm5pbmcobGV2ZWwsIGZvcm1hdCwgYXJncykge1xuICAvLyBXaGVuIGNoYW5naW5nIHRoaXMgbG9naWMsIHlvdSBtaWdodCB3YW50IHRvIGFsc29cbiAgLy8gdXBkYXRlIGNvbnNvbGVXaXRoU3RhY2tEZXYud3d3LmpzIGFzIHdlbGwuXG4gIHtcbiAgICB2YXIgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0RGVidWdDdXJyZW50RnJhbWU7XG4gICAgdmFyIHN0YWNrID0gUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZS5nZXRTdGFja0FkZGVuZHVtKCk7XG5cbiAgICBpZiAoc3RhY2sgIT09ICcnKSB7XG4gICAgICBmb3JtYXQgKz0gJyVzJztcbiAgICAgIGFyZ3MgPSBhcmdzLmNvbmNhdChbc3RhY2tdKTtcbiAgICB9IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuXG5cbiAgICB2YXIgYXJnc1dpdGhGb3JtYXQgPSBhcmdzLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgcmV0dXJuIFN0cmluZyhpdGVtKTtcbiAgICB9KTsgLy8gQ2FyZWZ1bDogUk4gY3VycmVudGx5IGRlcGVuZHMgb24gdGhpcyBwcmVmaXhcblxuICAgIGFyZ3NXaXRoRm9ybWF0LnVuc2hpZnQoJ1dhcm5pbmc6ICcgKyBmb3JtYXQpOyAvLyBXZSBpbnRlbnRpb25hbGx5IGRvbid0IHVzZSBzcHJlYWQgKG9yIC5hcHBseSkgZGlyZWN0bHkgYmVjYXVzZSBpdFxuICAgIC8vIGJyZWFrcyBJRTk6IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTM2MTBcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nXG5cbiAgICBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbChjb25zb2xlW2xldmVsXSwgY29uc29sZSwgYXJnc1dpdGhGb3JtYXQpO1xuICB9XG59XG5cbnZhciBGdW5jdGlvbkNvbXBvbmVudCA9IDA7XG52YXIgQ2xhc3NDb21wb25lbnQgPSAxO1xudmFyIEluZGV0ZXJtaW5hdGVDb21wb25lbnQgPSAyOyAvLyBCZWZvcmUgd2Uga25vdyB3aGV0aGVyIGl0IGlzIGZ1bmN0aW9uIG9yIGNsYXNzXG5cbnZhciBIb3N0Um9vdCA9IDM7IC8vIFJvb3Qgb2YgYSBob3N0IHRyZWUuIENvdWxkIGJlIG5lc3RlZCBpbnNpZGUgYW5vdGhlciBub2RlLlxuXG52YXIgSG9zdFBvcnRhbCA9IDQ7IC8vIEEgc3VidHJlZS4gQ291bGQgYmUgYW4gZW50cnkgcG9pbnQgdG8gYSBkaWZmZXJlbnQgcmVuZGVyZXIuXG5cbnZhciBIb3N0Q29tcG9uZW50ID0gNTtcbnZhciBIb3N0VGV4dCA9IDY7XG52YXIgRnJhZ21lbnQgPSA3O1xudmFyIE1vZGUgPSA4O1xudmFyIENvbnRleHRDb25zdW1lciA9IDk7XG52YXIgQ29udGV4dFByb3ZpZGVyID0gMTA7XG52YXIgRm9yd2FyZFJlZiA9IDExO1xudmFyIFByb2ZpbGVyID0gMTI7XG52YXIgU3VzcGVuc2VDb21wb25lbnQgPSAxMztcbnZhciBNZW1vQ29tcG9uZW50ID0gMTQ7XG52YXIgU2ltcGxlTWVtb0NvbXBvbmVudCA9IDE1O1xudmFyIExhenlDb21wb25lbnQgPSAxNjtcbnZhciBJbmNvbXBsZXRlQ2xhc3NDb21wb25lbnQgPSAxNztcbnZhciBEZWh5ZHJhdGVkRnJhZ21lbnQgPSAxODtcbnZhciBTdXNwZW5zZUxpc3RDb21wb25lbnQgPSAxOTtcbnZhciBTY29wZUNvbXBvbmVudCA9IDIxO1xudmFyIE9mZnNjcmVlbkNvbXBvbmVudCA9IDIyO1xudmFyIExlZ2FjeUhpZGRlbkNvbXBvbmVudCA9IDIzO1xudmFyIENhY2hlQ29tcG9uZW50ID0gMjQ7XG52YXIgVHJhY2luZ01hcmtlckNvbXBvbmVudCA9IDI1O1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG52YXIgZW5hYmxlQ2xpZW50UmVuZGVyRmFsbGJhY2tPblRleHRNaXNtYXRjaCA9IHRydWU7IC8vIFRPRE86IE5lZWQgdG8gcmV2aWV3IHRoaXMgY29kZSBvbmUgbW9yZSB0aW1lIGJlZm9yZSBsYW5kaW5nXG4vLyB0aGUgcmVhY3QtcmVjb25jaWxlciBwYWNrYWdlLlxuXG52YXIgZW5hYmxlTmV3UmVjb25jaWxlciA9IGZhbHNlOyAvLyBTdXBwb3J0IGxlZ2FjeSBQcmltZXIgc3VwcG9ydCBvbiBpbnRlcm5hbCBGQiB3d3dcblxudmFyIGVuYWJsZUxhenlDb250ZXh0UHJvcGFnYXRpb24gPSBmYWxzZTsgLy8gRkItb25seSB1c2FnZS4gVGhlIG5ldyBBUEkgaGFzIGRpZmZlcmVudCBzZW1hbnRpY3MuXG5cbnZhciBlbmFibGVMZWdhY3lIaWRkZW4gPSBmYWxzZTsgLy8gRW5hYmxlcyB1bnN0YWJsZV9hdm9pZFRoaXNGYWxsYmFjayBmZWF0dXJlIGluIEZpYmVyXG5cbnZhciBlbmFibGVTdXNwZW5zZUF2b2lkVGhpc0ZhbGxiYWNrID0gZmFsc2U7IC8vIEVuYWJsZXMgdW5zdGFibGVfYXZvaWRUaGlzRmFsbGJhY2sgZmVhdHVyZSBpbiBGaXp6XG4vLyBSZWFjdCBET00gQ2hvcHBpbmcgQmxvY2tcbi8vXG4vLyBTaW1pbGFyIHRvIG1haW4gQ2hvcHBpbmcgQmxvY2sgYnV0IG9ubHkgZmxhZ3MgcmVsYXRlZCB0byBSZWFjdCBET00uIFRoZXNlIGFyZVxuLy8gZ3JvdXBlZCBiZWNhdXNlIHdlIHdpbGwgbGlrZWx5IGJhdGNoIGFsbCBvZiB0aGVtIGludG8gYSBzaW5nbGUgbWFqb3IgcmVsZWFzZS5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBEaXNhYmxlIHN1cHBvcnQgZm9yIGNvbW1lbnQgbm9kZXMgYXMgUmVhY3QgRE9NIGNvbnRhaW5lcnMuIEFscmVhZHkgZGlzYWJsZWRcbi8vIGluIG9wZW4gc291cmNlLCBidXQgd3d3IGNvZGViYXNlIHN0aWxsIHJlbGllcyBvbiBpdC4gTmVlZCB0byByZW1vdmUuXG5cbnZhciBkaXNhYmxlQ29tbWVudHNBc0RPTUNvbnRhaW5lcnMgPSB0cnVlOyAvLyBEaXNhYmxlIGphdmFzY3JpcHQ6IFVSTCBzdHJpbmdzIGluIGhyZWYgZm9yIFhTUyBwcm90ZWN0aW9uLlxuLy8gYW5kIGNsaWVudCByZW5kZXJpbmcsIG1vc3RseSB0byBhbGxvdyBKU1ggYXR0cmlidXRlcyB0byBhcHBseSB0byB0aGUgY3VzdG9tXG4vLyBlbGVtZW50J3Mgb2JqZWN0IHByb3BlcnRpZXMgaW5zdGVhZCBvZiBvbmx5IEhUTUwgYXR0cmlidXRlcy5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTEzNDdcblxudmFyIGVuYWJsZUN1c3RvbUVsZW1lbnRQcm9wZXJ0eVN1cHBvcnQgPSBmYWxzZTsgLy8gRGlzYWJsZXMgY2hpbGRyZW4gZm9yIDx0ZXh0YXJlYT4gZWxlbWVudHNcbnZhciB3YXJuQWJvdXRTdHJpbmdSZWZzID0gZmFsc2U7IC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBEZWJ1Z2dpbmcgYW5kIERldlRvb2xzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gQWRkcyB1c2VyIHRpbWluZyBtYXJrcyBmb3IgZS5nLiBzdGF0ZSB1cGRhdGVzLCBzdXNwZW5zZSwgYW5kIHdvcmsgbG9vcCBzdHVmZixcbi8vIGZvciBhbiBleHBlcmltZW50YWwgdGltZWxpbmUgdG9vbC5cblxudmFyIGVuYWJsZVNjaGVkdWxpbmdQcm9maWxlciA9IHRydWU7IC8vIEhlbHBzIGlkZW50aWZ5IHNpZGUgZWZmZWN0cyBpbiByZW5kZXItcGhhc2UgbGlmZWN5Y2xlIGhvb2tzIGFuZCBzZXRTdGF0ZVxuXG52YXIgZW5hYmxlUHJvZmlsZXJUaW1lciA9IHRydWU7IC8vIFJlY29yZCBkdXJhdGlvbnMgZm9yIGNvbW1pdCBhbmQgcGFzc2l2ZSBlZmZlY3RzIHBoYXNlcy5cblxudmFyIGVuYWJsZVByb2ZpbGVyQ29tbWl0SG9va3MgPSB0cnVlOyAvLyBQaGFzZSBwYXJhbSBwYXNzZWQgdG8gb25SZW5kZXIgY2FsbGJhY2sgZGlmZmVyZW50aWF0ZXMgYmV0d2VlbiBhbiBcInVwZGF0ZVwiIGFuZCBhIFwiY2FzY2FkaW5nLXVwZGF0ZVwiLlxuXG52YXIgYWxsTmF0aXZlRXZlbnRzID0gbmV3IFNldCgpO1xuLyoqXG4gKiBNYXBwaW5nIGZyb20gcmVnaXN0cmF0aW9uIG5hbWUgdG8gZXZlbnQgbmFtZVxuICovXG5cblxudmFyIHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMgPSB7fTtcbi8qKlxuICogTWFwcGluZyBmcm9tIGxvd2VyY2FzZSByZWdpc3RyYXRpb24gbmFtZXMgdG8gdGhlIHByb3Blcmx5IGNhc2VkIHZlcnNpb24sXG4gKiB1c2VkIHRvIHdhcm4gaW4gdGhlIGNhc2Ugb2YgbWlzc2luZyBldmVudCBoYW5kbGVycy4gQXZhaWxhYmxlXG4gKiBvbmx5IGluIHRydWUuXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG5cbnZhciBwb3NzaWJsZVJlZ2lzdHJhdGlvbk5hbWVzID0gIHt9IDsgLy8gVHJ1c3QgdGhlIGRldmVsb3BlciB0byBvbmx5IHVzZSBwb3NzaWJsZVJlZ2lzdHJhdGlvbk5hbWVzIGluIHRydWVcblxuZnVuY3Rpb24gcmVnaXN0ZXJUd29QaGFzZUV2ZW50KHJlZ2lzdHJhdGlvbk5hbWUsIGRlcGVuZGVuY2llcykge1xuICByZWdpc3RlckRpcmVjdEV2ZW50KHJlZ2lzdHJhdGlvbk5hbWUsIGRlcGVuZGVuY2llcyk7XG4gIHJlZ2lzdGVyRGlyZWN0RXZlbnQocmVnaXN0cmF0aW9uTmFtZSArICdDYXB0dXJlJywgZGVwZW5kZW5jaWVzKTtcbn1cbmZ1bmN0aW9uIHJlZ2lzdGVyRGlyZWN0RXZlbnQocmVnaXN0cmF0aW9uTmFtZSwgZGVwZW5kZW5jaWVzKSB7XG4gIHtcbiAgICBpZiAocmVnaXN0cmF0aW9uTmFtZURlcGVuZGVuY2llc1tyZWdpc3RyYXRpb25OYW1lXSkge1xuICAgICAgZXJyb3IoJ0V2ZW50UmVnaXN0cnk6IE1vcmUgdGhhbiBvbmUgcGx1Z2luIGF0dGVtcHRlZCB0byBwdWJsaXNoIHRoZSBzYW1lICcgKyAncmVnaXN0cmF0aW9uIG5hbWUsIGAlc2AuJywgcmVnaXN0cmF0aW9uTmFtZSk7XG4gICAgfVxuICB9XG5cbiAgcmVnaXN0cmF0aW9uTmFtZURlcGVuZGVuY2llc1tyZWdpc3RyYXRpb25OYW1lXSA9IGRlcGVuZGVuY2llcztcblxuICB7XG4gICAgdmFyIGxvd2VyQ2FzZWROYW1lID0gcmVnaXN0cmF0aW9uTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIHBvc3NpYmxlUmVnaXN0cmF0aW9uTmFtZXNbbG93ZXJDYXNlZE5hbWVdID0gcmVnaXN0cmF0aW9uTmFtZTtcblxuICAgIGlmIChyZWdpc3RyYXRpb25OYW1lID09PSAnb25Eb3VibGVDbGljaycpIHtcbiAgICAgIHBvc3NpYmxlUmVnaXN0cmF0aW9uTmFtZXMub25kYmxjbGljayA9IHJlZ2lzdHJhdGlvbk5hbWU7XG4gICAgfVxuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBkZXBlbmRlbmNpZXMubGVuZ3RoOyBpKyspIHtcbiAgICBhbGxOYXRpdmVFdmVudHMuYWRkKGRlcGVuZGVuY2llc1tpXSk7XG4gIH1cbn1cblxudmFyIGNhblVzZURPTSA9ICEhKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiB3aW5kb3cuZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCAhPT0gJ3VuZGVmaW5lZCcpO1xuXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4vKlxuICogVGhlIGAnJyArIHZhbHVlYCBwYXR0ZXJuICh1c2VkIGluIGluIHBlcmYtc2Vuc2l0aXZlIGNvZGUpIHRocm93cyBmb3IgU3ltYm9sXG4gKiBhbmQgVGVtcG9yYWwuKiB0eXBlcy4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzIyMDY0LlxuICpcbiAqIFRoZSBmdW5jdGlvbnMgaW4gdGhpcyBtb2R1bGUgd2lsbCB0aHJvdyBhbiBlYXNpZXItdG8tdW5kZXJzdGFuZCxcbiAqIGVhc2llci10by1kZWJ1ZyBleGNlcHRpb24gd2l0aCBhIGNsZWFyIGVycm9ycyBtZXNzYWdlIG1lc3NhZ2UgZXhwbGFpbmluZyB0aGVcbiAqIHByb2JsZW0uIChJbnN0ZWFkIG9mIGEgY29uZnVzaW5nIGV4Y2VwdGlvbiB0aHJvd24gaW5zaWRlIHRoZSBpbXBsZW1lbnRhdGlvblxuICogb2YgdGhlIGB2YWx1ZWAgb2JqZWN0KS5cbiAqL1xuLy8gJEZsb3dGaXhNZSBvbmx5IGNhbGxlZCBpbiBERVYsIHNvIHZvaWQgcmV0dXJuIGlzIG5vdCBwb3NzaWJsZS5cbmZ1bmN0aW9uIHR5cGVOYW1lKHZhbHVlKSB7XG4gIHtcbiAgICAvLyB0b1N0cmluZ1RhZyBpcyBuZWVkZWQgZm9yIG5hbWVzcGFjZWQgdHlwZXMgbGlrZSBUZW1wb3JhbC5JbnN0YW50XG4gICAgdmFyIGhhc1RvU3RyaW5nVGFnID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wudG9TdHJpbmdUYWc7XG4gICAgdmFyIHR5cGUgPSBoYXNUb1N0cmluZ1RhZyAmJiB2YWx1ZVtTeW1ib2wudG9TdHJpbmdUYWddIHx8IHZhbHVlLmNvbnN0cnVjdG9yLm5hbWUgfHwgJ09iamVjdCc7XG4gICAgcmV0dXJuIHR5cGU7XG4gIH1cbn0gLy8gJEZsb3dGaXhNZSBvbmx5IGNhbGxlZCBpbiBERVYsIHNvIHZvaWQgcmV0dXJuIGlzIG5vdCBwb3NzaWJsZS5cblxuXG5mdW5jdGlvbiB3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkge1xuICB7XG4gICAgdHJ5IHtcbiAgICAgIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSkge1xuICAvLyBJZiB5b3UgZW5kZWQgdXAgaGVyZSBieSBmb2xsb3dpbmcgYW4gZXhjZXB0aW9uIGNhbGwgc3RhY2ssIGhlcmUncyB3aGF0J3NcbiAgLy8gaGFwcGVuZWQ6IHlvdSBzdXBwbGllZCBhbiBvYmplY3Qgb3Igc3ltYm9sIHZhbHVlIHRvIFJlYWN0IChhcyBhIHByb3AsIGtleSxcbiAgLy8gRE9NIGF0dHJpYnV0ZSwgQ1NTIHByb3BlcnR5LCBzdHJpbmcgcmVmLCBldGMuKSBhbmQgd2hlbiBSZWFjdCB0cmllZCB0b1xuICAvLyBjb2VyY2UgaXQgdG8gYSBzdHJpbmcgdXNpbmcgYCcnICsgdmFsdWVgLCBhbiBleGNlcHRpb24gd2FzIHRocm93bi5cbiAgLy9cbiAgLy8gVGhlIG1vc3QgY29tbW9uIHR5cGVzIHRoYXQgd2lsbCBjYXVzZSB0aGlzIGV4Y2VwdGlvbiBhcmUgYFN5bWJvbGAgaW5zdGFuY2VzXG4gIC8vIGFuZCBUZW1wb3JhbCBvYmplY3RzIGxpa2UgYFRlbXBvcmFsLkluc3RhbnRgLiBCdXQgYW55IG9iamVjdCB0aGF0IGhhcyBhXG4gIC8vIGB2YWx1ZU9mYCBvciBgW1N5bWJvbC50b1ByaW1pdGl2ZV1gIG1ldGhvZCB0aGF0IHRocm93cyB3aWxsIGFsc28gY2F1c2UgdGhpc1xuICAvLyBleGNlcHRpb24uIChMaWJyYXJ5IGF1dGhvcnMgZG8gdGhpcyB0byBwcmV2ZW50IHVzZXJzIGZyb20gdXNpbmcgYnVpbHQtaW5cbiAgLy8gbnVtZXJpYyBvcGVyYXRvcnMgbGlrZSBgK2Agb3IgY29tcGFyaXNvbiBvcGVyYXRvcnMgbGlrZSBgPj1gIGJlY2F1c2UgY3VzdG9tXG4gIC8vIG1ldGhvZHMgYXJlIG5lZWRlZCB0byBwZXJmb3JtIGFjY3VyYXRlIGFyaXRobWV0aWMgb3IgY29tcGFyaXNvbi4pXG4gIC8vXG4gIC8vIFRvIGZpeCB0aGUgcHJvYmxlbSwgY29lcmNlIHRoaXMgb2JqZWN0IG9yIHN5bWJvbCB2YWx1ZSB0byBhIHN0cmluZyBiZWZvcmVcbiAgLy8gcGFzc2luZyBpdCB0byBSZWFjdC4gVGhlIG1vc3QgcmVsaWFibGUgd2F5IGlzIHVzdWFsbHkgYFN0cmluZyh2YWx1ZSlgLlxuICAvL1xuICAvLyBUbyBmaW5kIHdoaWNoIHZhbHVlIGlzIHRocm93aW5nLCBjaGVjayB0aGUgYnJvd3NlciBvciBkZWJ1Z2dlciBjb25zb2xlLlxuICAvLyBCZWZvcmUgdGhpcyBleGNlcHRpb24gd2FzIHRocm93biwgdGhlcmUgc2hvdWxkIGJlIGBjb25zb2xlLmVycm9yYCBvdXRwdXRcbiAgLy8gdGhhdCBzaG93cyB0aGUgdHlwZSAoU3ltYm9sLCBUZW1wb3JhbC5QbGFpbkRhdGUsIGV0Yy4pIHRoYXQgY2F1c2VkIHRoZVxuICAvLyBwcm9ibGVtIGFuZCBob3cgdGhhdCB0eXBlIHdhcyB1c2VkOiBrZXksIGF0cnJpYnV0ZSwgaW5wdXQgdmFsdWUgcHJvcCwgZXRjLlxuICAvLyBJbiBtb3N0IGNhc2VzLCB0aGlzIGNvbnNvbGUgb3V0cHV0IGFsc28gc2hvd3MgdGhlIGNvbXBvbmVudCBhbmQgaXRzXG4gIC8vIGFuY2VzdG9yIGNvbXBvbmVudHMgd2hlcmUgdGhlIGV4Y2VwdGlvbiBoYXBwZW5lZC5cbiAgLy9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3NhZmUtc3RyaW5nLWNvZXJjaW9uXG4gIHJldHVybiAnJyArIHZhbHVlO1xufVxuXG5mdW5jdGlvbiBjaGVja0F0dHJpYnV0ZVN0cmluZ0NvZXJjaW9uKHZhbHVlLCBhdHRyaWJ1dGVOYW1lKSB7XG4gIHtcbiAgICBpZiAod2lsbENvZXJjaW9uVGhyb3codmFsdWUpKSB7XG4gICAgICBlcnJvcignVGhlIHByb3ZpZGVkIGAlc2AgYXR0cmlidXRlIGlzIGFuIHVuc3VwcG9ydGVkIHR5cGUgJXMuJyArICcgVGhpcyB2YWx1ZSBtdXN0IGJlIGNvZXJjZWQgdG8gYSBzdHJpbmcgYmVmb3JlIGJlZm9yZSB1c2luZyBpdCBoZXJlLicsIGF0dHJpYnV0ZU5hbWUsIHR5cGVOYW1lKHZhbHVlKSk7XG5cbiAgICAgIHJldHVybiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpOyAvLyB0aHJvdyAodG8gaGVscCBjYWxsZXJzIGZpbmQgdHJvdWJsZXNob290aW5nIGNvbW1lbnRzKVxuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gY2hlY2tLZXlTdHJpbmdDb2VyY2lvbih2YWx1ZSkge1xuICB7XG4gICAgaWYgKHdpbGxDb2VyY2lvblRocm93KHZhbHVlKSkge1xuICAgICAgZXJyb3IoJ1RoZSBwcm92aWRlZCBrZXkgaXMgYW4gdW5zdXBwb3J0ZWQgdHlwZSAlcy4nICsgJyBUaGlzIHZhbHVlIG11c3QgYmUgY29lcmNlZCB0byBhIHN0cmluZyBiZWZvcmUgYmVmb3JlIHVzaW5nIGl0IGhlcmUuJywgdHlwZU5hbWUodmFsdWUpKTtcblxuICAgICAgcmV0dXJuIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSk7IC8vIHRocm93ICh0byBoZWxwIGNhbGxlcnMgZmluZCB0cm91Ymxlc2hvb3RpbmcgY29tbWVudHMpXG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBjaGVja1Byb3BTdHJpbmdDb2VyY2lvbih2YWx1ZSwgcHJvcE5hbWUpIHtcbiAge1xuICAgIGlmICh3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkpIHtcbiAgICAgIGVycm9yKCdUaGUgcHJvdmlkZWQgYCVzYCBwcm9wIGlzIGFuIHVuc3VwcG9ydGVkIHR5cGUgJXMuJyArICcgVGhpcyB2YWx1ZSBtdXN0IGJlIGNvZXJjZWQgdG8gYSBzdHJpbmcgYmVmb3JlIGJlZm9yZSB1c2luZyBpdCBoZXJlLicsIHByb3BOYW1lLCB0eXBlTmFtZSh2YWx1ZSkpO1xuXG4gICAgICByZXR1cm4gdGVzdFN0cmluZ0NvZXJjaW9uKHZhbHVlKTsgLy8gdGhyb3cgKHRvIGhlbHAgY2FsbGVycyBmaW5kIHRyb3VibGVzaG9vdGluZyBjb21tZW50cylcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGNoZWNrQ1NTUHJvcGVydHlTdHJpbmdDb2VyY2lvbih2YWx1ZSwgcHJvcE5hbWUpIHtcbiAge1xuICAgIGlmICh3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkpIHtcbiAgICAgIGVycm9yKCdUaGUgcHJvdmlkZWQgYCVzYCBDU1MgcHJvcGVydHkgaXMgYW4gdW5zdXBwb3J0ZWQgdHlwZSAlcy4nICsgJyBUaGlzIHZhbHVlIG11c3QgYmUgY29lcmNlZCB0byBhIHN0cmluZyBiZWZvcmUgYmVmb3JlIHVzaW5nIGl0IGhlcmUuJywgcHJvcE5hbWUsIHR5cGVOYW1lKHZhbHVlKSk7XG5cbiAgICAgIHJldHVybiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpOyAvLyB0aHJvdyAodG8gaGVscCBjYWxsZXJzIGZpbmQgdHJvdWJsZXNob290aW5nIGNvbW1lbnRzKVxuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gY2hlY2tIdG1sU3RyaW5nQ29lcmNpb24odmFsdWUpIHtcbiAge1xuICAgIGlmICh3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkpIHtcbiAgICAgIGVycm9yKCdUaGUgcHJvdmlkZWQgSFRNTCBtYXJrdXAgdXNlcyBhIHZhbHVlIG9mIHVuc3VwcG9ydGVkIHR5cGUgJXMuJyArICcgVGhpcyB2YWx1ZSBtdXN0IGJlIGNvZXJjZWQgdG8gYSBzdHJpbmcgYmVmb3JlIGJlZm9yZSB1c2luZyBpdCBoZXJlLicsIHR5cGVOYW1lKHZhbHVlKSk7XG5cbiAgICAgIHJldHVybiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpOyAvLyB0aHJvdyAodG8gaGVscCBjYWxsZXJzIGZpbmQgdHJvdWJsZXNob290aW5nIGNvbW1lbnRzKVxuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gY2hlY2tGb3JtRmllbGRWYWx1ZVN0cmluZ0NvZXJjaW9uKHZhbHVlKSB7XG4gIHtcbiAgICBpZiAod2lsbENvZXJjaW9uVGhyb3codmFsdWUpKSB7XG4gICAgICBlcnJvcignRm9ybSBmaWVsZCB2YWx1ZXMgKHZhbHVlLCBjaGVja2VkLCBkZWZhdWx0VmFsdWUsIG9yIGRlZmF1bHRDaGVja2VkIHByb3BzKScgKyAnIG11c3QgYmUgc3RyaW5ncywgbm90ICVzLicgKyAnIFRoaXMgdmFsdWUgbXVzdCBiZSBjb2VyY2VkIHRvIGEgc3RyaW5nIGJlZm9yZSBiZWZvcmUgdXNpbmcgaXQgaGVyZS4nLCB0eXBlTmFtZSh2YWx1ZSkpO1xuXG4gICAgICByZXR1cm4gdGVzdFN0cmluZ0NvZXJjaW9uKHZhbHVlKTsgLy8gdGhyb3cgKHRvIGhlbHAgY2FsbGVycyBmaW5kIHRyb3VibGVzaG9vdGluZyBjb21tZW50cylcbiAgICB9XG4gIH1cbn1cblxuLy8gQSByZXNlcnZlZCBhdHRyaWJ1dGUuXG4vLyBJdCBpcyBoYW5kbGVkIGJ5IFJlYWN0IHNlcGFyYXRlbHkgYW5kIHNob3VsZG4ndCBiZSB3cml0dGVuIHRvIHRoZSBET00uXG52YXIgUkVTRVJWRUQgPSAwOyAvLyBBIHNpbXBsZSBzdHJpbmcgYXR0cmlidXRlLlxuLy8gQXR0cmlidXRlcyB0aGF0IGFyZW4ndCBpbiB0aGUgZmlsdGVyIGFyZSBwcmVzdW1lZCB0byBoYXZlIHRoaXMgdHlwZS5cblxudmFyIFNUUklORyA9IDE7IC8vIEEgc3RyaW5nIGF0dHJpYnV0ZSB0aGF0IGFjY2VwdHMgYm9vbGVhbnMgaW4gUmVhY3QuIEluIEhUTUwsIHRoZXNlIGFyZSBjYWxsZWRcbi8vIFwiZW51bWVyYXRlZFwiIGF0dHJpYnV0ZXMgd2l0aCBcInRydWVcIiBhbmQgXCJmYWxzZVwiIGFzIHBvc3NpYmxlIHZhbHVlcy5cbi8vIFdoZW4gdHJ1ZSwgaXQgc2hvdWxkIGJlIHNldCB0byBhIFwidHJ1ZVwiIHN0cmluZy5cbi8vIFdoZW4gZmFsc2UsIGl0IHNob3VsZCBiZSBzZXQgdG8gYSBcImZhbHNlXCIgc3RyaW5nLlxuXG52YXIgQk9PTEVBTklTSF9TVFJJTkcgPSAyOyAvLyBBIHJlYWwgYm9vbGVhbiBhdHRyaWJ1dGUuXG4vLyBXaGVuIHRydWUsIGl0IHNob3VsZCBiZSBwcmVzZW50IChzZXQgZWl0aGVyIHRvIGFuIGVtcHR5IHN0cmluZyBvciBpdHMgbmFtZSkuXG4vLyBXaGVuIGZhbHNlLCBpdCBzaG91bGQgYmUgb21pdHRlZC5cblxudmFyIEJPT0xFQU4gPSAzOyAvLyBBbiBhdHRyaWJ1dGUgdGhhdCBjYW4gYmUgdXNlZCBhcyBhIGZsYWcgYXMgd2VsbCBhcyB3aXRoIGEgdmFsdWUuXG4vLyBXaGVuIHRydWUsIGl0IHNob3VsZCBiZSBwcmVzZW50IChzZXQgZWl0aGVyIHRvIGFuIGVtcHR5IHN0cmluZyBvciBpdHMgbmFtZSkuXG4vLyBXaGVuIGZhbHNlLCBpdCBzaG91bGQgYmUgb21pdHRlZC5cbi8vIEZvciBhbnkgb3RoZXIgdmFsdWUsIHNob3VsZCBiZSBwcmVzZW50IHdpdGggdGhhdCB2YWx1ZS5cblxudmFyIE9WRVJMT0FERURfQk9PTEVBTiA9IDQ7IC8vIEFuIGF0dHJpYnV0ZSB0aGF0IG11c3QgYmUgbnVtZXJpYyBvciBwYXJzZSBhcyBhIG51bWVyaWMuXG4vLyBXaGVuIGZhbHN5LCBpdCBzaG91bGQgYmUgcmVtb3ZlZC5cblxudmFyIE5VTUVSSUMgPSA1OyAvLyBBbiBhdHRyaWJ1dGUgdGhhdCBtdXN0IGJlIHBvc2l0aXZlIG51bWVyaWMgb3IgcGFyc2UgYXMgYSBwb3NpdGl2ZSBudW1lcmljLlxuLy8gV2hlbiBmYWxzeSwgaXQgc2hvdWxkIGJlIHJlbW92ZWQuXG5cbnZhciBQT1NJVElWRV9OVU1FUklDID0gNjtcblxuLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xudmFyIEFUVFJJQlVURV9OQU1FX1NUQVJUX0NIQVIgPSBcIjpBLVpfYS16XFxcXHUwMEMwLVxcXFx1MDBENlxcXFx1MDBEOC1cXFxcdTAwRjZcXFxcdTAwRjgtXFxcXHUwMkZGXFxcXHUwMzcwLVxcXFx1MDM3RFxcXFx1MDM3Ri1cXFxcdTFGRkZcXFxcdTIwMEMtXFxcXHUyMDBEXFxcXHUyMDcwLVxcXFx1MjE4RlxcXFx1MkMwMC1cXFxcdTJGRUZcXFxcdTMwMDEtXFxcXHVEN0ZGXFxcXHVGOTAwLVxcXFx1RkRDRlxcXFx1RkRGMC1cXFxcdUZGRkRcIjtcbi8qIGVzbGludC1lbmFibGUgbWF4LWxlbiAqL1xuXG52YXIgQVRUUklCVVRFX05BTUVfQ0hBUiA9IEFUVFJJQlVURV9OQU1FX1NUQVJUX0NIQVIgKyBcIlxcXFwtLjAtOVxcXFx1MDBCN1xcXFx1MDMwMC1cXFxcdTAzNkZcXFxcdTIwM0YtXFxcXHUyMDQwXCI7XG52YXIgVkFMSURfQVRUUklCVVRFX05BTUVfUkVHRVggPSBuZXcgUmVnRXhwKCdeWycgKyBBVFRSSUJVVEVfTkFNRV9TVEFSVF9DSEFSICsgJ11bJyArIEFUVFJJQlVURV9OQU1FX0NIQVIgKyAnXSokJyk7XG52YXIgaWxsZWdhbEF0dHJpYnV0ZU5hbWVDYWNoZSA9IHt9O1xudmFyIHZhbGlkYXRlZEF0dHJpYnV0ZU5hbWVDYWNoZSA9IHt9O1xuZnVuY3Rpb24gaXNBdHRyaWJ1dGVOYW1lU2FmZShhdHRyaWJ1dGVOYW1lKSB7XG4gIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbGlkYXRlZEF0dHJpYnV0ZU5hbWVDYWNoZSwgYXR0cmlidXRlTmFtZSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGlsbGVnYWxBdHRyaWJ1dGVOYW1lQ2FjaGUsIGF0dHJpYnV0ZU5hbWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKFZBTElEX0FUVFJJQlVURV9OQU1FX1JFR0VYLnRlc3QoYXR0cmlidXRlTmFtZSkpIHtcbiAgICB2YWxpZGF0ZWRBdHRyaWJ1dGVOYW1lQ2FjaGVbYXR0cmlidXRlTmFtZV0gPSB0cnVlO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWxsZWdhbEF0dHJpYnV0ZU5hbWVDYWNoZVthdHRyaWJ1dGVOYW1lXSA9IHRydWU7XG5cbiAge1xuICAgIGVycm9yKCdJbnZhbGlkIGF0dHJpYnV0ZSBuYW1lOiBgJXNgJywgYXR0cmlidXRlTmFtZSk7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBzaG91bGRJZ25vcmVBdHRyaWJ1dGUobmFtZSwgcHJvcGVydHlJbmZvLCBpc0N1c3RvbUNvbXBvbmVudFRhZykge1xuICBpZiAocHJvcGVydHlJbmZvICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIHByb3BlcnR5SW5mby50eXBlID09PSBSRVNFUlZFRDtcbiAgfVxuXG4gIGlmIChpc0N1c3RvbUNvbXBvbmVudFRhZykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChuYW1lLmxlbmd0aCA+IDIgJiYgKG5hbWVbMF0gPT09ICdvJyB8fCBuYW1lWzBdID09PSAnTycpICYmIChuYW1lWzFdID09PSAnbicgfHwgbmFtZVsxXSA9PT0gJ04nKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gc2hvdWxkUmVtb3ZlQXR0cmlidXRlV2l0aFdhcm5pbmcobmFtZSwgdmFsdWUsIHByb3BlcnR5SW5mbywgaXNDdXN0b21Db21wb25lbnRUYWcpIHtcbiAgaWYgKHByb3BlcnR5SW5mbyAhPT0gbnVsbCAmJiBwcm9wZXJ0eUluZm8udHlwZSA9PT0gUkVTRVJWRUQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGVvZiB2YWx1ZSkge1xuICAgIGNhc2UgJ2Z1bmN0aW9uJzogLy8gJEZsb3dJc3N1ZSBzeW1ib2wgaXMgcGVyZmVjdGx5IHZhbGlkIGhlcmVcblxuICAgIGNhc2UgJ3N5bWJvbCc6XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgICAge1xuICAgICAgICBpZiAoaXNDdXN0b21Db21wb25lbnRUYWcpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHJvcGVydHlJbmZvICE9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuICFwcm9wZXJ0eUluZm8uYWNjZXB0c0Jvb2xlYW5zO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBwcmVmaXggPSBuYW1lLnRvTG93ZXJDYXNlKCkuc2xpY2UoMCwgNSk7XG4gICAgICAgICAgcmV0dXJuIHByZWZpeCAhPT0gJ2RhdGEtJyAmJiBwcmVmaXggIT09ICdhcmlhLSc7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIHNob3VsZFJlbW92ZUF0dHJpYnV0ZShuYW1lLCB2YWx1ZSwgcHJvcGVydHlJbmZvLCBpc0N1c3RvbUNvbXBvbmVudFRhZykge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdHlwZW9mIHZhbHVlID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKHNob3VsZFJlbW92ZUF0dHJpYnV0ZVdpdGhXYXJuaW5nKG5hbWUsIHZhbHVlLCBwcm9wZXJ0eUluZm8sIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGlzQ3VzdG9tQ29tcG9uZW50VGFnKSB7XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAocHJvcGVydHlJbmZvICE9PSBudWxsKSB7XG5cbiAgICBzd2l0Y2ggKHByb3BlcnR5SW5mby50eXBlKSB7XG4gICAgICBjYXNlIEJPT0xFQU46XG4gICAgICAgIHJldHVybiAhdmFsdWU7XG5cbiAgICAgIGNhc2UgT1ZFUkxPQURFRF9CT09MRUFOOlxuICAgICAgICByZXR1cm4gdmFsdWUgPT09IGZhbHNlO1xuXG4gICAgICBjYXNlIE5VTUVSSUM6XG4gICAgICAgIHJldHVybiBpc05hTih2YWx1ZSk7XG5cbiAgICAgIGNhc2UgUE9TSVRJVkVfTlVNRVJJQzpcbiAgICAgICAgcmV0dXJuIGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA8IDE7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gZ2V0UHJvcGVydHlJbmZvKG5hbWUpIHtcbiAgcmV0dXJuIHByb3BlcnRpZXMuaGFzT3duUHJvcGVydHkobmFtZSkgPyBwcm9wZXJ0aWVzW25hbWVdIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIHR5cGUsIG11c3RVc2VQcm9wZXJ0eSwgYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlTmFtZXNwYWNlLCBzYW5pdGl6ZVVSTCwgcmVtb3ZlRW1wdHlTdHJpbmcpIHtcbiAgdGhpcy5hY2NlcHRzQm9vbGVhbnMgPSB0eXBlID09PSBCT09MRUFOSVNIX1NUUklORyB8fCB0eXBlID09PSBCT09MRUFOIHx8IHR5cGUgPT09IE9WRVJMT0FERURfQk9PTEVBTjtcbiAgdGhpcy5hdHRyaWJ1dGVOYW1lID0gYXR0cmlidXRlTmFtZTtcbiAgdGhpcy5hdHRyaWJ1dGVOYW1lc3BhY2UgPSBhdHRyaWJ1dGVOYW1lc3BhY2U7XG4gIHRoaXMubXVzdFVzZVByb3BlcnR5ID0gbXVzdFVzZVByb3BlcnR5O1xuICB0aGlzLnByb3BlcnR5TmFtZSA9IG5hbWU7XG4gIHRoaXMudHlwZSA9IHR5cGU7XG4gIHRoaXMuc2FuaXRpemVVUkwgPSBzYW5pdGl6ZVVSTDtcbiAgdGhpcy5yZW1vdmVFbXB0eVN0cmluZyA9IHJlbW92ZUVtcHR5U3RyaW5nO1xufSAvLyBXaGVuIGFkZGluZyBhdHRyaWJ1dGVzIHRvIHRoaXMgbGlzdCwgYmUgc3VyZSB0byBhbHNvIGFkZCB0aGVtIHRvXG4vLyB0aGUgYHBvc3NpYmxlU3RhbmRhcmROYW1lc2AgbW9kdWxlIHRvIGVuc3VyZSBjYXNpbmcgYW5kIGluY29ycmVjdFxuLy8gbmFtZSB3YXJuaW5ncy5cblxuXG52YXIgcHJvcGVydGllcyA9IHt9OyAvLyBUaGVzZSBwcm9wcyBhcmUgcmVzZXJ2ZWQgYnkgUmVhY3QuIFRoZXkgc2hvdWxkbid0IGJlIHdyaXR0ZW4gdG8gdGhlIERPTS5cblxudmFyIHJlc2VydmVkUHJvcHMgPSBbJ2NoaWxkcmVuJywgJ2Rhbmdlcm91c2x5U2V0SW5uZXJIVE1MJywgLy8gVE9ETzogVGhpcyBwcmV2ZW50cyB0aGUgYXNzaWdubWVudCBvZiBkZWZhdWx0VmFsdWUgdG8gcmVndWxhclxuLy8gZWxlbWVudHMgKG5vdCBqdXN0IGlucHV0cykuIE5vdyB0aGF0IFJlYWN0RE9NSW5wdXQgYXNzaWducyB0byB0aGVcbi8vIGRlZmF1bHRWYWx1ZSBwcm9wZXJ0eSAtLSBkbyB3ZSBuZWVkIHRoaXM/XG4nZGVmYXVsdFZhbHVlJywgJ2RlZmF1bHRDaGVja2VkJywgJ2lubmVySFRNTCcsICdzdXBwcmVzc0NvbnRlbnRFZGl0YWJsZVdhcm5pbmcnLCAnc3VwcHJlc3NIeWRyYXRpb25XYXJuaW5nJywgJ3N0eWxlJ107XG5cbnJlc2VydmVkUHJvcHMuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBSRVNFUlZFRCwgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBuYW1lLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIEEgZmV3IFJlYWN0IHN0cmluZyBhdHRyaWJ1dGVzIGhhdmUgYSBkaWZmZXJlbnQgbmFtZS5cbi8vIFRoaXMgaXMgYSBtYXBwaW5nIGZyb20gUmVhY3QgcHJvcCBuYW1lcyB0byB0aGUgYXR0cmlidXRlIG5hbWVzLlxuXG5bWydhY2NlcHRDaGFyc2V0JywgJ2FjY2VwdC1jaGFyc2V0J10sIFsnY2xhc3NOYW1lJywgJ2NsYXNzJ10sIFsnaHRtbEZvcicsICdmb3InXSwgWydodHRwRXF1aXYnLCAnaHR0cC1lcXVpdiddXS5mb3JFYWNoKGZ1bmN0aW9uIChfcmVmKSB7XG4gIHZhciBuYW1lID0gX3JlZlswXSxcbiAgICAgIGF0dHJpYnV0ZU5hbWUgPSBfcmVmWzFdO1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBTVFJJTkcsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgYXR0cmlidXRlTmFtZSwgLy8gYXR0cmlidXRlTmFtZVxuICBudWxsLCAvLyBhdHRyaWJ1dGVOYW1lc3BhY2VcbiAgZmFsc2UsIC8vIHNhbml0aXplVVJMXG4gIGZhbHNlKTtcbn0pOyAvLyBUaGVzZSBhcmUgXCJlbnVtZXJhdGVkXCIgSFRNTCBhdHRyaWJ1dGVzIHRoYXQgYWNjZXB0IFwidHJ1ZVwiIGFuZCBcImZhbHNlXCIuXG4vLyBJbiBSZWFjdCwgd2UgbGV0IHVzZXJzIHBhc3MgYHRydWVgIGFuZCBgZmFsc2VgIGV2ZW4gdGhvdWdoIHRlY2huaWNhbGx5XG4vLyB0aGVzZSBhcmVuJ3QgYm9vbGVhbiBhdHRyaWJ1dGVzICh0aGV5IGFyZSBjb2VyY2VkIHRvIHN0cmluZ3MpLlxuXG5bJ2NvbnRlbnRFZGl0YWJsZScsICdkcmFnZ2FibGUnLCAnc3BlbGxDaGVjaycsICd2YWx1ZSddLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgcHJvcGVydGllc1tuYW1lXSA9IG5ldyBQcm9wZXJ0eUluZm9SZWNvcmQobmFtZSwgQk9PTEVBTklTSF9TVFJJTkcsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgbmFtZS50b0xvd2VyQ2FzZSgpLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIFRoZXNlIGFyZSBcImVudW1lcmF0ZWRcIiBTVkcgYXR0cmlidXRlcyB0aGF0IGFjY2VwdCBcInRydWVcIiBhbmQgXCJmYWxzZVwiLlxuLy8gSW4gUmVhY3QsIHdlIGxldCB1c2VycyBwYXNzIGB0cnVlYCBhbmQgYGZhbHNlYCBldmVuIHRob3VnaCB0ZWNobmljYWxseVxuLy8gdGhlc2UgYXJlbid0IGJvb2xlYW4gYXR0cmlidXRlcyAodGhleSBhcmUgY29lcmNlZCB0byBzdHJpbmdzKS5cbi8vIFNpbmNlIHRoZXNlIGFyZSBTVkcgYXR0cmlidXRlcywgdGhlaXIgYXR0cmlidXRlIG5hbWVzIGFyZSBjYXNlLXNlbnNpdGl2ZS5cblxuWydhdXRvUmV2ZXJzZScsICdleHRlcm5hbFJlc291cmNlc1JlcXVpcmVkJywgJ2ZvY3VzYWJsZScsICdwcmVzZXJ2ZUFscGhhJ10uZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBCT09MRUFOSVNIX1NUUklORywgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBuYW1lLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIFRoZXNlIGFyZSBIVE1MIGJvb2xlYW4gYXR0cmlidXRlcy5cblxuWydhbGxvd0Z1bGxTY3JlZW4nLCAnYXN5bmMnLCAvLyBOb3RlOiB0aGVyZSBpcyBhIHNwZWNpYWwgY2FzZSB0aGF0IHByZXZlbnRzIGl0IGZyb20gYmVpbmcgd3JpdHRlbiB0byB0aGUgRE9NXG4vLyBvbiB0aGUgY2xpZW50IHNpZGUgYmVjYXVzZSB0aGUgYnJvd3NlcnMgYXJlIGluY29uc2lzdGVudC4gSW5zdGVhZCB3ZSBjYWxsIGZvY3VzKCkuXG4nYXV0b0ZvY3VzJywgJ2F1dG9QbGF5JywgJ2NvbnRyb2xzJywgJ2RlZmF1bHQnLCAnZGVmZXInLCAnZGlzYWJsZWQnLCAnZGlzYWJsZVBpY3R1cmVJblBpY3R1cmUnLCAnZGlzYWJsZVJlbW90ZVBsYXliYWNrJywgJ2Zvcm1Ob1ZhbGlkYXRlJywgJ2hpZGRlbicsICdsb29wJywgJ25vTW9kdWxlJywgJ25vVmFsaWRhdGUnLCAnb3BlbicsICdwbGF5c0lubGluZScsICdyZWFkT25seScsICdyZXF1aXJlZCcsICdyZXZlcnNlZCcsICdzY29wZWQnLCAnc2VhbWxlc3MnLCAvLyBNaWNyb2RhdGFcbidpdGVtU2NvcGUnXS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIEJPT0xFQU4sIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgbmFtZS50b0xvd2VyQ2FzZSgpLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIFRoZXNlIGFyZSB0aGUgZmV3IFJlYWN0IHByb3BzIHRoYXQgd2Ugc2V0IGFzIERPTSBwcm9wZXJ0aWVzXG4vLyByYXRoZXIgdGhhbiBhdHRyaWJ1dGVzLiBUaGVzZSBhcmUgYWxsIGJvb2xlYW5zLlxuXG5bJ2NoZWNrZWQnLCAvLyBOb3RlOiBgb3B0aW9uLnNlbGVjdGVkYCBpcyBub3QgdXBkYXRlZCBpZiBgc2VsZWN0Lm11bHRpcGxlYCBpc1xuLy8gZGlzYWJsZWQgd2l0aCBgcmVtb3ZlQXR0cmlidXRlYC4gV2UgaGF2ZSBzcGVjaWFsIGxvZ2ljIGZvciBoYW5kbGluZyB0aGlzLlxuJ211bHRpcGxlJywgJ211dGVkJywgJ3NlbGVjdGVkJyAvLyBOT1RFOiBpZiB5b3UgYWRkIGEgY2FtZWxDYXNlZCBwcm9wIHRvIHRoaXMgbGlzdCxcbi8vIHlvdSdsbCBuZWVkIHRvIHNldCBhdHRyaWJ1dGVOYW1lIHRvIG5hbWUudG9Mb3dlckNhc2UoKVxuLy8gaW5zdGVhZCBpbiB0aGUgYXNzaWdubWVudCBiZWxvdy5cbl0uZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBCT09MRUFOLCB0cnVlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgbmFtZSwgLy8gYXR0cmlidXRlTmFtZVxuICBudWxsLCAvLyBhdHRyaWJ1dGVOYW1lc3BhY2VcbiAgZmFsc2UsIC8vIHNhbml0aXplVVJMXG4gIGZhbHNlKTtcbn0pOyAvLyBUaGVzZSBhcmUgSFRNTCBhdHRyaWJ1dGVzIHRoYXQgYXJlIFwib3ZlcmxvYWRlZCBib29sZWFuc1wiOiB0aGV5IGJlaGF2ZSBsaWtlXG4vLyBib29sZWFucywgYnV0IGNhbiBhbHNvIGFjY2VwdCBhIHN0cmluZyB2YWx1ZS5cblxuWydjYXB0dXJlJywgJ2Rvd25sb2FkJyAvLyBOT1RFOiBpZiB5b3UgYWRkIGEgY2FtZWxDYXNlZCBwcm9wIHRvIHRoaXMgbGlzdCxcbi8vIHlvdSdsbCBuZWVkIHRvIHNldCBhdHRyaWJ1dGVOYW1lIHRvIG5hbWUudG9Mb3dlckNhc2UoKVxuLy8gaW5zdGVhZCBpbiB0aGUgYXNzaWdubWVudCBiZWxvdy5cbl0uZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBPVkVSTE9BREVEX0JPT0xFQU4sIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgbmFtZSwgLy8gYXR0cmlidXRlTmFtZVxuICBudWxsLCAvLyBhdHRyaWJ1dGVOYW1lc3BhY2VcbiAgZmFsc2UsIC8vIHNhbml0aXplVVJMXG4gIGZhbHNlKTtcbn0pOyAvLyBUaGVzZSBhcmUgSFRNTCBhdHRyaWJ1dGVzIHRoYXQgbXVzdCBiZSBwb3NpdGl2ZSBudW1iZXJzLlxuXG5bJ2NvbHMnLCAncm93cycsICdzaXplJywgJ3NwYW4nIC8vIE5PVEU6IGlmIHlvdSBhZGQgYSBjYW1lbENhc2VkIHByb3AgdG8gdGhpcyBsaXN0LFxuLy8geW91J2xsIG5lZWQgdG8gc2V0IGF0dHJpYnV0ZU5hbWUgdG8gbmFtZS50b0xvd2VyQ2FzZSgpXG4vLyBpbnN0ZWFkIGluIHRoZSBhc3NpZ25tZW50IGJlbG93LlxuXS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIFBPU0lUSVZFX05VTUVSSUMsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgbmFtZSwgLy8gYXR0cmlidXRlTmFtZVxuICBudWxsLCAvLyBhdHRyaWJ1dGVOYW1lc3BhY2VcbiAgZmFsc2UsIC8vIHNhbml0aXplVVJMXG4gIGZhbHNlKTtcbn0pOyAvLyBUaGVzZSBhcmUgSFRNTCBhdHRyaWJ1dGVzIHRoYXQgbXVzdCBiZSBudW1iZXJzLlxuXG5bJ3Jvd1NwYW4nLCAnc3RhcnQnXS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIE5VTUVSSUMsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgbmFtZS50b0xvd2VyQ2FzZSgpLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7XG52YXIgQ0FNRUxJWkUgPSAvW1xcLVxcOl0oW2Etel0pL2c7XG5cbnZhciBjYXBpdGFsaXplID0gZnVuY3Rpb24gKHRva2VuKSB7XG4gIHJldHVybiB0b2tlblsxXS50b1VwcGVyQ2FzZSgpO1xufTsgLy8gVGhpcyBpcyBhIGxpc3Qgb2YgYWxsIFNWRyBhdHRyaWJ1dGVzIHRoYXQgbmVlZCBzcGVjaWFsIGNhc2luZywgbmFtZXNwYWNpbmcsXG4vLyBvciBib29sZWFuIHZhbHVlIGFzc2lnbm1lbnQuIFJlZ3VsYXIgYXR0cmlidXRlcyB0aGF0IGp1c3QgYWNjZXB0IHN0cmluZ3Ncbi8vIGFuZCBoYXZlIHRoZSBzYW1lIG5hbWVzIGFyZSBvbWl0dGVkLCBqdXN0IGxpa2UgaW4gdGhlIEhUTUwgYXR0cmlidXRlIGZpbHRlci5cbi8vIFNvbWUgb2YgdGhlc2UgYXR0cmlidXRlcyBjYW4gYmUgaGFyZCB0byBmaW5kLiBUaGlzIGxpc3Qgd2FzIGNyZWF0ZWQgYnlcbi8vIHNjcmFwaW5nIHRoZSBNRE4gZG9jdW1lbnRhdGlvbi5cblxuXG5bJ2FjY2VudC1oZWlnaHQnLCAnYWxpZ25tZW50LWJhc2VsaW5lJywgJ2FyYWJpYy1mb3JtJywgJ2Jhc2VsaW5lLXNoaWZ0JywgJ2NhcC1oZWlnaHQnLCAnY2xpcC1wYXRoJywgJ2NsaXAtcnVsZScsICdjb2xvci1pbnRlcnBvbGF0aW9uJywgJ2NvbG9yLWludGVycG9sYXRpb24tZmlsdGVycycsICdjb2xvci1wcm9maWxlJywgJ2NvbG9yLXJlbmRlcmluZycsICdkb21pbmFudC1iYXNlbGluZScsICdlbmFibGUtYmFja2dyb3VuZCcsICdmaWxsLW9wYWNpdHknLCAnZmlsbC1ydWxlJywgJ2Zsb29kLWNvbG9yJywgJ2Zsb29kLW9wYWNpdHknLCAnZm9udC1mYW1pbHknLCAnZm9udC1zaXplJywgJ2ZvbnQtc2l6ZS1hZGp1c3QnLCAnZm9udC1zdHJldGNoJywgJ2ZvbnQtc3R5bGUnLCAnZm9udC12YXJpYW50JywgJ2ZvbnQtd2VpZ2h0JywgJ2dseXBoLW5hbWUnLCAnZ2x5cGgtb3JpZW50YXRpb24taG9yaXpvbnRhbCcsICdnbHlwaC1vcmllbnRhdGlvbi12ZXJ0aWNhbCcsICdob3Jpei1hZHYteCcsICdob3Jpei1vcmlnaW4teCcsICdpbWFnZS1yZW5kZXJpbmcnLCAnbGV0dGVyLXNwYWNpbmcnLCAnbGlnaHRpbmctY29sb3InLCAnbWFya2VyLWVuZCcsICdtYXJrZXItbWlkJywgJ21hcmtlci1zdGFydCcsICdvdmVybGluZS1wb3NpdGlvbicsICdvdmVybGluZS10aGlja25lc3MnLCAncGFpbnQtb3JkZXInLCAncGFub3NlLTEnLCAncG9pbnRlci1ldmVudHMnLCAncmVuZGVyaW5nLWludGVudCcsICdzaGFwZS1yZW5kZXJpbmcnLCAnc3RvcC1jb2xvcicsICdzdG9wLW9wYWNpdHknLCAnc3RyaWtldGhyb3VnaC1wb3NpdGlvbicsICdzdHJpa2V0aHJvdWdoLXRoaWNrbmVzcycsICdzdHJva2UtZGFzaGFycmF5JywgJ3N0cm9rZS1kYXNob2Zmc2V0JywgJ3N0cm9rZS1saW5lY2FwJywgJ3N0cm9rZS1saW5lam9pbicsICdzdHJva2UtbWl0ZXJsaW1pdCcsICdzdHJva2Utb3BhY2l0eScsICdzdHJva2Utd2lkdGgnLCAndGV4dC1hbmNob3InLCAndGV4dC1kZWNvcmF0aW9uJywgJ3RleHQtcmVuZGVyaW5nJywgJ3VuZGVybGluZS1wb3NpdGlvbicsICd1bmRlcmxpbmUtdGhpY2tuZXNzJywgJ3VuaWNvZGUtYmlkaScsICd1bmljb2RlLXJhbmdlJywgJ3VuaXRzLXBlci1lbScsICd2LWFscGhhYmV0aWMnLCAndi1oYW5naW5nJywgJ3YtaWRlb2dyYXBoaWMnLCAndi1tYXRoZW1hdGljYWwnLCAndmVjdG9yLWVmZmVjdCcsICd2ZXJ0LWFkdi15JywgJ3ZlcnQtb3JpZ2luLXgnLCAndmVydC1vcmlnaW4teScsICd3b3JkLXNwYWNpbmcnLCAnd3JpdGluZy1tb2RlJywgJ3htbG5zOnhsaW5rJywgJ3gtaGVpZ2h0JyAvLyBOT1RFOiBpZiB5b3UgYWRkIGEgY2FtZWxDYXNlZCBwcm9wIHRvIHRoaXMgbGlzdCxcbi8vIHlvdSdsbCBuZWVkIHRvIHNldCBhdHRyaWJ1dGVOYW1lIHRvIG5hbWUudG9Mb3dlckNhc2UoKVxuLy8gaW5zdGVhZCBpbiB0aGUgYXNzaWdubWVudCBiZWxvdy5cbl0uZm9yRWFjaChmdW5jdGlvbiAoYXR0cmlidXRlTmFtZSkge1xuICB2YXIgbmFtZSA9IGF0dHJpYnV0ZU5hbWUucmVwbGFjZShDQU1FTElaRSwgY2FwaXRhbGl6ZSk7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIFNUUklORywgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBhdHRyaWJ1dGVOYW1lLCBudWxsLCAvLyBhdHRyaWJ1dGVOYW1lc3BhY2VcbiAgZmFsc2UsIC8vIHNhbml0aXplVVJMXG4gIGZhbHNlKTtcbn0pOyAvLyBTdHJpbmcgU1ZHIGF0dHJpYnV0ZXMgd2l0aCB0aGUgeGxpbmsgbmFtZXNwYWNlLlxuXG5bJ3hsaW5rOmFjdHVhdGUnLCAneGxpbms6YXJjcm9sZScsICd4bGluazpyb2xlJywgJ3hsaW5rOnNob3cnLCAneGxpbms6dGl0bGUnLCAneGxpbms6dHlwZScgLy8gTk9URTogaWYgeW91IGFkZCBhIGNhbWVsQ2FzZWQgcHJvcCB0byB0aGlzIGxpc3QsXG4vLyB5b3UnbGwgbmVlZCB0byBzZXQgYXR0cmlidXRlTmFtZSB0byBuYW1lLnRvTG93ZXJDYXNlKClcbi8vIGluc3RlYWQgaW4gdGhlIGFzc2lnbm1lbnQgYmVsb3cuXG5dLmZvckVhY2goZnVuY3Rpb24gKGF0dHJpYnV0ZU5hbWUpIHtcbiAgdmFyIG5hbWUgPSBhdHRyaWJ1dGVOYW1lLnJlcGxhY2UoQ0FNRUxJWkUsIGNhcGl0YWxpemUpO1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBTVFJJTkcsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgYXR0cmlidXRlTmFtZSwgJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnLCBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIFN0cmluZyBTVkcgYXR0cmlidXRlcyB3aXRoIHRoZSB4bWwgbmFtZXNwYWNlLlxuXG5bJ3htbDpiYXNlJywgJ3htbDpsYW5nJywgJ3htbDpzcGFjZScgLy8gTk9URTogaWYgeW91IGFkZCBhIGNhbWVsQ2FzZWQgcHJvcCB0byB0aGlzIGxpc3QsXG4vLyB5b3UnbGwgbmVlZCB0byBzZXQgYXR0cmlidXRlTmFtZSB0byBuYW1lLnRvTG93ZXJDYXNlKClcbi8vIGluc3RlYWQgaW4gdGhlIGFzc2lnbm1lbnQgYmVsb3cuXG5dLmZvckVhY2goZnVuY3Rpb24gKGF0dHJpYnV0ZU5hbWUpIHtcbiAgdmFyIG5hbWUgPSBhdHRyaWJ1dGVOYW1lLnJlcGxhY2UoQ0FNRUxJWkUsIGNhcGl0YWxpemUpO1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBTVFJJTkcsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgYXR0cmlidXRlTmFtZSwgJ2h0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZScsIGZhbHNlLCAvLyBzYW5pdGl6ZVVSTFxuICBmYWxzZSk7XG59KTsgLy8gVGhlc2UgYXR0cmlidXRlIGV4aXN0cyBib3RoIGluIEhUTUwgYW5kIFNWRy5cbi8vIFRoZSBhdHRyaWJ1dGUgbmFtZSBpcyBjYXNlLXNlbnNpdGl2ZSBpbiBTVkcgc28gd2UgY2FuJ3QganVzdCB1c2Vcbi8vIHRoZSBSZWFjdCBuYW1lIGxpa2Ugd2UgZG8gZm9yIGF0dHJpYnV0ZXMgdGhhdCBleGlzdCBvbmx5IGluIEhUTUwuXG5cblsndGFiSW5kZXgnLCAnY3Jvc3NPcmlnaW4nXS5mb3JFYWNoKGZ1bmN0aW9uIChhdHRyaWJ1dGVOYW1lKSB7XG4gIHByb3BlcnRpZXNbYXR0cmlidXRlTmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKGF0dHJpYnV0ZU5hbWUsIFNUUklORywgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBhdHRyaWJ1dGVOYW1lLnRvTG93ZXJDYXNlKCksIC8vIGF0dHJpYnV0ZU5hbWVcbiAgbnVsbCwgLy8gYXR0cmlidXRlTmFtZXNwYWNlXG4gIGZhbHNlLCAvLyBzYW5pdGl6ZVVSTFxuICBmYWxzZSk7XG59KTsgLy8gVGhlc2UgYXR0cmlidXRlcyBhY2NlcHQgVVJMcy4gVGhlc2UgbXVzdCBub3QgYWxsb3cgamF2YXNjcmlwdDogVVJMUy5cbi8vIFRoZXNlIHdpbGwgYWxzbyBuZWVkIHRvIGFjY2VwdCBUcnVzdGVkIFR5cGVzIG9iamVjdCBpbiB0aGUgZnV0dXJlLlxuXG52YXIgeGxpbmtIcmVmID0gJ3hsaW5rSHJlZic7XG5wcm9wZXJ0aWVzW3hsaW5rSHJlZl0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKCd4bGlua0hyZWYnLCBTVFJJTkcsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbid4bGluazpocmVmJywgJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnLCB0cnVlLCAvLyBzYW5pdGl6ZVVSTFxuZmFsc2UpO1xuWydzcmMnLCAnaHJlZicsICdhY3Rpb24nLCAnZm9ybUFjdGlvbiddLmZvckVhY2goZnVuY3Rpb24gKGF0dHJpYnV0ZU5hbWUpIHtcbiAgcHJvcGVydGllc1thdHRyaWJ1dGVOYW1lXSA9IG5ldyBQcm9wZXJ0eUluZm9SZWNvcmQoYXR0cmlidXRlTmFtZSwgU1RSSU5HLCBmYWxzZSwgLy8gbXVzdFVzZVByb3BlcnR5XG4gIGF0dHJpYnV0ZU5hbWUudG9Mb3dlckNhc2UoKSwgLy8gYXR0cmlidXRlTmFtZVxuICBudWxsLCAvLyBhdHRyaWJ1dGVOYW1lc3BhY2VcbiAgdHJ1ZSwgLy8gc2FuaXRpemVVUkxcbiAgdHJ1ZSk7XG59KTtcblxuLy8gYW5kIGFueSBuZXdsaW5lIG9yIHRhYiBhcmUgZmlsdGVyZWQgb3V0IGFzIGlmIHRoZXkncmUgbm90IHBhcnQgb2YgdGhlIFVSTC5cbi8vIGh0dHBzOi8vdXJsLnNwZWMud2hhdHdnLm9yZy8jdXJsLXBhcnNpbmdcbi8vIFRhYiBvciBuZXdsaW5lIGFyZSBkZWZpbmVkIGFzIFxcclxcblxcdDpcbi8vIGh0dHBzOi8vaW5mcmEuc3BlYy53aGF0d2cub3JnLyNhc2NpaS10YWItb3ItbmV3bGluZVxuLy8gQSBDMCBjb250cm9sIGlzIGEgY29kZSBwb2ludCBpbiB0aGUgcmFuZ2UgXFx1MDAwMCBOVUxMIHRvIFxcdTAwMUZcbi8vIElORk9STUFUSU9OIFNFUEFSQVRPUiBPTkUsIGluY2x1c2l2ZTpcbi8vIGh0dHBzOi8vaW5mcmEuc3BlYy53aGF0d2cub3JnLyNjMC1jb250cm9sLW9yLXNwYWNlXG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cblxudmFyIGlzSmF2YVNjcmlwdFByb3RvY29sID0gL15bXFx1MDAwMC1cXHUwMDFGIF0qaltcXHJcXG5cXHRdKmFbXFxyXFxuXFx0XSp2W1xcclxcblxcdF0qYVtcXHJcXG5cXHRdKnNbXFxyXFxuXFx0XSpjW1xcclxcblxcdF0qcltcXHJcXG5cXHRdKmlbXFxyXFxuXFx0XSpwW1xcclxcblxcdF0qdFtcXHJcXG5cXHRdKlxcOi9pO1xudmFyIGRpZFdhcm4gPSBmYWxzZTtcblxuZnVuY3Rpb24gc2FuaXRpemVVUkwodXJsKSB7XG4gIHtcbiAgICBpZiAoIWRpZFdhcm4gJiYgaXNKYXZhU2NyaXB0UHJvdG9jb2wudGVzdCh1cmwpKSB7XG4gICAgICBkaWRXYXJuID0gdHJ1ZTtcblxuICAgICAgZXJyb3IoJ0EgZnV0dXJlIHZlcnNpb24gb2YgUmVhY3Qgd2lsbCBibG9jayBqYXZhc2NyaXB0OiBVUkxzIGFzIGEgc2VjdXJpdHkgcHJlY2F1dGlvbi4gJyArICdVc2UgZXZlbnQgaGFuZGxlcnMgaW5zdGVhZCBpZiB5b3UgY2FuLiBJZiB5b3UgbmVlZCB0byBnZW5lcmF0ZSB1bnNhZmUgSFRNTCB0cnkgJyArICd1c2luZyBkYW5nZXJvdXNseVNldElubmVySFRNTCBpbnN0ZWFkLiBSZWFjdCB3YXMgcGFzc2VkICVzLicsIEpTT04uc3RyaW5naWZ5KHVybCkpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEdldCB0aGUgdmFsdWUgZm9yIGEgcHJvcGVydHkgb24gYSBub2RlLiBPbmx5IHVzZWQgaW4gREVWIGZvciBTU1IgdmFsaWRhdGlvbi5cbiAqIFRoZSBcImV4cGVjdGVkXCIgYXJndW1lbnQgaXMgdXNlZCBhcyBhIGhpbnQgb2Ygd2hhdCB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMuXG4gKiBTb21lIHByb3BlcnRpZXMgaGF2ZSBtdWx0aXBsZSBlcXVpdmFsZW50IHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gZ2V0VmFsdWVGb3JQcm9wZXJ0eShub2RlLCBuYW1lLCBleHBlY3RlZCwgcHJvcGVydHlJbmZvKSB7XG4gIHtcbiAgICBpZiAocHJvcGVydHlJbmZvLm11c3RVc2VQcm9wZXJ0eSkge1xuICAgICAgdmFyIHByb3BlcnR5TmFtZSA9IHByb3BlcnR5SW5mby5wcm9wZXJ0eU5hbWU7XG4gICAgICByZXR1cm4gbm9kZVtwcm9wZXJ0eU5hbWVdO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUaGlzIGNoZWNrIHByb3RlY3RzIG11bHRpcGxlIHVzZXMgb2YgYGV4cGVjdGVkYCwgd2hpY2ggaXMgd2h5IHRoZVxuICAgICAgLy8gcmVhY3QtaW50ZXJuYWwvc2FmZS1zdHJpbmctY29lcmNpb24gcnVsZSBpcyBkaXNhYmxlZCBpbiBzZXZlcmFsIHNwb3RzXG4gICAgICAvLyBiZWxvdy5cbiAgICAgIHtcbiAgICAgICAgY2hlY2tBdHRyaWJ1dGVTdHJpbmdDb2VyY2lvbihleHBlY3RlZCwgbmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICggcHJvcGVydHlJbmZvLnNhbml0aXplVVJMKSB7XG4gICAgICAgIC8vIElmIHdlIGhhdmVuJ3QgZnVsbHkgZGlzYWJsZWQgamF2YXNjcmlwdDogVVJMcywgYW5kIGlmXG4gICAgICAgIC8vIHRoZSBoeWRyYXRpb24gaXMgc3VjY2Vzc2Z1bCBvZiBhIGphdmFzY3JpcHQ6IFVSTCwgd2VcbiAgICAgICAgLy8gc3RpbGwgd2FudCB0byB3YXJuIG9uIHRoZSBjbGllbnQuXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuICAgICAgICBzYW5pdGl6ZVVSTCgnJyArIGV4cGVjdGVkKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGF0dHJpYnV0ZU5hbWUgPSBwcm9wZXJ0eUluZm8uYXR0cmlidXRlTmFtZTtcbiAgICAgIHZhciBzdHJpbmdWYWx1ZSA9IG51bGw7XG5cbiAgICAgIGlmIChwcm9wZXJ0eUluZm8udHlwZSA9PT0gT1ZFUkxPQURFRF9CT09MRUFOKSB7XG4gICAgICAgIGlmIChub2RlLmhhc0F0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKSkge1xuICAgICAgICAgIHZhciB2YWx1ZSA9IG5vZGUuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUpO1xuXG4gICAgICAgICAgaWYgKHZhbHVlID09PSAnJykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNob3VsZFJlbW92ZUF0dHJpYnV0ZShuYW1lLCBleHBlY3RlZCwgcHJvcGVydHlJbmZvLCBmYWxzZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICB9IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuXG5cbiAgICAgICAgICBpZiAodmFsdWUgPT09ICcnICsgZXhwZWN0ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBleHBlY3RlZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobm9kZS5oYXNBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSkpIHtcbiAgICAgICAgaWYgKHNob3VsZFJlbW92ZUF0dHJpYnV0ZShuYW1lLCBleHBlY3RlZCwgcHJvcGVydHlJbmZvLCBmYWxzZSkpIHtcbiAgICAgICAgICAvLyBXZSBoYWQgYW4gYXR0cmlidXRlIGJ1dCBzaG91bGRuJ3QgaGF2ZSBoYWQgb25lLCBzbyByZWFkIGl0XG4gICAgICAgICAgLy8gZm9yIHRoZSBlcnJvciBtZXNzYWdlLlxuICAgICAgICAgIHJldHVybiBub2RlLmdldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcm9wZXJ0eUluZm8udHlwZSA9PT0gQk9PTEVBTikge1xuICAgICAgICAgIC8vIElmIHRoaXMgd2FzIGEgYm9vbGVhbiwgaXQgZG9lc24ndCBtYXR0ZXIgd2hhdCB0aGUgdmFsdWUgaXNcbiAgICAgICAgICAvLyB0aGUgZmFjdCB0aGF0IHdlIGhhdmUgaXQgaXMgdGhlIHNhbWUgYXMgdGhlIGV4cGVjdGVkLlxuICAgICAgICAgIHJldHVybiBleHBlY3RlZDtcbiAgICAgICAgfSAvLyBFdmVuIGlmIHRoaXMgcHJvcGVydHkgdXNlcyBhIG5hbWVzcGFjZSB3ZSB1c2UgZ2V0QXR0cmlidXRlXG4gICAgICAgIC8vIGJlY2F1c2Ugd2UgYXNzdW1lIGl0cyBuYW1lc3BhY2VkIG5hbWUgaXMgdGhlIHNhbWUgYXMgb3VyIGNvbmZpZy5cbiAgICAgICAgLy8gVG8gdXNlIGdldEF0dHJpYnV0ZU5TIHdlIG5lZWQgdGhlIGxvY2FsIG5hbWUgd2hpY2ggd2UgZG9uJ3QgaGF2ZVxuICAgICAgICAvLyBpbiBvdXIgY29uZmlnIGF0bS5cblxuXG4gICAgICAgIHN0cmluZ1ZhbHVlID0gbm9kZS5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzaG91bGRSZW1vdmVBdHRyaWJ1dGUobmFtZSwgZXhwZWN0ZWQsIHByb3BlcnR5SW5mbywgZmFsc2UpKSB7XG4gICAgICAgIHJldHVybiBzdHJpbmdWYWx1ZSA9PT0gbnVsbCA/IGV4cGVjdGVkIDogc3RyaW5nVmFsdWU7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuICAgICAgfSBlbHNlIGlmIChzdHJpbmdWYWx1ZSA9PT0gJycgKyBleHBlY3RlZCkge1xuICAgICAgICByZXR1cm4gZXhwZWN0ZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gc3RyaW5nVmFsdWU7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEdldCB0aGUgdmFsdWUgZm9yIGEgYXR0cmlidXRlIG9uIGEgbm9kZS4gT25seSB1c2VkIGluIERFViBmb3IgU1NSIHZhbGlkYXRpb24uXG4gKiBUaGUgdGhpcmQgYXJndW1lbnQgaXMgdXNlZCBhcyBhIGhpbnQgb2Ygd2hhdCB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMuIFNvbWVcbiAqIGF0dHJpYnV0ZXMgaGF2ZSBtdWx0aXBsZSBlcXVpdmFsZW50IHZhbHVlcy5cbiAqL1xuXG5mdW5jdGlvbiBnZXRWYWx1ZUZvckF0dHJpYnV0ZShub2RlLCBuYW1lLCBleHBlY3RlZCwgaXNDdXN0b21Db21wb25lbnRUYWcpIHtcbiAge1xuICAgIGlmICghaXNBdHRyaWJ1dGVOYW1lU2FmZShuYW1lKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghbm9kZS5oYXNBdHRyaWJ1dGUobmFtZSkpIHtcbiAgICAgIHJldHVybiBleHBlY3RlZCA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgdmFsdWUgPSBub2RlLmdldEF0dHJpYnV0ZShuYW1lKTtcblxuICAgIHtcbiAgICAgIGNoZWNrQXR0cmlidXRlU3RyaW5nQ29lcmNpb24oZXhwZWN0ZWQsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZSA9PT0gJycgKyBleHBlY3RlZCkge1xuICAgICAgcmV0dXJuIGV4cGVjdGVkO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxufVxuLyoqXG4gKiBTZXRzIHRoZSB2YWx1ZSBmb3IgYSBwcm9wZXJ0eSBvbiBhIG5vZGUuXG4gKlxuICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICovXG5cbmZ1bmN0aW9uIHNldFZhbHVlRm9yUHJvcGVydHkobm9kZSwgbmFtZSwgdmFsdWUsIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSB7XG4gIHZhciBwcm9wZXJ0eUluZm8gPSBnZXRQcm9wZXJ0eUluZm8obmFtZSk7XG5cbiAgaWYgKHNob3VsZElnbm9yZUF0dHJpYnV0ZShuYW1lLCBwcm9wZXJ0eUluZm8sIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChzaG91bGRSZW1vdmVBdHRyaWJ1dGUobmFtZSwgdmFsdWUsIHByb3BlcnR5SW5mbywgaXNDdXN0b21Db21wb25lbnRUYWcpKSB7XG4gICAgdmFsdWUgPSBudWxsO1xuICB9XG5cblxuICBpZiAoaXNDdXN0b21Db21wb25lbnRUYWcgfHwgcHJvcGVydHlJbmZvID09PSBudWxsKSB7XG4gICAgaWYgKGlzQXR0cmlidXRlTmFtZVNhZmUobmFtZSkpIHtcbiAgICAgIHZhciBfYXR0cmlidXRlTmFtZSA9IG5hbWU7XG5cbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICBub2RlLnJlbW92ZUF0dHJpYnV0ZShfYXR0cmlidXRlTmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB7XG4gICAgICAgICAgY2hlY2tBdHRyaWJ1dGVTdHJpbmdDb2VyY2lvbih2YWx1ZSwgbmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShfYXR0cmlidXRlTmFtZSwgICcnICsgdmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBtdXN0VXNlUHJvcGVydHkgPSBwcm9wZXJ0eUluZm8ubXVzdFVzZVByb3BlcnR5O1xuXG4gIGlmIChtdXN0VXNlUHJvcGVydHkpIHtcbiAgICB2YXIgcHJvcGVydHlOYW1lID0gcHJvcGVydHlJbmZvLnByb3BlcnR5TmFtZTtcblxuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgdmFyIHR5cGUgPSBwcm9wZXJ0eUluZm8udHlwZTtcbiAgICAgIG5vZGVbcHJvcGVydHlOYW1lXSA9IHR5cGUgPT09IEJPT0xFQU4gPyBmYWxzZSA6ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBDb250cmFyeSB0byBgc2V0QXR0cmlidXRlYCwgb2JqZWN0IHByb3BlcnRpZXMgYXJlIHByb3Blcmx5XG4gICAgICAvLyBgdG9TdHJpbmdgZWQgYnkgSUU4LzkuXG4gICAgICBub2RlW3Byb3BlcnR5TmFtZV0gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm47XG4gIH0gLy8gVGhlIHJlc3QgYXJlIHRyZWF0ZWQgYXMgYXR0cmlidXRlcyB3aXRoIHNwZWNpYWwgY2FzZXMuXG5cblxuICB2YXIgYXR0cmlidXRlTmFtZSA9IHByb3BlcnR5SW5mby5hdHRyaWJ1dGVOYW1lLFxuICAgICAgYXR0cmlidXRlTmFtZXNwYWNlID0gcHJvcGVydHlJbmZvLmF0dHJpYnV0ZU5hbWVzcGFjZTtcblxuICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICBub2RlLnJlbW92ZUF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgX3R5cGUgPSBwcm9wZXJ0eUluZm8udHlwZTtcbiAgICB2YXIgYXR0cmlidXRlVmFsdWU7XG5cbiAgICBpZiAoX3R5cGUgPT09IEJPT0xFQU4gfHwgX3R5cGUgPT09IE9WRVJMT0FERURfQk9PTEVBTiAmJiB2YWx1ZSA9PT0gdHJ1ZSkge1xuICAgICAgLy8gSWYgYXR0cmlidXRlIHR5cGUgaXMgYm9vbGVhbiwgd2Uga25vdyBmb3Igc3VyZSBpdCB3b24ndCBiZSBhbiBleGVjdXRpb24gc2lua1xuICAgICAgLy8gYW5kIHdlIHdvbid0IHJlcXVpcmUgVHJ1c3RlZCBUeXBlIGhlcmUuXG4gICAgICBhdHRyaWJ1dGVWYWx1ZSA9ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBgc2V0QXR0cmlidXRlYCB3aXRoIG9iamVjdHMgYmVjb21lcyBvbmx5IGBbb2JqZWN0XWAgaW4gSUU4LzksXG4gICAgICAvLyAoJycgKyB2YWx1ZSkgbWFrZXMgaXQgb3V0cHV0IHRoZSBjb3JyZWN0IHRvU3RyaW5nKCktdmFsdWUuXG4gICAgICB7XG4gICAgICAgIHtcbiAgICAgICAgICBjaGVja0F0dHJpYnV0ZVN0cmluZ0NvZXJjaW9uKHZhbHVlLCBhdHRyaWJ1dGVOYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF0dHJpYnV0ZVZhbHVlID0gJycgKyB2YWx1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHByb3BlcnR5SW5mby5zYW5pdGl6ZVVSTCkge1xuICAgICAgICBzYW5pdGl6ZVVSTChhdHRyaWJ1dGVWYWx1ZS50b1N0cmluZygpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYXR0cmlidXRlTmFtZXNwYWNlKSB7XG4gICAgICBub2RlLnNldEF0dHJpYnV0ZU5TKGF0dHJpYnV0ZU5hbWVzcGFjZSwgYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlVmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBub2RlLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCBhdHRyaWJ1dGVWYWx1ZSk7XG4gICAgfVxuICB9XG59XG5cbi8vIEFUVEVOVElPTlxuLy8gV2hlbiBhZGRpbmcgbmV3IHN5bWJvbHMgdG8gdGhpcyBmaWxlLFxuLy8gUGxlYXNlIGNvbnNpZGVyIGFsc28gYWRkaW5nIHRvICdyZWFjdC1kZXZ0b29scy1zaGFyZWQvc3JjL2JhY2tlbmQvUmVhY3RTeW1ib2xzJ1xuLy8gVGhlIFN5bWJvbCB1c2VkIHRvIHRhZyB0aGUgUmVhY3RFbGVtZW50LWxpa2UgdHlwZXMuXG52YXIgUkVBQ1RfRUxFTUVOVF9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QuZWxlbWVudCcpO1xudmFyIFJFQUNUX1BPUlRBTF9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QucG9ydGFsJyk7XG52YXIgUkVBQ1RfRlJBR01FTlRfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LmZyYWdtZW50Jyk7XG52YXIgUkVBQ1RfU1RSSUNUX01PREVfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnN0cmljdF9tb2RlJyk7XG52YXIgUkVBQ1RfUFJPRklMRVJfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnByb2ZpbGVyJyk7XG52YXIgUkVBQ1RfUFJPVklERVJfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnByb3ZpZGVyJyk7XG52YXIgUkVBQ1RfQ09OVEVYVF9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QuY29udGV4dCcpO1xudmFyIFJFQUNUX0ZPUldBUkRfUkVGX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5mb3J3YXJkX3JlZicpO1xudmFyIFJFQUNUX1NVU1BFTlNFX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5zdXNwZW5zZScpO1xudmFyIFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnN1c3BlbnNlX2xpc3QnKTtcbnZhciBSRUFDVF9NRU1PX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5tZW1vJyk7XG52YXIgUkVBQ1RfTEFaWV9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QubGF6eScpO1xudmFyIFJFQUNUX1NDT1BFX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5zY29wZScpO1xudmFyIFJFQUNUX0RFQlVHX1RSQUNJTkdfTU9ERV9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QuZGVidWdfdHJhY2VfbW9kZScpO1xudmFyIFJFQUNUX09GRlNDUkVFTl9UWVBFID0gU3ltYm9sLmZvcigncmVhY3Qub2Zmc2NyZWVuJyk7XG52YXIgUkVBQ1RfTEVHQUNZX0hJRERFTl9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QubGVnYWN5X2hpZGRlbicpO1xudmFyIFJFQUNUX0NBQ0hFX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5jYWNoZScpO1xudmFyIFJFQUNUX1RSQUNJTkdfTUFSS0VSX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC50cmFjaW5nX21hcmtlcicpO1xudmFyIE1BWUJFX0lURVJBVE9SX1NZTUJPTCA9IFN5bWJvbC5pdGVyYXRvcjtcbnZhciBGQVVYX0lURVJBVE9SX1NZTUJPTCA9ICdAQGl0ZXJhdG9yJztcbmZ1bmN0aW9uIGdldEl0ZXJhdG9yRm4obWF5YmVJdGVyYWJsZSkge1xuICBpZiAobWF5YmVJdGVyYWJsZSA9PT0gbnVsbCB8fCB0eXBlb2YgbWF5YmVJdGVyYWJsZSAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBtYXliZUl0ZXJhdG9yID0gTUFZQkVfSVRFUkFUT1JfU1lNQk9MICYmIG1heWJlSXRlcmFibGVbTUFZQkVfSVRFUkFUT1JfU1lNQk9MXSB8fCBtYXliZUl0ZXJhYmxlW0ZBVVhfSVRFUkFUT1JfU1lNQk9MXTtcblxuICBpZiAodHlwZW9mIG1heWJlSXRlcmF0b3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gbWF5YmVJdGVyYXRvcjtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG52YXIgYXNzaWduID0gT2JqZWN0LmFzc2lnbjtcblxuLy8gSGVscGVycyB0byBwYXRjaCBjb25zb2xlLmxvZ3MgdG8gYXZvaWQgbG9nZ2luZyBkdXJpbmcgc2lkZS1lZmZlY3QgZnJlZVxuLy8gcmVwbGF5aW5nIG9uIHJlbmRlciBmdW5jdGlvbi4gVGhpcyBjdXJyZW50bHkgb25seSBwYXRjaGVzIHRoZSBvYmplY3Rcbi8vIGxhemlseSB3aGljaCB3b24ndCBjb3ZlciBpZiB0aGUgbG9nIGZ1bmN0aW9uIHdhcyBleHRyYWN0ZWQgZWFnZXJseS5cbi8vIFdlIGNvdWxkIGFsc28gZWFnZXJseSBwYXRjaCB0aGUgbWV0aG9kLlxudmFyIGRpc2FibGVkRGVwdGggPSAwO1xudmFyIHByZXZMb2c7XG52YXIgcHJldkluZm87XG52YXIgcHJldldhcm47XG52YXIgcHJldkVycm9yO1xudmFyIHByZXZHcm91cDtcbnZhciBwcmV2R3JvdXBDb2xsYXBzZWQ7XG52YXIgcHJldkdyb3VwRW5kO1xuXG5mdW5jdGlvbiBkaXNhYmxlZExvZygpIHt9XG5cbmRpc2FibGVkTG9nLl9fcmVhY3REaXNhYmxlZExvZyA9IHRydWU7XG5mdW5jdGlvbiBkaXNhYmxlTG9ncygpIHtcbiAge1xuICAgIGlmIChkaXNhYmxlZERlcHRoID09PSAwKSB7XG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSByZWFjdC1pbnRlcm5hbC9uby1wcm9kdWN0aW9uLWxvZ2dpbmcgKi9cbiAgICAgIHByZXZMb2cgPSBjb25zb2xlLmxvZztcbiAgICAgIHByZXZJbmZvID0gY29uc29sZS5pbmZvO1xuICAgICAgcHJldldhcm4gPSBjb25zb2xlLndhcm47XG4gICAgICBwcmV2RXJyb3IgPSBjb25zb2xlLmVycm9yO1xuICAgICAgcHJldkdyb3VwID0gY29uc29sZS5ncm91cDtcbiAgICAgIHByZXZHcm91cENvbGxhcHNlZCA9IGNvbnNvbGUuZ3JvdXBDb2xsYXBzZWQ7XG4gICAgICBwcmV2R3JvdXBFbmQgPSBjb25zb2xlLmdyb3VwRW5kOyAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzE5MDk5XG5cbiAgICAgIHZhciBwcm9wcyA9IHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICB2YWx1ZTogZGlzYWJsZWRMb2csXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICB9OyAvLyAkRmxvd0ZpeE1lIEZsb3cgdGhpbmtzIGNvbnNvbGUgaXMgaW1tdXRhYmxlLlxuXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhjb25zb2xlLCB7XG4gICAgICAgIGluZm86IHByb3BzLFxuICAgICAgICBsb2c6IHByb3BzLFxuICAgICAgICB3YXJuOiBwcm9wcyxcbiAgICAgICAgZXJyb3I6IHByb3BzLFxuICAgICAgICBncm91cDogcHJvcHMsXG4gICAgICAgIGdyb3VwQ29sbGFwc2VkOiBwcm9wcyxcbiAgICAgICAgZ3JvdXBFbmQ6IHByb3BzXG4gICAgICB9KTtcbiAgICAgIC8qIGVzbGludC1lbmFibGUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nICovXG4gICAgfVxuXG4gICAgZGlzYWJsZWREZXB0aCsrO1xuICB9XG59XG5mdW5jdGlvbiByZWVuYWJsZUxvZ3MoKSB7XG4gIHtcbiAgICBkaXNhYmxlZERlcHRoLS07XG5cbiAgICBpZiAoZGlzYWJsZWREZXB0aCA9PT0gMCkge1xuICAgICAgLyogZXNsaW50LWRpc2FibGUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nICovXG4gICAgICB2YXIgcHJvcHMgPSB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWVcbiAgICAgIH07IC8vICRGbG93Rml4TWUgRmxvdyB0aGlua3MgY29uc29sZSBpcyBpbW11dGFibGUuXG5cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGNvbnNvbGUsIHtcbiAgICAgICAgbG9nOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZMb2dcbiAgICAgICAgfSksXG4gICAgICAgIGluZm86IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkluZm9cbiAgICAgICAgfSksXG4gICAgICAgIHdhcm46IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldldhcm5cbiAgICAgICAgfSksXG4gICAgICAgIGVycm9yOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZFcnJvclxuICAgICAgICB9KSxcbiAgICAgICAgZ3JvdXA6IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkdyb3VwXG4gICAgICAgIH0pLFxuICAgICAgICBncm91cENvbGxhcHNlZDogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2R3JvdXBDb2xsYXBzZWRcbiAgICAgICAgfSksXG4gICAgICAgIGdyb3VwRW5kOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZHcm91cEVuZFxuICAgICAgICB9KVxuICAgICAgfSk7XG4gICAgICAvKiBlc2xpbnQtZW5hYmxlIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZyAqL1xuICAgIH1cblxuICAgIGlmIChkaXNhYmxlZERlcHRoIDwgMCkge1xuICAgICAgZXJyb3IoJ2Rpc2FibGVkRGVwdGggZmVsbCBiZWxvdyB6ZXJvLiAnICsgJ1RoaXMgaXMgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfVxufVxuXG52YXIgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudERpc3BhdGNoZXI7XG52YXIgcHJlZml4O1xuZnVuY3Rpb24gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUobmFtZSwgc291cmNlLCBvd25lckZuKSB7XG4gIHtcbiAgICBpZiAocHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIEV4dHJhY3QgdGhlIFZNIHNwZWNpZmljIHByZWZpeCB1c2VkIGJ5IGVhY2ggbGluZS5cbiAgICAgIHRyeSB7XG4gICAgICAgIHRocm93IEVycm9yKCk7XG4gICAgICB9IGNhdGNoICh4KSB7XG4gICAgICAgIHZhciBtYXRjaCA9IHguc3RhY2sudHJpbSgpLm1hdGNoKC9cXG4oICooYXQgKT8pLyk7XG4gICAgICAgIHByZWZpeCA9IG1hdGNoICYmIG1hdGNoWzFdIHx8ICcnO1xuICAgICAgfVxuICAgIH0gLy8gV2UgdXNlIHRoZSBwcmVmaXggdG8gZW5zdXJlIG91ciBzdGFja3MgbGluZSB1cCB3aXRoIG5hdGl2ZSBzdGFjayBmcmFtZXMuXG5cblxuICAgIHJldHVybiAnXFxuJyArIHByZWZpeCArIG5hbWU7XG4gIH1cbn1cbnZhciByZWVudHJ5ID0gZmFsc2U7XG52YXIgY29tcG9uZW50RnJhbWVDYWNoZTtcblxue1xuICB2YXIgUG9zc2libHlXZWFrTWFwID0gdHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgPyBXZWFrTWFwIDogTWFwO1xuICBjb21wb25lbnRGcmFtZUNhY2hlID0gbmV3IFBvc3NpYmx5V2Vha01hcCgpO1xufVxuXG5mdW5jdGlvbiBkZXNjcmliZU5hdGl2ZUNvbXBvbmVudEZyYW1lKGZuLCBjb25zdHJ1Y3QpIHtcbiAgLy8gSWYgc29tZXRoaW5nIGFza2VkIGZvciBhIHN0YWNrIGluc2lkZSBhIGZha2UgcmVuZGVyLCBpdCBzaG91bGQgZ2V0IGlnbm9yZWQuXG4gIGlmICggIWZuIHx8IHJlZW50cnkpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICB7XG4gICAgdmFyIGZyYW1lID0gY29tcG9uZW50RnJhbWVDYWNoZS5nZXQoZm4pO1xuXG4gICAgaWYgKGZyYW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmcmFtZTtcbiAgICB9XG4gIH1cblxuICB2YXIgY29udHJvbDtcbiAgcmVlbnRyeSA9IHRydWU7XG4gIHZhciBwcmV2aW91c1ByZXBhcmVTdGFja1RyYWNlID0gRXJyb3IucHJlcGFyZVN0YWNrVHJhY2U7IC8vICRGbG93Rml4TWUgSXQgZG9lcyBhY2NlcHQgdW5kZWZpbmVkLlxuXG4gIEVycm9yLnByZXBhcmVTdGFja1RyYWNlID0gdW5kZWZpbmVkO1xuICB2YXIgcHJldmlvdXNEaXNwYXRjaGVyO1xuXG4gIHtcbiAgICBwcmV2aW91c0Rpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyLmN1cnJlbnQ7IC8vIFNldCB0aGUgZGlzcGF0Y2hlciBpbiBERVYgYmVjYXVzZSB0aGlzIG1pZ2h0IGJlIGNhbGwgaW4gdGhlIHJlbmRlciBmdW5jdGlvblxuICAgIC8vIGZvciB3YXJuaW5ncy5cblxuICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIuY3VycmVudCA9IG51bGw7XG4gICAgZGlzYWJsZUxvZ3MoKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gVGhpcyBzaG91bGQgdGhyb3cuXG4gICAgaWYgKGNvbnN0cnVjdCkge1xuICAgICAgLy8gU29tZXRoaW5nIHNob3VsZCBiZSBzZXR0aW5nIHRoZSBwcm9wcyBpbiB0aGUgY29uc3RydWN0b3IuXG4gICAgICB2YXIgRmFrZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoKTtcbiAgICAgIH07IC8vICRGbG93Rml4TWVcblxuXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRmFrZS5wcm90b3R5cGUsICdwcm9wcycsIHtcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgLy8gV2UgdXNlIGEgdGhyb3dpbmcgc2V0dGVyIGluc3RlYWQgb2YgZnJvemVuIG9yIG5vbi13cml0YWJsZSBwcm9wc1xuICAgICAgICAgIC8vIGJlY2F1c2UgdGhhdCB3b24ndCB0aHJvdyBpbiBhIG5vbi1zdHJpY3QgbW9kZSBmdW5jdGlvbi5cbiAgICAgICAgICB0aHJvdyBFcnJvcigpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSAnb2JqZWN0JyAmJiBSZWZsZWN0LmNvbnN0cnVjdCkge1xuICAgICAgICAvLyBXZSBjb25zdHJ1Y3QgYSBkaWZmZXJlbnQgY29udHJvbCBmb3IgdGhpcyBjYXNlIHRvIGluY2x1ZGUgYW55IGV4dHJhXG4gICAgICAgIC8vIGZyYW1lcyBhZGRlZCBieSB0aGUgY29uc3RydWN0IGNhbGwuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgUmVmbGVjdC5jb25zdHJ1Y3QoRmFrZSwgW10pO1xuICAgICAgICB9IGNhdGNoICh4KSB7XG4gICAgICAgICAgY29udHJvbCA9IHg7XG4gICAgICAgIH1cblxuICAgICAgICBSZWZsZWN0LmNvbnN0cnVjdChmbiwgW10sIEZha2UpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBGYWtlLmNhbGwoKTtcbiAgICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICAgIGNvbnRyb2wgPSB4O1xuICAgICAgICB9XG5cbiAgICAgICAgZm4uY2FsbChGYWtlLnByb3RvdHlwZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRocm93IEVycm9yKCk7XG4gICAgICB9IGNhdGNoICh4KSB7XG4gICAgICAgIGNvbnRyb2wgPSB4O1xuICAgICAgfVxuXG4gICAgICBmbigpO1xuICAgIH1cbiAgfSBjYXRjaCAoc2FtcGxlKSB7XG4gICAgLy8gVGhpcyBpcyBpbmxpbmVkIG1hbnVhbGx5IGJlY2F1c2UgY2xvc3VyZSBkb2Vzbid0IGRvIGl0IGZvciB1cy5cbiAgICBpZiAoc2FtcGxlICYmIGNvbnRyb2wgJiYgdHlwZW9mIHNhbXBsZS5zdGFjayA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIFRoaXMgZXh0cmFjdHMgdGhlIGZpcnN0IGZyYW1lIGZyb20gdGhlIHNhbXBsZSB0aGF0IGlzbid0IGFsc28gaW4gdGhlIGNvbnRyb2wuXG4gICAgICAvLyBTa2lwcGluZyBvbmUgZnJhbWUgdGhhdCB3ZSBhc3N1bWUgaXMgdGhlIGZyYW1lIHRoYXQgY2FsbHMgdGhlIHR3by5cbiAgICAgIHZhciBzYW1wbGVMaW5lcyA9IHNhbXBsZS5zdGFjay5zcGxpdCgnXFxuJyk7XG4gICAgICB2YXIgY29udHJvbExpbmVzID0gY29udHJvbC5zdGFjay5zcGxpdCgnXFxuJyk7XG4gICAgICB2YXIgcyA9IHNhbXBsZUxpbmVzLmxlbmd0aCAtIDE7XG4gICAgICB2YXIgYyA9IGNvbnRyb2xMaW5lcy5sZW5ndGggLSAxO1xuXG4gICAgICB3aGlsZSAocyA+PSAxICYmIGMgPj0gMCAmJiBzYW1wbGVMaW5lc1tzXSAhPT0gY29udHJvbExpbmVzW2NdKSB7XG4gICAgICAgIC8vIFdlIGV4cGVjdCBhdCBsZWFzdCBvbmUgc3RhY2sgZnJhbWUgdG8gYmUgc2hhcmVkLlxuICAgICAgICAvLyBUeXBpY2FsbHkgdGhpcyB3aWxsIGJlIHRoZSByb290IG1vc3Qgb25lLiBIb3dldmVyLCBzdGFjayBmcmFtZXMgbWF5IGJlXG4gICAgICAgIC8vIGN1dCBvZmYgZHVlIHRvIG1heGltdW0gc3RhY2sgbGltaXRzLiBJbiB0aGlzIGNhc2UsIG9uZSBtYXliZSBjdXQgb2ZmXG4gICAgICAgIC8vIGVhcmxpZXIgdGhhbiB0aGUgb3RoZXIuIFdlIGFzc3VtZSB0aGF0IHRoZSBzYW1wbGUgaXMgbG9uZ2VyIG9yIHRoZSBzYW1lXG4gICAgICAgIC8vIGFuZCB0aGVyZSBmb3IgY3V0IG9mZiBlYXJsaWVyLiBTbyB3ZSBzaG91bGQgZmluZCB0aGUgcm9vdCBtb3N0IGZyYW1lIGluXG4gICAgICAgIC8vIHRoZSBzYW1wbGUgc29tZXdoZXJlIGluIHRoZSBjb250cm9sLlxuICAgICAgICBjLS07XG4gICAgICB9XG5cbiAgICAgIGZvciAoOyBzID49IDEgJiYgYyA+PSAwOyBzLS0sIGMtLSkge1xuICAgICAgICAvLyBOZXh0IHdlIGZpbmQgdGhlIGZpcnN0IG9uZSB0aGF0IGlzbid0IHRoZSBzYW1lIHdoaWNoIHNob3VsZCBiZSB0aGVcbiAgICAgICAgLy8gZnJhbWUgdGhhdCBjYWxsZWQgb3VyIHNhbXBsZSBmdW5jdGlvbiBhbmQgdGhlIGNvbnRyb2wuXG4gICAgICAgIGlmIChzYW1wbGVMaW5lc1tzXSAhPT0gY29udHJvbExpbmVzW2NdKSB7XG4gICAgICAgICAgLy8gSW4gVjgsIHRoZSBmaXJzdCBsaW5lIGlzIGRlc2NyaWJpbmcgdGhlIG1lc3NhZ2UgYnV0IG90aGVyIFZNcyBkb24ndC5cbiAgICAgICAgICAvLyBJZiB3ZSdyZSBhYm91dCB0byByZXR1cm4gdGhlIGZpcnN0IGxpbmUsIGFuZCB0aGUgY29udHJvbCBpcyBhbHNvIG9uIHRoZSBzYW1lXG4gICAgICAgICAgLy8gbGluZSwgdGhhdCdzIGEgcHJldHR5IGdvb2QgaW5kaWNhdG9yIHRoYXQgb3VyIHNhbXBsZSB0aHJldyBhdCBzYW1lIGxpbmUgYXNcbiAgICAgICAgICAvLyB0aGUgY29udHJvbC4gSS5lLiBiZWZvcmUgd2UgZW50ZXJlZCB0aGUgc2FtcGxlIGZyYW1lLiBTbyB3ZSBpZ25vcmUgdGhpcyByZXN1bHQuXG4gICAgICAgICAgLy8gVGhpcyBjYW4gaGFwcGVuIGlmIHlvdSBwYXNzZWQgYSBjbGFzcyB0byBmdW5jdGlvbiBjb21wb25lbnQsIG9yIG5vbi1mdW5jdGlvbi5cbiAgICAgICAgICBpZiAocyAhPT0gMSB8fCBjICE9PSAxKSB7XG4gICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgIHMtLTtcbiAgICAgICAgICAgICAgYy0tOyAvLyBXZSBtYXkgc3RpbGwgaGF2ZSBzaW1pbGFyIGludGVybWVkaWF0ZSBmcmFtZXMgZnJvbSB0aGUgY29uc3RydWN0IGNhbGwuXG4gICAgICAgICAgICAgIC8vIFRoZSBuZXh0IG9uZSB0aGF0IGlzbid0IHRoZSBzYW1lIHNob3VsZCBiZSBvdXIgbWF0Y2ggdGhvdWdoLlxuXG4gICAgICAgICAgICAgIGlmIChjIDwgMCB8fCBzYW1wbGVMaW5lc1tzXSAhPT0gY29udHJvbExpbmVzW2NdKSB7XG4gICAgICAgICAgICAgICAgLy8gVjggYWRkcyBhIFwibmV3XCIgcHJlZml4IGZvciBuYXRpdmUgY2xhc3Nlcy4gTGV0J3MgcmVtb3ZlIGl0IHRvIG1ha2UgaXQgcHJldHRpZXIuXG4gICAgICAgICAgICAgICAgdmFyIF9mcmFtZSA9ICdcXG4nICsgc2FtcGxlTGluZXNbc10ucmVwbGFjZSgnIGF0IG5ldyAnLCAnIGF0ICcpOyAvLyBJZiBvdXIgY29tcG9uZW50IGZyYW1lIGlzIGxhYmVsZWQgXCI8YW5vbnltb3VzPlwiXG4gICAgICAgICAgICAgICAgLy8gYnV0IHdlIGhhdmUgYSB1c2VyLXByb3ZpZGVkIFwiZGlzcGxheU5hbWVcIlxuICAgICAgICAgICAgICAgIC8vIHNwbGljZSBpdCBpbiB0byBtYWtlIHRoZSBzdGFjayBtb3JlIHJlYWRhYmxlLlxuXG5cbiAgICAgICAgICAgICAgICBpZiAoZm4uZGlzcGxheU5hbWUgJiYgX2ZyYW1lLmluY2x1ZGVzKCc8YW5vbnltb3VzPicpKSB7XG4gICAgICAgICAgICAgICAgICBfZnJhbWUgPSBfZnJhbWUucmVwbGFjZSgnPGFub255bW91cz4nLCBmbi5kaXNwbGF5TmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRGcmFtZUNhY2hlLnNldChmbiwgX2ZyYW1lKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IC8vIFJldHVybiB0aGUgbGluZSB3ZSBmb3VuZC5cblxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIF9mcmFtZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSB3aGlsZSAocyA+PSAxICYmIGMgPj0gMCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZmluYWxseSB7XG4gICAgcmVlbnRyeSA9IGZhbHNlO1xuXG4gICAge1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlci5jdXJyZW50ID0gcHJldmlvdXNEaXNwYXRjaGVyO1xuICAgICAgcmVlbmFibGVMb2dzKCk7XG4gICAgfVxuXG4gICAgRXJyb3IucHJlcGFyZVN0YWNrVHJhY2UgPSBwcmV2aW91c1ByZXBhcmVTdGFja1RyYWNlO1xuICB9IC8vIEZhbGxiYWNrIHRvIGp1c3QgdXNpbmcgdGhlIG5hbWUgaWYgd2UgY291bGRuJ3QgbWFrZSBpdCB0aHJvdy5cblxuXG4gIHZhciBuYW1lID0gZm4gPyBmbi5kaXNwbGF5TmFtZSB8fCBmbi5uYW1lIDogJyc7XG4gIHZhciBzeW50aGV0aWNGcmFtZSA9IG5hbWUgPyBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZShuYW1lKSA6ICcnO1xuXG4gIHtcbiAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjb21wb25lbnRGcmFtZUNhY2hlLnNldChmbiwgc3ludGhldGljRnJhbWUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzeW50aGV0aWNGcmFtZTtcbn1cblxuZnVuY3Rpb24gZGVzY3JpYmVDbGFzc0NvbXBvbmVudEZyYW1lKGN0b3IsIHNvdXJjZSwgb3duZXJGbikge1xuICB7XG4gICAgcmV0dXJuIGRlc2NyaWJlTmF0aXZlQ29tcG9uZW50RnJhbWUoY3RvciwgdHJ1ZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGRlc2NyaWJlRnVuY3Rpb25Db21wb25lbnRGcmFtZShmbiwgc291cmNlLCBvd25lckZuKSB7XG4gIHtcbiAgICByZXR1cm4gZGVzY3JpYmVOYXRpdmVDb21wb25lbnRGcmFtZShmbiwgZmFsc2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNob3VsZENvbnN0cnVjdChDb21wb25lbnQpIHtcbiAgdmFyIHByb3RvdHlwZSA9IENvbXBvbmVudC5wcm90b3R5cGU7XG4gIHJldHVybiAhIShwcm90b3R5cGUgJiYgcHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnQpO1xufVxuXG5mdW5jdGlvbiBkZXNjcmliZVVua25vd25FbGVtZW50VHlwZUZyYW1lSW5ERVYodHlwZSwgc291cmNlLCBvd25lckZuKSB7XG5cbiAgaWYgKHR5cGUgPT0gbnVsbCkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHtcbiAgICAgIHJldHVybiBkZXNjcmliZU5hdGl2ZUNvbXBvbmVudEZyYW1lKHR5cGUsIHNob3VsZENvbnN0cnVjdCh0eXBlKSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZSh0eXBlKTtcbiAgfVxuXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfVFlQRTpcbiAgICAgIHJldHVybiBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZSgnU3VzcGVuc2UnKTtcblxuICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfTElTVF9UWVBFOlxuICAgICAgcmV0dXJuIGRlc2NyaWJlQnVpbHRJbkNvbXBvbmVudEZyYW1lKCdTdXNwZW5zZUxpc3QnKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICBzd2l0Y2ggKHR5cGUuJCR0eXBlb2YpIHtcbiAgICAgIGNhc2UgUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRTpcbiAgICAgICAgcmV0dXJuIGRlc2NyaWJlRnVuY3Rpb25Db21wb25lbnRGcmFtZSh0eXBlLnJlbmRlcik7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTUVNT19UWVBFOlxuICAgICAgICAvLyBNZW1vIG1heSBjb250YWluIGFueSBjb21wb25lbnQgdHlwZSBzbyB3ZSByZWN1cnNpdmVseSByZXNvbHZlIGl0LlxuICAgICAgICByZXR1cm4gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKHR5cGUudHlwZSwgc291cmNlLCBvd25lckZuKTtcblxuICAgICAgY2FzZSBSRUFDVF9MQVpZX1RZUEU6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgbGF6eUNvbXBvbmVudCA9IHR5cGU7XG4gICAgICAgICAgdmFyIHBheWxvYWQgPSBsYXp5Q29tcG9uZW50Ll9wYXlsb2FkO1xuICAgICAgICAgIHZhciBpbml0ID0gbGF6eUNvbXBvbmVudC5faW5pdDtcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBMYXp5IG1heSBjb250YWluIGFueSBjb21wb25lbnQgdHlwZSBzbyB3ZSByZWN1cnNpdmVseSByZXNvbHZlIGl0LlxuICAgICAgICAgICAgcmV0dXJuIGRlc2NyaWJlVW5rbm93bkVsZW1lbnRUeXBlRnJhbWVJbkRFVihpbml0KHBheWxvYWQpLCBzb3VyY2UsIG93bmVyRm4pO1xuICAgICAgICAgIH0gY2F0Y2ggKHgpIHt9XG4gICAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gJyc7XG59XG5cbmZ1bmN0aW9uIGRlc2NyaWJlRmliZXIoZmliZXIpIHtcbiAgdmFyIG93bmVyID0gIGZpYmVyLl9kZWJ1Z093bmVyID8gZmliZXIuX2RlYnVnT3duZXIudHlwZSA6IG51bGwgO1xuICB2YXIgc291cmNlID0gIGZpYmVyLl9kZWJ1Z1NvdXJjZSA7XG5cbiAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUoZmliZXIudHlwZSk7XG5cbiAgICBjYXNlIExhenlDb21wb25lbnQ6XG4gICAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUoJ0xhenknKTtcblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUoJ1N1c3BlbnNlJyk7XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHJldHVybiBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZSgnU3VzcGVuc2VMaXN0Jyk7XG5cbiAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgIGNhc2UgSW5kZXRlcm1pbmF0ZUNvbXBvbmVudDpcbiAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICByZXR1cm4gZGVzY3JpYmVGdW5jdGlvbkNvbXBvbmVudEZyYW1lKGZpYmVyLnR5cGUpO1xuXG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgICAgcmV0dXJuIGRlc2NyaWJlRnVuY3Rpb25Db21wb25lbnRGcmFtZShmaWJlci50eXBlLnJlbmRlcik7XG5cbiAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgcmV0dXJuIGRlc2NyaWJlQ2xhc3NDb21wb25lbnRGcmFtZShmaWJlci50eXBlKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gJyc7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0U3RhY2tCeUZpYmVySW5EZXZBbmRQcm9kKHdvcmtJblByb2dyZXNzKSB7XG4gIHRyeSB7XG4gICAgdmFyIGluZm8gPSAnJztcbiAgICB2YXIgbm9kZSA9IHdvcmtJblByb2dyZXNzO1xuXG4gICAgZG8ge1xuICAgICAgaW5mbyArPSBkZXNjcmliZUZpYmVyKG5vZGUpO1xuICAgICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICAgIH0gd2hpbGUgKG5vZGUpO1xuXG4gICAgcmV0dXJuIGluZm87XG4gIH0gY2F0Y2ggKHgpIHtcbiAgICByZXR1cm4gJ1xcbkVycm9yIGdlbmVyYXRpbmcgc3RhY2s6ICcgKyB4Lm1lc3NhZ2UgKyAnXFxuJyArIHguc3RhY2s7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0V3JhcHBlZE5hbWUob3V0ZXJUeXBlLCBpbm5lclR5cGUsIHdyYXBwZXJOYW1lKSB7XG4gIHZhciBkaXNwbGF5TmFtZSA9IG91dGVyVHlwZS5kaXNwbGF5TmFtZTtcblxuICBpZiAoZGlzcGxheU5hbWUpIHtcbiAgICByZXR1cm4gZGlzcGxheU5hbWU7XG4gIH1cblxuICB2YXIgZnVuY3Rpb25OYW1lID0gaW5uZXJUeXBlLmRpc3BsYXlOYW1lIHx8IGlubmVyVHlwZS5uYW1lIHx8ICcnO1xuICByZXR1cm4gZnVuY3Rpb25OYW1lICE9PSAnJyA/IHdyYXBwZXJOYW1lICsgXCIoXCIgKyBmdW5jdGlvbk5hbWUgKyBcIilcIiA6IHdyYXBwZXJOYW1lO1xufSAvLyBLZWVwIGluIHN5bmMgd2l0aCByZWFjdC1yZWNvbmNpbGVyL2dldENvbXBvbmVudE5hbWVGcm9tRmliZXJcblxuXG5mdW5jdGlvbiBnZXRDb250ZXh0TmFtZSh0eXBlKSB7XG4gIHJldHVybiB0eXBlLmRpc3BsYXlOYW1lIHx8ICdDb250ZXh0Jztcbn0gLy8gTm90ZSB0aGF0IHRoZSByZWNvbmNpbGVyIHBhY2thZ2Ugc2hvdWxkIGdlbmVyYWxseSBwcmVmZXIgdG8gdXNlIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoKSBpbnN0ZWFkLlxuXG5cbmZ1bmN0aW9uIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSh0eXBlKSB7XG4gIGlmICh0eXBlID09IG51bGwpIHtcbiAgICAvLyBIb3N0IHJvb3QsIHRleHQgbm9kZSBvciBqdXN0IGludmFsaWQgdHlwZS5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHtcbiAgICBpZiAodHlwZW9mIHR5cGUudGFnID09PSAnbnVtYmVyJykge1xuICAgICAgZXJyb3IoJ1JlY2VpdmVkIGFuIHVuZXhwZWN0ZWQgb2JqZWN0IGluIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSgpLiAnICsgJ1RoaXMgaXMgbGlrZWx5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gdHlwZS5kaXNwbGF5TmFtZSB8fCB0eXBlLm5hbWUgfHwgbnVsbDtcbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdHlwZTtcbiAgfVxuXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgUkVBQ1RfRlJBR01FTlRfVFlQRTpcbiAgICAgIHJldHVybiAnRnJhZ21lbnQnO1xuXG4gICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgIHJldHVybiAnUG9ydGFsJztcblxuICAgIGNhc2UgUkVBQ1RfUFJPRklMRVJfVFlQRTpcbiAgICAgIHJldHVybiAnUHJvZmlsZXInO1xuXG4gICAgY2FzZSBSRUFDVF9TVFJJQ1RfTU9ERV9UWVBFOlxuICAgICAgcmV0dXJuICdTdHJpY3RNb2RlJztcblxuICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfVFlQRTpcbiAgICAgIHJldHVybiAnU3VzcGVuc2UnO1xuXG4gICAgY2FzZSBSRUFDVF9TVVNQRU5TRV9MSVNUX1RZUEU6XG4gICAgICByZXR1cm4gJ1N1c3BlbnNlTGlzdCc7XG5cbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICBzd2l0Y2ggKHR5cGUuJCR0eXBlb2YpIHtcbiAgICAgIGNhc2UgUkVBQ1RfQ09OVEVYVF9UWVBFOlxuICAgICAgICB2YXIgY29udGV4dCA9IHR5cGU7XG4gICAgICAgIHJldHVybiBnZXRDb250ZXh0TmFtZShjb250ZXh0KSArICcuQ29uc3VtZXInO1xuXG4gICAgICBjYXNlIFJFQUNUX1BST1ZJREVSX1RZUEU6XG4gICAgICAgIHZhciBwcm92aWRlciA9IHR5cGU7XG4gICAgICAgIHJldHVybiBnZXRDb250ZXh0TmFtZShwcm92aWRlci5fY29udGV4dCkgKyAnLlByb3ZpZGVyJztcblxuICAgICAgY2FzZSBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFOlxuICAgICAgICByZXR1cm4gZ2V0V3JhcHBlZE5hbWUodHlwZSwgdHlwZS5yZW5kZXIsICdGb3J3YXJkUmVmJyk7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTUVNT19UWVBFOlxuICAgICAgICB2YXIgb3V0ZXJOYW1lID0gdHlwZS5kaXNwbGF5TmFtZSB8fCBudWxsO1xuXG4gICAgICAgIGlmIChvdXRlck5hbWUgIT09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gb3V0ZXJOYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSh0eXBlLnR5cGUpIHx8ICdNZW1vJztcblxuICAgICAgY2FzZSBSRUFDVF9MQVpZX1RZUEU6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgbGF6eUNvbXBvbmVudCA9IHR5cGU7XG4gICAgICAgICAgdmFyIHBheWxvYWQgPSBsYXp5Q29tcG9uZW50Ll9wYXlsb2FkO1xuICAgICAgICAgIHZhciBpbml0ID0gbGF6eUNvbXBvbmVudC5faW5pdDtcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGluaXQocGF5bG9hZCkpO1xuICAgICAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZmFsbHRocm91Z2hcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gZ2V0V3JhcHBlZE5hbWUkMShvdXRlclR5cGUsIGlubmVyVHlwZSwgd3JhcHBlck5hbWUpIHtcbiAgdmFyIGZ1bmN0aW9uTmFtZSA9IGlubmVyVHlwZS5kaXNwbGF5TmFtZSB8fCBpbm5lclR5cGUubmFtZSB8fCAnJztcbiAgcmV0dXJuIG91dGVyVHlwZS5kaXNwbGF5TmFtZSB8fCAoZnVuY3Rpb25OYW1lICE9PSAnJyA/IHdyYXBwZXJOYW1lICsgXCIoXCIgKyBmdW5jdGlvbk5hbWUgKyBcIilcIiA6IHdyYXBwZXJOYW1lKTtcbn0gLy8gS2VlcCBpbiBzeW5jIHdpdGggc2hhcmVkL2dldENvbXBvbmVudE5hbWVGcm9tVHlwZVxuXG5cbmZ1bmN0aW9uIGdldENvbnRleHROYW1lJDEodHlwZSkge1xuICByZXR1cm4gdHlwZS5kaXNwbGF5TmFtZSB8fCAnQ29udGV4dCc7XG59XG5cbmZ1bmN0aW9uIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHtcbiAgdmFyIHRhZyA9IGZpYmVyLnRhZyxcbiAgICAgIHR5cGUgPSBmaWJlci50eXBlO1xuXG4gIHN3aXRjaCAodGFnKSB7XG4gICAgY2FzZSBDYWNoZUNvbXBvbmVudDpcbiAgICAgIHJldHVybiAnQ2FjaGUnO1xuXG4gICAgY2FzZSBDb250ZXh0Q29uc3VtZXI6XG4gICAgICB2YXIgY29udGV4dCA9IHR5cGU7XG4gICAgICByZXR1cm4gZ2V0Q29udGV4dE5hbWUkMShjb250ZXh0KSArICcuQ29uc3VtZXInO1xuXG4gICAgY2FzZSBDb250ZXh0UHJvdmlkZXI6XG4gICAgICB2YXIgcHJvdmlkZXIgPSB0eXBlO1xuICAgICAgcmV0dXJuIGdldENvbnRleHROYW1lJDEocHJvdmlkZXIuX2NvbnRleHQpICsgJy5Qcm92aWRlcic7XG5cbiAgICBjYXNlIERlaHlkcmF0ZWRGcmFnbWVudDpcbiAgICAgIHJldHVybiAnRGVoeWRyYXRlZEZyYWdtZW50JztcblxuICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIHJldHVybiBnZXRXcmFwcGVkTmFtZSQxKHR5cGUsIHR5cGUucmVuZGVyLCAnRm9yd2FyZFJlZicpO1xuXG4gICAgY2FzZSBGcmFnbWVudDpcbiAgICAgIHJldHVybiAnRnJhZ21lbnQnO1xuXG4gICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAgLy8gSG9zdCBjb21wb25lbnQgdHlwZSBpcyB0aGUgZGlzcGxheSBuYW1lIChlLmcuIFwiZGl2XCIsIFwiVmlld1wiKVxuICAgICAgcmV0dXJuIHR5cGU7XG5cbiAgICBjYXNlIEhvc3RQb3J0YWw6XG4gICAgICByZXR1cm4gJ1BvcnRhbCc7XG5cbiAgICBjYXNlIEhvc3RSb290OlxuICAgICAgcmV0dXJuICdSb290JztcblxuICAgIGNhc2UgSG9zdFRleHQ6XG4gICAgICByZXR1cm4gJ1RleHQnO1xuXG4gICAgY2FzZSBMYXp5Q29tcG9uZW50OlxuICAgICAgLy8gTmFtZSBjb21lcyBmcm9tIHRoZSB0eXBlIGluIHRoaXMgY2FzZTsgd2UgZG9uJ3QgaGF2ZSBhIHRhZy5cbiAgICAgIHJldHVybiBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZSk7XG5cbiAgICBjYXNlIE1vZGU6XG4gICAgICBpZiAodHlwZSA9PT0gUkVBQ1RfU1RSSUNUX01PREVfVFlQRSkge1xuICAgICAgICAvLyBEb24ndCBiZSBsZXNzIHNwZWNpZmljIHRoYW4gc2hhcmVkL2dldENvbXBvbmVudE5hbWVGcm9tVHlwZVxuICAgICAgICByZXR1cm4gJ1N0cmljdE1vZGUnO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gJ01vZGUnO1xuXG4gICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgICByZXR1cm4gJ09mZnNjcmVlbic7XG5cbiAgICBjYXNlIFByb2ZpbGVyOlxuICAgICAgcmV0dXJuICdQcm9maWxlcic7XG5cbiAgICBjYXNlIFNjb3BlQ29tcG9uZW50OlxuICAgICAgcmV0dXJuICdTY29wZSc7XG5cbiAgICBjYXNlIFN1c3BlbnNlQ29tcG9uZW50OlxuICAgICAgcmV0dXJuICdTdXNwZW5zZSc7XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHJldHVybiAnU3VzcGVuc2VMaXN0JztcblxuICAgIGNhc2UgVHJhY2luZ01hcmtlckNvbXBvbmVudDpcbiAgICAgIHJldHVybiAnVHJhY2luZ01hcmtlcic7XG4gICAgLy8gVGhlIGRpc3BsYXkgbmFtZSBmb3IgdGhpcyB0YWdzIGNvbWUgZnJvbSB0aGUgdXNlci1wcm92aWRlZCB0eXBlOlxuXG4gICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgIGNhc2UgSW5jb21wbGV0ZUNsYXNzQ29tcG9uZW50OlxuICAgIGNhc2UgSW5kZXRlcm1pbmF0ZUNvbXBvbmVudDpcbiAgICBjYXNlIE1lbW9Db21wb25lbnQ6XG4gICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgaWYgKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiB0eXBlLmRpc3BsYXlOYW1lIHx8IHR5cGUubmFtZSB8fCBudWxsO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiB0eXBlO1xuICAgICAgfVxuXG4gICAgICBicmVhaztcblxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbnZhciBSZWFjdERlYnVnQ3VycmVudEZyYW1lID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZTtcbnZhciBjdXJyZW50ID0gbnVsbDtcbnZhciBpc1JlbmRlcmluZyA9IGZhbHNlO1xuZnVuY3Rpb24gZ2V0Q3VycmVudEZpYmVyT3duZXJOYW1lSW5EZXZPck51bGwoKSB7XG4gIHtcbiAgICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIG93bmVyID0gY3VycmVudC5fZGVidWdPd25lcjtcblxuICAgIGlmIChvd25lciAhPT0gbnVsbCAmJiB0eXBlb2Ygb3duZXIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihvd25lcik7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGdldEN1cnJlbnRGaWJlclN0YWNrSW5EZXYoKSB7XG4gIHtcbiAgICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH0gLy8gU2FmZSBiZWNhdXNlIGlmIGN1cnJlbnQgZmliZXIgZXhpc3RzLCB3ZSBhcmUgcmVjb25jaWxpbmcsXG4gICAgLy8gYW5kIGl0IGlzIGd1YXJhbnRlZWQgdG8gYmUgdGhlIHdvcmstaW4tcHJvZ3Jlc3MgdmVyc2lvbi5cblxuXG4gICAgcmV0dXJuIGdldFN0YWNrQnlGaWJlckluRGV2QW5kUHJvZChjdXJyZW50KTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXNldEN1cnJlbnRGaWJlcigpIHtcbiAge1xuICAgIFJlYWN0RGVidWdDdXJyZW50RnJhbWUuZ2V0Q3VycmVudFN0YWNrID0gbnVsbDtcbiAgICBjdXJyZW50ID0gbnVsbDtcbiAgICBpc1JlbmRlcmluZyA9IGZhbHNlO1xuICB9XG59XG5mdW5jdGlvbiBzZXRDdXJyZW50RmliZXIoZmliZXIpIHtcbiAge1xuICAgIFJlYWN0RGVidWdDdXJyZW50RnJhbWUuZ2V0Q3VycmVudFN0YWNrID0gZmliZXIgPT09IG51bGwgPyBudWxsIDogZ2V0Q3VycmVudEZpYmVyU3RhY2tJbkRldjtcbiAgICBjdXJyZW50ID0gZmliZXI7XG4gICAgaXNSZW5kZXJpbmcgPSBmYWxzZTtcbiAgfVxufVxuZnVuY3Rpb24gZ2V0Q3VycmVudEZpYmVyKCkge1xuICB7XG4gICAgcmV0dXJuIGN1cnJlbnQ7XG4gIH1cbn1cbmZ1bmN0aW9uIHNldElzUmVuZGVyaW5nKHJlbmRlcmluZykge1xuICB7XG4gICAgaXNSZW5kZXJpbmcgPSByZW5kZXJpbmc7XG4gIH1cbn1cblxuLy8gRmxvdyBkb2VzIG5vdCBhbGxvdyBzdHJpbmcgY29uY2F0ZW5hdGlvbiBvZiBtb3N0IG5vbi1zdHJpbmcgdHlwZXMuIFRvIHdvcmtcbi8vIGFyb3VuZCB0aGlzIGxpbWl0YXRpb24sIHdlIHVzZSBhbiBvcGFxdWUgdHlwZSB0aGF0IGNhbiBvbmx5IGJlIG9idGFpbmVkIGJ5XG4vLyBwYXNzaW5nIHRoZSB2YWx1ZSB0aHJvdWdoIGdldFRvU3RyaW5nVmFsdWUgZmlyc3QuXG5mdW5jdGlvbiB0b1N0cmluZyh2YWx1ZSkge1xuICAvLyBUaGUgY29lcmNpb24gc2FmZXR5IGNoZWNrIGlzIHBlcmZvcm1lZCBpbiBnZXRUb1N0cmluZ1ZhbHVlKCkuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuICByZXR1cm4gJycgKyB2YWx1ZTtcbn1cbmZ1bmN0aW9uIGdldFRvU3RyaW5nVmFsdWUodmFsdWUpIHtcbiAgc3dpdGNoICh0eXBlb2YgdmFsdWUpIHtcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICBjYXNlICdudW1iZXInOlxuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgY2FzZSAndW5kZWZpbmVkJzpcbiAgICAgIHJldHVybiB2YWx1ZTtcblxuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICB7XG4gICAgICAgIGNoZWNrRm9ybUZpZWxkVmFsdWVTdHJpbmdDb2VyY2lvbih2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB2YWx1ZTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBmdW5jdGlvbiwgc3ltYm9sIGFyZSBhc3NpZ25lZCBhcyBlbXB0eSBzdHJpbmdzXG4gICAgICByZXR1cm4gJyc7XG4gIH1cbn1cblxudmFyIGhhc1JlYWRPbmx5VmFsdWUgPSB7XG4gIGJ1dHRvbjogdHJ1ZSxcbiAgY2hlY2tib3g6IHRydWUsXG4gIGltYWdlOiB0cnVlLFxuICBoaWRkZW46IHRydWUsXG4gIHJhZGlvOiB0cnVlLFxuICByZXNldDogdHJ1ZSxcbiAgc3VibWl0OiB0cnVlXG59O1xuZnVuY3Rpb24gY2hlY2tDb250cm9sbGVkVmFsdWVQcm9wcyh0YWdOYW1lLCBwcm9wcykge1xuICB7XG4gICAgaWYgKCEoaGFzUmVhZE9ubHlWYWx1ZVtwcm9wcy50eXBlXSB8fCBwcm9wcy5vbkNoYW5nZSB8fCBwcm9wcy5vbklucHV0IHx8IHByb3BzLnJlYWRPbmx5IHx8IHByb3BzLmRpc2FibGVkIHx8IHByb3BzLnZhbHVlID09IG51bGwpKSB7XG4gICAgICBlcnJvcignWW91IHByb3ZpZGVkIGEgYHZhbHVlYCBwcm9wIHRvIGEgZm9ybSBmaWVsZCB3aXRob3V0IGFuICcgKyAnYG9uQ2hhbmdlYCBoYW5kbGVyLiBUaGlzIHdpbGwgcmVuZGVyIGEgcmVhZC1vbmx5IGZpZWxkLiBJZiAnICsgJ3RoZSBmaWVsZCBzaG91bGQgYmUgbXV0YWJsZSB1c2UgYGRlZmF1bHRWYWx1ZWAuIE90aGVyd2lzZSwgJyArICdzZXQgZWl0aGVyIGBvbkNoYW5nZWAgb3IgYHJlYWRPbmx5YC4nKTtcbiAgICB9XG5cbiAgICBpZiAoIShwcm9wcy5vbkNoYW5nZSB8fCBwcm9wcy5yZWFkT25seSB8fCBwcm9wcy5kaXNhYmxlZCB8fCBwcm9wcy5jaGVja2VkID09IG51bGwpKSB7XG4gICAgICBlcnJvcignWW91IHByb3ZpZGVkIGEgYGNoZWNrZWRgIHByb3AgdG8gYSBmb3JtIGZpZWxkIHdpdGhvdXQgYW4gJyArICdgb25DaGFuZ2VgIGhhbmRsZXIuIFRoaXMgd2lsbCByZW5kZXIgYSByZWFkLW9ubHkgZmllbGQuIElmICcgKyAndGhlIGZpZWxkIHNob3VsZCBiZSBtdXRhYmxlIHVzZSBgZGVmYXVsdENoZWNrZWRgLiBPdGhlcndpc2UsICcgKyAnc2V0IGVpdGhlciBgb25DaGFuZ2VgIG9yIGByZWFkT25seWAuJyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGlzQ2hlY2thYmxlKGVsZW0pIHtcbiAgdmFyIHR5cGUgPSBlbGVtLnR5cGU7XG4gIHZhciBub2RlTmFtZSA9IGVsZW0ubm9kZU5hbWU7XG4gIHJldHVybiBub2RlTmFtZSAmJiBub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSAnaW5wdXQnICYmICh0eXBlID09PSAnY2hlY2tib3gnIHx8IHR5cGUgPT09ICdyYWRpbycpO1xufVxuXG5mdW5jdGlvbiBnZXRUcmFja2VyKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUuX3ZhbHVlVHJhY2tlcjtcbn1cblxuZnVuY3Rpb24gZGV0YWNoVHJhY2tlcihub2RlKSB7XG4gIG5vZGUuX3ZhbHVlVHJhY2tlciA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGdldFZhbHVlRnJvbU5vZGUobm9kZSkge1xuICB2YXIgdmFsdWUgPSAnJztcblxuICBpZiAoIW5vZGUpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBpZiAoaXNDaGVja2FibGUobm9kZSkpIHtcbiAgICB2YWx1ZSA9IG5vZGUuY2hlY2tlZCA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gIH0gZWxzZSB7XG4gICAgdmFsdWUgPSBub2RlLnZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiB0cmFja1ZhbHVlT25Ob2RlKG5vZGUpIHtcbiAgdmFyIHZhbHVlRmllbGQgPSBpc0NoZWNrYWJsZShub2RlKSA/ICdjaGVja2VkJyA6ICd2YWx1ZSc7XG4gIHZhciBkZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihub2RlLmNvbnN0cnVjdG9yLnByb3RvdHlwZSwgdmFsdWVGaWVsZCk7XG5cbiAge1xuICAgIGNoZWNrRm9ybUZpZWxkVmFsdWVTdHJpbmdDb2VyY2lvbihub2RlW3ZhbHVlRmllbGRdKTtcbiAgfVxuXG4gIHZhciBjdXJyZW50VmFsdWUgPSAnJyArIG5vZGVbdmFsdWVGaWVsZF07IC8vIGlmIHNvbWVvbmUgaGFzIGFscmVhZHkgZGVmaW5lZCBhIHZhbHVlIG9yIFNhZmFyaSwgdGhlbiBiYWlsXG4gIC8vIGFuZCBkb24ndCB0cmFjayB2YWx1ZSB3aWxsIGNhdXNlIG92ZXIgcmVwb3J0aW5nIG9mIGNoYW5nZXMsXG4gIC8vIGJ1dCBpdCdzIGJldHRlciB0aGVuIGEgaGFyZCBmYWlsdXJlXG4gIC8vIChuZWVkZWQgZm9yIGNlcnRhaW4gdGVzdHMgdGhhdCBzcHlPbiBpbnB1dCB2YWx1ZXMgYW5kIFNhZmFyaSlcblxuICBpZiAobm9kZS5oYXNPd25Qcm9wZXJ0eSh2YWx1ZUZpZWxkKSB8fCB0eXBlb2YgZGVzY3JpcHRvciA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIGRlc2NyaXB0b3IuZ2V0ICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBkZXNjcmlwdG9yLnNldCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBnZXQgPSBkZXNjcmlwdG9yLmdldCxcbiAgICAgIHNldCA9IGRlc2NyaXB0b3Iuc2V0O1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkobm9kZSwgdmFsdWVGaWVsZCwge1xuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBnZXQuY2FsbCh0aGlzKTtcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICB7XG4gICAgICAgIGNoZWNrRm9ybUZpZWxkVmFsdWVTdHJpbmdDb2VyY2lvbih2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIGN1cnJlbnRWYWx1ZSA9ICcnICsgdmFsdWU7XG4gICAgICBzZXQuY2FsbCh0aGlzLCB2YWx1ZSk7XG4gICAgfVxuICB9KTsgLy8gV2UgY291bGQndmUgcGFzc2VkIHRoaXMgdGhlIGZpcnN0IHRpbWVcbiAgLy8gYnV0IGl0IHRyaWdnZXJzIGEgYnVnIGluIElFMTEgYW5kIEVkZ2UgMTQvMTUuXG4gIC8vIENhbGxpbmcgZGVmaW5lUHJvcGVydHkoKSBhZ2FpbiBzaG91bGQgYmUgZXF1aXZhbGVudC5cbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xMTc2OFxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShub2RlLCB2YWx1ZUZpZWxkLCB7XG4gICAgZW51bWVyYWJsZTogZGVzY3JpcHRvci5lbnVtZXJhYmxlXG4gIH0pO1xuICB2YXIgdHJhY2tlciA9IHtcbiAgICBnZXRWYWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIGN1cnJlbnRWYWx1ZTtcbiAgICB9LFxuICAgIHNldFZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIHtcbiAgICAgICAgY2hlY2tGb3JtRmllbGRWYWx1ZVN0cmluZ0NvZXJjaW9uKHZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgY3VycmVudFZhbHVlID0gJycgKyB2YWx1ZTtcbiAgICB9LFxuICAgIHN0b3BUcmFja2luZzogZnVuY3Rpb24gKCkge1xuICAgICAgZGV0YWNoVHJhY2tlcihub2RlKTtcbiAgICAgIGRlbGV0ZSBub2RlW3ZhbHVlRmllbGRdO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHRyYWNrZXI7XG59XG5cbmZ1bmN0aW9uIHRyYWNrKG5vZGUpIHtcbiAgaWYgKGdldFRyYWNrZXIobm9kZSkpIHtcbiAgICByZXR1cm47XG4gIH0gLy8gVE9ETzogT25jZSBpdCdzIGp1c3QgRmliZXIgd2UgY2FuIG1vdmUgdGhpcyB0byBub2RlLl93cmFwcGVyU3RhdGVcblxuXG4gIG5vZGUuX3ZhbHVlVHJhY2tlciA9IHRyYWNrVmFsdWVPbk5vZGUobm9kZSk7XG59XG5mdW5jdGlvbiB1cGRhdGVWYWx1ZUlmQ2hhbmdlZChub2RlKSB7XG4gIGlmICghbm9kZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciB0cmFja2VyID0gZ2V0VHJhY2tlcihub2RlKTsgLy8gaWYgdGhlcmUgaXMgbm8gdHJhY2tlciBhdCB0aGlzIHBvaW50IGl0J3MgdW5saWtlbHlcbiAgLy8gdGhhdCB0cnlpbmcgYWdhaW4gd2lsbCBzdWNjZWVkXG5cbiAgaWYgKCF0cmFja2VyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICB2YXIgbGFzdFZhbHVlID0gdHJhY2tlci5nZXRWYWx1ZSgpO1xuICB2YXIgbmV4dFZhbHVlID0gZ2V0VmFsdWVGcm9tTm9kZShub2RlKTtcblxuICBpZiAobmV4dFZhbHVlICE9PSBsYXN0VmFsdWUpIHtcbiAgICB0cmFja2VyLnNldFZhbHVlKG5leHRWYWx1ZSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGdldEFjdGl2ZUVsZW1lbnQoZG9jKSB7XG4gIGRvYyA9IGRvYyB8fCAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyA/IGRvY3VtZW50IDogdW5kZWZpbmVkKTtcblxuICBpZiAodHlwZW9mIGRvYyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGRvYy5hY3RpdmVFbGVtZW50IHx8IGRvYy5ib2R5O1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGRvYy5ib2R5O1xuICB9XG59XG5cbnZhciBkaWRXYXJuVmFsdWVEZWZhdWx0VmFsdWUgPSBmYWxzZTtcbnZhciBkaWRXYXJuQ2hlY2tlZERlZmF1bHRDaGVja2VkID0gZmFsc2U7XG52YXIgZGlkV2FybkNvbnRyb2xsZWRUb1VuY29udHJvbGxlZCA9IGZhbHNlO1xudmFyIGRpZFdhcm5VbmNvbnRyb2xsZWRUb0NvbnRyb2xsZWQgPSBmYWxzZTtcblxuZnVuY3Rpb24gaXNDb250cm9sbGVkKHByb3BzKSB7XG4gIHZhciB1c2VzQ2hlY2tlZCA9IHByb3BzLnR5cGUgPT09ICdjaGVja2JveCcgfHwgcHJvcHMudHlwZSA9PT0gJ3JhZGlvJztcbiAgcmV0dXJuIHVzZXNDaGVja2VkID8gcHJvcHMuY2hlY2tlZCAhPSBudWxsIDogcHJvcHMudmFsdWUgIT0gbnVsbDtcbn1cbi8qKlxuICogSW1wbGVtZW50cyBhbiA8aW5wdXQ+IGhvc3QgY29tcG9uZW50IHRoYXQgYWxsb3dzIHNldHRpbmcgdGhlc2Ugb3B0aW9uYWxcbiAqIHByb3BzOiBgY2hlY2tlZGAsIGB2YWx1ZWAsIGBkZWZhdWx0Q2hlY2tlZGAsIGFuZCBgZGVmYXVsdFZhbHVlYC5cbiAqXG4gKiBJZiBgY2hlY2tlZGAgb3IgYHZhbHVlYCBhcmUgbm90IHN1cHBsaWVkIChvciBudWxsL3VuZGVmaW5lZCksIHVzZXIgYWN0aW9uc1xuICogdGhhdCBhZmZlY3QgdGhlIGNoZWNrZWQgc3RhdGUgb3IgdmFsdWUgd2lsbCB0cmlnZ2VyIHVwZGF0ZXMgdG8gdGhlIGVsZW1lbnQuXG4gKlxuICogSWYgdGhleSBhcmUgc3VwcGxpZWQgKGFuZCBub3QgbnVsbC91bmRlZmluZWQpLCB0aGUgcmVuZGVyZWQgZWxlbWVudCB3aWxsIG5vdFxuICogdHJpZ2dlciB1cGRhdGVzIHRvIHRoZSBlbGVtZW50LiBJbnN0ZWFkLCB0aGUgcHJvcHMgbXVzdCBjaGFuZ2UgaW4gb3JkZXIgZm9yXG4gKiB0aGUgcmVuZGVyZWQgZWxlbWVudCB0byBiZSB1cGRhdGVkLlxuICpcbiAqIFRoZSByZW5kZXJlZCBlbGVtZW50IHdpbGwgYmUgaW5pdGlhbGl6ZWQgYXMgdW5jaGVja2VkIChvciBgZGVmYXVsdENoZWNrZWRgKVxuICogd2l0aCBhbiBlbXB0eSB2YWx1ZSAob3IgYGRlZmF1bHRWYWx1ZWApLlxuICpcbiAqIFNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDEyL1dELWh0bWw1LTIwMTIxMDI1L3RoZS1pbnB1dC1lbGVtZW50Lmh0bWxcbiAqL1xuXG5cbmZ1bmN0aW9uIGdldEhvc3RQcm9wcyhlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7XG4gIHZhciBjaGVja2VkID0gcHJvcHMuY2hlY2tlZDtcbiAgdmFyIGhvc3RQcm9wcyA9IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICBkZWZhdWx0Q2hlY2tlZDogdW5kZWZpbmVkLFxuICAgIGRlZmF1bHRWYWx1ZTogdW5kZWZpbmVkLFxuICAgIHZhbHVlOiB1bmRlZmluZWQsXG4gICAgY2hlY2tlZDogY2hlY2tlZCAhPSBudWxsID8gY2hlY2tlZCA6IG5vZGUuX3dyYXBwZXJTdGF0ZS5pbml0aWFsQ2hlY2tlZFxuICB9KTtcbiAgcmV0dXJuIGhvc3RQcm9wcztcbn1cbmZ1bmN0aW9uIGluaXRXcmFwcGVyU3RhdGUoZWxlbWVudCwgcHJvcHMpIHtcbiAge1xuICAgIGNoZWNrQ29udHJvbGxlZFZhbHVlUHJvcHMoJ2lucHV0JywgcHJvcHMpO1xuXG4gICAgaWYgKHByb3BzLmNoZWNrZWQgIT09IHVuZGVmaW5lZCAmJiBwcm9wcy5kZWZhdWx0Q2hlY2tlZCAhPT0gdW5kZWZpbmVkICYmICFkaWRXYXJuQ2hlY2tlZERlZmF1bHRDaGVja2VkKSB7XG4gICAgICBlcnJvcignJXMgY29udGFpbnMgYW4gaW5wdXQgb2YgdHlwZSAlcyB3aXRoIGJvdGggY2hlY2tlZCBhbmQgZGVmYXVsdENoZWNrZWQgcHJvcHMuICcgKyAnSW5wdXQgZWxlbWVudHMgbXVzdCBiZSBlaXRoZXIgY29udHJvbGxlZCBvciB1bmNvbnRyb2xsZWQgJyArICcoc3BlY2lmeSBlaXRoZXIgdGhlIGNoZWNrZWQgcHJvcCwgb3IgdGhlIGRlZmF1bHRDaGVja2VkIHByb3AsIGJ1dCBub3QgJyArICdib3RoKS4gRGVjaWRlIGJldHdlZW4gdXNpbmcgYSBjb250cm9sbGVkIG9yIHVuY29udHJvbGxlZCBpbnB1dCAnICsgJ2VsZW1lbnQgYW5kIHJlbW92ZSBvbmUgb2YgdGhlc2UgcHJvcHMuIE1vcmUgaW5mbzogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvY29udHJvbGxlZC1jb21wb25lbnRzJywgZ2V0Q3VycmVudEZpYmVyT3duZXJOYW1lSW5EZXZPck51bGwoKSB8fCAnQSBjb21wb25lbnQnLCBwcm9wcy50eXBlKTtcblxuICAgICAgZGlkV2FybkNoZWNrZWREZWZhdWx0Q2hlY2tlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnZhbHVlICE9PSB1bmRlZmluZWQgJiYgcHJvcHMuZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQgJiYgIWRpZFdhcm5WYWx1ZURlZmF1bHRWYWx1ZSkge1xuICAgICAgZXJyb3IoJyVzIGNvbnRhaW5zIGFuIGlucHV0IG9mIHR5cGUgJXMgd2l0aCBib3RoIHZhbHVlIGFuZCBkZWZhdWx0VmFsdWUgcHJvcHMuICcgKyAnSW5wdXQgZWxlbWVudHMgbXVzdCBiZSBlaXRoZXIgY29udHJvbGxlZCBvciB1bmNvbnRyb2xsZWQgJyArICcoc3BlY2lmeSBlaXRoZXIgdGhlIHZhbHVlIHByb3AsIG9yIHRoZSBkZWZhdWx0VmFsdWUgcHJvcCwgYnV0IG5vdCAnICsgJ2JvdGgpLiBEZWNpZGUgYmV0d2VlbiB1c2luZyBhIGNvbnRyb2xsZWQgb3IgdW5jb250cm9sbGVkIGlucHV0ICcgKyAnZWxlbWVudCBhbmQgcmVtb3ZlIG9uZSBvZiB0aGVzZSBwcm9wcy4gTW9yZSBpbmZvOiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9jb250cm9sbGVkLWNvbXBvbmVudHMnLCBnZXRDdXJyZW50RmliZXJPd25lck5hbWVJbkRldk9yTnVsbCgpIHx8ICdBIGNvbXBvbmVudCcsIHByb3BzLnR5cGUpO1xuXG4gICAgICBkaWRXYXJuVmFsdWVEZWZhdWx0VmFsdWUgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHZhciBub2RlID0gZWxlbWVudDtcbiAgdmFyIGRlZmF1bHRWYWx1ZSA9IHByb3BzLmRlZmF1bHRWYWx1ZSA9PSBudWxsID8gJycgOiBwcm9wcy5kZWZhdWx0VmFsdWU7XG4gIG5vZGUuX3dyYXBwZXJTdGF0ZSA9IHtcbiAgICBpbml0aWFsQ2hlY2tlZDogcHJvcHMuY2hlY2tlZCAhPSBudWxsID8gcHJvcHMuY2hlY2tlZCA6IHByb3BzLmRlZmF1bHRDaGVja2VkLFxuICAgIGluaXRpYWxWYWx1ZTogZ2V0VG9TdHJpbmdWYWx1ZShwcm9wcy52YWx1ZSAhPSBudWxsID8gcHJvcHMudmFsdWUgOiBkZWZhdWx0VmFsdWUpLFxuICAgIGNvbnRyb2xsZWQ6IGlzQ29udHJvbGxlZChwcm9wcylcbiAgfTtcbn1cbmZ1bmN0aW9uIHVwZGF0ZUNoZWNrZWQoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50O1xuICB2YXIgY2hlY2tlZCA9IHByb3BzLmNoZWNrZWQ7XG5cbiAgaWYgKGNoZWNrZWQgIT0gbnVsbCkge1xuICAgIHNldFZhbHVlRm9yUHJvcGVydHkobm9kZSwgJ2NoZWNrZWQnLCBjaGVja2VkLCBmYWxzZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIHVwZGF0ZVdyYXBwZXIoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50O1xuXG4gIHtcbiAgICB2YXIgY29udHJvbGxlZCA9IGlzQ29udHJvbGxlZChwcm9wcyk7XG5cbiAgICBpZiAoIW5vZGUuX3dyYXBwZXJTdGF0ZS5jb250cm9sbGVkICYmIGNvbnRyb2xsZWQgJiYgIWRpZFdhcm5VbmNvbnRyb2xsZWRUb0NvbnRyb2xsZWQpIHtcbiAgICAgIGVycm9yKCdBIGNvbXBvbmVudCBpcyBjaGFuZ2luZyBhbiB1bmNvbnRyb2xsZWQgaW5wdXQgdG8gYmUgY29udHJvbGxlZC4gJyArICdUaGlzIGlzIGxpa2VseSBjYXVzZWQgYnkgdGhlIHZhbHVlIGNoYW5naW5nIGZyb20gdW5kZWZpbmVkIHRvICcgKyAnYSBkZWZpbmVkIHZhbHVlLCB3aGljaCBzaG91bGQgbm90IGhhcHBlbi4gJyArICdEZWNpZGUgYmV0d2VlbiB1c2luZyBhIGNvbnRyb2xsZWQgb3IgdW5jb250cm9sbGVkIGlucHV0ICcgKyAnZWxlbWVudCBmb3IgdGhlIGxpZmV0aW1lIG9mIHRoZSBjb21wb25lbnQuIE1vcmUgaW5mbzogaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL2NvbnRyb2xsZWQtY29tcG9uZW50cycpO1xuXG4gICAgICBkaWRXYXJuVW5jb250cm9sbGVkVG9Db250cm9sbGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAobm9kZS5fd3JhcHBlclN0YXRlLmNvbnRyb2xsZWQgJiYgIWNvbnRyb2xsZWQgJiYgIWRpZFdhcm5Db250cm9sbGVkVG9VbmNvbnRyb2xsZWQpIHtcbiAgICAgIGVycm9yKCdBIGNvbXBvbmVudCBpcyBjaGFuZ2luZyBhIGNvbnRyb2xsZWQgaW5wdXQgdG8gYmUgdW5jb250cm9sbGVkLiAnICsgJ1RoaXMgaXMgbGlrZWx5IGNhdXNlZCBieSB0aGUgdmFsdWUgY2hhbmdpbmcgZnJvbSBhIGRlZmluZWQgdG8gJyArICd1bmRlZmluZWQsIHdoaWNoIHNob3VsZCBub3QgaGFwcGVuLiAnICsgJ0RlY2lkZSBiZXR3ZWVuIHVzaW5nIGEgY29udHJvbGxlZCBvciB1bmNvbnRyb2xsZWQgaW5wdXQgJyArICdlbGVtZW50IGZvciB0aGUgbGlmZXRpbWUgb2YgdGhlIGNvbXBvbmVudC4gTW9yZSBpbmZvOiBodHRwczovL3JlYWN0anMub3JnL2xpbmsvY29udHJvbGxlZC1jb21wb25lbnRzJyk7XG5cbiAgICAgIGRpZFdhcm5Db250cm9sbGVkVG9VbmNvbnRyb2xsZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUNoZWNrZWQoZWxlbWVudCwgcHJvcHMpO1xuICB2YXIgdmFsdWUgPSBnZXRUb1N0cmluZ1ZhbHVlKHByb3BzLnZhbHVlKTtcbiAgdmFyIHR5cGUgPSBwcm9wcy50eXBlO1xuXG4gIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgaWYgKHR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICBpZiAodmFsdWUgPT09IDAgJiYgbm9kZS52YWx1ZSA9PT0gJycgfHwgLy8gV2UgZXhwbGljaXRseSB3YW50IHRvIGNvZXJjZSB0byBudW1iZXIgaGVyZSBpZiBwb3NzaWJsZS5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgbm9kZS52YWx1ZSAhPSB2YWx1ZSkge1xuICAgICAgICBub2RlLnZhbHVlID0gdG9TdHJpbmcodmFsdWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobm9kZS52YWx1ZSAhPT0gdG9TdHJpbmcodmFsdWUpKSB7XG4gICAgICBub2RlLnZhbHVlID0gdG9TdHJpbmcodmFsdWUpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3VibWl0JyB8fCB0eXBlID09PSAncmVzZXQnKSB7XG4gICAgLy8gU3VibWl0L3Jlc2V0IGlucHV0cyBuZWVkIHRoZSBhdHRyaWJ1dGUgcmVtb3ZlZCBjb21wbGV0ZWx5IHRvIGF2b2lkXG4gICAgLy8gYmxhbmstdGV4dCBidXR0b25zLlxuICAgIG5vZGUucmVtb3ZlQXR0cmlidXRlKCd2YWx1ZScpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHtcbiAgICAvLyBXaGVuIHN5bmNpbmcgdGhlIHZhbHVlIGF0dHJpYnV0ZSwgdGhlIHZhbHVlIGNvbWVzIGZyb20gYSBjYXNjYWRlIG9mXG4gICAgLy8gcHJvcGVydGllczpcbiAgICAvLyAgMS4gVGhlIHZhbHVlIFJlYWN0IHByb3BlcnR5XG4gICAgLy8gIDIuIFRoZSBkZWZhdWx0VmFsdWUgUmVhY3QgcHJvcGVydHlcbiAgICAvLyAgMy4gT3RoZXJ3aXNlIHRoZXJlIHNob3VsZCBiZSBubyBjaGFuZ2VcbiAgICBpZiAocHJvcHMuaGFzT3duUHJvcGVydHkoJ3ZhbHVlJykpIHtcbiAgICAgIHNldERlZmF1bHRWYWx1ZShub2RlLCBwcm9wcy50eXBlLCB2YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChwcm9wcy5oYXNPd25Qcm9wZXJ0eSgnZGVmYXVsdFZhbHVlJykpIHtcbiAgICAgIHNldERlZmF1bHRWYWx1ZShub2RlLCBwcm9wcy50eXBlLCBnZXRUb1N0cmluZ1ZhbHVlKHByb3BzLmRlZmF1bHRWYWx1ZSkpO1xuICAgIH1cbiAgfVxuXG4gIHtcbiAgICAvLyBXaGVuIHN5bmNpbmcgdGhlIGNoZWNrZWQgYXR0cmlidXRlLCBpdCBvbmx5IGNoYW5nZXMgd2hlbiBpdCBuZWVkc1xuICAgIC8vIHRvIGJlIHJlbW92ZWQsIHN1Y2ggYXMgdHJhbnNpdGlvbmluZyBmcm9tIGEgY2hlY2tib3ggaW50byBhIHRleHQgaW5wdXRcbiAgICBpZiAocHJvcHMuY2hlY2tlZCA9PSBudWxsICYmIHByb3BzLmRlZmF1bHRDaGVja2VkICE9IG51bGwpIHtcbiAgICAgIG5vZGUuZGVmYXVsdENoZWNrZWQgPSAhIXByb3BzLmRlZmF1bHRDaGVja2VkO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gcG9zdE1vdW50V3JhcHBlcihlbGVtZW50LCBwcm9wcywgaXNIeWRyYXRpbmcpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50OyAvLyBEbyBub3QgYXNzaWduIHZhbHVlIGlmIGl0IGlzIGFscmVhZHkgc2V0LiBUaGlzIHByZXZlbnRzIHVzZXIgdGV4dCBpbnB1dFxuICAvLyBmcm9tIGJlaW5nIGxvc3QgZHVyaW5nIFNTUiBoeWRyYXRpb24uXG5cbiAgaWYgKHByb3BzLmhhc093blByb3BlcnR5KCd2YWx1ZScpIHx8IHByb3BzLmhhc093blByb3BlcnR5KCdkZWZhdWx0VmFsdWUnKSkge1xuICAgIHZhciB0eXBlID0gcHJvcHMudHlwZTtcbiAgICB2YXIgaXNCdXR0b24gPSB0eXBlID09PSAnc3VibWl0JyB8fCB0eXBlID09PSAncmVzZXQnOyAvLyBBdm9pZCBzZXR0aW5nIHZhbHVlIGF0dHJpYnV0ZSBvbiBzdWJtaXQvcmVzZXQgaW5wdXRzIGFzIGl0IG92ZXJyaWRlcyB0aGVcbiAgICAvLyBkZWZhdWx0IHZhbHVlIHByb3ZpZGVkIGJ5IHRoZSBicm93c2VyLiBTZWU6ICMxMjg3MlxuXG4gICAgaWYgKGlzQnV0dG9uICYmIChwcm9wcy52YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHByb3BzLnZhbHVlID09PSBudWxsKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBpbml0aWFsVmFsdWUgPSB0b1N0cmluZyhub2RlLl93cmFwcGVyU3RhdGUuaW5pdGlhbFZhbHVlKTsgLy8gRG8gbm90IGFzc2lnbiB2YWx1ZSBpZiBpdCBpcyBhbHJlYWR5IHNldC4gVGhpcyBwcmV2ZW50cyB1c2VyIHRleHQgaW5wdXRcbiAgICAvLyBmcm9tIGJlaW5nIGxvc3QgZHVyaW5nIFNTUiBoeWRyYXRpb24uXG5cbiAgICBpZiAoIWlzSHlkcmF0aW5nKSB7XG4gICAgICB7XG4gICAgICAgIC8vIFdoZW4gc3luY2luZyB0aGUgdmFsdWUgYXR0cmlidXRlLCB0aGUgdmFsdWUgcHJvcGVydHkgc2hvdWxkIHVzZVxuICAgICAgICAvLyB0aGUgd3JhcHBlclN0YXRlLl9pbml0aWFsVmFsdWUgcHJvcGVydHkuIFRoaXMgdXNlczpcbiAgICAgICAgLy9cbiAgICAgICAgLy8gICAxLiBUaGUgdmFsdWUgUmVhY3QgcHJvcGVydHkgd2hlbiBwcmVzZW50XG4gICAgICAgIC8vICAgMi4gVGhlIGRlZmF1bHRWYWx1ZSBSZWFjdCBwcm9wZXJ0eSB3aGVuIHByZXNlbnRcbiAgICAgICAgLy8gICAzLiBBbiBlbXB0eSBzdHJpbmdcbiAgICAgICAgaWYgKGluaXRpYWxWYWx1ZSAhPT0gbm9kZS52YWx1ZSkge1xuICAgICAgICAgIG5vZGUudmFsdWUgPSBpbml0aWFsVmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB7XG4gICAgICAvLyBPdGhlcndpc2UsIHRoZSB2YWx1ZSBhdHRyaWJ1dGUgaXMgc3luY2hyb25pemVkIHRvIHRoZSBwcm9wZXJ0eSxcbiAgICAgIC8vIHNvIHdlIGFzc2lnbiBkZWZhdWx0VmFsdWUgdG8gdGhlIHNhbWUgdGhpbmcgYXMgdGhlIHZhbHVlIHByb3BlcnR5XG4gICAgICAvLyBhc3NpZ25tZW50IHN0ZXAgYWJvdmUuXG4gICAgICBub2RlLmRlZmF1bHRWYWx1ZSA9IGluaXRpYWxWYWx1ZTtcbiAgICB9XG4gIH0gLy8gTm9ybWFsbHksIHdlJ2QganVzdCBkbyBgbm9kZS5jaGVja2VkID0gbm9kZS5jaGVja2VkYCB1cG9uIGluaXRpYWwgbW91bnQsIGxlc3MgdGhpcyBidWdcbiAgLy8gdGhpcyBpcyBuZWVkZWQgdG8gd29yayBhcm91bmQgYSBjaHJvbWUgYnVnIHdoZXJlIHNldHRpbmcgZGVmYXVsdENoZWNrZWRcbiAgLy8gd2lsbCBzb21ldGltZXMgaW5mbHVlbmNlIHRoZSB2YWx1ZSBvZiBjaGVja2VkIChldmVuIGFmdGVyIGRldGFjaG1lbnQpLlxuICAvLyBSZWZlcmVuY2U6IGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTYwODQxNlxuICAvLyBXZSBuZWVkIHRvIHRlbXBvcmFyaWx5IHVuc2V0IG5hbWUgdG8gYXZvaWQgZGlzcnVwdGluZyByYWRpbyBidXR0b24gZ3JvdXBzLlxuXG5cbiAgdmFyIG5hbWUgPSBub2RlLm5hbWU7XG5cbiAgaWYgKG5hbWUgIT09ICcnKSB7XG4gICAgbm9kZS5uYW1lID0gJyc7XG4gIH1cblxuICB7XG4gICAgLy8gV2hlbiBzeW5jaW5nIHRoZSBjaGVja2VkIGF0dHJpYnV0ZSwgYm90aCB0aGUgY2hlY2tlZCBwcm9wZXJ0eSBhbmRcbiAgICAvLyBhdHRyaWJ1dGUgYXJlIGFzc2lnbmVkIGF0IHRoZSBzYW1lIHRpbWUgdXNpbmcgZGVmYXVsdENoZWNrZWQuIFRoaXMgdXNlczpcbiAgICAvL1xuICAgIC8vICAgMS4gVGhlIGNoZWNrZWQgUmVhY3QgcHJvcGVydHkgd2hlbiBwcmVzZW50XG4gICAgLy8gICAyLiBUaGUgZGVmYXVsdENoZWNrZWQgUmVhY3QgcHJvcGVydHkgd2hlbiBwcmVzZW50XG4gICAgLy8gICAzLiBPdGhlcndpc2UsIGZhbHNlXG4gICAgbm9kZS5kZWZhdWx0Q2hlY2tlZCA9ICFub2RlLmRlZmF1bHRDaGVja2VkO1xuICAgIG5vZGUuZGVmYXVsdENoZWNrZWQgPSAhIW5vZGUuX3dyYXBwZXJTdGF0ZS5pbml0aWFsQ2hlY2tlZDtcbiAgfVxuXG4gIGlmIChuYW1lICE9PSAnJykge1xuICAgIG5vZGUubmFtZSA9IG5hbWU7XG4gIH1cbn1cbmZ1bmN0aW9uIHJlc3RvcmVDb250cm9sbGVkU3RhdGUoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50O1xuICB1cGRhdGVXcmFwcGVyKG5vZGUsIHByb3BzKTtcbiAgdXBkYXRlTmFtZWRDb3VzaW5zKG5vZGUsIHByb3BzKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlTmFtZWRDb3VzaW5zKHJvb3ROb2RlLCBwcm9wcykge1xuICB2YXIgbmFtZSA9IHByb3BzLm5hbWU7XG5cbiAgaWYgKHByb3BzLnR5cGUgPT09ICdyYWRpbycgJiYgbmFtZSAhPSBudWxsKSB7XG4gICAgdmFyIHF1ZXJ5Um9vdCA9IHJvb3ROb2RlO1xuXG4gICAgd2hpbGUgKHF1ZXJ5Um9vdC5wYXJlbnROb2RlKSB7XG4gICAgICBxdWVyeVJvb3QgPSBxdWVyeVJvb3QucGFyZW50Tm9kZTtcbiAgICB9IC8vIElmIGByb290Tm9kZS5mb3JtYCB3YXMgbm9uLW51bGwsIHRoZW4gd2UgY291bGQgdHJ5IGBmb3JtLmVsZW1lbnRzYCxcbiAgICAvLyBidXQgdGhhdCBzb21ldGltZXMgYmVoYXZlcyBzdHJhbmdlbHkgaW4gSUU4LiBXZSBjb3VsZCBhbHNvIHRyeSB1c2luZ1xuICAgIC8vIGBmb3JtLmdldEVsZW1lbnRzQnlOYW1lYCwgYnV0IHRoYXQgd2lsbCBvbmx5IHJldHVybiBkaXJlY3QgY2hpbGRyZW5cbiAgICAvLyBhbmQgd29uJ3QgaW5jbHVkZSBpbnB1dHMgdGhhdCB1c2UgdGhlIEhUTUw1IGBmb3JtPWAgYXR0cmlidXRlLiBTaW5jZVxuICAgIC8vIHRoZSBpbnB1dCBtaWdodCBub3QgZXZlbiBiZSBpbiBhIGZvcm0uIEl0IG1pZ2h0IG5vdCBldmVuIGJlIGluIHRoZVxuICAgIC8vIGRvY3VtZW50LiBMZXQncyBqdXN0IHVzZSB0aGUgbG9jYWwgYHF1ZXJ5U2VsZWN0b3JBbGxgIHRvIGVuc3VyZSB3ZSBkb24ndFxuICAgIC8vIG1pc3MgYW55dGhpbmcuXG5cblxuICAgIHtcbiAgICAgIGNoZWNrQXR0cmlidXRlU3RyaW5nQ29lcmNpb24obmFtZSwgJ25hbWUnKTtcbiAgICB9XG5cbiAgICB2YXIgZ3JvdXAgPSBxdWVyeVJvb3QucXVlcnlTZWxlY3RvckFsbCgnaW5wdXRbbmFtZT0nICsgSlNPTi5zdHJpbmdpZnkoJycgKyBuYW1lKSArICddW3R5cGU9XCJyYWRpb1wiXScpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBncm91cC5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIG90aGVyTm9kZSA9IGdyb3VwW2ldO1xuXG4gICAgICBpZiAob3RoZXJOb2RlID09PSByb290Tm9kZSB8fCBvdGhlck5vZGUuZm9ybSAhPT0gcm9vdE5vZGUuZm9ybSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH0gLy8gVGhpcyB3aWxsIHRocm93IGlmIHJhZGlvIGJ1dHRvbnMgcmVuZGVyZWQgYnkgZGlmZmVyZW50IGNvcGllcyBvZiBSZWFjdFxuICAgICAgLy8gYW5kIHRoZSBzYW1lIG5hbWUgYXJlIHJlbmRlcmVkIGludG8gdGhlIHNhbWUgZm9ybSAoc2FtZSBhcyAjMTkzOSkuXG4gICAgICAvLyBUaGF0J3MgcHJvYmFibHkgb2theTsgd2UgZG9uJ3Qgc3VwcG9ydCBpdCBqdXN0IGFzIHdlIGRvbid0IHN1cHBvcnRcbiAgICAgIC8vIG1peGluZyBSZWFjdCByYWRpbyBidXR0b25zIHdpdGggbm9uLVJlYWN0IG9uZXMuXG5cblxuICAgICAgdmFyIG90aGVyUHJvcHMgPSBnZXRGaWJlckN1cnJlbnRQcm9wc0Zyb21Ob2RlKG90aGVyTm9kZSk7XG5cbiAgICAgIGlmICghb3RoZXJQcm9wcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlYWN0RE9NSW5wdXQ6IE1peGluZyBSZWFjdCBhbmQgbm9uLVJlYWN0IHJhZGlvIGlucHV0cyB3aXRoIHRoZSAnICsgJ3NhbWUgYG5hbWVgIGlzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgICB9IC8vIFdlIG5lZWQgdXBkYXRlIHRoZSB0cmFja2VkIHZhbHVlIG9uIHRoZSBuYW1lZCBjb3VzaW4gc2luY2UgdGhlIHZhbHVlXG4gICAgICAvLyB3YXMgY2hhbmdlZCBidXQgdGhlIGlucHV0IHNhdyBubyBldmVudCBvciB2YWx1ZSBzZXRcblxuXG4gICAgICB1cGRhdGVWYWx1ZUlmQ2hhbmdlZChvdGhlck5vZGUpOyAvLyBJZiB0aGlzIGlzIGEgY29udHJvbGxlZCByYWRpbyBidXR0b24gZ3JvdXAsIGZvcmNpbmcgdGhlIGlucHV0IHRoYXRcbiAgICAgIC8vIHdhcyBwcmV2aW91c2x5IGNoZWNrZWQgdG8gdXBkYXRlIHdpbGwgY2F1c2UgaXQgdG8gYmUgY29tZSByZS1jaGVja2VkXG4gICAgICAvLyBhcyBhcHByb3ByaWF0ZS5cblxuICAgICAgdXBkYXRlV3JhcHBlcihvdGhlck5vZGUsIG90aGVyUHJvcHMpO1xuICAgIH1cbiAgfVxufSAvLyBJbiBDaHJvbWUsIGFzc2lnbmluZyBkZWZhdWx0VmFsdWUgdG8gY2VydGFpbiBpbnB1dCB0eXBlcyB0cmlnZ2VycyBpbnB1dCB2YWxpZGF0aW9uLlxuLy8gRm9yIG51bWJlciBpbnB1dHMsIHRoZSBkaXNwbGF5IHZhbHVlIGxvc2VzIHRyYWlsaW5nIGRlY2ltYWwgcG9pbnRzLiBGb3IgZW1haWwgaW5wdXRzLFxuLy8gQ2hyb21lIHJhaXNlcyBcIlRoZSBzcGVjaWZpZWQgdmFsdWUgPHg+IGlzIG5vdCBhIHZhbGlkIGVtYWlsIGFkZHJlc3NcIi5cbi8vXG4vLyBIZXJlIHdlIGNoZWNrIHRvIHNlZSBpZiB0aGUgZGVmYXVsdFZhbHVlIGhhcyBhY3R1YWxseSBjaGFuZ2VkLCBhdm9pZGluZyB0aGVzZSBwcm9ibGVtc1xuLy8gd2hlbiB0aGUgdXNlciBpcyBpbnB1dHRpbmcgdGV4dFxuLy9cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvNzI1M1xuXG5cbmZ1bmN0aW9uIHNldERlZmF1bHRWYWx1ZShub2RlLCB0eXBlLCB2YWx1ZSkge1xuICBpZiAoIC8vIEZvY3VzZWQgbnVtYmVyIGlucHV0cyBzeW5jaHJvbml6ZSBvbiBibHVyLiBTZWUgQ2hhbmdlRXZlbnRQbHVnaW4uanNcbiAgdHlwZSAhPT0gJ251bWJlcicgfHwgZ2V0QWN0aXZlRWxlbWVudChub2RlLm93bmVyRG9jdW1lbnQpICE9PSBub2RlKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgIG5vZGUuZGVmYXVsdFZhbHVlID0gdG9TdHJpbmcobm9kZS5fd3JhcHBlclN0YXRlLmluaXRpYWxWYWx1ZSk7XG4gICAgfSBlbHNlIGlmIChub2RlLmRlZmF1bHRWYWx1ZSAhPT0gdG9TdHJpbmcodmFsdWUpKSB7XG4gICAgICBub2RlLmRlZmF1bHRWYWx1ZSA9IHRvU3RyaW5nKHZhbHVlKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIGRpZFdhcm5TZWxlY3RlZFNldE9uT3B0aW9uID0gZmFsc2U7XG52YXIgZGlkV2FybkludmFsaWRDaGlsZCA9IGZhbHNlO1xudmFyIGRpZFdhcm5JbnZhbGlkSW5uZXJIVE1MID0gZmFsc2U7XG4vKipcbiAqIEltcGxlbWVudHMgYW4gPG9wdGlvbj4gaG9zdCBjb21wb25lbnQgdGhhdCB3YXJucyB3aGVuIGBzZWxlY3RlZGAgaXMgc2V0LlxuICovXG5cbmZ1bmN0aW9uIHZhbGlkYXRlUHJvcHMoZWxlbWVudCwgcHJvcHMpIHtcbiAge1xuICAgIC8vIElmIGEgdmFsdWUgaXMgbm90IHByb3ZpZGVkLCB0aGVuIHRoZSBjaGlsZHJlbiBtdXN0IGJlIHNpbXBsZS5cbiAgICBpZiAocHJvcHMudmFsdWUgPT0gbnVsbCkge1xuICAgICAgaWYgKHR5cGVvZiBwcm9wcy5jaGlsZHJlbiA9PT0gJ29iamVjdCcgJiYgcHJvcHMuY2hpbGRyZW4gIT09IG51bGwpIHtcbiAgICAgICAgUmVhY3QuQ2hpbGRyZW4uZm9yRWFjaChwcm9wcy5jaGlsZHJlbiwgZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgaWYgKGNoaWxkID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGNoaWxkID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgY2hpbGQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFkaWRXYXJuSW52YWxpZENoaWxkKSB7XG4gICAgICAgICAgICBkaWRXYXJuSW52YWxpZENoaWxkID0gdHJ1ZTtcblxuICAgICAgICAgICAgZXJyb3IoJ0Nhbm5vdCBpbmZlciB0aGUgb3B0aW9uIHZhbHVlIG9mIGNvbXBsZXggY2hpbGRyZW4uICcgKyAnUGFzcyBhIGB2YWx1ZWAgcHJvcCBvciB1c2UgYSBwbGFpbiBzdHJpbmcgYXMgY2hpbGRyZW4gdG8gPG9wdGlvbj4uJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAocHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwgIT0gbnVsbCkge1xuICAgICAgICBpZiAoIWRpZFdhcm5JbnZhbGlkSW5uZXJIVE1MKSB7XG4gICAgICAgICAgZGlkV2FybkludmFsaWRJbm5lckhUTUwgPSB0cnVlO1xuXG4gICAgICAgICAgZXJyb3IoJ1Bhc3MgYSBgdmFsdWVgIHByb3AgaWYgeW91IHNldCBkYW5nZXJvdXNseUlubmVySFRNTCBzbyBSZWFjdCBrbm93cyAnICsgJ3doaWNoIHZhbHVlIHNob3VsZCBiZSBzZWxlY3RlZC4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gLy8gVE9ETzogUmVtb3ZlIHN1cHBvcnQgZm9yIGBzZWxlY3RlZGAgaW4gPG9wdGlvbj4uXG5cblxuICAgIGlmIChwcm9wcy5zZWxlY3RlZCAhPSBudWxsICYmICFkaWRXYXJuU2VsZWN0ZWRTZXRPbk9wdGlvbikge1xuICAgICAgZXJyb3IoJ1VzZSB0aGUgYGRlZmF1bHRWYWx1ZWAgb3IgYHZhbHVlYCBwcm9wcyBvbiA8c2VsZWN0PiBpbnN0ZWFkIG9mICcgKyAnc2V0dGluZyBgc2VsZWN0ZWRgIG9uIDxvcHRpb24+LicpO1xuXG4gICAgICBkaWRXYXJuU2VsZWN0ZWRTZXRPbk9wdGlvbiA9IHRydWU7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBwb3N0TW91bnRXcmFwcGVyJDEoZWxlbWVudCwgcHJvcHMpIHtcbiAgLy8gdmFsdWU9XCJcIiBzaG91bGQgbWFrZSBhIHZhbHVlIGF0dHJpYnV0ZSAoIzYyMTkpXG4gIGlmIChwcm9wcy52YWx1ZSAhPSBudWxsKSB7XG4gICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3ZhbHVlJywgdG9TdHJpbmcoZ2V0VG9TdHJpbmdWYWx1ZShwcm9wcy52YWx1ZSkpKTtcbiAgfVxufVxuXG52YXIgaXNBcnJheUltcGwgPSBBcnJheS5pc0FycmF5OyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVkZWNsYXJlXG5cbmZ1bmN0aW9uIGlzQXJyYXkoYSkge1xuICByZXR1cm4gaXNBcnJheUltcGwoYSk7XG59XG5cbnZhciBkaWRXYXJuVmFsdWVEZWZhdWx0VmFsdWUkMTtcblxue1xuICBkaWRXYXJuVmFsdWVEZWZhdWx0VmFsdWUkMSA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBnZXREZWNsYXJhdGlvbkVycm9yQWRkZW5kdW0oKSB7XG4gIHZhciBvd25lck5hbWUgPSBnZXRDdXJyZW50RmliZXJPd25lck5hbWVJbkRldk9yTnVsbCgpO1xuXG4gIGlmIChvd25lck5hbWUpIHtcbiAgICByZXR1cm4gJ1xcblxcbkNoZWNrIHRoZSByZW5kZXIgbWV0aG9kIG9mIGAnICsgb3duZXJOYW1lICsgJ2AuJztcbiAgfVxuXG4gIHJldHVybiAnJztcbn1cblxudmFyIHZhbHVlUHJvcE5hbWVzID0gWyd2YWx1ZScsICdkZWZhdWx0VmFsdWUnXTtcbi8qKlxuICogVmFsaWRhdGlvbiBmdW5jdGlvbiBmb3IgYHZhbHVlYCBhbmQgYGRlZmF1bHRWYWx1ZWAuXG4gKi9cblxuZnVuY3Rpb24gY2hlY2tTZWxlY3RQcm9wVHlwZXMocHJvcHMpIHtcbiAge1xuICAgIGNoZWNrQ29udHJvbGxlZFZhbHVlUHJvcHMoJ3NlbGVjdCcsIHByb3BzKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsdWVQcm9wTmFtZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBwcm9wTmFtZSA9IHZhbHVlUHJvcE5hbWVzW2ldO1xuXG4gICAgICBpZiAocHJvcHNbcHJvcE5hbWVdID09IG51bGwpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBwcm9wTmFtZUlzQXJyYXkgPSBpc0FycmF5KHByb3BzW3Byb3BOYW1lXSk7XG5cbiAgICAgIGlmIChwcm9wcy5tdWx0aXBsZSAmJiAhcHJvcE5hbWVJc0FycmF5KSB7XG4gICAgICAgIGVycm9yKCdUaGUgYCVzYCBwcm9wIHN1cHBsaWVkIHRvIDxzZWxlY3Q+IG11c3QgYmUgYW4gYXJyYXkgaWYgJyArICdgbXVsdGlwbGVgIGlzIHRydWUuJXMnLCBwcm9wTmFtZSwgZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKCkpO1xuICAgICAgfSBlbHNlIGlmICghcHJvcHMubXVsdGlwbGUgJiYgcHJvcE5hbWVJc0FycmF5KSB7XG4gICAgICAgIGVycm9yKCdUaGUgYCVzYCBwcm9wIHN1cHBsaWVkIHRvIDxzZWxlY3Q+IG11c3QgYmUgYSBzY2FsYXIgJyArICd2YWx1ZSBpZiBgbXVsdGlwbGVgIGlzIGZhbHNlLiVzJywgcHJvcE5hbWUsIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bSgpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlT3B0aW9ucyhub2RlLCBtdWx0aXBsZSwgcHJvcFZhbHVlLCBzZXREZWZhdWx0U2VsZWN0ZWQpIHtcbiAgdmFyIG9wdGlvbnMgPSBub2RlLm9wdGlvbnM7XG5cbiAgaWYgKG11bHRpcGxlKSB7XG4gICAgdmFyIHNlbGVjdGVkVmFsdWVzID0gcHJvcFZhbHVlO1xuICAgIHZhciBzZWxlY3RlZFZhbHVlID0ge307XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlbGVjdGVkVmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvLyBQcmVmaXggdG8gYXZvaWQgY2hhb3Mgd2l0aCBzcGVjaWFsIGtleXMuXG4gICAgICBzZWxlY3RlZFZhbHVlWyckJyArIHNlbGVjdGVkVmFsdWVzW2ldXSA9IHRydWU7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IG9wdGlvbnMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICB2YXIgc2VsZWN0ZWQgPSBzZWxlY3RlZFZhbHVlLmhhc093blByb3BlcnR5KCckJyArIG9wdGlvbnNbX2ldLnZhbHVlKTtcblxuICAgICAgaWYgKG9wdGlvbnNbX2ldLnNlbGVjdGVkICE9PSBzZWxlY3RlZCkge1xuICAgICAgICBvcHRpb25zW19pXS5zZWxlY3RlZCA9IHNlbGVjdGVkO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2VsZWN0ZWQgJiYgc2V0RGVmYXVsdFNlbGVjdGVkKSB7XG4gICAgICAgIG9wdGlvbnNbX2ldLmRlZmF1bHRTZWxlY3RlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIERvIG5vdCBzZXQgYHNlbGVjdC52YWx1ZWAgYXMgZXhhY3QgYmVoYXZpb3IgaXNuJ3QgY29uc2lzdGVudCBhY3Jvc3MgYWxsXG4gICAgLy8gYnJvd3NlcnMgZm9yIGFsbCBjYXNlcy5cbiAgICB2YXIgX3NlbGVjdGVkVmFsdWUgPSB0b1N0cmluZyhnZXRUb1N0cmluZ1ZhbHVlKHByb3BWYWx1ZSkpO1xuXG4gICAgdmFyIGRlZmF1bHRTZWxlY3RlZCA9IG51bGw7XG5cbiAgICBmb3IgKHZhciBfaTIgPSAwOyBfaTIgPCBvcHRpb25zLmxlbmd0aDsgX2kyKyspIHtcbiAgICAgIGlmIChvcHRpb25zW19pMl0udmFsdWUgPT09IF9zZWxlY3RlZFZhbHVlKSB7XG4gICAgICAgIG9wdGlvbnNbX2kyXS5zZWxlY3RlZCA9IHRydWU7XG5cbiAgICAgICAgaWYgKHNldERlZmF1bHRTZWxlY3RlZCkge1xuICAgICAgICAgIG9wdGlvbnNbX2kyXS5kZWZhdWx0U2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGVmYXVsdFNlbGVjdGVkID09PSBudWxsICYmICFvcHRpb25zW19pMl0uZGlzYWJsZWQpIHtcbiAgICAgICAgZGVmYXVsdFNlbGVjdGVkID0gb3B0aW9uc1tfaTJdO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChkZWZhdWx0U2VsZWN0ZWQgIT09IG51bGwpIHtcbiAgICAgIGRlZmF1bHRTZWxlY3RlZC5zZWxlY3RlZCA9IHRydWU7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEltcGxlbWVudHMgYSA8c2VsZWN0PiBob3N0IGNvbXBvbmVudCB0aGF0IGFsbG93cyBvcHRpb25hbGx5IHNldHRpbmcgdGhlXG4gKiBwcm9wcyBgdmFsdWVgIGFuZCBgZGVmYXVsdFZhbHVlYC4gSWYgYG11bHRpcGxlYCBpcyBmYWxzZSwgdGhlIHByb3AgbXVzdCBiZSBhXG4gKiBzdHJpbmdhYmxlLiBJZiBgbXVsdGlwbGVgIGlzIHRydWUsIHRoZSBwcm9wIG11c3QgYmUgYW4gYXJyYXkgb2Ygc3RyaW5nYWJsZXMuXG4gKlxuICogSWYgYHZhbHVlYCBpcyBub3Qgc3VwcGxpZWQgKG9yIG51bGwvdW5kZWZpbmVkKSwgdXNlciBhY3Rpb25zIHRoYXQgY2hhbmdlIHRoZVxuICogc2VsZWN0ZWQgb3B0aW9uIHdpbGwgdHJpZ2dlciB1cGRhdGVzIHRvIHRoZSByZW5kZXJlZCBvcHRpb25zLlxuICpcbiAqIElmIGl0IGlzIHN1cHBsaWVkIChhbmQgbm90IG51bGwvdW5kZWZpbmVkKSwgdGhlIHJlbmRlcmVkIG9wdGlvbnMgd2lsbCBub3RcbiAqIHVwZGF0ZSBpbiByZXNwb25zZSB0byB1c2VyIGFjdGlvbnMuIEluc3RlYWQsIHRoZSBgdmFsdWVgIHByb3AgbXVzdCBjaGFuZ2UgaW5cbiAqIG9yZGVyIGZvciB0aGUgcmVuZGVyZWQgb3B0aW9ucyB0byB1cGRhdGUuXG4gKlxuICogSWYgYGRlZmF1bHRWYWx1ZWAgaXMgcHJvdmlkZWQsIGFueSBvcHRpb25zIHdpdGggdGhlIHN1cHBsaWVkIHZhbHVlcyB3aWxsIGJlXG4gKiBzZWxlY3RlZC5cbiAqL1xuXG5cbmZ1bmN0aW9uIGdldEhvc3RQcm9wcyQxKGVsZW1lbnQsIHByb3BzKSB7XG4gIHJldHVybiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgdmFsdWU6IHVuZGVmaW5lZFxuICB9KTtcbn1cbmZ1bmN0aW9uIGluaXRXcmFwcGVyU3RhdGUkMShlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7XG5cbiAge1xuICAgIGNoZWNrU2VsZWN0UHJvcFR5cGVzKHByb3BzKTtcbiAgfVxuXG4gIG5vZGUuX3dyYXBwZXJTdGF0ZSA9IHtcbiAgICB3YXNNdWx0aXBsZTogISFwcm9wcy5tdWx0aXBsZVxuICB9O1xuXG4gIHtcbiAgICBpZiAocHJvcHMudmFsdWUgIT09IHVuZGVmaW5lZCAmJiBwcm9wcy5kZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCAmJiAhZGlkV2FyblZhbHVlRGVmYXVsdFZhbHVlJDEpIHtcbiAgICAgIGVycm9yKCdTZWxlY3QgZWxlbWVudHMgbXVzdCBiZSBlaXRoZXIgY29udHJvbGxlZCBvciB1bmNvbnRyb2xsZWQgJyArICcoc3BlY2lmeSBlaXRoZXIgdGhlIHZhbHVlIHByb3AsIG9yIHRoZSBkZWZhdWx0VmFsdWUgcHJvcCwgYnV0IG5vdCAnICsgJ2JvdGgpLiBEZWNpZGUgYmV0d2VlbiB1c2luZyBhIGNvbnRyb2xsZWQgb3IgdW5jb250cm9sbGVkIHNlbGVjdCAnICsgJ2VsZW1lbnQgYW5kIHJlbW92ZSBvbmUgb2YgdGhlc2UgcHJvcHMuIE1vcmUgaW5mbzogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvY29udHJvbGxlZC1jb21wb25lbnRzJyk7XG5cbiAgICAgIGRpZFdhcm5WYWx1ZURlZmF1bHRWYWx1ZSQxID0gdHJ1ZTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIHBvc3RNb3VudFdyYXBwZXIkMihlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7XG4gIG5vZGUubXVsdGlwbGUgPSAhIXByb3BzLm11bHRpcGxlO1xuICB2YXIgdmFsdWUgPSBwcm9wcy52YWx1ZTtcblxuICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgIHVwZGF0ZU9wdGlvbnMobm9kZSwgISFwcm9wcy5tdWx0aXBsZSwgdmFsdWUsIGZhbHNlKTtcbiAgfSBlbHNlIGlmIChwcm9wcy5kZWZhdWx0VmFsdWUgIT0gbnVsbCkge1xuICAgIHVwZGF0ZU9wdGlvbnMobm9kZSwgISFwcm9wcy5tdWx0aXBsZSwgcHJvcHMuZGVmYXVsdFZhbHVlLCB0cnVlKTtcbiAgfVxufVxuZnVuY3Rpb24gcG9zdFVwZGF0ZVdyYXBwZXIoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50O1xuICB2YXIgd2FzTXVsdGlwbGUgPSBub2RlLl93cmFwcGVyU3RhdGUud2FzTXVsdGlwbGU7XG4gIG5vZGUuX3dyYXBwZXJTdGF0ZS53YXNNdWx0aXBsZSA9ICEhcHJvcHMubXVsdGlwbGU7XG4gIHZhciB2YWx1ZSA9IHByb3BzLnZhbHVlO1xuXG4gIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgdXBkYXRlT3B0aW9ucyhub2RlLCAhIXByb3BzLm11bHRpcGxlLCB2YWx1ZSwgZmFsc2UpO1xuICB9IGVsc2UgaWYgKHdhc011bHRpcGxlICE9PSAhIXByb3BzLm11bHRpcGxlKSB7XG4gICAgLy8gRm9yIHNpbXBsaWNpdHksIHJlYXBwbHkgYGRlZmF1bHRWYWx1ZWAgaWYgYG11bHRpcGxlYCBpcyB0b2dnbGVkLlxuICAgIGlmIChwcm9wcy5kZWZhdWx0VmFsdWUgIT0gbnVsbCkge1xuICAgICAgdXBkYXRlT3B0aW9ucyhub2RlLCAhIXByb3BzLm11bHRpcGxlLCBwcm9wcy5kZWZhdWx0VmFsdWUsIHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZXZlcnQgdGhlIHNlbGVjdCBiYWNrIHRvIGl0cyBkZWZhdWx0IHVuc2VsZWN0ZWQgc3RhdGUuXG4gICAgICB1cGRhdGVPcHRpb25zKG5vZGUsICEhcHJvcHMubXVsdGlwbGUsIHByb3BzLm11bHRpcGxlID8gW10gOiAnJywgZmFsc2UpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gcmVzdG9yZUNvbnRyb2xsZWRTdGF0ZSQxKGVsZW1lbnQsIHByb3BzKSB7XG4gIHZhciBub2RlID0gZWxlbWVudDtcbiAgdmFyIHZhbHVlID0gcHJvcHMudmFsdWU7XG5cbiAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICB1cGRhdGVPcHRpb25zKG5vZGUsICEhcHJvcHMubXVsdGlwbGUsIHZhbHVlLCBmYWxzZSk7XG4gIH1cbn1cblxudmFyIGRpZFdhcm5WYWxEZWZhdWx0VmFsID0gZmFsc2U7XG5cbi8qKlxuICogSW1wbGVtZW50cyBhIDx0ZXh0YXJlYT4gaG9zdCBjb21wb25lbnQgdGhhdCBhbGxvd3Mgc2V0dGluZyBgdmFsdWVgLCBhbmRcbiAqIGBkZWZhdWx0VmFsdWVgLiBUaGlzIGRpZmZlcnMgZnJvbSB0aGUgdHJhZGl0aW9uYWwgRE9NIEFQSSBiZWNhdXNlIHZhbHVlIGlzXG4gKiB1c3VhbGx5IHNldCBhcyBQQ0RBVEEgY2hpbGRyZW4uXG4gKlxuICogSWYgYHZhbHVlYCBpcyBub3Qgc3VwcGxpZWQgKG9yIG51bGwvdW5kZWZpbmVkKSwgdXNlciBhY3Rpb25zIHRoYXQgYWZmZWN0IHRoZVxuICogdmFsdWUgd2lsbCB0cmlnZ2VyIHVwZGF0ZXMgdG8gdGhlIGVsZW1lbnQuXG4gKlxuICogSWYgYHZhbHVlYCBpcyBzdXBwbGllZCAoYW5kIG5vdCBudWxsL3VuZGVmaW5lZCksIHRoZSByZW5kZXJlZCBlbGVtZW50IHdpbGxcbiAqIG5vdCB0cmlnZ2VyIHVwZGF0ZXMgdG8gdGhlIGVsZW1lbnQuIEluc3RlYWQsIHRoZSBgdmFsdWVgIHByb3AgbXVzdCBjaGFuZ2UgaW5cbiAqIG9yZGVyIGZvciB0aGUgcmVuZGVyZWQgZWxlbWVudCB0byBiZSB1cGRhdGVkLlxuICpcbiAqIFRoZSByZW5kZXJlZCBlbGVtZW50IHdpbGwgYmUgaW5pdGlhbGl6ZWQgd2l0aCBhbiBlbXB0eSB2YWx1ZSwgdGhlIHByb3BcbiAqIGBkZWZhdWx0VmFsdWVgIGlmIHNwZWNpZmllZCwgb3IgdGhlIGNoaWxkcmVuIGNvbnRlbnQgKGRlcHJlY2F0ZWQpLlxuICovXG5mdW5jdGlvbiBnZXRIb3N0UHJvcHMkMihlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7XG5cbiAgaWYgKHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MICE9IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2BkYW5nZXJvdXNseVNldElubmVySFRNTGAgZG9lcyBub3QgbWFrZSBzZW5zZSBvbiA8dGV4dGFyZWE+LicpO1xuICB9IC8vIEFsd2F5cyBzZXQgY2hpbGRyZW4gdG8gdGhlIHNhbWUgdGhpbmcuIEluIElFOSwgdGhlIHNlbGVjdGlvbiByYW5nZSB3aWxsXG4gIC8vIGdldCByZXNldCBpZiBgdGV4dENvbnRlbnRgIGlzIG11dGF0ZWQuICBXZSBjb3VsZCBhZGQgYSBjaGVjayBpbiBzZXRUZXh0Q29udGVudFxuICAvLyB0byBvbmx5IHNldCB0aGUgdmFsdWUgaWYvd2hlbiB0aGUgdmFsdWUgZGlmZmVycyBmcm9tIHRoZSBub2RlIHZhbHVlICh3aGljaCB3b3VsZFxuICAvLyBjb21wbGV0ZWx5IHNvbHZlIHRoaXMgSUU5IGJ1ZyksIGJ1dCBTZWJhc3RpYW4rU29waGllIHNlZW1lZCB0byBsaWtlIHRoaXNcbiAgLy8gc29sdXRpb24uIFRoZSB2YWx1ZSBjYW4gYmUgYSBib29sZWFuIG9yIG9iamVjdCBzbyB0aGF0J3Mgd2h5IGl0J3MgZm9yY2VkXG4gIC8vIHRvIGJlIGEgc3RyaW5nLlxuXG5cbiAgdmFyIGhvc3RQcm9wcyA9IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgIGRlZmF1bHRWYWx1ZTogdW5kZWZpbmVkLFxuICAgIGNoaWxkcmVuOiB0b1N0cmluZyhub2RlLl93cmFwcGVyU3RhdGUuaW5pdGlhbFZhbHVlKVxuICB9KTtcblxuICByZXR1cm4gaG9zdFByb3BzO1xufVxuZnVuY3Rpb24gaW5pdFdyYXBwZXJTdGF0ZSQyKGVsZW1lbnQsIHByb3BzKSB7XG4gIHZhciBub2RlID0gZWxlbWVudDtcblxuICB7XG4gICAgY2hlY2tDb250cm9sbGVkVmFsdWVQcm9wcygndGV4dGFyZWEnLCBwcm9wcyk7XG5cbiAgICBpZiAocHJvcHMudmFsdWUgIT09IHVuZGVmaW5lZCAmJiBwcm9wcy5kZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCAmJiAhZGlkV2FyblZhbERlZmF1bHRWYWwpIHtcbiAgICAgIGVycm9yKCclcyBjb250YWlucyBhIHRleHRhcmVhIHdpdGggYm90aCB2YWx1ZSBhbmQgZGVmYXVsdFZhbHVlIHByb3BzLiAnICsgJ1RleHRhcmVhIGVsZW1lbnRzIG11c3QgYmUgZWl0aGVyIGNvbnRyb2xsZWQgb3IgdW5jb250cm9sbGVkICcgKyAnKHNwZWNpZnkgZWl0aGVyIHRoZSB2YWx1ZSBwcm9wLCBvciB0aGUgZGVmYXVsdFZhbHVlIHByb3AsIGJ1dCBub3QgJyArICdib3RoKS4gRGVjaWRlIGJldHdlZW4gdXNpbmcgYSBjb250cm9sbGVkIG9yIHVuY29udHJvbGxlZCB0ZXh0YXJlYSAnICsgJ2FuZCByZW1vdmUgb25lIG9mIHRoZXNlIHByb3BzLiBNb3JlIGluZm86ICcgKyAnaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL2NvbnRyb2xsZWQtY29tcG9uZW50cycsIGdldEN1cnJlbnRGaWJlck93bmVyTmFtZUluRGV2T3JOdWxsKCkgfHwgJ0EgY29tcG9uZW50Jyk7XG5cbiAgICAgIGRpZFdhcm5WYWxEZWZhdWx0VmFsID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICB2YXIgaW5pdGlhbFZhbHVlID0gcHJvcHMudmFsdWU7IC8vIE9ubHkgYm90aGVyIGZldGNoaW5nIGRlZmF1bHQgdmFsdWUgaWYgd2UncmUgZ29pbmcgdG8gdXNlIGl0XG5cbiAgaWYgKGluaXRpYWxWYWx1ZSA9PSBudWxsKSB7XG4gICAgdmFyIGNoaWxkcmVuID0gcHJvcHMuY2hpbGRyZW4sXG4gICAgICAgIGRlZmF1bHRWYWx1ZSA9IHByb3BzLmRlZmF1bHRWYWx1ZTtcblxuICAgIGlmIChjaGlsZHJlbiAhPSBudWxsKSB7XG4gICAgICB7XG4gICAgICAgIGVycm9yKCdVc2UgdGhlIGBkZWZhdWx0VmFsdWVgIG9yIGB2YWx1ZWAgcHJvcHMgaW5zdGVhZCBvZiBzZXR0aW5nICcgKyAnY2hpbGRyZW4gb24gPHRleHRhcmVhPi4nKTtcbiAgICAgIH1cblxuICAgICAge1xuICAgICAgICBpZiAoZGVmYXVsdFZhbHVlICE9IG51bGwpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lmIHlvdSBzdXBwbHkgYGRlZmF1bHRWYWx1ZWAgb24gYSA8dGV4dGFyZWE+LCBkbyBub3QgcGFzcyBjaGlsZHJlbi4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0FycmF5KGNoaWxkcmVuKSkge1xuICAgICAgICAgIGlmIChjaGlsZHJlbi5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJzx0ZXh0YXJlYT4gY2FuIG9ubHkgaGF2ZSBhdCBtb3N0IG9uZSBjaGlsZC4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuWzBdO1xuICAgICAgICB9XG5cbiAgICAgICAgZGVmYXVsdFZhbHVlID0gY2hpbGRyZW47XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGRlZmF1bHRWYWx1ZSA9PSBudWxsKSB7XG4gICAgICBkZWZhdWx0VmFsdWUgPSAnJztcbiAgICB9XG5cbiAgICBpbml0aWFsVmFsdWUgPSBkZWZhdWx0VmFsdWU7XG4gIH1cblxuICBub2RlLl93cmFwcGVyU3RhdGUgPSB7XG4gICAgaW5pdGlhbFZhbHVlOiBnZXRUb1N0cmluZ1ZhbHVlKGluaXRpYWxWYWx1ZSlcbiAgfTtcbn1cbmZ1bmN0aW9uIHVwZGF0ZVdyYXBwZXIkMShlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7XG4gIHZhciB2YWx1ZSA9IGdldFRvU3RyaW5nVmFsdWUocHJvcHMudmFsdWUpO1xuICB2YXIgZGVmYXVsdFZhbHVlID0gZ2V0VG9TdHJpbmdWYWx1ZShwcm9wcy5kZWZhdWx0VmFsdWUpO1xuXG4gIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgLy8gQ2FzdCBgdmFsdWVgIHRvIGEgc3RyaW5nIHRvIGVuc3VyZSB0aGUgdmFsdWUgaXMgc2V0IGNvcnJlY3RseS4gV2hpbGVcbiAgICAvLyBicm93c2VycyB0eXBpY2FsbHkgZG8gdGhpcyBhcyBuZWNlc3NhcnksIGpzZG9tIGRvZXNuJ3QuXG4gICAgdmFyIG5ld1ZhbHVlID0gdG9TdHJpbmcodmFsdWUpOyAvLyBUbyBhdm9pZCBzaWRlIGVmZmVjdHMgKHN1Y2ggYXMgbG9zaW5nIHRleHQgc2VsZWN0aW9uKSwgb25seSBzZXQgdmFsdWUgaWYgY2hhbmdlZFxuXG4gICAgaWYgKG5ld1ZhbHVlICE9PSBub2RlLnZhbHVlKSB7XG4gICAgICBub2RlLnZhbHVlID0gbmV3VmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmRlZmF1bHRWYWx1ZSA9PSBudWxsICYmIG5vZGUuZGVmYXVsdFZhbHVlICE9PSBuZXdWYWx1ZSkge1xuICAgICAgbm9kZS5kZWZhdWx0VmFsdWUgPSBuZXdWYWx1ZTtcbiAgICB9XG4gIH1cblxuICBpZiAoZGVmYXVsdFZhbHVlICE9IG51bGwpIHtcbiAgICBub2RlLmRlZmF1bHRWYWx1ZSA9IHRvU3RyaW5nKGRlZmF1bHRWYWx1ZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIHBvc3RNb3VudFdyYXBwZXIkMyhlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7IC8vIFRoaXMgaXMgaW4gcG9zdE1vdW50IGJlY2F1c2Ugd2UgbmVlZCBhY2Nlc3MgdG8gdGhlIERPTSBub2RlLCB3aGljaCBpcyBub3RcbiAgLy8gYXZhaWxhYmxlIHVudGlsIGFmdGVyIHRoZSBjb21wb25lbnQgaGFzIG1vdW50ZWQuXG5cbiAgdmFyIHRleHRDb250ZW50ID0gbm9kZS50ZXh0Q29udGVudDsgLy8gT25seSBzZXQgbm9kZS52YWx1ZSBpZiB0ZXh0Q29udGVudCBpcyBlcXVhbCB0byB0aGUgZXhwZWN0ZWRcbiAgLy8gaW5pdGlhbCB2YWx1ZS4gSW4gSUUxMC9JRTExIHRoZXJlIGlzIGEgYnVnIHdoZXJlIHRoZSBwbGFjZWhvbGRlciBhdHRyaWJ1dGVcbiAgLy8gd2lsbCBwb3B1bGF0ZSB0ZXh0Q29udGVudCBhcyB3ZWxsLlxuICAvLyBodHRwczovL2RldmVsb3Blci5taWNyb3NvZnQuY29tL21pY3Jvc29mdC1lZGdlL3BsYXRmb3JtL2lzc3Vlcy8xMDE1MjUvXG5cbiAgaWYgKHRleHRDb250ZW50ID09PSBub2RlLl93cmFwcGVyU3RhdGUuaW5pdGlhbFZhbHVlKSB7XG4gICAgaWYgKHRleHRDb250ZW50ICE9PSAnJyAmJiB0ZXh0Q29udGVudCAhPT0gbnVsbCkge1xuICAgICAgbm9kZS52YWx1ZSA9IHRleHRDb250ZW50O1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gcmVzdG9yZUNvbnRyb2xsZWRTdGF0ZSQyKGVsZW1lbnQsIHByb3BzKSB7XG4gIC8vIERPTSBjb21wb25lbnQgaXMgc3RpbGwgbW91bnRlZDsgdXBkYXRlXG4gIHVwZGF0ZVdyYXBwZXIkMShlbGVtZW50LCBwcm9wcyk7XG59XG5cbnZhciBIVE1MX05BTUVTUEFDRSA9ICdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sJztcbnZhciBNQVRIX05BTUVTUEFDRSA9ICdodHRwOi8vd3d3LnczLm9yZy8xOTk4L01hdGgvTWF0aE1MJztcbnZhciBTVkdfTkFNRVNQQUNFID0gJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJzsgLy8gQXNzdW1lcyB0aGVyZSBpcyBubyBwYXJlbnQgbmFtZXNwYWNlLlxuXG5mdW5jdGlvbiBnZXRJbnRyaW5zaWNOYW1lc3BhY2UodHlwZSkge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdzdmcnOlxuICAgICAgcmV0dXJuIFNWR19OQU1FU1BBQ0U7XG5cbiAgICBjYXNlICdtYXRoJzpcbiAgICAgIHJldHVybiBNQVRIX05BTUVTUEFDRTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gSFRNTF9OQU1FU1BBQ0U7XG4gIH1cbn1cbmZ1bmN0aW9uIGdldENoaWxkTmFtZXNwYWNlKHBhcmVudE5hbWVzcGFjZSwgdHlwZSkge1xuICBpZiAocGFyZW50TmFtZXNwYWNlID09IG51bGwgfHwgcGFyZW50TmFtZXNwYWNlID09PSBIVE1MX05BTUVTUEFDRSkge1xuICAgIC8vIE5vIChvciBkZWZhdWx0KSBwYXJlbnQgbmFtZXNwYWNlOiBwb3RlbnRpYWwgZW50cnkgcG9pbnQuXG4gICAgcmV0dXJuIGdldEludHJpbnNpY05hbWVzcGFjZSh0eXBlKTtcbiAgfVxuXG4gIGlmIChwYXJlbnROYW1lc3BhY2UgPT09IFNWR19OQU1FU1BBQ0UgJiYgdHlwZSA9PT0gJ2ZvcmVpZ25PYmplY3QnKSB7XG4gICAgLy8gV2UncmUgbGVhdmluZyBTVkcuXG4gICAgcmV0dXJuIEhUTUxfTkFNRVNQQUNFO1xuICB9IC8vIEJ5IGRlZmF1bHQsIHBhc3MgbmFtZXNwYWNlIGJlbG93LlxuXG5cbiAgcmV0dXJuIHBhcmVudE5hbWVzcGFjZTtcbn1cblxuLyogZ2xvYmFscyBNU0FwcCAqL1xuXG4vKipcbiAqIENyZWF0ZSBhIGZ1bmN0aW9uIHdoaWNoIGhhcyAndW5zYWZlJyBwcml2aWxlZ2VzIChyZXF1aXJlZCBieSB3aW5kb3dzOCBhcHBzKVxuICovXG52YXIgY3JlYXRlTWljcm9zb2Z0VW5zYWZlTG9jYWxGdW5jdGlvbiA9IGZ1bmN0aW9uIChmdW5jKSB7XG4gIGlmICh0eXBlb2YgTVNBcHAgIT09ICd1bmRlZmluZWQnICYmIE1TQXBwLmV4ZWNVbnNhZmVMb2NhbEZ1bmN0aW9uKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChhcmcwLCBhcmcxLCBhcmcyLCBhcmczKSB7XG4gICAgICBNU0FwcC5leGVjVW5zYWZlTG9jYWxGdW5jdGlvbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBmdW5jKGFyZzAsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZnVuYztcbiAgfVxufTtcblxudmFyIHJldXNhYmxlU1ZHQ29udGFpbmVyO1xuLyoqXG4gKiBTZXQgdGhlIGlubmVySFRNTCBwcm9wZXJ0eSBvZiBhIG5vZGVcbiAqXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR9IG5vZGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sXG4gKiBAaW50ZXJuYWxcbiAqL1xuXG52YXIgc2V0SW5uZXJIVE1MID0gY3JlYXRlTWljcm9zb2Z0VW5zYWZlTG9jYWxGdW5jdGlvbihmdW5jdGlvbiAobm9kZSwgaHRtbCkge1xuICBpZiAobm9kZS5uYW1lc3BhY2VVUkkgPT09IFNWR19OQU1FU1BBQ0UpIHtcblxuICAgIGlmICghKCdpbm5lckhUTUwnIGluIG5vZGUpKSB7XG4gICAgICAvLyBJRSBkb2VzIG5vdCBoYXZlIGlubmVySFRNTCBmb3IgU1ZHIG5vZGVzLCBzbyBpbnN0ZWFkIHdlIGluamVjdCB0aGVcbiAgICAgIC8vIG5ldyBtYXJrdXAgaW4gYSB0ZW1wIG5vZGUgYW5kIHRoZW4gbW92ZSB0aGUgY2hpbGQgbm9kZXMgYWNyb3NzIGludG9cbiAgICAgIC8vIHRoZSB0YXJnZXQgbm9kZVxuICAgICAgcmV1c2FibGVTVkdDb250YWluZXIgPSByZXVzYWJsZVNWR0NvbnRhaW5lciB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIHJldXNhYmxlU1ZHQ29udGFpbmVyLmlubmVySFRNTCA9ICc8c3ZnPicgKyBodG1sLnZhbHVlT2YoKS50b1N0cmluZygpICsgJzwvc3ZnPic7XG4gICAgICB2YXIgc3ZnTm9kZSA9IHJldXNhYmxlU1ZHQ29udGFpbmVyLmZpcnN0Q2hpbGQ7XG5cbiAgICAgIHdoaWxlIChub2RlLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgbm9kZS5yZW1vdmVDaGlsZChub2RlLmZpcnN0Q2hpbGQpO1xuICAgICAgfVxuXG4gICAgICB3aGlsZSAoc3ZnTm9kZS5maXJzdENoaWxkKSB7XG4gICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQoc3ZnTm9kZS5maXJzdENoaWxkKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIG5vZGUuaW5uZXJIVE1MID0gaHRtbDtcbn0pO1xuXG4vKipcbiAqIEhUTUwgbm9kZVR5cGUgdmFsdWVzIHRoYXQgcmVwcmVzZW50IHRoZSB0eXBlIG9mIHRoZSBub2RlXG4gKi9cbnZhciBFTEVNRU5UX05PREUgPSAxO1xudmFyIFRFWFRfTk9ERSA9IDM7XG52YXIgQ09NTUVOVF9OT0RFID0gODtcbnZhciBET0NVTUVOVF9OT0RFID0gOTtcbnZhciBET0NVTUVOVF9GUkFHTUVOVF9OT0RFID0gMTE7XG5cbi8qKlxuICogU2V0IHRoZSB0ZXh0Q29udGVudCBwcm9wZXJ0eSBvZiBhIG5vZGUuIEZvciB0ZXh0IHVwZGF0ZXMsIGl0J3MgZmFzdGVyXG4gKiB0byBzZXQgdGhlIGBub2RlVmFsdWVgIG9mIHRoZSBUZXh0IG5vZGUgZGlyZWN0bHkgaW5zdGVhZCBvZiB1c2luZ1xuICogYC50ZXh0Q29udGVudGAgd2hpY2ggd2lsbCByZW1vdmUgdGhlIGV4aXN0aW5nIG5vZGUgYW5kIGNyZWF0ZSBhIG5ldyBvbmUuXG4gKlxuICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICogQGludGVybmFsXG4gKi9cblxudmFyIHNldFRleHRDb250ZW50ID0gZnVuY3Rpb24gKG5vZGUsIHRleHQpIHtcbiAgaWYgKHRleHQpIHtcbiAgICB2YXIgZmlyc3RDaGlsZCA9IG5vZGUuZmlyc3RDaGlsZDtcblxuICAgIGlmIChmaXJzdENoaWxkICYmIGZpcnN0Q2hpbGQgPT09IG5vZGUubGFzdENoaWxkICYmIGZpcnN0Q2hpbGQubm9kZVR5cGUgPT09IFRFWFRfTk9ERSkge1xuICAgICAgZmlyc3RDaGlsZC5ub2RlVmFsdWUgPSB0ZXh0O1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIG5vZGUudGV4dENvbnRlbnQgPSB0ZXh0O1xufTtcblxuLy8gTGlzdCBkZXJpdmVkIGZyb20gR2Vja28gc291cmNlIGNvZGU6XG4vLyBodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS9nZWNrby1kZXYvYmxvYi80ZTYzOGVmYzcxL2xheW91dC9zdHlsZS90ZXN0L3Byb3BlcnR5X2RhdGFiYXNlLmpzXG52YXIgc2hvcnRoYW5kVG9Mb25naGFuZCA9IHtcbiAgYW5pbWF0aW9uOiBbJ2FuaW1hdGlvbkRlbGF5JywgJ2FuaW1hdGlvbkRpcmVjdGlvbicsICdhbmltYXRpb25EdXJhdGlvbicsICdhbmltYXRpb25GaWxsTW9kZScsICdhbmltYXRpb25JdGVyYXRpb25Db3VudCcsICdhbmltYXRpb25OYW1lJywgJ2FuaW1hdGlvblBsYXlTdGF0ZScsICdhbmltYXRpb25UaW1pbmdGdW5jdGlvbiddLFxuICBiYWNrZ3JvdW5kOiBbJ2JhY2tncm91bmRBdHRhY2htZW50JywgJ2JhY2tncm91bmRDbGlwJywgJ2JhY2tncm91bmRDb2xvcicsICdiYWNrZ3JvdW5kSW1hZ2UnLCAnYmFja2dyb3VuZE9yaWdpbicsICdiYWNrZ3JvdW5kUG9zaXRpb25YJywgJ2JhY2tncm91bmRQb3NpdGlvblknLCAnYmFja2dyb3VuZFJlcGVhdCcsICdiYWNrZ3JvdW5kU2l6ZSddLFxuICBiYWNrZ3JvdW5kUG9zaXRpb246IFsnYmFja2dyb3VuZFBvc2l0aW9uWCcsICdiYWNrZ3JvdW5kUG9zaXRpb25ZJ10sXG4gIGJvcmRlcjogWydib3JkZXJCb3R0b21Db2xvcicsICdib3JkZXJCb3R0b21TdHlsZScsICdib3JkZXJCb3R0b21XaWR0aCcsICdib3JkZXJJbWFnZU91dHNldCcsICdib3JkZXJJbWFnZVJlcGVhdCcsICdib3JkZXJJbWFnZVNsaWNlJywgJ2JvcmRlckltYWdlU291cmNlJywgJ2JvcmRlckltYWdlV2lkdGgnLCAnYm9yZGVyTGVmdENvbG9yJywgJ2JvcmRlckxlZnRTdHlsZScsICdib3JkZXJMZWZ0V2lkdGgnLCAnYm9yZGVyUmlnaHRDb2xvcicsICdib3JkZXJSaWdodFN0eWxlJywgJ2JvcmRlclJpZ2h0V2lkdGgnLCAnYm9yZGVyVG9wQ29sb3InLCAnYm9yZGVyVG9wU3R5bGUnLCAnYm9yZGVyVG9wV2lkdGgnXSxcbiAgYm9yZGVyQmxvY2tFbmQ6IFsnYm9yZGVyQmxvY2tFbmRDb2xvcicsICdib3JkZXJCbG9ja0VuZFN0eWxlJywgJ2JvcmRlckJsb2NrRW5kV2lkdGgnXSxcbiAgYm9yZGVyQmxvY2tTdGFydDogWydib3JkZXJCbG9ja1N0YXJ0Q29sb3InLCAnYm9yZGVyQmxvY2tTdGFydFN0eWxlJywgJ2JvcmRlckJsb2NrU3RhcnRXaWR0aCddLFxuICBib3JkZXJCb3R0b206IFsnYm9yZGVyQm90dG9tQ29sb3InLCAnYm9yZGVyQm90dG9tU3R5bGUnLCAnYm9yZGVyQm90dG9tV2lkdGgnXSxcbiAgYm9yZGVyQ29sb3I6IFsnYm9yZGVyQm90dG9tQ29sb3InLCAnYm9yZGVyTGVmdENvbG9yJywgJ2JvcmRlclJpZ2h0Q29sb3InLCAnYm9yZGVyVG9wQ29sb3InXSxcbiAgYm9yZGVySW1hZ2U6IFsnYm9yZGVySW1hZ2VPdXRzZXQnLCAnYm9yZGVySW1hZ2VSZXBlYXQnLCAnYm9yZGVySW1hZ2VTbGljZScsICdib3JkZXJJbWFnZVNvdXJjZScsICdib3JkZXJJbWFnZVdpZHRoJ10sXG4gIGJvcmRlcklubGluZUVuZDogWydib3JkZXJJbmxpbmVFbmRDb2xvcicsICdib3JkZXJJbmxpbmVFbmRTdHlsZScsICdib3JkZXJJbmxpbmVFbmRXaWR0aCddLFxuICBib3JkZXJJbmxpbmVTdGFydDogWydib3JkZXJJbmxpbmVTdGFydENvbG9yJywgJ2JvcmRlcklubGluZVN0YXJ0U3R5bGUnLCAnYm9yZGVySW5saW5lU3RhcnRXaWR0aCddLFxuICBib3JkZXJMZWZ0OiBbJ2JvcmRlckxlZnRDb2xvcicsICdib3JkZXJMZWZ0U3R5bGUnLCAnYm9yZGVyTGVmdFdpZHRoJ10sXG4gIGJvcmRlclJhZGl1czogWydib3JkZXJCb3R0b21MZWZ0UmFkaXVzJywgJ2JvcmRlckJvdHRvbVJpZ2h0UmFkaXVzJywgJ2JvcmRlclRvcExlZnRSYWRpdXMnLCAnYm9yZGVyVG9wUmlnaHRSYWRpdXMnXSxcbiAgYm9yZGVyUmlnaHQ6IFsnYm9yZGVyUmlnaHRDb2xvcicsICdib3JkZXJSaWdodFN0eWxlJywgJ2JvcmRlclJpZ2h0V2lkdGgnXSxcbiAgYm9yZGVyU3R5bGU6IFsnYm9yZGVyQm90dG9tU3R5bGUnLCAnYm9yZGVyTGVmdFN0eWxlJywgJ2JvcmRlclJpZ2h0U3R5bGUnLCAnYm9yZGVyVG9wU3R5bGUnXSxcbiAgYm9yZGVyVG9wOiBbJ2JvcmRlclRvcENvbG9yJywgJ2JvcmRlclRvcFN0eWxlJywgJ2JvcmRlclRvcFdpZHRoJ10sXG4gIGJvcmRlcldpZHRoOiBbJ2JvcmRlckJvdHRvbVdpZHRoJywgJ2JvcmRlckxlZnRXaWR0aCcsICdib3JkZXJSaWdodFdpZHRoJywgJ2JvcmRlclRvcFdpZHRoJ10sXG4gIGNvbHVtblJ1bGU6IFsnY29sdW1uUnVsZUNvbG9yJywgJ2NvbHVtblJ1bGVTdHlsZScsICdjb2x1bW5SdWxlV2lkdGgnXSxcbiAgY29sdW1uczogWydjb2x1bW5Db3VudCcsICdjb2x1bW5XaWR0aCddLFxuICBmbGV4OiBbJ2ZsZXhCYXNpcycsICdmbGV4R3JvdycsICdmbGV4U2hyaW5rJ10sXG4gIGZsZXhGbG93OiBbJ2ZsZXhEaXJlY3Rpb24nLCAnZmxleFdyYXAnXSxcbiAgZm9udDogWydmb250RmFtaWx5JywgJ2ZvbnRGZWF0dXJlU2V0dGluZ3MnLCAnZm9udEtlcm5pbmcnLCAnZm9udExhbmd1YWdlT3ZlcnJpZGUnLCAnZm9udFNpemUnLCAnZm9udFNpemVBZGp1c3QnLCAnZm9udFN0cmV0Y2gnLCAnZm9udFN0eWxlJywgJ2ZvbnRWYXJpYW50JywgJ2ZvbnRWYXJpYW50QWx0ZXJuYXRlcycsICdmb250VmFyaWFudENhcHMnLCAnZm9udFZhcmlhbnRFYXN0QXNpYW4nLCAnZm9udFZhcmlhbnRMaWdhdHVyZXMnLCAnZm9udFZhcmlhbnROdW1lcmljJywgJ2ZvbnRWYXJpYW50UG9zaXRpb24nLCAnZm9udFdlaWdodCcsICdsaW5lSGVpZ2h0J10sXG4gIGZvbnRWYXJpYW50OiBbJ2ZvbnRWYXJpYW50QWx0ZXJuYXRlcycsICdmb250VmFyaWFudENhcHMnLCAnZm9udFZhcmlhbnRFYXN0QXNpYW4nLCAnZm9udFZhcmlhbnRMaWdhdHVyZXMnLCAnZm9udFZhcmlhbnROdW1lcmljJywgJ2ZvbnRWYXJpYW50UG9zaXRpb24nXSxcbiAgZ2FwOiBbJ2NvbHVtbkdhcCcsICdyb3dHYXAnXSxcbiAgZ3JpZDogWydncmlkQXV0b0NvbHVtbnMnLCAnZ3JpZEF1dG9GbG93JywgJ2dyaWRBdXRvUm93cycsICdncmlkVGVtcGxhdGVBcmVhcycsICdncmlkVGVtcGxhdGVDb2x1bW5zJywgJ2dyaWRUZW1wbGF0ZVJvd3MnXSxcbiAgZ3JpZEFyZWE6IFsnZ3JpZENvbHVtbkVuZCcsICdncmlkQ29sdW1uU3RhcnQnLCAnZ3JpZFJvd0VuZCcsICdncmlkUm93U3RhcnQnXSxcbiAgZ3JpZENvbHVtbjogWydncmlkQ29sdW1uRW5kJywgJ2dyaWRDb2x1bW5TdGFydCddLFxuICBncmlkQ29sdW1uR2FwOiBbJ2NvbHVtbkdhcCddLFxuICBncmlkR2FwOiBbJ2NvbHVtbkdhcCcsICdyb3dHYXAnXSxcbiAgZ3JpZFJvdzogWydncmlkUm93RW5kJywgJ2dyaWRSb3dTdGFydCddLFxuICBncmlkUm93R2FwOiBbJ3Jvd0dhcCddLFxuICBncmlkVGVtcGxhdGU6IFsnZ3JpZFRlbXBsYXRlQXJlYXMnLCAnZ3JpZFRlbXBsYXRlQ29sdW1ucycsICdncmlkVGVtcGxhdGVSb3dzJ10sXG4gIGxpc3RTdHlsZTogWydsaXN0U3R5bGVJbWFnZScsICdsaXN0U3R5bGVQb3NpdGlvbicsICdsaXN0U3R5bGVUeXBlJ10sXG4gIG1hcmdpbjogWydtYXJnaW5Cb3R0b20nLCAnbWFyZ2luTGVmdCcsICdtYXJnaW5SaWdodCcsICdtYXJnaW5Ub3AnXSxcbiAgbWFya2VyOiBbJ21hcmtlckVuZCcsICdtYXJrZXJNaWQnLCAnbWFya2VyU3RhcnQnXSxcbiAgbWFzazogWydtYXNrQ2xpcCcsICdtYXNrQ29tcG9zaXRlJywgJ21hc2tJbWFnZScsICdtYXNrTW9kZScsICdtYXNrT3JpZ2luJywgJ21hc2tQb3NpdGlvblgnLCAnbWFza1Bvc2l0aW9uWScsICdtYXNrUmVwZWF0JywgJ21hc2tTaXplJ10sXG4gIG1hc2tQb3NpdGlvbjogWydtYXNrUG9zaXRpb25YJywgJ21hc2tQb3NpdGlvblknXSxcbiAgb3V0bGluZTogWydvdXRsaW5lQ29sb3InLCAnb3V0bGluZVN0eWxlJywgJ291dGxpbmVXaWR0aCddLFxuICBvdmVyZmxvdzogWydvdmVyZmxvd1gnLCAnb3ZlcmZsb3dZJ10sXG4gIHBhZGRpbmc6IFsncGFkZGluZ0JvdHRvbScsICdwYWRkaW5nTGVmdCcsICdwYWRkaW5nUmlnaHQnLCAncGFkZGluZ1RvcCddLFxuICBwbGFjZUNvbnRlbnQ6IFsnYWxpZ25Db250ZW50JywgJ2p1c3RpZnlDb250ZW50J10sXG4gIHBsYWNlSXRlbXM6IFsnYWxpZ25JdGVtcycsICdqdXN0aWZ5SXRlbXMnXSxcbiAgcGxhY2VTZWxmOiBbJ2FsaWduU2VsZicsICdqdXN0aWZ5U2VsZiddLFxuICB0ZXh0RGVjb3JhdGlvbjogWyd0ZXh0RGVjb3JhdGlvbkNvbG9yJywgJ3RleHREZWNvcmF0aW9uTGluZScsICd0ZXh0RGVjb3JhdGlvblN0eWxlJ10sXG4gIHRleHRFbXBoYXNpczogWyd0ZXh0RW1waGFzaXNDb2xvcicsICd0ZXh0RW1waGFzaXNTdHlsZSddLFxuICB0cmFuc2l0aW9uOiBbJ3RyYW5zaXRpb25EZWxheScsICd0cmFuc2l0aW9uRHVyYXRpb24nLCAndHJhbnNpdGlvblByb3BlcnR5JywgJ3RyYW5zaXRpb25UaW1pbmdGdW5jdGlvbiddLFxuICB3b3JkV3JhcDogWydvdmVyZmxvd1dyYXAnXVxufTtcblxuLyoqXG4gKiBDU1MgcHJvcGVydGllcyB3aGljaCBhY2NlcHQgbnVtYmVycyBidXQgYXJlIG5vdCBpbiB1bml0cyBvZiBcInB4XCIuXG4gKi9cbnZhciBpc1VuaXRsZXNzTnVtYmVyID0ge1xuICBhbmltYXRpb25JdGVyYXRpb25Db3VudDogdHJ1ZSxcbiAgYXNwZWN0UmF0aW86IHRydWUsXG4gIGJvcmRlckltYWdlT3V0c2V0OiB0cnVlLFxuICBib3JkZXJJbWFnZVNsaWNlOiB0cnVlLFxuICBib3JkZXJJbWFnZVdpZHRoOiB0cnVlLFxuICBib3hGbGV4OiB0cnVlLFxuICBib3hGbGV4R3JvdXA6IHRydWUsXG4gIGJveE9yZGluYWxHcm91cDogdHJ1ZSxcbiAgY29sdW1uQ291bnQ6IHRydWUsXG4gIGNvbHVtbnM6IHRydWUsXG4gIGZsZXg6IHRydWUsXG4gIGZsZXhHcm93OiB0cnVlLFxuICBmbGV4UG9zaXRpdmU6IHRydWUsXG4gIGZsZXhTaHJpbms6IHRydWUsXG4gIGZsZXhOZWdhdGl2ZTogdHJ1ZSxcbiAgZmxleE9yZGVyOiB0cnVlLFxuICBncmlkQXJlYTogdHJ1ZSxcbiAgZ3JpZFJvdzogdHJ1ZSxcbiAgZ3JpZFJvd0VuZDogdHJ1ZSxcbiAgZ3JpZFJvd1NwYW46IHRydWUsXG4gIGdyaWRSb3dTdGFydDogdHJ1ZSxcbiAgZ3JpZENvbHVtbjogdHJ1ZSxcbiAgZ3JpZENvbHVtbkVuZDogdHJ1ZSxcbiAgZ3JpZENvbHVtblNwYW46IHRydWUsXG4gIGdyaWRDb2x1bW5TdGFydDogdHJ1ZSxcbiAgZm9udFdlaWdodDogdHJ1ZSxcbiAgbGluZUNsYW1wOiB0cnVlLFxuICBsaW5lSGVpZ2h0OiB0cnVlLFxuICBvcGFjaXR5OiB0cnVlLFxuICBvcmRlcjogdHJ1ZSxcbiAgb3JwaGFuczogdHJ1ZSxcbiAgdGFiU2l6ZTogdHJ1ZSxcbiAgd2lkb3dzOiB0cnVlLFxuICB6SW5kZXg6IHRydWUsXG4gIHpvb206IHRydWUsXG4gIC8vIFNWRy1yZWxhdGVkIHByb3BlcnRpZXNcbiAgZmlsbE9wYWNpdHk6IHRydWUsXG4gIGZsb29kT3BhY2l0eTogdHJ1ZSxcbiAgc3RvcE9wYWNpdHk6IHRydWUsXG4gIHN0cm9rZURhc2hhcnJheTogdHJ1ZSxcbiAgc3Ryb2tlRGFzaG9mZnNldDogdHJ1ZSxcbiAgc3Ryb2tlTWl0ZXJsaW1pdDogdHJ1ZSxcbiAgc3Ryb2tlT3BhY2l0eTogdHJ1ZSxcbiAgc3Ryb2tlV2lkdGg6IHRydWVcbn07XG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcmVmaXggdmVuZG9yLXNwZWNpZmljIHByZWZpeCwgZWc6IFdlYmtpdFxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBzdHlsZSBuYW1lLCBlZzogdHJhbnNpdGlvbkR1cmF0aW9uXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHN0eWxlIG5hbWUgcHJlZml4ZWQgd2l0aCBgcHJlZml4YCwgcHJvcGVybHkgY2FtZWxDYXNlZCwgZWc6XG4gKiBXZWJraXRUcmFuc2l0aW9uRHVyYXRpb25cbiAqL1xuXG5mdW5jdGlvbiBwcmVmaXhLZXkocHJlZml4LCBrZXkpIHtcbiAgcmV0dXJuIHByZWZpeCArIGtleS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIGtleS5zdWJzdHJpbmcoMSk7XG59XG4vKipcbiAqIFN1cHBvcnQgc3R5bGUgbmFtZXMgdGhhdCBtYXkgY29tZSBwYXNzZWQgaW4gcHJlZml4ZWQgYnkgYWRkaW5nIHBlcm11dGF0aW9uc1xuICogb2YgdmVuZG9yIHByZWZpeGVzLlxuICovXG5cblxudmFyIHByZWZpeGVzID0gWydXZWJraXQnLCAnbXMnLCAnTW96JywgJ08nXTsgLy8gVXNpbmcgT2JqZWN0LmtleXMgaGVyZSwgb3IgZWxzZSB0aGUgdmFuaWxsYSBmb3ItaW4gbG9vcCBtYWtlcyBJRTggZ28gaW50byBhblxuLy8gaW5maW5pdGUgbG9vcCwgYmVjYXVzZSBpdCBpdGVyYXRlcyBvdmVyIHRoZSBuZXdseSBhZGRlZCBwcm9wcyB0b28uXG5cbk9iamVjdC5rZXlzKGlzVW5pdGxlc3NOdW1iZXIpLmZvckVhY2goZnVuY3Rpb24gKHByb3ApIHtcbiAgcHJlZml4ZXMuZm9yRWFjaChmdW5jdGlvbiAocHJlZml4KSB7XG4gICAgaXNVbml0bGVzc051bWJlcltwcmVmaXhLZXkocHJlZml4LCBwcm9wKV0gPSBpc1VuaXRsZXNzTnVtYmVyW3Byb3BdO1xuICB9KTtcbn0pO1xuXG4vKipcbiAqIENvbnZlcnQgYSB2YWx1ZSBpbnRvIHRoZSBwcm9wZXIgY3NzIHdyaXRhYmxlIHZhbHVlLiBUaGUgc3R5bGUgbmFtZSBgbmFtZWBcbiAqIHNob3VsZCBiZSBsb2dpY2FsIChubyBoeXBoZW5zKSwgYXMgc3BlY2lmaWVkXG4gKiBpbiBgQ1NTUHJvcGVydHkuaXNVbml0bGVzc051bWJlcmAuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgQ1NTIHByb3BlcnR5IG5hbWUgc3VjaCBhcyBgdG9wTWFyZ2luYC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgQ1NTIHByb3BlcnR5IHZhbHVlIHN1Y2ggYXMgYDEwcHhgLlxuICogQHJldHVybiB7c3RyaW5nfSBOb3JtYWxpemVkIHN0eWxlIHZhbHVlIHdpdGggZGltZW5zaW9ucyBhcHBsaWVkLlxuICovXG5cbmZ1bmN0aW9uIGRhbmdlcm91c1N0eWxlVmFsdWUobmFtZSwgdmFsdWUsIGlzQ3VzdG9tUHJvcGVydHkpIHtcbiAgLy8gTm90ZSB0aGF0IHdlJ3ZlIHJlbW92ZWQgZXNjYXBlVGV4dEZvckJyb3dzZXIoKSBjYWxscyBoZXJlIHNpbmNlIHRoZVxuICAvLyB3aG9sZSBzdHJpbmcgd2lsbCBiZSBlc2NhcGVkIHdoZW4gdGhlIGF0dHJpYnV0ZSBpcyBpbmplY3RlZCBpbnRvXG4gIC8vIHRoZSBtYXJrdXAuIElmIHlvdSBwcm92aWRlIHVuc2FmZSB1c2VyIGRhdGEgaGVyZSB0aGV5IGNhbiBpbmplY3RcbiAgLy8gYXJiaXRyYXJ5IENTUyB3aGljaCBtYXkgYmUgcHJvYmxlbWF0aWMgKEkgY291bGRuJ3QgcmVwcm8gdGhpcyk6XG4gIC8vIGh0dHBzOi8vd3d3Lm93YXNwLm9yZy9pbmRleC5waHAvWFNTX0ZpbHRlcl9FdmFzaW9uX0NoZWF0X1NoZWV0XG4gIC8vIGh0dHA6Ly93d3cudGhlc3Bhbm5lci5jby51ay8yMDA3LzExLzI2L3VsdGltYXRlLXhzcy1jc3MtaW5qZWN0aW9uL1xuICAvLyBUaGlzIGlzIG5vdCBhbiBYU1MgaG9sZSBidXQgaW5zdGVhZCBhIHBvdGVudGlhbCBDU1MgaW5qZWN0aW9uIGlzc3VlXG4gIC8vIHdoaWNoIGhhcyBsZWFkIHRvIGEgZ3JlYXRlciBkaXNjdXNzaW9uIGFib3V0IGhvdyB3ZSdyZSBnb2luZyB0b1xuICAvLyB0cnVzdCBVUkxzIG1vdmluZyBmb3J3YXJkLiBTZWUgIzIxMTU5MDFcbiAgdmFyIGlzRW1wdHkgPSB2YWx1ZSA9PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nIHx8IHZhbHVlID09PSAnJztcblxuICBpZiAoaXNFbXB0eSkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGlmICghaXNDdXN0b21Qcm9wZXJ0eSAmJiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmIHZhbHVlICE9PSAwICYmICEoaXNVbml0bGVzc051bWJlci5oYXNPd25Qcm9wZXJ0eShuYW1lKSAmJiBpc1VuaXRsZXNzTnVtYmVyW25hbWVdKSkge1xuICAgIHJldHVybiB2YWx1ZSArICdweCc7IC8vIFByZXN1bWVzIGltcGxpY2l0ICdweCcgc3VmZml4IGZvciB1bml0bGVzcyBudW1iZXJzXG4gIH1cblxuICB7XG4gICAgY2hlY2tDU1NQcm9wZXJ0eVN0cmluZ0NvZXJjaW9uKHZhbHVlLCBuYW1lKTtcbiAgfVxuXG4gIHJldHVybiAoJycgKyB2YWx1ZSkudHJpbSgpO1xufVxuXG52YXIgdXBwZXJjYXNlUGF0dGVybiA9IC8oW0EtWl0pL2c7XG52YXIgbXNQYXR0ZXJuID0gL15tcy0vO1xuLyoqXG4gKiBIeXBoZW5hdGVzIGEgY2FtZWxjYXNlZCBDU1MgcHJvcGVydHkgbmFtZSwgZm9yIGV4YW1wbGU6XG4gKlxuICogICA+IGh5cGhlbmF0ZVN0eWxlTmFtZSgnYmFja2dyb3VuZENvbG9yJylcbiAqICAgPCBcImJhY2tncm91bmQtY29sb3JcIlxuICogICA+IGh5cGhlbmF0ZVN0eWxlTmFtZSgnTW96VHJhbnNpdGlvbicpXG4gKiAgIDwgXCItbW96LXRyYW5zaXRpb25cIlxuICogICA+IGh5cGhlbmF0ZVN0eWxlTmFtZSgnbXNUcmFuc2l0aW9uJylcbiAqICAgPCBcIi1tcy10cmFuc2l0aW9uXCJcbiAqXG4gKiBBcyBNb2Rlcm5penIgc3VnZ2VzdHMgKGh0dHA6Ly9tb2Rlcm5penIuY29tL2RvY3MvI3ByZWZpeGVkKSwgYW4gYG1zYCBwcmVmaXhcbiAqIGlzIGNvbnZlcnRlZCB0byBgLW1zLWAuXG4gKi9cblxuZnVuY3Rpb24gaHlwaGVuYXRlU3R5bGVOYW1lKG5hbWUpIHtcbiAgcmV0dXJuIG5hbWUucmVwbGFjZSh1cHBlcmNhc2VQYXR0ZXJuLCAnLSQxJykudG9Mb3dlckNhc2UoKS5yZXBsYWNlKG1zUGF0dGVybiwgJy1tcy0nKTtcbn1cblxudmFyIHdhcm5WYWxpZFN0eWxlID0gZnVuY3Rpb24gKCkge307XG5cbntcbiAgLy8gJ21zVHJhbnNmb3JtJyBpcyBjb3JyZWN0LCBidXQgdGhlIG90aGVyIHByZWZpeGVzIHNob3VsZCBiZSBjYXBpdGFsaXplZFxuICB2YXIgYmFkVmVuZG9yZWRTdHlsZU5hbWVQYXR0ZXJuID0gL14oPzp3ZWJraXR8bW96fG8pW0EtWl0vO1xuICB2YXIgbXNQYXR0ZXJuJDEgPSAvXi1tcy0vO1xuICB2YXIgaHlwaGVuUGF0dGVybiA9IC8tKC4pL2c7IC8vIHN0eWxlIHZhbHVlcyBzaG91bGRuJ3QgY29udGFpbiBhIHNlbWljb2xvblxuXG4gIHZhciBiYWRTdHlsZVZhbHVlV2l0aFNlbWljb2xvblBhdHRlcm4gPSAvO1xccyokLztcbiAgdmFyIHdhcm5lZFN0eWxlTmFtZXMgPSB7fTtcbiAgdmFyIHdhcm5lZFN0eWxlVmFsdWVzID0ge307XG4gIHZhciB3YXJuZWRGb3JOYU5WYWx1ZSA9IGZhbHNlO1xuICB2YXIgd2FybmVkRm9ySW5maW5pdHlWYWx1ZSA9IGZhbHNlO1xuXG4gIHZhciBjYW1lbGl6ZSA9IGZ1bmN0aW9uIChzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nLnJlcGxhY2UoaHlwaGVuUGF0dGVybiwgZnVuY3Rpb24gKF8sIGNoYXJhY3Rlcikge1xuICAgICAgcmV0dXJuIGNoYXJhY3Rlci50b1VwcGVyQ2FzZSgpO1xuICAgIH0pO1xuICB9O1xuXG4gIHZhciB3YXJuSHlwaGVuYXRlZFN0eWxlTmFtZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgaWYgKHdhcm5lZFN0eWxlTmFtZXMuaGFzT3duUHJvcGVydHkobmFtZSkgJiYgd2FybmVkU3R5bGVOYW1lc1tuYW1lXSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdhcm5lZFN0eWxlTmFtZXNbbmFtZV0gPSB0cnVlO1xuXG4gICAgZXJyb3IoJ1Vuc3VwcG9ydGVkIHN0eWxlIHByb3BlcnR5ICVzLiBEaWQgeW91IG1lYW4gJXM/JywgbmFtZSwgLy8gQXMgQW5kaSBTbWl0aCBzdWdnZXN0c1xuICAgIC8vIChodHRwOi8vd3d3LmFuZGlzbWl0aC5jb20vYmxvZy8yMDEyLzAyL21vZGVybml6ci1wcmVmaXhlZC8pLCBhbiBgLW1zYCBwcmVmaXhcbiAgICAvLyBpcyBjb252ZXJ0ZWQgdG8gbG93ZXJjYXNlIGBtc2AuXG4gICAgY2FtZWxpemUobmFtZS5yZXBsYWNlKG1zUGF0dGVybiQxLCAnbXMtJykpKTtcbiAgfTtcblxuICB2YXIgd2FybkJhZFZlbmRvcmVkU3R5bGVOYW1lID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICBpZiAod2FybmVkU3R5bGVOYW1lcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSAmJiB3YXJuZWRTdHlsZU5hbWVzW25hbWVdKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2FybmVkU3R5bGVOYW1lc1tuYW1lXSA9IHRydWU7XG5cbiAgICBlcnJvcignVW5zdXBwb3J0ZWQgdmVuZG9yLXByZWZpeGVkIHN0eWxlIHByb3BlcnR5ICVzLiBEaWQgeW91IG1lYW4gJXM/JywgbmFtZSwgbmFtZS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIG5hbWUuc2xpY2UoMSkpO1xuICB9O1xuXG4gIHZhciB3YXJuU3R5bGVWYWx1ZVdpdGhTZW1pY29sb24gPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgICBpZiAod2FybmVkU3R5bGVWYWx1ZXMuaGFzT3duUHJvcGVydHkodmFsdWUpICYmIHdhcm5lZFN0eWxlVmFsdWVzW3ZhbHVlXSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdhcm5lZFN0eWxlVmFsdWVzW3ZhbHVlXSA9IHRydWU7XG5cbiAgICBlcnJvcihcIlN0eWxlIHByb3BlcnR5IHZhbHVlcyBzaG91bGRuJ3QgY29udGFpbiBhIHNlbWljb2xvbi4gXCIgKyAnVHJ5IFwiJXM6ICVzXCIgaW5zdGVhZC4nLCBuYW1lLCB2YWx1ZS5yZXBsYWNlKGJhZFN0eWxlVmFsdWVXaXRoU2VtaWNvbG9uUGF0dGVybiwgJycpKTtcbiAgfTtcblxuICB2YXIgd2FyblN0eWxlVmFsdWVJc05hTiA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICAgIGlmICh3YXJuZWRGb3JOYU5WYWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdhcm5lZEZvck5hTlZhbHVlID0gdHJ1ZTtcblxuICAgIGVycm9yKCdgTmFOYCBpcyBhbiBpbnZhbGlkIHZhbHVlIGZvciB0aGUgYCVzYCBjc3Mgc3R5bGUgcHJvcGVydHkuJywgbmFtZSk7XG4gIH07XG5cbiAgdmFyIHdhcm5TdHlsZVZhbHVlSXNJbmZpbml0eSA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICAgIGlmICh3YXJuZWRGb3JJbmZpbml0eVZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2FybmVkRm9ySW5maW5pdHlWYWx1ZSA9IHRydWU7XG5cbiAgICBlcnJvcignYEluZmluaXR5YCBpcyBhbiBpbnZhbGlkIHZhbHVlIGZvciB0aGUgYCVzYCBjc3Mgc3R5bGUgcHJvcGVydHkuJywgbmFtZSk7XG4gIH07XG5cbiAgd2FyblZhbGlkU3R5bGUgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgICBpZiAobmFtZS5pbmRleE9mKCctJykgPiAtMSkge1xuICAgICAgd2Fybkh5cGhlbmF0ZWRTdHlsZU5hbWUobmFtZSk7XG4gICAgfSBlbHNlIGlmIChiYWRWZW5kb3JlZFN0eWxlTmFtZVBhdHRlcm4udGVzdChuYW1lKSkge1xuICAgICAgd2FybkJhZFZlbmRvcmVkU3R5bGVOYW1lKG5hbWUpO1xuICAgIH0gZWxzZSBpZiAoYmFkU3R5bGVWYWx1ZVdpdGhTZW1pY29sb25QYXR0ZXJuLnRlc3QodmFsdWUpKSB7XG4gICAgICB3YXJuU3R5bGVWYWx1ZVdpdGhTZW1pY29sb24obmFtZSwgdmFsdWUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICBpZiAoaXNOYU4odmFsdWUpKSB7XG4gICAgICAgIHdhcm5TdHlsZVZhbHVlSXNOYU4obmFtZSwgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmICghaXNGaW5pdGUodmFsdWUpKSB7XG4gICAgICAgIHdhcm5TdHlsZVZhbHVlSXNJbmZpbml0eShuYW1lLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG52YXIgd2FyblZhbGlkU3R5bGUkMSA9IHdhcm5WYWxpZFN0eWxlO1xuXG4vKipcbiAqIE9wZXJhdGlvbnMgZm9yIGRlYWxpbmcgd2l0aCBDU1MgcHJvcGVydGllcy5cbiAqL1xuXG4vKipcbiAqIFRoaXMgY3JlYXRlcyBhIHN0cmluZyB0aGF0IGlzIGV4cGVjdGVkIHRvIGJlIGVxdWl2YWxlbnQgdG8gdGhlIHN0eWxlXG4gKiBhdHRyaWJ1dGUgZ2VuZXJhdGVkIGJ5IHNlcnZlci1zaWRlIHJlbmRlcmluZy4gSXQgYnktcGFzc2VzIHdhcm5pbmdzIGFuZFxuICogc2VjdXJpdHkgY2hlY2tzIHNvIGl0J3Mgbm90IHNhZmUgdG8gdXNlIHRoaXMgdmFsdWUgZm9yIGFueXRoaW5nIG90aGVyIHRoYW5cbiAqIGNvbXBhcmlzb24uIEl0IGlzIG9ubHkgdXNlZCBpbiBERVYgZm9yIFNTUiB2YWxpZGF0aW9uLlxuICovXG5cbmZ1bmN0aW9uIGNyZWF0ZURhbmdlcm91c1N0cmluZ0ZvclN0eWxlcyhzdHlsZXMpIHtcbiAge1xuICAgIHZhciBzZXJpYWxpemVkID0gJyc7XG4gICAgdmFyIGRlbGltaXRlciA9ICcnO1xuXG4gICAgZm9yICh2YXIgc3R5bGVOYW1lIGluIHN0eWxlcykge1xuICAgICAgaWYgKCFzdHlsZXMuaGFzT3duUHJvcGVydHkoc3R5bGVOYW1lKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIHN0eWxlVmFsdWUgPSBzdHlsZXNbc3R5bGVOYW1lXTtcblxuICAgICAgaWYgKHN0eWxlVmFsdWUgIT0gbnVsbCkge1xuICAgICAgICB2YXIgaXNDdXN0b21Qcm9wZXJ0eSA9IHN0eWxlTmFtZS5pbmRleE9mKCctLScpID09PSAwO1xuICAgICAgICBzZXJpYWxpemVkICs9IGRlbGltaXRlciArIChpc0N1c3RvbVByb3BlcnR5ID8gc3R5bGVOYW1lIDogaHlwaGVuYXRlU3R5bGVOYW1lKHN0eWxlTmFtZSkpICsgJzonO1xuICAgICAgICBzZXJpYWxpemVkICs9IGRhbmdlcm91c1N0eWxlVmFsdWUoc3R5bGVOYW1lLCBzdHlsZVZhbHVlLCBpc0N1c3RvbVByb3BlcnR5KTtcbiAgICAgICAgZGVsaW1pdGVyID0gJzsnO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzZXJpYWxpemVkIHx8IG51bGw7XG4gIH1cbn1cbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgZm9yIG11bHRpcGxlIHN0eWxlcyBvbiBhIG5vZGUuICBJZiBhIHZhbHVlIGlzIHNwZWNpZmllZCBhc1xuICogJycgKGVtcHR5IHN0cmluZyksIHRoZSBjb3JyZXNwb25kaW5nIHN0eWxlIHByb3BlcnR5IHdpbGwgYmUgdW5zZXQuXG4gKlxuICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXG4gKiBAcGFyYW0ge29iamVjdH0gc3R5bGVzXG4gKi9cblxuZnVuY3Rpb24gc2V0VmFsdWVGb3JTdHlsZXMobm9kZSwgc3R5bGVzKSB7XG4gIHZhciBzdHlsZSA9IG5vZGUuc3R5bGU7XG5cbiAgZm9yICh2YXIgc3R5bGVOYW1lIGluIHN0eWxlcykge1xuICAgIGlmICghc3R5bGVzLmhhc093blByb3BlcnR5KHN0eWxlTmFtZSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHZhciBpc0N1c3RvbVByb3BlcnR5ID0gc3R5bGVOYW1lLmluZGV4T2YoJy0tJykgPT09IDA7XG5cbiAgICB7XG4gICAgICBpZiAoIWlzQ3VzdG9tUHJvcGVydHkpIHtcbiAgICAgICAgd2FyblZhbGlkU3R5bGUkMShzdHlsZU5hbWUsIHN0eWxlc1tzdHlsZU5hbWVdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgc3R5bGVWYWx1ZSA9IGRhbmdlcm91c1N0eWxlVmFsdWUoc3R5bGVOYW1lLCBzdHlsZXNbc3R5bGVOYW1lXSwgaXNDdXN0b21Qcm9wZXJ0eSk7XG5cbiAgICBpZiAoc3R5bGVOYW1lID09PSAnZmxvYXQnKSB7XG4gICAgICBzdHlsZU5hbWUgPSAnY3NzRmxvYXQnO1xuICAgIH1cblxuICAgIGlmIChpc0N1c3RvbVByb3BlcnR5KSB7XG4gICAgICBzdHlsZS5zZXRQcm9wZXJ0eShzdHlsZU5hbWUsIHN0eWxlVmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHlsZVtzdHlsZU5hbWVdID0gc3R5bGVWYWx1ZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNWYWx1ZUVtcHR5KHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nIHx8IHZhbHVlID09PSAnJztcbn1cbi8qKlxuICogR2l2ZW4ge2NvbG9yOiAncmVkJywgb3ZlcmZsb3c6ICdoaWRkZW4nfSByZXR1cm5zIHtcbiAqICAgY29sb3I6ICdjb2xvcicsXG4gKiAgIG92ZXJmbG93WDogJ292ZXJmbG93JyxcbiAqICAgb3ZlcmZsb3dZOiAnb3ZlcmZsb3cnLFxuICogfS4gVGhpcyBjYW4gYmUgcmVhZCBhcyBcInRoZSBvdmVyZmxvd1kgcHJvcGVydHkgd2FzIHNldCBieSB0aGUgb3ZlcmZsb3dcbiAqIHNob3J0aGFuZFwiLiBUaGF0IGlzLCB0aGUgdmFsdWVzIGFyZSB0aGUgcHJvcGVydHkgdGhhdCBlYWNoIHdhcyBkZXJpdmVkIGZyb20uXG4gKi9cblxuXG5mdW5jdGlvbiBleHBhbmRTaG9ydGhhbmRNYXAoc3R5bGVzKSB7XG4gIHZhciBleHBhbmRlZCA9IHt9O1xuXG4gIGZvciAodmFyIGtleSBpbiBzdHlsZXMpIHtcbiAgICB2YXIgbG9uZ2hhbmRzID0gc2hvcnRoYW5kVG9Mb25naGFuZFtrZXldIHx8IFtrZXldO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsb25naGFuZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGV4cGFuZGVkW2xvbmdoYW5kc1tpXV0gPSBrZXk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGV4cGFuZGVkO1xufVxuLyoqXG4gKiBXaGVuIG1peGluZyBzaG9ydGhhbmQgYW5kIGxvbmdoYW5kIHByb3BlcnR5IG5hbWVzLCB3ZSB3YXJuIGR1cmluZyB1cGRhdGVzIGlmXG4gKiB3ZSBleHBlY3QgYW4gaW5jb3JyZWN0IHJlc3VsdCB0byBvY2N1ci4gSW4gcGFydGljdWxhciwgd2Ugd2FybiBmb3I6XG4gKlxuICogVXBkYXRpbmcgYSBzaG9ydGhhbmQgcHJvcGVydHkgKGxvbmdoYW5kIGdldHMgb3ZlcndyaXR0ZW4pOlxuICogICB7Zm9udDogJ2ZvbycsIGZvbnRWYXJpYW50OiAnYmFyJ30gLT4ge2ZvbnQ6ICdiYXonLCBmb250VmFyaWFudDogJ2Jhcid9XG4gKiAgIGJlY29tZXMgLnN0eWxlLmZvbnQgPSAnYmF6J1xuICogUmVtb3ZpbmcgYSBzaG9ydGhhbmQgcHJvcGVydHkgKGxvbmdoYW5kIGdldHMgbG9zdCB0b28pOlxuICogICB7Zm9udDogJ2ZvbycsIGZvbnRWYXJpYW50OiAnYmFyJ30gLT4ge2ZvbnRWYXJpYW50OiAnYmFyJ31cbiAqICAgYmVjb21lcyAuc3R5bGUuZm9udCA9ICcnXG4gKiBSZW1vdmluZyBhIGxvbmdoYW5kIHByb3BlcnR5IChzaG91bGQgcmV2ZXJ0IHRvIHNob3J0aGFuZDsgZG9lc24ndCk6XG4gKiAgIHtmb250OiAnZm9vJywgZm9udFZhcmlhbnQ6ICdiYXInfSAtPiB7Zm9udDogJ2Zvbyd9XG4gKiAgIGJlY29tZXMgLnN0eWxlLmZvbnRWYXJpYW50ID0gJydcbiAqL1xuXG5cbmZ1bmN0aW9uIHZhbGlkYXRlU2hvcnRoYW5kUHJvcGVydHlDb2xsaXNpb25JbkRldihzdHlsZVVwZGF0ZXMsIG5leHRTdHlsZXMpIHtcbiAge1xuICAgIGlmICghbmV4dFN0eWxlcykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBleHBhbmRlZFVwZGF0ZXMgPSBleHBhbmRTaG9ydGhhbmRNYXAoc3R5bGVVcGRhdGVzKTtcbiAgICB2YXIgZXhwYW5kZWRTdHlsZXMgPSBleHBhbmRTaG9ydGhhbmRNYXAobmV4dFN0eWxlcyk7XG4gICAgdmFyIHdhcm5lZEFib3V0ID0ge307XG5cbiAgICBmb3IgKHZhciBrZXkgaW4gZXhwYW5kZWRVcGRhdGVzKSB7XG4gICAgICB2YXIgb3JpZ2luYWxLZXkgPSBleHBhbmRlZFVwZGF0ZXNba2V5XTtcbiAgICAgIHZhciBjb3JyZWN0T3JpZ2luYWxLZXkgPSBleHBhbmRlZFN0eWxlc1trZXldO1xuXG4gICAgICBpZiAoY29ycmVjdE9yaWdpbmFsS2V5ICYmIG9yaWdpbmFsS2V5ICE9PSBjb3JyZWN0T3JpZ2luYWxLZXkpIHtcbiAgICAgICAgdmFyIHdhcm5pbmdLZXkgPSBvcmlnaW5hbEtleSArICcsJyArIGNvcnJlY3RPcmlnaW5hbEtleTtcblxuICAgICAgICBpZiAod2FybmVkQWJvdXRbd2FybmluZ0tleV0pIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdhcm5lZEFib3V0W3dhcm5pbmdLZXldID0gdHJ1ZTtcblxuICAgICAgICBlcnJvcignJXMgYSBzdHlsZSBwcm9wZXJ0eSBkdXJpbmcgcmVyZW5kZXIgKCVzKSB3aGVuIGEgJyArICdjb25mbGljdGluZyBwcm9wZXJ0eSBpcyBzZXQgKCVzKSBjYW4gbGVhZCB0byBzdHlsaW5nIGJ1Z3MuIFRvICcgKyBcImF2b2lkIHRoaXMsIGRvbid0IG1peCBzaG9ydGhhbmQgYW5kIG5vbi1zaG9ydGhhbmQgcHJvcGVydGllcyBcIiArICdmb3IgdGhlIHNhbWUgdmFsdWU7IGluc3RlYWQsIHJlcGxhY2UgdGhlIHNob3J0aGFuZCB3aXRoICcgKyAnc2VwYXJhdGUgdmFsdWVzLicsIGlzVmFsdWVFbXB0eShzdHlsZVVwZGF0ZXNbb3JpZ2luYWxLZXldKSA/ICdSZW1vdmluZycgOiAnVXBkYXRpbmcnLCBvcmlnaW5hbEtleSwgY29ycmVjdE9yaWdpbmFsS2V5KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gRm9yIEhUTUwsIGNlcnRhaW4gdGFncyBzaG91bGQgb21pdCB0aGVpciBjbG9zZSB0YWcuIFdlIGtlZXAgYSBsaXN0IGZvclxuLy8gdGhvc2Ugc3BlY2lhbC1jYXNlIHRhZ3MuXG52YXIgb21pdHRlZENsb3NlVGFncyA9IHtcbiAgYXJlYTogdHJ1ZSxcbiAgYmFzZTogdHJ1ZSxcbiAgYnI6IHRydWUsXG4gIGNvbDogdHJ1ZSxcbiAgZW1iZWQ6IHRydWUsXG4gIGhyOiB0cnVlLFxuICBpbWc6IHRydWUsXG4gIGlucHV0OiB0cnVlLFxuICBrZXlnZW46IHRydWUsXG4gIGxpbms6IHRydWUsXG4gIG1ldGE6IHRydWUsXG4gIHBhcmFtOiB0cnVlLFxuICBzb3VyY2U6IHRydWUsXG4gIHRyYWNrOiB0cnVlLFxuICB3YnI6IHRydWUgLy8gTk9URTogbWVudWl0ZW0ncyBjbG9zZSB0YWcgc2hvdWxkIGJlIG9taXR0ZWQsIGJ1dCB0aGF0IGNhdXNlcyBwcm9ibGVtcy5cblxufTtcblxuLy8gYG9taXR0ZWRDbG9zZVRhZ3NgIGV4Y2VwdCB0aGF0IGBtZW51aXRlbWAgc2hvdWxkIHN0aWxsIGhhdmUgaXRzIGNsb3NpbmcgdGFnLlxuXG52YXIgdm9pZEVsZW1lbnRUYWdzID0gYXNzaWduKHtcbiAgbWVudWl0ZW06IHRydWVcbn0sIG9taXR0ZWRDbG9zZVRhZ3MpO1xuXG52YXIgSFRNTCA9ICdfX2h0bWwnO1xuXG5mdW5jdGlvbiBhc3NlcnRWYWxpZFByb3BzKHRhZywgcHJvcHMpIHtcbiAgaWYgKCFwcm9wcykge1xuICAgIHJldHVybjtcbiAgfSAvLyBOb3RlIHRoZSB1c2Ugb2YgYD09YCB3aGljaCBjaGVja3MgZm9yIG51bGwgb3IgdW5kZWZpbmVkLlxuXG5cbiAgaWYgKHZvaWRFbGVtZW50VGFnc1t0YWddKSB7XG4gICAgaWYgKHByb3BzLmNoaWxkcmVuICE9IG51bGwgfHwgcHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwgIT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHRhZyArIFwiIGlzIGEgdm9pZCBlbGVtZW50IHRhZyBhbmQgbXVzdCBuZWl0aGVyIGhhdmUgYGNoaWxkcmVuYCBub3IgXCIgKyAndXNlIGBkYW5nZXJvdXNseVNldElubmVySFRNTGAuJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MICE9IG51bGwpIHtcbiAgICBpZiAocHJvcHMuY2hpbGRyZW4gIT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gb25seSBzZXQgb25lIG9mIGBjaGlsZHJlbmAgb3IgYHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MYC4nKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MICE9PSAnb2JqZWN0JyB8fCAhKEhUTUwgaW4gcHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Bwcm9wcy5kYW5nZXJvdXNseVNldElubmVySFRNTGAgbXVzdCBiZSBpbiB0aGUgZm9ybSBge19faHRtbDogLi4ufWAuICcgKyAnUGxlYXNlIHZpc2l0IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9kYW5nZXJvdXNseS1zZXQtaW5uZXItaHRtbCAnICsgJ2ZvciBtb3JlIGluZm9ybWF0aW9uLicpO1xuICAgIH1cbiAgfVxuXG4gIHtcbiAgICBpZiAoIXByb3BzLnN1cHByZXNzQ29udGVudEVkaXRhYmxlV2FybmluZyAmJiBwcm9wcy5jb250ZW50RWRpdGFibGUgJiYgcHJvcHMuY2hpbGRyZW4gIT0gbnVsbCkge1xuICAgICAgZXJyb3IoJ0EgY29tcG9uZW50IGlzIGBjb250ZW50RWRpdGFibGVgIGFuZCBjb250YWlucyBgY2hpbGRyZW5gIG1hbmFnZWQgYnkgJyArICdSZWFjdC4gSXQgaXMgbm93IHlvdXIgcmVzcG9uc2liaWxpdHkgdG8gZ3VhcmFudGVlIHRoYXQgbm9uZSBvZiAnICsgJ3Rob3NlIG5vZGVzIGFyZSB1bmV4cGVjdGVkbHkgbW9kaWZpZWQgb3IgZHVwbGljYXRlZC4gVGhpcyBpcyAnICsgJ3Byb2JhYmx5IG5vdCBpbnRlbnRpb25hbC4nKTtcbiAgICB9XG4gIH1cblxuICBpZiAocHJvcHMuc3R5bGUgIT0gbnVsbCAmJiB0eXBlb2YgcHJvcHMuc3R5bGUgIT09ICdvYmplY3QnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgYHN0eWxlYCBwcm9wIGV4cGVjdHMgYSBtYXBwaW5nIGZyb20gc3R5bGUgcHJvcGVydGllcyB0byB2YWx1ZXMsICcgKyBcIm5vdCBhIHN0cmluZy4gRm9yIGV4YW1wbGUsIHN0eWxlPXt7bWFyZ2luUmlnaHQ6IHNwYWNpbmcgKyAnZW0nfX0gd2hlbiBcIiArICd1c2luZyBKU1guJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNDdXN0b21Db21wb25lbnQodGFnTmFtZSwgcHJvcHMpIHtcbiAgaWYgKHRhZ05hbWUuaW5kZXhPZignLScpID09PSAtMSkge1xuICAgIHJldHVybiB0eXBlb2YgcHJvcHMuaXMgPT09ICdzdHJpbmcnO1xuICB9XG5cbiAgc3dpdGNoICh0YWdOYW1lKSB7XG4gICAgLy8gVGhlc2UgYXJlIHJlc2VydmVkIFNWRyBhbmQgTWF0aE1MIGVsZW1lbnRzLlxuICAgIC8vIFdlIGRvbid0IG1pbmQgdGhpcyBsaXN0IHRvbyBtdWNoIGJlY2F1c2Ugd2UgZXhwZWN0IGl0IHRvIG5ldmVyIGdyb3cuXG4gICAgLy8gVGhlIGFsdGVybmF0aXZlIGlzIHRvIHRyYWNrIHRoZSBuYW1lc3BhY2UgaW4gYSBmZXcgcGxhY2VzIHdoaWNoIGlzIGNvbnZvbHV0ZWQuXG4gICAgLy8gaHR0cHM6Ly93M2MuZ2l0aHViLmlvL3dlYmNvbXBvbmVudHMvc3BlYy9jdXN0b20vI2N1c3RvbS1lbGVtZW50cy1jb3JlLWNvbmNlcHRzXG4gICAgY2FzZSAnYW5ub3RhdGlvbi14bWwnOlxuICAgIGNhc2UgJ2NvbG9yLXByb2ZpbGUnOlxuICAgIGNhc2UgJ2ZvbnQtZmFjZSc6XG4gICAgY2FzZSAnZm9udC1mYWNlLXNyYyc6XG4gICAgY2FzZSAnZm9udC1mYWNlLXVyaSc6XG4gICAgY2FzZSAnZm9udC1mYWNlLWZvcm1hdCc6XG4gICAgY2FzZSAnZm9udC1mYWNlLW5hbWUnOlxuICAgIGNhc2UgJ21pc3NpbmctZ2x5cGgnOlxuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB0cnVlO1xuICB9XG59XG5cbi8vIFdoZW4gYWRkaW5nIGF0dHJpYnV0ZXMgdG8gdGhlIEhUTUwgb3IgU1ZHIGFsbG93ZWQgYXR0cmlidXRlIGxpc3QsIGJlIHN1cmUgdG9cbi8vIGFsc28gYWRkIHRoZW0gdG8gdGhpcyBtb2R1bGUgdG8gZW5zdXJlIGNhc2luZyBhbmQgaW5jb3JyZWN0IG5hbWVcbi8vIHdhcm5pbmdzLlxudmFyIHBvc3NpYmxlU3RhbmRhcmROYW1lcyA9IHtcbiAgLy8gSFRNTFxuICBhY2NlcHQ6ICdhY2NlcHQnLFxuICBhY2NlcHRjaGFyc2V0OiAnYWNjZXB0Q2hhcnNldCcsXG4gICdhY2NlcHQtY2hhcnNldCc6ICdhY2NlcHRDaGFyc2V0JyxcbiAgYWNjZXNza2V5OiAnYWNjZXNzS2V5JyxcbiAgYWN0aW9uOiAnYWN0aW9uJyxcbiAgYWxsb3dmdWxsc2NyZWVuOiAnYWxsb3dGdWxsU2NyZWVuJyxcbiAgYWx0OiAnYWx0JyxcbiAgYXM6ICdhcycsXG4gIGFzeW5jOiAnYXN5bmMnLFxuICBhdXRvY2FwaXRhbGl6ZTogJ2F1dG9DYXBpdGFsaXplJyxcbiAgYXV0b2NvbXBsZXRlOiAnYXV0b0NvbXBsZXRlJyxcbiAgYXV0b2NvcnJlY3Q6ICdhdXRvQ29ycmVjdCcsXG4gIGF1dG9mb2N1czogJ2F1dG9Gb2N1cycsXG4gIGF1dG9wbGF5OiAnYXV0b1BsYXknLFxuICBhdXRvc2F2ZTogJ2F1dG9TYXZlJyxcbiAgY2FwdHVyZTogJ2NhcHR1cmUnLFxuICBjZWxscGFkZGluZzogJ2NlbGxQYWRkaW5nJyxcbiAgY2VsbHNwYWNpbmc6ICdjZWxsU3BhY2luZycsXG4gIGNoYWxsZW5nZTogJ2NoYWxsZW5nZScsXG4gIGNoYXJzZXQ6ICdjaGFyU2V0JyxcbiAgY2hlY2tlZDogJ2NoZWNrZWQnLFxuICBjaGlsZHJlbjogJ2NoaWxkcmVuJyxcbiAgY2l0ZTogJ2NpdGUnLFxuICBjbGFzczogJ2NsYXNzTmFtZScsXG4gIGNsYXNzaWQ6ICdjbGFzc0lEJyxcbiAgY2xhc3NuYW1lOiAnY2xhc3NOYW1lJyxcbiAgY29sczogJ2NvbHMnLFxuICBjb2xzcGFuOiAnY29sU3BhbicsXG4gIGNvbnRlbnQ6ICdjb250ZW50JyxcbiAgY29udGVudGVkaXRhYmxlOiAnY29udGVudEVkaXRhYmxlJyxcbiAgY29udGV4dG1lbnU6ICdjb250ZXh0TWVudScsXG4gIGNvbnRyb2xzOiAnY29udHJvbHMnLFxuICBjb250cm9sc2xpc3Q6ICdjb250cm9sc0xpc3QnLFxuICBjb29yZHM6ICdjb29yZHMnLFxuICBjcm9zc29yaWdpbjogJ2Nyb3NzT3JpZ2luJyxcbiAgZGFuZ2Vyb3VzbHlzZXRpbm5lcmh0bWw6ICdkYW5nZXJvdXNseVNldElubmVySFRNTCcsXG4gIGRhdGE6ICdkYXRhJyxcbiAgZGF0ZXRpbWU6ICdkYXRlVGltZScsXG4gIGRlZmF1bHQ6ICdkZWZhdWx0JyxcbiAgZGVmYXVsdGNoZWNrZWQ6ICdkZWZhdWx0Q2hlY2tlZCcsXG4gIGRlZmF1bHR2YWx1ZTogJ2RlZmF1bHRWYWx1ZScsXG4gIGRlZmVyOiAnZGVmZXInLFxuICBkaXI6ICdkaXInLFxuICBkaXNhYmxlZDogJ2Rpc2FibGVkJyxcbiAgZGlzYWJsZXBpY3R1cmVpbnBpY3R1cmU6ICdkaXNhYmxlUGljdHVyZUluUGljdHVyZScsXG4gIGRpc2FibGVyZW1vdGVwbGF5YmFjazogJ2Rpc2FibGVSZW1vdGVQbGF5YmFjaycsXG4gIGRvd25sb2FkOiAnZG93bmxvYWQnLFxuICBkcmFnZ2FibGU6ICdkcmFnZ2FibGUnLFxuICBlbmN0eXBlOiAnZW5jVHlwZScsXG4gIGVudGVya2V5aGludDogJ2VudGVyS2V5SGludCcsXG4gIGZvcjogJ2h0bWxGb3InLFxuICBmb3JtOiAnZm9ybScsXG4gIGZvcm1tZXRob2Q6ICdmb3JtTWV0aG9kJyxcbiAgZm9ybWFjdGlvbjogJ2Zvcm1BY3Rpb24nLFxuICBmb3JtZW5jdHlwZTogJ2Zvcm1FbmNUeXBlJyxcbiAgZm9ybW5vdmFsaWRhdGU6ICdmb3JtTm9WYWxpZGF0ZScsXG4gIGZvcm10YXJnZXQ6ICdmb3JtVGFyZ2V0JyxcbiAgZnJhbWVib3JkZXI6ICdmcmFtZUJvcmRlcicsXG4gIGhlYWRlcnM6ICdoZWFkZXJzJyxcbiAgaGVpZ2h0OiAnaGVpZ2h0JyxcbiAgaGlkZGVuOiAnaGlkZGVuJyxcbiAgaGlnaDogJ2hpZ2gnLFxuICBocmVmOiAnaHJlZicsXG4gIGhyZWZsYW5nOiAnaHJlZkxhbmcnLFxuICBodG1sZm9yOiAnaHRtbEZvcicsXG4gIGh0dHBlcXVpdjogJ2h0dHBFcXVpdicsXG4gICdodHRwLWVxdWl2JzogJ2h0dHBFcXVpdicsXG4gIGljb246ICdpY29uJyxcbiAgaWQ6ICdpZCcsXG4gIGltYWdlc2l6ZXM6ICdpbWFnZVNpemVzJyxcbiAgaW1hZ2VzcmNzZXQ6ICdpbWFnZVNyY1NldCcsXG4gIGlubmVyaHRtbDogJ2lubmVySFRNTCcsXG4gIGlucHV0bW9kZTogJ2lucHV0TW9kZScsXG4gIGludGVncml0eTogJ2ludGVncml0eScsXG4gIGlzOiAnaXMnLFxuICBpdGVtaWQ6ICdpdGVtSUQnLFxuICBpdGVtcHJvcDogJ2l0ZW1Qcm9wJyxcbiAgaXRlbXJlZjogJ2l0ZW1SZWYnLFxuICBpdGVtc2NvcGU6ICdpdGVtU2NvcGUnLFxuICBpdGVtdHlwZTogJ2l0ZW1UeXBlJyxcbiAga2V5cGFyYW1zOiAna2V5UGFyYW1zJyxcbiAga2V5dHlwZTogJ2tleVR5cGUnLFxuICBraW5kOiAna2luZCcsXG4gIGxhYmVsOiAnbGFiZWwnLFxuICBsYW5nOiAnbGFuZycsXG4gIGxpc3Q6ICdsaXN0JyxcbiAgbG9vcDogJ2xvb3AnLFxuICBsb3c6ICdsb3cnLFxuICBtYW5pZmVzdDogJ21hbmlmZXN0JyxcbiAgbWFyZ2lud2lkdGg6ICdtYXJnaW5XaWR0aCcsXG4gIG1hcmdpbmhlaWdodDogJ21hcmdpbkhlaWdodCcsXG4gIG1heDogJ21heCcsXG4gIG1heGxlbmd0aDogJ21heExlbmd0aCcsXG4gIG1lZGlhOiAnbWVkaWEnLFxuICBtZWRpYWdyb3VwOiAnbWVkaWFHcm91cCcsXG4gIG1ldGhvZDogJ21ldGhvZCcsXG4gIG1pbjogJ21pbicsXG4gIG1pbmxlbmd0aDogJ21pbkxlbmd0aCcsXG4gIG11bHRpcGxlOiAnbXVsdGlwbGUnLFxuICBtdXRlZDogJ211dGVkJyxcbiAgbmFtZTogJ25hbWUnLFxuICBub21vZHVsZTogJ25vTW9kdWxlJyxcbiAgbm9uY2U6ICdub25jZScsXG4gIG5vdmFsaWRhdGU6ICdub1ZhbGlkYXRlJyxcbiAgb3BlbjogJ29wZW4nLFxuICBvcHRpbXVtOiAnb3B0aW11bScsXG4gIHBhdHRlcm46ICdwYXR0ZXJuJyxcbiAgcGxhY2Vob2xkZXI6ICdwbGFjZWhvbGRlcicsXG4gIHBsYXlzaW5saW5lOiAncGxheXNJbmxpbmUnLFxuICBwb3N0ZXI6ICdwb3N0ZXInLFxuICBwcmVsb2FkOiAncHJlbG9hZCcsXG4gIHByb2ZpbGU6ICdwcm9maWxlJyxcbiAgcmFkaW9ncm91cDogJ3JhZGlvR3JvdXAnLFxuICByZWFkb25seTogJ3JlYWRPbmx5JyxcbiAgcmVmZXJyZXJwb2xpY3k6ICdyZWZlcnJlclBvbGljeScsXG4gIHJlbDogJ3JlbCcsXG4gIHJlcXVpcmVkOiAncmVxdWlyZWQnLFxuICByZXZlcnNlZDogJ3JldmVyc2VkJyxcbiAgcm9sZTogJ3JvbGUnLFxuICByb3dzOiAncm93cycsXG4gIHJvd3NwYW46ICdyb3dTcGFuJyxcbiAgc2FuZGJveDogJ3NhbmRib3gnLFxuICBzY29wZTogJ3Njb3BlJyxcbiAgc2NvcGVkOiAnc2NvcGVkJyxcbiAgc2Nyb2xsaW5nOiAnc2Nyb2xsaW5nJyxcbiAgc2VhbWxlc3M6ICdzZWFtbGVzcycsXG4gIHNlbGVjdGVkOiAnc2VsZWN0ZWQnLFxuICBzaGFwZTogJ3NoYXBlJyxcbiAgc2l6ZTogJ3NpemUnLFxuICBzaXplczogJ3NpemVzJyxcbiAgc3BhbjogJ3NwYW4nLFxuICBzcGVsbGNoZWNrOiAnc3BlbGxDaGVjaycsXG4gIHNyYzogJ3NyYycsXG4gIHNyY2RvYzogJ3NyY0RvYycsXG4gIHNyY2xhbmc6ICdzcmNMYW5nJyxcbiAgc3Jjc2V0OiAnc3JjU2V0JyxcbiAgc3RhcnQ6ICdzdGFydCcsXG4gIHN0ZXA6ICdzdGVwJyxcbiAgc3R5bGU6ICdzdHlsZScsXG4gIHN1bW1hcnk6ICdzdW1tYXJ5JyxcbiAgdGFiaW5kZXg6ICd0YWJJbmRleCcsXG4gIHRhcmdldDogJ3RhcmdldCcsXG4gIHRpdGxlOiAndGl0bGUnLFxuICB0eXBlOiAndHlwZScsXG4gIHVzZW1hcDogJ3VzZU1hcCcsXG4gIHZhbHVlOiAndmFsdWUnLFxuICB3aWR0aDogJ3dpZHRoJyxcbiAgd21vZGU6ICd3bW9kZScsXG4gIHdyYXA6ICd3cmFwJyxcbiAgLy8gU1ZHXG4gIGFib3V0OiAnYWJvdXQnLFxuICBhY2NlbnRoZWlnaHQ6ICdhY2NlbnRIZWlnaHQnLFxuICAnYWNjZW50LWhlaWdodCc6ICdhY2NlbnRIZWlnaHQnLFxuICBhY2N1bXVsYXRlOiAnYWNjdW11bGF0ZScsXG4gIGFkZGl0aXZlOiAnYWRkaXRpdmUnLFxuICBhbGlnbm1lbnRiYXNlbGluZTogJ2FsaWdubWVudEJhc2VsaW5lJyxcbiAgJ2FsaWdubWVudC1iYXNlbGluZSc6ICdhbGlnbm1lbnRCYXNlbGluZScsXG4gIGFsbG93cmVvcmRlcjogJ2FsbG93UmVvcmRlcicsXG4gIGFscGhhYmV0aWM6ICdhbHBoYWJldGljJyxcbiAgYW1wbGl0dWRlOiAnYW1wbGl0dWRlJyxcbiAgYXJhYmljZm9ybTogJ2FyYWJpY0Zvcm0nLFxuICAnYXJhYmljLWZvcm0nOiAnYXJhYmljRm9ybScsXG4gIGFzY2VudDogJ2FzY2VudCcsXG4gIGF0dHJpYnV0ZW5hbWU6ICdhdHRyaWJ1dGVOYW1lJyxcbiAgYXR0cmlidXRldHlwZTogJ2F0dHJpYnV0ZVR5cGUnLFxuICBhdXRvcmV2ZXJzZTogJ2F1dG9SZXZlcnNlJyxcbiAgYXppbXV0aDogJ2F6aW11dGgnLFxuICBiYXNlZnJlcXVlbmN5OiAnYmFzZUZyZXF1ZW5jeScsXG4gIGJhc2VsaW5lc2hpZnQ6ICdiYXNlbGluZVNoaWZ0JyxcbiAgJ2Jhc2VsaW5lLXNoaWZ0JzogJ2Jhc2VsaW5lU2hpZnQnLFxuICBiYXNlcHJvZmlsZTogJ2Jhc2VQcm9maWxlJyxcbiAgYmJveDogJ2Jib3gnLFxuICBiZWdpbjogJ2JlZ2luJyxcbiAgYmlhczogJ2JpYXMnLFxuICBieTogJ2J5JyxcbiAgY2FsY21vZGU6ICdjYWxjTW9kZScsXG4gIGNhcGhlaWdodDogJ2NhcEhlaWdodCcsXG4gICdjYXAtaGVpZ2h0JzogJ2NhcEhlaWdodCcsXG4gIGNsaXA6ICdjbGlwJyxcbiAgY2xpcHBhdGg6ICdjbGlwUGF0aCcsXG4gICdjbGlwLXBhdGgnOiAnY2xpcFBhdGgnLFxuICBjbGlwcGF0aHVuaXRzOiAnY2xpcFBhdGhVbml0cycsXG4gIGNsaXBydWxlOiAnY2xpcFJ1bGUnLFxuICAnY2xpcC1ydWxlJzogJ2NsaXBSdWxlJyxcbiAgY29sb3I6ICdjb2xvcicsXG4gIGNvbG9yaW50ZXJwb2xhdGlvbjogJ2NvbG9ySW50ZXJwb2xhdGlvbicsXG4gICdjb2xvci1pbnRlcnBvbGF0aW9uJzogJ2NvbG9ySW50ZXJwb2xhdGlvbicsXG4gIGNvbG9yaW50ZXJwb2xhdGlvbmZpbHRlcnM6ICdjb2xvckludGVycG9sYXRpb25GaWx0ZXJzJyxcbiAgJ2NvbG9yLWludGVycG9sYXRpb24tZmlsdGVycyc6ICdjb2xvckludGVycG9sYXRpb25GaWx0ZXJzJyxcbiAgY29sb3Jwcm9maWxlOiAnY29sb3JQcm9maWxlJyxcbiAgJ2NvbG9yLXByb2ZpbGUnOiAnY29sb3JQcm9maWxlJyxcbiAgY29sb3JyZW5kZXJpbmc6ICdjb2xvclJlbmRlcmluZycsXG4gICdjb2xvci1yZW5kZXJpbmcnOiAnY29sb3JSZW5kZXJpbmcnLFxuICBjb250ZW50c2NyaXB0dHlwZTogJ2NvbnRlbnRTY3JpcHRUeXBlJyxcbiAgY29udGVudHN0eWxldHlwZTogJ2NvbnRlbnRTdHlsZVR5cGUnLFxuICBjdXJzb3I6ICdjdXJzb3InLFxuICBjeDogJ2N4JyxcbiAgY3k6ICdjeScsXG4gIGQ6ICdkJyxcbiAgZGF0YXR5cGU6ICdkYXRhdHlwZScsXG4gIGRlY2VsZXJhdGU6ICdkZWNlbGVyYXRlJyxcbiAgZGVzY2VudDogJ2Rlc2NlbnQnLFxuICBkaWZmdXNlY29uc3RhbnQ6ICdkaWZmdXNlQ29uc3RhbnQnLFxuICBkaXJlY3Rpb246ICdkaXJlY3Rpb24nLFxuICBkaXNwbGF5OiAnZGlzcGxheScsXG4gIGRpdmlzb3I6ICdkaXZpc29yJyxcbiAgZG9taW5hbnRiYXNlbGluZTogJ2RvbWluYW50QmFzZWxpbmUnLFxuICAnZG9taW5hbnQtYmFzZWxpbmUnOiAnZG9taW5hbnRCYXNlbGluZScsXG4gIGR1cjogJ2R1cicsXG4gIGR4OiAnZHgnLFxuICBkeTogJ2R5JyxcbiAgZWRnZW1vZGU6ICdlZGdlTW9kZScsXG4gIGVsZXZhdGlvbjogJ2VsZXZhdGlvbicsXG4gIGVuYWJsZWJhY2tncm91bmQ6ICdlbmFibGVCYWNrZ3JvdW5kJyxcbiAgJ2VuYWJsZS1iYWNrZ3JvdW5kJzogJ2VuYWJsZUJhY2tncm91bmQnLFxuICBlbmQ6ICdlbmQnLFxuICBleHBvbmVudDogJ2V4cG9uZW50JyxcbiAgZXh0ZXJuYWxyZXNvdXJjZXNyZXF1aXJlZDogJ2V4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWQnLFxuICBmaWxsOiAnZmlsbCcsXG4gIGZpbGxvcGFjaXR5OiAnZmlsbE9wYWNpdHknLFxuICAnZmlsbC1vcGFjaXR5JzogJ2ZpbGxPcGFjaXR5JyxcbiAgZmlsbHJ1bGU6ICdmaWxsUnVsZScsXG4gICdmaWxsLXJ1bGUnOiAnZmlsbFJ1bGUnLFxuICBmaWx0ZXI6ICdmaWx0ZXInLFxuICBmaWx0ZXJyZXM6ICdmaWx0ZXJSZXMnLFxuICBmaWx0ZXJ1bml0czogJ2ZpbHRlclVuaXRzJyxcbiAgZmxvb2RvcGFjaXR5OiAnZmxvb2RPcGFjaXR5JyxcbiAgJ2Zsb29kLW9wYWNpdHknOiAnZmxvb2RPcGFjaXR5JyxcbiAgZmxvb2Rjb2xvcjogJ2Zsb29kQ29sb3InLFxuICAnZmxvb2QtY29sb3InOiAnZmxvb2RDb2xvcicsXG4gIGZvY3VzYWJsZTogJ2ZvY3VzYWJsZScsXG4gIGZvbnRmYW1pbHk6ICdmb250RmFtaWx5JyxcbiAgJ2ZvbnQtZmFtaWx5JzogJ2ZvbnRGYW1pbHknLFxuICBmb250c2l6ZTogJ2ZvbnRTaXplJyxcbiAgJ2ZvbnQtc2l6ZSc6ICdmb250U2l6ZScsXG4gIGZvbnRzaXplYWRqdXN0OiAnZm9udFNpemVBZGp1c3QnLFxuICAnZm9udC1zaXplLWFkanVzdCc6ICdmb250U2l6ZUFkanVzdCcsXG4gIGZvbnRzdHJldGNoOiAnZm9udFN0cmV0Y2gnLFxuICAnZm9udC1zdHJldGNoJzogJ2ZvbnRTdHJldGNoJyxcbiAgZm9udHN0eWxlOiAnZm9udFN0eWxlJyxcbiAgJ2ZvbnQtc3R5bGUnOiAnZm9udFN0eWxlJyxcbiAgZm9udHZhcmlhbnQ6ICdmb250VmFyaWFudCcsXG4gICdmb250LXZhcmlhbnQnOiAnZm9udFZhcmlhbnQnLFxuICBmb250d2VpZ2h0OiAnZm9udFdlaWdodCcsXG4gICdmb250LXdlaWdodCc6ICdmb250V2VpZ2h0JyxcbiAgZm9ybWF0OiAnZm9ybWF0JyxcbiAgZnJvbTogJ2Zyb20nLFxuICBmeDogJ2Z4JyxcbiAgZnk6ICdmeScsXG4gIGcxOiAnZzEnLFxuICBnMjogJ2cyJyxcbiAgZ2x5cGhuYW1lOiAnZ2x5cGhOYW1lJyxcbiAgJ2dseXBoLW5hbWUnOiAnZ2x5cGhOYW1lJyxcbiAgZ2x5cGhvcmllbnRhdGlvbmhvcml6b250YWw6ICdnbHlwaE9yaWVudGF0aW9uSG9yaXpvbnRhbCcsXG4gICdnbHlwaC1vcmllbnRhdGlvbi1ob3Jpem9udGFsJzogJ2dseXBoT3JpZW50YXRpb25Ib3Jpem9udGFsJyxcbiAgZ2x5cGhvcmllbnRhdGlvbnZlcnRpY2FsOiAnZ2x5cGhPcmllbnRhdGlvblZlcnRpY2FsJyxcbiAgJ2dseXBoLW9yaWVudGF0aW9uLXZlcnRpY2FsJzogJ2dseXBoT3JpZW50YXRpb25WZXJ0aWNhbCcsXG4gIGdseXBocmVmOiAnZ2x5cGhSZWYnLFxuICBncmFkaWVudHRyYW5zZm9ybTogJ2dyYWRpZW50VHJhbnNmb3JtJyxcbiAgZ3JhZGllbnR1bml0czogJ2dyYWRpZW50VW5pdHMnLFxuICBoYW5naW5nOiAnaGFuZ2luZycsXG4gIGhvcml6YWR2eDogJ2hvcml6QWR2WCcsXG4gICdob3Jpei1hZHYteCc6ICdob3JpekFkdlgnLFxuICBob3Jpem9yaWdpbng6ICdob3Jpek9yaWdpblgnLFxuICAnaG9yaXotb3JpZ2luLXgnOiAnaG9yaXpPcmlnaW5YJyxcbiAgaWRlb2dyYXBoaWM6ICdpZGVvZ3JhcGhpYycsXG4gIGltYWdlcmVuZGVyaW5nOiAnaW1hZ2VSZW5kZXJpbmcnLFxuICAnaW1hZ2UtcmVuZGVyaW5nJzogJ2ltYWdlUmVuZGVyaW5nJyxcbiAgaW4yOiAnaW4yJyxcbiAgaW46ICdpbicsXG4gIGlubGlzdDogJ2lubGlzdCcsXG4gIGludGVyY2VwdDogJ2ludGVyY2VwdCcsXG4gIGsxOiAnazEnLFxuICBrMjogJ2syJyxcbiAgazM6ICdrMycsXG4gIGs0OiAnazQnLFxuICBrOiAnaycsXG4gIGtlcm5lbG1hdHJpeDogJ2tlcm5lbE1hdHJpeCcsXG4gIGtlcm5lbHVuaXRsZW5ndGg6ICdrZXJuZWxVbml0TGVuZ3RoJyxcbiAga2VybmluZzogJ2tlcm5pbmcnLFxuICBrZXlwb2ludHM6ICdrZXlQb2ludHMnLFxuICBrZXlzcGxpbmVzOiAna2V5U3BsaW5lcycsXG4gIGtleXRpbWVzOiAna2V5VGltZXMnLFxuICBsZW5ndGhhZGp1c3Q6ICdsZW5ndGhBZGp1c3QnLFxuICBsZXR0ZXJzcGFjaW5nOiAnbGV0dGVyU3BhY2luZycsXG4gICdsZXR0ZXItc3BhY2luZyc6ICdsZXR0ZXJTcGFjaW5nJyxcbiAgbGlnaHRpbmdjb2xvcjogJ2xpZ2h0aW5nQ29sb3InLFxuICAnbGlnaHRpbmctY29sb3InOiAnbGlnaHRpbmdDb2xvcicsXG4gIGxpbWl0aW5nY29uZWFuZ2xlOiAnbGltaXRpbmdDb25lQW5nbGUnLFxuICBsb2NhbDogJ2xvY2FsJyxcbiAgbWFya2VyZW5kOiAnbWFya2VyRW5kJyxcbiAgJ21hcmtlci1lbmQnOiAnbWFya2VyRW5kJyxcbiAgbWFya2VyaGVpZ2h0OiAnbWFya2VySGVpZ2h0JyxcbiAgbWFya2VybWlkOiAnbWFya2VyTWlkJyxcbiAgJ21hcmtlci1taWQnOiAnbWFya2VyTWlkJyxcbiAgbWFya2Vyc3RhcnQ6ICdtYXJrZXJTdGFydCcsXG4gICdtYXJrZXItc3RhcnQnOiAnbWFya2VyU3RhcnQnLFxuICBtYXJrZXJ1bml0czogJ21hcmtlclVuaXRzJyxcbiAgbWFya2Vyd2lkdGg6ICdtYXJrZXJXaWR0aCcsXG4gIG1hc2s6ICdtYXNrJyxcbiAgbWFza2NvbnRlbnR1bml0czogJ21hc2tDb250ZW50VW5pdHMnLFxuICBtYXNrdW5pdHM6ICdtYXNrVW5pdHMnLFxuICBtYXRoZW1hdGljYWw6ICdtYXRoZW1hdGljYWwnLFxuICBtb2RlOiAnbW9kZScsXG4gIG51bW9jdGF2ZXM6ICdudW1PY3RhdmVzJyxcbiAgb2Zmc2V0OiAnb2Zmc2V0JyxcbiAgb3BhY2l0eTogJ29wYWNpdHknLFxuICBvcGVyYXRvcjogJ29wZXJhdG9yJyxcbiAgb3JkZXI6ICdvcmRlcicsXG4gIG9yaWVudDogJ29yaWVudCcsXG4gIG9yaWVudGF0aW9uOiAnb3JpZW50YXRpb24nLFxuICBvcmlnaW46ICdvcmlnaW4nLFxuICBvdmVyZmxvdzogJ292ZXJmbG93JyxcbiAgb3ZlcmxpbmVwb3NpdGlvbjogJ292ZXJsaW5lUG9zaXRpb24nLFxuICAnb3ZlcmxpbmUtcG9zaXRpb24nOiAnb3ZlcmxpbmVQb3NpdGlvbicsXG4gIG92ZXJsaW5ldGhpY2tuZXNzOiAnb3ZlcmxpbmVUaGlja25lc3MnLFxuICAnb3ZlcmxpbmUtdGhpY2tuZXNzJzogJ292ZXJsaW5lVGhpY2tuZXNzJyxcbiAgcGFpbnRvcmRlcjogJ3BhaW50T3JkZXInLFxuICAncGFpbnQtb3JkZXInOiAncGFpbnRPcmRlcicsXG4gIHBhbm9zZTE6ICdwYW5vc2UxJyxcbiAgJ3Bhbm9zZS0xJzogJ3Bhbm9zZTEnLFxuICBwYXRobGVuZ3RoOiAncGF0aExlbmd0aCcsXG4gIHBhdHRlcm5jb250ZW50dW5pdHM6ICdwYXR0ZXJuQ29udGVudFVuaXRzJyxcbiAgcGF0dGVybnRyYW5zZm9ybTogJ3BhdHRlcm5UcmFuc2Zvcm0nLFxuICBwYXR0ZXJudW5pdHM6ICdwYXR0ZXJuVW5pdHMnLFxuICBwb2ludGVyZXZlbnRzOiAncG9pbnRlckV2ZW50cycsXG4gICdwb2ludGVyLWV2ZW50cyc6ICdwb2ludGVyRXZlbnRzJyxcbiAgcG9pbnRzOiAncG9pbnRzJyxcbiAgcG9pbnRzYXR4OiAncG9pbnRzQXRYJyxcbiAgcG9pbnRzYXR5OiAncG9pbnRzQXRZJyxcbiAgcG9pbnRzYXR6OiAncG9pbnRzQXRaJyxcbiAgcHJlZml4OiAncHJlZml4JyxcbiAgcHJlc2VydmVhbHBoYTogJ3ByZXNlcnZlQWxwaGEnLFxuICBwcmVzZXJ2ZWFzcGVjdHJhdGlvOiAncHJlc2VydmVBc3BlY3RSYXRpbycsXG4gIHByaW1pdGl2ZXVuaXRzOiAncHJpbWl0aXZlVW5pdHMnLFxuICBwcm9wZXJ0eTogJ3Byb3BlcnR5JyxcbiAgcjogJ3InLFxuICByYWRpdXM6ICdyYWRpdXMnLFxuICByZWZ4OiAncmVmWCcsXG4gIHJlZnk6ICdyZWZZJyxcbiAgcmVuZGVyaW5naW50ZW50OiAncmVuZGVyaW5nSW50ZW50JyxcbiAgJ3JlbmRlcmluZy1pbnRlbnQnOiAncmVuZGVyaW5nSW50ZW50JyxcbiAgcmVwZWF0Y291bnQ6ICdyZXBlYXRDb3VudCcsXG4gIHJlcGVhdGR1cjogJ3JlcGVhdER1cicsXG4gIHJlcXVpcmVkZXh0ZW5zaW9uczogJ3JlcXVpcmVkRXh0ZW5zaW9ucycsXG4gIHJlcXVpcmVkZmVhdHVyZXM6ICdyZXF1aXJlZEZlYXR1cmVzJyxcbiAgcmVzb3VyY2U6ICdyZXNvdXJjZScsXG4gIHJlc3RhcnQ6ICdyZXN0YXJ0JyxcbiAgcmVzdWx0OiAncmVzdWx0JyxcbiAgcmVzdWx0czogJ3Jlc3VsdHMnLFxuICByb3RhdGU6ICdyb3RhdGUnLFxuICByeDogJ3J4JyxcbiAgcnk6ICdyeScsXG4gIHNjYWxlOiAnc2NhbGUnLFxuICBzZWN1cml0eTogJ3NlY3VyaXR5JyxcbiAgc2VlZDogJ3NlZWQnLFxuICBzaGFwZXJlbmRlcmluZzogJ3NoYXBlUmVuZGVyaW5nJyxcbiAgJ3NoYXBlLXJlbmRlcmluZyc6ICdzaGFwZVJlbmRlcmluZycsXG4gIHNsb3BlOiAnc2xvcGUnLFxuICBzcGFjaW5nOiAnc3BhY2luZycsXG4gIHNwZWN1bGFyY29uc3RhbnQ6ICdzcGVjdWxhckNvbnN0YW50JyxcbiAgc3BlY3VsYXJleHBvbmVudDogJ3NwZWN1bGFyRXhwb25lbnQnLFxuICBzcGVlZDogJ3NwZWVkJyxcbiAgc3ByZWFkbWV0aG9kOiAnc3ByZWFkTWV0aG9kJyxcbiAgc3RhcnRvZmZzZXQ6ICdzdGFydE9mZnNldCcsXG4gIHN0ZGRldmlhdGlvbjogJ3N0ZERldmlhdGlvbicsXG4gIHN0ZW1oOiAnc3RlbWgnLFxuICBzdGVtdjogJ3N0ZW12JyxcbiAgc3RpdGNodGlsZXM6ICdzdGl0Y2hUaWxlcycsXG4gIHN0b3Bjb2xvcjogJ3N0b3BDb2xvcicsXG4gICdzdG9wLWNvbG9yJzogJ3N0b3BDb2xvcicsXG4gIHN0b3BvcGFjaXR5OiAnc3RvcE9wYWNpdHknLFxuICAnc3RvcC1vcGFjaXR5JzogJ3N0b3BPcGFjaXR5JyxcbiAgc3RyaWtldGhyb3VnaHBvc2l0aW9uOiAnc3RyaWtldGhyb3VnaFBvc2l0aW9uJyxcbiAgJ3N0cmlrZXRocm91Z2gtcG9zaXRpb24nOiAnc3RyaWtldGhyb3VnaFBvc2l0aW9uJyxcbiAgc3RyaWtldGhyb3VnaHRoaWNrbmVzczogJ3N0cmlrZXRocm91Z2hUaGlja25lc3MnLFxuICAnc3RyaWtldGhyb3VnaC10aGlja25lc3MnOiAnc3RyaWtldGhyb3VnaFRoaWNrbmVzcycsXG4gIHN0cmluZzogJ3N0cmluZycsXG4gIHN0cm9rZTogJ3N0cm9rZScsXG4gIHN0cm9rZWRhc2hhcnJheTogJ3N0cm9rZURhc2hhcnJheScsXG4gICdzdHJva2UtZGFzaGFycmF5JzogJ3N0cm9rZURhc2hhcnJheScsXG4gIHN0cm9rZWRhc2hvZmZzZXQ6ICdzdHJva2VEYXNob2Zmc2V0JyxcbiAgJ3N0cm9rZS1kYXNob2Zmc2V0JzogJ3N0cm9rZURhc2hvZmZzZXQnLFxuICBzdHJva2VsaW5lY2FwOiAnc3Ryb2tlTGluZWNhcCcsXG4gICdzdHJva2UtbGluZWNhcCc6ICdzdHJva2VMaW5lY2FwJyxcbiAgc3Ryb2tlbGluZWpvaW46ICdzdHJva2VMaW5lam9pbicsXG4gICdzdHJva2UtbGluZWpvaW4nOiAnc3Ryb2tlTGluZWpvaW4nLFxuICBzdHJva2VtaXRlcmxpbWl0OiAnc3Ryb2tlTWl0ZXJsaW1pdCcsXG4gICdzdHJva2UtbWl0ZXJsaW1pdCc6ICdzdHJva2VNaXRlcmxpbWl0JyxcbiAgc3Ryb2tld2lkdGg6ICdzdHJva2VXaWR0aCcsXG4gICdzdHJva2Utd2lkdGgnOiAnc3Ryb2tlV2lkdGgnLFxuICBzdHJva2VvcGFjaXR5OiAnc3Ryb2tlT3BhY2l0eScsXG4gICdzdHJva2Utb3BhY2l0eSc6ICdzdHJva2VPcGFjaXR5JyxcbiAgc3VwcHJlc3Njb250ZW50ZWRpdGFibGV3YXJuaW5nOiAnc3VwcHJlc3NDb250ZW50RWRpdGFibGVXYXJuaW5nJyxcbiAgc3VwcHJlc3NoeWRyYXRpb253YXJuaW5nOiAnc3VwcHJlc3NIeWRyYXRpb25XYXJuaW5nJyxcbiAgc3VyZmFjZXNjYWxlOiAnc3VyZmFjZVNjYWxlJyxcbiAgc3lzdGVtbGFuZ3VhZ2U6ICdzeXN0ZW1MYW5ndWFnZScsXG4gIHRhYmxldmFsdWVzOiAndGFibGVWYWx1ZXMnLFxuICB0YXJnZXR4OiAndGFyZ2V0WCcsXG4gIHRhcmdldHk6ICd0YXJnZXRZJyxcbiAgdGV4dGFuY2hvcjogJ3RleHRBbmNob3InLFxuICAndGV4dC1hbmNob3InOiAndGV4dEFuY2hvcicsXG4gIHRleHRkZWNvcmF0aW9uOiAndGV4dERlY29yYXRpb24nLFxuICAndGV4dC1kZWNvcmF0aW9uJzogJ3RleHREZWNvcmF0aW9uJyxcbiAgdGV4dGxlbmd0aDogJ3RleHRMZW5ndGgnLFxuICB0ZXh0cmVuZGVyaW5nOiAndGV4dFJlbmRlcmluZycsXG4gICd0ZXh0LXJlbmRlcmluZyc6ICd0ZXh0UmVuZGVyaW5nJyxcbiAgdG86ICd0bycsXG4gIHRyYW5zZm9ybTogJ3RyYW5zZm9ybScsXG4gIHR5cGVvZjogJ3R5cGVvZicsXG4gIHUxOiAndTEnLFxuICB1MjogJ3UyJyxcbiAgdW5kZXJsaW5lcG9zaXRpb246ICd1bmRlcmxpbmVQb3NpdGlvbicsXG4gICd1bmRlcmxpbmUtcG9zaXRpb24nOiAndW5kZXJsaW5lUG9zaXRpb24nLFxuICB1bmRlcmxpbmV0aGlja25lc3M6ICd1bmRlcmxpbmVUaGlja25lc3MnLFxuICAndW5kZXJsaW5lLXRoaWNrbmVzcyc6ICd1bmRlcmxpbmVUaGlja25lc3MnLFxuICB1bmljb2RlOiAndW5pY29kZScsXG4gIHVuaWNvZGViaWRpOiAndW5pY29kZUJpZGknLFxuICAndW5pY29kZS1iaWRpJzogJ3VuaWNvZGVCaWRpJyxcbiAgdW5pY29kZXJhbmdlOiAndW5pY29kZVJhbmdlJyxcbiAgJ3VuaWNvZGUtcmFuZ2UnOiAndW5pY29kZVJhbmdlJyxcbiAgdW5pdHNwZXJlbTogJ3VuaXRzUGVyRW0nLFxuICAndW5pdHMtcGVyLWVtJzogJ3VuaXRzUGVyRW0nLFxuICB1bnNlbGVjdGFibGU6ICd1bnNlbGVjdGFibGUnLFxuICB2YWxwaGFiZXRpYzogJ3ZBbHBoYWJldGljJyxcbiAgJ3YtYWxwaGFiZXRpYyc6ICd2QWxwaGFiZXRpYycsXG4gIHZhbHVlczogJ3ZhbHVlcycsXG4gIHZlY3RvcmVmZmVjdDogJ3ZlY3RvckVmZmVjdCcsXG4gICd2ZWN0b3ItZWZmZWN0JzogJ3ZlY3RvckVmZmVjdCcsXG4gIHZlcnNpb246ICd2ZXJzaW9uJyxcbiAgdmVydGFkdnk6ICd2ZXJ0QWR2WScsXG4gICd2ZXJ0LWFkdi15JzogJ3ZlcnRBZHZZJyxcbiAgdmVydG9yaWdpbng6ICd2ZXJ0T3JpZ2luWCcsXG4gICd2ZXJ0LW9yaWdpbi14JzogJ3ZlcnRPcmlnaW5YJyxcbiAgdmVydG9yaWdpbnk6ICd2ZXJ0T3JpZ2luWScsXG4gICd2ZXJ0LW9yaWdpbi15JzogJ3ZlcnRPcmlnaW5ZJyxcbiAgdmhhbmdpbmc6ICd2SGFuZ2luZycsXG4gICd2LWhhbmdpbmcnOiAndkhhbmdpbmcnLFxuICB2aWRlb2dyYXBoaWM6ICd2SWRlb2dyYXBoaWMnLFxuICAndi1pZGVvZ3JhcGhpYyc6ICd2SWRlb2dyYXBoaWMnLFxuICB2aWV3Ym94OiAndmlld0JveCcsXG4gIHZpZXd0YXJnZXQ6ICd2aWV3VGFyZ2V0JyxcbiAgdmlzaWJpbGl0eTogJ3Zpc2liaWxpdHknLFxuICB2bWF0aGVtYXRpY2FsOiAndk1hdGhlbWF0aWNhbCcsXG4gICd2LW1hdGhlbWF0aWNhbCc6ICd2TWF0aGVtYXRpY2FsJyxcbiAgdm9jYWI6ICd2b2NhYicsXG4gIHdpZHRoczogJ3dpZHRocycsXG4gIHdvcmRzcGFjaW5nOiAnd29yZFNwYWNpbmcnLFxuICAnd29yZC1zcGFjaW5nJzogJ3dvcmRTcGFjaW5nJyxcbiAgd3JpdGluZ21vZGU6ICd3cml0aW5nTW9kZScsXG4gICd3cml0aW5nLW1vZGUnOiAnd3JpdGluZ01vZGUnLFxuICB4MTogJ3gxJyxcbiAgeDI6ICd4MicsXG4gIHg6ICd4JyxcbiAgeGNoYW5uZWxzZWxlY3RvcjogJ3hDaGFubmVsU2VsZWN0b3InLFxuICB4aGVpZ2h0OiAneEhlaWdodCcsXG4gICd4LWhlaWdodCc6ICd4SGVpZ2h0JyxcbiAgeGxpbmthY3R1YXRlOiAneGxpbmtBY3R1YXRlJyxcbiAgJ3hsaW5rOmFjdHVhdGUnOiAneGxpbmtBY3R1YXRlJyxcbiAgeGxpbmthcmNyb2xlOiAneGxpbmtBcmNyb2xlJyxcbiAgJ3hsaW5rOmFyY3JvbGUnOiAneGxpbmtBcmNyb2xlJyxcbiAgeGxpbmtocmVmOiAneGxpbmtIcmVmJyxcbiAgJ3hsaW5rOmhyZWYnOiAneGxpbmtIcmVmJyxcbiAgeGxpbmtyb2xlOiAneGxpbmtSb2xlJyxcbiAgJ3hsaW5rOnJvbGUnOiAneGxpbmtSb2xlJyxcbiAgeGxpbmtzaG93OiAneGxpbmtTaG93JyxcbiAgJ3hsaW5rOnNob3cnOiAneGxpbmtTaG93JyxcbiAgeGxpbmt0aXRsZTogJ3hsaW5rVGl0bGUnLFxuICAneGxpbms6dGl0bGUnOiAneGxpbmtUaXRsZScsXG4gIHhsaW5rdHlwZTogJ3hsaW5rVHlwZScsXG4gICd4bGluazp0eXBlJzogJ3hsaW5rVHlwZScsXG4gIHhtbGJhc2U6ICd4bWxCYXNlJyxcbiAgJ3htbDpiYXNlJzogJ3htbEJhc2UnLFxuICB4bWxsYW5nOiAneG1sTGFuZycsXG4gICd4bWw6bGFuZyc6ICd4bWxMYW5nJyxcbiAgeG1sbnM6ICd4bWxucycsXG4gICd4bWw6c3BhY2UnOiAneG1sU3BhY2UnLFxuICB4bWxuc3hsaW5rOiAneG1sbnNYbGluaycsXG4gICd4bWxuczp4bGluayc6ICd4bWxuc1hsaW5rJyxcbiAgeG1sc3BhY2U6ICd4bWxTcGFjZScsXG4gIHkxOiAneTEnLFxuICB5MjogJ3kyJyxcbiAgeTogJ3knLFxuICB5Y2hhbm5lbHNlbGVjdG9yOiAneUNoYW5uZWxTZWxlY3RvcicsXG4gIHo6ICd6JyxcbiAgem9vbWFuZHBhbjogJ3pvb21BbmRQYW4nXG59O1xuXG52YXIgYXJpYVByb3BlcnRpZXMgPSB7XG4gICdhcmlhLWN1cnJlbnQnOiAwLFxuICAvLyBzdGF0ZVxuICAnYXJpYS1kZXNjcmlwdGlvbic6IDAsXG4gICdhcmlhLWRldGFpbHMnOiAwLFxuICAnYXJpYS1kaXNhYmxlZCc6IDAsXG4gIC8vIHN0YXRlXG4gICdhcmlhLWhpZGRlbic6IDAsXG4gIC8vIHN0YXRlXG4gICdhcmlhLWludmFsaWQnOiAwLFxuICAvLyBzdGF0ZVxuICAnYXJpYS1rZXlzaG9ydGN1dHMnOiAwLFxuICAnYXJpYS1sYWJlbCc6IDAsXG4gICdhcmlhLXJvbGVkZXNjcmlwdGlvbic6IDAsXG4gIC8vIFdpZGdldCBBdHRyaWJ1dGVzXG4gICdhcmlhLWF1dG9jb21wbGV0ZSc6IDAsXG4gICdhcmlhLWNoZWNrZWQnOiAwLFxuICAnYXJpYS1leHBhbmRlZCc6IDAsXG4gICdhcmlhLWhhc3BvcHVwJzogMCxcbiAgJ2FyaWEtbGV2ZWwnOiAwLFxuICAnYXJpYS1tb2RhbCc6IDAsXG4gICdhcmlhLW11bHRpbGluZSc6IDAsXG4gICdhcmlhLW11bHRpc2VsZWN0YWJsZSc6IDAsXG4gICdhcmlhLW9yaWVudGF0aW9uJzogMCxcbiAgJ2FyaWEtcGxhY2Vob2xkZXInOiAwLFxuICAnYXJpYS1wcmVzc2VkJzogMCxcbiAgJ2FyaWEtcmVhZG9ubHknOiAwLFxuICAnYXJpYS1yZXF1aXJlZCc6IDAsXG4gICdhcmlhLXNlbGVjdGVkJzogMCxcbiAgJ2FyaWEtc29ydCc6IDAsXG4gICdhcmlhLXZhbHVlbWF4JzogMCxcbiAgJ2FyaWEtdmFsdWVtaW4nOiAwLFxuICAnYXJpYS12YWx1ZW5vdyc6IDAsXG4gICdhcmlhLXZhbHVldGV4dCc6IDAsXG4gIC8vIExpdmUgUmVnaW9uIEF0dHJpYnV0ZXNcbiAgJ2FyaWEtYXRvbWljJzogMCxcbiAgJ2FyaWEtYnVzeSc6IDAsXG4gICdhcmlhLWxpdmUnOiAwLFxuICAnYXJpYS1yZWxldmFudCc6IDAsXG4gIC8vIERyYWctYW5kLURyb3AgQXR0cmlidXRlc1xuICAnYXJpYS1kcm9wZWZmZWN0JzogMCxcbiAgJ2FyaWEtZ3JhYmJlZCc6IDAsXG4gIC8vIFJlbGF0aW9uc2hpcCBBdHRyaWJ1dGVzXG4gICdhcmlhLWFjdGl2ZWRlc2NlbmRhbnQnOiAwLFxuICAnYXJpYS1jb2xjb3VudCc6IDAsXG4gICdhcmlhLWNvbGluZGV4JzogMCxcbiAgJ2FyaWEtY29sc3Bhbic6IDAsXG4gICdhcmlhLWNvbnRyb2xzJzogMCxcbiAgJ2FyaWEtZGVzY3JpYmVkYnknOiAwLFxuICAnYXJpYS1lcnJvcm1lc3NhZ2UnOiAwLFxuICAnYXJpYS1mbG93dG8nOiAwLFxuICAnYXJpYS1sYWJlbGxlZGJ5JzogMCxcbiAgJ2FyaWEtb3ducyc6IDAsXG4gICdhcmlhLXBvc2luc2V0JzogMCxcbiAgJ2FyaWEtcm93Y291bnQnOiAwLFxuICAnYXJpYS1yb3dpbmRleCc6IDAsXG4gICdhcmlhLXJvd3NwYW4nOiAwLFxuICAnYXJpYS1zZXRzaXplJzogMFxufTtcblxudmFyIHdhcm5lZFByb3BlcnRpZXMgPSB7fTtcbnZhciByQVJJQSA9IG5ldyBSZWdFeHAoJ14oYXJpYSktWycgKyBBVFRSSUJVVEVfTkFNRV9DSEFSICsgJ10qJCcpO1xudmFyIHJBUklBQ2FtZWwgPSBuZXcgUmVnRXhwKCdeKGFyaWEpW0EtWl1bJyArIEFUVFJJQlVURV9OQU1FX0NIQVIgKyAnXSokJyk7XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUHJvcGVydHkodGFnTmFtZSwgbmFtZSkge1xuICB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwod2FybmVkUHJvcGVydGllcywgbmFtZSkgJiYgd2FybmVkUHJvcGVydGllc1tuYW1lXSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHJBUklBQ2FtZWwudGVzdChuYW1lKSkge1xuICAgICAgdmFyIGFyaWFOYW1lID0gJ2FyaWEtJyArIG5hbWUuc2xpY2UoNCkudG9Mb3dlckNhc2UoKTtcbiAgICAgIHZhciBjb3JyZWN0TmFtZSA9IGFyaWFQcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KGFyaWFOYW1lKSA/IGFyaWFOYW1lIDogbnVsbDsgLy8gSWYgdGhpcyBpcyBhbiBhcmlhLSogYXR0cmlidXRlLCBidXQgaXMgbm90IGxpc3RlZCBpbiB0aGUga25vd24gRE9NXG4gICAgICAvLyBET00gcHJvcGVydGllcywgdGhlbiBpdCBpcyBhbiBpbnZhbGlkIGFyaWEtKiBhdHRyaWJ1dGUuXG5cbiAgICAgIGlmIChjb3JyZWN0TmFtZSA9PSBudWxsKSB7XG4gICAgICAgIGVycm9yKCdJbnZhbGlkIEFSSUEgYXR0cmlidXRlIGAlc2AuIEFSSUEgYXR0cmlidXRlcyBmb2xsb3cgdGhlIHBhdHRlcm4gYXJpYS0qIGFuZCBtdXN0IGJlIGxvd2VyY2FzZS4nLCBuYW1lKTtcblxuICAgICAgICB3YXJuZWRQcm9wZXJ0aWVzW25hbWVdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IC8vIGFyaWEtKiBhdHRyaWJ1dGVzIHNob3VsZCBiZSBsb3dlcmNhc2U7IHN1Z2dlc3QgdGhlIGxvd2VyY2FzZSB2ZXJzaW9uLlxuXG5cbiAgICAgIGlmIChuYW1lICE9PSBjb3JyZWN0TmFtZSkge1xuICAgICAgICBlcnJvcignSW52YWxpZCBBUklBIGF0dHJpYnV0ZSBgJXNgLiBEaWQgeW91IG1lYW4gYCVzYD8nLCBuYW1lLCBjb3JyZWN0TmFtZSk7XG5cbiAgICAgICAgd2FybmVkUHJvcGVydGllc1tuYW1lXSA9IHRydWU7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyQVJJQS50ZXN0KG5hbWUpKSB7XG4gICAgICB2YXIgbG93ZXJDYXNlZE5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgICB2YXIgc3RhbmRhcmROYW1lID0gYXJpYVByb3BlcnRpZXMuaGFzT3duUHJvcGVydHkobG93ZXJDYXNlZE5hbWUpID8gbG93ZXJDYXNlZE5hbWUgOiBudWxsOyAvLyBJZiB0aGlzIGlzIGFuIGFyaWEtKiBhdHRyaWJ1dGUsIGJ1dCBpcyBub3QgbGlzdGVkIGluIHRoZSBrbm93biBET01cbiAgICAgIC8vIERPTSBwcm9wZXJ0aWVzLCB0aGVuIGl0IGlzIGFuIGludmFsaWQgYXJpYS0qIGF0dHJpYnV0ZS5cblxuICAgICAgaWYgKHN0YW5kYXJkTmFtZSA9PSBudWxsKSB7XG4gICAgICAgIHdhcm5lZFByb3BlcnRpZXNbbmFtZV0gPSB0cnVlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9IC8vIGFyaWEtKiBhdHRyaWJ1dGVzIHNob3VsZCBiZSBsb3dlcmNhc2U7IHN1Z2dlc3QgdGhlIGxvd2VyY2FzZSB2ZXJzaW9uLlxuXG5cbiAgICAgIGlmIChuYW1lICE9PSBzdGFuZGFyZE5hbWUpIHtcbiAgICAgICAgZXJyb3IoJ1Vua25vd24gQVJJQSBhdHRyaWJ1dGUgYCVzYC4gRGlkIHlvdSBtZWFuIGAlc2A/JywgbmFtZSwgc3RhbmRhcmROYW1lKTtcblxuICAgICAgICB3YXJuZWRQcm9wZXJ0aWVzW25hbWVdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHdhcm5JbnZhbGlkQVJJQVByb3BzKHR5cGUsIHByb3BzKSB7XG4gIHtcbiAgICB2YXIgaW52YWxpZFByb3BzID0gW107XG5cbiAgICBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHtcbiAgICAgIHZhciBpc1ZhbGlkID0gdmFsaWRhdGVQcm9wZXJ0eSh0eXBlLCBrZXkpO1xuXG4gICAgICBpZiAoIWlzVmFsaWQpIHtcbiAgICAgICAgaW52YWxpZFByb3BzLnB1c2goa2V5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgdW5rbm93blByb3BTdHJpbmcgPSBpbnZhbGlkUHJvcHMubWFwKGZ1bmN0aW9uIChwcm9wKSB7XG4gICAgICByZXR1cm4gJ2AnICsgcHJvcCArICdgJztcbiAgICB9KS5qb2luKCcsICcpO1xuXG4gICAgaWYgKGludmFsaWRQcm9wcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIGVycm9yKCdJbnZhbGlkIGFyaWEgcHJvcCAlcyBvbiA8JXM+IHRhZy4gJyArICdGb3IgZGV0YWlscywgc2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9pbnZhbGlkLWFyaWEtcHJvcHMnLCB1bmtub3duUHJvcFN0cmluZywgdHlwZSk7XG4gICAgfSBlbHNlIGlmIChpbnZhbGlkUHJvcHMubGVuZ3RoID4gMSkge1xuICAgICAgZXJyb3IoJ0ludmFsaWQgYXJpYSBwcm9wcyAlcyBvbiA8JXM+IHRhZy4gJyArICdGb3IgZGV0YWlscywgc2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9pbnZhbGlkLWFyaWEtcHJvcHMnLCB1bmtub3duUHJvcFN0cmluZywgdHlwZSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUHJvcGVydGllcyh0eXBlLCBwcm9wcykge1xuICBpZiAoaXNDdXN0b21Db21wb25lbnQodHlwZSwgcHJvcHMpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgd2FybkludmFsaWRBUklBUHJvcHModHlwZSwgcHJvcHMpO1xufVxuXG52YXIgZGlkV2FyblZhbHVlTnVsbCA9IGZhbHNlO1xuZnVuY3Rpb24gdmFsaWRhdGVQcm9wZXJ0aWVzJDEodHlwZSwgcHJvcHMpIHtcbiAge1xuICAgIGlmICh0eXBlICE9PSAnaW5wdXQnICYmIHR5cGUgIT09ICd0ZXh0YXJlYScgJiYgdHlwZSAhPT0gJ3NlbGVjdCcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMgIT0gbnVsbCAmJiBwcm9wcy52YWx1ZSA9PT0gbnVsbCAmJiAhZGlkV2FyblZhbHVlTnVsbCkge1xuICAgICAgZGlkV2FyblZhbHVlTnVsbCA9IHRydWU7XG5cbiAgICAgIGlmICh0eXBlID09PSAnc2VsZWN0JyAmJiBwcm9wcy5tdWx0aXBsZSkge1xuICAgICAgICBlcnJvcignYHZhbHVlYCBwcm9wIG9uIGAlc2Agc2hvdWxkIG5vdCBiZSBudWxsLiAnICsgJ0NvbnNpZGVyIHVzaW5nIGFuIGVtcHR5IGFycmF5IHdoZW4gYG11bHRpcGxlYCBpcyBzZXQgdG8gYHRydWVgICcgKyAndG8gY2xlYXIgdGhlIGNvbXBvbmVudCBvciBgdW5kZWZpbmVkYCBmb3IgdW5jb250cm9sbGVkIGNvbXBvbmVudHMuJywgdHlwZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlcnJvcignYHZhbHVlYCBwcm9wIG9uIGAlc2Agc2hvdWxkIG5vdCBiZSBudWxsLiAnICsgJ0NvbnNpZGVyIHVzaW5nIGFuIGVtcHR5IHN0cmluZyB0byBjbGVhciB0aGUgY29tcG9uZW50IG9yIGB1bmRlZmluZWRgICcgKyAnZm9yIHVuY29udHJvbGxlZCBjb21wb25lbnRzLicsIHR5cGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG52YXIgdmFsaWRhdGVQcm9wZXJ0eSQxID0gZnVuY3Rpb24gKCkge307XG5cbntcbiAgdmFyIHdhcm5lZFByb3BlcnRpZXMkMSA9IHt9O1xuICB2YXIgRVZFTlRfTkFNRV9SRUdFWCA9IC9eb24uLztcbiAgdmFyIElOVkFMSURfRVZFTlRfTkFNRV9SRUdFWCA9IC9eb25bXkEtWl0vO1xuICB2YXIgckFSSUEkMSA9IG5ldyBSZWdFeHAoJ14oYXJpYSktWycgKyBBVFRSSUJVVEVfTkFNRV9DSEFSICsgJ10qJCcpO1xuICB2YXIgckFSSUFDYW1lbCQxID0gbmV3IFJlZ0V4cCgnXihhcmlhKVtBLVpdWycgKyBBVFRSSUJVVEVfTkFNRV9DSEFSICsgJ10qJCcpO1xuXG4gIHZhbGlkYXRlUHJvcGVydHkkMSA9IGZ1bmN0aW9uICh0YWdOYW1lLCBuYW1lLCB2YWx1ZSwgZXZlbnRSZWdpc3RyeSkge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHdhcm5lZFByb3BlcnRpZXMkMSwgbmFtZSkgJiYgd2FybmVkUHJvcGVydGllcyQxW25hbWVdKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgbG93ZXJDYXNlZE5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAobG93ZXJDYXNlZE5hbWUgPT09ICdvbmZvY3VzaW4nIHx8IGxvd2VyQ2FzZWROYW1lID09PSAnb25mb2N1c291dCcpIHtcbiAgICAgIGVycm9yKCdSZWFjdCB1c2VzIG9uRm9jdXMgYW5kIG9uQmx1ciBpbnN0ZWFkIG9mIG9uRm9jdXNJbiBhbmQgb25Gb2N1c091dC4gJyArICdBbGwgUmVhY3QgZXZlbnRzIGFyZSBub3JtYWxpemVkIHRvIGJ1YmJsZSwgc28gb25Gb2N1c0luIGFuZCBvbkZvY3VzT3V0ICcgKyAnYXJlIG5vdCBuZWVkZWQvc3VwcG9ydGVkIGJ5IFJlYWN0LicpO1xuXG4gICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSAvLyBXZSBjYW4ndCByZWx5IG9uIHRoZSBldmVudCBzeXN0ZW0gYmVpbmcgaW5qZWN0ZWQgb24gdGhlIHNlcnZlci5cblxuXG4gICAgaWYgKGV2ZW50UmVnaXN0cnkgIT0gbnVsbCkge1xuICAgICAgdmFyIHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMgPSBldmVudFJlZ2lzdHJ5LnJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMsXG4gICAgICAgICAgcG9zc2libGVSZWdpc3RyYXRpb25OYW1lcyA9IGV2ZW50UmVnaXN0cnkucG9zc2libGVSZWdpc3RyYXRpb25OYW1lcztcblxuICAgICAgaWYgKHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHZhciByZWdpc3RyYXRpb25OYW1lID0gcG9zc2libGVSZWdpc3RyYXRpb25OYW1lcy5oYXNPd25Qcm9wZXJ0eShsb3dlckNhc2VkTmFtZSkgPyBwb3NzaWJsZVJlZ2lzdHJhdGlvbk5hbWVzW2xvd2VyQ2FzZWROYW1lXSA6IG51bGw7XG5cbiAgICAgIGlmIChyZWdpc3RyYXRpb25OYW1lICE9IG51bGwpIHtcbiAgICAgICAgZXJyb3IoJ0ludmFsaWQgZXZlbnQgaGFuZGxlciBwcm9wZXJ0eSBgJXNgLiBEaWQgeW91IG1lYW4gYCVzYD8nLCBuYW1lLCByZWdpc3RyYXRpb25OYW1lKTtcblxuICAgICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKEVWRU5UX05BTUVfUkVHRVgudGVzdChuYW1lKSkge1xuICAgICAgICBlcnJvcignVW5rbm93biBldmVudCBoYW5kbGVyIHByb3BlcnR5IGAlc2AuIEl0IHdpbGwgYmUgaWdub3JlZC4nLCBuYW1lKTtcblxuICAgICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKEVWRU5UX05BTUVfUkVHRVgudGVzdChuYW1lKSkge1xuICAgICAgLy8gSWYgbm8gZXZlbnQgcGx1Z2lucyBoYXZlIGJlZW4gaW5qZWN0ZWQsIHdlIGFyZSBpbiBhIHNlcnZlciBlbnZpcm9ubWVudC5cbiAgICAgIC8vIFNvIHdlIGNhbid0IHRlbGwgaWYgdGhlIGV2ZW50IG5hbWUgaXMgY29ycmVjdCBmb3Igc3VyZSwgYnV0IHdlIGNhbiBmaWx0ZXJcbiAgICAgIC8vIG91dCBrbm93biBiYWQgb25lcyBsaWtlIGBvbmNsaWNrYC4gV2UgY2FuJ3Qgc3VnZ2VzdCBhIHNwZWNpZmljIHJlcGxhY2VtZW50IHRob3VnaC5cbiAgICAgIGlmIChJTlZBTElEX0VWRU5UX05BTUVfUkVHRVgudGVzdChuYW1lKSkge1xuICAgICAgICBlcnJvcignSW52YWxpZCBldmVudCBoYW5kbGVyIHByb3BlcnR5IGAlc2AuICcgKyAnUmVhY3QgZXZlbnRzIHVzZSB0aGUgY2FtZWxDYXNlIG5hbWluZyBjb252ZW50aW9uLCBmb3IgZXhhbXBsZSBgb25DbGlja2AuJywgbmFtZSk7XG4gICAgICB9XG5cbiAgICAgIHdhcm5lZFByb3BlcnRpZXMkMVtuYW1lXSA9IHRydWU7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IC8vIExldCB0aGUgQVJJQSBhdHRyaWJ1dGUgaG9vayB2YWxpZGF0ZSBBUklBIGF0dHJpYnV0ZXNcblxuXG4gICAgaWYgKHJBUklBJDEudGVzdChuYW1lKSB8fCByQVJJQUNhbWVsJDEudGVzdChuYW1lKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGxvd2VyQ2FzZWROYW1lID09PSAnaW5uZXJodG1sJykge1xuICAgICAgZXJyb3IoJ0RpcmVjdGx5IHNldHRpbmcgcHJvcGVydHkgYGlubmVySFRNTGAgaXMgbm90IHBlcm1pdHRlZC4gJyArICdGb3IgbW9yZSBpbmZvcm1hdGlvbiwgbG9va3VwIGRvY3VtZW50YXRpb24gb24gYGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MYC4nKTtcblxuICAgICAgd2FybmVkUHJvcGVydGllcyQxW25hbWVdID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChsb3dlckNhc2VkTmFtZSA9PT0gJ2FyaWEnKSB7XG4gICAgICBlcnJvcignVGhlIGBhcmlhYCBhdHRyaWJ1dGUgaXMgcmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UgaW4gUmVhY3QuICcgKyAnUGFzcyBpbmRpdmlkdWFsIGBhcmlhLWAgYXR0cmlidXRlcyBpbnN0ZWFkLicpO1xuXG4gICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGxvd2VyQ2FzZWROYW1lID09PSAnaXMnICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgZXJyb3IoJ1JlY2VpdmVkIGEgYCVzYCBmb3IgYSBzdHJpbmcgYXR0cmlidXRlIGBpc2AuIElmIHRoaXMgaXMgZXhwZWN0ZWQsIGNhc3QgJyArICd0aGUgdmFsdWUgdG8gYSBzdHJpbmcuJywgdHlwZW9mIHZhbHVlKTtcblxuICAgICAgd2FybmVkUHJvcGVydGllcyQxW25hbWVdID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmIGlzTmFOKHZhbHVlKSkge1xuICAgICAgZXJyb3IoJ1JlY2VpdmVkIE5hTiBmb3IgdGhlIGAlc2AgYXR0cmlidXRlLiBJZiB0aGlzIGlzIGV4cGVjdGVkLCBjYXN0ICcgKyAndGhlIHZhbHVlIHRvIGEgc3RyaW5nLicsIG5hbWUpO1xuXG4gICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgdmFyIHByb3BlcnR5SW5mbyA9IGdldFByb3BlcnR5SW5mbyhuYW1lKTtcbiAgICB2YXIgaXNSZXNlcnZlZCA9IHByb3BlcnR5SW5mbyAhPT0gbnVsbCAmJiBwcm9wZXJ0eUluZm8udHlwZSA9PT0gUkVTRVJWRUQ7IC8vIEtub3duIGF0dHJpYnV0ZXMgc2hvdWxkIG1hdGNoIHRoZSBjYXNpbmcgc3BlY2lmaWVkIGluIHRoZSBwcm9wZXJ0eSBjb25maWcuXG5cbiAgICBpZiAocG9zc2libGVTdGFuZGFyZE5hbWVzLmhhc093blByb3BlcnR5KGxvd2VyQ2FzZWROYW1lKSkge1xuICAgICAgdmFyIHN0YW5kYXJkTmFtZSA9IHBvc3NpYmxlU3RhbmRhcmROYW1lc1tsb3dlckNhc2VkTmFtZV07XG5cbiAgICAgIGlmIChzdGFuZGFyZE5hbWUgIT09IG5hbWUpIHtcbiAgICAgICAgZXJyb3IoJ0ludmFsaWQgRE9NIHByb3BlcnR5IGAlc2AuIERpZCB5b3UgbWVhbiBgJXNgPycsIG5hbWUsIHN0YW5kYXJkTmFtZSk7XG5cbiAgICAgICAgd2FybmVkUHJvcGVydGllcyQxW25hbWVdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghaXNSZXNlcnZlZCAmJiBuYW1lICE9PSBsb3dlckNhc2VkTmFtZSkge1xuICAgICAgLy8gVW5rbm93biBhdHRyaWJ1dGVzIHNob3VsZCBoYXZlIGxvd2VyY2FzZSBjYXNpbmcgc2luY2UgdGhhdCdzIGhvdyB0aGV5XG4gICAgICAvLyB3aWxsIGJlIGNhc2VkIGFueXdheSB3aXRoIHNlcnZlciByZW5kZXJpbmcuXG4gICAgICBlcnJvcignUmVhY3QgZG9lcyBub3QgcmVjb2duaXplIHRoZSBgJXNgIHByb3Agb24gYSBET00gZWxlbWVudC4gSWYgeW91ICcgKyAnaW50ZW50aW9uYWxseSB3YW50IGl0IHRvIGFwcGVhciBpbiB0aGUgRE9NIGFzIGEgY3VzdG9tICcgKyAnYXR0cmlidXRlLCBzcGVsbCBpdCBhcyBsb3dlcmNhc2UgYCVzYCBpbnN0ZWFkLiAnICsgJ0lmIHlvdSBhY2NpZGVudGFsbHkgcGFzc2VkIGl0IGZyb20gYSBwYXJlbnQgY29tcG9uZW50LCByZW1vdmUgJyArICdpdCBmcm9tIHRoZSBET00gZWxlbWVudC4nLCBuYW1lLCBsb3dlckNhc2VkTmFtZSk7XG5cbiAgICAgIHdhcm5lZFByb3BlcnRpZXMkMVtuYW1lXSA9IHRydWU7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicgJiYgc2hvdWxkUmVtb3ZlQXR0cmlidXRlV2l0aFdhcm5pbmcobmFtZSwgdmFsdWUsIHByb3BlcnR5SW5mbywgZmFsc2UpKSB7XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgZXJyb3IoJ1JlY2VpdmVkIGAlc2AgZm9yIGEgbm9uLWJvb2xlYW4gYXR0cmlidXRlIGAlc2AuXFxuXFxuJyArICdJZiB5b3Ugd2FudCB0byB3cml0ZSBpdCB0byB0aGUgRE9NLCBwYXNzIGEgc3RyaW5nIGluc3RlYWQ6ICcgKyAnJXM9XCIlc1wiIG9yICVzPXt2YWx1ZS50b1N0cmluZygpfS4nLCB2YWx1ZSwgbmFtZSwgbmFtZSwgdmFsdWUsIG5hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXJyb3IoJ1JlY2VpdmVkIGAlc2AgZm9yIGEgbm9uLWJvb2xlYW4gYXR0cmlidXRlIGAlc2AuXFxuXFxuJyArICdJZiB5b3Ugd2FudCB0byB3cml0ZSBpdCB0byB0aGUgRE9NLCBwYXNzIGEgc3RyaW5nIGluc3RlYWQ6ICcgKyAnJXM9XCIlc1wiIG9yICVzPXt2YWx1ZS50b1N0cmluZygpfS5cXG5cXG4nICsgJ0lmIHlvdSB1c2VkIHRvIGNvbmRpdGlvbmFsbHkgb21pdCBpdCB3aXRoICVzPXtjb25kaXRpb24gJiYgdmFsdWV9LCAnICsgJ3Bhc3MgJXM9e2NvbmRpdGlvbiA/IHZhbHVlIDogdW5kZWZpbmVkfSBpbnN0ZWFkLicsIHZhbHVlLCBuYW1lLCBuYW1lLCB2YWx1ZSwgbmFtZSwgbmFtZSwgbmFtZSk7XG4gICAgICB9XG5cbiAgICAgIHdhcm5lZFByb3BlcnRpZXMkMVtuYW1lXSA9IHRydWU7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IC8vIE5vdyB0aGF0IHdlJ3ZlIHZhbGlkYXRlZCBjYXNpbmcsIGRvIG5vdCB2YWxpZGF0ZVxuICAgIC8vIGRhdGEgdHlwZXMgZm9yIHJlc2VydmVkIHByb3BzXG5cblxuICAgIGlmIChpc1Jlc2VydmVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IC8vIFdhcm4gd2hlbiBhIGtub3duIGF0dHJpYnV0ZSBpcyBhIGJhZCB0eXBlXG5cblxuICAgIGlmIChzaG91bGRSZW1vdmVBdHRyaWJ1dGVXaXRoV2FybmluZyhuYW1lLCB2YWx1ZSwgcHJvcGVydHlJbmZvLCBmYWxzZSkpIHtcbiAgICAgIHdhcm5lZFByb3BlcnRpZXMkMVtuYW1lXSA9IHRydWU7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSAvLyBXYXJuIHdoZW4gcGFzc2luZyB0aGUgc3RyaW5ncyAnZmFsc2UnIG9yICd0cnVlJyBpbnRvIGEgYm9vbGVhbiBwcm9wXG5cblxuICAgIGlmICgodmFsdWUgPT09ICdmYWxzZScgfHwgdmFsdWUgPT09ICd0cnVlJykgJiYgcHJvcGVydHlJbmZvICE9PSBudWxsICYmIHByb3BlcnR5SW5mby50eXBlID09PSBCT09MRUFOKSB7XG4gICAgICBlcnJvcignUmVjZWl2ZWQgdGhlIHN0cmluZyBgJXNgIGZvciB0aGUgYm9vbGVhbiBhdHRyaWJ1dGUgYCVzYC4gJyArICclcyAnICsgJ0RpZCB5b3UgbWVhbiAlcz17JXN9PycsIHZhbHVlLCBuYW1lLCB2YWx1ZSA9PT0gJ2ZhbHNlJyA/ICdUaGUgYnJvd3NlciB3aWxsIGludGVycHJldCBpdCBhcyBhIHRydXRoeSB2YWx1ZS4nIDogJ0FsdGhvdWdoIHRoaXMgd29ya3MsIGl0IHdpbGwgbm90IHdvcmsgYXMgZXhwZWN0ZWQgaWYgeW91IHBhc3MgdGhlIHN0cmluZyBcImZhbHNlXCIuJywgbmFtZSwgdmFsdWUpO1xuXG4gICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG59XG5cbnZhciB3YXJuVW5rbm93blByb3BlcnRpZXMgPSBmdW5jdGlvbiAodHlwZSwgcHJvcHMsIGV2ZW50UmVnaXN0cnkpIHtcbiAge1xuICAgIHZhciB1bmtub3duUHJvcHMgPSBbXTtcblxuICAgIGZvciAodmFyIGtleSBpbiBwcm9wcykge1xuICAgICAgdmFyIGlzVmFsaWQgPSB2YWxpZGF0ZVByb3BlcnR5JDEodHlwZSwga2V5LCBwcm9wc1trZXldLCBldmVudFJlZ2lzdHJ5KTtcblxuICAgICAgaWYgKCFpc1ZhbGlkKSB7XG4gICAgICAgIHVua25vd25Qcm9wcy5wdXNoKGtleSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHVua25vd25Qcm9wU3RyaW5nID0gdW5rbm93blByb3BzLm1hcChmdW5jdGlvbiAocHJvcCkge1xuICAgICAgcmV0dXJuICdgJyArIHByb3AgKyAnYCc7XG4gICAgfSkuam9pbignLCAnKTtcblxuICAgIGlmICh1bmtub3duUHJvcHMubGVuZ3RoID09PSAxKSB7XG4gICAgICBlcnJvcignSW52YWxpZCB2YWx1ZSBmb3IgcHJvcCAlcyBvbiA8JXM+IHRhZy4gRWl0aGVyIHJlbW92ZSBpdCBmcm9tIHRoZSBlbGVtZW50LCAnICsgJ29yIHBhc3MgYSBzdHJpbmcgb3IgbnVtYmVyIHZhbHVlIHRvIGtlZXAgaXQgaW4gdGhlIERPTS4gJyArICdGb3IgZGV0YWlscywgc2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9hdHRyaWJ1dGUtYmVoYXZpb3IgJywgdW5rbm93blByb3BTdHJpbmcsIHR5cGUpO1xuICAgIH0gZWxzZSBpZiAodW5rbm93blByb3BzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGVycm9yKCdJbnZhbGlkIHZhbHVlcyBmb3IgcHJvcHMgJXMgb24gPCVzPiB0YWcuIEVpdGhlciByZW1vdmUgdGhlbSBmcm9tIHRoZSBlbGVtZW50LCAnICsgJ29yIHBhc3MgYSBzdHJpbmcgb3IgbnVtYmVyIHZhbHVlIHRvIGtlZXAgdGhlbSBpbiB0aGUgRE9NLiAnICsgJ0ZvciBkZXRhaWxzLCBzZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL2F0dHJpYnV0ZS1iZWhhdmlvciAnLCB1bmtub3duUHJvcFN0cmluZywgdHlwZSk7XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiB2YWxpZGF0ZVByb3BlcnRpZXMkMih0eXBlLCBwcm9wcywgZXZlbnRSZWdpc3RyeSkge1xuICBpZiAoaXNDdXN0b21Db21wb25lbnQodHlwZSwgcHJvcHMpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgd2FyblVua25vd25Qcm9wZXJ0aWVzKHR5cGUsIHByb3BzLCBldmVudFJlZ2lzdHJ5KTtcbn1cblxudmFyIElTX0VWRU5UX0hBTkRMRV9OT05fTUFOQUdFRF9OT0RFID0gMTtcbnZhciBJU19OT05fREVMRUdBVEVEID0gMSA8PCAxO1xudmFyIElTX0NBUFRVUkVfUEhBU0UgPSAxIDw8IDI7XG4vLyBzZXQgdG8gTEVHQUNZX0ZCX1NVUFBPUlQuIExFR0FDWV9GQl9TVVBQT1JUIG9ubHkgZ2V0cyBzZXQgd2hlblxuLy8gd2UgY2FsbCB3aWxsRGVmZXJMYXRlckZvckxlZ2FjeUZCU3VwcG9ydCwgdGh1cyBub3QgYmFpbGluZyBvdXRcbi8vIHdpbGwgcmVzdWx0IGluIGVuZGxlc3MgY3ljbGVzIGxpa2UgYW4gaW5maW5pdGUgbG9vcC5cbi8vIFdlIGFsc28gZG9uJ3Qgd2FudCB0byBkZWZlciBkdXJpbmcgZXZlbnQgcmVwbGF5aW5nLlxuXG52YXIgU0hPVUxEX05PVF9QUk9DRVNTX1BPTFlGSUxMX0VWRU5UX1BMVUdJTlMgPSBJU19FVkVOVF9IQU5ETEVfTk9OX01BTkFHRURfTk9ERSB8IElTX05PTl9ERUxFR0FURUQgfCBJU19DQVBUVVJFX1BIQVNFO1xuXG4vLyBUaGlzIGV4aXN0cyB0byBhdm9pZCBjaXJjdWxhciBkZXBlbmRlbmN5IGJldHdlZW4gUmVhY3RET01FdmVudFJlcGxheWluZ1xuLy8gYW5kIERPTVBsdWdpbkV2ZW50U3lzdGVtLlxudmFyIGN1cnJlbnRSZXBsYXlpbmdFdmVudCA9IG51bGw7XG5mdW5jdGlvbiBzZXRSZXBsYXlpbmdFdmVudChldmVudCkge1xuICB7XG4gICAgaWYgKGN1cnJlbnRSZXBsYXlpbmdFdmVudCAhPT0gbnVsbCkge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIGN1cnJlbnRseSByZXBsYXlpbmcgZXZlbnQgdG8gYmUgbnVsbC4gVGhpcyBlcnJvciAnICsgJ2lzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfVxuXG4gIGN1cnJlbnRSZXBsYXlpbmdFdmVudCA9IGV2ZW50O1xufVxuZnVuY3Rpb24gcmVzZXRSZXBsYXlpbmdFdmVudCgpIHtcbiAge1xuICAgIGlmIChjdXJyZW50UmVwbGF5aW5nRXZlbnQgPT09IG51bGwpIHtcbiAgICAgIGVycm9yKCdFeHBlY3RlZCBjdXJyZW50bHkgcmVwbGF5aW5nIGV2ZW50IHRvIG5vdCBiZSBudWxsLiBUaGlzIGVycm9yICcgKyAnaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuICB9XG5cbiAgY3VycmVudFJlcGxheWluZ0V2ZW50ID0gbnVsbDtcbn1cbmZ1bmN0aW9uIGlzUmVwbGF5aW5nRXZlbnQoZXZlbnQpIHtcbiAgcmV0dXJuIGV2ZW50ID09PSBjdXJyZW50UmVwbGF5aW5nRXZlbnQ7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgdGFyZ2V0IG5vZGUgZnJvbSBhIG5hdGl2ZSBicm93c2VyIGV2ZW50IGJ5IGFjY291bnRpbmcgZm9yXG4gKiBpbmNvbnNpc3RlbmNpZXMgaW4gYnJvd3NlciBET00gQVBJcy5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtET01FdmVudFRhcmdldH0gVGFyZ2V0IG5vZGUuXG4gKi9cblxuZnVuY3Rpb24gZ2V0RXZlbnRUYXJnZXQobmF0aXZlRXZlbnQpIHtcbiAgLy8gRmFsbGJhY2sgdG8gbmF0aXZlRXZlbnQuc3JjRWxlbWVudCBmb3IgSUU5XG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTI1MDZcbiAgdmFyIHRhcmdldCA9IG5hdGl2ZUV2ZW50LnRhcmdldCB8fCBuYXRpdmVFdmVudC5zcmNFbGVtZW50IHx8IHdpbmRvdzsgLy8gTm9ybWFsaXplIFNWRyA8dXNlPiBlbGVtZW50IGV2ZW50cyAjNDk2M1xuXG4gIGlmICh0YXJnZXQuY29ycmVzcG9uZGluZ1VzZUVsZW1lbnQpIHtcbiAgICB0YXJnZXQgPSB0YXJnZXQuY29ycmVzcG9uZGluZ1VzZUVsZW1lbnQ7XG4gIH0gLy8gU2FmYXJpIG1heSBmaXJlIGV2ZW50cyBvbiB0ZXh0IG5vZGVzIChOb2RlLlRFWFRfTk9ERSBpcyAzKS5cbiAgLy8gQHNlZSBodHRwOi8vd3d3LnF1aXJrc21vZGUub3JnL2pzL2V2ZW50c19wcm9wZXJ0aWVzLmh0bWxcblxuXG4gIHJldHVybiB0YXJnZXQubm9kZVR5cGUgPT09IFRFWFRfTk9ERSA/IHRhcmdldC5wYXJlbnROb2RlIDogdGFyZ2V0O1xufVxuXG52YXIgcmVzdG9yZUltcGwgPSBudWxsO1xudmFyIHJlc3RvcmVUYXJnZXQgPSBudWxsO1xudmFyIHJlc3RvcmVRdWV1ZSA9IG51bGw7XG5cbmZ1bmN0aW9uIHJlc3RvcmVTdGF0ZU9mVGFyZ2V0KHRhcmdldCkge1xuICAvLyBXZSBwZXJmb3JtIHRoaXMgdHJhbnNsYXRpb24gYXQgdGhlIGVuZCBvZiB0aGUgZXZlbnQgbG9vcCBzbyB0aGF0IHdlXG4gIC8vIGFsd2F5cyByZWNlaXZlIHRoZSBjb3JyZWN0IGZpYmVyIGhlcmVcbiAgdmFyIGludGVybmFsSW5zdGFuY2UgPSBnZXRJbnN0YW5jZUZyb21Ob2RlKHRhcmdldCk7XG5cbiAgaWYgKCFpbnRlcm5hbEluc3RhbmNlKSB7XG4gICAgLy8gVW5tb3VudGVkXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHR5cGVvZiByZXN0b3JlSW1wbCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBFcnJvcignc2V0UmVzdG9yZUltcGxlbWVudGF0aW9uKCkgbmVlZHMgdG8gYmUgY2FsbGVkIHRvIGhhbmRsZSBhIHRhcmdldCBmb3IgY29udHJvbGxlZCAnICsgJ2V2ZW50cy4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgfVxuXG4gIHZhciBzdGF0ZU5vZGUgPSBpbnRlcm5hbEluc3RhbmNlLnN0YXRlTm9kZTsgLy8gR3VhcmQgYWdhaW5zdCBGaWJlciBiZWluZyB1bm1vdW50ZWQuXG5cbiAgaWYgKHN0YXRlTm9kZSkge1xuICAgIHZhciBfcHJvcHMgPSBnZXRGaWJlckN1cnJlbnRQcm9wc0Zyb21Ob2RlKHN0YXRlTm9kZSk7XG5cbiAgICByZXN0b3JlSW1wbChpbnRlcm5hbEluc3RhbmNlLnN0YXRlTm9kZSwgaW50ZXJuYWxJbnN0YW5jZS50eXBlLCBfcHJvcHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNldFJlc3RvcmVJbXBsZW1lbnRhdGlvbihpbXBsKSB7XG4gIHJlc3RvcmVJbXBsID0gaW1wbDtcbn1cbmZ1bmN0aW9uIGVucXVldWVTdGF0ZVJlc3RvcmUodGFyZ2V0KSB7XG4gIGlmIChyZXN0b3JlVGFyZ2V0KSB7XG4gICAgaWYgKHJlc3RvcmVRdWV1ZSkge1xuICAgICAgcmVzdG9yZVF1ZXVlLnB1c2godGFyZ2V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdG9yZVF1ZXVlID0gW3RhcmdldF07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJlc3RvcmVUYXJnZXQgPSB0YXJnZXQ7XG4gIH1cbn1cbmZ1bmN0aW9uIG5lZWRzU3RhdGVSZXN0b3JlKCkge1xuICByZXR1cm4gcmVzdG9yZVRhcmdldCAhPT0gbnVsbCB8fCByZXN0b3JlUXVldWUgIT09IG51bGw7XG59XG5mdW5jdGlvbiByZXN0b3JlU3RhdGVJZk5lZWRlZCgpIHtcbiAgaWYgKCFyZXN0b3JlVGFyZ2V0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHRhcmdldCA9IHJlc3RvcmVUYXJnZXQ7XG4gIHZhciBxdWV1ZWRUYXJnZXRzID0gcmVzdG9yZVF1ZXVlO1xuICByZXN0b3JlVGFyZ2V0ID0gbnVsbDtcbiAgcmVzdG9yZVF1ZXVlID0gbnVsbDtcbiAgcmVzdG9yZVN0YXRlT2ZUYXJnZXQodGFyZ2V0KTtcblxuICBpZiAocXVldWVkVGFyZ2V0cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcXVldWVkVGFyZ2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgcmVzdG9yZVN0YXRlT2ZUYXJnZXQocXVldWVkVGFyZ2V0c1tpXSk7XG4gICAgfVxuICB9XG59XG5cbi8vIHRoZSByZW5kZXJlci4gU3VjaCBhcyB3aGVuIHdlJ3JlIGRpc3BhdGNoaW5nIGV2ZW50cyBvciBpZiB0aGlyZCBwYXJ0eVxuLy8gbGlicmFyaWVzIG5lZWQgdG8gY2FsbCBiYXRjaGVkVXBkYXRlcy4gRXZlbnR1YWxseSwgdGhpcyBBUEkgd2lsbCBnbyBhd2F5IHdoZW5cbi8vIGV2ZXJ5dGhpbmcgaXMgYmF0Y2hlZCBieSBkZWZhdWx0LiBXZSdsbCB0aGVuIGhhdmUgYSBzaW1pbGFyIEFQSSB0byBvcHQtb3V0IG9mXG4vLyBzY2hlZHVsZWQgd29yayBhbmQgaW5zdGVhZCBkbyBzeW5jaHJvbm91cyB3b3JrLlxuLy8gRGVmYXVsdHNcblxudmFyIGJhdGNoZWRVcGRhdGVzSW1wbCA9IGZ1bmN0aW9uIChmbiwgYm9va2tlZXBpbmcpIHtcbiAgcmV0dXJuIGZuKGJvb2trZWVwaW5nKTtcbn07XG5cbnZhciBmbHVzaFN5bmNJbXBsID0gZnVuY3Rpb24gKCkge307XG5cbnZhciBpc0luc2lkZUV2ZW50SGFuZGxlciA9IGZhbHNlO1xuXG5mdW5jdGlvbiBmaW5pc2hFdmVudEhhbmRsZXIoKSB7XG4gIC8vIEhlcmUgd2Ugd2FpdCB1bnRpbCBhbGwgdXBkYXRlcyBoYXZlIHByb3BhZ2F0ZWQsIHdoaWNoIGlzIGltcG9ydGFudFxuICAvLyB3aGVuIHVzaW5nIGNvbnRyb2xsZWQgY29tcG9uZW50cyB3aXRoaW4gbGF5ZXJzOlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzE2OThcbiAgLy8gVGhlbiB3ZSByZXN0b3JlIHN0YXRlIG9mIGFueSBjb250cm9sbGVkIGNvbXBvbmVudC5cbiAgdmFyIGNvbnRyb2xsZWRDb21wb25lbnRzSGF2ZVBlbmRpbmdVcGRhdGVzID0gbmVlZHNTdGF0ZVJlc3RvcmUoKTtcblxuICBpZiAoY29udHJvbGxlZENvbXBvbmVudHNIYXZlUGVuZGluZ1VwZGF0ZXMpIHtcbiAgICAvLyBJZiBhIGNvbnRyb2xsZWQgZXZlbnQgd2FzIGZpcmVkLCB3ZSBtYXkgbmVlZCB0byByZXN0b3JlIHRoZSBzdGF0ZSBvZlxuICAgIC8vIHRoZSBET00gbm9kZSBiYWNrIHRvIHRoZSBjb250cm9sbGVkIHZhbHVlLiBUaGlzIGlzIG5lY2Vzc2FyeSB3aGVuIFJlYWN0XG4gICAgLy8gYmFpbHMgb3V0IG9mIHRoZSB1cGRhdGUgd2l0aG91dCB0b3VjaGluZyB0aGUgRE9NLlxuICAgIC8vIFRPRE86IFJlc3RvcmUgc3RhdGUgaW4gdGhlIG1pY3JvdGFzaywgYWZ0ZXIgdGhlIGRpc2NyZXRlIHVwZGF0ZXMgZmx1c2gsXG4gICAgLy8gaW5zdGVhZCBvZiBlYXJseSBmbHVzaGluZyB0aGVtIGhlcmUuXG4gICAgZmx1c2hTeW5jSW1wbCgpO1xuICAgIHJlc3RvcmVTdGF0ZUlmTmVlZGVkKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYmF0Y2hlZFVwZGF0ZXMoZm4sIGEsIGIpIHtcbiAgaWYgKGlzSW5zaWRlRXZlbnRIYW5kbGVyKSB7XG4gICAgLy8gSWYgd2UgYXJlIGN1cnJlbnRseSBpbnNpZGUgYW5vdGhlciBiYXRjaCwgd2UgbmVlZCB0byB3YWl0IHVudGlsIGl0XG4gICAgLy8gZnVsbHkgY29tcGxldGVzIGJlZm9yZSByZXN0b3Jpbmcgc3RhdGUuXG4gICAgcmV0dXJuIGZuKGEsIGIpO1xuICB9XG5cbiAgaXNJbnNpZGVFdmVudEhhbmRsZXIgPSB0cnVlO1xuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGJhdGNoZWRVcGRhdGVzSW1wbChmbiwgYSwgYik7XG4gIH0gZmluYWxseSB7XG4gICAgaXNJbnNpZGVFdmVudEhhbmRsZXIgPSBmYWxzZTtcbiAgICBmaW5pc2hFdmVudEhhbmRsZXIoKTtcbiAgfVxufSAvLyBUT0RPOiBSZXBsYWNlIHdpdGggZmx1c2hTeW5jXG5mdW5jdGlvbiBzZXRCYXRjaGluZ0ltcGxlbWVudGF0aW9uKF9iYXRjaGVkVXBkYXRlc0ltcGwsIF9kaXNjcmV0ZVVwZGF0ZXNJbXBsLCBfZmx1c2hTeW5jSW1wbCkge1xuICBiYXRjaGVkVXBkYXRlc0ltcGwgPSBfYmF0Y2hlZFVwZGF0ZXNJbXBsO1xuICBmbHVzaFN5bmNJbXBsID0gX2ZsdXNoU3luY0ltcGw7XG59XG5cbmZ1bmN0aW9uIGlzSW50ZXJhY3RpdmUodGFnKSB7XG4gIHJldHVybiB0YWcgPT09ICdidXR0b24nIHx8IHRhZyA9PT0gJ2lucHV0JyB8fCB0YWcgPT09ICdzZWxlY3QnIHx8IHRhZyA9PT0gJ3RleHRhcmVhJztcbn1cblxuZnVuY3Rpb24gc2hvdWxkUHJldmVudE1vdXNlRXZlbnQobmFtZSwgdHlwZSwgcHJvcHMpIHtcbiAgc3dpdGNoIChuYW1lKSB7XG4gICAgY2FzZSAnb25DbGljayc6XG4gICAgY2FzZSAnb25DbGlja0NhcHR1cmUnOlxuICAgIGNhc2UgJ29uRG91YmxlQ2xpY2snOlxuICAgIGNhc2UgJ29uRG91YmxlQ2xpY2tDYXB0dXJlJzpcbiAgICBjYXNlICdvbk1vdXNlRG93bic6XG4gICAgY2FzZSAnb25Nb3VzZURvd25DYXB0dXJlJzpcbiAgICBjYXNlICdvbk1vdXNlTW92ZSc6XG4gICAgY2FzZSAnb25Nb3VzZU1vdmVDYXB0dXJlJzpcbiAgICBjYXNlICdvbk1vdXNlVXAnOlxuICAgIGNhc2UgJ29uTW91c2VVcENhcHR1cmUnOlxuICAgIGNhc2UgJ29uTW91c2VFbnRlcic6XG4gICAgICByZXR1cm4gISEocHJvcHMuZGlzYWJsZWQgJiYgaXNJbnRlcmFjdGl2ZSh0eXBlKSk7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7b2JqZWN0fSBpbnN0IFRoZSBpbnN0YW5jZSwgd2hpY2ggaXMgdGhlIHNvdXJjZSBvZiBldmVudHMuXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVnaXN0cmF0aW9uTmFtZSBOYW1lIG9mIGxpc3RlbmVyIChlLmcuIGBvbkNsaWNrYCkuXG4gKiBAcmV0dXJuIHs/ZnVuY3Rpb259IFRoZSBzdG9yZWQgY2FsbGJhY2suXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRMaXN0ZW5lcihpbnN0LCByZWdpc3RyYXRpb25OYW1lKSB7XG4gIHZhciBzdGF0ZU5vZGUgPSBpbnN0LnN0YXRlTm9kZTtcblxuICBpZiAoc3RhdGVOb2RlID09PSBudWxsKSB7XG4gICAgLy8gV29yayBpbiBwcm9ncmVzcyAoZXg6IG9ubG9hZCBldmVudHMgaW4gaW5jcmVtZW50YWwgbW9kZSkuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgcHJvcHMgPSBnZXRGaWJlckN1cnJlbnRQcm9wc0Zyb21Ob2RlKHN0YXRlTm9kZSk7XG5cbiAgaWYgKHByb3BzID09PSBudWxsKSB7XG4gICAgLy8gV29yayBpbiBwcm9ncmVzcy5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBsaXN0ZW5lciA9IHByb3BzW3JlZ2lzdHJhdGlvbk5hbWVdO1xuXG4gIGlmIChzaG91bGRQcmV2ZW50TW91c2VFdmVudChyZWdpc3RyYXRpb25OYW1lLCBpbnN0LnR5cGUsIHByb3BzKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKGxpc3RlbmVyICYmIHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkIGBcIiArIHJlZ2lzdHJhdGlvbk5hbWUgKyBcImAgbGlzdGVuZXIgdG8gYmUgYSBmdW5jdGlvbiwgaW5zdGVhZCBnb3QgYSB2YWx1ZSBvZiBgXCIgKyB0eXBlb2YgbGlzdGVuZXIgKyBcImAgdHlwZS5cIik7XG4gIH1cblxuICByZXR1cm4gbGlzdGVuZXI7XG59XG5cbnZhciBwYXNzaXZlQnJvd3NlckV2ZW50c1N1cHBvcnRlZCA9IGZhbHNlOyAvLyBDaGVjayBpZiBicm93c2VyIHN1cHBvcnQgZXZlbnRzIHdpdGggcGFzc2l2ZSBsaXN0ZW5lcnNcbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FdmVudFRhcmdldC9hZGRFdmVudExpc3RlbmVyI1NhZmVseV9kZXRlY3Rpbmdfb3B0aW9uX3N1cHBvcnRcblxuaWYgKGNhblVzZURPTSkge1xuICB0cnkge1xuICAgIHZhciBvcHRpb25zID0ge307IC8vICRGbG93Rml4TWU6IElnbm9yZSBGbG93IGNvbXBsYWluaW5nIGFib3V0IG5lZWRpbmcgYSB2YWx1ZVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9wdGlvbnMsICdwYXNzaXZlJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHBhc3NpdmVCcm93c2VyRXZlbnRzU3VwcG9ydGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndGVzdCcsIG9wdGlvbnMsIG9wdGlvbnMpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCd0ZXN0Jywgb3B0aW9ucywgb3B0aW9ucyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBwYXNzaXZlQnJvd3NlckV2ZW50c1N1cHBvcnRlZCA9IGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGludm9rZUd1YXJkZWRDYWxsYmFja1Byb2QobmFtZSwgZnVuYywgY29udGV4dCwgYSwgYiwgYywgZCwgZSwgZikge1xuICB2YXIgZnVuY0FyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDMpO1xuXG4gIHRyeSB7XG4gICAgZnVuYy5hcHBseShjb250ZXh0LCBmdW5jQXJncyk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhpcy5vbkVycm9yKGVycm9yKTtcbiAgfVxufVxuXG52YXIgaW52b2tlR3VhcmRlZENhbGxiYWNrSW1wbCA9IGludm9rZUd1YXJkZWRDYWxsYmFja1Byb2Q7XG5cbntcbiAgLy8gSW4gREVWIG1vZGUsIHdlIHN3YXAgb3V0IGludm9rZUd1YXJkZWRDYWxsYmFjayBmb3IgYSBzcGVjaWFsIHZlcnNpb25cbiAgLy8gdGhhdCBwbGF5cyBtb3JlIG5pY2VseSB3aXRoIHRoZSBicm93c2VyJ3MgRGV2VG9vbHMuIFRoZSBpZGVhIGlzIHRvIHByZXNlcnZlXG4gIC8vIFwiUGF1c2Ugb24gZXhjZXB0aW9uc1wiIGJlaGF2aW9yLiBCZWNhdXNlIFJlYWN0IHdyYXBzIGFsbCB1c2VyLXByb3ZpZGVkXG4gIC8vIGZ1bmN0aW9ucyBpbiBpbnZva2VHdWFyZGVkQ2FsbGJhY2ssIGFuZCB0aGUgcHJvZHVjdGlvbiB2ZXJzaW9uIG9mXG4gIC8vIGludm9rZUd1YXJkZWRDYWxsYmFjayB1c2VzIGEgdHJ5LWNhdGNoLCBhbGwgdXNlciBleGNlcHRpb25zIGFyZSB0cmVhdGVkXG4gIC8vIGxpa2UgY2F1Z2h0IGV4Y2VwdGlvbnMsIGFuZCB0aGUgRGV2VG9vbHMgd29uJ3QgcGF1c2UgdW5sZXNzIHRoZSBkZXZlbG9wZXJcbiAgLy8gdGFrZXMgdGhlIGV4dHJhIHN0ZXAgb2YgZW5hYmxpbmcgcGF1c2Ugb24gY2F1Z2h0IGV4Y2VwdGlvbnMuIFRoaXMgaXNcbiAgLy8gdW5pbnR1aXRpdmUsIHRob3VnaCwgYmVjYXVzZSBldmVuIHRob3VnaCBSZWFjdCBoYXMgY2F1Z2h0IHRoZSBlcnJvciwgZnJvbVxuICAvLyB0aGUgZGV2ZWxvcGVyJ3MgcGVyc3BlY3RpdmUsIHRoZSBlcnJvciBpcyB1bmNhdWdodC5cbiAgLy9cbiAgLy8gVG8gcHJlc2VydmUgdGhlIGV4cGVjdGVkIFwiUGF1c2Ugb24gZXhjZXB0aW9uc1wiIGJlaGF2aW9yLCB3ZSBkb24ndCB1c2UgYVxuICAvLyB0cnktY2F0Y2ggaW4gREVWLiBJbnN0ZWFkLCB3ZSBzeW5jaHJvbm91c2x5IGRpc3BhdGNoIGEgZmFrZSBldmVudCB0byBhIGZha2VcbiAgLy8gRE9NIG5vZGUsIGFuZCBjYWxsIHRoZSB1c2VyLXByb3ZpZGVkIGNhbGxiYWNrIGZyb20gaW5zaWRlIGFuIGV2ZW50IGhhbmRsZXJcbiAgLy8gZm9yIHRoYXQgZmFrZSBldmVudC4gSWYgdGhlIGNhbGxiYWNrIHRocm93cywgdGhlIGVycm9yIGlzIFwiY2FwdHVyZWRcIiB1c2luZ1xuICAvLyBhIGdsb2JhbCBldmVudCBoYW5kbGVyLiBCdXQgYmVjYXVzZSB0aGUgZXJyb3IgaGFwcGVucyBpbiBhIGRpZmZlcmVudFxuICAvLyBldmVudCBsb29wIGNvbnRleHQsIGl0IGRvZXMgbm90IGludGVycnVwdCB0aGUgbm9ybWFsIHByb2dyYW0gZmxvdy5cbiAgLy8gRWZmZWN0aXZlbHksIHRoaXMgZ2l2ZXMgdXMgdHJ5LWNhdGNoIGJlaGF2aW9yIHdpdGhvdXQgYWN0dWFsbHkgdXNpbmdcbiAgLy8gdHJ5LWNhdGNoLiBOZWF0IVxuICAvLyBDaGVjayB0aGF0IHRoZSBicm93c2VyIHN1cHBvcnRzIHRoZSBBUElzIHdlIG5lZWQgdG8gaW1wbGVtZW50IG91ciBzcGVjaWFsXG4gIC8vIERFViB2ZXJzaW9uIG9mIGludm9rZUd1YXJkZWRDYWxsYmFja1xuICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHdpbmRvdy5kaXNwYXRjaEV2ZW50ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGRvY3VtZW50LmNyZWF0ZUV2ZW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdmFyIGZha2VOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgncmVhY3QnKTtcblxuICAgIGludm9rZUd1YXJkZWRDYWxsYmFja0ltcGwgPSBmdW5jdGlvbiBpbnZva2VHdWFyZGVkQ2FsbGJhY2tEZXYobmFtZSwgZnVuYywgY29udGV4dCwgYSwgYiwgYywgZCwgZSwgZikge1xuICAgICAgLy8gSWYgZG9jdW1lbnQgZG9lc24ndCBleGlzdCB3ZSBrbm93IGZvciBzdXJlIHdlIHdpbGwgY3Jhc2ggaW4gdGhpcyBtZXRob2RcbiAgICAgIC8vIHdoZW4gd2UgY2FsbCBkb2N1bWVudC5jcmVhdGVFdmVudCgpLiBIb3dldmVyIHRoaXMgY2FuIGNhdXNlIGNvbmZ1c2luZ1xuICAgICAgLy8gZXJyb3JzOiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svY3JlYXRlLXJlYWN0LWFwcC9pc3N1ZXMvMzQ4MlxuICAgICAgLy8gU28gd2UgcHJlZW1wdGl2ZWx5IHRocm93IHdpdGggYSBiZXR0ZXIgbWVzc2FnZSBpbnN0ZWFkLlxuICAgICAgaWYgKHR5cGVvZiBkb2N1bWVudCA9PT0gJ3VuZGVmaW5lZCcgfHwgZG9jdW1lbnQgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgYGRvY3VtZW50YCBnbG9iYWwgd2FzIGRlZmluZWQgd2hlbiBSZWFjdCB3YXMgaW5pdGlhbGl6ZWQsIGJ1dCBpcyBub3QgJyArICdkZWZpbmVkIGFueW1vcmUuIFRoaXMgY2FuIGhhcHBlbiBpbiBhIHRlc3QgZW52aXJvbm1lbnQgaWYgYSBjb21wb25lbnQgJyArICdzY2hlZHVsZXMgYW4gdXBkYXRlIGZyb20gYW4gYXN5bmNocm9ub3VzIGNhbGxiYWNrLCBidXQgdGhlIHRlc3QgaGFzIGFscmVhZHkgJyArICdmaW5pc2hlZCBydW5uaW5nLiBUbyBzb2x2ZSB0aGlzLCB5b3UgY2FuIGVpdGhlciB1bm1vdW50IHRoZSBjb21wb25lbnQgYXQgJyArICd0aGUgZW5kIG9mIHlvdXIgdGVzdCAoYW5kIGVuc3VyZSB0aGF0IGFueSBhc3luY2hyb25vdXMgb3BlcmF0aW9ucyBnZXQgJyArICdjYW5jZWxlZCBpbiBgY29tcG9uZW50V2lsbFVubW91bnRgKSwgb3IgeW91IGNhbiBjaGFuZ2UgdGhlIHRlc3QgaXRzZWxmICcgKyAndG8gYmUgYXN5bmNocm9ub3VzLicpO1xuICAgICAgfVxuXG4gICAgICB2YXIgZXZ0ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0V2ZW50Jyk7XG4gICAgICB2YXIgZGlkQ2FsbCA9IGZhbHNlOyAvLyBLZWVwcyB0cmFjayBvZiB3aGV0aGVyIHRoZSB1c2VyLXByb3ZpZGVkIGNhbGxiYWNrIHRocmV3IGFuIGVycm9yLiBXZVxuICAgICAgLy8gc2V0IHRoaXMgdG8gdHJ1ZSBhdCB0aGUgYmVnaW5uaW5nLCB0aGVuIHNldCBpdCB0byBmYWxzZSByaWdodCBhZnRlclxuICAgICAgLy8gY2FsbGluZyB0aGUgZnVuY3Rpb24uIElmIHRoZSBmdW5jdGlvbiBlcnJvcnMsIGBkaWRFcnJvcmAgd2lsbCBuZXZlciBiZVxuICAgICAgLy8gc2V0IHRvIGZhbHNlLiBUaGlzIHN0cmF0ZWd5IHdvcmtzIGV2ZW4gaWYgdGhlIGJyb3dzZXIgaXMgZmxha3kgYW5kXG4gICAgICAvLyBmYWlscyB0byBjYWxsIG91ciBnbG9iYWwgZXJyb3IgaGFuZGxlciwgYmVjYXVzZSBpdCBkb2Vzbid0IHJlbHkgb25cbiAgICAgIC8vIHRoZSBlcnJvciBldmVudCBhdCBhbGwuXG5cbiAgICAgIHZhciBkaWRFcnJvciA9IHRydWU7IC8vIEtlZXBzIHRyYWNrIG9mIHRoZSB2YWx1ZSBvZiB3aW5kb3cuZXZlbnQgc28gdGhhdCB3ZSBjYW4gcmVzZXQgaXRcbiAgICAgIC8vIGR1cmluZyB0aGUgY2FsbGJhY2sgdG8gbGV0IHVzZXIgY29kZSBhY2Nlc3Mgd2luZG93LmV2ZW50IGluIHRoZVxuICAgICAgLy8gYnJvd3NlcnMgdGhhdCBzdXBwb3J0IGl0LlxuXG4gICAgICB2YXIgd2luZG93RXZlbnQgPSB3aW5kb3cuZXZlbnQ7IC8vIEtlZXBzIHRyYWNrIG9mIHRoZSBkZXNjcmlwdG9yIG9mIHdpbmRvdy5ldmVudCB0byByZXN0b3JlIGl0IGFmdGVyIGV2ZW50XG4gICAgICAvLyBkaXNwYXRjaGluZzogaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xMzY4OFxuXG4gICAgICB2YXIgd2luZG93RXZlbnREZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih3aW5kb3csICdldmVudCcpO1xuXG4gICAgICBmdW5jdGlvbiByZXN0b3JlQWZ0ZXJEaXNwYXRjaCgpIHtcbiAgICAgICAgLy8gV2UgaW1tZWRpYXRlbHkgcmVtb3ZlIHRoZSBjYWxsYmFjayBmcm9tIGV2ZW50IGxpc3RlbmVycyBzbyB0aGF0XG4gICAgICAgIC8vIG5lc3RlZCBgaW52b2tlR3VhcmRlZENhbGxiYWNrYCBjYWxscyBkbyBub3QgY2xhc2guIE90aGVyd2lzZSwgYVxuICAgICAgICAvLyBuZXN0ZWQgY2FsbCB3b3VsZCB0cmlnZ2VyIHRoZSBmYWtlIGV2ZW50IGhhbmRsZXJzIG9mIGFueSBjYWxsIGhpZ2hlclxuICAgICAgICAvLyBpbiB0aGUgc3RhY2suXG4gICAgICAgIGZha2VOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZ0VHlwZSwgY2FsbENhbGxiYWNrLCBmYWxzZSk7IC8vIFdlIGNoZWNrIGZvciB3aW5kb3cuaGFzT3duUHJvcGVydHkoJ2V2ZW50JykgdG8gcHJldmVudCB0aGVcbiAgICAgICAgLy8gd2luZG93LmV2ZW50IGFzc2lnbm1lbnQgaW4gYm90aCBJRSA8PSAxMCBhcyB0aGV5IHRocm93IGFuIGVycm9yXG4gICAgICAgIC8vIFwiTWVtYmVyIG5vdCBmb3VuZFwiIGluIHN0cmljdCBtb2RlLCBhbmQgaW4gRmlyZWZveCB3aGljaCBkb2VzIG5vdFxuICAgICAgICAvLyBzdXBwb3J0IHdpbmRvdy5ldmVudC5cblxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdy5ldmVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93Lmhhc093blByb3BlcnR5KCdldmVudCcpKSB7XG4gICAgICAgICAgd2luZG93LmV2ZW50ID0gd2luZG93RXZlbnQ7XG4gICAgICAgIH1cbiAgICAgIH0gLy8gQ3JlYXRlIGFuIGV2ZW50IGhhbmRsZXIgZm9yIG91ciBmYWtlIGV2ZW50LiBXZSB3aWxsIHN5bmNocm9ub3VzbHlcbiAgICAgIC8vIGRpc3BhdGNoIG91ciBmYWtlIGV2ZW50IHVzaW5nIGBkaXNwYXRjaEV2ZW50YC4gSW5zaWRlIHRoZSBoYW5kbGVyLCB3ZVxuICAgICAgLy8gY2FsbCB0aGUgdXNlci1wcm92aWRlZCBjYWxsYmFjay5cblxuXG4gICAgICB2YXIgZnVuY0FyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDMpO1xuXG4gICAgICBmdW5jdGlvbiBjYWxsQ2FsbGJhY2soKSB7XG4gICAgICAgIGRpZENhbGwgPSB0cnVlO1xuICAgICAgICByZXN0b3JlQWZ0ZXJEaXNwYXRjaCgpO1xuICAgICAgICBmdW5jLmFwcGx5KGNvbnRleHQsIGZ1bmNBcmdzKTtcbiAgICAgICAgZGlkRXJyb3IgPSBmYWxzZTtcbiAgICAgIH0gLy8gQ3JlYXRlIGEgZ2xvYmFsIGVycm9yIGV2ZW50IGhhbmRsZXIuIFdlIHVzZSB0aGlzIHRvIGNhcHR1cmUgdGhlIHZhbHVlXG4gICAgICAvLyB0aGF0IHdhcyB0aHJvd24uIEl0J3MgcG9zc2libGUgdGhhdCB0aGlzIGVycm9yIGhhbmRsZXIgd2lsbCBmaXJlIG1vcmVcbiAgICAgIC8vIHRoYW4gb25jZTsgZm9yIGV4YW1wbGUsIGlmIG5vbi1SZWFjdCBjb2RlIGFsc28gY2FsbHMgYGRpc3BhdGNoRXZlbnRgXG4gICAgICAvLyBhbmQgYSBoYW5kbGVyIGZvciB0aGF0IGV2ZW50IHRocm93cy4gV2Ugc2hvdWxkIGJlIHJlc2lsaWVudCB0byBtb3N0IG9mXG4gICAgICAvLyB0aG9zZSBjYXNlcy4gRXZlbiBpZiBvdXIgZXJyb3IgZXZlbnQgaGFuZGxlciBmaXJlcyBtb3JlIHRoYW4gb25jZSwgdGhlXG4gICAgICAvLyBsYXN0IGVycm9yIGV2ZW50IGlzIGFsd2F5cyB1c2VkLiBJZiB0aGUgY2FsbGJhY2sgYWN0dWFsbHkgZG9lcyBlcnJvcixcbiAgICAgIC8vIHdlIGtub3cgdGhhdCB0aGUgbGFzdCBlcnJvciBldmVudCBpcyB0aGUgY29ycmVjdCBvbmUsIGJlY2F1c2UgaXQncyBub3RcbiAgICAgIC8vIHBvc3NpYmxlIGZvciBhbnl0aGluZyBlbHNlIHRvIGhhdmUgaGFwcGVuZWQgaW4gYmV0d2VlbiBvdXIgY2FsbGJhY2tcbiAgICAgIC8vIGVycm9yaW5nIGFuZCB0aGUgY29kZSB0aGF0IGZvbGxvd3MgdGhlIGBkaXNwYXRjaEV2ZW50YCBjYWxsIGJlbG93LiBJZlxuICAgICAgLy8gdGhlIGNhbGxiYWNrIGRvZXNuJ3QgZXJyb3IsIGJ1dCB0aGUgZXJyb3IgZXZlbnQgd2FzIGZpcmVkLCB3ZSBrbm93IHRvXG4gICAgICAvLyBpZ25vcmUgaXQgYmVjYXVzZSBgZGlkRXJyb3JgIHdpbGwgYmUgZmFsc2UsIGFzIGRlc2NyaWJlZCBhYm92ZS5cblxuXG4gICAgICB2YXIgZXJyb3I7IC8vIFVzZSB0aGlzIHRvIHRyYWNrIHdoZXRoZXIgdGhlIGVycm9yIGV2ZW50IGlzIGV2ZXIgY2FsbGVkLlxuXG4gICAgICB2YXIgZGlkU2V0RXJyb3IgPSBmYWxzZTtcbiAgICAgIHZhciBpc0Nyb3NzT3JpZ2luRXJyb3IgPSBmYWxzZTtcblxuICAgICAgZnVuY3Rpb24gaGFuZGxlV2luZG93RXJyb3IoZXZlbnQpIHtcbiAgICAgICAgZXJyb3IgPSBldmVudC5lcnJvcjtcbiAgICAgICAgZGlkU2V0RXJyb3IgPSB0cnVlO1xuXG4gICAgICAgIGlmIChlcnJvciA9PT0gbnVsbCAmJiBldmVudC5jb2xubyA9PT0gMCAmJiBldmVudC5saW5lbm8gPT09IDApIHtcbiAgICAgICAgICBpc0Nyb3NzT3JpZ2luRXJyb3IgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgICAgICAvLyBTb21lIG90aGVyIGVycm9yIGhhbmRsZXIgaGFzIHByZXZlbnRlZCBkZWZhdWx0LlxuICAgICAgICAgIC8vIEJyb3dzZXJzIHNpbGVuY2UgdGhlIGVycm9yIHJlcG9ydCBpZiB0aGlzIGhhcHBlbnMuXG4gICAgICAgICAgLy8gV2UnbGwgcmVtZW1iZXIgdGhpcyB0byBsYXRlciBkZWNpZGUgd2hldGhlciB0byBsb2cgaXQgb3Igbm90LlxuICAgICAgICAgIGlmIChlcnJvciAhPSBudWxsICYmIHR5cGVvZiBlcnJvciA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGVycm9yLl9zdXBwcmVzc0xvZ2dpbmcgPSB0cnVlO1xuICAgICAgICAgICAgfSBjYXRjaCAoaW5uZXIpIHsvLyBJZ25vcmUuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IC8vIENyZWF0ZSBhIGZha2UgZXZlbnQgdHlwZS5cblxuXG4gICAgICB2YXIgZXZ0VHlwZSA9IFwicmVhY3QtXCIgKyAobmFtZSA/IG5hbWUgOiAnaW52b2tlZ3VhcmRlZGNhbGxiYWNrJyk7IC8vIEF0dGFjaCBvdXIgZXZlbnQgaGFuZGxlcnNcblxuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgaGFuZGxlV2luZG93RXJyb3IpO1xuICAgICAgZmFrZU5vZGUuYWRkRXZlbnRMaXN0ZW5lcihldnRUeXBlLCBjYWxsQ2FsbGJhY2ssIGZhbHNlKTsgLy8gU3luY2hyb25vdXNseSBkaXNwYXRjaCBvdXIgZmFrZSBldmVudC4gSWYgdGhlIHVzZXItcHJvdmlkZWQgZnVuY3Rpb25cbiAgICAgIC8vIGVycm9ycywgaXQgd2lsbCB0cmlnZ2VyIG91ciBnbG9iYWwgZXJyb3IgaGFuZGxlci5cblxuICAgICAgZXZ0LmluaXRFdmVudChldnRUeXBlLCBmYWxzZSwgZmFsc2UpO1xuICAgICAgZmFrZU5vZGUuZGlzcGF0Y2hFdmVudChldnQpO1xuXG4gICAgICBpZiAod2luZG93RXZlbnREZXNjcmlwdG9yKSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3csICdldmVudCcsIHdpbmRvd0V2ZW50RGVzY3JpcHRvcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChkaWRDYWxsICYmIGRpZEVycm9yKSB7XG4gICAgICAgIGlmICghZGlkU2V0RXJyb3IpIHtcbiAgICAgICAgICAvLyBUaGUgY2FsbGJhY2sgZXJyb3JlZCwgYnV0IHRoZSBlcnJvciBldmVudCBuZXZlciBmaXJlZC5cbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2Rlc1xuICAgICAgICAgIGVycm9yID0gbmV3IEVycm9yKCdBbiBlcnJvciB3YXMgdGhyb3duIGluc2lkZSBvbmUgb2YgeW91ciBjb21wb25lbnRzLCBidXQgUmVhY3QgJyArIFwiZG9lc24ndCBrbm93IHdoYXQgaXQgd2FzLiBUaGlzIGlzIGxpa2VseSBkdWUgdG8gYnJvd3NlciBcIiArICdmbGFraW5lc3MuIFJlYWN0IGRvZXMgaXRzIGJlc3QgdG8gcHJlc2VydmUgdGhlIFwiUGF1c2Ugb24gJyArICdleGNlcHRpb25zXCIgYmVoYXZpb3Igb2YgdGhlIERldlRvb2xzLCB3aGljaCByZXF1aXJlcyBzb21lICcgKyBcIkRFVi1tb2RlIG9ubHkgdHJpY2tzLiBJdCdzIHBvc3NpYmxlIHRoYXQgdGhlc2UgZG9uJ3Qgd29yayBpbiBcIiArICd5b3VyIGJyb3dzZXIuIFRyeSB0cmlnZ2VyaW5nIHRoZSBlcnJvciBpbiBwcm9kdWN0aW9uIG1vZGUsICcgKyAnb3Igc3dpdGNoaW5nIHRvIGEgbW9kZXJuIGJyb3dzZXIuIElmIHlvdSBzdXNwZWN0IHRoYXQgdGhpcyBpcyAnICsgJ2FjdHVhbGx5IGFuIGlzc3VlIHdpdGggUmVhY3QsIHBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzQ3Jvc3NPcmlnaW5FcnJvcikge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9wcm9kLWVycm9yLWNvZGVzXG4gICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoXCJBIGNyb3NzLW9yaWdpbiBlcnJvciB3YXMgdGhyb3duLiBSZWFjdCBkb2Vzbid0IGhhdmUgYWNjZXNzIHRvIFwiICsgJ3RoZSBhY3R1YWwgZXJyb3Igb2JqZWN0IGluIGRldmVsb3BtZW50LiAnICsgJ1NlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvY3Jvc3NvcmlnaW4tZXJyb3IgZm9yIG1vcmUgaW5mb3JtYXRpb24uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm9uRXJyb3IoZXJyb3IpO1xuICAgICAgfSAvLyBSZW1vdmUgb3VyIGV2ZW50IGxpc3RlbmVyc1xuXG5cbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdlcnJvcicsIGhhbmRsZVdpbmRvd0Vycm9yKTtcblxuICAgICAgaWYgKCFkaWRDYWxsKSB7XG4gICAgICAgIC8vIFNvbWV0aGluZyB3ZW50IHJlYWxseSB3cm9uZywgYW5kIG91ciBldmVudCB3YXMgbm90IGRpc3BhdGNoZWQuXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTY3MzRcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xNjU4NVxuICAgICAgICAvLyBGYWxsIGJhY2sgdG8gdGhlIHByb2R1Y3Rpb24gaW1wbGVtZW50YXRpb24uXG4gICAgICAgIHJlc3RvcmVBZnRlckRpc3BhdGNoKCk7XG4gICAgICAgIHJldHVybiBpbnZva2VHdWFyZGVkQ2FsbGJhY2tQcm9kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxufVxuXG52YXIgaW52b2tlR3VhcmRlZENhbGxiYWNrSW1wbCQxID0gaW52b2tlR3VhcmRlZENhbGxiYWNrSW1wbDtcblxudmFyIGhhc0Vycm9yID0gZmFsc2U7XG52YXIgY2F1Z2h0RXJyb3IgPSBudWxsOyAvLyBVc2VkIGJ5IGV2ZW50IHN5c3RlbSB0byBjYXB0dXJlL3JldGhyb3cgdGhlIGZpcnN0IGVycm9yLlxuXG52YXIgaGFzUmV0aHJvd0Vycm9yID0gZmFsc2U7XG52YXIgcmV0aHJvd0Vycm9yID0gbnVsbDtcbnZhciByZXBvcnRlciA9IHtcbiAgb25FcnJvcjogZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgaGFzRXJyb3IgPSB0cnVlO1xuICAgIGNhdWdodEVycm9yID0gZXJyb3I7XG4gIH1cbn07XG4vKipcbiAqIENhbGwgYSBmdW5jdGlvbiB3aGlsZSBndWFyZGluZyBhZ2FpbnN0IGVycm9ycyB0aGF0IGhhcHBlbnMgd2l0aGluIGl0LlxuICogUmV0dXJucyBhbiBlcnJvciBpZiBpdCB0aHJvd3MsIG90aGVyd2lzZSBudWxsLlxuICpcbiAqIEluIHByb2R1Y3Rpb24sIHRoaXMgaXMgaW1wbGVtZW50ZWQgdXNpbmcgYSB0cnktY2F0Y2guIFRoZSByZWFzb24gd2UgZG9uJ3RcbiAqIHVzZSBhIHRyeS1jYXRjaCBkaXJlY3RseSBpcyBzbyB0aGF0IHdlIGNhbiBzd2FwIG91dCBhIGRpZmZlcmVudFxuICogaW1wbGVtZW50YXRpb24gaW4gREVWIG1vZGUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgdGhlIGd1YXJkIHRvIHVzZSBmb3IgbG9nZ2luZyBvciBkZWJ1Z2dpbmdcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGludm9rZVxuICogQHBhcmFtIHsqfSBjb250ZXh0IFRoZSBjb250ZXh0IHRvIHVzZSB3aGVuIGNhbGxpbmcgdGhlIGZ1bmN0aW9uXG4gKiBAcGFyYW0gey4uLip9IGFyZ3MgQXJndW1lbnRzIGZvciBmdW5jdGlvblxuICovXG5cbmZ1bmN0aW9uIGludm9rZUd1YXJkZWRDYWxsYmFjayhuYW1lLCBmdW5jLCBjb250ZXh0LCBhLCBiLCBjLCBkLCBlLCBmKSB7XG4gIGhhc0Vycm9yID0gZmFsc2U7XG4gIGNhdWdodEVycm9yID0gbnVsbDtcbiAgaW52b2tlR3VhcmRlZENhbGxiYWNrSW1wbCQxLmFwcGx5KHJlcG9ydGVyLCBhcmd1bWVudHMpO1xufVxuLyoqXG4gKiBTYW1lIGFzIGludm9rZUd1YXJkZWRDYWxsYmFjaywgYnV0IGluc3RlYWQgb2YgcmV0dXJuaW5nIGFuIGVycm9yLCBpdCBzdG9yZXNcbiAqIGl0IGluIGEgZ2xvYmFsIHNvIGl0IGNhbiBiZSByZXRocm93biBieSBgcmV0aHJvd0NhdWdodEVycm9yYCBsYXRlci5cbiAqIFRPRE86IFNlZSBpZiBjYXVnaHRFcnJvciBhbmQgcmV0aHJvd0Vycm9yIGNhbiBiZSB1bmlmaWVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG9mIHRoZSBndWFyZCB0byB1c2UgZm9yIGxvZ2dpbmcgb3IgZGVidWdnaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBpbnZva2VcbiAqIEBwYXJhbSB7Kn0gY29udGV4dCBUaGUgY29udGV4dCB0byB1c2Ugd2hlbiBjYWxsaW5nIHRoZSBmdW5jdGlvblxuICogQHBhcmFtIHsuLi4qfSBhcmdzIEFyZ3VtZW50cyBmb3IgZnVuY3Rpb25cbiAqL1xuXG5mdW5jdGlvbiBpbnZva2VHdWFyZGVkQ2FsbGJhY2tBbmRDYXRjaEZpcnN0RXJyb3IobmFtZSwgZnVuYywgY29udGV4dCwgYSwgYiwgYywgZCwgZSwgZikge1xuICBpbnZva2VHdWFyZGVkQ2FsbGJhY2suYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICBpZiAoaGFzRXJyb3IpIHtcbiAgICB2YXIgZXJyb3IgPSBjbGVhckNhdWdodEVycm9yKCk7XG5cbiAgICBpZiAoIWhhc1JldGhyb3dFcnJvcikge1xuICAgICAgaGFzUmV0aHJvd0Vycm9yID0gdHJ1ZTtcbiAgICAgIHJldGhyb3dFcnJvciA9IGVycm9yO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBEdXJpbmcgZXhlY3V0aW9uIG9mIGd1YXJkZWQgZnVuY3Rpb25zIHdlIHdpbGwgY2FwdHVyZSB0aGUgZmlyc3QgZXJyb3Igd2hpY2hcbiAqIHdlIHdpbGwgcmV0aHJvdyB0byBiZSBoYW5kbGVkIGJ5IHRoZSB0b3AgbGV2ZWwgZXJyb3IgaGFuZGxlci5cbiAqL1xuXG5mdW5jdGlvbiByZXRocm93Q2F1Z2h0RXJyb3IoKSB7XG4gIGlmIChoYXNSZXRocm93RXJyb3IpIHtcbiAgICB2YXIgZXJyb3IgPSByZXRocm93RXJyb3I7XG4gICAgaGFzUmV0aHJvd0Vycm9yID0gZmFsc2U7XG4gICAgcmV0aHJvd0Vycm9yID0gbnVsbDtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuZnVuY3Rpb24gaGFzQ2F1Z2h0RXJyb3IoKSB7XG4gIHJldHVybiBoYXNFcnJvcjtcbn1cbmZ1bmN0aW9uIGNsZWFyQ2F1Z2h0RXJyb3IoKSB7XG4gIGlmIChoYXNFcnJvcikge1xuICAgIHZhciBlcnJvciA9IGNhdWdodEVycm9yO1xuICAgIGhhc0Vycm9yID0gZmFsc2U7XG4gICAgY2F1Z2h0RXJyb3IgPSBudWxsO1xuICAgIHJldHVybiBlcnJvcjtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyQ2F1Z2h0RXJyb3Igd2FzIGNhbGxlZCBidXQgbm8gZXJyb3Igd2FzIGNhcHR1cmVkLiBUaGlzIGVycm9yICcgKyAnaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBgUmVhY3RJbnN0YW5jZU1hcGAgbWFpbnRhaW5zIGEgbWFwcGluZyBmcm9tIGEgcHVibGljIGZhY2luZyBzdGF0ZWZ1bFxuICogaW5zdGFuY2UgKGtleSkgYW5kIHRoZSBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiAodmFsdWUpLiBUaGlzIGFsbG93cyBwdWJsaWNcbiAqIG1ldGhvZHMgdG8gYWNjZXB0IHRoZSB1c2VyIGZhY2luZyBpbnN0YW5jZSBhcyBhbiBhcmd1bWVudCBhbmQgbWFwIHRoZW0gYmFja1xuICogdG8gaW50ZXJuYWwgbWV0aG9kcy5cbiAqXG4gKiBOb3RlIHRoYXQgdGhpcyBtb2R1bGUgaXMgY3VycmVudGx5IHNoYXJlZCBhbmQgYXNzdW1lZCB0byBiZSBzdGF0ZWxlc3MuXG4gKiBJZiB0aGlzIGJlY29tZXMgYW4gYWN0dWFsIE1hcCwgdGhhdCB3aWxsIGJyZWFrLlxuICovXG5mdW5jdGlvbiBnZXQoa2V5KSB7XG4gIHJldHVybiBrZXkuX3JlYWN0SW50ZXJuYWxzO1xufVxuZnVuY3Rpb24gaGFzKGtleSkge1xuICByZXR1cm4ga2V5Ll9yZWFjdEludGVybmFscyAhPT0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gc2V0KGtleSwgdmFsdWUpIHtcbiAga2V5Ll9yZWFjdEludGVybmFscyA9IHZhbHVlO1xufVxuXG4vLyBEb24ndCBjaGFuZ2UgdGhlc2UgdHdvIHZhbHVlcy4gVGhleSdyZSB1c2VkIGJ5IFJlYWN0IERldiBUb29scy5cbnZhciBOb0ZsYWdzID1cbi8qICAgICAgICAgICAgICAgICAgICAgICovXG4wO1xudmFyIFBlcmZvcm1lZFdvcmsgPVxuLyogICAgICAgICAgICAgICAgKi9cbjE7IC8vIFlvdSBjYW4gY2hhbmdlIHRoZSByZXN0IChhbmQgYWRkIG1vcmUpLlxuXG52YXIgUGxhY2VtZW50ID1cbi8qICAgICAgICAgICAgICAgICAgICAqL1xuMjtcbnZhciBVcGRhdGUgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICovXG40O1xudmFyIENoaWxkRGVsZXRpb24gPVxuLyogICAgICAgICAgICAgICAgKi9cbjE2O1xudmFyIENvbnRlbnRSZXNldCA9XG4vKiAgICAgICAgICAgICAgICAgKi9cbjMyO1xudmFyIENhbGxiYWNrID1cbi8qICAgICAgICAgICAgICAgICAgICAgKi9cbjY0O1xudmFyIERpZENhcHR1cmUgPVxuLyogICAgICAgICAgICAgICAgICAgKi9cbjEyODtcbnZhciBGb3JjZUNsaWVudFJlbmRlciA9XG4vKiAgICAgICAgICAgICovXG4yNTY7XG52YXIgUmVmID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuNTEyO1xudmFyIFNuYXBzaG90ID1cbi8qICAgICAgICAgICAgICAgICAgICAgKi9cbjEwMjQ7XG52YXIgUGFzc2l2ZSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAqL1xuMjA0ODtcbnZhciBIeWRyYXRpbmcgPVxuLyogICAgICAgICAgICAgICAgICAgICovXG40MDk2O1xudmFyIFZpc2liaWxpdHkgPVxuLyogICAgICAgICAgICAgICAgICAgKi9cbjgxOTI7XG52YXIgU3RvcmVDb25zaXN0ZW5jeSA9XG4vKiAgICAgICAgICAgICAqL1xuMTYzODQ7XG52YXIgTGlmZWN5Y2xlRWZmZWN0TWFzayA9IFBhc3NpdmUgfCBVcGRhdGUgfCBDYWxsYmFjayB8IFJlZiB8IFNuYXBzaG90IHwgU3RvcmVDb25zaXN0ZW5jeTsgLy8gVW5pb24gb2YgYWxsIGNvbW1pdCBmbGFncyAoZmxhZ3Mgd2l0aCB0aGUgbGlmZXRpbWUgb2YgYSBwYXJ0aWN1bGFyIGNvbW1pdClcblxudmFyIEhvc3RFZmZlY3RNYXNrID1cbi8qICAgICAgICAgICAgICAgKi9cbjMyNzY3OyAvLyBUaGVzZSBhcmUgbm90IHJlYWxseSBzaWRlIGVmZmVjdHMsIGJ1dCB3ZSBzdGlsbCByZXVzZSB0aGlzIGZpZWxkLlxuXG52YXIgSW5jb21wbGV0ZSA9XG4vKiAgICAgICAgICAgICAgICAgICAqL1xuMzI3Njg7XG52YXIgU2hvdWxkQ2FwdHVyZSA9XG4vKiAgICAgICAgICAgICAgICAqL1xuNjU1MzY7XG52YXIgRm9yY2VVcGRhdGVGb3JMZWdhY3lTdXNwZW5zZSA9XG4vKiAqL1xuMTMxMDcyO1xudmFyIEZvcmtlZCA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgKi9cbjEwNDg1NzY7IC8vIFN0YXRpYyB0YWdzIGRlc2NyaWJlIGFzcGVjdHMgb2YgYSBmaWJlciB0aGF0IGFyZSBub3Qgc3BlY2lmaWMgdG8gYSByZW5kZXIsXG4vLyBlLmcuIGEgZmliZXIgdXNlcyBhIHBhc3NpdmUgZWZmZWN0IChldmVuIGlmIHRoZXJlIGFyZSBubyB1cGRhdGVzIG9uIHRoaXMgcGFydGljdWxhciByZW5kZXIpLlxuLy8gVGhpcyBlbmFibGVzIHVzIHRvIGRlZmVyIG1vcmUgd29yayBpbiB0aGUgdW5tb3VudCBjYXNlLFxuLy8gc2luY2Ugd2UgY2FuIGRlZmVyIHRyYXZlcnNpbmcgdGhlIHRyZWUgZHVyaW5nIGxheW91dCB0byBsb29rIGZvciBQYXNzaXZlIGVmZmVjdHMsXG4vLyBhbmQgaW5zdGVhZCByZWx5IG9uIHRoZSBzdGF0aWMgZmxhZyBhcyBhIHNpZ25hbCB0aGF0IHRoZXJlIG1heSBiZSBjbGVhbnVwIHdvcmsuXG5cbnZhciBSZWZTdGF0aWMgPVxuLyogICAgICAgICAgICAgICAgICAgICovXG4yMDk3MTUyO1xudmFyIExheW91dFN0YXRpYyA9XG4vKiAgICAgICAgICAgICAgICAgKi9cbjQxOTQzMDQ7XG52YXIgUGFzc2l2ZVN0YXRpYyA9XG4vKiAgICAgICAgICAgICAgICAqL1xuODM4ODYwODsgLy8gVGhlc2UgZmxhZ3MgYWxsb3cgdXMgdG8gdHJhdmVyc2UgdG8gZmliZXJzIHRoYXQgaGF2ZSBlZmZlY3RzIG9uIG1vdW50XG4vLyB3aXRob3V0IHRyYXZlcnNpbmcgdGhlIGVudGlyZSB0cmVlIGFmdGVyIGV2ZXJ5IGNvbW1pdCBmb3Jcbi8vIGRvdWJsZSBpbnZva2luZ1xuXG52YXIgTW91bnRMYXlvdXREZXYgPVxuLyogICAgICAgICAgICAgICAqL1xuMTY3NzcyMTY7XG52YXIgTW91bnRQYXNzaXZlRGV2ID1cbi8qICAgICAgICAgICAgICAqL1xuMzM1NTQ0MzI7IC8vIEdyb3VwcyBvZiBmbGFncyB0aGF0IGFyZSB1c2VkIGluIHRoZSBjb21taXQgcGhhc2UgdG8gc2tpcCBvdmVyIHRyZWVzIHRoYXRcbi8vIGRvbid0IGNvbnRhaW4gZWZmZWN0cywgYnkgY2hlY2tpbmcgc3VidHJlZUZsYWdzLlxuXG52YXIgQmVmb3JlTXV0YXRpb25NYXNrID0gLy8gVE9ETzogUmVtb3ZlIFVwZGF0ZSBmbGFnIGZyb20gYmVmb3JlIG11dGF0aW9uIHBoYXNlIGJ5IHJlLWxhbmRpbmcgVmlzaWJpbGl0eVxuLy8gZmxhZyBsb2dpYyAoc2VlICMyMDA0MylcblVwZGF0ZSB8IFNuYXBzaG90IHwgKCAwKTtcbnZhciBNdXRhdGlvbk1hc2sgPSBQbGFjZW1lbnQgfCBVcGRhdGUgfCBDaGlsZERlbGV0aW9uIHwgQ29udGVudFJlc2V0IHwgUmVmIHwgSHlkcmF0aW5nIHwgVmlzaWJpbGl0eTtcbnZhciBMYXlvdXRNYXNrID0gVXBkYXRlIHwgQ2FsbGJhY2sgfCBSZWYgfCBWaXNpYmlsaXR5OyAvLyBUT0RPOiBTcGxpdCBpbnRvIFBhc3NpdmVNb3VudE1hc2sgYW5kIFBhc3NpdmVVbm1vdW50TWFza1xuXG52YXIgUGFzc2l2ZU1hc2sgPSBQYXNzaXZlIHwgQ2hpbGREZWxldGlvbjsgLy8gVW5pb24gb2YgdGFncyB0aGF0IGRvbid0IGdldCByZXNldCBvbiBjbG9uZXMuXG4vLyBUaGlzIGFsbG93cyBjZXJ0YWluIGNvbmNlcHRzIHRvIHBlcnNpc3Qgd2l0aG91dCByZWNhbGN1bGF0aW5nIHRoZW0sXG4vLyBlLmcuIHdoZXRoZXIgYSBzdWJ0cmVlIGNvbnRhaW5zIHBhc3NpdmUgZWZmZWN0cyBvciBwb3J0YWxzLlxuXG52YXIgU3RhdGljTWFzayA9IExheW91dFN0YXRpYyB8IFBhc3NpdmVTdGF0aWMgfCBSZWZTdGF0aWM7XG5cbnZhciBSZWFjdEN1cnJlbnRPd25lciA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudE93bmVyO1xuZnVuY3Rpb24gZ2V0TmVhcmVzdE1vdW50ZWRGaWJlcihmaWJlcikge1xuICB2YXIgbm9kZSA9IGZpYmVyO1xuICB2YXIgbmVhcmVzdE1vdW50ZWQgPSBmaWJlcjtcblxuICBpZiAoIWZpYmVyLmFsdGVybmF0ZSkge1xuICAgIC8vIElmIHRoZXJlIGlzIG5vIGFsdGVybmF0ZSwgdGhpcyBtaWdodCBiZSBhIG5ldyB0cmVlIHRoYXQgaXNuJ3QgaW5zZXJ0ZWRcbiAgICAvLyB5ZXQuIElmIGl0IGlzLCB0aGVuIGl0IHdpbGwgaGF2ZSBhIHBlbmRpbmcgaW5zZXJ0aW9uIGVmZmVjdCBvbiBpdC5cbiAgICB2YXIgbmV4dE5vZGUgPSBub2RlO1xuXG4gICAgZG8ge1xuICAgICAgbm9kZSA9IG5leHROb2RlO1xuXG4gICAgICBpZiAoKG5vZGUuZmxhZ3MgJiAoUGxhY2VtZW50IHwgSHlkcmF0aW5nKSkgIT09IE5vRmxhZ3MpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBhbiBpbnNlcnRpb24gb3IgaW4tcHJvZ3Jlc3MgaHlkcmF0aW9uLiBUaGUgbmVhcmVzdCBwb3NzaWJsZVxuICAgICAgICAvLyBtb3VudGVkIGZpYmVyIGlzIHRoZSBwYXJlbnQgYnV0IHdlIG5lZWQgdG8gY29udGludWUgdG8gZmlndXJlIG91dFxuICAgICAgICAvLyBpZiB0aGF0IG9uZSBpcyBzdGlsbCBtb3VudGVkLlxuICAgICAgICBuZWFyZXN0TW91bnRlZCA9IG5vZGUucmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBuZXh0Tm9kZSA9IG5vZGUucmV0dXJuO1xuICAgIH0gd2hpbGUgKG5leHROb2RlKTtcbiAgfSBlbHNlIHtcbiAgICB3aGlsZSAobm9kZS5yZXR1cm4pIHtcbiAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICB9XG4gIH1cblxuICBpZiAobm9kZS50YWcgPT09IEhvc3RSb290KSB7XG4gICAgLy8gVE9ETzogQ2hlY2sgaWYgdGhpcyB3YXMgYSBuZXN0ZWQgSG9zdFJvb3Qgd2hlbiB1c2VkIHdpdGhcbiAgICAvLyByZW5kZXJDb250YWluZXJJbnRvU3VidHJlZS5cbiAgICByZXR1cm4gbmVhcmVzdE1vdW50ZWQ7XG4gIH0gLy8gSWYgd2UgZGlkbid0IGhpdCB0aGUgcm9vdCwgdGhhdCBtZWFucyB0aGF0IHdlJ3JlIGluIGFuIGRpc2Nvbm5lY3RlZCB0cmVlXG4gIC8vIHRoYXQgaGFzIGJlZW4gdW5tb3VudGVkLlxuXG5cbiAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBnZXRTdXNwZW5zZUluc3RhbmNlRnJvbUZpYmVyKGZpYmVyKSB7XG4gIGlmIChmaWJlci50YWcgPT09IFN1c3BlbnNlQ29tcG9uZW50KSB7XG4gICAgdmFyIHN1c3BlbnNlU3RhdGUgPSBmaWJlci5tZW1vaXplZFN0YXRlO1xuXG4gICAgaWYgKHN1c3BlbnNlU3RhdGUgPT09IG51bGwpIHtcbiAgICAgIHZhciBjdXJyZW50ID0gZmliZXIuYWx0ZXJuYXRlO1xuXG4gICAgICBpZiAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgICBzdXNwZW5zZVN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzdXNwZW5zZVN0YXRlICE9PSBudWxsKSB7XG4gICAgICByZXR1cm4gc3VzcGVuc2VTdGF0ZS5kZWh5ZHJhdGVkO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gZ2V0Q29udGFpbmVyRnJvbUZpYmVyKGZpYmVyKSB7XG4gIHJldHVybiBmaWJlci50YWcgPT09IEhvc3RSb290ID8gZmliZXIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm8gOiBudWxsO1xufVxuZnVuY3Rpb24gaXNGaWJlck1vdW50ZWQoZmliZXIpIHtcbiAgcmV0dXJuIGdldE5lYXJlc3RNb3VudGVkRmliZXIoZmliZXIpID09PSBmaWJlcjtcbn1cbmZ1bmN0aW9uIGlzTW91bnRlZChjb21wb25lbnQpIHtcbiAge1xuICAgIHZhciBvd25lciA9IFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQ7XG5cbiAgICBpZiAob3duZXIgIT09IG51bGwgJiYgb3duZXIudGFnID09PSBDbGFzc0NvbXBvbmVudCkge1xuICAgICAgdmFyIG93bmVyRmliZXIgPSBvd25lcjtcbiAgICAgIHZhciBpbnN0YW5jZSA9IG93bmVyRmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICBpZiAoIWluc3RhbmNlLl93YXJuZWRBYm91dFJlZnNJblJlbmRlcikge1xuICAgICAgICBlcnJvcignJXMgaXMgYWNjZXNzaW5nIGlzTW91bnRlZCBpbnNpZGUgaXRzIHJlbmRlcigpIGZ1bmN0aW9uLiAnICsgJ3JlbmRlcigpIHNob3VsZCBiZSBhIHB1cmUgZnVuY3Rpb24gb2YgcHJvcHMgYW5kIHN0YXRlLiBJdCBzaG91bGQgJyArICduZXZlciBhY2Nlc3Mgc29tZXRoaW5nIHRoYXQgcmVxdWlyZXMgc3RhbGUgZGF0YSBmcm9tIHRoZSBwcmV2aW91cyAnICsgJ3JlbmRlciwgc3VjaCBhcyByZWZzLiBNb3ZlIHRoaXMgbG9naWMgdG8gY29tcG9uZW50RGlkTW91bnQgYW5kICcgKyAnY29tcG9uZW50RGlkVXBkYXRlIGluc3RlYWQuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihvd25lckZpYmVyKSB8fCAnQSBjb21wb25lbnQnKTtcbiAgICAgIH1cblxuICAgICAgaW5zdGFuY2UuX3dhcm5lZEFib3V0UmVmc0luUmVuZGVyID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICB2YXIgZmliZXIgPSBnZXQoY29tcG9uZW50KTtcblxuICBpZiAoIWZpYmVyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIGdldE5lYXJlc3RNb3VudGVkRmliZXIoZmliZXIpID09PSBmaWJlcjtcbn1cblxuZnVuY3Rpb24gYXNzZXJ0SXNNb3VudGVkKGZpYmVyKSB7XG4gIGlmIChnZXROZWFyZXN0TW91bnRlZEZpYmVyKGZpYmVyKSAhPT0gZmliZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIG5vZGUgb24gYW4gdW5tb3VudGVkIGNvbXBvbmVudC4nKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5kQ3VycmVudEZpYmVyVXNpbmdTbG93UGF0aChmaWJlcikge1xuICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuXG4gIGlmICghYWx0ZXJuYXRlKSB7XG4gICAgLy8gSWYgdGhlcmUgaXMgbm8gYWx0ZXJuYXRlLCB0aGVuIHdlIG9ubHkgbmVlZCB0byBjaGVjayBpZiBpdCBpcyBtb3VudGVkLlxuICAgIHZhciBuZWFyZXN0TW91bnRlZCA9IGdldE5lYXJlc3RNb3VudGVkRmliZXIoZmliZXIpO1xuXG4gICAgaWYgKG5lYXJlc3RNb3VudGVkID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIG5vZGUgb24gYW4gdW5tb3VudGVkIGNvbXBvbmVudC4nKTtcbiAgICB9XG5cbiAgICBpZiAobmVhcmVzdE1vdW50ZWQgIT09IGZpYmVyKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gZmliZXI7XG4gIH0gLy8gSWYgd2UgaGF2ZSB0d28gcG9zc2libGUgYnJhbmNoZXMsIHdlJ2xsIHdhbGsgYmFja3dhcmRzIHVwIHRvIHRoZSByb290XG4gIC8vIHRvIHNlZSB3aGF0IHBhdGggdGhlIHJvb3QgcG9pbnRzIHRvLiBPbiB0aGUgd2F5IHdlIG1heSBoaXQgb25lIG9mIHRoZVxuICAvLyBzcGVjaWFsIGNhc2VzIGFuZCB3ZSdsbCBkZWFsIHdpdGggdGhlbS5cblxuXG4gIHZhciBhID0gZmliZXI7XG4gIHZhciBiID0gYWx0ZXJuYXRlO1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgdmFyIHBhcmVudEEgPSBhLnJldHVybjtcblxuICAgIGlmIChwYXJlbnRBID09PSBudWxsKSB7XG4gICAgICAvLyBXZSdyZSBhdCB0aGUgcm9vdC5cbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHZhciBwYXJlbnRCID0gcGFyZW50QS5hbHRlcm5hdGU7XG5cbiAgICBpZiAocGFyZW50QiA9PT0gbnVsbCkge1xuICAgICAgLy8gVGhlcmUgaXMgbm8gYWx0ZXJuYXRlLiBUaGlzIGlzIGFuIHVudXN1YWwgY2FzZS4gQ3VycmVudGx5LCBpdCBvbmx5XG4gICAgICAvLyBoYXBwZW5zIHdoZW4gYSBTdXNwZW5zZSBjb21wb25lbnQgaXMgaGlkZGVuLiBBbiBleHRyYSBmcmFnbWVudCBmaWJlclxuICAgICAgLy8gaXMgaW5zZXJ0ZWQgaW4gYmV0d2VlbiB0aGUgU3VzcGVuc2UgZmliZXIgYW5kIGl0cyBjaGlsZHJlbi4gU2tpcFxuICAgICAgLy8gb3ZlciB0aGlzIGV4dHJhIGZyYWdtZW50IGZpYmVyIGFuZCBwcm9jZWVkIHRvIHRoZSBuZXh0IHBhcmVudC5cbiAgICAgIHZhciBuZXh0UGFyZW50ID0gcGFyZW50QS5yZXR1cm47XG5cbiAgICAgIGlmIChuZXh0UGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgIGEgPSBiID0gbmV4dFBhcmVudDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9IC8vIElmIHRoZXJlJ3Mgbm8gcGFyZW50LCB3ZSdyZSBhdCB0aGUgcm9vdC5cblxuXG4gICAgICBicmVhaztcbiAgICB9IC8vIElmIGJvdGggY29waWVzIG9mIHRoZSBwYXJlbnQgZmliZXIgcG9pbnQgdG8gdGhlIHNhbWUgY2hpbGQsIHdlIGNhblxuICAgIC8vIGFzc3VtZSB0aGF0IHRoZSBjaGlsZCBpcyBjdXJyZW50LiBUaGlzIGhhcHBlbnMgd2hlbiB3ZSBiYWlsb3V0IG9uIGxvd1xuICAgIC8vIHByaW9yaXR5OiB0aGUgYmFpbGVkIG91dCBmaWJlcidzIGNoaWxkIHJldXNlcyB0aGUgY3VycmVudCBjaGlsZC5cblxuXG4gICAgaWYgKHBhcmVudEEuY2hpbGQgPT09IHBhcmVudEIuY2hpbGQpIHtcbiAgICAgIHZhciBjaGlsZCA9IHBhcmVudEEuY2hpbGQ7XG5cbiAgICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgICBpZiAoY2hpbGQgPT09IGEpIHtcbiAgICAgICAgICAvLyBXZSd2ZSBkZXRlcm1pbmVkIHRoYXQgQSBpcyB0aGUgY3VycmVudCBicmFuY2guXG4gICAgICAgICAgYXNzZXJ0SXNNb3VudGVkKHBhcmVudEEpO1xuICAgICAgICAgIHJldHVybiBmaWJlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjaGlsZCA9PT0gYikge1xuICAgICAgICAgIC8vIFdlJ3ZlIGRldGVybWluZWQgdGhhdCBCIGlzIHRoZSBjdXJyZW50IGJyYW5jaC5cbiAgICAgICAgICBhc3NlcnRJc01vdW50ZWQocGFyZW50QSk7XG4gICAgICAgICAgcmV0dXJuIGFsdGVybmF0ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNoaWxkID0gY2hpbGQuc2libGluZztcbiAgICAgIH0gLy8gV2Ugc2hvdWxkIG5ldmVyIGhhdmUgYW4gYWx0ZXJuYXRlIGZvciBhbnkgbW91bnRpbmcgbm9kZS4gU28gdGhlIG9ubHlcbiAgICAgIC8vIHdheSB0aGlzIGNvdWxkIHBvc3NpYmx5IGhhcHBlbiBpcyBpZiB0aGlzIHdhcyB1bm1vdW50ZWQsIGlmIGF0IGFsbC5cblxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIG5vZGUgb24gYW4gdW5tb3VudGVkIGNvbXBvbmVudC4nKTtcbiAgICB9XG5cbiAgICBpZiAoYS5yZXR1cm4gIT09IGIucmV0dXJuKSB7XG4gICAgICAvLyBUaGUgcmV0dXJuIHBvaW50ZXIgb2YgQSBhbmQgdGhlIHJldHVybiBwb2ludGVyIG9mIEIgcG9pbnQgdG8gZGlmZmVyZW50XG4gICAgICAvLyBmaWJlcnMuIFdlIGFzc3VtZSB0aGF0IHJldHVybiBwb2ludGVycyBuZXZlciBjcmlzcy1jcm9zcywgc28gQSBtdXN0XG4gICAgICAvLyBiZWxvbmcgdG8gdGhlIGNoaWxkIHNldCBvZiBBLnJldHVybiwgYW5kIEIgbXVzdCBiZWxvbmcgdG8gdGhlIGNoaWxkXG4gICAgICAvLyBzZXQgb2YgQi5yZXR1cm4uXG4gICAgICBhID0gcGFyZW50QTtcbiAgICAgIGIgPSBwYXJlbnRCO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUaGUgcmV0dXJuIHBvaW50ZXJzIHBvaW50IHRvIHRoZSBzYW1lIGZpYmVyLiBXZSdsbCBoYXZlIHRvIHVzZSB0aGVcbiAgICAgIC8vIGRlZmF1bHQsIHNsb3cgcGF0aDogc2NhbiB0aGUgY2hpbGQgc2V0cyBvZiBlYWNoIHBhcmVudCBhbHRlcm5hdGUgdG8gc2VlXG4gICAgICAvLyB3aGljaCBjaGlsZCBiZWxvbmdzIHRvIHdoaWNoIHNldC5cbiAgICAgIC8vXG4gICAgICAvLyBTZWFyY2ggcGFyZW50IEEncyBjaGlsZCBzZXRcbiAgICAgIHZhciBkaWRGaW5kQ2hpbGQgPSBmYWxzZTtcbiAgICAgIHZhciBfY2hpbGQgPSBwYXJlbnRBLmNoaWxkO1xuXG4gICAgICB3aGlsZSAoX2NoaWxkKSB7XG4gICAgICAgIGlmIChfY2hpbGQgPT09IGEpIHtcbiAgICAgICAgICBkaWRGaW5kQ2hpbGQgPSB0cnVlO1xuICAgICAgICAgIGEgPSBwYXJlbnRBO1xuICAgICAgICAgIGIgPSBwYXJlbnRCO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKF9jaGlsZCA9PT0gYikge1xuICAgICAgICAgIGRpZEZpbmRDaGlsZCA9IHRydWU7XG4gICAgICAgICAgYiA9IHBhcmVudEE7XG4gICAgICAgICAgYSA9IHBhcmVudEI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBfY2hpbGQgPSBfY2hpbGQuc2libGluZztcbiAgICAgIH1cblxuICAgICAgaWYgKCFkaWRGaW5kQ2hpbGQpIHtcbiAgICAgICAgLy8gU2VhcmNoIHBhcmVudCBCJ3MgY2hpbGQgc2V0XG4gICAgICAgIF9jaGlsZCA9IHBhcmVudEIuY2hpbGQ7XG5cbiAgICAgICAgd2hpbGUgKF9jaGlsZCkge1xuICAgICAgICAgIGlmIChfY2hpbGQgPT09IGEpIHtcbiAgICAgICAgICAgIGRpZEZpbmRDaGlsZCA9IHRydWU7XG4gICAgICAgICAgICBhID0gcGFyZW50QjtcbiAgICAgICAgICAgIGIgPSBwYXJlbnRBO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKF9jaGlsZCA9PT0gYikge1xuICAgICAgICAgICAgZGlkRmluZENoaWxkID0gdHJ1ZTtcbiAgICAgICAgICAgIGIgPSBwYXJlbnRCO1xuICAgICAgICAgICAgYSA9IHBhcmVudEE7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBfY2hpbGQgPSBfY2hpbGQuc2libGluZztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghZGlkRmluZENoaWxkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGlsZCB3YXMgbm90IGZvdW5kIGluIGVpdGhlciBwYXJlbnQgc2V0LiBUaGlzIGluZGljYXRlcyBhIGJ1ZyAnICsgJ2luIFJlYWN0IHJlbGF0ZWQgdG8gdGhlIHJldHVybiBwb2ludGVyLiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChhLmFsdGVybmF0ZSAhPT0gYikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmV0dXJuIGZpYmVycyBzaG91bGQgYWx3YXlzIGJlIGVhY2ggb3RoZXJzJyBhbHRlcm5hdGVzLiBcIiArICdUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfSAvLyBJZiB0aGUgcm9vdCBpcyBub3QgYSBob3N0IGNvbnRhaW5lciwgd2UncmUgaW4gYSBkaXNjb25uZWN0ZWQgdHJlZS4gSS5lLlxuICAvLyB1bm1vdW50ZWQuXG5cblxuICBpZiAoYS50YWcgIT09IEhvc3RSb290KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCBub2RlIG9uIGFuIHVubW91bnRlZCBjb21wb25lbnQuJyk7XG4gIH1cblxuICBpZiAoYS5zdGF0ZU5vZGUuY3VycmVudCA9PT0gYSkge1xuICAgIC8vIFdlJ3ZlIGRldGVybWluZWQgdGhhdCBBIGlzIHRoZSBjdXJyZW50IGJyYW5jaC5cbiAgICByZXR1cm4gZmliZXI7XG4gIH0gLy8gT3RoZXJ3aXNlIEIgaGFzIHRvIGJlIGN1cnJlbnQgYnJhbmNoLlxuXG5cbiAgcmV0dXJuIGFsdGVybmF0ZTtcbn1cbmZ1bmN0aW9uIGZpbmRDdXJyZW50SG9zdEZpYmVyKHBhcmVudCkge1xuICB2YXIgY3VycmVudFBhcmVudCA9IGZpbmRDdXJyZW50RmliZXJVc2luZ1Nsb3dQYXRoKHBhcmVudCk7XG4gIHJldHVybiBjdXJyZW50UGFyZW50ICE9PSBudWxsID8gZmluZEN1cnJlbnRIb3N0RmliZXJJbXBsKGN1cnJlbnRQYXJlbnQpIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gZmluZEN1cnJlbnRIb3N0RmliZXJJbXBsKG5vZGUpIHtcbiAgLy8gTmV4dCB3ZSdsbCBkcmlsbCBkb3duIHRoaXMgY29tcG9uZW50IHRvIGZpbmQgdGhlIGZpcnN0IEhvc3RDb21wb25lbnQvVGV4dC5cbiAgaWYgKG5vZGUudGFnID09PSBIb3N0Q29tcG9uZW50IHx8IG5vZGUudGFnID09PSBIb3N0VGV4dCkge1xuICAgIHJldHVybiBub2RlO1xuICB9XG5cbiAgdmFyIGNoaWxkID0gbm9kZS5jaGlsZDtcblxuICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICB2YXIgbWF0Y2ggPSBmaW5kQ3VycmVudEhvc3RGaWJlckltcGwoY2hpbGQpO1xuXG4gICAgaWYgKG1hdGNoICE9PSBudWxsKSB7XG4gICAgICByZXR1cm4gbWF0Y2g7XG4gICAgfVxuXG4gICAgY2hpbGQgPSBjaGlsZC5zaWJsaW5nO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGZpbmRDdXJyZW50SG9zdEZpYmVyV2l0aE5vUG9ydGFscyhwYXJlbnQpIHtcbiAgdmFyIGN1cnJlbnRQYXJlbnQgPSBmaW5kQ3VycmVudEZpYmVyVXNpbmdTbG93UGF0aChwYXJlbnQpO1xuICByZXR1cm4gY3VycmVudFBhcmVudCAhPT0gbnVsbCA/IGZpbmRDdXJyZW50SG9zdEZpYmVyV2l0aE5vUG9ydGFsc0ltcGwoY3VycmVudFBhcmVudCkgOiBudWxsO1xufVxuXG5mdW5jdGlvbiBmaW5kQ3VycmVudEhvc3RGaWJlcldpdGhOb1BvcnRhbHNJbXBsKG5vZGUpIHtcbiAgLy8gTmV4dCB3ZSdsbCBkcmlsbCBkb3duIHRoaXMgY29tcG9uZW50IHRvIGZpbmQgdGhlIGZpcnN0IEhvc3RDb21wb25lbnQvVGV4dC5cbiAgaWYgKG5vZGUudGFnID09PSBIb3N0Q29tcG9uZW50IHx8IG5vZGUudGFnID09PSBIb3N0VGV4dCkge1xuICAgIHJldHVybiBub2RlO1xuICB9XG5cbiAgdmFyIGNoaWxkID0gbm9kZS5jaGlsZDtcblxuICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICBpZiAoY2hpbGQudGFnICE9PSBIb3N0UG9ydGFsKSB7XG4gICAgICB2YXIgbWF0Y2ggPSBmaW5kQ3VycmVudEhvc3RGaWJlcldpdGhOb1BvcnRhbHNJbXBsKGNoaWxkKTtcblxuICAgICAgaWYgKG1hdGNoICE9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBtYXRjaDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjaGlsZCA9IGNoaWxkLnNpYmxpbmc7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuLy8gVGhpcyBtb2R1bGUgb25seSBleGlzdHMgYXMgYW4gRVNNIHdyYXBwZXIgYXJvdW5kIHRoZSBleHRlcm5hbCBDb21tb25KU1xudmFyIHNjaGVkdWxlQ2FsbGJhY2sgPSBTY2hlZHVsZXIudW5zdGFibGVfc2NoZWR1bGVDYWxsYmFjaztcbnZhciBjYW5jZWxDYWxsYmFjayA9IFNjaGVkdWxlci51bnN0YWJsZV9jYW5jZWxDYWxsYmFjaztcbnZhciBzaG91bGRZaWVsZCA9IFNjaGVkdWxlci51bnN0YWJsZV9zaG91bGRZaWVsZDtcbnZhciByZXF1ZXN0UGFpbnQgPSBTY2hlZHVsZXIudW5zdGFibGVfcmVxdWVzdFBhaW50O1xudmFyIG5vdyA9IFNjaGVkdWxlci51bnN0YWJsZV9ub3c7XG52YXIgZ2V0Q3VycmVudFByaW9yaXR5TGV2ZWwgPSBTY2hlZHVsZXIudW5zdGFibGVfZ2V0Q3VycmVudFByaW9yaXR5TGV2ZWw7XG52YXIgSW1tZWRpYXRlUHJpb3JpdHkgPSBTY2hlZHVsZXIudW5zdGFibGVfSW1tZWRpYXRlUHJpb3JpdHk7XG52YXIgVXNlckJsb2NraW5nUHJpb3JpdHkgPSBTY2hlZHVsZXIudW5zdGFibGVfVXNlckJsb2NraW5nUHJpb3JpdHk7XG52YXIgTm9ybWFsUHJpb3JpdHkgPSBTY2hlZHVsZXIudW5zdGFibGVfTm9ybWFsUHJpb3JpdHk7XG52YXIgTG93UHJpb3JpdHkgPSBTY2hlZHVsZXIudW5zdGFibGVfTG93UHJpb3JpdHk7XG52YXIgSWRsZVByaW9yaXR5ID0gU2NoZWR1bGVyLnVuc3RhYmxlX0lkbGVQcmlvcml0eTtcbi8vIHRoaXMgZG9lc24ndCBhY3R1YWxseSBleGlzdCBvbiB0aGUgc2NoZWR1bGVyLCBidXQgaXQgKmRvZXMqXG4vLyBvbiBzY2hlZHVsZXIvdW5zdGFibGVfbW9jaywgd2hpY2ggd2UnbGwgbmVlZCBmb3IgaW50ZXJuYWwgdGVzdGluZ1xudmFyIHVuc3RhYmxlX3lpZWxkVmFsdWUgPSBTY2hlZHVsZXIudW5zdGFibGVfeWllbGRWYWx1ZTtcbnZhciB1bnN0YWJsZV9zZXREaXNhYmxlWWllbGRWYWx1ZSA9IFNjaGVkdWxlci51bnN0YWJsZV9zZXREaXNhYmxlWWllbGRWYWx1ZTtcblxudmFyIHJlbmRlcmVySUQgPSBudWxsO1xudmFyIGluamVjdGVkSG9vayA9IG51bGw7XG52YXIgaW5qZWN0ZWRQcm9maWxpbmdIb29rcyA9IG51bGw7XG52YXIgaGFzTG9nZ2VkRXJyb3IgPSBmYWxzZTtcbnZhciBpc0RldlRvb2xzUHJlc2VudCA9IHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gIT09ICd1bmRlZmluZWQnO1xuZnVuY3Rpb24gaW5qZWN0SW50ZXJuYWxzKGludGVybmFscykge1xuICBpZiAodHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAvLyBObyBEZXZUb29sc1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBob29rID0gX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fO1xuXG4gIGlmIChob29rLmlzRGlzYWJsZWQpIHtcbiAgICAvLyBUaGlzIGlzbid0IGEgcmVhbCBwcm9wZXJ0eSBvbiB0aGUgaG9vaywgYnV0IGl0IGNhbiBiZSBzZXQgdG8gb3B0IG91dFxuICAgIC8vIG9mIERldlRvb2xzIGludGVncmF0aW9uIGFuZCBhc3NvY2lhdGVkIHdhcm5pbmdzIGFuZCBsb2dzLlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMzg3N1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKCFob29rLnN1cHBvcnRzRmliZXIpIHtcbiAgICB7XG4gICAgICBlcnJvcignVGhlIGluc3RhbGxlZCB2ZXJzaW9uIG9mIFJlYWN0IERldlRvb2xzIGlzIHRvbyBvbGQgYW5kIHdpbGwgbm90IHdvcmsgJyArICd3aXRoIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgUmVhY3QuIFBsZWFzZSB1cGRhdGUgUmVhY3QgRGV2VG9vbHMuICcgKyAnaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3JlYWN0LWRldnRvb2xzJyk7XG4gICAgfSAvLyBEZXZUb29scyBleGlzdHMsIGV2ZW4gdGhvdWdoIGl0IGRvZXNuJ3Qgc3VwcG9ydCBGaWJlci5cblxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICB0cnkge1xuICAgIGlmIChlbmFibGVTY2hlZHVsaW5nUHJvZmlsZXIpIHtcbiAgICAgIC8vIENvbmRpdGlvbmFsbHkgaW5qZWN0IHRoZXNlIGhvb2tzIG9ubHkgaWYgVGltZWxpbmUgcHJvZmlsZXIgaXMgc3VwcG9ydGVkIGJ5IHRoaXMgYnVpbGQuXG4gICAgICAvLyBUaGlzIGdpdmVzIERldlRvb2xzIGEgd2F5IHRvIGZlYXR1cmUgZGV0ZWN0IHRoYXQgaXNuJ3QgdGllZCB0byB2ZXJzaW9uIG51bWJlclxuICAgICAgLy8gKHNpbmNlIHByb2ZpbGluZyBhbmQgdGltZWxpbmUgYXJlIGNvbnRyb2xsZWQgYnkgZGlmZmVyZW50IGZlYXR1cmUgZmxhZ3MpLlxuICAgICAgaW50ZXJuYWxzID0gYXNzaWduKHt9LCBpbnRlcm5hbHMsIHtcbiAgICAgICAgZ2V0TGFuZUxhYmVsTWFwOiBnZXRMYW5lTGFiZWxNYXAsXG4gICAgICAgIGluamVjdFByb2ZpbGluZ0hvb2tzOiBpbmplY3RQcm9maWxpbmdIb29rc1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmVuZGVyZXJJRCA9IGhvb2suaW5qZWN0KGludGVybmFscyk7IC8vIFdlIGhhdmUgc3VjY2Vzc2Z1bGx5IGluamVjdGVkLCBzbyBub3cgaXQgaXMgc2FmZSB0byBzZXQgdXAgaG9va3MuXG5cbiAgICBpbmplY3RlZEhvb2sgPSBob29rO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICAvLyBDYXRjaCBhbGwgZXJyb3JzIGJlY2F1c2UgaXQgaXMgdW5zYWZlIHRvIHRocm93IGR1cmluZyBpbml0aWFsaXphdGlvbi5cbiAgICB7XG4gICAgICBlcnJvcignUmVhY3QgaW5zdHJ1bWVudGF0aW9uIGVuY291bnRlcmVkIGFuIGVycm9yOiAlcy4nLCBlcnIpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChob29rLmNoZWNrRENFKSB7XG4gICAgLy8gVGhpcyBpcyB0aGUgcmVhbCBEZXZUb29scy5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICAvLyBUaGlzIGlzIGxpa2VseSBhIGhvb2sgaW5zdGFsbGVkIGJ5IEZhc3QgUmVmcmVzaCBydW50aW1lLlxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuZnVuY3Rpb24gb25TY2hlZHVsZVJvb3Qocm9vdCwgY2hpbGRyZW4pIHtcbiAge1xuICAgIGlmIChpbmplY3RlZEhvb2sgJiYgdHlwZW9mIGluamVjdGVkSG9vay5vblNjaGVkdWxlRmliZXJSb290ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpbmplY3RlZEhvb2sub25TY2hlZHVsZUZpYmVyUm9vdChyZW5kZXJlcklELCByb290LCBjaGlsZHJlbik7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKCAhaGFzTG9nZ2VkRXJyb3IpIHtcbiAgICAgICAgICBoYXNMb2dnZWRFcnJvciA9IHRydWU7XG5cbiAgICAgICAgICBlcnJvcignUmVhY3QgaW5zdHJ1bWVudGF0aW9uIGVuY291bnRlcmVkIGFuIGVycm9yOiAlcycsIGVycik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG9uQ29tbWl0Um9vdChyb290LCBldmVudFByaW9yaXR5KSB7XG4gIGlmIChpbmplY3RlZEhvb2sgJiYgdHlwZW9mIGluamVjdGVkSG9vay5vbkNvbW1pdEZpYmVyUm9vdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRyeSB7XG4gICAgICB2YXIgZGlkRXJyb3IgPSAocm9vdC5jdXJyZW50LmZsYWdzICYgRGlkQ2FwdHVyZSkgPT09IERpZENhcHR1cmU7XG5cbiAgICAgIGlmIChlbmFibGVQcm9maWxlclRpbWVyKSB7XG4gICAgICAgIHZhciBzY2hlZHVsZXJQcmlvcml0eTtcblxuICAgICAgICBzd2l0Y2ggKGV2ZW50UHJpb3JpdHkpIHtcbiAgICAgICAgICBjYXNlIERpc2NyZXRlRXZlbnRQcmlvcml0eTpcbiAgICAgICAgICAgIHNjaGVkdWxlclByaW9yaXR5ID0gSW1tZWRpYXRlUHJpb3JpdHk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgQ29udGludW91c0V2ZW50UHJpb3JpdHk6XG4gICAgICAgICAgICBzY2hlZHVsZXJQcmlvcml0eSA9IFVzZXJCbG9ja2luZ1ByaW9yaXR5O1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIERlZmF1bHRFdmVudFByaW9yaXR5OlxuICAgICAgICAgICAgc2NoZWR1bGVyUHJpb3JpdHkgPSBOb3JtYWxQcmlvcml0eTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBJZGxlRXZlbnRQcmlvcml0eTpcbiAgICAgICAgICAgIHNjaGVkdWxlclByaW9yaXR5ID0gSWRsZVByaW9yaXR5O1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgc2NoZWR1bGVyUHJpb3JpdHkgPSBOb3JtYWxQcmlvcml0eTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaW5qZWN0ZWRIb29rLm9uQ29tbWl0RmliZXJSb290KHJlbmRlcmVySUQsIHJvb3QsIHNjaGVkdWxlclByaW9yaXR5LCBkaWRFcnJvcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbmplY3RlZEhvb2sub25Db21taXRGaWJlclJvb3QocmVuZGVyZXJJRCwgcm9vdCwgdW5kZWZpbmVkLCBkaWRFcnJvcik7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB7XG4gICAgICAgIGlmICghaGFzTG9nZ2VkRXJyb3IpIHtcbiAgICAgICAgICBoYXNMb2dnZWRFcnJvciA9IHRydWU7XG5cbiAgICAgICAgICBlcnJvcignUmVhY3QgaW5zdHJ1bWVudGF0aW9uIGVuY291bnRlcmVkIGFuIGVycm9yOiAlcycsIGVycik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG9uUG9zdENvbW1pdFJvb3Qocm9vdCkge1xuICBpZiAoaW5qZWN0ZWRIb29rICYmIHR5cGVvZiBpbmplY3RlZEhvb2sub25Qb3N0Q29tbWl0RmliZXJSb290ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGluamVjdGVkSG9vay5vblBvc3RDb21taXRGaWJlclJvb3QocmVuZGVyZXJJRCwgcm9vdCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB7XG4gICAgICAgIGlmICghaGFzTG9nZ2VkRXJyb3IpIHtcbiAgICAgICAgICBoYXNMb2dnZWRFcnJvciA9IHRydWU7XG5cbiAgICAgICAgICBlcnJvcignUmVhY3QgaW5zdHJ1bWVudGF0aW9uIGVuY291bnRlcmVkIGFuIGVycm9yOiAlcycsIGVycik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG9uQ29tbWl0VW5tb3VudChmaWJlcikge1xuICBpZiAoaW5qZWN0ZWRIb29rICYmIHR5cGVvZiBpbmplY3RlZEhvb2sub25Db21taXRGaWJlclVubW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0cnkge1xuICAgICAgaW5qZWN0ZWRIb29rLm9uQ29tbWl0RmliZXJVbm1vdW50KHJlbmRlcmVySUQsIGZpYmVyKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHtcbiAgICAgICAgaWYgKCFoYXNMb2dnZWRFcnJvcikge1xuICAgICAgICAgIGhhc0xvZ2dlZEVycm9yID0gdHJ1ZTtcblxuICAgICAgICAgIGVycm9yKCdSZWFjdCBpbnN0cnVtZW50YXRpb24gZW5jb3VudGVyZWQgYW4gZXJyb3I6ICVzJywgZXJyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMobmV3SXNTdHJpY3RNb2RlKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIHVuc3RhYmxlX3lpZWxkVmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIFdlJ3JlIGluIGEgdGVzdCBiZWNhdXNlIFNjaGVkdWxlci51bnN0YWJsZV95aWVsZFZhbHVlIG9ubHkgZXhpc3RzXG4gICAgICAvLyBpbiBTY2hlZHVsZXJNb2NrLiBUbyByZWR1Y2UgdGhlIG5vaXNlIGluIHN0cmljdCBtb2RlIHRlc3RzLFxuICAgICAgLy8gc3VwcHJlc3Mgd2FybmluZ3MgYW5kIGRpc2FibGUgc2NoZWR1bGVyIHlpZWxkaW5nIGR1cmluZyB0aGUgZG91YmxlIHJlbmRlclxuICAgICAgdW5zdGFibGVfc2V0RGlzYWJsZVlpZWxkVmFsdWUobmV3SXNTdHJpY3RNb2RlKTtcbiAgICAgIHNldFN1cHByZXNzV2FybmluZyhuZXdJc1N0cmljdE1vZGUpO1xuICAgIH1cblxuICAgIGlmIChpbmplY3RlZEhvb2sgJiYgdHlwZW9mIGluamVjdGVkSG9vay5zZXRTdHJpY3RNb2RlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpbmplY3RlZEhvb2suc2V0U3RyaWN0TW9kZShyZW5kZXJlcklELCBuZXdJc1N0cmljdE1vZGUpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoIWhhc0xvZ2dlZEVycm9yKSB7XG4gICAgICAgICAgICBoYXNMb2dnZWRFcnJvciA9IHRydWU7XG5cbiAgICAgICAgICAgIGVycm9yKCdSZWFjdCBpbnN0cnVtZW50YXRpb24gZW5jb3VudGVyZWQgYW4gZXJyb3I6ICVzJywgZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn0gLy8gUHJvZmlsZXIgQVBJIGhvb2tzXG5cbmZ1bmN0aW9uIGluamVjdFByb2ZpbGluZ0hvb2tzKHByb2ZpbGluZ0hvb2tzKSB7XG4gIGluamVjdGVkUHJvZmlsaW5nSG9va3MgPSBwcm9maWxpbmdIb29rcztcbn1cblxuZnVuY3Rpb24gZ2V0TGFuZUxhYmVsTWFwKCkge1xuICB7XG4gICAgdmFyIG1hcCA9IG5ldyBNYXAoKTtcbiAgICB2YXIgbGFuZSA9IDE7XG5cbiAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgVG90YWxMYW5lczsgaW5kZXgrKykge1xuICAgICAgdmFyIGxhYmVsID0gZ2V0TGFiZWxGb3JMYW5lKGxhbmUpO1xuICAgICAgbWFwLnNldChsYW5lLCBsYWJlbCk7XG4gICAgICBsYW5lICo9IDI7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hcDtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXJrQ29tbWl0U3RhcnRlZChsYW5lcykge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbW1pdFN0YXJ0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbW1pdFN0YXJ0ZWQobGFuZXMpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0NvbW1pdFN0b3BwZWQoKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tbWl0U3RvcHBlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tbWl0U3RvcHBlZCgpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0NvbXBvbmVudFJlbmRlclN0YXJ0ZWQoZmliZXIpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRSZW5kZXJTdGFydGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRSZW5kZXJTdGFydGVkKGZpYmVyKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21wb25lbnRSZW5kZXJTdG9wcGVkKCkge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudFJlbmRlclN0b3BwZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudFJlbmRlclN0b3BwZWQoKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0TW91bnRTdGFydGVkKGZpYmVyKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdE1vdW50U3RhcnRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdE1vdW50U3RhcnRlZChmaWJlcik7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdE1vdW50U3RvcHBlZCgpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0TW91bnRTdG9wcGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0TW91bnRTdG9wcGVkKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdFVubW91bnRTdGFydGVkKGZpYmVyKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdFVubW91bnRTdGFydGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0VW5tb3VudFN0YXJ0ZWQoZmliZXIpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RVbm1vdW50U3RvcHBlZCgpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0VW5tb3VudFN0b3BwZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RVbm1vdW50U3RvcHBlZCgpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0NvbXBvbmVudExheW91dEVmZmVjdE1vdW50U3RhcnRlZChmaWJlcikge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudExheW91dEVmZmVjdE1vdW50U3RhcnRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0TW91bnRTdGFydGVkKGZpYmVyKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RNb3VudFN0b3BwZWQoKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0TW91bnRTdG9wcGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RNb3VudFN0b3BwZWQoKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RVbm1vdW50U3RhcnRlZChmaWJlcikge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdGFydGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RVbm1vdW50U3RhcnRlZChmaWJlcik7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0VW5tb3VudFN0b3BwZWQoKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0VW5tb3VudFN0b3BwZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdG9wcGVkKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrQ29tcG9uZW50RXJyb3JlZChmaWJlciwgdGhyb3duVmFsdWUsIGxhbmVzKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50RXJyb3JlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50RXJyb3JlZChmaWJlciwgdGhyb3duVmFsdWUsIGxhbmVzKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21wb25lbnRTdXNwZW5kZWQoZmliZXIsIHdha2VhYmxlLCBsYW5lcykge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudFN1c3BlbmRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50U3VzcGVuZGVkKGZpYmVyLCB3YWtlYWJsZSwgbGFuZXMpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0xheW91dEVmZmVjdHNTdGFydGVkKGxhbmVzKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrTGF5b3V0RWZmZWN0c1N0YXJ0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0xheW91dEVmZmVjdHNTdGFydGVkKGxhbmVzKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtMYXlvdXRFZmZlY3RzU3RvcHBlZCgpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtMYXlvdXRFZmZlY3RzU3RvcHBlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrTGF5b3V0RWZmZWN0c1N0b3BwZWQoKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtQYXNzaXZlRWZmZWN0c1N0YXJ0ZWQobGFuZXMpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtQYXNzaXZlRWZmZWN0c1N0YXJ0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1Bhc3NpdmVFZmZlY3RzU3RhcnRlZChsYW5lcyk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrUGFzc2l2ZUVmZmVjdHNTdG9wcGVkKCkge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1Bhc3NpdmVFZmZlY3RzU3RvcHBlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUGFzc2l2ZUVmZmVjdHNTdG9wcGVkKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrUmVuZGVyU3RhcnRlZChsYW5lcykge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1JlbmRlclN0YXJ0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1JlbmRlclN0YXJ0ZWQobGFuZXMpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya1JlbmRlcllpZWxkZWQoKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUmVuZGVyWWllbGRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUmVuZGVyWWllbGRlZCgpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya1JlbmRlclN0b3BwZWQoKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUmVuZGVyU3RvcHBlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUmVuZGVyU3RvcHBlZCgpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya1JlbmRlclNjaGVkdWxlZChsYW5lKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUmVuZGVyU2NoZWR1bGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtSZW5kZXJTY2hlZHVsZWQobGFuZSk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrRm9yY2VVcGRhdGVTY2hlZHVsZWQoZmliZXIsIGxhbmUpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtGb3JjZVVwZGF0ZVNjaGVkdWxlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrRm9yY2VVcGRhdGVTY2hlZHVsZWQoZmliZXIsIGxhbmUpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya1N0YXRlVXBkYXRlU2NoZWR1bGVkKGZpYmVyLCBsYW5lKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrU3RhdGVVcGRhdGVTY2hlZHVsZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1N0YXRlVXBkYXRlU2NoZWR1bGVkKGZpYmVyLCBsYW5lKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIE5vTW9kZSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuMDsgLy8gVE9ETzogUmVtb3ZlIENvbmN1cnJlbnRNb2RlIGJ5IHJlYWRpbmcgZnJvbSB0aGUgcm9vdCB0YWcgaW5zdGVhZFxuXG52YXIgQ29uY3VycmVudE1vZGUgPVxuLyogICAgICAgICAgICAgICAgICovXG4xO1xudmFyIFByb2ZpbGVNb2RlID1cbi8qICAgICAgICAgICAgICAgICAgICAqL1xuMjtcbnZhciBTdHJpY3RMZWdhY3lNb2RlID1cbi8qICAgICAgICAgICAgICAgKi9cbjg7XG52YXIgU3RyaWN0RWZmZWN0c01vZGUgPVxuLyogICAgICAgICAgICAgICovXG4xNjtcblxuLy8gVE9ETzogVGhpcyBpcyBwcmV0dHkgd2VsbCBzdXBwb3J0ZWQgYnkgYnJvd3NlcnMuIE1heWJlIHdlIGNhbiBkcm9wIGl0LlxudmFyIGNsejMyID0gTWF0aC5jbHozMiA/IE1hdGguY2x6MzIgOiBjbHozMkZhbGxiYWNrOyAvLyBDb3VudCBsZWFkaW5nIHplcm9zLlxuLy8gQmFzZWQgb246XG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9NYXRoL2NsejMyXG5cbnZhciBsb2cgPSBNYXRoLmxvZztcbnZhciBMTjIgPSBNYXRoLkxOMjtcblxuZnVuY3Rpb24gY2x6MzJGYWxsYmFjayh4KSB7XG4gIHZhciBhc1VpbnQgPSB4ID4+PiAwO1xuXG4gIGlmIChhc1VpbnQgPT09IDApIHtcbiAgICByZXR1cm4gMzI7XG4gIH1cblxuICByZXR1cm4gMzEgLSAobG9nKGFzVWludCkgLyBMTjIgfCAwKSB8IDA7XG59XG5cbi8vIElmIHRob3NlIHZhbHVlcyBhcmUgY2hhbmdlZCB0aGF0IHBhY2thZ2Ugc2hvdWxkIGJlIHJlYnVpbHQgYW5kIHJlZGVwbG95ZWQuXG5cbnZhciBUb3RhbExhbmVzID0gMzE7XG52YXIgTm9MYW5lcyA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICovXG4wO1xudmFyIE5vTGFuZSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjA7XG52YXIgU3luY0xhbmUgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAqL1xuMTtcbnZhciBJbnB1dENvbnRpbnVvdXNIeWRyYXRpb25MYW5lID1cbi8qICAgICovXG4yO1xudmFyIElucHV0Q29udGludW91c0xhbmUgPVxuLyogICAgICAgICAgICAgKi9cbjQ7XG52YXIgRGVmYXVsdEh5ZHJhdGlvbkxhbmUgPVxuLyogICAgICAgICAgICAqL1xuODtcbnZhciBEZWZhdWx0TGFuZSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICovXG4xNjtcbnZhciBUcmFuc2l0aW9uSHlkcmF0aW9uTGFuZSA9XG4vKiAgICAgICAgICAgICAgICAqL1xuMzI7XG52YXIgVHJhbnNpdGlvbkxhbmVzID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAqL1xuNDE5NDI0MDtcbnZhciBUcmFuc2l0aW9uTGFuZTEgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAqL1xuNjQ7XG52YXIgVHJhbnNpdGlvbkxhbmUyID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjEyODtcbnZhciBUcmFuc2l0aW9uTGFuZTMgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAqL1xuMjU2O1xudmFyIFRyYW5zaXRpb25MYW5lNCA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICovXG41MTI7XG52YXIgVHJhbnNpdGlvbkxhbmU1ID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjEwMjQ7XG52YXIgVHJhbnNpdGlvbkxhbmU2ID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjIwNDg7XG52YXIgVHJhbnNpdGlvbkxhbmU3ID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjQwOTY7XG52YXIgVHJhbnNpdGlvbkxhbmU4ID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjgxOTI7XG52YXIgVHJhbnNpdGlvbkxhbmU5ID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjE2Mzg0O1xudmFyIFRyYW5zaXRpb25MYW5lMTAgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICovXG4zMjc2ODtcbnZhciBUcmFuc2l0aW9uTGFuZTExID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAqL1xuNjU1MzY7XG52YXIgVHJhbnNpdGlvbkxhbmUxMiA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgKi9cbjEzMTA3MjtcbnZhciBUcmFuc2l0aW9uTGFuZTEzID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAqL1xuMjYyMTQ0O1xudmFyIFRyYW5zaXRpb25MYW5lMTQgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICovXG41MjQyODg7XG52YXIgVHJhbnNpdGlvbkxhbmUxNSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgKi9cbjEwNDg1NzY7XG52YXIgVHJhbnNpdGlvbkxhbmUxNiA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgKi9cbjIwOTcxNTI7XG52YXIgUmV0cnlMYW5lcyA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuMTMwMDIzNDI0O1xudmFyIFJldHJ5TGFuZTEgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG40MTk0MzA0O1xudmFyIFJldHJ5TGFuZTIgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG44Mzg4NjA4O1xudmFyIFJldHJ5TGFuZTMgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4xNjc3NzIxNjtcbnZhciBSZXRyeUxhbmU0ID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuMzM1NTQ0MzI7XG52YXIgUmV0cnlMYW5lNSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjY3MTA4ODY0O1xudmFyIFNvbWVSZXRyeUxhbmUgPSBSZXRyeUxhbmUxO1xudmFyIFNlbGVjdGl2ZUh5ZHJhdGlvbkxhbmUgPVxuLyogICAgICAgICAgKi9cbjEzNDIxNzcyODtcbnZhciBOb25JZGxlTGFuZXMgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAgICovXG4yNjg0MzU0NTU7XG52YXIgSWRsZUh5ZHJhdGlvbkxhbmUgPVxuLyogICAgICAgICAgICAgICAqL1xuMjY4NDM1NDU2O1xudmFyIElkbGVMYW5lID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjUzNjg3MDkxMjtcbnZhciBPZmZzY3JlZW5MYW5lID1cbi8qICAgICAgICAgICAgICAgICAgICovXG4xMDczNzQxODI0OyAvLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgZm9yIHRoZSBleHBlcmltZW50YWwgdGltZWxpbmUgKHJlYWN0LWRldnRvb2xzLXRpbWVsaW5lKVxuLy8gSXQgc2hvdWxkIGJlIGtlcHQgaW4gc3luYyB3aXRoIHRoZSBMYW5lcyB2YWx1ZXMgYWJvdmUuXG5cbmZ1bmN0aW9uIGdldExhYmVsRm9yTGFuZShsYW5lKSB7XG4gIHtcbiAgICBpZiAobGFuZSAmIFN5bmNMYW5lKSB7XG4gICAgICByZXR1cm4gJ1N5bmMnO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgSW5wdXRDb250aW51b3VzSHlkcmF0aW9uTGFuZSkge1xuICAgICAgcmV0dXJuICdJbnB1dENvbnRpbnVvdXNIeWRyYXRpb24nO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgSW5wdXRDb250aW51b3VzTGFuZSkge1xuICAgICAgcmV0dXJuICdJbnB1dENvbnRpbnVvdXMnO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgRGVmYXVsdEh5ZHJhdGlvbkxhbmUpIHtcbiAgICAgIHJldHVybiAnRGVmYXVsdEh5ZHJhdGlvbic7XG4gICAgfVxuXG4gICAgaWYgKGxhbmUgJiBEZWZhdWx0TGFuZSkge1xuICAgICAgcmV0dXJuICdEZWZhdWx0JztcbiAgICB9XG5cbiAgICBpZiAobGFuZSAmIFRyYW5zaXRpb25IeWRyYXRpb25MYW5lKSB7XG4gICAgICByZXR1cm4gJ1RyYW5zaXRpb25IeWRyYXRpb24nO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgVHJhbnNpdGlvbkxhbmVzKSB7XG4gICAgICByZXR1cm4gJ1RyYW5zaXRpb24nO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgUmV0cnlMYW5lcykge1xuICAgICAgcmV0dXJuICdSZXRyeSc7XG4gICAgfVxuXG4gICAgaWYgKGxhbmUgJiBTZWxlY3RpdmVIeWRyYXRpb25MYW5lKSB7XG4gICAgICByZXR1cm4gJ1NlbGVjdGl2ZUh5ZHJhdGlvbic7XG4gICAgfVxuXG4gICAgaWYgKGxhbmUgJiBJZGxlSHlkcmF0aW9uTGFuZSkge1xuICAgICAgcmV0dXJuICdJZGxlSHlkcmF0aW9uJztcbiAgICB9XG5cbiAgICBpZiAobGFuZSAmIElkbGVMYW5lKSB7XG4gICAgICByZXR1cm4gJ0lkbGUnO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgT2Zmc2NyZWVuTGFuZSkge1xuICAgICAgcmV0dXJuICdPZmZzY3JlZW4nO1xuICAgIH1cbiAgfVxufVxudmFyIE5vVGltZXN0YW1wID0gLTE7XG52YXIgbmV4dFRyYW5zaXRpb25MYW5lID0gVHJhbnNpdGlvbkxhbmUxO1xudmFyIG5leHRSZXRyeUxhbmUgPSBSZXRyeUxhbmUxO1xuXG5mdW5jdGlvbiBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lcyhsYW5lcykge1xuICBzd2l0Y2ggKGdldEhpZ2hlc3RQcmlvcml0eUxhbmUobGFuZXMpKSB7XG4gICAgY2FzZSBTeW5jTGFuZTpcbiAgICAgIHJldHVybiBTeW5jTGFuZTtcblxuICAgIGNhc2UgSW5wdXRDb250aW51b3VzSHlkcmF0aW9uTGFuZTpcbiAgICAgIHJldHVybiBJbnB1dENvbnRpbnVvdXNIeWRyYXRpb25MYW5lO1xuXG4gICAgY2FzZSBJbnB1dENvbnRpbnVvdXNMYW5lOlxuICAgICAgcmV0dXJuIElucHV0Q29udGludW91c0xhbmU7XG5cbiAgICBjYXNlIERlZmF1bHRIeWRyYXRpb25MYW5lOlxuICAgICAgcmV0dXJuIERlZmF1bHRIeWRyYXRpb25MYW5lO1xuXG4gICAgY2FzZSBEZWZhdWx0TGFuZTpcbiAgICAgIHJldHVybiBEZWZhdWx0TGFuZTtcblxuICAgIGNhc2UgVHJhbnNpdGlvbkh5ZHJhdGlvbkxhbmU6XG4gICAgICByZXR1cm4gVHJhbnNpdGlvbkh5ZHJhdGlvbkxhbmU7XG5cbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMjpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMzpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNDpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNjpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNzpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lODpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lOTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTA6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTExOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxMjpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTM6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTE0OlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxNTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTY6XG4gICAgICByZXR1cm4gbGFuZXMgJiBUcmFuc2l0aW9uTGFuZXM7XG5cbiAgICBjYXNlIFJldHJ5TGFuZTE6XG4gICAgY2FzZSBSZXRyeUxhbmUyOlxuICAgIGNhc2UgUmV0cnlMYW5lMzpcbiAgICBjYXNlIFJldHJ5TGFuZTQ6XG4gICAgY2FzZSBSZXRyeUxhbmU1OlxuICAgICAgcmV0dXJuIGxhbmVzICYgUmV0cnlMYW5lcztcblxuICAgIGNhc2UgU2VsZWN0aXZlSHlkcmF0aW9uTGFuZTpcbiAgICAgIHJldHVybiBTZWxlY3RpdmVIeWRyYXRpb25MYW5lO1xuXG4gICAgY2FzZSBJZGxlSHlkcmF0aW9uTGFuZTpcbiAgICAgIHJldHVybiBJZGxlSHlkcmF0aW9uTGFuZTtcblxuICAgIGNhc2UgSWRsZUxhbmU6XG4gICAgICByZXR1cm4gSWRsZUxhbmU7XG5cbiAgICBjYXNlIE9mZnNjcmVlbkxhbmU6XG4gICAgICByZXR1cm4gT2Zmc2NyZWVuTGFuZTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIGVycm9yKCdTaG91bGQgaGF2ZSBmb3VuZCBtYXRjaGluZyBsYW5lcy4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4nKTtcbiAgICAgIH0gLy8gVGhpcyBzaG91bGRuJ3QgYmUgcmVhY2hhYmxlLCBidXQgYXMgYSBmYWxsYmFjaywgcmV0dXJuIHRoZSBlbnRpcmUgYml0bWFzay5cblxuXG4gICAgICByZXR1cm4gbGFuZXM7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0TmV4dExhbmVzKHJvb3QsIHdpcExhbmVzKSB7XG4gIC8vIEVhcmx5IGJhaWxvdXQgaWYgdGhlcmUncyBubyBwZW5kaW5nIHdvcmsgbGVmdC5cbiAgdmFyIHBlbmRpbmdMYW5lcyA9IHJvb3QucGVuZGluZ0xhbmVzO1xuXG4gIGlmIChwZW5kaW5nTGFuZXMgPT09IE5vTGFuZXMpIHtcbiAgICByZXR1cm4gTm9MYW5lcztcbiAgfVxuXG4gIHZhciBuZXh0TGFuZXMgPSBOb0xhbmVzO1xuICB2YXIgc3VzcGVuZGVkTGFuZXMgPSByb290LnN1c3BlbmRlZExhbmVzO1xuICB2YXIgcGluZ2VkTGFuZXMgPSByb290LnBpbmdlZExhbmVzOyAvLyBEbyBub3Qgd29yayBvbiBhbnkgaWRsZSB3b3JrIHVudGlsIGFsbCB0aGUgbm9uLWlkbGUgd29yayBoYXMgZmluaXNoZWQsXG4gIC8vIGV2ZW4gaWYgdGhlIHdvcmsgaXMgc3VzcGVuZGVkLlxuXG4gIHZhciBub25JZGxlUGVuZGluZ0xhbmVzID0gcGVuZGluZ0xhbmVzICYgTm9uSWRsZUxhbmVzO1xuXG4gIGlmIChub25JZGxlUGVuZGluZ0xhbmVzICE9PSBOb0xhbmVzKSB7XG4gICAgdmFyIG5vbklkbGVVbmJsb2NrZWRMYW5lcyA9IG5vbklkbGVQZW5kaW5nTGFuZXMgJiB+c3VzcGVuZGVkTGFuZXM7XG5cbiAgICBpZiAobm9uSWRsZVVuYmxvY2tlZExhbmVzICE9PSBOb0xhbmVzKSB7XG4gICAgICBuZXh0TGFuZXMgPSBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lcyhub25JZGxlVW5ibG9ja2VkTGFuZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbm9uSWRsZVBpbmdlZExhbmVzID0gbm9uSWRsZVBlbmRpbmdMYW5lcyAmIHBpbmdlZExhbmVzO1xuXG4gICAgICBpZiAobm9uSWRsZVBpbmdlZExhbmVzICE9PSBOb0xhbmVzKSB7XG4gICAgICAgIG5leHRMYW5lcyA9IGdldEhpZ2hlc3RQcmlvcml0eUxhbmVzKG5vbklkbGVQaW5nZWRMYW5lcyk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFRoZSBvbmx5IHJlbWFpbmluZyB3b3JrIGlzIElkbGUuXG4gICAgdmFyIHVuYmxvY2tlZExhbmVzID0gcGVuZGluZ0xhbmVzICYgfnN1c3BlbmRlZExhbmVzO1xuXG4gICAgaWYgKHVuYmxvY2tlZExhbmVzICE9PSBOb0xhbmVzKSB7XG4gICAgICBuZXh0TGFuZXMgPSBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lcyh1bmJsb2NrZWRMYW5lcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChwaW5nZWRMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgICAgICBuZXh0TGFuZXMgPSBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lcyhwaW5nZWRMYW5lcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKG5leHRMYW5lcyA9PT0gTm9MYW5lcykge1xuICAgIC8vIFRoaXMgc2hvdWxkIG9ubHkgYmUgcmVhY2hhYmxlIGlmIHdlJ3JlIHN1c3BlbmRlZFxuICAgIC8vIFRPRE86IENvbnNpZGVyIHdhcm5pbmcgaW4gdGhpcyBwYXRoIGlmIGEgZmFsbGJhY2sgdGltZXIgaXMgbm90IHNjaGVkdWxlZC5cbiAgICByZXR1cm4gTm9MYW5lcztcbiAgfSAvLyBJZiB3ZSdyZSBhbHJlYWR5IGluIHRoZSBtaWRkbGUgb2YgYSByZW5kZXIsIHN3aXRjaGluZyBsYW5lcyB3aWxsIGludGVycnVwdFxuICAvLyBpdCBhbmQgd2UnbGwgbG9zZSBvdXIgcHJvZ3Jlc3MuIFdlIHNob3VsZCBvbmx5IGRvIHRoaXMgaWYgdGhlIG5ldyBsYW5lcyBhcmVcbiAgLy8gaGlnaGVyIHByaW9yaXR5LlxuXG5cbiAgaWYgKHdpcExhbmVzICE9PSBOb0xhbmVzICYmIHdpcExhbmVzICE9PSBuZXh0TGFuZXMgJiYgLy8gSWYgd2UgYWxyZWFkeSBzdXNwZW5kZWQgd2l0aCBhIGRlbGF5LCB0aGVuIGludGVycnVwdGluZyBpcyBmaW5lLiBEb24ndFxuICAvLyBib3RoZXIgd2FpdGluZyB1bnRpbCB0aGUgcm9vdCBpcyBjb21wbGV0ZS5cbiAgKHdpcExhbmVzICYgc3VzcGVuZGVkTGFuZXMpID09PSBOb0xhbmVzKSB7XG4gICAgdmFyIG5leHRMYW5lID0gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZShuZXh0TGFuZXMpO1xuICAgIHZhciB3aXBMYW5lID0gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZSh3aXBMYW5lcyk7XG5cbiAgICBpZiAoIC8vIFRlc3RzIHdoZXRoZXIgdGhlIG5leHQgbGFuZSBpcyBlcXVhbCBvciBsb3dlciBwcmlvcml0eSB0aGFuIHRoZSB3aXBcbiAgICAvLyBvbmUuIFRoaXMgd29ya3MgYmVjYXVzZSB0aGUgYml0cyBkZWNyZWFzZSBpbiBwcmlvcml0eSBhcyB5b3UgZ28gbGVmdC5cbiAgICBuZXh0TGFuZSA+PSB3aXBMYW5lIHx8IC8vIERlZmF1bHQgcHJpb3JpdHkgdXBkYXRlcyBzaG91bGQgbm90IGludGVycnVwdCB0cmFuc2l0aW9uIHVwZGF0ZXMuIFRoZVxuICAgIC8vIG9ubHkgZGlmZmVyZW5jZSBiZXR3ZWVuIGRlZmF1bHQgdXBkYXRlcyBhbmQgdHJhbnNpdGlvbiB1cGRhdGVzIGlzIHRoYXRcbiAgICAvLyBkZWZhdWx0IHVwZGF0ZXMgZG8gbm90IHN1cHBvcnQgcmVmcmVzaCB0cmFuc2l0aW9ucy5cbiAgICBuZXh0TGFuZSA9PT0gRGVmYXVsdExhbmUgJiYgKHdpcExhbmUgJiBUcmFuc2l0aW9uTGFuZXMpICE9PSBOb0xhbmVzKSB7XG4gICAgICAvLyBLZWVwIHdvcmtpbmcgb24gdGhlIGV4aXN0aW5nIGluLXByb2dyZXNzIHRyZWUuIERvIG5vdCBpbnRlcnJ1cHQuXG4gICAgICByZXR1cm4gd2lwTGFuZXM7XG4gICAgfVxuICB9XG5cbiAgaWYgKChuZXh0TGFuZXMgJiBJbnB1dENvbnRpbnVvdXNMYW5lKSAhPT0gTm9MYW5lcykge1xuICAgIC8vIFdoZW4gdXBkYXRlcyBhcmUgc3luYyBieSBkZWZhdWx0LCB3ZSBlbnRhbmdsZSBjb250aW51b3VzIHByaW9yaXR5IHVwZGF0ZXNcbiAgICAvLyBhbmQgZGVmYXVsdCB1cGRhdGVzLCBzbyB0aGV5IHJlbmRlciBpbiB0aGUgc2FtZSBiYXRjaC4gVGhlIG9ubHkgcmVhc29uXG4gICAgLy8gdGhleSB1c2Ugc2VwYXJhdGUgbGFuZXMgaXMgYmVjYXVzZSBjb250aW51b3VzIHVwZGF0ZXMgc2hvdWxkIGludGVycnVwdFxuICAgIC8vIHRyYW5zaXRpb25zLCBidXQgZGVmYXVsdCB1cGRhdGVzIHNob3VsZCBub3QuXG4gICAgbmV4dExhbmVzIHw9IHBlbmRpbmdMYW5lcyAmIERlZmF1bHRMYW5lO1xuICB9IC8vIENoZWNrIGZvciBlbnRhbmdsZWQgbGFuZXMgYW5kIGFkZCB0aGVtIHRvIHRoZSBiYXRjaC5cbiAgLy9cbiAgLy8gQSBsYW5lIGlzIHNhaWQgdG8gYmUgZW50YW5nbGVkIHdpdGggYW5vdGhlciB3aGVuIGl0J3Mgbm90IGFsbG93ZWQgdG8gcmVuZGVyXG4gIC8vIGluIGEgYmF0Y2ggdGhhdCBkb2VzIG5vdCBhbHNvIGluY2x1ZGUgdGhlIG90aGVyIGxhbmUuIFR5cGljYWxseSB3ZSBkbyB0aGlzXG4gIC8vIHdoZW4gbXVsdGlwbGUgdXBkYXRlcyBoYXZlIHRoZSBzYW1lIHNvdXJjZSwgYW5kIHdlIG9ubHkgd2FudCB0byByZXNwb25kIHRvXG4gIC8vIHRoZSBtb3N0IHJlY2VudCBldmVudCBmcm9tIHRoYXQgc291cmNlLlxuICAvL1xuICAvLyBOb3RlIHRoYXQgd2UgYXBwbHkgZW50YW5nbGVtZW50cyAqYWZ0ZXIqIGNoZWNraW5nIGZvciBwYXJ0aWFsIHdvcmsgYWJvdmUuXG4gIC8vIFRoaXMgbWVhbnMgdGhhdCBpZiBhIGxhbmUgaXMgZW50YW5nbGVkIGR1cmluZyBhbiBpbnRlcmxlYXZlZCBldmVudCB3aGlsZVxuICAvLyBpdCdzIGFscmVhZHkgcmVuZGVyaW5nLCB3ZSB3b24ndCBpbnRlcnJ1cHQgaXQuIFRoaXMgaXMgaW50ZW50aW9uYWwsIHNpbmNlXG4gIC8vIGVudGFuZ2xlbWVudCBpcyB1c3VhbGx5IFwiYmVzdCBlZmZvcnRcIjogd2UnbGwgdHJ5IG91ciBiZXN0IHRvIHJlbmRlciB0aGVcbiAgLy8gbGFuZXMgaW4gdGhlIHNhbWUgYmF0Y2gsIGJ1dCBpdCdzIG5vdCB3b3J0aCB0aHJvd2luZyBvdXQgcGFydGlhbGx5XG4gIC8vIGNvbXBsZXRlZCB3b3JrIGluIG9yZGVyIHRvIGRvIGl0LlxuICAvLyBUT0RPOiBSZWNvbnNpZGVyIHRoaXMuIFRoZSBjb3VudGVyLWFyZ3VtZW50IGlzIHRoYXQgdGhlIHBhcnRpYWwgd29ya1xuICAvLyByZXByZXNlbnRzIGFuIGludGVybWVkaWF0ZSBzdGF0ZSwgd2hpY2ggd2UgZG9uJ3Qgd2FudCB0byBzaG93IHRvIHRoZSB1c2VyLlxuICAvLyBBbmQgYnkgc3BlbmRpbmcgZXh0cmEgdGltZSBmaW5pc2hpbmcgaXQsIHdlJ3JlIGluY3JlYXNpbmcgdGhlIGFtb3VudCBvZlxuICAvLyB0aW1lIGl0IHRha2VzIHRvIHNob3cgdGhlIGZpbmFsIHN0YXRlLCB3aGljaCBpcyB3aGF0IHRoZXkgYXJlIGFjdHVhbGx5XG4gIC8vIHdhaXRpbmcgZm9yLlxuICAvL1xuICAvLyBGb3IgdGhvc2UgZXhjZXB0aW9ucyB3aGVyZSBlbnRhbmdsZW1lbnQgaXMgc2VtYW50aWNhbGx5IGltcG9ydGFudCwgbGlrZVxuICAvLyB1c2VNdXRhYmxlU291cmNlLCB3ZSBzaG91bGQgZW5zdXJlIHRoYXQgdGhlcmUgaXMgbm8gcGFydGlhbCB3b3JrIGF0IHRoZVxuICAvLyB0aW1lIHdlIGFwcGx5IHRoZSBlbnRhbmdsZW1lbnQuXG5cblxuICB2YXIgZW50YW5nbGVkTGFuZXMgPSByb290LmVudGFuZ2xlZExhbmVzO1xuXG4gIGlmIChlbnRhbmdsZWRMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgIHZhciBlbnRhbmdsZW1lbnRzID0gcm9vdC5lbnRhbmdsZW1lbnRzO1xuICAgIHZhciBsYW5lcyA9IG5leHRMYW5lcyAmIGVudGFuZ2xlZExhbmVzO1xuXG4gICAgd2hpbGUgKGxhbmVzID4gMCkge1xuICAgICAgdmFyIGluZGV4ID0gcGlja0FyYml0cmFyeUxhbmVJbmRleChsYW5lcyk7XG4gICAgICB2YXIgbGFuZSA9IDEgPDwgaW5kZXg7XG4gICAgICBuZXh0TGFuZXMgfD0gZW50YW5nbGVtZW50c1tpbmRleF07XG4gICAgICBsYW5lcyAmPSB+bGFuZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV4dExhbmVzO1xufVxuZnVuY3Rpb24gZ2V0TW9zdFJlY2VudEV2ZW50VGltZShyb290LCBsYW5lcykge1xuICB2YXIgZXZlbnRUaW1lcyA9IHJvb3QuZXZlbnRUaW1lcztcbiAgdmFyIG1vc3RSZWNlbnRFdmVudFRpbWUgPSBOb1RpbWVzdGFtcDtcblxuICB3aGlsZSAobGFuZXMgPiAwKSB7XG4gICAgdmFyIGluZGV4ID0gcGlja0FyYml0cmFyeUxhbmVJbmRleChsYW5lcyk7XG4gICAgdmFyIGxhbmUgPSAxIDw8IGluZGV4O1xuICAgIHZhciBldmVudFRpbWUgPSBldmVudFRpbWVzW2luZGV4XTtcblxuICAgIGlmIChldmVudFRpbWUgPiBtb3N0UmVjZW50RXZlbnRUaW1lKSB7XG4gICAgICBtb3N0UmVjZW50RXZlbnRUaW1lID0gZXZlbnRUaW1lO1xuICAgIH1cblxuICAgIGxhbmVzICY9IH5sYW5lO1xuICB9XG5cbiAgcmV0dXJuIG1vc3RSZWNlbnRFdmVudFRpbWU7XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVFeHBpcmF0aW9uVGltZShsYW5lLCBjdXJyZW50VGltZSkge1xuICBzd2l0Y2ggKGxhbmUpIHtcbiAgICBjYXNlIFN5bmNMYW5lOlxuICAgIGNhc2UgSW5wdXRDb250aW51b3VzSHlkcmF0aW9uTGFuZTpcbiAgICBjYXNlIElucHV0Q29udGludW91c0xhbmU6XG4gICAgICAvLyBVc2VyIGludGVyYWN0aW9ucyBzaG91bGQgZXhwaXJlIHNsaWdodGx5IG1vcmUgcXVpY2tseS5cbiAgICAgIC8vXG4gICAgICAvLyBOT1RFOiBUaGlzIGlzIHNldCB0byB0aGUgY29ycmVzcG9uZGluZyBjb25zdGFudCBhcyBpbiBTY2hlZHVsZXIuanMuXG4gICAgICAvLyBXaGVuIHdlIG1hZGUgaXQgbGFyZ2VyLCBhIHByb2R1Y3QgbWV0cmljIGluIHd3dyByZWdyZXNzZWQsIHN1Z2dlc3RpbmdcbiAgICAgIC8vIHRoZXJlJ3MgYSB1c2VyIGludGVyYWN0aW9uIHRoYXQncyBiZWluZyBzdGFydmVkIGJ5IGEgc2VyaWVzIG9mXG4gICAgICAvLyBzeW5jaHJvbm91cyB1cGRhdGVzLiBJZiB0aGF0IHRoZW9yeSBpcyBjb3JyZWN0LCB0aGUgcHJvcGVyIHNvbHV0aW9uIGlzXG4gICAgICAvLyB0byBmaXggdGhlIHN0YXJ2YXRpb24uIEhvd2V2ZXIsIHRoaXMgc2NlbmFyaW8gc3VwcG9ydHMgdGhlIGlkZWEgdGhhdFxuICAgICAgLy8gZXhwaXJhdGlvbiB0aW1lcyBhcmUgYW4gaW1wb3J0YW50IHNhZmVndWFyZCB3aGVuIHN0YXJ2YXRpb25cbiAgICAgIC8vIGRvZXMgaGFwcGVuLlxuICAgICAgcmV0dXJuIGN1cnJlbnRUaW1lICsgMjUwO1xuXG4gICAgY2FzZSBEZWZhdWx0SHlkcmF0aW9uTGFuZTpcbiAgICBjYXNlIERlZmF1bHRMYW5lOlxuICAgIGNhc2UgVHJhbnNpdGlvbkh5ZHJhdGlvbkxhbmU6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTE6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTI6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTM6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTQ6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTU6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTY6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTc6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTg6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTk6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTEwOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxMTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTI6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTEzOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxNDpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTU6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTE2OlxuICAgICAgcmV0dXJuIGN1cnJlbnRUaW1lICsgNTAwMDtcblxuICAgIGNhc2UgUmV0cnlMYW5lMTpcbiAgICBjYXNlIFJldHJ5TGFuZTI6XG4gICAgY2FzZSBSZXRyeUxhbmUzOlxuICAgIGNhc2UgUmV0cnlMYW5lNDpcbiAgICBjYXNlIFJldHJ5TGFuZTU6XG4gICAgICAvLyBUT0RPOiBSZXRyaWVzIHNob3VsZCBiZSBhbGxvd2VkIHRvIGV4cGlyZSBpZiB0aGV5IGFyZSBDUFUgYm91bmQgZm9yXG4gICAgICAvLyB0b28gbG9uZywgYnV0IHdoZW4gSSBtYWRlIHRoaXMgY2hhbmdlIGl0IGNhdXNlZCBhIHNwaWtlIGluIGJyb3dzZXJcbiAgICAgIC8vIGNyYXNoZXMuIFRoZXJlIG11c3QgYmUgc29tZSBvdGhlciB1bmRlcmx5aW5nIGJ1Zzsgbm90IHN1cGVyIHVyZ2VudCBidXRcbiAgICAgIC8vIGlkZWFsbHkgc2hvdWxkIGZpZ3VyZSBvdXQgd2h5IGFuZCBmaXggaXQuIFVuZm9ydHVuYXRlbHkgd2UgZG9uJ3QgaGF2ZVxuICAgICAgLy8gYSByZXBybyBmb3IgdGhlIGNyYXNoZXMsIG9ubHkgZGV0ZWN0ZWQgdmlhIHByb2R1Y3Rpb24gbWV0cmljcy5cbiAgICAgIHJldHVybiBOb1RpbWVzdGFtcDtcblxuICAgIGNhc2UgU2VsZWN0aXZlSHlkcmF0aW9uTGFuZTpcbiAgICBjYXNlIElkbGVIeWRyYXRpb25MYW5lOlxuICAgIGNhc2UgSWRsZUxhbmU6XG4gICAgY2FzZSBPZmZzY3JlZW5MYW5lOlxuICAgICAgLy8gQW55dGhpbmcgaWRsZSBwcmlvcml0eSBvciBsb3dlciBzaG91bGQgbmV2ZXIgZXhwaXJlLlxuICAgICAgcmV0dXJuIE5vVGltZXN0YW1wO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHtcbiAgICAgICAgZXJyb3IoJ1Nob3VsZCBoYXZlIGZvdW5kIG1hdGNoaW5nIGxhbmVzLiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0LicpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gTm9UaW1lc3RhbXA7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWFya1N0YXJ2ZWRMYW5lc0FzRXhwaXJlZChyb290LCBjdXJyZW50VGltZSkge1xuICAvLyBUT0RPOiBUaGlzIGdldHMgY2FsbGVkIGV2ZXJ5IHRpbWUgd2UgeWllbGQuIFdlIGNhbiBvcHRpbWl6ZSBieSBzdG9yaW5nXG4gIC8vIHRoZSBlYXJsaWVzdCBleHBpcmF0aW9uIHRpbWUgb24gdGhlIHJvb3QuIFRoZW4gdXNlIHRoYXQgdG8gcXVpY2tseSBiYWlsIG91dFxuICAvLyBvZiB0aGlzIGZ1bmN0aW9uLlxuICB2YXIgcGVuZGluZ0xhbmVzID0gcm9vdC5wZW5kaW5nTGFuZXM7XG4gIHZhciBzdXNwZW5kZWRMYW5lcyA9IHJvb3Quc3VzcGVuZGVkTGFuZXM7XG4gIHZhciBwaW5nZWRMYW5lcyA9IHJvb3QucGluZ2VkTGFuZXM7XG4gIHZhciBleHBpcmF0aW9uVGltZXMgPSByb290LmV4cGlyYXRpb25UaW1lczsgLy8gSXRlcmF0ZSB0aHJvdWdoIHRoZSBwZW5kaW5nIGxhbmVzIGFuZCBjaGVjayBpZiB3ZSd2ZSByZWFjaGVkIHRoZWlyXG4gIC8vIGV4cGlyYXRpb24gdGltZS4gSWYgc28sIHdlJ2xsIGFzc3VtZSB0aGUgdXBkYXRlIGlzIGJlaW5nIHN0YXJ2ZWQgYW5kIG1hcmtcbiAgLy8gaXQgYXMgZXhwaXJlZCB0byBmb3JjZSBpdCB0byBmaW5pc2guXG5cbiAgdmFyIGxhbmVzID0gcGVuZGluZ0xhbmVzO1xuXG4gIHdoaWxlIChsYW5lcyA+IDApIHtcbiAgICB2YXIgaW5kZXggPSBwaWNrQXJiaXRyYXJ5TGFuZUluZGV4KGxhbmVzKTtcbiAgICB2YXIgbGFuZSA9IDEgPDwgaW5kZXg7XG4gICAgdmFyIGV4cGlyYXRpb25UaW1lID0gZXhwaXJhdGlvblRpbWVzW2luZGV4XTtcblxuICAgIGlmIChleHBpcmF0aW9uVGltZSA9PT0gTm9UaW1lc3RhbXApIHtcbiAgICAgIC8vIEZvdW5kIGEgcGVuZGluZyBsYW5lIHdpdGggbm8gZXhwaXJhdGlvbiB0aW1lLiBJZiBpdCdzIG5vdCBzdXNwZW5kZWQsIG9yXG4gICAgICAvLyBpZiBpdCdzIHBpbmdlZCwgYXNzdW1lIGl0J3MgQ1BVLWJvdW5kLiBDb21wdXRlIGEgbmV3IGV4cGlyYXRpb24gdGltZVxuICAgICAgLy8gdXNpbmcgdGhlIGN1cnJlbnQgdGltZS5cbiAgICAgIGlmICgobGFuZSAmIHN1c3BlbmRlZExhbmVzKSA9PT0gTm9MYW5lcyB8fCAobGFuZSAmIHBpbmdlZExhbmVzKSAhPT0gTm9MYW5lcykge1xuICAgICAgICAvLyBBc3N1bWVzIHRpbWVzdGFtcHMgYXJlIG1vbm90b25pY2FsbHkgaW5jcmVhc2luZy5cbiAgICAgICAgZXhwaXJhdGlvblRpbWVzW2luZGV4XSA9IGNvbXB1dGVFeHBpcmF0aW9uVGltZShsYW5lLCBjdXJyZW50VGltZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChleHBpcmF0aW9uVGltZSA8PSBjdXJyZW50VGltZSkge1xuICAgICAgLy8gVGhpcyBsYW5lIGV4cGlyZWRcbiAgICAgIHJvb3QuZXhwaXJlZExhbmVzIHw9IGxhbmU7XG4gICAgfVxuXG4gICAgbGFuZXMgJj0gfmxhbmU7XG4gIH1cbn0gLy8gVGhpcyByZXR1cm5zIHRoZSBoaWdoZXN0IHByaW9yaXR5IHBlbmRpbmcgbGFuZXMgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZXlcbi8vIGFyZSBzdXNwZW5kZWQuXG5cbmZ1bmN0aW9uIGdldEhpZ2hlc3RQcmlvcml0eVBlbmRpbmdMYW5lcyhyb290KSB7XG4gIHJldHVybiBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lcyhyb290LnBlbmRpbmdMYW5lcyk7XG59XG5mdW5jdGlvbiBnZXRMYW5lc1RvUmV0cnlTeW5jaHJvbm91c2x5T25FcnJvcihyb290KSB7XG4gIHZhciBldmVyeXRoaW5nQnV0T2Zmc2NyZWVuID0gcm9vdC5wZW5kaW5nTGFuZXMgJiB+T2Zmc2NyZWVuTGFuZTtcblxuICBpZiAoZXZlcnl0aGluZ0J1dE9mZnNjcmVlbiAhPT0gTm9MYW5lcykge1xuICAgIHJldHVybiBldmVyeXRoaW5nQnV0T2Zmc2NyZWVuO1xuICB9XG5cbiAgaWYgKGV2ZXJ5dGhpbmdCdXRPZmZzY3JlZW4gJiBPZmZzY3JlZW5MYW5lKSB7XG4gICAgcmV0dXJuIE9mZnNjcmVlbkxhbmU7XG4gIH1cblxuICByZXR1cm4gTm9MYW5lcztcbn1cbmZ1bmN0aW9uIGluY2x1ZGVzU3luY0xhbmUobGFuZXMpIHtcbiAgcmV0dXJuIChsYW5lcyAmIFN5bmNMYW5lKSAhPT0gTm9MYW5lcztcbn1cbmZ1bmN0aW9uIGluY2x1ZGVzTm9uSWRsZVdvcmsobGFuZXMpIHtcbiAgcmV0dXJuIChsYW5lcyAmIE5vbklkbGVMYW5lcykgIT09IE5vTGFuZXM7XG59XG5mdW5jdGlvbiBpbmNsdWRlc09ubHlSZXRyaWVzKGxhbmVzKSB7XG4gIHJldHVybiAobGFuZXMgJiBSZXRyeUxhbmVzKSA9PT0gbGFuZXM7XG59XG5mdW5jdGlvbiBpbmNsdWRlc09ubHlOb25VcmdlbnRMYW5lcyhsYW5lcykge1xuICB2YXIgVXJnZW50TGFuZXMgPSBTeW5jTGFuZSB8IElucHV0Q29udGludW91c0xhbmUgfCBEZWZhdWx0TGFuZTtcbiAgcmV0dXJuIChsYW5lcyAmIFVyZ2VudExhbmVzKSA9PT0gTm9MYW5lcztcbn1cbmZ1bmN0aW9uIGluY2x1ZGVzT25seVRyYW5zaXRpb25zKGxhbmVzKSB7XG4gIHJldHVybiAobGFuZXMgJiBUcmFuc2l0aW9uTGFuZXMpID09PSBsYW5lcztcbn1cbmZ1bmN0aW9uIGluY2x1ZGVzQmxvY2tpbmdMYW5lKHJvb3QsIGxhbmVzKSB7XG5cbiAgdmFyIFN5bmNEZWZhdWx0TGFuZXMgPSBJbnB1dENvbnRpbnVvdXNIeWRyYXRpb25MYW5lIHwgSW5wdXRDb250aW51b3VzTGFuZSB8IERlZmF1bHRIeWRyYXRpb25MYW5lIHwgRGVmYXVsdExhbmU7XG4gIHJldHVybiAobGFuZXMgJiBTeW5jRGVmYXVsdExhbmVzKSAhPT0gTm9MYW5lcztcbn1cbmZ1bmN0aW9uIGluY2x1ZGVzRXhwaXJlZExhbmUocm9vdCwgbGFuZXMpIHtcbiAgLy8gVGhpcyBpcyBhIHNlcGFyYXRlIGNoZWNrIGZyb20gaW5jbHVkZXNCbG9ja2luZ0xhbmUgYmVjYXVzZSBhIGxhbmUgY2FuXG4gIC8vIGV4cGlyZSBhZnRlciBhIHJlbmRlciBoYXMgYWxyZWFkeSBzdGFydGVkLlxuICByZXR1cm4gKGxhbmVzICYgcm9vdC5leHBpcmVkTGFuZXMpICE9PSBOb0xhbmVzO1xufVxuZnVuY3Rpb24gaXNUcmFuc2l0aW9uTGFuZShsYW5lKSB7XG4gIHJldHVybiAobGFuZSAmIFRyYW5zaXRpb25MYW5lcykgIT09IE5vTGFuZXM7XG59XG5mdW5jdGlvbiBjbGFpbU5leHRUcmFuc2l0aW9uTGFuZSgpIHtcbiAgLy8gQ3ljbGUgdGhyb3VnaCB0aGUgbGFuZXMsIGFzc2lnbmluZyBlYWNoIG5ldyB0cmFuc2l0aW9uIHRvIHRoZSBuZXh0IGxhbmUuXG4gIC8vIEluIG1vc3QgY2FzZXMsIHRoaXMgbWVhbnMgZXZlcnkgdHJhbnNpdGlvbiBnZXRzIGl0cyBvd24gbGFuZSwgdW50aWwgd2VcbiAgLy8gcnVuIG91dCBvZiBsYW5lcyBhbmQgY3ljbGUgYmFjayB0byB0aGUgYmVnaW5uaW5nLlxuICB2YXIgbGFuZSA9IG5leHRUcmFuc2l0aW9uTGFuZTtcbiAgbmV4dFRyYW5zaXRpb25MYW5lIDw8PSAxO1xuXG4gIGlmICgobmV4dFRyYW5zaXRpb25MYW5lICYgVHJhbnNpdGlvbkxhbmVzKSA9PT0gTm9MYW5lcykge1xuICAgIG5leHRUcmFuc2l0aW9uTGFuZSA9IFRyYW5zaXRpb25MYW5lMTtcbiAgfVxuXG4gIHJldHVybiBsYW5lO1xufVxuZnVuY3Rpb24gY2xhaW1OZXh0UmV0cnlMYW5lKCkge1xuICB2YXIgbGFuZSA9IG5leHRSZXRyeUxhbmU7XG4gIG5leHRSZXRyeUxhbmUgPDw9IDE7XG5cbiAgaWYgKChuZXh0UmV0cnlMYW5lICYgUmV0cnlMYW5lcykgPT09IE5vTGFuZXMpIHtcbiAgICBuZXh0UmV0cnlMYW5lID0gUmV0cnlMYW5lMTtcbiAgfVxuXG4gIHJldHVybiBsYW5lO1xufVxuZnVuY3Rpb24gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZShsYW5lcykge1xuICByZXR1cm4gbGFuZXMgJiAtbGFuZXM7XG59XG5mdW5jdGlvbiBwaWNrQXJiaXRyYXJ5TGFuZShsYW5lcykge1xuICAvLyBUaGlzIHdyYXBwZXIgZnVuY3Rpb24gZ2V0cyBpbmxpbmVkLiBPbmx5IGV4aXN0cyBzbyB0byBjb21tdW5pY2F0ZSB0aGF0IGl0XG4gIC8vIGRvZXNuJ3QgbWF0dGVyIHdoaWNoIGJpdCBpcyBzZWxlY3RlZDsgeW91IGNhbiBwaWNrIGFueSBiaXQgd2l0aG91dFxuICAvLyBhZmZlY3RpbmcgdGhlIGFsZ29yaXRobXMgd2hlcmUgaXRzIHVzZWQuIEhlcmUgSSdtIHVzaW5nXG4gIC8vIGdldEhpZ2hlc3RQcmlvcml0eUxhbmUgYmVjYXVzZSBpdCByZXF1aXJlcyB0aGUgZmV3ZXN0IG9wZXJhdGlvbnMuXG4gIHJldHVybiBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lKGxhbmVzKTtcbn1cblxuZnVuY3Rpb24gcGlja0FyYml0cmFyeUxhbmVJbmRleChsYW5lcykge1xuICByZXR1cm4gMzEgLSBjbHozMihsYW5lcyk7XG59XG5cbmZ1bmN0aW9uIGxhbmVUb0luZGV4KGxhbmUpIHtcbiAgcmV0dXJuIHBpY2tBcmJpdHJhcnlMYW5lSW5kZXgobGFuZSk7XG59XG5cbmZ1bmN0aW9uIGluY2x1ZGVzU29tZUxhbmUoYSwgYikge1xuICByZXR1cm4gKGEgJiBiKSAhPT0gTm9MYW5lcztcbn1cbmZ1bmN0aW9uIGlzU3Vic2V0T2ZMYW5lcyhzZXQsIHN1YnNldCkge1xuICByZXR1cm4gKHNldCAmIHN1YnNldCkgPT09IHN1YnNldDtcbn1cbmZ1bmN0aW9uIG1lcmdlTGFuZXMoYSwgYikge1xuICByZXR1cm4gYSB8IGI7XG59XG5mdW5jdGlvbiByZW1vdmVMYW5lcyhzZXQsIHN1YnNldCkge1xuICByZXR1cm4gc2V0ICYgfnN1YnNldDtcbn1cbmZ1bmN0aW9uIGludGVyc2VjdExhbmVzKGEsIGIpIHtcbiAgcmV0dXJuIGEgJiBiO1xufSAvLyBTZWVtcyByZWR1bmRhbnQsIGJ1dCBpdCBjaGFuZ2VzIHRoZSB0eXBlIGZyb20gYSBzaW5nbGUgbGFuZSAodXNlZCBmb3Jcbi8vIHVwZGF0ZXMpIHRvIGEgZ3JvdXAgb2YgbGFuZXMgKHVzZWQgZm9yIGZsdXNoaW5nIHdvcmspLlxuXG5mdW5jdGlvbiBsYW5lVG9MYW5lcyhsYW5lKSB7XG4gIHJldHVybiBsYW5lO1xufVxuZnVuY3Rpb24gaGlnaGVyUHJpb3JpdHlMYW5lKGEsIGIpIHtcbiAgLy8gVGhpcyB3b3JrcyBiZWNhdXNlIHRoZSBiaXQgcmFuZ2VzIGRlY3JlYXNlIGluIHByaW9yaXR5IGFzIHlvdSBnbyBsZWZ0LlxuICByZXR1cm4gYSAhPT0gTm9MYW5lICYmIGEgPCBiID8gYSA6IGI7XG59XG5mdW5jdGlvbiBjcmVhdGVMYW5lTWFwKGluaXRpYWwpIHtcbiAgLy8gSW50ZW50aW9uYWxseSBwdXNoaW5nIG9uZSBieSBvbmUuXG4gIC8vIGh0dHBzOi8vdjguZGV2L2Jsb2cvZWxlbWVudHMta2luZHMjYXZvaWQtY3JlYXRpbmctaG9sZXNcbiAgdmFyIGxhbmVNYXAgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IFRvdGFsTGFuZXM7IGkrKykge1xuICAgIGxhbmVNYXAucHVzaChpbml0aWFsKTtcbiAgfVxuXG4gIHJldHVybiBsYW5lTWFwO1xufVxuZnVuY3Rpb24gbWFya1Jvb3RVcGRhdGVkKHJvb3QsIHVwZGF0ZUxhbmUsIGV2ZW50VGltZSkge1xuICByb290LnBlbmRpbmdMYW5lcyB8PSB1cGRhdGVMYW5lOyAvLyBJZiB0aGVyZSBhcmUgYW55IHN1c3BlbmRlZCB0cmFuc2l0aW9ucywgaXQncyBwb3NzaWJsZSB0aGlzIG5ldyB1cGRhdGVcbiAgLy8gY291bGQgdW5ibG9jayB0aGVtLiBDbGVhciB0aGUgc3VzcGVuZGVkIGxhbmVzIHNvIHRoYXQgd2UgY2FuIHRyeSByZW5kZXJpbmdcbiAgLy8gdGhlbSBhZ2Fpbi5cbiAgLy9cbiAgLy8gVE9ETzogV2UgcmVhbGx5IG9ubHkgbmVlZCB0byB1bnN1c3BlbmQgb25seSBsYW5lcyB0aGF0IGFyZSBpbiB0aGVcbiAgLy8gYHN1YnRyZWVMYW5lc2Agb2YgdGhlIHVwZGF0ZWQgZmliZXIsIG9yIHRoZSB1cGRhdGUgbGFuZXMgb2YgdGhlIHJldHVyblxuICAvLyBwYXRoLiBUaGlzIHdvdWxkIGV4Y2x1ZGUgc3VzcGVuZGVkIHVwZGF0ZXMgaW4gYW4gdW5yZWxhdGVkIHNpYmxpbmcgdHJlZSxcbiAgLy8gc2luY2UgdGhlcmUncyBubyB3YXkgZm9yIHRoaXMgdXBkYXRlIHRvIHVuYmxvY2sgaXQuXG4gIC8vXG4gIC8vIFdlIGRvbid0IGRvIHRoaXMgaWYgdGhlIGluY29taW5nIHVwZGF0ZSBpcyBpZGxlLCBiZWNhdXNlIHdlIG5ldmVyIHByb2Nlc3NcbiAgLy8gaWRsZSB1cGRhdGVzIHVudGlsIGFmdGVyIGFsbCB0aGUgcmVndWxhciB1cGRhdGVzIGhhdmUgZmluaXNoZWQ7IHRoZXJlJ3Mgbm9cbiAgLy8gd2F5IGl0IGNvdWxkIHVuYmxvY2sgYSB0cmFuc2l0aW9uLlxuXG4gIGlmICh1cGRhdGVMYW5lICE9PSBJZGxlTGFuZSkge1xuICAgIHJvb3Quc3VzcGVuZGVkTGFuZXMgPSBOb0xhbmVzO1xuICAgIHJvb3QucGluZ2VkTGFuZXMgPSBOb0xhbmVzO1xuICB9XG5cbiAgdmFyIGV2ZW50VGltZXMgPSByb290LmV2ZW50VGltZXM7XG4gIHZhciBpbmRleCA9IGxhbmVUb0luZGV4KHVwZGF0ZUxhbmUpOyAvLyBXZSBjYW4gYWx3YXlzIG92ZXJ3cml0ZSBhbiBleGlzdGluZyB0aW1lc3RhbXAgYmVjYXVzZSB3ZSBwcmVmZXIgdGhlIG1vc3RcbiAgLy8gcmVjZW50IGV2ZW50LCBhbmQgd2UgYXNzdW1lIHRpbWUgaXMgbW9ub3RvbmljYWxseSBpbmNyZWFzaW5nLlxuXG4gIGV2ZW50VGltZXNbaW5kZXhdID0gZXZlbnRUaW1lO1xufVxuZnVuY3Rpb24gbWFya1Jvb3RTdXNwZW5kZWQocm9vdCwgc3VzcGVuZGVkTGFuZXMpIHtcbiAgcm9vdC5zdXNwZW5kZWRMYW5lcyB8PSBzdXNwZW5kZWRMYW5lcztcbiAgcm9vdC5waW5nZWRMYW5lcyAmPSB+c3VzcGVuZGVkTGFuZXM7IC8vIFRoZSBzdXNwZW5kZWQgbGFuZXMgYXJlIG5vIGxvbmdlciBDUFUtYm91bmQuIENsZWFyIHRoZWlyIGV4cGlyYXRpb24gdGltZXMuXG5cbiAgdmFyIGV4cGlyYXRpb25UaW1lcyA9IHJvb3QuZXhwaXJhdGlvblRpbWVzO1xuICB2YXIgbGFuZXMgPSBzdXNwZW5kZWRMYW5lcztcblxuICB3aGlsZSAobGFuZXMgPiAwKSB7XG4gICAgdmFyIGluZGV4ID0gcGlja0FyYml0cmFyeUxhbmVJbmRleChsYW5lcyk7XG4gICAgdmFyIGxhbmUgPSAxIDw8IGluZGV4O1xuICAgIGV4cGlyYXRpb25UaW1lc1tpbmRleF0gPSBOb1RpbWVzdGFtcDtcbiAgICBsYW5lcyAmPSB+bGFuZTtcbiAgfVxufVxuZnVuY3Rpb24gbWFya1Jvb3RQaW5nZWQocm9vdCwgcGluZ2VkTGFuZXMsIGV2ZW50VGltZSkge1xuICByb290LnBpbmdlZExhbmVzIHw9IHJvb3Quc3VzcGVuZGVkTGFuZXMgJiBwaW5nZWRMYW5lcztcbn1cbmZ1bmN0aW9uIG1hcmtSb290RmluaXNoZWQocm9vdCwgcmVtYWluaW5nTGFuZXMpIHtcbiAgdmFyIG5vTG9uZ2VyUGVuZGluZ0xhbmVzID0gcm9vdC5wZW5kaW5nTGFuZXMgJiB+cmVtYWluaW5nTGFuZXM7XG4gIHJvb3QucGVuZGluZ0xhbmVzID0gcmVtYWluaW5nTGFuZXM7IC8vIExldCdzIHRyeSBldmVyeXRoaW5nIGFnYWluXG5cbiAgcm9vdC5zdXNwZW5kZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHJvb3QucGluZ2VkTGFuZXMgPSBOb0xhbmVzO1xuICByb290LmV4cGlyZWRMYW5lcyAmPSByZW1haW5pbmdMYW5lcztcbiAgcm9vdC5tdXRhYmxlUmVhZExhbmVzICY9IHJlbWFpbmluZ0xhbmVzO1xuICByb290LmVudGFuZ2xlZExhbmVzICY9IHJlbWFpbmluZ0xhbmVzO1xuICB2YXIgZW50YW5nbGVtZW50cyA9IHJvb3QuZW50YW5nbGVtZW50cztcbiAgdmFyIGV2ZW50VGltZXMgPSByb290LmV2ZW50VGltZXM7XG4gIHZhciBleHBpcmF0aW9uVGltZXMgPSByb290LmV4cGlyYXRpb25UaW1lczsgLy8gQ2xlYXIgdGhlIGxhbmVzIHRoYXQgbm8gbG9uZ2VyIGhhdmUgcGVuZGluZyB3b3JrXG5cbiAgdmFyIGxhbmVzID0gbm9Mb25nZXJQZW5kaW5nTGFuZXM7XG5cbiAgd2hpbGUgKGxhbmVzID4gMCkge1xuICAgIHZhciBpbmRleCA9IHBpY2tBcmJpdHJhcnlMYW5lSW5kZXgobGFuZXMpO1xuICAgIHZhciBsYW5lID0gMSA8PCBpbmRleDtcbiAgICBlbnRhbmdsZW1lbnRzW2luZGV4XSA9IE5vTGFuZXM7XG4gICAgZXZlbnRUaW1lc1tpbmRleF0gPSBOb1RpbWVzdGFtcDtcbiAgICBleHBpcmF0aW9uVGltZXNbaW5kZXhdID0gTm9UaW1lc3RhbXA7XG4gICAgbGFuZXMgJj0gfmxhbmU7XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtSb290RW50YW5nbGVkKHJvb3QsIGVudGFuZ2xlZExhbmVzKSB7XG4gIC8vIEluIGFkZGl0aW9uIHRvIGVudGFuZ2xpbmcgZWFjaCBvZiB0aGUgZ2l2ZW4gbGFuZXMgd2l0aCBlYWNoIG90aGVyLCB3ZSBhbHNvXG4gIC8vIGhhdmUgdG8gY29uc2lkZXIgX3RyYW5zaXRpdmVfIGVudGFuZ2xlbWVudHMuIEZvciBlYWNoIGxhbmUgdGhhdCBpcyBhbHJlYWR5XG4gIC8vIGVudGFuZ2xlZCB3aXRoICphbnkqIG9mIHRoZSBnaXZlbiBsYW5lcywgdGhhdCBsYW5lIGlzIG5vdyB0cmFuc2l0aXZlbHlcbiAgLy8gZW50YW5nbGVkIHdpdGggKmFsbCogdGhlIGdpdmVuIGxhbmVzLlxuICAvL1xuICAvLyBUcmFuc2xhdGVkOiBJZiBDIGlzIGVudGFuZ2xlZCB3aXRoIEEsIHRoZW4gZW50YW5nbGluZyBBIHdpdGggQiBhbHNvXG4gIC8vIGVudGFuZ2xlcyBDIHdpdGggQi5cbiAgLy9cbiAgLy8gSWYgdGhpcyBpcyBoYXJkIHRvIGdyYXNwLCBpdCBtaWdodCBoZWxwIHRvIGludGVudGlvbmFsbHkgYnJlYWsgdGhpc1xuICAvLyBmdW5jdGlvbiBhbmQgbG9vayBhdCB0aGUgdGVzdHMgdGhhdCBmYWlsIGluIFJlYWN0VHJhbnNpdGlvbi10ZXN0LmpzLiBUcnlcbiAgLy8gY29tbWVudGluZyBvdXQgb25lIG9mIHRoZSBjb25kaXRpb25zIGJlbG93LlxuICB2YXIgcm9vdEVudGFuZ2xlZExhbmVzID0gcm9vdC5lbnRhbmdsZWRMYW5lcyB8PSBlbnRhbmdsZWRMYW5lcztcbiAgdmFyIGVudGFuZ2xlbWVudHMgPSByb290LmVudGFuZ2xlbWVudHM7XG4gIHZhciBsYW5lcyA9IHJvb3RFbnRhbmdsZWRMYW5lcztcblxuICB3aGlsZSAobGFuZXMpIHtcbiAgICB2YXIgaW5kZXggPSBwaWNrQXJiaXRyYXJ5TGFuZUluZGV4KGxhbmVzKTtcbiAgICB2YXIgbGFuZSA9IDEgPDwgaW5kZXg7XG5cbiAgICBpZiAoIC8vIElzIHRoaXMgb25lIG9mIHRoZSBuZXdseSBlbnRhbmdsZWQgbGFuZXM/XG4gICAgbGFuZSAmIGVudGFuZ2xlZExhbmVzIHwgLy8gSXMgdGhpcyBsYW5lIHRyYW5zaXRpdmVseSBlbnRhbmdsZWQgd2l0aCB0aGUgbmV3bHkgZW50YW5nbGVkIGxhbmVzP1xuICAgIGVudGFuZ2xlbWVudHNbaW5kZXhdICYgZW50YW5nbGVkTGFuZXMpIHtcbiAgICAgIGVudGFuZ2xlbWVudHNbaW5kZXhdIHw9IGVudGFuZ2xlZExhbmVzO1xuICAgIH1cblxuICAgIGxhbmVzICY9IH5sYW5lO1xuICB9XG59XG5mdW5jdGlvbiBnZXRCdW1wZWRMYW5lRm9ySHlkcmF0aW9uKHJvb3QsIHJlbmRlckxhbmVzKSB7XG4gIHZhciByZW5kZXJMYW5lID0gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZShyZW5kZXJMYW5lcyk7XG4gIHZhciBsYW5lO1xuXG4gIHN3aXRjaCAocmVuZGVyTGFuZSkge1xuICAgIGNhc2UgSW5wdXRDb250aW51b3VzTGFuZTpcbiAgICAgIGxhbmUgPSBJbnB1dENvbnRpbnVvdXNIeWRyYXRpb25MYW5lO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIERlZmF1bHRMYW5lOlxuICAgICAgbGFuZSA9IERlZmF1bHRIeWRyYXRpb25MYW5lO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMjpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMzpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNDpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNjpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNzpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lODpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lOTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTA6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTExOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxMjpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTM6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTE0OlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxNTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTY6XG4gICAgY2FzZSBSZXRyeUxhbmUxOlxuICAgIGNhc2UgUmV0cnlMYW5lMjpcbiAgICBjYXNlIFJldHJ5TGFuZTM6XG4gICAgY2FzZSBSZXRyeUxhbmU0OlxuICAgIGNhc2UgUmV0cnlMYW5lNTpcbiAgICAgIGxhbmUgPSBUcmFuc2l0aW9uSHlkcmF0aW9uTGFuZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBJZGxlTGFuZTpcbiAgICAgIGxhbmUgPSBJZGxlSHlkcmF0aW9uTGFuZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpcyBhbHJlYWR5IGVpdGhlciBhIGh5ZHJhdGlvbiBsYW5lLCBvciBzaG91bGRuJ3RcbiAgICAgIC8vIGJlIHJldHJpZWQgYXQgYSBoeWRyYXRpb24gbGFuZS5cbiAgICAgIGxhbmUgPSBOb0xhbmU7XG4gICAgICBicmVhaztcbiAgfSAvLyBDaGVjayBpZiB0aGUgbGFuZSB3ZSBjaG9zZSBpcyBzdXNwZW5kZWQuIElmIHNvLCB0aGF0IGluZGljYXRlcyB0aGF0IHdlXG4gIC8vIGFscmVhZHkgYXR0ZW1wdGVkIGFuZCBmYWlsZWQgdG8gaHlkcmF0ZSBhdCB0aGF0IGxldmVsLiBBbHNvIGNoZWNrIGlmIHdlJ3JlXG4gIC8vIGFscmVhZHkgcmVuZGVyaW5nIHRoYXQgbGFuZSwgd2hpY2ggaXMgcmFyZSBidXQgY291bGQgaGFwcGVuLlxuXG5cbiAgaWYgKChsYW5lICYgKHJvb3Quc3VzcGVuZGVkTGFuZXMgfCByZW5kZXJMYW5lcykpICE9PSBOb0xhbmUpIHtcbiAgICAvLyBHaXZlIHVwIHRyeWluZyB0byBoeWRyYXRlIGFuZCBmYWxsIGJhY2sgdG8gY2xpZW50IHJlbmRlci5cbiAgICByZXR1cm4gTm9MYW5lO1xuICB9XG5cbiAgcmV0dXJuIGxhbmU7XG59XG5mdW5jdGlvbiBhZGRGaWJlclRvTGFuZXNNYXAocm9vdCwgZmliZXIsIGxhbmVzKSB7XG5cbiAgaWYgKCFpc0RldlRvb2xzUHJlc2VudCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBwZW5kaW5nVXBkYXRlcnNMYW5lTWFwID0gcm9vdC5wZW5kaW5nVXBkYXRlcnNMYW5lTWFwO1xuXG4gIHdoaWxlIChsYW5lcyA+IDApIHtcbiAgICB2YXIgaW5kZXggPSBsYW5lVG9JbmRleChsYW5lcyk7XG4gICAgdmFyIGxhbmUgPSAxIDw8IGluZGV4O1xuICAgIHZhciB1cGRhdGVycyA9IHBlbmRpbmdVcGRhdGVyc0xhbmVNYXBbaW5kZXhdO1xuICAgIHVwZGF0ZXJzLmFkZChmaWJlcik7XG4gICAgbGFuZXMgJj0gfmxhbmU7XG4gIH1cbn1cbmZ1bmN0aW9uIG1vdmVQZW5kaW5nRmliZXJzVG9NZW1vaXplZChyb290LCBsYW5lcykge1xuXG4gIGlmICghaXNEZXZUb29sc1ByZXNlbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcGVuZGluZ1VwZGF0ZXJzTGFuZU1hcCA9IHJvb3QucGVuZGluZ1VwZGF0ZXJzTGFuZU1hcDtcbiAgdmFyIG1lbW9pemVkVXBkYXRlcnMgPSByb290Lm1lbW9pemVkVXBkYXRlcnM7XG5cbiAgd2hpbGUgKGxhbmVzID4gMCkge1xuICAgIHZhciBpbmRleCA9IGxhbmVUb0luZGV4KGxhbmVzKTtcbiAgICB2YXIgbGFuZSA9IDEgPDwgaW5kZXg7XG4gICAgdmFyIHVwZGF0ZXJzID0gcGVuZGluZ1VwZGF0ZXJzTGFuZU1hcFtpbmRleF07XG5cbiAgICBpZiAodXBkYXRlcnMuc2l6ZSA+IDApIHtcbiAgICAgIHVwZGF0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgICAgIHZhciBhbHRlcm5hdGUgPSBmaWJlci5hbHRlcm5hdGU7XG5cbiAgICAgICAgaWYgKGFsdGVybmF0ZSA9PT0gbnVsbCB8fCAhbWVtb2l6ZWRVcGRhdGVycy5oYXMoYWx0ZXJuYXRlKSkge1xuICAgICAgICAgIG1lbW9pemVkVXBkYXRlcnMuYWRkKGZpYmVyKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB1cGRhdGVycy5jbGVhcigpO1xuICAgIH1cblxuICAgIGxhbmVzICY9IH5sYW5lO1xuICB9XG59XG5mdW5jdGlvbiBnZXRUcmFuc2l0aW9uc0ZvckxhbmVzKHJvb3QsIGxhbmVzKSB7XG4gIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG52YXIgRGlzY3JldGVFdmVudFByaW9yaXR5ID0gU3luY0xhbmU7XG52YXIgQ29udGludW91c0V2ZW50UHJpb3JpdHkgPSBJbnB1dENvbnRpbnVvdXNMYW5lO1xudmFyIERlZmF1bHRFdmVudFByaW9yaXR5ID0gRGVmYXVsdExhbmU7XG52YXIgSWRsZUV2ZW50UHJpb3JpdHkgPSBJZGxlTGFuZTtcbnZhciBjdXJyZW50VXBkYXRlUHJpb3JpdHkgPSBOb0xhbmU7XG5mdW5jdGlvbiBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoKSB7XG4gIHJldHVybiBjdXJyZW50VXBkYXRlUHJpb3JpdHk7XG59XG5mdW5jdGlvbiBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkobmV3UHJpb3JpdHkpIHtcbiAgY3VycmVudFVwZGF0ZVByaW9yaXR5ID0gbmV3UHJpb3JpdHk7XG59XG5mdW5jdGlvbiBydW5XaXRoUHJpb3JpdHkocHJpb3JpdHksIGZuKSB7XG4gIHZhciBwcmV2aW91c1ByaW9yaXR5ID0gY3VycmVudFVwZGF0ZVByaW9yaXR5O1xuXG4gIHRyeSB7XG4gICAgY3VycmVudFVwZGF0ZVByaW9yaXR5ID0gcHJpb3JpdHk7XG4gICAgcmV0dXJuIGZuKCk7XG4gIH0gZmluYWxseSB7XG4gICAgY3VycmVudFVwZGF0ZVByaW9yaXR5ID0gcHJldmlvdXNQcmlvcml0eTtcbiAgfVxufVxuZnVuY3Rpb24gaGlnaGVyRXZlbnRQcmlvcml0eShhLCBiKSB7XG4gIHJldHVybiBhICE9PSAwICYmIGEgPCBiID8gYSA6IGI7XG59XG5mdW5jdGlvbiBsb3dlckV2ZW50UHJpb3JpdHkoYSwgYikge1xuICByZXR1cm4gYSA9PT0gMCB8fCBhID4gYiA/IGEgOiBiO1xufVxuZnVuY3Rpb24gaXNIaWdoZXJFdmVudFByaW9yaXR5KGEsIGIpIHtcbiAgcmV0dXJuIGEgIT09IDAgJiYgYSA8IGI7XG59XG5mdW5jdGlvbiBsYW5lc1RvRXZlbnRQcmlvcml0eShsYW5lcykge1xuICB2YXIgbGFuZSA9IGdldEhpZ2hlc3RQcmlvcml0eUxhbmUobGFuZXMpO1xuXG4gIGlmICghaXNIaWdoZXJFdmVudFByaW9yaXR5KERpc2NyZXRlRXZlbnRQcmlvcml0eSwgbGFuZSkpIHtcbiAgICByZXR1cm4gRGlzY3JldGVFdmVudFByaW9yaXR5O1xuICB9XG5cbiAgaWYgKCFpc0hpZ2hlckV2ZW50UHJpb3JpdHkoQ29udGludW91c0V2ZW50UHJpb3JpdHksIGxhbmUpKSB7XG4gICAgcmV0dXJuIENvbnRpbnVvdXNFdmVudFByaW9yaXR5O1xuICB9XG5cbiAgaWYgKGluY2x1ZGVzTm9uSWRsZVdvcmsobGFuZSkpIHtcbiAgICByZXR1cm4gRGVmYXVsdEV2ZW50UHJpb3JpdHk7XG4gIH1cblxuICByZXR1cm4gSWRsZUV2ZW50UHJpb3JpdHk7XG59XG5cbi8vIFRoaXMgaXMgaW1wb3J0ZWQgYnkgdGhlIGV2ZW50IHJlcGxheWluZyBpbXBsZW1lbnRhdGlvbiBpbiBSZWFjdCBET00uIEl0J3Ncbi8vIGluIGEgc2VwYXJhdGUgZmlsZSB0byBicmVhayBhIGNpcmN1bGFyIGRlcGVuZGVuY3kgYmV0d2VlbiB0aGUgcmVuZGVyZXIgYW5kXG4vLyB0aGUgcmVjb25jaWxlci5cbmZ1bmN0aW9uIGlzUm9vdERlaHlkcmF0ZWQocm9vdCkge1xuICB2YXIgY3VycmVudFN0YXRlID0gcm9vdC5jdXJyZW50Lm1lbW9pemVkU3RhdGU7XG4gIHJldHVybiBjdXJyZW50U3RhdGUuaXNEZWh5ZHJhdGVkO1xufVxuXG52YXIgX2F0dGVtcHRTeW5jaHJvbm91c0h5ZHJhdGlvbjtcblxuZnVuY3Rpb24gc2V0QXR0ZW1wdFN5bmNocm9ub3VzSHlkcmF0aW9uKGZuKSB7XG4gIF9hdHRlbXB0U3luY2hyb25vdXNIeWRyYXRpb24gPSBmbjtcbn1cbmZ1bmN0aW9uIGF0dGVtcHRTeW5jaHJvbm91c0h5ZHJhdGlvbihmaWJlcikge1xuICBfYXR0ZW1wdFN5bmNocm9ub3VzSHlkcmF0aW9uKGZpYmVyKTtcbn1cbnZhciBhdHRlbXB0Q29udGludW91c0h5ZHJhdGlvbjtcbmZ1bmN0aW9uIHNldEF0dGVtcHRDb250aW51b3VzSHlkcmF0aW9uKGZuKSB7XG4gIGF0dGVtcHRDb250aW51b3VzSHlkcmF0aW9uID0gZm47XG59XG52YXIgYXR0ZW1wdEh5ZHJhdGlvbkF0Q3VycmVudFByaW9yaXR5O1xuZnVuY3Rpb24gc2V0QXR0ZW1wdEh5ZHJhdGlvbkF0Q3VycmVudFByaW9yaXR5KGZuKSB7XG4gIGF0dGVtcHRIeWRyYXRpb25BdEN1cnJlbnRQcmlvcml0eSA9IGZuO1xufVxudmFyIGdldEN1cnJlbnRVcGRhdGVQcmlvcml0eSQxO1xuZnVuY3Rpb24gc2V0R2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KGZuKSB7XG4gIGdldEN1cnJlbnRVcGRhdGVQcmlvcml0eSQxID0gZm47XG59XG52YXIgYXR0ZW1wdEh5ZHJhdGlvbkF0UHJpb3JpdHk7XG5mdW5jdGlvbiBzZXRBdHRlbXB0SHlkcmF0aW9uQXRQcmlvcml0eShmbikge1xuICBhdHRlbXB0SHlkcmF0aW9uQXRQcmlvcml0eSA9IGZuO1xufSAvLyBUT0RPOiBVcGdyYWRlIHRoaXMgZGVmaW5pdGlvbiBvbmNlIHdlJ3JlIG9uIGEgbmV3ZXIgdmVyc2lvbiBvZiBGbG93IHRoYXRcbi8vIGhhcyB0aGlzIGRlZmluaXRpb24gYnVpbHQtaW4uXG5cbnZhciBoYXNTY2hlZHVsZWRSZXBsYXlBdHRlbXB0ID0gZmFsc2U7IC8vIFRoZSBxdWV1ZSBvZiBkaXNjcmV0ZSBldmVudHMgdG8gYmUgcmVwbGF5ZWQuXG5cbnZhciBxdWV1ZWREaXNjcmV0ZUV2ZW50cyA9IFtdOyAvLyBJbmRpY2F0ZXMgaWYgYW55IGNvbnRpbnVvdXMgZXZlbnQgdGFyZ2V0cyBhcmUgbm9uLW51bGwgZm9yIGVhcmx5IGJhaWxvdXQuXG4vLyBpZiB0aGUgbGFzdCB0YXJnZXQgd2FzIGRlaHlkcmF0ZWQuXG5cbnZhciBxdWV1ZWRGb2N1cyA9IG51bGw7XG52YXIgcXVldWVkRHJhZyA9IG51bGw7XG52YXIgcXVldWVkTW91c2UgPSBudWxsOyAvLyBGb3IgcG9pbnRlciBldmVudHMgdGhlcmUgY2FuIGJlIG9uZSBsYXRlc3QgZXZlbnQgcGVyIHBvaW50ZXJJZC5cblxudmFyIHF1ZXVlZFBvaW50ZXJzID0gbmV3IE1hcCgpO1xudmFyIHF1ZXVlZFBvaW50ZXJDYXB0dXJlcyA9IG5ldyBNYXAoKTsgLy8gV2UgY291bGQgY29uc2lkZXIgcmVwbGF5aW5nIHNlbGVjdGlvbmNoYW5nZSBhbmQgdG91Y2htb3ZlcyB0b28uXG5cbnZhciBxdWV1ZWRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldHMgPSBbXTtcbnZhciBkaXNjcmV0ZVJlcGxheWFibGVFdmVudHMgPSBbJ21vdXNlZG93bicsICdtb3VzZXVwJywgJ3RvdWNoY2FuY2VsJywgJ3RvdWNoZW5kJywgJ3RvdWNoc3RhcnQnLCAnYXV4Y2xpY2snLCAnZGJsY2xpY2snLCAncG9pbnRlcmNhbmNlbCcsICdwb2ludGVyZG93bicsICdwb2ludGVydXAnLCAnZHJhZ2VuZCcsICdkcmFnc3RhcnQnLCAnZHJvcCcsICdjb21wb3NpdGlvbmVuZCcsICdjb21wb3NpdGlvbnN0YXJ0JywgJ2tleWRvd24nLCAna2V5cHJlc3MnLCAna2V5dXAnLCAnaW5wdXQnLCAndGV4dElucHV0JywgLy8gSW50ZW50aW9uYWxseSBjYW1lbENhc2Vcbidjb3B5JywgJ2N1dCcsICdwYXN0ZScsICdjbGljaycsICdjaGFuZ2UnLCAnY29udGV4dG1lbnUnLCAncmVzZXQnLCAnc3VibWl0J107XG5mdW5jdGlvbiBpc0Rpc2NyZXRlRXZlbnRUaGF0UmVxdWlyZXNIeWRyYXRpb24oZXZlbnRUeXBlKSB7XG4gIHJldHVybiBkaXNjcmV0ZVJlcGxheWFibGVFdmVudHMuaW5kZXhPZihldmVudFR5cGUpID4gLTE7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVF1ZXVlZFJlcGxheWFibGVFdmVudChibG9ja2VkT24sIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCkge1xuICByZXR1cm4ge1xuICAgIGJsb2NrZWRPbjogYmxvY2tlZE9uLFxuICAgIGRvbUV2ZW50TmFtZTogZG9tRXZlbnROYW1lLFxuICAgIGV2ZW50U3lzdGVtRmxhZ3M6IGV2ZW50U3lzdGVtRmxhZ3MsXG4gICAgbmF0aXZlRXZlbnQ6IG5hdGl2ZUV2ZW50LFxuICAgIHRhcmdldENvbnRhaW5lcnM6IFt0YXJnZXRDb250YWluZXJdXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNsZWFySWZDb250aW51b3VzRXZlbnQoZG9tRXZlbnROYW1lLCBuYXRpdmVFdmVudCkge1xuICBzd2l0Y2ggKGRvbUV2ZW50TmFtZSkge1xuICAgIGNhc2UgJ2ZvY3VzaW4nOlxuICAgIGNhc2UgJ2ZvY3Vzb3V0JzpcbiAgICAgIHF1ZXVlZEZvY3VzID0gbnVsbDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnZHJhZ2VudGVyJzpcbiAgICBjYXNlICdkcmFnbGVhdmUnOlxuICAgICAgcXVldWVkRHJhZyA9IG51bGw7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ21vdXNlb3Zlcic6XG4gICAgY2FzZSAnbW91c2VvdXQnOlxuICAgICAgcXVldWVkTW91c2UgPSBudWxsO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdwb2ludGVyb3Zlcic6XG4gICAgY2FzZSAncG9pbnRlcm91dCc6XG4gICAgICB7XG4gICAgICAgIHZhciBwb2ludGVySWQgPSBuYXRpdmVFdmVudC5wb2ludGVySWQ7XG4gICAgICAgIHF1ZXVlZFBvaW50ZXJzLmRlbGV0ZShwb2ludGVySWQpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgJ2dvdHBvaW50ZXJjYXB0dXJlJzpcbiAgICBjYXNlICdsb3N0cG9pbnRlcmNhcHR1cmUnOlxuICAgICAge1xuICAgICAgICB2YXIgX3BvaW50ZXJJZCA9IG5hdGl2ZUV2ZW50LnBvaW50ZXJJZDtcbiAgICAgICAgcXVldWVkUG9pbnRlckNhcHR1cmVzLmRlbGV0ZShfcG9pbnRlcklkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWNjdW11bGF0ZU9yQ3JlYXRlQ29udGludW91c1F1ZXVlZFJlcGxheWFibGVFdmVudChleGlzdGluZ1F1ZXVlZEV2ZW50LCBibG9ja2VkT24sIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCkge1xuICBpZiAoZXhpc3RpbmdRdWV1ZWRFdmVudCA9PT0gbnVsbCB8fCBleGlzdGluZ1F1ZXVlZEV2ZW50Lm5hdGl2ZUV2ZW50ICE9PSBuYXRpdmVFdmVudCkge1xuICAgIHZhciBxdWV1ZWRFdmVudCA9IGNyZWF0ZVF1ZXVlZFJlcGxheWFibGVFdmVudChibG9ja2VkT24sIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCk7XG5cbiAgICBpZiAoYmxvY2tlZE9uICE9PSBudWxsKSB7XG4gICAgICB2YXIgX2ZpYmVyMiA9IGdldEluc3RhbmNlRnJvbU5vZGUoYmxvY2tlZE9uKTtcblxuICAgICAgaWYgKF9maWJlcjIgIT09IG51bGwpIHtcbiAgICAgICAgLy8gQXR0ZW1wdCB0byBpbmNyZWFzZSB0aGUgcHJpb3JpdHkgb2YgdGhpcyB0YXJnZXQuXG4gICAgICAgIGF0dGVtcHRDb250aW51b3VzSHlkcmF0aW9uKF9maWJlcjIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBxdWV1ZWRFdmVudDtcbiAgfSAvLyBJZiB3ZSBoYXZlIGFscmVhZHkgcXVldWVkIHRoaXMgZXhhY3QgZXZlbnQsIHRoZW4gaXQncyBiZWNhdXNlXG4gIC8vIHRoZSBkaWZmZXJlbnQgZXZlbnQgc3lzdGVtcyBoYXZlIGRpZmZlcmVudCBET00gZXZlbnQgbGlzdGVuZXJzLlxuICAvLyBXZSBjYW4gYWNjdW11bGF0ZSB0aGUgZmxhZ3MsIGFuZCB0aGUgdGFyZ2V0Q29udGFpbmVycywgYW5kXG4gIC8vIHN0b3JlIGEgc2luZ2xlIGV2ZW50IHRvIGJlIHJlcGxheWVkLlxuXG5cbiAgZXhpc3RpbmdRdWV1ZWRFdmVudC5ldmVudFN5c3RlbUZsYWdzIHw9IGV2ZW50U3lzdGVtRmxhZ3M7XG4gIHZhciB0YXJnZXRDb250YWluZXJzID0gZXhpc3RpbmdRdWV1ZWRFdmVudC50YXJnZXRDb250YWluZXJzO1xuXG4gIGlmICh0YXJnZXRDb250YWluZXIgIT09IG51bGwgJiYgdGFyZ2V0Q29udGFpbmVycy5pbmRleE9mKHRhcmdldENvbnRhaW5lcikgPT09IC0xKSB7XG4gICAgdGFyZ2V0Q29udGFpbmVycy5wdXNoKHRhcmdldENvbnRhaW5lcik7XG4gIH1cblxuICByZXR1cm4gZXhpc3RpbmdRdWV1ZWRFdmVudDtcbn1cblxuZnVuY3Rpb24gcXVldWVJZkNvbnRpbnVvdXNFdmVudChibG9ja2VkT24sIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCkge1xuICAvLyBUaGVzZSBzZXQgcmVsYXRlZFRhcmdldCB0byBudWxsIGJlY2F1c2UgdGhlIHJlcGxheWVkIGV2ZW50IHdpbGwgYmUgdHJlYXRlZCBhcyBpZiB3ZVxuICAvLyBtb3ZlZCBmcm9tIG91dHNpZGUgdGhlIHdpbmRvdyAobm8gdGFyZ2V0KSBvbnRvIHRoZSB0YXJnZXQgb25jZSBpdCBoeWRyYXRlcy5cbiAgLy8gSW5zdGVhZCBvZiBtdXRhdGluZyB3ZSBjb3VsZCBjbG9uZSB0aGUgZXZlbnQuXG4gIHN3aXRjaCAoZG9tRXZlbnROYW1lKSB7XG4gICAgY2FzZSAnZm9jdXNpbic6XG4gICAgICB7XG4gICAgICAgIHZhciBmb2N1c0V2ZW50ID0gbmF0aXZlRXZlbnQ7XG4gICAgICAgIHF1ZXVlZEZvY3VzID0gYWNjdW11bGF0ZU9yQ3JlYXRlQ29udGludW91c1F1ZXVlZFJlcGxheWFibGVFdmVudChxdWV1ZWRGb2N1cywgYmxvY2tlZE9uLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgZm9jdXNFdmVudCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgY2FzZSAnZHJhZ2VudGVyJzpcbiAgICAgIHtcbiAgICAgICAgdmFyIGRyYWdFdmVudCA9IG5hdGl2ZUV2ZW50O1xuICAgICAgICBxdWV1ZWREcmFnID0gYWNjdW11bGF0ZU9yQ3JlYXRlQ29udGludW91c1F1ZXVlZFJlcGxheWFibGVFdmVudChxdWV1ZWREcmFnLCBibG9ja2VkT24sIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBkcmFnRXZlbnQpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgIGNhc2UgJ21vdXNlb3Zlcic6XG4gICAgICB7XG4gICAgICAgIHZhciBtb3VzZUV2ZW50ID0gbmF0aXZlRXZlbnQ7XG4gICAgICAgIHF1ZXVlZE1vdXNlID0gYWNjdW11bGF0ZU9yQ3JlYXRlQ29udGludW91c1F1ZXVlZFJlcGxheWFibGVFdmVudChxdWV1ZWRNb3VzZSwgYmxvY2tlZE9uLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgbW91c2VFdmVudCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgY2FzZSAncG9pbnRlcm92ZXInOlxuICAgICAge1xuICAgICAgICB2YXIgcG9pbnRlckV2ZW50ID0gbmF0aXZlRXZlbnQ7XG4gICAgICAgIHZhciBwb2ludGVySWQgPSBwb2ludGVyRXZlbnQucG9pbnRlcklkO1xuICAgICAgICBxdWV1ZWRQb2ludGVycy5zZXQocG9pbnRlcklkLCBhY2N1bXVsYXRlT3JDcmVhdGVDb250aW51b3VzUXVldWVkUmVwbGF5YWJsZUV2ZW50KHF1ZXVlZFBvaW50ZXJzLmdldChwb2ludGVySWQpIHx8IG51bGwsIGJsb2NrZWRPbiwgZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIsIHBvaW50ZXJFdmVudCkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgIGNhc2UgJ2dvdHBvaW50ZXJjYXB0dXJlJzpcbiAgICAgIHtcbiAgICAgICAgdmFyIF9wb2ludGVyRXZlbnQgPSBuYXRpdmVFdmVudDtcbiAgICAgICAgdmFyIF9wb2ludGVySWQyID0gX3BvaW50ZXJFdmVudC5wb2ludGVySWQ7XG4gICAgICAgIHF1ZXVlZFBvaW50ZXJDYXB0dXJlcy5zZXQoX3BvaW50ZXJJZDIsIGFjY3VtdWxhdGVPckNyZWF0ZUNvbnRpbnVvdXNRdWV1ZWRSZXBsYXlhYmxlRXZlbnQocXVldWVkUG9pbnRlckNhcHR1cmVzLmdldChfcG9pbnRlcklkMikgfHwgbnVsbCwgYmxvY2tlZE9uLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgX3BvaW50ZXJFdmVudCkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn0gLy8gQ2hlY2sgaWYgdGhpcyB0YXJnZXQgaXMgdW5ibG9ja2VkLiBSZXR1cm5zIHRydWUgaWYgaXQncyB1bmJsb2NrZWQuXG5cbmZ1bmN0aW9uIGF0dGVtcHRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldChxdWV1ZWRUYXJnZXQpIHtcbiAgLy8gVE9ETzogVGhpcyBmdW5jdGlvbiBzaGFyZXMgYSBsb3Qgb2YgbG9naWMgd2l0aCBmaW5kSW5zdGFuY2VCbG9ja2luZ0V2ZW50LlxuICAvLyBUcnkgdG8gdW5pZnkgdGhlbS4gSXQncyBhIGJpdCB0cmlja3kgc2luY2UgaXQgd291bGQgcmVxdWlyZSB0d28gcmV0dXJuXG4gIC8vIHZhbHVlcy5cbiAgdmFyIHRhcmdldEluc3QgPSBnZXRDbG9zZXN0SW5zdGFuY2VGcm9tTm9kZShxdWV1ZWRUYXJnZXQudGFyZ2V0KTtcblxuICBpZiAodGFyZ2V0SW5zdCAhPT0gbnVsbCkge1xuICAgIHZhciBuZWFyZXN0TW91bnRlZCA9IGdldE5lYXJlc3RNb3VudGVkRmliZXIodGFyZ2V0SW5zdCk7XG5cbiAgICBpZiAobmVhcmVzdE1vdW50ZWQgIT09IG51bGwpIHtcbiAgICAgIHZhciB0YWcgPSBuZWFyZXN0TW91bnRlZC50YWc7XG5cbiAgICAgIGlmICh0YWcgPT09IFN1c3BlbnNlQ29tcG9uZW50KSB7XG4gICAgICAgIHZhciBpbnN0YW5jZSA9IGdldFN1c3BlbnNlSW5zdGFuY2VGcm9tRmliZXIobmVhcmVzdE1vdW50ZWQpO1xuXG4gICAgICAgIGlmIChpbnN0YW5jZSAhPT0gbnVsbCkge1xuICAgICAgICAgIC8vIFdlJ3JlIGJsb2NrZWQgb24gaHlkcmF0aW5nIHRoaXMgYm91bmRhcnkuXG4gICAgICAgICAgLy8gSW5jcmVhc2UgaXRzIHByaW9yaXR5LlxuICAgICAgICAgIHF1ZXVlZFRhcmdldC5ibG9ja2VkT24gPSBpbnN0YW5jZTtcbiAgICAgICAgICBhdHRlbXB0SHlkcmF0aW9uQXRQcmlvcml0eShxdWV1ZWRUYXJnZXQucHJpb3JpdHksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGF0dGVtcHRIeWRyYXRpb25BdEN1cnJlbnRQcmlvcml0eShuZWFyZXN0TW91bnRlZCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRhZyA9PT0gSG9zdFJvb3QpIHtcbiAgICAgICAgdmFyIHJvb3QgPSBuZWFyZXN0TW91bnRlZC5zdGF0ZU5vZGU7XG5cbiAgICAgICAgaWYgKGlzUm9vdERlaHlkcmF0ZWQocm9vdCkpIHtcbiAgICAgICAgICBxdWV1ZWRUYXJnZXQuYmxvY2tlZE9uID0gZ2V0Q29udGFpbmVyRnJvbUZpYmVyKG5lYXJlc3RNb3VudGVkKTsgLy8gV2UgZG9uJ3QgY3VycmVudGx5IGhhdmUgYSB3YXkgdG8gaW5jcmVhc2UgdGhlIHByaW9yaXR5IG9mXG4gICAgICAgICAgLy8gYSByb290IG90aGVyIHRoYW4gc3luYy5cblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHF1ZXVlZFRhcmdldC5ibG9ja2VkT24gPSBudWxsO1xufVxuXG5mdW5jdGlvbiBxdWV1ZUV4cGxpY2l0SHlkcmF0aW9uVGFyZ2V0KHRhcmdldCkge1xuICAvLyBUT0RPOiBUaGlzIHdpbGwgcmVhZCB0aGUgcHJpb3JpdHkgaWYgaXQncyBkaXNwYXRjaGVkIGJ5IHRoZSBSZWFjdFxuICAvLyBldmVudCBzeXN0ZW0gYnV0IG5vdCBuYXRpdmUgZXZlbnRzLiBTaG91bGQgcmVhZCB3aW5kb3cuZXZlbnQudHlwZSwgbGlrZVxuICAvLyB3ZSBkbyBmb3IgdXBkYXRlcyAoZ2V0Q3VycmVudEV2ZW50UHJpb3JpdHkpLlxuICB2YXIgdXBkYXRlUHJpb3JpdHkgPSBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkkMSgpO1xuICB2YXIgcXVldWVkVGFyZ2V0ID0ge1xuICAgIGJsb2NrZWRPbjogbnVsbCxcbiAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICBwcmlvcml0eTogdXBkYXRlUHJpb3JpdHlcbiAgfTtcbiAgdmFyIGkgPSAwO1xuXG4gIGZvciAoOyBpIDwgcXVldWVkRXhwbGljaXRIeWRyYXRpb25UYXJnZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgLy8gU3RvcCBvbmNlIHdlIGhpdCB0aGUgZmlyc3QgdGFyZ2V0IHdpdGggbG93ZXIgcHJpb3JpdHkgdGhhblxuICAgIGlmICghaXNIaWdoZXJFdmVudFByaW9yaXR5KHVwZGF0ZVByaW9yaXR5LCBxdWV1ZWRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldHNbaV0ucHJpb3JpdHkpKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBxdWV1ZWRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldHMuc3BsaWNlKGksIDAsIHF1ZXVlZFRhcmdldCk7XG5cbiAgaWYgKGkgPT09IDApIHtcbiAgICBhdHRlbXB0RXhwbGljaXRIeWRyYXRpb25UYXJnZXQocXVldWVkVGFyZ2V0KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhdHRlbXB0UmVwbGF5Q29udGludW91c1F1ZXVlZEV2ZW50KHF1ZXVlZEV2ZW50KSB7XG4gIGlmIChxdWV1ZWRFdmVudC5ibG9ja2VkT24gIT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgdGFyZ2V0Q29udGFpbmVycyA9IHF1ZXVlZEV2ZW50LnRhcmdldENvbnRhaW5lcnM7XG5cbiAgd2hpbGUgKHRhcmdldENvbnRhaW5lcnMubGVuZ3RoID4gMCkge1xuICAgIHZhciB0YXJnZXRDb250YWluZXIgPSB0YXJnZXRDb250YWluZXJzWzBdO1xuICAgIHZhciBuZXh0QmxvY2tlZE9uID0gZmluZEluc3RhbmNlQmxvY2tpbmdFdmVudChxdWV1ZWRFdmVudC5kb21FdmVudE5hbWUsIHF1ZXVlZEV2ZW50LmV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgcXVldWVkRXZlbnQubmF0aXZlRXZlbnQpO1xuXG4gICAgaWYgKG5leHRCbG9ja2VkT24gPT09IG51bGwpIHtcbiAgICAgIHtcbiAgICAgICAgdmFyIG5hdGl2ZUV2ZW50ID0gcXVldWVkRXZlbnQubmF0aXZlRXZlbnQ7XG4gICAgICAgIHZhciBuYXRpdmVFdmVudENsb25lID0gbmV3IG5hdGl2ZUV2ZW50LmNvbnN0cnVjdG9yKG5hdGl2ZUV2ZW50LnR5cGUsIG5hdGl2ZUV2ZW50KTtcbiAgICAgICAgc2V0UmVwbGF5aW5nRXZlbnQobmF0aXZlRXZlbnRDbG9uZSk7XG4gICAgICAgIG5hdGl2ZUV2ZW50LnRhcmdldC5kaXNwYXRjaEV2ZW50KG5hdGl2ZUV2ZW50Q2xvbmUpO1xuICAgICAgICByZXNldFJlcGxheWluZ0V2ZW50KCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFdlJ3JlIHN0aWxsIGJsb2NrZWQuIFRyeSBhZ2FpbiBsYXRlci5cbiAgICAgIHZhciBfZmliZXIzID0gZ2V0SW5zdGFuY2VGcm9tTm9kZShuZXh0QmxvY2tlZE9uKTtcblxuICAgICAgaWYgKF9maWJlcjMgIT09IG51bGwpIHtcbiAgICAgICAgYXR0ZW1wdENvbnRpbnVvdXNIeWRyYXRpb24oX2ZpYmVyMyk7XG4gICAgICB9XG5cbiAgICAgIHF1ZXVlZEV2ZW50LmJsb2NrZWRPbiA9IG5leHRCbG9ja2VkT247XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSAvLyBUaGlzIHRhcmdldCBjb250YWluZXIgd2FzIHN1Y2Nlc3NmdWxseSBkaXNwYXRjaGVkLiBUcnkgdGhlIG5leHQuXG5cblxuICAgIHRhcmdldENvbnRhaW5lcnMuc2hpZnQoKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBhdHRlbXB0UmVwbGF5Q29udGludW91c1F1ZXVlZEV2ZW50SW5NYXAocXVldWVkRXZlbnQsIGtleSwgbWFwKSB7XG4gIGlmIChhdHRlbXB0UmVwbGF5Q29udGludW91c1F1ZXVlZEV2ZW50KHF1ZXVlZEV2ZW50KSkge1xuICAgIG1hcC5kZWxldGUoa2V5KTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXBsYXlVbmJsb2NrZWRFdmVudHMoKSB7XG4gIGhhc1NjaGVkdWxlZFJlcGxheUF0dGVtcHQgPSBmYWxzZTtcblxuXG4gIGlmIChxdWV1ZWRGb2N1cyAhPT0gbnVsbCAmJiBhdHRlbXB0UmVwbGF5Q29udGludW91c1F1ZXVlZEV2ZW50KHF1ZXVlZEZvY3VzKSkge1xuICAgIHF1ZXVlZEZvY3VzID0gbnVsbDtcbiAgfVxuXG4gIGlmIChxdWV1ZWREcmFnICE9PSBudWxsICYmIGF0dGVtcHRSZXBsYXlDb250aW51b3VzUXVldWVkRXZlbnQocXVldWVkRHJhZykpIHtcbiAgICBxdWV1ZWREcmFnID0gbnVsbDtcbiAgfVxuXG4gIGlmIChxdWV1ZWRNb3VzZSAhPT0gbnVsbCAmJiBhdHRlbXB0UmVwbGF5Q29udGludW91c1F1ZXVlZEV2ZW50KHF1ZXVlZE1vdXNlKSkge1xuICAgIHF1ZXVlZE1vdXNlID0gbnVsbDtcbiAgfVxuXG4gIHF1ZXVlZFBvaW50ZXJzLmZvckVhY2goYXR0ZW1wdFJlcGxheUNvbnRpbnVvdXNRdWV1ZWRFdmVudEluTWFwKTtcbiAgcXVldWVkUG9pbnRlckNhcHR1cmVzLmZvckVhY2goYXR0ZW1wdFJlcGxheUNvbnRpbnVvdXNRdWV1ZWRFdmVudEluTWFwKTtcbn1cblxuZnVuY3Rpb24gc2NoZWR1bGVDYWxsYmFja0lmVW5ibG9ja2VkKHF1ZXVlZEV2ZW50LCB1bmJsb2NrZWQpIHtcbiAgaWYgKHF1ZXVlZEV2ZW50LmJsb2NrZWRPbiA9PT0gdW5ibG9ja2VkKSB7XG4gICAgcXVldWVkRXZlbnQuYmxvY2tlZE9uID0gbnVsbDtcblxuICAgIGlmICghaGFzU2NoZWR1bGVkUmVwbGF5QXR0ZW1wdCkge1xuICAgICAgaGFzU2NoZWR1bGVkUmVwbGF5QXR0ZW1wdCA9IHRydWU7IC8vIFNjaGVkdWxlIGEgY2FsbGJhY2sgdG8gYXR0ZW1wdCByZXBsYXlpbmcgYXMgbWFueSBldmVudHMgYXMgYXJlXG4gICAgICAvLyBub3cgdW5ibG9ja2VkLiBUaGlzIGZpcnN0IG1pZ2h0IG5vdCBhY3R1YWxseSBiZSB1bmJsb2NrZWQgeWV0LlxuICAgICAgLy8gV2UgY291bGQgY2hlY2sgaXQgZWFybHkgdG8gYXZvaWQgc2NoZWR1bGluZyBhbiB1bm5lY2Vzc2FyeSBjYWxsYmFjay5cblxuICAgICAgU2NoZWR1bGVyLnVuc3RhYmxlX3NjaGVkdWxlQ2FsbGJhY2soU2NoZWR1bGVyLnVuc3RhYmxlX05vcm1hbFByaW9yaXR5LCByZXBsYXlVbmJsb2NrZWRFdmVudHMpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZXRyeUlmQmxvY2tlZE9uKHVuYmxvY2tlZCkge1xuICAvLyBNYXJrIGFueXRoaW5nIHRoYXQgd2FzIGJsb2NrZWQgb24gdGhpcyBhcyBubyBsb25nZXIgYmxvY2tlZFxuICAvLyBhbmQgZWxpZ2libGUgZm9yIGEgcmVwbGF5LlxuICBpZiAocXVldWVkRGlzY3JldGVFdmVudHMubGVuZ3RoID4gMCkge1xuICAgIHNjaGVkdWxlQ2FsbGJhY2tJZlVuYmxvY2tlZChxdWV1ZWREaXNjcmV0ZUV2ZW50c1swXSwgdW5ibG9ja2VkKTsgLy8gVGhpcyBpcyBhIGV4cG9uZW50aWFsIHNlYXJjaCBmb3IgZWFjaCBib3VuZGFyeSB0aGF0IGNvbW1pdHMuIEkgdGhpbmsgaXQnc1xuICAgIC8vIHdvcnRoIGl0IGJlY2F1c2Ugd2UgZXhwZWN0IHZlcnkgZmV3IGRpc2NyZXRlIGV2ZW50cyB0byBxdWV1ZSB1cCBhbmQgb25jZVxuICAgIC8vIHdlIGFyZSBhY3R1YWxseSBmdWxseSB1bmJsb2NrZWQgaXQgd2lsbCBiZSBmYXN0IHRvIHJlcGxheSB0aGVtLlxuXG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBxdWV1ZWREaXNjcmV0ZUV2ZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHF1ZXVlZEV2ZW50ID0gcXVldWVkRGlzY3JldGVFdmVudHNbaV07XG5cbiAgICAgIGlmIChxdWV1ZWRFdmVudC5ibG9ja2VkT24gPT09IHVuYmxvY2tlZCkge1xuICAgICAgICBxdWV1ZWRFdmVudC5ibG9ja2VkT24gPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChxdWV1ZWRGb2N1cyAhPT0gbnVsbCkge1xuICAgIHNjaGVkdWxlQ2FsbGJhY2tJZlVuYmxvY2tlZChxdWV1ZWRGb2N1cywgdW5ibG9ja2VkKTtcbiAgfVxuXG4gIGlmIChxdWV1ZWREcmFnICE9PSBudWxsKSB7XG4gICAgc2NoZWR1bGVDYWxsYmFja0lmVW5ibG9ja2VkKHF1ZXVlZERyYWcsIHVuYmxvY2tlZCk7XG4gIH1cblxuICBpZiAocXVldWVkTW91c2UgIT09IG51bGwpIHtcbiAgICBzY2hlZHVsZUNhbGxiYWNrSWZVbmJsb2NrZWQocXVldWVkTW91c2UsIHVuYmxvY2tlZCk7XG4gIH1cblxuICB2YXIgdW5ibG9jayA9IGZ1bmN0aW9uIChxdWV1ZWRFdmVudCkge1xuICAgIHJldHVybiBzY2hlZHVsZUNhbGxiYWNrSWZVbmJsb2NrZWQocXVldWVkRXZlbnQsIHVuYmxvY2tlZCk7XG4gIH07XG5cbiAgcXVldWVkUG9pbnRlcnMuZm9yRWFjaCh1bmJsb2NrKTtcbiAgcXVldWVkUG9pbnRlckNhcHR1cmVzLmZvckVhY2godW5ibG9jayk7XG5cbiAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IHF1ZXVlZEV4cGxpY2l0SHlkcmF0aW9uVGFyZ2V0cy5sZW5ndGg7IF9pKyspIHtcbiAgICB2YXIgcXVldWVkVGFyZ2V0ID0gcXVldWVkRXhwbGljaXRIeWRyYXRpb25UYXJnZXRzW19pXTtcblxuICAgIGlmIChxdWV1ZWRUYXJnZXQuYmxvY2tlZE9uID09PSB1bmJsb2NrZWQpIHtcbiAgICAgIHF1ZXVlZFRhcmdldC5ibG9ja2VkT24gPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHdoaWxlIChxdWV1ZWRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldHMubGVuZ3RoID4gMCkge1xuICAgIHZhciBuZXh0RXhwbGljaXRUYXJnZXQgPSBxdWV1ZWRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldHNbMF07XG5cbiAgICBpZiAobmV4dEV4cGxpY2l0VGFyZ2V0LmJsb2NrZWRPbiAhPT0gbnVsbCkge1xuICAgICAgLy8gV2UncmUgc3RpbGwgYmxvY2tlZC5cbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSB7XG4gICAgICBhdHRlbXB0RXhwbGljaXRIeWRyYXRpb25UYXJnZXQobmV4dEV4cGxpY2l0VGFyZ2V0KTtcblxuICAgICAgaWYgKG5leHRFeHBsaWNpdFRhcmdldC5ibG9ja2VkT24gPT09IG51bGwpIHtcbiAgICAgICAgLy8gV2UncmUgdW5ibG9ja2VkLlxuICAgICAgICBxdWV1ZWRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldHMuc2hpZnQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3RDdXJyZW50QmF0Y2hDb25maWc7IC8vIFRPRE86IGNhbiB3ZSBzdG9wIGV4cG9ydGluZyB0aGVzZT9cblxudmFyIF9lbmFibGVkID0gdHJ1ZTsgLy8gVGhpcyBpcyBleHBvcnRlZCBpbiBGQiBidWlsZHMgZm9yIHVzZSBieSBsZWdhY3kgRkIgbGF5ZXIgaW5mcmEuXG4vLyBXZSdkIGxpa2UgdG8gcmVtb3ZlIHRoaXMgYnV0IGl0J3Mgbm90IGNsZWFyIGlmIHRoaXMgaXMgc2FmZS5cblxuZnVuY3Rpb24gc2V0RW5hYmxlZChlbmFibGVkKSB7XG4gIF9lbmFibGVkID0gISFlbmFibGVkO1xufVxuZnVuY3Rpb24gaXNFbmFibGVkKCkge1xuICByZXR1cm4gX2VuYWJsZWQ7XG59XG5mdW5jdGlvbiBjcmVhdGVFdmVudExpc3RlbmVyV3JhcHBlcldpdGhQcmlvcml0eSh0YXJnZXRDb250YWluZXIsIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncykge1xuICB2YXIgZXZlbnRQcmlvcml0eSA9IGdldEV2ZW50UHJpb3JpdHkoZG9tRXZlbnROYW1lKTtcbiAgdmFyIGxpc3RlbmVyV3JhcHBlcjtcblxuICBzd2l0Y2ggKGV2ZW50UHJpb3JpdHkpIHtcbiAgICBjYXNlIERpc2NyZXRlRXZlbnRQcmlvcml0eTpcbiAgICAgIGxpc3RlbmVyV3JhcHBlciA9IGRpc3BhdGNoRGlzY3JldGVFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBDb250aW51b3VzRXZlbnRQcmlvcml0eTpcbiAgICAgIGxpc3RlbmVyV3JhcHBlciA9IGRpc3BhdGNoQ29udGludW91c0V2ZW50O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIERlZmF1bHRFdmVudFByaW9yaXR5OlxuICAgIGRlZmF1bHQ6XG4gICAgICBsaXN0ZW5lcldyYXBwZXIgPSBkaXNwYXRjaEV2ZW50O1xuICAgICAgYnJlYWs7XG4gIH1cblxuICByZXR1cm4gbGlzdGVuZXJXcmFwcGVyLmJpbmQobnVsbCwgZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIpO1xufVxuXG5mdW5jdGlvbiBkaXNwYXRjaERpc2NyZXRlRXZlbnQoZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCBjb250YWluZXIsIG5hdGl2ZUV2ZW50KSB7XG4gIHZhciBwcmV2aW91c1ByaW9yaXR5ID0gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KCk7XG4gIHZhciBwcmV2VHJhbnNpdGlvbiA9IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb247XG4gIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb24gPSBudWxsO1xuXG4gIHRyeSB7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KERpc2NyZXRlRXZlbnRQcmlvcml0eSk7XG4gICAgZGlzcGF0Y2hFdmVudChkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIGNvbnRhaW5lciwgbmF0aXZlRXZlbnQpO1xuICB9IGZpbmFsbHkge1xuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmV2aW91c1ByaW9yaXR5KTtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZy50cmFuc2l0aW9uID0gcHJldlRyYW5zaXRpb247XG4gIH1cbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hDb250aW51b3VzRXZlbnQoZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCBjb250YWluZXIsIG5hdGl2ZUV2ZW50KSB7XG4gIHZhciBwcmV2aW91c1ByaW9yaXR5ID0gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KCk7XG4gIHZhciBwcmV2VHJhbnNpdGlvbiA9IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb247XG4gIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb24gPSBudWxsO1xuXG4gIHRyeSB7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KENvbnRpbnVvdXNFdmVudFByaW9yaXR5KTtcbiAgICBkaXNwYXRjaEV2ZW50KGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgY29udGFpbmVyLCBuYXRpdmVFdmVudCk7XG4gIH0gZmluYWxseSB7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KHByZXZpb3VzUHJpb3JpdHkpO1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb24gPSBwcmV2VHJhbnNpdGlvbjtcbiAgfVxufVxuXG5mdW5jdGlvbiBkaXNwYXRjaEV2ZW50KGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCkge1xuICBpZiAoIV9lbmFibGVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAge1xuICAgIGRpc3BhdGNoRXZlbnRXaXRoRW5hYmxlQ2FwdHVyZVBoYXNlU2VsZWN0aXZlSHlkcmF0aW9uV2l0aG91dERpc2NyZXRlRXZlbnRSZXBsYXkoZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIsIG5hdGl2ZUV2ZW50KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkaXNwYXRjaEV2ZW50V2l0aEVuYWJsZUNhcHR1cmVQaGFzZVNlbGVjdGl2ZUh5ZHJhdGlvbldpdGhvdXREaXNjcmV0ZUV2ZW50UmVwbGF5KGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCkge1xuICB2YXIgYmxvY2tlZE9uID0gZmluZEluc3RhbmNlQmxvY2tpbmdFdmVudChkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgbmF0aXZlRXZlbnQpO1xuXG4gIGlmIChibG9ja2VkT24gPT09IG51bGwpIHtcbiAgICBkaXNwYXRjaEV2ZW50Rm9yUGx1Z2luRXZlbnRTeXN0ZW0oZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCBuYXRpdmVFdmVudCwgcmV0dXJuX3RhcmdldEluc3QsIHRhcmdldENvbnRhaW5lcik7XG4gICAgY2xlYXJJZkNvbnRpbnVvdXNFdmVudChkb21FdmVudE5hbWUsIG5hdGl2ZUV2ZW50KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAocXVldWVJZkNvbnRpbnVvdXNFdmVudChibG9ja2VkT24sIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCkpIHtcbiAgICBuYXRpdmVFdmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICByZXR1cm47XG4gIH0gLy8gV2UgbmVlZCB0byBjbGVhciBvbmx5IGlmIHdlIGRpZG4ndCBxdWV1ZSBiZWNhdXNlXG4gIC8vIHF1ZXVlaW5nIGlzIGFjY3VtdWxhdGl2ZS5cblxuXG4gIGNsZWFySWZDb250aW51b3VzRXZlbnQoZG9tRXZlbnROYW1lLCBuYXRpdmVFdmVudCk7XG5cbiAgaWYgKGV2ZW50U3lzdGVtRmxhZ3MgJiBJU19DQVBUVVJFX1BIQVNFICYmIGlzRGlzY3JldGVFdmVudFRoYXRSZXF1aXJlc0h5ZHJhdGlvbihkb21FdmVudE5hbWUpKSB7XG4gICAgd2hpbGUgKGJsb2NrZWRPbiAhPT0gbnVsbCkge1xuICAgICAgdmFyIGZpYmVyID0gZ2V0SW5zdGFuY2VGcm9tTm9kZShibG9ja2VkT24pO1xuXG4gICAgICBpZiAoZmliZXIgIT09IG51bGwpIHtcbiAgICAgICAgYXR0ZW1wdFN5bmNocm9ub3VzSHlkcmF0aW9uKGZpYmVyKTtcbiAgICAgIH1cblxuICAgICAgdmFyIG5leHRCbG9ja2VkT24gPSBmaW5kSW5zdGFuY2VCbG9ja2luZ0V2ZW50KGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCk7XG5cbiAgICAgIGlmIChuZXh0QmxvY2tlZE9uID09PSBudWxsKSB7XG4gICAgICAgIGRpc3BhdGNoRXZlbnRGb3JQbHVnaW5FdmVudFN5c3RlbShkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIG5hdGl2ZUV2ZW50LCByZXR1cm5fdGFyZ2V0SW5zdCwgdGFyZ2V0Q29udGFpbmVyKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5leHRCbG9ja2VkT24gPT09IGJsb2NrZWRPbikge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgYmxvY2tlZE9uID0gbmV4dEJsb2NrZWRPbjtcbiAgICB9XG5cbiAgICBpZiAoYmxvY2tlZE9uICE9PSBudWxsKSB7XG4gICAgICBuYXRpdmVFdmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm47XG4gIH0gLy8gVGhpcyBpcyBub3QgcmVwbGF5YWJsZSBzbyB3ZSdsbCBpbnZva2UgaXQgYnV0IHdpdGhvdXQgYSB0YXJnZXQsXG4gIC8vIGluIGNhc2UgdGhlIGV2ZW50IHN5c3RlbSBuZWVkcyB0byB0cmFjZSBpdC5cblxuXG4gIGRpc3BhdGNoRXZlbnRGb3JQbHVnaW5FdmVudFN5c3RlbShkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIG5hdGl2ZUV2ZW50LCBudWxsLCB0YXJnZXRDb250YWluZXIpO1xufVxuXG52YXIgcmV0dXJuX3RhcmdldEluc3QgPSBudWxsOyAvLyBSZXR1cm5zIGEgU3VzcGVuc2VJbnN0YW5jZSBvciBDb250YWluZXIgaWYgaXQncyBibG9ja2VkLlxuLy8gVGhlIHJldHVybl90YXJnZXRJbnN0IGZpZWxkIGFib3ZlIGlzIGNvbmNlcHR1YWxseSBwYXJ0IG9mIHRoZSByZXR1cm4gdmFsdWUuXG5cbmZ1bmN0aW9uIGZpbmRJbnN0YW5jZUJsb2NraW5nRXZlbnQoZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIsIG5hdGl2ZUV2ZW50KSB7XG4gIC8vIFRPRE86IFdhcm4gaWYgX2VuYWJsZWQgaXMgZmFsc2UuXG4gIHJldHVybl90YXJnZXRJbnN0ID0gbnVsbDtcbiAgdmFyIG5hdGl2ZUV2ZW50VGFyZ2V0ID0gZ2V0RXZlbnRUYXJnZXQobmF0aXZlRXZlbnQpO1xuICB2YXIgdGFyZ2V0SW5zdCA9IGdldENsb3Nlc3RJbnN0YW5jZUZyb21Ob2RlKG5hdGl2ZUV2ZW50VGFyZ2V0KTtcblxuICBpZiAodGFyZ2V0SW5zdCAhPT0gbnVsbCkge1xuICAgIHZhciBuZWFyZXN0TW91bnRlZCA9IGdldE5lYXJlc3RNb3VudGVkRmliZXIodGFyZ2V0SW5zdCk7XG5cbiAgICBpZiAobmVhcmVzdE1vdW50ZWQgPT09IG51bGwpIHtcbiAgICAgIC8vIFRoaXMgdHJlZSBoYXMgYmVlbiB1bm1vdW50ZWQgYWxyZWFkeS4gRGlzcGF0Y2ggd2l0aG91dCBhIHRhcmdldC5cbiAgICAgIHRhcmdldEluc3QgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgdGFnID0gbmVhcmVzdE1vdW50ZWQudGFnO1xuXG4gICAgICBpZiAodGFnID09PSBTdXNwZW5zZUNvbXBvbmVudCkge1xuICAgICAgICB2YXIgaW5zdGFuY2UgPSBnZXRTdXNwZW5zZUluc3RhbmNlRnJvbUZpYmVyKG5lYXJlc3RNb3VudGVkKTtcblxuICAgICAgICBpZiAoaW5zdGFuY2UgIT09IG51bGwpIHtcbiAgICAgICAgICAvLyBRdWV1ZSB0aGUgZXZlbnQgdG8gYmUgcmVwbGF5ZWQgbGF0ZXIuIEFib3J0IGRpc3BhdGNoaW5nIHNpbmNlIHdlXG4gICAgICAgICAgLy8gZG9uJ3Qgd2FudCB0aGlzIGV2ZW50IGRpc3BhdGNoZWQgdHdpY2UgdGhyb3VnaCB0aGUgZXZlbnQgc3lzdGVtLlxuICAgICAgICAgIC8vIFRPRE86IElmIHRoaXMgaXMgdGhlIGZpcnN0IGRpc2NyZXRlIGV2ZW50IGluIHRoZSBxdWV1ZS4gU2NoZWR1bGUgYW4gaW5jcmVhc2VkXG4gICAgICAgICAgLy8gcHJpb3JpdHkgZm9yIHRoaXMgYm91bmRhcnkuXG4gICAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgICAgICB9IC8vIFRoaXMgc2hvdWxkbid0IGhhcHBlbiwgc29tZXRoaW5nIHdlbnQgd3JvbmcgYnV0IHRvIGF2b2lkIGJsb2NraW5nXG4gICAgICAgIC8vIHRoZSB3aG9sZSBzeXN0ZW0sIGRpc3BhdGNoIHRoZSBldmVudCB3aXRob3V0IGEgdGFyZ2V0LlxuICAgICAgICAvLyBUT0RPOiBXYXJuLlxuXG5cbiAgICAgICAgdGFyZ2V0SW5zdCA9IG51bGw7XG4gICAgICB9IGVsc2UgaWYgKHRhZyA9PT0gSG9zdFJvb3QpIHtcbiAgICAgICAgdmFyIHJvb3QgPSBuZWFyZXN0TW91bnRlZC5zdGF0ZU5vZGU7XG5cbiAgICAgICAgaWYgKGlzUm9vdERlaHlkcmF0ZWQocm9vdCkpIHtcbiAgICAgICAgICAvLyBJZiB0aGlzIGhhcHBlbnMgZHVyaW5nIGEgcmVwbGF5IHNvbWV0aGluZyB3ZW50IHdyb25nIGFuZCBpdCBtaWdodCBibG9ja1xuICAgICAgICAgIC8vIHRoZSB3aG9sZSBzeXN0ZW0uXG4gICAgICAgICAgcmV0dXJuIGdldENvbnRhaW5lckZyb21GaWJlcihuZWFyZXN0TW91bnRlZCk7XG4gICAgICAgIH1cblxuICAgICAgICB0YXJnZXRJbnN0ID0gbnVsbDtcbiAgICAgIH0gZWxzZSBpZiAobmVhcmVzdE1vdW50ZWQgIT09IHRhcmdldEluc3QpIHtcbiAgICAgICAgLy8gSWYgd2UgZ2V0IGFuIGV2ZW50IChleDogaW1nIG9ubG9hZCkgYmVmb3JlIGNvbW1pdHRpbmcgdGhhdFxuICAgICAgICAvLyBjb21wb25lbnQncyBtb3VudCwgaWdub3JlIGl0IGZvciBub3cgKHRoYXQgaXMsIHRyZWF0IGl0IGFzIGlmIGl0IHdhcyBhblxuICAgICAgICAvLyBldmVudCBvbiBhIG5vbi1SZWFjdCB0cmVlKS4gV2UgbWlnaHQgYWxzbyBjb25zaWRlciBxdWV1ZWluZyBldmVudHMgYW5kXG4gICAgICAgIC8vIGRpc3BhdGNoaW5nIHRoZW0gYWZ0ZXIgdGhlIG1vdW50LlxuICAgICAgICB0YXJnZXRJbnN0ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm5fdGFyZ2V0SW5zdCA9IHRhcmdldEluc3Q7IC8vIFdlJ3JlIG5vdCBibG9ja2VkIG9uIGFueXRoaW5nLlxuXG4gIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gZ2V0RXZlbnRQcmlvcml0eShkb21FdmVudE5hbWUpIHtcbiAgc3dpdGNoIChkb21FdmVudE5hbWUpIHtcbiAgICAvLyBVc2VkIGJ5IFNpbXBsZUV2ZW50UGx1Z2luOlxuICAgIGNhc2UgJ2NhbmNlbCc6XG4gICAgY2FzZSAnY2xpY2snOlxuICAgIGNhc2UgJ2Nsb3NlJzpcbiAgICBjYXNlICdjb250ZXh0bWVudSc6XG4gICAgY2FzZSAnY29weSc6XG4gICAgY2FzZSAnY3V0JzpcbiAgICBjYXNlICdhdXhjbGljayc6XG4gICAgY2FzZSAnZGJsY2xpY2snOlxuICAgIGNhc2UgJ2RyYWdlbmQnOlxuICAgIGNhc2UgJ2RyYWdzdGFydCc6XG4gICAgY2FzZSAnZHJvcCc6XG4gICAgY2FzZSAnZm9jdXNpbic6XG4gICAgY2FzZSAnZm9jdXNvdXQnOlxuICAgIGNhc2UgJ2lucHV0JzpcbiAgICBjYXNlICdpbnZhbGlkJzpcbiAgICBjYXNlICdrZXlkb3duJzpcbiAgICBjYXNlICdrZXlwcmVzcyc6XG4gICAgY2FzZSAna2V5dXAnOlxuICAgIGNhc2UgJ21vdXNlZG93bic6XG4gICAgY2FzZSAnbW91c2V1cCc6XG4gICAgY2FzZSAncGFzdGUnOlxuICAgIGNhc2UgJ3BhdXNlJzpcbiAgICBjYXNlICdwbGF5JzpcbiAgICBjYXNlICdwb2ludGVyY2FuY2VsJzpcbiAgICBjYXNlICdwb2ludGVyZG93bic6XG4gICAgY2FzZSAncG9pbnRlcnVwJzpcbiAgICBjYXNlICdyYXRlY2hhbmdlJzpcbiAgICBjYXNlICdyZXNldCc6XG4gICAgY2FzZSAncmVzaXplJzpcbiAgICBjYXNlICdzZWVrZWQnOlxuICAgIGNhc2UgJ3N1Ym1pdCc6XG4gICAgY2FzZSAndG91Y2hjYW5jZWwnOlxuICAgIGNhc2UgJ3RvdWNoZW5kJzpcbiAgICBjYXNlICd0b3VjaHN0YXJ0JzpcbiAgICBjYXNlICd2b2x1bWVjaGFuZ2UnOiAvLyBVc2VkIGJ5IHBvbHlmaWxsczpcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZmFsbHRocm91Z2hcblxuICAgIGNhc2UgJ2NoYW5nZSc6XG4gICAgY2FzZSAnc2VsZWN0aW9uY2hhbmdlJzpcbiAgICBjYXNlICd0ZXh0SW5wdXQnOlxuICAgIGNhc2UgJ2NvbXBvc2l0aW9uc3RhcnQnOlxuICAgIGNhc2UgJ2NvbXBvc2l0aW9uZW5kJzpcbiAgICBjYXNlICdjb21wb3NpdGlvbnVwZGF0ZSc6IC8vIE9ubHkgZW5hYmxlQ3JlYXRlRXZlbnRIYW5kbGVBUEk6XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWZhbGx0aHJvdWdoXG5cbiAgICBjYXNlICdiZWZvcmVibHVyJzpcbiAgICBjYXNlICdhZnRlcmJsdXInOiAvLyBOb3QgdXNlZCBieSBSZWFjdCBidXQgY291bGQgYmUgYnkgdXNlciBjb2RlOlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuXG4gICAgY2FzZSAnYmVmb3JlaW5wdXQnOlxuICAgIGNhc2UgJ2JsdXInOlxuICAgIGNhc2UgJ2Z1bGxzY3JlZW5jaGFuZ2UnOlxuICAgIGNhc2UgJ2ZvY3VzJzpcbiAgICBjYXNlICdoYXNoY2hhbmdlJzpcbiAgICBjYXNlICdwb3BzdGF0ZSc6XG4gICAgY2FzZSAnc2VsZWN0JzpcbiAgICBjYXNlICdzZWxlY3RzdGFydCc6XG4gICAgICByZXR1cm4gRGlzY3JldGVFdmVudFByaW9yaXR5O1xuXG4gICAgY2FzZSAnZHJhZyc6XG4gICAgY2FzZSAnZHJhZ2VudGVyJzpcbiAgICBjYXNlICdkcmFnZXhpdCc6XG4gICAgY2FzZSAnZHJhZ2xlYXZlJzpcbiAgICBjYXNlICdkcmFnb3Zlcic6XG4gICAgY2FzZSAnbW91c2Vtb3ZlJzpcbiAgICBjYXNlICdtb3VzZW91dCc6XG4gICAgY2FzZSAnbW91c2VvdmVyJzpcbiAgICBjYXNlICdwb2ludGVybW92ZSc6XG4gICAgY2FzZSAncG9pbnRlcm91dCc6XG4gICAgY2FzZSAncG9pbnRlcm92ZXInOlxuICAgIGNhc2UgJ3Njcm9sbCc6XG4gICAgY2FzZSAndG9nZ2xlJzpcbiAgICBjYXNlICd0b3VjaG1vdmUnOlxuICAgIGNhc2UgJ3doZWVsJzogLy8gTm90IHVzZWQgYnkgUmVhY3QgYnV0IGNvdWxkIGJlIGJ5IHVzZXIgY29kZTpcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZmFsbHRocm91Z2hcblxuICAgIGNhc2UgJ21vdXNlZW50ZXInOlxuICAgIGNhc2UgJ21vdXNlbGVhdmUnOlxuICAgIGNhc2UgJ3BvaW50ZXJlbnRlcic6XG4gICAgY2FzZSAncG9pbnRlcmxlYXZlJzpcbiAgICAgIHJldHVybiBDb250aW51b3VzRXZlbnRQcmlvcml0eTtcblxuICAgIGNhc2UgJ21lc3NhZ2UnOlxuICAgICAge1xuICAgICAgICAvLyBXZSBtaWdodCBiZSBpbiB0aGUgU2NoZWR1bGVyIGNhbGxiYWNrLlxuICAgICAgICAvLyBFdmVudHVhbGx5IHRoaXMgbWVjaGFuaXNtIHdpbGwgYmUgcmVwbGFjZWQgYnkgYSBjaGVja1xuICAgICAgICAvLyBvZiB0aGUgY3VycmVudCBwcmlvcml0eSBvbiB0aGUgbmF0aXZlIHNjaGVkdWxlci5cbiAgICAgICAgdmFyIHNjaGVkdWxlclByaW9yaXR5ID0gZ2V0Q3VycmVudFByaW9yaXR5TGV2ZWwoKTtcblxuICAgICAgICBzd2l0Y2ggKHNjaGVkdWxlclByaW9yaXR5KSB7XG4gICAgICAgICAgY2FzZSBJbW1lZGlhdGVQcmlvcml0eTpcbiAgICAgICAgICAgIHJldHVybiBEaXNjcmV0ZUV2ZW50UHJpb3JpdHk7XG5cbiAgICAgICAgICBjYXNlIFVzZXJCbG9ja2luZ1ByaW9yaXR5OlxuICAgICAgICAgICAgcmV0dXJuIENvbnRpbnVvdXNFdmVudFByaW9yaXR5O1xuXG4gICAgICAgICAgY2FzZSBOb3JtYWxQcmlvcml0eTpcbiAgICAgICAgICBjYXNlIExvd1ByaW9yaXR5OlxuICAgICAgICAgICAgLy8gVE9ETzogSGFuZGxlIExvd1NjaGVkdWxlclByaW9yaXR5LCBzb21laG93LiBNYXliZSB0aGUgc2FtZSBsYW5lIGFzIGh5ZHJhdGlvbi5cbiAgICAgICAgICAgIHJldHVybiBEZWZhdWx0RXZlbnRQcmlvcml0eTtcblxuICAgICAgICAgIGNhc2UgSWRsZVByaW9yaXR5OlxuICAgICAgICAgICAgcmV0dXJuIElkbGVFdmVudFByaW9yaXR5O1xuXG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBEZWZhdWx0RXZlbnRQcmlvcml0eTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBEZWZhdWx0RXZlbnRQcmlvcml0eTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhZGRFdmVudEJ1YmJsZUxpc3RlbmVyKHRhcmdldCwgZXZlbnRUeXBlLCBsaXN0ZW5lcikge1xuICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyLCBmYWxzZSk7XG4gIHJldHVybiBsaXN0ZW5lcjtcbn1cbmZ1bmN0aW9uIGFkZEV2ZW50Q2FwdHVyZUxpc3RlbmVyKHRhcmdldCwgZXZlbnRUeXBlLCBsaXN0ZW5lcikge1xuICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyLCB0cnVlKTtcbiAgcmV0dXJuIGxpc3RlbmVyO1xufVxuZnVuY3Rpb24gYWRkRXZlbnRDYXB0dXJlTGlzdGVuZXJXaXRoUGFzc2l2ZUZsYWcodGFyZ2V0LCBldmVudFR5cGUsIGxpc3RlbmVyLCBwYXNzaXZlKSB7XG4gIHRhcmdldC5hZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIsIHtcbiAgICBjYXB0dXJlOiB0cnVlLFxuICAgIHBhc3NpdmU6IHBhc3NpdmVcbiAgfSk7XG4gIHJldHVybiBsaXN0ZW5lcjtcbn1cbmZ1bmN0aW9uIGFkZEV2ZW50QnViYmxlTGlzdGVuZXJXaXRoUGFzc2l2ZUZsYWcodGFyZ2V0LCBldmVudFR5cGUsIGxpc3RlbmVyLCBwYXNzaXZlKSB7XG4gIHRhcmdldC5hZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIsIHtcbiAgICBwYXNzaXZlOiBwYXNzaXZlXG4gIH0pO1xuICByZXR1cm4gbGlzdGVuZXI7XG59XG5cbi8qKlxuICogVGhlc2UgdmFyaWFibGVzIHN0b3JlIGluZm9ybWF0aW9uIGFib3V0IHRleHQgY29udGVudCBvZiBhIHRhcmdldCBub2RlLFxuICogYWxsb3dpbmcgY29tcGFyaXNvbiBvZiBjb250ZW50IGJlZm9yZSBhbmQgYWZ0ZXIgYSBnaXZlbiBldmVudC5cbiAqXG4gKiBJZGVudGlmeSB0aGUgbm9kZSB3aGVyZSBzZWxlY3Rpb24gY3VycmVudGx5IGJlZ2lucywgdGhlbiBvYnNlcnZlXG4gKiBib3RoIGl0cyB0ZXh0IGNvbnRlbnQgYW5kIGl0cyBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBET00uIFNpbmNlIHRoZVxuICogYnJvd3NlciBtYXkgbmF0aXZlbHkgcmVwbGFjZSB0aGUgdGFyZ2V0IG5vZGUgZHVyaW5nIGNvbXBvc2l0aW9uLCB3ZSBjYW5cbiAqIHVzZSBpdHMgcG9zaXRpb24gdG8gZmluZCBpdHMgcmVwbGFjZW1lbnQuXG4gKlxuICpcbiAqL1xudmFyIHJvb3QgPSBudWxsO1xudmFyIHN0YXJ0VGV4dCA9IG51bGw7XG52YXIgZmFsbGJhY2tUZXh0ID0gbnVsbDtcbmZ1bmN0aW9uIGluaXRpYWxpemUobmF0aXZlRXZlbnRUYXJnZXQpIHtcbiAgcm9vdCA9IG5hdGl2ZUV2ZW50VGFyZ2V0O1xuICBzdGFydFRleHQgPSBnZXRUZXh0KCk7XG4gIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gcmVzZXQoKSB7XG4gIHJvb3QgPSBudWxsO1xuICBzdGFydFRleHQgPSBudWxsO1xuICBmYWxsYmFja1RleHQgPSBudWxsO1xufVxuZnVuY3Rpb24gZ2V0RGF0YSgpIHtcbiAgaWYgKGZhbGxiYWNrVGV4dCkge1xuICAgIHJldHVybiBmYWxsYmFja1RleHQ7XG4gIH1cblxuICB2YXIgc3RhcnQ7XG4gIHZhciBzdGFydFZhbHVlID0gc3RhcnRUZXh0O1xuICB2YXIgc3RhcnRMZW5ndGggPSBzdGFydFZhbHVlLmxlbmd0aDtcbiAgdmFyIGVuZDtcbiAgdmFyIGVuZFZhbHVlID0gZ2V0VGV4dCgpO1xuICB2YXIgZW5kTGVuZ3RoID0gZW5kVmFsdWUubGVuZ3RoO1xuXG4gIGZvciAoc3RhcnQgPSAwOyBzdGFydCA8IHN0YXJ0TGVuZ3RoOyBzdGFydCsrKSB7XG4gICAgaWYgKHN0YXJ0VmFsdWVbc3RhcnRdICE9PSBlbmRWYWx1ZVtzdGFydF0pIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHZhciBtaW5FbmQgPSBzdGFydExlbmd0aCAtIHN0YXJ0O1xuXG4gIGZvciAoZW5kID0gMTsgZW5kIDw9IG1pbkVuZDsgZW5kKyspIHtcbiAgICBpZiAoc3RhcnRWYWx1ZVtzdGFydExlbmd0aCAtIGVuZF0gIT09IGVuZFZhbHVlW2VuZExlbmd0aCAtIGVuZF0pIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHZhciBzbGljZVRhaWwgPSBlbmQgPiAxID8gMSAtIGVuZCA6IHVuZGVmaW5lZDtcbiAgZmFsbGJhY2tUZXh0ID0gZW5kVmFsdWUuc2xpY2Uoc3RhcnQsIHNsaWNlVGFpbCk7XG4gIHJldHVybiBmYWxsYmFja1RleHQ7XG59XG5mdW5jdGlvbiBnZXRUZXh0KCkge1xuICBpZiAoJ3ZhbHVlJyBpbiByb290KSB7XG4gICAgcmV0dXJuIHJvb3QudmFsdWU7XG4gIH1cblxuICByZXR1cm4gcm9vdC50ZXh0Q29udGVudDtcbn1cblxuLyoqXG4gKiBgY2hhckNvZGVgIHJlcHJlc2VudHMgdGhlIGFjdHVhbCBcImNoYXJhY3RlciBjb2RlXCIgYW5kIGlzIHNhZmUgdG8gdXNlIHdpdGhcbiAqIGBTdHJpbmcuZnJvbUNoYXJDb2RlYC4gQXMgc3VjaCwgb25seSBrZXlzIHRoYXQgY29ycmVzcG9uZCB0byBwcmludGFibGVcbiAqIGNoYXJhY3RlcnMgcHJvZHVjZSBhIHZhbGlkIGBjaGFyQ29kZWAsIHRoZSBvbmx5IGV4Y2VwdGlvbiB0byB0aGlzIGlzIEVudGVyLlxuICogVGhlIFRhYi1rZXkgaXMgY29uc2lkZXJlZCBub24tcHJpbnRhYmxlIGFuZCBkb2VzIG5vdCBoYXZlIGEgYGNoYXJDb2RlYCxcbiAqIHByZXN1bWFibHkgYmVjYXVzZSBpdCBkb2VzIG5vdCBwcm9kdWNlIGEgdGFiLWNoYXJhY3RlciBpbiBicm93c2Vycy5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE5vcm1hbGl6ZWQgYGNoYXJDb2RlYCBwcm9wZXJ0eS5cbiAqL1xuZnVuY3Rpb24gZ2V0RXZlbnRDaGFyQ29kZShuYXRpdmVFdmVudCkge1xuICB2YXIgY2hhckNvZGU7XG4gIHZhciBrZXlDb2RlID0gbmF0aXZlRXZlbnQua2V5Q29kZTtcblxuICBpZiAoJ2NoYXJDb2RlJyBpbiBuYXRpdmVFdmVudCkge1xuICAgIGNoYXJDb2RlID0gbmF0aXZlRXZlbnQuY2hhckNvZGU7IC8vIEZGIGRvZXMgbm90IHNldCBgY2hhckNvZGVgIGZvciB0aGUgRW50ZXIta2V5LCBjaGVjayBhZ2FpbnN0IGBrZXlDb2RlYC5cblxuICAgIGlmIChjaGFyQ29kZSA9PT0gMCAmJiBrZXlDb2RlID09PSAxMykge1xuICAgICAgY2hhckNvZGUgPSAxMztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gSUU4IGRvZXMgbm90IGltcGxlbWVudCBgY2hhckNvZGVgLCBidXQgYGtleUNvZGVgIGhhcyB0aGUgY29ycmVjdCB2YWx1ZS5cbiAgICBjaGFyQ29kZSA9IGtleUNvZGU7XG4gIH0gLy8gSUUgYW5kIEVkZ2UgKG9uIFdpbmRvd3MpIGFuZCBDaHJvbWUgLyBTYWZhcmkgKG9uIFdpbmRvd3MgYW5kIExpbnV4KVxuICAvLyByZXBvcnQgRW50ZXIgYXMgY2hhckNvZGUgMTAgd2hlbiBjdHJsIGlzIHByZXNzZWQuXG5cblxuICBpZiAoY2hhckNvZGUgPT09IDEwKSB7XG4gICAgY2hhckNvZGUgPSAxMztcbiAgfSAvLyBTb21lIG5vbi1wcmludGFibGUga2V5cyBhcmUgcmVwb3J0ZWQgaW4gYGNoYXJDb2RlYC9ga2V5Q29kZWAsIGRpc2NhcmQgdGhlbS5cbiAgLy8gTXVzdCBub3QgZGlzY2FyZCB0aGUgKG5vbi0pcHJpbnRhYmxlIEVudGVyLWtleS5cblxuXG4gIGlmIChjaGFyQ29kZSA+PSAzMiB8fCBjaGFyQ29kZSA9PT0gMTMpIHtcbiAgICByZXR1cm4gY2hhckNvZGU7XG4gIH1cblxuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gZnVuY3Rpb25UaGF0UmV0dXJuc1RydWUoKSB7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBmdW5jdGlvblRoYXRSZXR1cm5zRmFsc2UoKSB7XG4gIHJldHVybiBmYWxzZTtcbn0gLy8gVGhpcyBpcyBpbnRlbnRpb25hbGx5IGEgZmFjdG9yeSBzbyB0aGF0IHdlIGhhdmUgZGlmZmVyZW50IHJldHVybmVkIGNvbnN0cnVjdG9ycy5cbi8vIElmIHdlIGhhZCBhIHNpbmdsZSBjb25zdHJ1Y3RvciwgaXQgd291bGQgYmUgbWVnYW1vcnBoaWMgYW5kIGVuZ2luZXMgd291bGQgZGVvcHQuXG5cblxuZnVuY3Rpb24gY3JlYXRlU3ludGhldGljRXZlbnQoSW50ZXJmYWNlKSB7XG4gIC8qKlxuICAgKiBTeW50aGV0aWMgZXZlbnRzIGFyZSBkaXNwYXRjaGVkIGJ5IGV2ZW50IHBsdWdpbnMsIHR5cGljYWxseSBpbiByZXNwb25zZSB0byBhXG4gICAqIHRvcC1sZXZlbCBldmVudCBkZWxlZ2F0aW9uIGhhbmRsZXIuXG4gICAqXG4gICAqIFRoZXNlIHN5c3RlbXMgc2hvdWxkIGdlbmVyYWxseSB1c2UgcG9vbGluZyB0byByZWR1Y2UgdGhlIGZyZXF1ZW5jeSBvZiBnYXJiYWdlXG4gICAqIGNvbGxlY3Rpb24uIFRoZSBzeXN0ZW0gc2hvdWxkIGNoZWNrIGBpc1BlcnNpc3RlbnRgIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZVxuICAgKiBldmVudCBzaG91bGQgYmUgcmVsZWFzZWQgaW50byB0aGUgcG9vbCBhZnRlciBiZWluZyBkaXNwYXRjaGVkLiBVc2VycyB0aGF0XG4gICAqIG5lZWQgYSBwZXJzaXN0ZWQgZXZlbnQgc2hvdWxkIGludm9rZSBgcGVyc2lzdGAuXG4gICAqXG4gICAqIFN5bnRoZXRpYyBldmVudHMgKGFuZCBzdWJjbGFzc2VzKSBpbXBsZW1lbnQgdGhlIERPTSBMZXZlbCAzIEV2ZW50cyBBUEkgYnlcbiAgICogbm9ybWFsaXppbmcgYnJvd3NlciBxdWlya3MuIFN1YmNsYXNzZXMgZG8gbm90IG5lY2Vzc2FyaWx5IGhhdmUgdG8gaW1wbGVtZW50IGFcbiAgICogRE9NIGludGVyZmFjZTsgY3VzdG9tIGFwcGxpY2F0aW9uLXNwZWNpZmljIGV2ZW50cyBjYW4gYWxzbyBzdWJjbGFzcyB0aGlzLlxuICAgKi9cbiAgZnVuY3Rpb24gU3ludGhldGljQmFzZUV2ZW50KHJlYWN0TmFtZSwgcmVhY3RFdmVudFR5cGUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICAgIHRoaXMuX3JlYWN0TmFtZSA9IHJlYWN0TmFtZTtcbiAgICB0aGlzLl90YXJnZXRJbnN0ID0gdGFyZ2V0SW5zdDtcbiAgICB0aGlzLnR5cGUgPSByZWFjdEV2ZW50VHlwZTtcbiAgICB0aGlzLm5hdGl2ZUV2ZW50ID0gbmF0aXZlRXZlbnQ7XG4gICAgdGhpcy50YXJnZXQgPSBuYXRpdmVFdmVudFRhcmdldDtcbiAgICB0aGlzLmN1cnJlbnRUYXJnZXQgPSBudWxsO1xuXG4gICAgZm9yICh2YXIgX3Byb3BOYW1lIGluIEludGVyZmFjZSkge1xuICAgICAgaWYgKCFJbnRlcmZhY2UuaGFzT3duUHJvcGVydHkoX3Byb3BOYW1lKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIG5vcm1hbGl6ZSA9IEludGVyZmFjZVtfcHJvcE5hbWVdO1xuXG4gICAgICBpZiAobm9ybWFsaXplKSB7XG4gICAgICAgIHRoaXNbX3Byb3BOYW1lXSA9IG5vcm1hbGl6ZShuYXRpdmVFdmVudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzW19wcm9wTmFtZV0gPSBuYXRpdmVFdmVudFtfcHJvcE5hbWVdO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0UHJldmVudGVkID0gbmF0aXZlRXZlbnQuZGVmYXVsdFByZXZlbnRlZCAhPSBudWxsID8gbmF0aXZlRXZlbnQuZGVmYXVsdFByZXZlbnRlZCA6IG5hdGl2ZUV2ZW50LnJldHVyblZhbHVlID09PSBmYWxzZTtcblxuICAgIGlmIChkZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICB0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IGZ1bmN0aW9uVGhhdFJldHVybnNUcnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IGZ1bmN0aW9uVGhhdFJldHVybnNGYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkID0gZnVuY3Rpb25UaGF0UmV0dXJuc0ZhbHNlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgYXNzaWduKFN5bnRoZXRpY0Jhc2VFdmVudC5wcm90b3R5cGUsIHtcbiAgICBwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5kZWZhdWx0UHJldmVudGVkID0gdHJ1ZTtcbiAgICAgIHZhciBldmVudCA9IHRoaXMubmF0aXZlRXZlbnQ7XG5cbiAgICAgIGlmICghZXZlbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQucHJldmVudERlZmF1bHQpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsgLy8gJEZsb3dGaXhNZSAtIGZsb3cgaXMgbm90IGF3YXJlIG9mIGB1bmtub3duYCBpbiBJRVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZXZlbnQucmV0dXJuVmFsdWUgIT09ICd1bmtub3duJykge1xuICAgICAgICBldmVudC5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IGZ1bmN0aW9uVGhhdFJldHVybnNUcnVlO1xuICAgIH0sXG4gICAgc3RvcFByb3BhZ2F0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgZXZlbnQgPSB0aGlzLm5hdGl2ZUV2ZW50O1xuXG4gICAgICBpZiAoIWV2ZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50LnN0b3BQcm9wYWdhdGlvbikge1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgLy8gJEZsb3dGaXhNZSAtIGZsb3cgaXMgbm90IGF3YXJlIG9mIGB1bmtub3duYCBpbiBJRVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZXZlbnQuY2FuY2VsQnViYmxlICE9PSAndW5rbm93bicpIHtcbiAgICAgICAgLy8gVGhlIENoYW5nZUV2ZW50UGx1Z2luIHJlZ2lzdGVycyBhIFwicHJvcGVydHljaGFuZ2VcIiBldmVudCBmb3JcbiAgICAgICAgLy8gSUUuIFRoaXMgZXZlbnQgZG9lcyBub3Qgc3VwcG9ydCBidWJibGluZyBvciBjYW5jZWxsaW5nLCBhbmRcbiAgICAgICAgLy8gYW55IHJlZmVyZW5jZXMgdG8gY2FuY2VsQnViYmxlIHRocm93IFwiTWVtYmVyIG5vdCBmb3VuZFwiLiAgQVxuICAgICAgICAvLyB0eXBlb2YgY2hlY2sgb2YgXCJ1bmtub3duXCIgY2lyY3VtdmVudHMgdGhpcyBpc3N1ZSAoYW5kIGlzIGFsc29cbiAgICAgICAgLy8gSUUgc3BlY2lmaWMpLlxuICAgICAgICBldmVudC5jYW5jZWxCdWJibGUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkID0gZnVuY3Rpb25UaGF0UmV0dXJuc1RydWU7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFdlIHJlbGVhc2UgYWxsIGRpc3BhdGNoZWQgYFN5bnRoZXRpY0V2ZW50YHMgYWZ0ZXIgZWFjaCBldmVudCBsb29wLCBhZGRpbmdcbiAgICAgKiB0aGVtIGJhY2sgaW50byB0aGUgcG9vbC4gVGhpcyBhbGxvd3MgYSB3YXkgdG8gaG9sZCBvbnRvIGEgcmVmZXJlbmNlIHRoYXRcbiAgICAgKiB3b24ndCBiZSBhZGRlZCBiYWNrIGludG8gdGhlIHBvb2wuXG4gICAgICovXG4gICAgcGVyc2lzdDogZnVuY3Rpb24gKCkgey8vIE1vZGVybiBldmVudCBzeXN0ZW0gZG9lc24ndCB1c2UgcG9vbGluZy5cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoaXMgZXZlbnQgc2hvdWxkIGJlIHJlbGVhc2VkIGJhY2sgaW50byB0aGUgcG9vbC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhpcyBzaG91bGQgbm90IGJlIHJlbGVhc2VkLCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICovXG4gICAgaXNQZXJzaXN0ZW50OiBmdW5jdGlvblRoYXRSZXR1cm5zVHJ1ZVxuICB9KTtcbiAgcmV0dXJuIFN5bnRoZXRpY0Jhc2VFdmVudDtcbn1cbi8qKlxuICogQGludGVyZmFjZSBFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvXG4gKi9cblxuXG52YXIgRXZlbnRJbnRlcmZhY2UgPSB7XG4gIGV2ZW50UGhhc2U6IDAsXG4gIGJ1YmJsZXM6IDAsXG4gIGNhbmNlbGFibGU6IDAsXG4gIHRpbWVTdGFtcDogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgcmV0dXJuIGV2ZW50LnRpbWVTdGFtcCB8fCBEYXRlLm5vdygpO1xuICB9LFxuICBkZWZhdWx0UHJldmVudGVkOiAwLFxuICBpc1RydXN0ZWQ6IDBcbn07XG52YXIgU3ludGhldGljRXZlbnQgPSBjcmVhdGVTeW50aGV0aWNFdmVudChFdmVudEludGVyZmFjZSk7XG5cbnZhciBVSUV2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBFdmVudEludGVyZmFjZSwge1xuICB2aWV3OiAwLFxuICBkZXRhaWw6IDBcbn0pO1xuXG52YXIgU3ludGhldGljVUlFdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KFVJRXZlbnRJbnRlcmZhY2UpO1xudmFyIGxhc3RNb3ZlbWVudFg7XG52YXIgbGFzdE1vdmVtZW50WTtcbnZhciBsYXN0TW91c2VFdmVudDtcblxuZnVuY3Rpb24gdXBkYXRlTW91c2VNb3ZlbWVudFBvbHlmaWxsU3RhdGUoZXZlbnQpIHtcbiAgaWYgKGV2ZW50ICE9PSBsYXN0TW91c2VFdmVudCkge1xuICAgIGlmIChsYXN0TW91c2VFdmVudCAmJiBldmVudC50eXBlID09PSAnbW91c2Vtb3ZlJykge1xuICAgICAgbGFzdE1vdmVtZW50WCA9IGV2ZW50LnNjcmVlblggLSBsYXN0TW91c2VFdmVudC5zY3JlZW5YO1xuICAgICAgbGFzdE1vdmVtZW50WSA9IGV2ZW50LnNjcmVlblkgLSBsYXN0TW91c2VFdmVudC5zY3JlZW5ZO1xuICAgIH0gZWxzZSB7XG4gICAgICBsYXN0TW92ZW1lbnRYID0gMDtcbiAgICAgIGxhc3RNb3ZlbWVudFkgPSAwO1xuICAgIH1cblxuICAgIGxhc3RNb3VzZUV2ZW50ID0gZXZlbnQ7XG4gIH1cbn1cbi8qKlxuICogQGludGVyZmFjZSBNb3VzZUV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy9cbiAqL1xuXG5cbnZhciBNb3VzZUV2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBVSUV2ZW50SW50ZXJmYWNlLCB7XG4gIHNjcmVlblg6IDAsXG4gIHNjcmVlblk6IDAsXG4gIGNsaWVudFg6IDAsXG4gIGNsaWVudFk6IDAsXG4gIHBhZ2VYOiAwLFxuICBwYWdlWTogMCxcbiAgY3RybEtleTogMCxcbiAgc2hpZnRLZXk6IDAsXG4gIGFsdEtleTogMCxcbiAgbWV0YUtleTogMCxcbiAgZ2V0TW9kaWZpZXJTdGF0ZTogZ2V0RXZlbnRNb2RpZmllclN0YXRlLFxuICBidXR0b246IDAsXG4gIGJ1dHRvbnM6IDAsXG4gIHJlbGF0ZWRUYXJnZXQ6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmIChldmVudC5yZWxhdGVkVGFyZ2V0ID09PSB1bmRlZmluZWQpIHJldHVybiBldmVudC5mcm9tRWxlbWVudCA9PT0gZXZlbnQuc3JjRWxlbWVudCA/IGV2ZW50LnRvRWxlbWVudCA6IGV2ZW50LmZyb21FbGVtZW50O1xuICAgIHJldHVybiBldmVudC5yZWxhdGVkVGFyZ2V0O1xuICB9LFxuICBtb3ZlbWVudFg6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmICgnbW92ZW1lbnRYJyBpbiBldmVudCkge1xuICAgICAgcmV0dXJuIGV2ZW50Lm1vdmVtZW50WDtcbiAgICB9XG5cbiAgICB1cGRhdGVNb3VzZU1vdmVtZW50UG9seWZpbGxTdGF0ZShldmVudCk7XG4gICAgcmV0dXJuIGxhc3RNb3ZlbWVudFg7XG4gIH0sXG4gIG1vdmVtZW50WTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgaWYgKCdtb3ZlbWVudFknIGluIGV2ZW50KSB7XG4gICAgICByZXR1cm4gZXZlbnQubW92ZW1lbnRZO1xuICAgIH0gLy8gRG9uJ3QgbmVlZCB0byBjYWxsIHVwZGF0ZU1vdXNlTW92ZW1lbnRQb2x5ZmlsbFN0YXRlKCkgaGVyZVxuICAgIC8vIGJlY2F1c2UgaXQncyBndWFyYW50ZWVkIHRvIGhhdmUgYWxyZWFkeSBydW4gd2hlbiBtb3ZlbWVudFhcbiAgICAvLyB3YXMgY29waWVkLlxuXG5cbiAgICByZXR1cm4gbGFzdE1vdmVtZW50WTtcbiAgfVxufSk7XG5cbnZhciBTeW50aGV0aWNNb3VzZUV2ZW50ID0gY3JlYXRlU3ludGhldGljRXZlbnQoTW91c2VFdmVudEludGVyZmFjZSk7XG4vKipcbiAqIEBpbnRlcmZhY2UgRHJhZ0V2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy9cbiAqL1xuXG52YXIgRHJhZ0V2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBNb3VzZUV2ZW50SW50ZXJmYWNlLCB7XG4gIGRhdGFUcmFuc2ZlcjogMFxufSk7XG5cbnZhciBTeW50aGV0aWNEcmFnRXZlbnQgPSBjcmVhdGVTeW50aGV0aWNFdmVudChEcmFnRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIEZvY3VzRXZlbnRcbiAqIEBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzL1xuICovXG5cbnZhciBGb2N1c0V2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBVSUV2ZW50SW50ZXJmYWNlLCB7XG4gIHJlbGF0ZWRUYXJnZXQ6IDBcbn0pO1xuXG52YXIgU3ludGhldGljRm9jdXNFdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KEZvY3VzRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL2NzczMtYW5pbWF0aW9ucy8jQW5pbWF0aW9uRXZlbnQtaW50ZXJmYWNlXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9BbmltYXRpb25FdmVudFxuICovXG5cbnZhciBBbmltYXRpb25FdmVudEludGVyZmFjZSA9IGFzc2lnbih7fSwgRXZlbnRJbnRlcmZhY2UsIHtcbiAgYW5pbWF0aW9uTmFtZTogMCxcbiAgZWxhcHNlZFRpbWU6IDAsXG4gIHBzZXVkb0VsZW1lbnQ6IDBcbn0pO1xuXG52YXIgU3ludGhldGljQW5pbWF0aW9uRXZlbnQgPSBjcmVhdGVTeW50aGV0aWNFdmVudChBbmltYXRpb25FdmVudEludGVyZmFjZSk7XG4vKipcbiAqIEBpbnRlcmZhY2UgRXZlbnRcbiAqIEBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvY2xpcGJvYXJkLWFwaXMvXG4gKi9cblxudmFyIENsaXBib2FyZEV2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBFdmVudEludGVyZmFjZSwge1xuICBjbGlwYm9hcmREYXRhOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICByZXR1cm4gJ2NsaXBib2FyZERhdGEnIGluIGV2ZW50ID8gZXZlbnQuY2xpcGJvYXJkRGF0YSA6IHdpbmRvdy5jbGlwYm9hcmREYXRhO1xuICB9XG59KTtcblxudmFyIFN5bnRoZXRpY0NsaXBib2FyZEV2ZW50ID0gY3JlYXRlU3ludGhldGljRXZlbnQoQ2xpcGJvYXJkRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy8jZXZlbnRzLWNvbXBvc2l0aW9uZXZlbnRzXG4gKi9cblxudmFyIENvbXBvc2l0aW9uRXZlbnRJbnRlcmZhY2UgPSBhc3NpZ24oe30sIEV2ZW50SW50ZXJmYWNlLCB7XG4gIGRhdGE6IDBcbn0pO1xuXG52YXIgU3ludGhldGljQ29tcG9zaXRpb25FdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KENvbXBvc2l0aW9uRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTMvV0QtRE9NLUxldmVsLTMtRXZlbnRzLTIwMTMxMTA1XG4gKiAgICAgIC8jZXZlbnRzLWlucHV0ZXZlbnRzXG4gKi9cbi8vIEhhcHBlbnMgdG8gc2hhcmUgdGhlIHNhbWUgbGlzdCBmb3Igbm93LlxuXG52YXIgU3ludGhldGljSW5wdXRFdmVudCA9IFN5bnRoZXRpY0NvbXBvc2l0aW9uRXZlbnQ7XG4vKipcbiAqIE5vcm1hbGl6YXRpb24gb2YgZGVwcmVjYXRlZCBIVE1MNSBga2V5YCB2YWx1ZXNcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0tleWJvYXJkRXZlbnQjS2V5X25hbWVzXG4gKi9cblxudmFyIG5vcm1hbGl6ZUtleSA9IHtcbiAgRXNjOiAnRXNjYXBlJyxcbiAgU3BhY2ViYXI6ICcgJyxcbiAgTGVmdDogJ0Fycm93TGVmdCcsXG4gIFVwOiAnQXJyb3dVcCcsXG4gIFJpZ2h0OiAnQXJyb3dSaWdodCcsXG4gIERvd246ICdBcnJvd0Rvd24nLFxuICBEZWw6ICdEZWxldGUnLFxuICBXaW46ICdPUycsXG4gIE1lbnU6ICdDb250ZXh0TWVudScsXG4gIEFwcHM6ICdDb250ZXh0TWVudScsXG4gIFNjcm9sbDogJ1Njcm9sbExvY2snLFxuICBNb3pQcmludGFibGVLZXk6ICdVbmlkZW50aWZpZWQnXG59O1xuLyoqXG4gKiBUcmFuc2xhdGlvbiBmcm9tIGxlZ2FjeSBga2V5Q29kZWAgdG8gSFRNTDUgYGtleWBcbiAqIE9ubHkgc3BlY2lhbCBrZXlzIHN1cHBvcnRlZCwgYWxsIG90aGVycyBkZXBlbmQgb24ga2V5Ym9hcmQgbGF5b3V0IG9yIGJyb3dzZXJcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0tleWJvYXJkRXZlbnQjS2V5X25hbWVzXG4gKi9cblxudmFyIHRyYW5zbGF0ZVRvS2V5ID0ge1xuICAnOCc6ICdCYWNrc3BhY2UnLFxuICAnOSc6ICdUYWInLFxuICAnMTInOiAnQ2xlYXInLFxuICAnMTMnOiAnRW50ZXInLFxuICAnMTYnOiAnU2hpZnQnLFxuICAnMTcnOiAnQ29udHJvbCcsXG4gICcxOCc6ICdBbHQnLFxuICAnMTknOiAnUGF1c2UnLFxuICAnMjAnOiAnQ2Fwc0xvY2snLFxuICAnMjcnOiAnRXNjYXBlJyxcbiAgJzMyJzogJyAnLFxuICAnMzMnOiAnUGFnZVVwJyxcbiAgJzM0JzogJ1BhZ2VEb3duJyxcbiAgJzM1JzogJ0VuZCcsXG4gICczNic6ICdIb21lJyxcbiAgJzM3JzogJ0Fycm93TGVmdCcsXG4gICczOCc6ICdBcnJvd1VwJyxcbiAgJzM5JzogJ0Fycm93UmlnaHQnLFxuICAnNDAnOiAnQXJyb3dEb3duJyxcbiAgJzQ1JzogJ0luc2VydCcsXG4gICc0Nic6ICdEZWxldGUnLFxuICAnMTEyJzogJ0YxJyxcbiAgJzExMyc6ICdGMicsXG4gICcxMTQnOiAnRjMnLFxuICAnMTE1JzogJ0Y0JyxcbiAgJzExNic6ICdGNScsXG4gICcxMTcnOiAnRjYnLFxuICAnMTE4JzogJ0Y3JyxcbiAgJzExOSc6ICdGOCcsXG4gICcxMjAnOiAnRjknLFxuICAnMTIxJzogJ0YxMCcsXG4gICcxMjInOiAnRjExJyxcbiAgJzEyMyc6ICdGMTInLFxuICAnMTQ0JzogJ051bUxvY2snLFxuICAnMTQ1JzogJ1Njcm9sbExvY2snLFxuICAnMjI0JzogJ01ldGEnXG59O1xuLyoqXG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IE5vcm1hbGl6ZWQgYGtleWAgcHJvcGVydHkuXG4gKi9cblxuZnVuY3Rpb24gZ2V0RXZlbnRLZXkobmF0aXZlRXZlbnQpIHtcbiAgaWYgKG5hdGl2ZUV2ZW50LmtleSkge1xuICAgIC8vIE5vcm1hbGl6ZSBpbmNvbnNpc3RlbnQgdmFsdWVzIHJlcG9ydGVkIGJ5IGJyb3dzZXJzIGR1ZSB0b1xuICAgIC8vIGltcGxlbWVudGF0aW9ucyBvZiBhIHdvcmtpbmcgZHJhZnQgc3BlY2lmaWNhdGlvbi5cbiAgICAvLyBGaXJlRm94IGltcGxlbWVudHMgYGtleWAgYnV0IHJldHVybnMgYE1velByaW50YWJsZUtleWAgZm9yIGFsbFxuICAgIC8vIHByaW50YWJsZSBjaGFyYWN0ZXJzIChub3JtYWxpemVkIHRvIGBVbmlkZW50aWZpZWRgKSwgaWdub3JlIGl0LlxuICAgIHZhciBrZXkgPSBub3JtYWxpemVLZXlbbmF0aXZlRXZlbnQua2V5XSB8fCBuYXRpdmVFdmVudC5rZXk7XG5cbiAgICBpZiAoa2V5ICE9PSAnVW5pZGVudGlmaWVkJykge1xuICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG4gIH0gLy8gQnJvd3NlciBkb2VzIG5vdCBpbXBsZW1lbnQgYGtleWAsIHBvbHlmaWxsIGFzIG11Y2ggb2YgaXQgYXMgd2UgY2FuLlxuXG5cbiAgaWYgKG5hdGl2ZUV2ZW50LnR5cGUgPT09ICdrZXlwcmVzcycpIHtcbiAgICB2YXIgY2hhckNvZGUgPSBnZXRFdmVudENoYXJDb2RlKG5hdGl2ZUV2ZW50KTsgLy8gVGhlIGVudGVyLWtleSBpcyB0ZWNobmljYWxseSBib3RoIHByaW50YWJsZSBhbmQgbm9uLXByaW50YWJsZSBhbmQgY2FuXG4gICAgLy8gdGh1cyBiZSBjYXB0dXJlZCBieSBga2V5cHJlc3NgLCBubyBvdGhlciBub24tcHJpbnRhYmxlIGtleSBzaG91bGQuXG5cbiAgICByZXR1cm4gY2hhckNvZGUgPT09IDEzID8gJ0VudGVyJyA6IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hhckNvZGUpO1xuICB9XG5cbiAgaWYgKG5hdGl2ZUV2ZW50LnR5cGUgPT09ICdrZXlkb3duJyB8fCBuYXRpdmVFdmVudC50eXBlID09PSAna2V5dXAnKSB7XG4gICAgLy8gV2hpbGUgdXNlciBrZXlib2FyZCBsYXlvdXQgZGV0ZXJtaW5lcyB0aGUgYWN0dWFsIG1lYW5pbmcgb2YgZWFjaFxuICAgIC8vIGBrZXlDb2RlYCB2YWx1ZSwgYWxtb3N0IGFsbCBmdW5jdGlvbiBrZXlzIGhhdmUgYSB1bml2ZXJzYWwgdmFsdWUuXG4gICAgcmV0dXJuIHRyYW5zbGF0ZVRvS2V5W25hdGl2ZUV2ZW50LmtleUNvZGVdIHx8ICdVbmlkZW50aWZpZWQnO1xuICB9XG5cbiAgcmV0dXJuICcnO1xufVxuLyoqXG4gKiBUcmFuc2xhdGlvbiBmcm9tIG1vZGlmaWVyIGtleSB0byB0aGUgYXNzb2NpYXRlZCBwcm9wZXJ0eSBpbiB0aGUgZXZlbnQuXG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy8ja2V5cy1Nb2RpZmllcnNcbiAqL1xuXG5cbnZhciBtb2RpZmllcktleVRvUHJvcCA9IHtcbiAgQWx0OiAnYWx0S2V5JyxcbiAgQ29udHJvbDogJ2N0cmxLZXknLFxuICBNZXRhOiAnbWV0YUtleScsXG4gIFNoaWZ0OiAnc2hpZnRLZXknXG59OyAvLyBPbGRlciBicm93c2VycyAoU2FmYXJpIDw9IDEwLCBpT1MgU2FmYXJpIDw9IDEwLjIpIGRvIG5vdCBzdXBwb3J0XG4vLyBnZXRNb2RpZmllclN0YXRlLiBJZiBnZXRNb2RpZmllclN0YXRlIGlzIG5vdCBzdXBwb3J0ZWQsIHdlIG1hcCBpdCB0byBhIHNldCBvZlxuLy8gbW9kaWZpZXIga2V5cyBleHBvc2VkIGJ5IHRoZSBldmVudC4gSW4gdGhpcyBjYXNlLCBMb2NrLWtleXMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cbmZ1bmN0aW9uIG1vZGlmaWVyU3RhdGVHZXR0ZXIoa2V5QXJnKSB7XG4gIHZhciBzeW50aGV0aWNFdmVudCA9IHRoaXM7XG4gIHZhciBuYXRpdmVFdmVudCA9IHN5bnRoZXRpY0V2ZW50Lm5hdGl2ZUV2ZW50O1xuXG4gIGlmIChuYXRpdmVFdmVudC5nZXRNb2RpZmllclN0YXRlKSB7XG4gICAgcmV0dXJuIG5hdGl2ZUV2ZW50LmdldE1vZGlmaWVyU3RhdGUoa2V5QXJnKTtcbiAgfVxuXG4gIHZhciBrZXlQcm9wID0gbW9kaWZpZXJLZXlUb1Byb3Bba2V5QXJnXTtcbiAgcmV0dXJuIGtleVByb3AgPyAhIW5hdGl2ZUV2ZW50W2tleVByb3BdIDogZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGdldEV2ZW50TW9kaWZpZXJTdGF0ZShuYXRpdmVFdmVudCkge1xuICByZXR1cm4gbW9kaWZpZXJTdGF0ZUdldHRlcjtcbn1cbi8qKlxuICogQGludGVyZmFjZSBLZXlib2FyZEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy9cbiAqL1xuXG5cbnZhciBLZXlib2FyZEV2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBVSUV2ZW50SW50ZXJmYWNlLCB7XG4gIGtleTogZ2V0RXZlbnRLZXksXG4gIGNvZGU6IDAsXG4gIGxvY2F0aW9uOiAwLFxuICBjdHJsS2V5OiAwLFxuICBzaGlmdEtleTogMCxcbiAgYWx0S2V5OiAwLFxuICBtZXRhS2V5OiAwLFxuICByZXBlYXQ6IDAsXG4gIGxvY2FsZTogMCxcbiAgZ2V0TW9kaWZpZXJTdGF0ZTogZ2V0RXZlbnRNb2RpZmllclN0YXRlLFxuICAvLyBMZWdhY3kgSW50ZXJmYWNlXG4gIGNoYXJDb2RlOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAvLyBgY2hhckNvZGVgIGlzIHRoZSByZXN1bHQgb2YgYSBLZXlQcmVzcyBldmVudCBhbmQgcmVwcmVzZW50cyB0aGUgdmFsdWUgb2ZcbiAgICAvLyB0aGUgYWN0dWFsIHByaW50YWJsZSBjaGFyYWN0ZXIuXG4gICAgLy8gS2V5UHJlc3MgaXMgZGVwcmVjYXRlZCwgYnV0IGl0cyByZXBsYWNlbWVudCBpcyBub3QgeWV0IGZpbmFsIGFuZCBub3RcbiAgICAvLyBpbXBsZW1lbnRlZCBpbiBhbnkgbWFqb3IgYnJvd3Nlci4gT25seSBLZXlQcmVzcyBoYXMgY2hhckNvZGUuXG4gICAgaWYgKGV2ZW50LnR5cGUgPT09ICdrZXlwcmVzcycpIHtcbiAgICAgIHJldHVybiBnZXRFdmVudENoYXJDb2RlKGV2ZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gMDtcbiAgfSxcbiAga2V5Q29kZTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgLy8gYGtleUNvZGVgIGlzIHRoZSByZXN1bHQgb2YgYSBLZXlEb3duL1VwIGV2ZW50IGFuZCByZXByZXNlbnRzIHRoZSB2YWx1ZSBvZlxuICAgIC8vIHBoeXNpY2FsIGtleWJvYXJkIGtleS5cbiAgICAvLyBUaGUgYWN0dWFsIG1lYW5pbmcgb2YgdGhlIHZhbHVlIGRlcGVuZHMgb24gdGhlIHVzZXJzJyBrZXlib2FyZCBsYXlvdXRcbiAgICAvLyB3aGljaCBjYW5ub3QgYmUgZGV0ZWN0ZWQuIEFzc3VtaW5nIHRoYXQgaXQgaXMgYSBVUyBrZXlib2FyZCBsYXlvdXRcbiAgICAvLyBwcm92aWRlcyBhIHN1cnByaXNpbmdseSBhY2N1cmF0ZSBtYXBwaW5nIGZvciBVUyBhbmQgRXVyb3BlYW4gdXNlcnMuXG4gICAgLy8gRHVlIHRvIHRoaXMsIGl0IGlzIGxlZnQgdG8gdGhlIHVzZXIgdG8gaW1wbGVtZW50IGF0IHRoaXMgdGltZS5cbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2tleWRvd24nIHx8IGV2ZW50LnR5cGUgPT09ICdrZXl1cCcpIHtcbiAgICAgIHJldHVybiBldmVudC5rZXlDb2RlO1xuICAgIH1cblxuICAgIHJldHVybiAwO1xuICB9LFxuICB3aGljaDogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgLy8gYHdoaWNoYCBpcyBhbiBhbGlhcyBmb3IgZWl0aGVyIGBrZXlDb2RlYCBvciBgY2hhckNvZGVgIGRlcGVuZGluZyBvbiB0aGVcbiAgICAvLyB0eXBlIG9mIHRoZSBldmVudC5cbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2tleXByZXNzJykge1xuICAgICAgcmV0dXJuIGdldEV2ZW50Q2hhckNvZGUoZXZlbnQpO1xuICAgIH1cblxuICAgIGlmIChldmVudC50eXBlID09PSAna2V5ZG93bicgfHwgZXZlbnQudHlwZSA9PT0gJ2tleXVwJykge1xuICAgICAgcmV0dXJuIGV2ZW50LmtleUNvZGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIDA7XG4gIH1cbn0pO1xuXG52YXIgU3ludGhldGljS2V5Ym9hcmRFdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KEtleWJvYXJkRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIFBvaW50ZXJFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9wb2ludGVyZXZlbnRzL1xuICovXG5cbnZhciBQb2ludGVyRXZlbnRJbnRlcmZhY2UgPSBhc3NpZ24oe30sIE1vdXNlRXZlbnRJbnRlcmZhY2UsIHtcbiAgcG9pbnRlcklkOiAwLFxuICB3aWR0aDogMCxcbiAgaGVpZ2h0OiAwLFxuICBwcmVzc3VyZTogMCxcbiAgdGFuZ2VudGlhbFByZXNzdXJlOiAwLFxuICB0aWx0WDogMCxcbiAgdGlsdFk6IDAsXG4gIHR3aXN0OiAwLFxuICBwb2ludGVyVHlwZTogMCxcbiAgaXNQcmltYXJ5OiAwXG59KTtcblxudmFyIFN5bnRoZXRpY1BvaW50ZXJFdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KFBvaW50ZXJFdmVudEludGVyZmFjZSk7XG4vKipcbiAqIEBpbnRlcmZhY2UgVG91Y2hFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi90b3VjaC1ldmVudHMvXG4gKi9cblxudmFyIFRvdWNoRXZlbnRJbnRlcmZhY2UgPSBhc3NpZ24oe30sIFVJRXZlbnRJbnRlcmZhY2UsIHtcbiAgdG91Y2hlczogMCxcbiAgdGFyZ2V0VG91Y2hlczogMCxcbiAgY2hhbmdlZFRvdWNoZXM6IDAsXG4gIGFsdEtleTogMCxcbiAgbWV0YUtleTogMCxcbiAgY3RybEtleTogMCxcbiAgc2hpZnRLZXk6IDAsXG4gIGdldE1vZGlmaWVyU3RhdGU6IGdldEV2ZW50TW9kaWZpZXJTdGF0ZVxufSk7XG5cbnZhciBTeW50aGV0aWNUb3VjaEV2ZW50ID0gY3JlYXRlU3ludGhldGljRXZlbnQoVG91Y2hFdmVudEludGVyZmFjZSk7XG4vKipcbiAqIEBpbnRlcmZhY2UgRXZlbnRcbiAqIEBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvMjAwOS9XRC1jc3MzLXRyYW5zaXRpb25zLTIwMDkwMzIwLyN0cmFuc2l0aW9uLWV2ZW50cy1cbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1RyYW5zaXRpb25FdmVudFxuICovXG5cbnZhciBUcmFuc2l0aW9uRXZlbnRJbnRlcmZhY2UgPSBhc3NpZ24oe30sIEV2ZW50SW50ZXJmYWNlLCB7XG4gIHByb3BlcnR5TmFtZTogMCxcbiAgZWxhcHNlZFRpbWU6IDAsXG4gIHBzZXVkb0VsZW1lbnQ6IDBcbn0pO1xuXG52YXIgU3ludGhldGljVHJhbnNpdGlvbkV2ZW50ID0gY3JlYXRlU3ludGhldGljRXZlbnQoVHJhbnNpdGlvbkV2ZW50SW50ZXJmYWNlKTtcbi8qKlxuICogQGludGVyZmFjZSBXaGVlbEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy9cbiAqL1xuXG52YXIgV2hlZWxFdmVudEludGVyZmFjZSA9IGFzc2lnbih7fSwgTW91c2VFdmVudEludGVyZmFjZSwge1xuICBkZWx0YVg6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHJldHVybiAnZGVsdGFYJyBpbiBldmVudCA/IGV2ZW50LmRlbHRhWCA6IC8vIEZhbGxiYWNrIHRvIGB3aGVlbERlbHRhWGAgZm9yIFdlYmtpdCBhbmQgbm9ybWFsaXplIChyaWdodCBpcyBwb3NpdGl2ZSkuXG4gICAgJ3doZWVsRGVsdGFYJyBpbiBldmVudCA/IC1ldmVudC53aGVlbERlbHRhWCA6IDA7XG4gIH0sXG4gIGRlbHRhWTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgcmV0dXJuICdkZWx0YVknIGluIGV2ZW50ID8gZXZlbnQuZGVsdGFZIDogLy8gRmFsbGJhY2sgdG8gYHdoZWVsRGVsdGFZYCBmb3IgV2Via2l0IGFuZCBub3JtYWxpemUgKGRvd24gaXMgcG9zaXRpdmUpLlxuICAgICd3aGVlbERlbHRhWScgaW4gZXZlbnQgPyAtZXZlbnQud2hlZWxEZWx0YVkgOiAvLyBGYWxsYmFjayB0byBgd2hlZWxEZWx0YWAgZm9yIElFPDkgYW5kIG5vcm1hbGl6ZSAoZG93biBpcyBwb3NpdGl2ZSkuXG4gICAgJ3doZWVsRGVsdGEnIGluIGV2ZW50ID8gLWV2ZW50LndoZWVsRGVsdGEgOiAwO1xuICB9LFxuICBkZWx0YVo6IDAsXG4gIC8vIEJyb3dzZXJzIHdpdGhvdXQgXCJkZWx0YU1vZGVcIiBpcyByZXBvcnRpbmcgaW4gcmF3IHdoZWVsIGRlbHRhIHdoZXJlIG9uZVxuICAvLyBub3RjaCBvbiB0aGUgc2Nyb2xsIGlzIGFsd2F5cyArLy0gMTIwLCByb3VnaGx5IGVxdWl2YWxlbnQgdG8gcGl4ZWxzLlxuICAvLyBBIGdvb2QgYXBwcm94aW1hdGlvbiBvZiBET01fREVMVEFfTElORSAoMSkgaXMgNSUgb2Ygdmlld3BvcnQgc2l6ZSBvclxuICAvLyB+NDAgcGl4ZWxzLCBmb3IgRE9NX0RFTFRBX1NDUkVFTiAoMikgaXQgaXMgODcuNSUgb2Ygdmlld3BvcnQgc2l6ZS5cbiAgZGVsdGFNb2RlOiAwXG59KTtcblxudmFyIFN5bnRoZXRpY1doZWVsRXZlbnQgPSBjcmVhdGVTeW50aGV0aWNFdmVudChXaGVlbEV2ZW50SW50ZXJmYWNlKTtcblxudmFyIEVORF9LRVlDT0RFUyA9IFs5LCAxMywgMjcsIDMyXTsgLy8gVGFiLCBSZXR1cm4sIEVzYywgU3BhY2VcblxudmFyIFNUQVJUX0tFWUNPREUgPSAyMjk7XG52YXIgY2FuVXNlQ29tcG9zaXRpb25FdmVudCA9IGNhblVzZURPTSAmJiAnQ29tcG9zaXRpb25FdmVudCcgaW4gd2luZG93O1xudmFyIGRvY3VtZW50TW9kZSA9IG51bGw7XG5cbmlmIChjYW5Vc2VET00gJiYgJ2RvY3VtZW50TW9kZScgaW4gZG9jdW1lbnQpIHtcbiAgZG9jdW1lbnRNb2RlID0gZG9jdW1lbnQuZG9jdW1lbnRNb2RlO1xufSAvLyBXZWJraXQgb2ZmZXJzIGEgdmVyeSB1c2VmdWwgYHRleHRJbnB1dGAgZXZlbnQgdGhhdCBjYW4gYmUgdXNlZCB0b1xuLy8gZGlyZWN0bHkgcmVwcmVzZW50IGBiZWZvcmVJbnB1dGAuIFRoZSBJRSBgdGV4dGlucHV0YCBldmVudCBpcyBub3QgYXNcbi8vIHVzZWZ1bCwgc28gd2UgZG9uJ3QgdXNlIGl0LlxuXG5cbnZhciBjYW5Vc2VUZXh0SW5wdXRFdmVudCA9IGNhblVzZURPTSAmJiAnVGV4dEV2ZW50JyBpbiB3aW5kb3cgJiYgIWRvY3VtZW50TW9kZTsgLy8gSW4gSUU5Kywgd2UgaGF2ZSBhY2Nlc3MgdG8gY29tcG9zaXRpb24gZXZlbnRzLCBidXQgdGhlIGRhdGEgc3VwcGxpZWRcbi8vIGJ5IHRoZSBuYXRpdmUgY29tcG9zaXRpb25lbmQgZXZlbnQgbWF5IGJlIGluY29ycmVjdC4gSmFwYW5lc2UgaWRlb2dyYXBoaWNcbi8vIHNwYWNlcywgZm9yIGluc3RhbmNlIChcXHUzMDAwKSBhcmUgbm90IHJlY29yZGVkIGNvcnJlY3RseS5cblxudmFyIHVzZUZhbGxiYWNrQ29tcG9zaXRpb25EYXRhID0gY2FuVXNlRE9NICYmICghY2FuVXNlQ29tcG9zaXRpb25FdmVudCB8fCBkb2N1bWVudE1vZGUgJiYgZG9jdW1lbnRNb2RlID4gOCAmJiBkb2N1bWVudE1vZGUgPD0gMTEpO1xudmFyIFNQQUNFQkFSX0NPREUgPSAzMjtcbnZhciBTUEFDRUJBUl9DSEFSID0gU3RyaW5nLmZyb21DaGFyQ29kZShTUEFDRUJBUl9DT0RFKTtcblxuZnVuY3Rpb24gcmVnaXN0ZXJFdmVudHMoKSB7XG4gIHJlZ2lzdGVyVHdvUGhhc2VFdmVudCgnb25CZWZvcmVJbnB1dCcsIFsnY29tcG9zaXRpb25lbmQnLCAna2V5cHJlc3MnLCAndGV4dElucHV0JywgJ3Bhc3RlJ10pO1xuICByZWdpc3RlclR3b1BoYXNlRXZlbnQoJ29uQ29tcG9zaXRpb25FbmQnLCBbJ2NvbXBvc2l0aW9uZW5kJywgJ2ZvY3Vzb3V0JywgJ2tleWRvd24nLCAna2V5cHJlc3MnLCAna2V5dXAnLCAnbW91c2Vkb3duJ10pO1xuICByZWdpc3RlclR3b1BoYXNlRXZlbnQoJ29uQ29tcG9zaXRpb25TdGFydCcsIFsnY29tcG9zaXRpb25zdGFydCcsICdmb2N1c291dCcsICdrZXlkb3duJywgJ2tleXByZXNzJywgJ2tleXVwJywgJ21vdXNlZG93biddKTtcbiAgcmVnaXN0ZXJUd29QaGFzZUV2ZW50KCdvbkNvbXBvc2l0aW9uVXBkYXRlJywgWydjb21wb3NpdGlvbnVwZGF0ZScsICdmb2N1c291dCcsICdrZXlkb3duJywgJ2tleXByZXNzJywgJ2tleXVwJywgJ21vdXNlZG93biddKTtcbn0gLy8gVHJhY2sgd2hldGhlciB3ZSd2ZSBldmVyIGhhbmRsZWQgYSBrZXlwcmVzcyBvbiB0aGUgc3BhY2Uga2V5LlxuXG5cbnZhciBoYXNTcGFjZUtleXByZXNzID0gZmFsc2U7XG4vKipcbiAqIFJldHVybiB3aGV0aGVyIGEgbmF0aXZlIGtleXByZXNzIGV2ZW50IGlzIGFzc3VtZWQgdG8gYmUgYSBjb21tYW5kLlxuICogVGhpcyBpcyByZXF1aXJlZCBiZWNhdXNlIEZpcmVmb3ggZmlyZXMgYGtleXByZXNzYCBldmVudHMgZm9yIGtleSBjb21tYW5kc1xuICogKGN1dCwgY29weSwgc2VsZWN0LWFsbCwgZXRjLikgZXZlbiB0aG91Z2ggbm8gY2hhcmFjdGVyIGlzIGluc2VydGVkLlxuICovXG5cbmZ1bmN0aW9uIGlzS2V5cHJlc3NDb21tYW5kKG5hdGl2ZUV2ZW50KSB7XG4gIHJldHVybiAobmF0aXZlRXZlbnQuY3RybEtleSB8fCBuYXRpdmVFdmVudC5hbHRLZXkgfHwgbmF0aXZlRXZlbnQubWV0YUtleSkgJiYgLy8gY3RybEtleSAmJiBhbHRLZXkgaXMgZXF1aXZhbGVudCB0byBBbHRHciwgYW5kIGlzIG5vdCBhIGNvbW1hbmQuXG4gICEobmF0aXZlRXZlbnQuY3RybEtleSAmJiBuYXRpdmVFdmVudC5hbHRLZXkpO1xufVxuLyoqXG4gKiBUcmFuc2xhdGUgbmF0aXZlIHRvcCBsZXZlbCBldmVudHMgaW50byBldmVudCB0eXBlcy5cbiAqL1xuXG5cbmZ1bmN0aW9uIGdldENvbXBvc2l0aW9uRXZlbnRUeXBlKGRvbUV2ZW50TmFtZSkge1xuICBzd2l0Y2ggKGRvbUV2ZW50TmFtZSkge1xuICAgIGNhc2UgJ2NvbXBvc2l0aW9uc3RhcnQnOlxuICAgICAgcmV0dXJuICdvbkNvbXBvc2l0aW9uU3RhcnQnO1xuXG4gICAgY2FzZSAnY29tcG9zaXRpb25lbmQnOlxuICAgICAgcmV0dXJuICdvbkNvbXBvc2l0aW9uRW5kJztcblxuICAgIGNhc2UgJ2NvbXBvc2l0aW9udXBkYXRlJzpcbiAgICAgIHJldHVybiAnb25Db21wb3NpdGlvblVwZGF0ZSc7XG4gIH1cbn1cbi8qKlxuICogRG9lcyBvdXIgZmFsbGJhY2sgYmVzdC1ndWVzcyBtb2RlbCB0aGluayB0aGlzIGV2ZW50IHNpZ25pZmllcyB0aGF0XG4gKiBjb21wb3NpdGlvbiBoYXMgYmVndW4/XG4gKi9cblxuXG5mdW5jdGlvbiBpc0ZhbGxiYWNrQ29tcG9zaXRpb25TdGFydChkb21FdmVudE5hbWUsIG5hdGl2ZUV2ZW50KSB7XG4gIHJldHVybiBkb21FdmVudE5hbWUgPT09ICdrZXlkb3duJyAmJiBuYXRpdmVFdmVudC5rZXlDb2RlID09PSBTVEFSVF9LRVlDT0RFO1xufVxuLyoqXG4gKiBEb2VzIG91ciBmYWxsYmFjayBtb2RlIHRoaW5rIHRoYXQgdGhpcyBldmVudCBpcyB0aGUgZW5kIG9mIGNvbXBvc2l0aW9uP1xuICovXG5cblxuZnVuY3Rpb24gaXNGYWxsYmFja0NvbXBvc2l0aW9uRW5kKGRvbUV2ZW50TmFtZSwgbmF0aXZlRXZlbnQpIHtcbiAgc3dpdGNoIChkb21FdmVudE5hbWUpIHtcbiAgICBjYXNlICdrZXl1cCc6XG4gICAgICAvLyBDb21tYW5kIGtleXMgaW5zZXJ0IG9yIGNsZWFyIElNRSBpbnB1dC5cbiAgICAgIHJldHVybiBFTkRfS0VZQ09ERVMuaW5kZXhPZihuYXRpdmVFdmVudC5rZXlDb2RlKSAhPT0gLTE7XG5cbiAgICBjYXNlICdrZXlkb3duJzpcbiAgICAgIC8vIEV4cGVjdCBJTUUga2V5Q29kZSBvbiBlYWNoIGtleWRvd24uIElmIHdlIGdldCBhbnkgb3RoZXJcbiAgICAgIC8vIGNvZGUgd2UgbXVzdCBoYXZlIGV4aXRlZCBlYXJsaWVyLlxuICAgICAgcmV0dXJuIG5hdGl2ZUV2ZW50LmtleUNvZGUgIT09IFNUQVJUX0tFWUNPREU7XG5cbiAgICBjYXNlICdrZXlwcmVzcyc6XG4gICAgY2FzZSAnbW91c2Vkb3duJzpcbiAgICBjYXNlICdmb2N1c291dCc6XG4gICAgICAvLyBFdmVudHMgYXJlIG5vdCBwb3NzaWJsZSB3aXRob3V0IGNhbmNlbGxpbmcgSU1FLlxuICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG4vKipcbiAqIEdvb2dsZSBJbnB1dCBUb29scyBwcm92aWRlcyBjb21wb3NpdGlvbiBkYXRhIHZpYSBhIEN1c3RvbUV2ZW50LFxuICogd2l0aCB0aGUgYGRhdGFgIHByb3BlcnR5IHBvcHVsYXRlZCBpbiB0aGUgYGRldGFpbGAgb2JqZWN0LiBJZiB0aGlzXG4gKiBpcyBhdmFpbGFibGUgb24gdGhlIGV2ZW50IG9iamVjdCwgdXNlIGl0LiBJZiBub3QsIHRoaXMgaXMgYSBwbGFpblxuICogY29tcG9zaXRpb24gZXZlbnQgYW5kIHdlIGhhdmUgbm90aGluZyBzcGVjaWFsIHRvIGV4dHJhY3QuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50XG4gKiBAcmV0dXJuIHs/c3RyaW5nfVxuICovXG5cblxuZnVuY3Rpb24gZ2V0RGF0YUZyb21DdXN0b21FdmVudChuYXRpdmVFdmVudCkge1xuICB2YXIgZGV0YWlsID0gbmF0aXZlRXZlbnQuZGV0YWlsO1xuXG4gIGlmICh0eXBlb2YgZGV0YWlsID09PSAnb2JqZWN0JyAmJiAnZGF0YScgaW4gZGV0YWlsKSB7XG4gICAgcmV0dXJuIGRldGFpbC5kYXRhO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG4vKipcbiAqIENoZWNrIGlmIGEgY29tcG9zaXRpb24gZXZlbnQgd2FzIHRyaWdnZXJlZCBieSBLb3JlYW4gSU1FLlxuICogT3VyIGZhbGxiYWNrIG1vZGUgZG9lcyBub3Qgd29yayB3ZWxsIHdpdGggSUUncyBLb3JlYW4gSU1FLFxuICogc28ganVzdCB1c2UgbmF0aXZlIGNvbXBvc2l0aW9uIGV2ZW50cyB3aGVuIEtvcmVhbiBJTUUgaXMgdXNlZC5cbiAqIEFsdGhvdWdoIENvbXBvc2l0aW9uRXZlbnQubG9jYWxlIHByb3BlcnR5IGlzIGRlcHJlY2F0ZWQsXG4gKiBpdCBpcyBhdmFpbGFibGUgaW4gSUUsIHdoZXJlIG91ciBmYWxsYmFjayBtb2RlIGlzIGVuYWJsZWQuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5cblxuZnVuY3Rpb24gaXNVc2luZ0tvcmVhbklNRShuYXRpdmVFdmVudCkge1xuICByZXR1cm4gbmF0aXZlRXZlbnQubG9jYWxlID09PSAna28nO1xufSAvLyBUcmFjayB0aGUgY3VycmVudCBJTUUgY29tcG9zaXRpb24gc3RhdHVzLCBpZiBhbnkuXG5cblxudmFyIGlzQ29tcG9zaW5nID0gZmFsc2U7XG4vKipcbiAqIEByZXR1cm4gez9vYmplY3R9IEEgU3ludGhldGljQ29tcG9zaXRpb25FdmVudC5cbiAqL1xuXG5mdW5jdGlvbiBleHRyYWN0Q29tcG9zaXRpb25FdmVudChkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICB2YXIgZXZlbnRUeXBlO1xuICB2YXIgZmFsbGJhY2tEYXRhO1xuXG4gIGlmIChjYW5Vc2VDb21wb3NpdGlvbkV2ZW50KSB7XG4gICAgZXZlbnRUeXBlID0gZ2V0Q29tcG9zaXRpb25FdmVudFR5cGUoZG9tRXZlbnROYW1lKTtcbiAgfSBlbHNlIGlmICghaXNDb21wb3NpbmcpIHtcbiAgICBpZiAoaXNGYWxsYmFja0NvbXBvc2l0aW9uU3RhcnQoZG9tRXZlbnROYW1lLCBuYXRpdmVFdmVudCkpIHtcbiAgICAgIGV2ZW50VHlwZSA9ICdvbkNvbXBvc2l0aW9uU3RhcnQnO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc0ZhbGxiYWNrQ29tcG9zaXRpb25FbmQoZG9tRXZlbnROYW1lLCBuYXRpdmVFdmVudCkpIHtcbiAgICBldmVudFR5cGUgPSAnb25Db21wb3NpdGlvbkVuZCc7XG4gIH1cblxuICBpZiAoIWV2ZW50VHlwZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKHVzZUZhbGxiYWNrQ29tcG9zaXRpb25EYXRhICYmICFpc1VzaW5nS29yZWFuSU1FKG5hdGl2ZUV2ZW50KSkge1xuICAgIC8vIFRoZSBjdXJyZW50IGNvbXBvc2l0aW9uIGlzIHN0b3JlZCBzdGF0aWNhbGx5IGFuZCBtdXN0IG5vdCBiZVxuICAgIC8vIG92ZXJ3cml0dGVuIHdoaWxlIGNvbXBvc2l0aW9uIGNvbnRpbnVlcy5cbiAgICBpZiAoIWlzQ29tcG9zaW5nICYmIGV2ZW50VHlwZSA9PT0gJ29uQ29tcG9zaXRpb25TdGFydCcpIHtcbiAgICAgIGlzQ29tcG9zaW5nID0gaW5pdGlhbGl6ZShuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgfSBlbHNlIGlmIChldmVudFR5cGUgPT09ICdvbkNvbXBvc2l0aW9uRW5kJykge1xuICAgICAgaWYgKGlzQ29tcG9zaW5nKSB7XG4gICAgICAgIGZhbGxiYWNrRGF0YSA9IGdldERhdGEoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgbGlzdGVuZXJzID0gYWNjdW11bGF0ZVR3b1BoYXNlTGlzdGVuZXJzKHRhcmdldEluc3QsIGV2ZW50VHlwZSk7XG5cbiAgaWYgKGxpc3RlbmVycy5sZW5ndGggPiAwKSB7XG4gICAgdmFyIGV2ZW50ID0gbmV3IFN5bnRoZXRpY0NvbXBvc2l0aW9uRXZlbnQoZXZlbnRUeXBlLCBkb21FdmVudE5hbWUsIG51bGwsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgZGlzcGF0Y2hRdWV1ZS5wdXNoKHtcbiAgICAgIGV2ZW50OiBldmVudCxcbiAgICAgIGxpc3RlbmVyczogbGlzdGVuZXJzXG4gICAgfSk7XG5cbiAgICBpZiAoZmFsbGJhY2tEYXRhKSB7XG4gICAgICAvLyBJbmplY3QgZGF0YSBnZW5lcmF0ZWQgZnJvbSBmYWxsYmFjayBwYXRoIGludG8gdGhlIHN5bnRoZXRpYyBldmVudC5cbiAgICAgIC8vIFRoaXMgbWF0Y2hlcyB0aGUgcHJvcGVydHkgb2YgbmF0aXZlIENvbXBvc2l0aW9uRXZlbnRJbnRlcmZhY2UuXG4gICAgICBldmVudC5kYXRhID0gZmFsbGJhY2tEYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgY3VzdG9tRGF0YSA9IGdldERhdGFGcm9tQ3VzdG9tRXZlbnQobmF0aXZlRXZlbnQpO1xuXG4gICAgICBpZiAoY3VzdG9tRGF0YSAhPT0gbnVsbCkge1xuICAgICAgICBldmVudC5kYXRhID0gY3VzdG9tRGF0YTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0TmF0aXZlQmVmb3JlSW5wdXRDaGFycyhkb21FdmVudE5hbWUsIG5hdGl2ZUV2ZW50KSB7XG4gIHN3aXRjaCAoZG9tRXZlbnROYW1lKSB7XG4gICAgY2FzZSAnY29tcG9zaXRpb25lbmQnOlxuICAgICAgcmV0dXJuIGdldERhdGFGcm9tQ3VzdG9tRXZlbnQobmF0aXZlRXZlbnQpO1xuXG4gICAgY2FzZSAna2V5cHJlc3MnOlxuICAgICAgLyoqXG4gICAgICAgKiBJZiBuYXRpdmUgYHRleHRJbnB1dGAgZXZlbnRzIGFyZSBhdmFpbGFibGUsIG91ciBnb2FsIGlzIHRvIG1ha2VcbiAgICAgICAqIHVzZSBvZiB0aGVtLiBIb3dldmVyLCB0aGVyZSBpcyBhIHNwZWNpYWwgY2FzZTogdGhlIHNwYWNlYmFyIGtleS5cbiAgICAgICAqIEluIFdlYmtpdCwgcHJldmVudGluZyBkZWZhdWx0IG9uIGEgc3BhY2ViYXIgYHRleHRJbnB1dGAgZXZlbnRcbiAgICAgICAqIGNhbmNlbHMgY2hhcmFjdGVyIGluc2VydGlvbiwgYnV0IGl0ICphbHNvKiBjYXVzZXMgdGhlIGJyb3dzZXJcbiAgICAgICAqIHRvIGZhbGwgYmFjayB0byBpdHMgZGVmYXVsdCBzcGFjZWJhciBiZWhhdmlvciBvZiBzY3JvbGxpbmcgdGhlXG4gICAgICAgKiBwYWdlLlxuICAgICAgICpcbiAgICAgICAqIFRyYWNraW5nIGF0OlxuICAgICAgICogaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTM1NTEwM1xuICAgICAgICpcbiAgICAgICAqIFRvIGF2b2lkIHRoaXMgaXNzdWUsIHVzZSB0aGUga2V5cHJlc3MgZXZlbnQgYXMgaWYgbm8gYHRleHRJbnB1dGBcbiAgICAgICAqIGV2ZW50IGlzIGF2YWlsYWJsZS5cbiAgICAgICAqL1xuICAgICAgdmFyIHdoaWNoID0gbmF0aXZlRXZlbnQud2hpY2g7XG5cbiAgICAgIGlmICh3aGljaCAhPT0gU1BBQ0VCQVJfQ09ERSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgaGFzU3BhY2VLZXlwcmVzcyA9IHRydWU7XG4gICAgICByZXR1cm4gU1BBQ0VCQVJfQ0hBUjtcblxuICAgIGNhc2UgJ3RleHRJbnB1dCc6XG4gICAgICAvLyBSZWNvcmQgdGhlIGNoYXJhY3RlcnMgdG8gYmUgYWRkZWQgdG8gdGhlIERPTS5cbiAgICAgIHZhciBjaGFycyA9IG5hdGl2ZUV2ZW50LmRhdGE7IC8vIElmIGl0J3MgYSBzcGFjZWJhciBjaGFyYWN0ZXIsIGFzc3VtZSB0aGF0IHdlIGhhdmUgYWxyZWFkeSBoYW5kbGVkXG4gICAgICAvLyBpdCBhdCB0aGUga2V5cHJlc3MgbGV2ZWwgYW5kIGJhaWwgaW1tZWRpYXRlbHkuIEFuZHJvaWQgQ2hyb21lXG4gICAgICAvLyBkb2Vzbid0IGdpdmUgdXMga2V5Y29kZXMsIHNvIHdlIG5lZWQgdG8gaWdub3JlIGl0LlxuXG4gICAgICBpZiAoY2hhcnMgPT09IFNQQUNFQkFSX0NIQVIgJiYgaGFzU3BhY2VLZXlwcmVzcykge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNoYXJzO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIEZvciBvdGhlciBuYXRpdmUgZXZlbnQgdHlwZXMsIGRvIG5vdGhpbmcuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuLyoqXG4gKiBGb3IgYnJvd3NlcnMgdGhhdCBkbyBub3QgcHJvdmlkZSB0aGUgYHRleHRJbnB1dGAgZXZlbnQsIGV4dHJhY3QgdGhlXG4gKiBhcHByb3ByaWF0ZSBzdHJpbmcgdG8gdXNlIGZvciBTeW50aGV0aWNJbnB1dEV2ZW50LlxuICovXG5cblxuZnVuY3Rpb24gZ2V0RmFsbGJhY2tCZWZvcmVJbnB1dENoYXJzKGRvbUV2ZW50TmFtZSwgbmF0aXZlRXZlbnQpIHtcbiAgLy8gSWYgd2UgYXJlIGN1cnJlbnRseSBjb21wb3NpbmcgKElNRSkgYW5kIHVzaW5nIGEgZmFsbGJhY2sgdG8gZG8gc28sXG4gIC8vIHRyeSB0byBleHRyYWN0IHRoZSBjb21wb3NlZCBjaGFyYWN0ZXJzIGZyb20gdGhlIGZhbGxiYWNrIG9iamVjdC5cbiAgLy8gSWYgY29tcG9zaXRpb24gZXZlbnQgaXMgYXZhaWxhYmxlLCB3ZSBleHRyYWN0IGEgc3RyaW5nIG9ubHkgYXRcbiAgLy8gY29tcG9zaXRpb25ldmVudCwgb3RoZXJ3aXNlIGV4dHJhY3QgaXQgYXQgZmFsbGJhY2sgZXZlbnRzLlxuICBpZiAoaXNDb21wb3NpbmcpIHtcbiAgICBpZiAoZG9tRXZlbnROYW1lID09PSAnY29tcG9zaXRpb25lbmQnIHx8ICFjYW5Vc2VDb21wb3NpdGlvbkV2ZW50ICYmIGlzRmFsbGJhY2tDb21wb3NpdGlvbkVuZChkb21FdmVudE5hbWUsIG5hdGl2ZUV2ZW50KSkge1xuICAgICAgdmFyIGNoYXJzID0gZ2V0RGF0YSgpO1xuICAgICAgcmVzZXQoKTtcbiAgICAgIGlzQ29tcG9zaW5nID0gZmFsc2U7XG4gICAgICByZXR1cm4gY2hhcnM7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzd2l0Y2ggKGRvbUV2ZW50TmFtZSkge1xuICAgIGNhc2UgJ3Bhc3RlJzpcbiAgICAgIC8vIElmIGEgcGFzdGUgZXZlbnQgb2NjdXJzIGFmdGVyIGEga2V5cHJlc3MsIHRocm93IG91dCB0aGUgaW5wdXRcbiAgICAgIC8vIGNoYXJzLiBQYXN0ZSBldmVudHMgc2hvdWxkIG5vdCBsZWFkIHRvIEJlZm9yZUlucHV0IGV2ZW50cy5cbiAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY2FzZSAna2V5cHJlc3MnOlxuICAgICAgLyoqXG4gICAgICAgKiBBcyBvZiB2MjcsIEZpcmVmb3ggbWF5IGZpcmUga2V5cHJlc3MgZXZlbnRzIGV2ZW4gd2hlbiBubyBjaGFyYWN0ZXJcbiAgICAgICAqIHdpbGwgYmUgaW5zZXJ0ZWQuIEEgZmV3IHBvc3NpYmlsaXRpZXM6XG4gICAgICAgKlxuICAgICAgICogLSBgd2hpY2hgIGlzIGAwYC4gQXJyb3cga2V5cywgRXNjIGtleSwgZXRjLlxuICAgICAgICpcbiAgICAgICAqIC0gYHdoaWNoYCBpcyB0aGUgcHJlc3NlZCBrZXkgY29kZSwgYnV0IG5vIGNoYXIgaXMgYXZhaWxhYmxlLlxuICAgICAgICogICBFeDogJ0FsdEdyICsgZGAgaW4gUG9saXNoLiBUaGVyZSBpcyBubyBtb2RpZmllZCBjaGFyYWN0ZXIgZm9yXG4gICAgICAgKiAgIHRoaXMga2V5IGNvbWJpbmF0aW9uIGFuZCBubyBjaGFyYWN0ZXIgaXMgaW5zZXJ0ZWQgaW50byB0aGVcbiAgICAgICAqICAgZG9jdW1lbnQsIGJ1dCBGRiBmaXJlcyB0aGUga2V5cHJlc3MgZm9yIGNoYXIgY29kZSBgMTAwYCBhbnl3YXkuXG4gICAgICAgKiAgIE5vIGBpbnB1dGAgZXZlbnQgd2lsbCBvY2N1ci5cbiAgICAgICAqXG4gICAgICAgKiAtIGB3aGljaGAgaXMgdGhlIHByZXNzZWQga2V5IGNvZGUsIGJ1dCBhIGNvbW1hbmQgY29tYmluYXRpb24gaXNcbiAgICAgICAqICAgYmVpbmcgdXNlZC4gRXg6IGBDbWQrQ2AuIE5vIGNoYXJhY3RlciBpcyBpbnNlcnRlZCwgYW5kIG5vXG4gICAgICAgKiAgIGBpbnB1dGAgZXZlbnQgd2lsbCBvY2N1ci5cbiAgICAgICAqL1xuICAgICAgaWYgKCFpc0tleXByZXNzQ29tbWFuZChuYXRpdmVFdmVudCkpIHtcbiAgICAgICAgLy8gSUUgZmlyZXMgdGhlIGBrZXlwcmVzc2AgZXZlbnQgd2hlbiBhIHVzZXIgdHlwZXMgYW4gZW1vamkgdmlhXG4gICAgICAgIC8vIFRvdWNoIGtleWJvYXJkIG9mIFdpbmRvd3MuICBJbiBzdWNoIGEgY2FzZSwgdGhlIGBjaGFyYCBwcm9wZXJ0eVxuICAgICAgICAvLyBob2xkcyBhbiBlbW9qaSBjaGFyYWN0ZXIgbGlrZSBgXFx1RDgzRFxcdURFMEFgLiAgQmVjYXVzZSBpdHMgbGVuZ3RoXG4gICAgICAgIC8vIGlzIDIsIHRoZSBwcm9wZXJ0eSBgd2hpY2hgIGRvZXMgbm90IHJlcHJlc2VudCBhbiBlbW9qaSBjb3JyZWN0bHkuXG4gICAgICAgIC8vIEluIHN1Y2ggYSBjYXNlLCB3ZSBkaXJlY3RseSByZXR1cm4gdGhlIGBjaGFyYCBwcm9wZXJ0eSBpbnN0ZWFkIG9mXG4gICAgICAgIC8vIHVzaW5nIGB3aGljaGAuXG4gICAgICAgIGlmIChuYXRpdmVFdmVudC5jaGFyICYmIG5hdGl2ZUV2ZW50LmNoYXIubGVuZ3RoID4gMSkge1xuICAgICAgICAgIHJldHVybiBuYXRpdmVFdmVudC5jaGFyO1xuICAgICAgICB9IGVsc2UgaWYgKG5hdGl2ZUV2ZW50LndoaWNoKSB7XG4gICAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUobmF0aXZlRXZlbnQud2hpY2gpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY2FzZSAnY29tcG9zaXRpb25lbmQnOlxuICAgICAgcmV0dXJuIHVzZUZhbGxiYWNrQ29tcG9zaXRpb25EYXRhICYmICFpc1VzaW5nS29yZWFuSU1FKG5hdGl2ZUV2ZW50KSA/IG51bGwgOiBuYXRpdmVFdmVudC5kYXRhO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBudWxsO1xuICB9XG59XG4vKipcbiAqIEV4dHJhY3QgYSBTeW50aGV0aWNJbnB1dEV2ZW50IGZvciBgYmVmb3JlSW5wdXRgLCBiYXNlZCBvbiBlaXRoZXIgbmF0aXZlXG4gKiBgdGV4dElucHV0YCBvciBmYWxsYmFjayBiZWhhdmlvci5cbiAqXG4gKiBAcmV0dXJuIHs/b2JqZWN0fSBBIFN5bnRoZXRpY0lucHV0RXZlbnQuXG4gKi9cblxuXG5mdW5jdGlvbiBleHRyYWN0QmVmb3JlSW5wdXRFdmVudChkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICB2YXIgY2hhcnM7XG5cbiAgaWYgKGNhblVzZVRleHRJbnB1dEV2ZW50KSB7XG4gICAgY2hhcnMgPSBnZXROYXRpdmVCZWZvcmVJbnB1dENoYXJzKGRvbUV2ZW50TmFtZSwgbmF0aXZlRXZlbnQpO1xuICB9IGVsc2Uge1xuICAgIGNoYXJzID0gZ2V0RmFsbGJhY2tCZWZvcmVJbnB1dENoYXJzKGRvbUV2ZW50TmFtZSwgbmF0aXZlRXZlbnQpO1xuICB9IC8vIElmIG5vIGNoYXJhY3RlcnMgYXJlIGJlaW5nIGluc2VydGVkLCBubyBCZWZvcmVJbnB1dCBldmVudCBzaG91bGRcbiAgLy8gYmUgZmlyZWQuXG5cblxuICBpZiAoIWNoYXJzKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgbGlzdGVuZXJzID0gYWNjdW11bGF0ZVR3b1BoYXNlTGlzdGVuZXJzKHRhcmdldEluc3QsICdvbkJlZm9yZUlucHV0Jyk7XG5cbiAgaWYgKGxpc3RlbmVycy5sZW5ndGggPiAwKSB7XG4gICAgdmFyIGV2ZW50ID0gbmV3IFN5bnRoZXRpY0lucHV0RXZlbnQoJ29uQmVmb3JlSW5wdXQnLCAnYmVmb3JlaW5wdXQnLCBudWxsLCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuICAgIGRpc3BhdGNoUXVldWUucHVzaCh7XG4gICAgICBldmVudDogZXZlbnQsXG4gICAgICBsaXN0ZW5lcnM6IGxpc3RlbmVyc1xuICAgIH0pO1xuICAgIGV2ZW50LmRhdGEgPSBjaGFycztcbiAgfVxufVxuLyoqXG4gKiBDcmVhdGUgYW4gYG9uQmVmb3JlSW5wdXRgIGV2ZW50IHRvIG1hdGNoXG4gKiBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDEzL1dELURPTS1MZXZlbC0zLUV2ZW50cy0yMDEzMTEwNS8jZXZlbnRzLWlucHV0ZXZlbnRzLlxuICpcbiAqIFRoaXMgZXZlbnQgcGx1Z2luIGlzIGJhc2VkIG9uIHRoZSBuYXRpdmUgYHRleHRJbnB1dGAgZXZlbnRcbiAqIGF2YWlsYWJsZSBpbiBDaHJvbWUsIFNhZmFyaSwgT3BlcmEsIGFuZCBJRS4gVGhpcyBldmVudCBmaXJlcyBhZnRlclxuICogYG9uS2V5UHJlc3NgIGFuZCBgb25Db21wb3NpdGlvbkVuZGAsIGJ1dCBiZWZvcmUgYG9uSW5wdXRgLlxuICpcbiAqIGBiZWZvcmVJbnB1dGAgaXMgc3BlYydkIGJ1dCBub3QgaW1wbGVtZW50ZWQgaW4gYW55IGJyb3dzZXJzLCBhbmRcbiAqIHRoZSBgaW5wdXRgIGV2ZW50IGRvZXMgbm90IHByb3ZpZGUgYW55IHVzZWZ1bCBpbmZvcm1hdGlvbiBhYm91dCB3aGF0IGhhc1xuICogYWN0dWFsbHkgYmVlbiBhZGRlZCwgY29udHJhcnkgdG8gdGhlIHNwZWMuIFRodXMsIGB0ZXh0SW5wdXRgIGlzIHRoZSBiZXN0XG4gKiBhdmFpbGFibGUgZXZlbnQgdG8gaWRlbnRpZnkgdGhlIGNoYXJhY3RlcnMgdGhhdCBoYXZlIGFjdHVhbGx5IGJlZW4gaW5zZXJ0ZWRcbiAqIGludG8gdGhlIHRhcmdldCBub2RlLlxuICpcbiAqIFRoaXMgcGx1Z2luIGlzIGFsc28gcmVzcG9uc2libGUgZm9yIGVtaXR0aW5nIGBjb21wb3NpdGlvbmAgZXZlbnRzLCB0aHVzXG4gKiBhbGxvd2luZyB1cyB0byBzaGFyZSBjb21wb3NpdGlvbiBmYWxsYmFjayBjb2RlIGZvciBib3RoIGBiZWZvcmVJbnB1dGAgYW5kXG4gKiBgY29tcG9zaXRpb25gIGV2ZW50IHR5cGVzLlxuICovXG5cblxuZnVuY3Rpb24gZXh0cmFjdEV2ZW50cyhkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyKSB7XG4gIGV4dHJhY3RDb21wb3NpdGlvbkV2ZW50KGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgZXh0cmFjdEJlZm9yZUlucHV0RXZlbnQoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xufVxuXG4vKipcbiAqIEBzZWUgaHR0cDovL3d3dy53aGF0d2cub3JnL3NwZWNzL3dlYi1hcHBzL2N1cnJlbnQtd29yay9tdWx0aXBhZ2UvdGhlLWlucHV0LWVsZW1lbnQuaHRtbCNpbnB1dC10eXBlLWF0dHItc3VtbWFyeVxuICovXG52YXIgc3VwcG9ydGVkSW5wdXRUeXBlcyA9IHtcbiAgY29sb3I6IHRydWUsXG4gIGRhdGU6IHRydWUsXG4gIGRhdGV0aW1lOiB0cnVlLFxuICAnZGF0ZXRpbWUtbG9jYWwnOiB0cnVlLFxuICBlbWFpbDogdHJ1ZSxcbiAgbW9udGg6IHRydWUsXG4gIG51bWJlcjogdHJ1ZSxcbiAgcGFzc3dvcmQ6IHRydWUsXG4gIHJhbmdlOiB0cnVlLFxuICBzZWFyY2g6IHRydWUsXG4gIHRlbDogdHJ1ZSxcbiAgdGV4dDogdHJ1ZSxcbiAgdGltZTogdHJ1ZSxcbiAgdXJsOiB0cnVlLFxuICB3ZWVrOiB0cnVlXG59O1xuXG5mdW5jdGlvbiBpc1RleHRJbnB1dEVsZW1lbnQoZWxlbSkge1xuICB2YXIgbm9kZU5hbWUgPSBlbGVtICYmIGVsZW0ubm9kZU5hbWUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXG4gIGlmIChub2RlTmFtZSA9PT0gJ2lucHV0Jykge1xuICAgIHJldHVybiAhIXN1cHBvcnRlZElucHV0VHlwZXNbZWxlbS50eXBlXTtcbiAgfVxuXG4gIGlmIChub2RlTmFtZSA9PT0gJ3RleHRhcmVhJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhbiBldmVudCBpcyBzdXBwb3J0ZWQgaW4gdGhlIGN1cnJlbnQgZXhlY3V0aW9uIGVudmlyb25tZW50LlxuICpcbiAqIE5PVEU6IFRoaXMgd2lsbCBub3Qgd29yayBjb3JyZWN0bHkgZm9yIG5vbi1nZW5lcmljIGV2ZW50cyBzdWNoIGFzIGBjaGFuZ2VgLFxuICogYHJlc2V0YCwgYGxvYWRgLCBgZXJyb3JgLCBhbmQgYHNlbGVjdGAuXG4gKlxuICogQm9ycm93cyBmcm9tIE1vZGVybml6ci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lU3VmZml4IEV2ZW50IG5hbWUsIGUuZy4gXCJjbGlja1wiLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZXZlbnQgaXMgc3VwcG9ydGVkLlxuICogQGludGVybmFsXG4gKiBAbGljZW5zZSBNb2Rlcm5penIgMy4wLjBwcmUgKEN1c3RvbSBCdWlsZCkgfCBNSVRcbiAqL1xuXG5mdW5jdGlvbiBpc0V2ZW50U3VwcG9ydGVkKGV2ZW50TmFtZVN1ZmZpeCkge1xuICBpZiAoIWNhblVzZURPTSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBldmVudE5hbWUgPSAnb24nICsgZXZlbnROYW1lU3VmZml4O1xuICB2YXIgaXNTdXBwb3J0ZWQgPSAoZXZlbnROYW1lIGluIGRvY3VtZW50KTtcblxuICBpZiAoIWlzU3VwcG9ydGVkKSB7XG4gICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShldmVudE5hbWUsICdyZXR1cm47Jyk7XG4gICAgaXNTdXBwb3J0ZWQgPSB0eXBlb2YgZWxlbWVudFtldmVudE5hbWVdID09PSAnZnVuY3Rpb24nO1xuICB9XG5cbiAgcmV0dXJuIGlzU3VwcG9ydGVkO1xufVxuXG5mdW5jdGlvbiByZWdpc3RlckV2ZW50cyQxKCkge1xuICByZWdpc3RlclR3b1BoYXNlRXZlbnQoJ29uQ2hhbmdlJywgWydjaGFuZ2UnLCAnY2xpY2snLCAnZm9jdXNpbicsICdmb2N1c291dCcsICdpbnB1dCcsICdrZXlkb3duJywgJ2tleXVwJywgJ3NlbGVjdGlvbmNoYW5nZSddKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQW5kQWNjdW11bGF0ZUNoYW5nZUV2ZW50KGRpc3BhdGNoUXVldWUsIGluc3QsIG5hdGl2ZUV2ZW50LCB0YXJnZXQpIHtcbiAgLy8gRmxhZyB0aGlzIGV2ZW50IGxvb3AgYXMgbmVlZGluZyBzdGF0ZSByZXN0b3JlLlxuICBlbnF1ZXVlU3RhdGVSZXN0b3JlKHRhcmdldCk7XG4gIHZhciBsaXN0ZW5lcnMgPSBhY2N1bXVsYXRlVHdvUGhhc2VMaXN0ZW5lcnMoaW5zdCwgJ29uQ2hhbmdlJyk7XG5cbiAgaWYgKGxpc3RlbmVycy5sZW5ndGggPiAwKSB7XG4gICAgdmFyIGV2ZW50ID0gbmV3IFN5bnRoZXRpY0V2ZW50KCdvbkNoYW5nZScsICdjaGFuZ2UnLCBudWxsLCBuYXRpdmVFdmVudCwgdGFyZ2V0KTtcbiAgICBkaXNwYXRjaFF1ZXVlLnB1c2goe1xuICAgICAgZXZlbnQ6IGV2ZW50LFxuICAgICAgbGlzdGVuZXJzOiBsaXN0ZW5lcnNcbiAgICB9KTtcbiAgfVxufVxuLyoqXG4gKiBGb3IgSUUgc2hpbXNcbiAqL1xuXG5cbnZhciBhY3RpdmVFbGVtZW50ID0gbnVsbDtcbnZhciBhY3RpdmVFbGVtZW50SW5zdCA9IG51bGw7XG4vKipcbiAqIFNFQ1RJT046IGhhbmRsZSBgY2hhbmdlYCBldmVudFxuICovXG5cbmZ1bmN0aW9uIHNob3VsZFVzZUNoYW5nZUV2ZW50KGVsZW0pIHtcbiAgdmFyIG5vZGVOYW1lID0gZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiBub2RlTmFtZSA9PT0gJ3NlbGVjdCcgfHwgbm9kZU5hbWUgPT09ICdpbnB1dCcgJiYgZWxlbS50eXBlID09PSAnZmlsZSc7XG59XG5cbmZ1bmN0aW9uIG1hbnVhbERpc3BhdGNoQ2hhbmdlRXZlbnQobmF0aXZlRXZlbnQpIHtcbiAgdmFyIGRpc3BhdGNoUXVldWUgPSBbXTtcbiAgY3JlYXRlQW5kQWNjdW11bGF0ZUNoYW5nZUV2ZW50KGRpc3BhdGNoUXVldWUsIGFjdGl2ZUVsZW1lbnRJbnN0LCBuYXRpdmVFdmVudCwgZ2V0RXZlbnRUYXJnZXQobmF0aXZlRXZlbnQpKTsgLy8gSWYgY2hhbmdlIGFuZCBwcm9wZXJ0eWNoYW5nZSBidWJibGVkLCB3ZSdkIGp1c3QgYmluZCB0byBpdCBsaWtlIGFsbCB0aGVcbiAgLy8gb3RoZXIgZXZlbnRzIGFuZCBoYXZlIGl0IGdvIHRocm91Z2ggUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLiBTaW5jZSBpdFxuICAvLyBkb2Vzbid0LCB3ZSBtYW51YWxseSBsaXN0ZW4gZm9yIHRoZSBldmVudHMgYW5kIHNvIHdlIGhhdmUgdG8gZW5xdWV1ZSBhbmRcbiAgLy8gcHJvY2VzcyB0aGUgYWJzdHJhY3QgZXZlbnQgbWFudWFsbHkuXG4gIC8vXG4gIC8vIEJhdGNoaW5nIGlzIG5lY2Vzc2FyeSBoZXJlIGluIG9yZGVyIHRvIGVuc3VyZSB0aGF0IGFsbCBldmVudCBoYW5kbGVycyBydW5cbiAgLy8gYmVmb3JlIHRoZSBuZXh0IHJlcmVuZGVyIChpbmNsdWRpbmcgZXZlbnQgaGFuZGxlcnMgYXR0YWNoZWQgdG8gYW5jZXN0b3JcbiAgLy8gZWxlbWVudHMgaW5zdGVhZCBvZiBkaXJlY3RseSBvbiB0aGUgaW5wdXQpLiBXaXRob3V0IHRoaXMsIGNvbnRyb2xsZWRcbiAgLy8gY29tcG9uZW50cyBkb24ndCB3b3JrIHByb3Blcmx5IGluIGNvbmp1bmN0aW9uIHdpdGggZXZlbnQgYnViYmxpbmcgYmVjYXVzZVxuICAvLyB0aGUgY29tcG9uZW50IGlzIHJlcmVuZGVyZWQgYW5kIHRoZSB2YWx1ZSByZXZlcnRlZCBiZWZvcmUgYWxsIHRoZSBldmVudFxuICAvLyBoYW5kbGVycyBjYW4gcnVuLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy83MDguXG5cbiAgYmF0Y2hlZFVwZGF0ZXMocnVuRXZlbnRJbkJhdGNoLCBkaXNwYXRjaFF1ZXVlKTtcbn1cblxuZnVuY3Rpb24gcnVuRXZlbnRJbkJhdGNoKGRpc3BhdGNoUXVldWUpIHtcbiAgcHJvY2Vzc0Rpc3BhdGNoUXVldWUoZGlzcGF0Y2hRdWV1ZSwgMCk7XG59XG5cbmZ1bmN0aW9uIGdldEluc3RJZlZhbHVlQ2hhbmdlZCh0YXJnZXRJbnN0KSB7XG4gIHZhciB0YXJnZXROb2RlID0gZ2V0Tm9kZUZyb21JbnN0YW5jZSh0YXJnZXRJbnN0KTtcblxuICBpZiAodXBkYXRlVmFsdWVJZkNoYW5nZWQodGFyZ2V0Tm9kZSkpIHtcbiAgICByZXR1cm4gdGFyZ2V0SW5zdDtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRUYXJnZXRJbnN0Rm9yQ2hhbmdlRXZlbnQoZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0KSB7XG4gIGlmIChkb21FdmVudE5hbWUgPT09ICdjaGFuZ2UnKSB7XG4gICAgcmV0dXJuIHRhcmdldEluc3Q7XG4gIH1cbn1cbi8qKlxuICogU0VDVElPTjogaGFuZGxlIGBpbnB1dGAgZXZlbnRcbiAqL1xuXG5cbnZhciBpc0lucHV0RXZlbnRTdXBwb3J0ZWQgPSBmYWxzZTtcblxuaWYgKGNhblVzZURPTSkge1xuICAvLyBJRTkgY2xhaW1zIHRvIHN1cHBvcnQgdGhlIGlucHV0IGV2ZW50IGJ1dCBmYWlscyB0byB0cmlnZ2VyIGl0IHdoZW5cbiAgLy8gZGVsZXRpbmcgdGV4dCwgc28gd2UgaWdub3JlIGl0cyBpbnB1dCBldmVudHMuXG4gIGlzSW5wdXRFdmVudFN1cHBvcnRlZCA9IGlzRXZlbnRTdXBwb3J0ZWQoJ2lucHV0JykgJiYgKCFkb2N1bWVudC5kb2N1bWVudE1vZGUgfHwgZG9jdW1lbnQuZG9jdW1lbnRNb2RlID4gOSk7XG59XG4vKipcbiAqIChGb3IgSUUgPD05KSBTdGFydHMgdHJhY2tpbmcgcHJvcGVydHljaGFuZ2UgZXZlbnRzIG9uIHRoZSBwYXNzZWQtaW4gZWxlbWVudFxuICogYW5kIG92ZXJyaWRlIHRoZSB2YWx1ZSBwcm9wZXJ0eSBzbyB0aGF0IHdlIGNhbiBkaXN0aW5ndWlzaCB1c2VyIGV2ZW50cyBmcm9tXG4gKiB2YWx1ZSBjaGFuZ2VzIGluIEpTLlxuICovXG5cblxuZnVuY3Rpb24gc3RhcnRXYXRjaGluZ0ZvclZhbHVlQ2hhbmdlKHRhcmdldCwgdGFyZ2V0SW5zdCkge1xuICBhY3RpdmVFbGVtZW50ID0gdGFyZ2V0O1xuICBhY3RpdmVFbGVtZW50SW5zdCA9IHRhcmdldEluc3Q7XG4gIGFjdGl2ZUVsZW1lbnQuYXR0YWNoRXZlbnQoJ29ucHJvcGVydHljaGFuZ2UnLCBoYW5kbGVQcm9wZXJ0eUNoYW5nZSk7XG59XG4vKipcbiAqIChGb3IgSUUgPD05KSBSZW1vdmVzIHRoZSBldmVudCBsaXN0ZW5lcnMgZnJvbSB0aGUgY3VycmVudGx5LXRyYWNrZWQgZWxlbWVudCxcbiAqIGlmIGFueSBleGlzdHMuXG4gKi9cblxuXG5mdW5jdGlvbiBzdG9wV2F0Y2hpbmdGb3JWYWx1ZUNoYW5nZSgpIHtcbiAgaWYgKCFhY3RpdmVFbGVtZW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgYWN0aXZlRWxlbWVudC5kZXRhY2hFdmVudCgnb25wcm9wZXJ0eWNoYW5nZScsIGhhbmRsZVByb3BlcnR5Q2hhbmdlKTtcbiAgYWN0aXZlRWxlbWVudCA9IG51bGw7XG4gIGFjdGl2ZUVsZW1lbnRJbnN0ID0gbnVsbDtcbn1cbi8qKlxuICogKEZvciBJRSA8PTkpIEhhbmRsZXMgYSBwcm9wZXJ0eWNoYW5nZSBldmVudCwgc2VuZGluZyBhIGBjaGFuZ2VgIGV2ZW50IGlmXG4gKiB0aGUgdmFsdWUgb2YgdGhlIGFjdGl2ZSBlbGVtZW50IGhhcyBjaGFuZ2VkLlxuICovXG5cblxuZnVuY3Rpb24gaGFuZGxlUHJvcGVydHlDaGFuZ2UobmF0aXZlRXZlbnQpIHtcbiAgaWYgKG5hdGl2ZUV2ZW50LnByb3BlcnR5TmFtZSAhPT0gJ3ZhbHVlJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChnZXRJbnN0SWZWYWx1ZUNoYW5nZWQoYWN0aXZlRWxlbWVudEluc3QpKSB7XG4gICAgbWFudWFsRGlzcGF0Y2hDaGFuZ2VFdmVudChuYXRpdmVFdmVudCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFuZGxlRXZlbnRzRm9ySW5wdXRFdmVudFBvbHlmaWxsKGRvbUV2ZW50TmFtZSwgdGFyZ2V0LCB0YXJnZXRJbnN0KSB7XG4gIGlmIChkb21FdmVudE5hbWUgPT09ICdmb2N1c2luJykge1xuICAgIC8vIEluIElFOSwgcHJvcGVydHljaGFuZ2UgZmlyZXMgZm9yIG1vc3QgaW5wdXQgZXZlbnRzIGJ1dCBpcyBidWdneSBhbmRcbiAgICAvLyBkb2Vzbid0IGZpcmUgd2hlbiB0ZXh0IGlzIGRlbGV0ZWQsIGJ1dCBjb252ZW5pZW50bHksIHNlbGVjdGlvbmNoYW5nZVxuICAgIC8vIGFwcGVhcnMgdG8gZmlyZSBpbiBhbGwgb2YgdGhlIHJlbWFpbmluZyBjYXNlcyBzbyB3ZSBjYXRjaCB0aG9zZSBhbmRcbiAgICAvLyBmb3J3YXJkIHRoZSBldmVudCBpZiB0aGUgdmFsdWUgaGFzIGNoYW5nZWRcbiAgICAvLyBJbiBlaXRoZXIgY2FzZSwgd2UgZG9uJ3Qgd2FudCB0byBjYWxsIHRoZSBldmVudCBoYW5kbGVyIGlmIHRoZSB2YWx1ZVxuICAgIC8vIGlzIGNoYW5nZWQgZnJvbSBKUyBzbyB3ZSByZWRlZmluZSBhIHNldHRlciBmb3IgYC52YWx1ZWAgdGhhdCB1cGRhdGVzXG4gICAgLy8gb3VyIGFjdGl2ZUVsZW1lbnRWYWx1ZSB2YXJpYWJsZSwgYWxsb3dpbmcgdXMgdG8gaWdub3JlIHRob3NlIGNoYW5nZXNcbiAgICAvL1xuICAgIC8vIHN0b3BXYXRjaGluZygpIHNob3VsZCBiZSBhIG5vb3AgaGVyZSBidXQgd2UgY2FsbCBpdCBqdXN0IGluIGNhc2Ugd2VcbiAgICAvLyBtaXNzZWQgYSBibHVyIGV2ZW50IHNvbWVob3cuXG4gICAgc3RvcFdhdGNoaW5nRm9yVmFsdWVDaGFuZ2UoKTtcbiAgICBzdGFydFdhdGNoaW5nRm9yVmFsdWVDaGFuZ2UodGFyZ2V0LCB0YXJnZXRJbnN0KTtcbiAgfSBlbHNlIGlmIChkb21FdmVudE5hbWUgPT09ICdmb2N1c291dCcpIHtcbiAgICBzdG9wV2F0Y2hpbmdGb3JWYWx1ZUNoYW5nZSgpO1xuICB9XG59IC8vIEZvciBJRTggYW5kIElFOS5cblxuXG5mdW5jdGlvbiBnZXRUYXJnZXRJbnN0Rm9ySW5wdXRFdmVudFBvbHlmaWxsKGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCkge1xuICBpZiAoZG9tRXZlbnROYW1lID09PSAnc2VsZWN0aW9uY2hhbmdlJyB8fCBkb21FdmVudE5hbWUgPT09ICdrZXl1cCcgfHwgZG9tRXZlbnROYW1lID09PSAna2V5ZG93bicpIHtcbiAgICAvLyBPbiB0aGUgc2VsZWN0aW9uY2hhbmdlIGV2ZW50LCB0aGUgdGFyZ2V0IGlzIGp1c3QgZG9jdW1lbnQgd2hpY2ggaXNuJ3RcbiAgICAvLyBoZWxwZnVsIGZvciB1cyBzbyBqdXN0IGNoZWNrIGFjdGl2ZUVsZW1lbnQgaW5zdGVhZC5cbiAgICAvL1xuICAgIC8vIDk5JSBvZiB0aGUgdGltZSwga2V5ZG93biBhbmQga2V5dXAgYXJlbid0IG5lY2Vzc2FyeS4gSUU4IGZhaWxzIHRvIGZpcmVcbiAgICAvLyBwcm9wZXJ0eWNoYW5nZSBvbiB0aGUgZmlyc3QgaW5wdXQgZXZlbnQgYWZ0ZXIgc2V0dGluZyBgdmFsdWVgIGZyb20gYVxuICAgIC8vIHNjcmlwdCBhbmQgZmlyZXMgb25seSBrZXlkb3duLCBrZXlwcmVzcywga2V5dXAuIENhdGNoaW5nIGtleXVwIHVzdWFsbHlcbiAgICAvLyBnZXRzIGl0IGFuZCBjYXRjaGluZyBrZXlkb3duIGxldHMgdXMgZmlyZSBhbiBldmVudCBmb3IgdGhlIGZpcnN0XG4gICAgLy8ga2V5c3Ryb2tlIGlmIHVzZXIgZG9lcyBhIGtleSByZXBlYXQgKGl0J2xsIGJlIGEgbGl0dGxlIGRlbGF5ZWQ6IHJpZ2h0XG4gICAgLy8gYmVmb3JlIHRoZSBzZWNvbmQga2V5c3Ryb2tlKS4gT3RoZXIgaW5wdXQgbWV0aG9kcyAoZS5nLiwgcGFzdGUpIHNlZW0gdG9cbiAgICAvLyBmaXJlIHNlbGVjdGlvbmNoYW5nZSBub3JtYWxseS5cbiAgICByZXR1cm4gZ2V0SW5zdElmVmFsdWVDaGFuZ2VkKGFjdGl2ZUVsZW1lbnRJbnN0KTtcbiAgfVxufVxuLyoqXG4gKiBTRUNUSU9OOiBoYW5kbGUgYGNsaWNrYCBldmVudFxuICovXG5cblxuZnVuY3Rpb24gc2hvdWxkVXNlQ2xpY2tFdmVudChlbGVtKSB7XG4gIC8vIFVzZSB0aGUgYGNsaWNrYCBldmVudCB0byBkZXRlY3QgY2hhbmdlcyB0byBjaGVja2JveCBhbmQgcmFkaW8gaW5wdXRzLlxuICAvLyBUaGlzIGFwcHJvYWNoIHdvcmtzIGFjcm9zcyBhbGwgYnJvd3NlcnMsIHdoZXJlYXMgYGNoYW5nZWAgZG9lcyBub3QgZmlyZVxuICAvLyB1bnRpbCBgYmx1cmAgaW4gSUU4LlxuICB2YXIgbm9kZU5hbWUgPSBlbGVtLm5vZGVOYW1lO1xuICByZXR1cm4gbm9kZU5hbWUgJiYgbm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2lucHV0JyAmJiAoZWxlbS50eXBlID09PSAnY2hlY2tib3gnIHx8IGVsZW0udHlwZSA9PT0gJ3JhZGlvJyk7XG59XG5cbmZ1bmN0aW9uIGdldFRhcmdldEluc3RGb3JDbGlja0V2ZW50KGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCkge1xuICBpZiAoZG9tRXZlbnROYW1lID09PSAnY2xpY2snKSB7XG4gICAgcmV0dXJuIGdldEluc3RJZlZhbHVlQ2hhbmdlZCh0YXJnZXRJbnN0KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRUYXJnZXRJbnN0Rm9ySW5wdXRPckNoYW5nZUV2ZW50KGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCkge1xuICBpZiAoZG9tRXZlbnROYW1lID09PSAnaW5wdXQnIHx8IGRvbUV2ZW50TmFtZSA9PT0gJ2NoYW5nZScpIHtcbiAgICByZXR1cm4gZ2V0SW5zdElmVmFsdWVDaGFuZ2VkKHRhcmdldEluc3QpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGhhbmRsZUNvbnRyb2xsZWRJbnB1dEJsdXIobm9kZSkge1xuICB2YXIgc3RhdGUgPSBub2RlLl93cmFwcGVyU3RhdGU7XG5cbiAgaWYgKCFzdGF0ZSB8fCAhc3RhdGUuY29udHJvbGxlZCB8fCBub2RlLnR5cGUgIT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAge1xuICAgIC8vIElmIGNvbnRyb2xsZWQsIGFzc2lnbiB0aGUgdmFsdWUgYXR0cmlidXRlIHRvIHRoZSBjdXJyZW50IHZhbHVlIG9uIGJsdXJcbiAgICBzZXREZWZhdWx0VmFsdWUobm9kZSwgJ251bWJlcicsIG5vZGUudmFsdWUpO1xuICB9XG59XG4vKipcbiAqIFRoaXMgcGx1Z2luIGNyZWF0ZXMgYW4gYG9uQ2hhbmdlYCBldmVudCB0aGF0IG5vcm1hbGl6ZXMgY2hhbmdlIGV2ZW50c1xuICogYWNyb3NzIGZvcm0gZWxlbWVudHMuIFRoaXMgZXZlbnQgZmlyZXMgYXQgYSB0aW1lIHdoZW4gaXQncyBwb3NzaWJsZSB0b1xuICogY2hhbmdlIHRoZSBlbGVtZW50J3MgdmFsdWUgd2l0aG91dCBzZWVpbmcgYSBmbGlja2VyLlxuICpcbiAqIFN1cHBvcnRlZCBlbGVtZW50cyBhcmU6XG4gKiAtIGlucHV0IChzZWUgYGlzVGV4dElucHV0RWxlbWVudGApXG4gKiAtIHRleHRhcmVhXG4gKiAtIHNlbGVjdFxuICovXG5cblxuZnVuY3Rpb24gZXh0cmFjdEV2ZW50cyQxKGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0LCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIpIHtcbiAgdmFyIHRhcmdldE5vZGUgPSB0YXJnZXRJbnN0ID8gZ2V0Tm9kZUZyb21JbnN0YW5jZSh0YXJnZXRJbnN0KSA6IHdpbmRvdztcbiAgdmFyIGdldFRhcmdldEluc3RGdW5jLCBoYW5kbGVFdmVudEZ1bmM7XG5cbiAgaWYgKHNob3VsZFVzZUNoYW5nZUV2ZW50KHRhcmdldE5vZGUpKSB7XG4gICAgZ2V0VGFyZ2V0SW5zdEZ1bmMgPSBnZXRUYXJnZXRJbnN0Rm9yQ2hhbmdlRXZlbnQ7XG4gIH0gZWxzZSBpZiAoaXNUZXh0SW5wdXRFbGVtZW50KHRhcmdldE5vZGUpKSB7XG4gICAgaWYgKGlzSW5wdXRFdmVudFN1cHBvcnRlZCkge1xuICAgICAgZ2V0VGFyZ2V0SW5zdEZ1bmMgPSBnZXRUYXJnZXRJbnN0Rm9ySW5wdXRPckNoYW5nZUV2ZW50O1xuICAgIH0gZWxzZSB7XG4gICAgICBnZXRUYXJnZXRJbnN0RnVuYyA9IGdldFRhcmdldEluc3RGb3JJbnB1dEV2ZW50UG9seWZpbGw7XG4gICAgICBoYW5kbGVFdmVudEZ1bmMgPSBoYW5kbGVFdmVudHNGb3JJbnB1dEV2ZW50UG9seWZpbGw7XG4gICAgfVxuICB9IGVsc2UgaWYgKHNob3VsZFVzZUNsaWNrRXZlbnQodGFyZ2V0Tm9kZSkpIHtcbiAgICBnZXRUYXJnZXRJbnN0RnVuYyA9IGdldFRhcmdldEluc3RGb3JDbGlja0V2ZW50O1xuICB9XG5cbiAgaWYgKGdldFRhcmdldEluc3RGdW5jKSB7XG4gICAgdmFyIGluc3QgPSBnZXRUYXJnZXRJbnN0RnVuYyhkb21FdmVudE5hbWUsIHRhcmdldEluc3QpO1xuXG4gICAgaWYgKGluc3QpIHtcbiAgICAgIGNyZWF0ZUFuZEFjY3VtdWxhdGVDaGFuZ2VFdmVudChkaXNwYXRjaFF1ZXVlLCBpbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIGlmIChoYW5kbGVFdmVudEZ1bmMpIHtcbiAgICBoYW5kbGVFdmVudEZ1bmMoZG9tRXZlbnROYW1lLCB0YXJnZXROb2RlLCB0YXJnZXRJbnN0KTtcbiAgfSAvLyBXaGVuIGJsdXJyaW5nLCBzZXQgdGhlIHZhbHVlIGF0dHJpYnV0ZSBmb3IgbnVtYmVyIGlucHV0c1xuXG5cbiAgaWYgKGRvbUV2ZW50TmFtZSA9PT0gJ2ZvY3Vzb3V0Jykge1xuICAgIGhhbmRsZUNvbnRyb2xsZWRJbnB1dEJsdXIodGFyZ2V0Tm9kZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJFdmVudHMkMigpIHtcbiAgcmVnaXN0ZXJEaXJlY3RFdmVudCgnb25Nb3VzZUVudGVyJywgWydtb3VzZW91dCcsICdtb3VzZW92ZXInXSk7XG4gIHJlZ2lzdGVyRGlyZWN0RXZlbnQoJ29uTW91c2VMZWF2ZScsIFsnbW91c2VvdXQnLCAnbW91c2VvdmVyJ10pO1xuICByZWdpc3RlckRpcmVjdEV2ZW50KCdvblBvaW50ZXJFbnRlcicsIFsncG9pbnRlcm91dCcsICdwb2ludGVyb3ZlciddKTtcbiAgcmVnaXN0ZXJEaXJlY3RFdmVudCgnb25Qb2ludGVyTGVhdmUnLCBbJ3BvaW50ZXJvdXQnLCAncG9pbnRlcm92ZXInXSk7XG59XG4vKipcbiAqIEZvciBhbG1vc3QgZXZlcnkgaW50ZXJhY3Rpb24gd2UgY2FyZSBhYm91dCwgdGhlcmUgd2lsbCBiZSBib3RoIGEgdG9wLWxldmVsXG4gKiBgbW91c2VvdmVyYCBhbmQgYG1vdXNlb3V0YCBldmVudCB0aGF0IG9jY3Vycy4gT25seSB1c2UgYG1vdXNlb3V0YCBzbyB0aGF0XG4gKiB3ZSBkbyBub3QgZXh0cmFjdCBkdXBsaWNhdGUgZXZlbnRzLiBIb3dldmVyLCBtb3ZpbmcgdGhlIG1vdXNlIGludG8gdGhlXG4gKiBicm93c2VyIGZyb20gb3V0c2lkZSB3aWxsIG5vdCBmaXJlIGEgYG1vdXNlb3V0YCBldmVudC4gSW4gdGhpcyBjYXNlLCB3ZSB1c2VcbiAqIHRoZSBgbW91c2VvdmVyYCB0b3AtbGV2ZWwgZXZlbnQuXG4gKi9cblxuXG5mdW5jdGlvbiBleHRyYWN0RXZlbnRzJDIoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lcikge1xuICB2YXIgaXNPdmVyRXZlbnQgPSBkb21FdmVudE5hbWUgPT09ICdtb3VzZW92ZXInIHx8IGRvbUV2ZW50TmFtZSA9PT0gJ3BvaW50ZXJvdmVyJztcbiAgdmFyIGlzT3V0RXZlbnQgPSBkb21FdmVudE5hbWUgPT09ICdtb3VzZW91dCcgfHwgZG9tRXZlbnROYW1lID09PSAncG9pbnRlcm91dCc7XG5cbiAgaWYgKGlzT3ZlckV2ZW50ICYmICFpc1JlcGxheWluZ0V2ZW50KG5hdGl2ZUV2ZW50KSkge1xuICAgIC8vIElmIHRoaXMgaXMgYW4gb3ZlciBldmVudCB3aXRoIGEgdGFyZ2V0LCB3ZSBtaWdodCBoYXZlIGFscmVhZHkgZGlzcGF0Y2hlZFxuICAgIC8vIHRoZSBldmVudCBpbiB0aGUgb3V0IGV2ZW50IG9mIHRoZSBvdGhlciB0YXJnZXQuIElmIHRoaXMgaXMgcmVwbGF5ZWQsXG4gICAgLy8gdGhlbiBpdCdzIGJlY2F1c2Ugd2UgY291bGRuJ3QgZGlzcGF0Y2ggYWdhaW5zdCB0aGlzIHRhcmdldCBwcmV2aW91c2x5XG4gICAgLy8gc28gd2UgaGF2ZSB0byBkbyBpdCBub3cgaW5zdGVhZC5cbiAgICB2YXIgcmVsYXRlZCA9IG5hdGl2ZUV2ZW50LnJlbGF0ZWRUYXJnZXQgfHwgbmF0aXZlRXZlbnQuZnJvbUVsZW1lbnQ7XG5cbiAgICBpZiAocmVsYXRlZCkge1xuICAgICAgLy8gSWYgdGhlIHJlbGF0ZWQgbm9kZSBpcyBtYW5hZ2VkIGJ5IFJlYWN0LCB3ZSBjYW4gYXNzdW1lIHRoYXQgd2UgaGF2ZVxuICAgICAgLy8gYWxyZWFkeSBkaXNwYXRjaGVkIHRoZSBjb3JyZXNwb25kaW5nIGV2ZW50cyBkdXJpbmcgaXRzIG1vdXNlb3V0LlxuICAgICAgaWYgKGdldENsb3Nlc3RJbnN0YW5jZUZyb21Ob2RlKHJlbGF0ZWQpIHx8IGlzQ29udGFpbmVyTWFya2VkQXNSb290KHJlbGF0ZWQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoIWlzT3V0RXZlbnQgJiYgIWlzT3ZlckV2ZW50KSB7XG4gICAgLy8gTXVzdCBub3QgYmUgYSBtb3VzZSBvciBwb2ludGVyIGluIG9yIG91dCAtIGlnbm9yaW5nLlxuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciB3aW47IC8vIFRPRE86IHdoeSBpcyB0aGlzIG51bGxhYmxlIGluIHRoZSB0eXBlcyBidXQgd2UgcmVhZCBmcm9tIGl0P1xuXG4gIGlmIChuYXRpdmVFdmVudFRhcmdldC53aW5kb3cgPT09IG5hdGl2ZUV2ZW50VGFyZ2V0KSB7XG4gICAgLy8gYG5hdGl2ZUV2ZW50VGFyZ2V0YCBpcyBwcm9iYWJseSBhIHdpbmRvdyBvYmplY3QuXG4gICAgd2luID0gbmF0aXZlRXZlbnRUYXJnZXQ7XG4gIH0gZWxzZSB7XG4gICAgLy8gVE9ETzogRmlndXJlIG91dCB3aHkgYG93bmVyRG9jdW1lbnRgIGlzIHNvbWV0aW1lcyB1bmRlZmluZWQgaW4gSUU4LlxuICAgIHZhciBkb2MgPSBuYXRpdmVFdmVudFRhcmdldC5vd25lckRvY3VtZW50O1xuXG4gICAgaWYgKGRvYykge1xuICAgICAgd2luID0gZG9jLmRlZmF1bHRWaWV3IHx8IGRvYy5wYXJlbnRXaW5kb3c7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdpbiA9IHdpbmRvdztcbiAgICB9XG4gIH1cblxuICB2YXIgZnJvbTtcbiAgdmFyIHRvO1xuXG4gIGlmIChpc091dEV2ZW50KSB7XG4gICAgdmFyIF9yZWxhdGVkID0gbmF0aXZlRXZlbnQucmVsYXRlZFRhcmdldCB8fCBuYXRpdmVFdmVudC50b0VsZW1lbnQ7XG5cbiAgICBmcm9tID0gdGFyZ2V0SW5zdDtcbiAgICB0byA9IF9yZWxhdGVkID8gZ2V0Q2xvc2VzdEluc3RhbmNlRnJvbU5vZGUoX3JlbGF0ZWQpIDogbnVsbDtcblxuICAgIGlmICh0byAhPT0gbnVsbCkge1xuICAgICAgdmFyIG5lYXJlc3RNb3VudGVkID0gZ2V0TmVhcmVzdE1vdW50ZWRGaWJlcih0byk7XG5cbiAgICAgIGlmICh0byAhPT0gbmVhcmVzdE1vdW50ZWQgfHwgdG8udGFnICE9PSBIb3N0Q29tcG9uZW50ICYmIHRvLnRhZyAhPT0gSG9zdFRleHQpIHtcbiAgICAgICAgdG8gPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBNb3ZpbmcgdG8gYSBub2RlIGZyb20gb3V0c2lkZSB0aGUgd2luZG93LlxuICAgIGZyb20gPSBudWxsO1xuICAgIHRvID0gdGFyZ2V0SW5zdDtcbiAgfVxuXG4gIGlmIChmcm9tID09PSB0bykge1xuICAgIC8vIE5vdGhpbmcgcGVydGFpbnMgdG8gb3VyIG1hbmFnZWQgY29tcG9uZW50cy5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljTW91c2VFdmVudDtcbiAgdmFyIGxlYXZlRXZlbnRUeXBlID0gJ29uTW91c2VMZWF2ZSc7XG4gIHZhciBlbnRlckV2ZW50VHlwZSA9ICdvbk1vdXNlRW50ZXInO1xuICB2YXIgZXZlbnRUeXBlUHJlZml4ID0gJ21vdXNlJztcblxuICBpZiAoZG9tRXZlbnROYW1lID09PSAncG9pbnRlcm91dCcgfHwgZG9tRXZlbnROYW1lID09PSAncG9pbnRlcm92ZXInKSB7XG4gICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljUG9pbnRlckV2ZW50O1xuICAgIGxlYXZlRXZlbnRUeXBlID0gJ29uUG9pbnRlckxlYXZlJztcbiAgICBlbnRlckV2ZW50VHlwZSA9ICdvblBvaW50ZXJFbnRlcic7XG4gICAgZXZlbnRUeXBlUHJlZml4ID0gJ3BvaW50ZXInO1xuICB9XG5cbiAgdmFyIGZyb21Ob2RlID0gZnJvbSA9PSBudWxsID8gd2luIDogZ2V0Tm9kZUZyb21JbnN0YW5jZShmcm9tKTtcbiAgdmFyIHRvTm9kZSA9IHRvID09IG51bGwgPyB3aW4gOiBnZXROb2RlRnJvbUluc3RhbmNlKHRvKTtcbiAgdmFyIGxlYXZlID0gbmV3IFN5bnRoZXRpY0V2ZW50Q3RvcihsZWF2ZUV2ZW50VHlwZSwgZXZlbnRUeXBlUHJlZml4ICsgJ2xlYXZlJywgZnJvbSwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgbGVhdmUudGFyZ2V0ID0gZnJvbU5vZGU7XG4gIGxlYXZlLnJlbGF0ZWRUYXJnZXQgPSB0b05vZGU7XG4gIHZhciBlbnRlciA9IG51bGw7IC8vIFdlIHNob3VsZCBvbmx5IHByb2Nlc3MgdGhpcyBuYXRpdmVFdmVudCBpZiB3ZSBhcmUgcHJvY2Vzc2luZ1xuICAvLyB0aGUgZmlyc3QgYW5jZXN0b3IuIE5leHQgdGltZSwgd2Ugd2lsbCBpZ25vcmUgdGhlIGV2ZW50LlxuXG4gIHZhciBuYXRpdmVUYXJnZXRJbnN0ID0gZ2V0Q2xvc2VzdEluc3RhbmNlRnJvbU5vZGUobmF0aXZlRXZlbnRUYXJnZXQpO1xuXG4gIGlmIChuYXRpdmVUYXJnZXRJbnN0ID09PSB0YXJnZXRJbnN0KSB7XG4gICAgdmFyIGVudGVyRXZlbnQgPSBuZXcgU3ludGhldGljRXZlbnRDdG9yKGVudGVyRXZlbnRUeXBlLCBldmVudFR5cGVQcmVmaXggKyAnZW50ZXInLCB0bywgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgICBlbnRlckV2ZW50LnRhcmdldCA9IHRvTm9kZTtcbiAgICBlbnRlckV2ZW50LnJlbGF0ZWRUYXJnZXQgPSBmcm9tTm9kZTtcbiAgICBlbnRlciA9IGVudGVyRXZlbnQ7XG4gIH1cblxuICBhY2N1bXVsYXRlRW50ZXJMZWF2ZVR3b1BoYXNlTGlzdGVuZXJzKGRpc3BhdGNoUXVldWUsIGxlYXZlLCBlbnRlciwgZnJvbSwgdG8pO1xufVxuXG4vKipcbiAqIGlubGluZWQgT2JqZWN0LmlzIHBvbHlmaWxsIHRvIGF2b2lkIHJlcXVpcmluZyBjb25zdW1lcnMgc2hpcCB0aGVpciBvd25cbiAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL09iamVjdC9pc1xuICovXG5mdW5jdGlvbiBpcyh4LCB5KSB7XG4gIHJldHVybiB4ID09PSB5ICYmICh4ICE9PSAwIHx8IDEgLyB4ID09PSAxIC8geSkgfHwgeCAhPT0geCAmJiB5ICE9PSB5IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gIDtcbn1cblxudmFyIG9iamVjdElzID0gdHlwZW9mIE9iamVjdC5pcyA9PT0gJ2Z1bmN0aW9uJyA/IE9iamVjdC5pcyA6IGlzO1xuXG4vKipcbiAqIFBlcmZvcm1zIGVxdWFsaXR5IGJ5IGl0ZXJhdGluZyB0aHJvdWdoIGtleXMgb24gYW4gb2JqZWN0IGFuZCByZXR1cm5pbmcgZmFsc2VcbiAqIHdoZW4gYW55IGtleSBoYXMgdmFsdWVzIHdoaWNoIGFyZSBub3Qgc3RyaWN0bHkgZXF1YWwgYmV0d2VlbiB0aGUgYXJndW1lbnRzLlxuICogUmV0dXJucyB0cnVlIHdoZW4gdGhlIHZhbHVlcyBvZiBhbGwga2V5cyBhcmUgc3RyaWN0bHkgZXF1YWwuXG4gKi9cblxuZnVuY3Rpb24gc2hhbGxvd0VxdWFsKG9iakEsIG9iakIpIHtcbiAgaWYgKG9iamVjdElzKG9iakEsIG9iakIpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAodHlwZW9mIG9iakEgIT09ICdvYmplY3QnIHx8IG9iakEgPT09IG51bGwgfHwgdHlwZW9mIG9iakIgIT09ICdvYmplY3QnIHx8IG9iakIgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIga2V5c0EgPSBPYmplY3Qua2V5cyhvYmpBKTtcbiAgdmFyIGtleXNCID0gT2JqZWN0LmtleXMob2JqQik7XG5cbiAgaWYgKGtleXNBLmxlbmd0aCAhPT0ga2V5c0IubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IC8vIFRlc3QgZm9yIEEncyBrZXlzIGRpZmZlcmVudCBmcm9tIEIuXG5cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXNBLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGN1cnJlbnRLZXkgPSBrZXlzQVtpXTtcblxuICAgIGlmICghaGFzT3duUHJvcGVydHkuY2FsbChvYmpCLCBjdXJyZW50S2V5KSB8fCAhb2JqZWN0SXMob2JqQVtjdXJyZW50S2V5XSwgb2JqQltjdXJyZW50S2V5XSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBHaXZlbiBhbnkgbm9kZSByZXR1cm4gdGhlIGZpcnN0IGxlYWYgbm9kZSB3aXRob3V0IGNoaWxkcmVuLlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX0gbm9kZVxuICogQHJldHVybiB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX1cbiAqL1xuXG5mdW5jdGlvbiBnZXRMZWFmTm9kZShub2RlKSB7XG4gIHdoaWxlIChub2RlICYmIG5vZGUuZmlyc3RDaGlsZCkge1xuICAgIG5vZGUgPSBub2RlLmZpcnN0Q2hpbGQ7XG4gIH1cblxuICByZXR1cm4gbm9kZTtcbn1cbi8qKlxuICogR2V0IHRoZSBuZXh0IHNpYmxpbmcgd2l0aGluIGEgY29udGFpbmVyLiBUaGlzIHdpbGwgd2FsayB1cCB0aGVcbiAqIERPTSBpZiBhIG5vZGUncyBzaWJsaW5ncyBoYXZlIGJlZW4gZXhoYXVzdGVkLlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX0gbm9kZVxuICogQHJldHVybiB7P0RPTUVsZW1lbnR8RE9NVGV4dE5vZGV9XG4gKi9cblxuXG5mdW5jdGlvbiBnZXRTaWJsaW5nTm9kZShub2RlKSB7XG4gIHdoaWxlIChub2RlKSB7XG4gICAgaWYgKG5vZGUubmV4dFNpYmxpbmcpIHtcbiAgICAgIHJldHVybiBub2RlLm5leHRTaWJsaW5nO1xuICAgIH1cblxuICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gIH1cbn1cbi8qKlxuICogR2V0IG9iamVjdCBkZXNjcmliaW5nIHRoZSBub2RlcyB3aGljaCBjb250YWluIGNoYXJhY3RlcnMgYXQgb2Zmc2V0LlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX0gcm9vdFxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHJldHVybiB7P29iamVjdH1cbiAqL1xuXG5cbmZ1bmN0aW9uIGdldE5vZGVGb3JDaGFyYWN0ZXJPZmZzZXQocm9vdCwgb2Zmc2V0KSB7XG4gIHZhciBub2RlID0gZ2V0TGVhZk5vZGUocm9vdCk7XG4gIHZhciBub2RlU3RhcnQgPSAwO1xuICB2YXIgbm9kZUVuZCA9IDA7XG5cbiAgd2hpbGUgKG5vZGUpIHtcbiAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gVEVYVF9OT0RFKSB7XG4gICAgICBub2RlRW5kID0gbm9kZVN0YXJ0ICsgbm9kZS50ZXh0Q29udGVudC5sZW5ndGg7XG5cbiAgICAgIGlmIChub2RlU3RhcnQgPD0gb2Zmc2V0ICYmIG5vZGVFbmQgPj0gb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbm9kZTogbm9kZSxcbiAgICAgICAgICBvZmZzZXQ6IG9mZnNldCAtIG5vZGVTdGFydFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBub2RlU3RhcnQgPSBub2RlRW5kO1xuICAgIH1cblxuICAgIG5vZGUgPSBnZXRMZWFmTm9kZShnZXRTaWJsaW5nTm9kZShub2RlKSk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR9IG91dGVyTm9kZVxuICogQHJldHVybiB7P29iamVjdH1cbiAqL1xuXG5mdW5jdGlvbiBnZXRPZmZzZXRzKG91dGVyTm9kZSkge1xuICB2YXIgb3duZXJEb2N1bWVudCA9IG91dGVyTm9kZS5vd25lckRvY3VtZW50O1xuICB2YXIgd2luID0gb3duZXJEb2N1bWVudCAmJiBvd25lckRvY3VtZW50LmRlZmF1bHRWaWV3IHx8IHdpbmRvdztcbiAgdmFyIHNlbGVjdGlvbiA9IHdpbi5nZXRTZWxlY3Rpb24gJiYgd2luLmdldFNlbGVjdGlvbigpO1xuXG4gIGlmICghc2VsZWN0aW9uIHx8IHNlbGVjdGlvbi5yYW5nZUNvdW50ID09PSAwKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgYW5jaG9yTm9kZSA9IHNlbGVjdGlvbi5hbmNob3JOb2RlLFxuICAgICAgYW5jaG9yT2Zmc2V0ID0gc2VsZWN0aW9uLmFuY2hvck9mZnNldCxcbiAgICAgIGZvY3VzTm9kZSA9IHNlbGVjdGlvbi5mb2N1c05vZGUsXG4gICAgICBmb2N1c09mZnNldCA9IHNlbGVjdGlvbi5mb2N1c09mZnNldDsgLy8gSW4gRmlyZWZveCwgYW5jaG9yTm9kZSBhbmQgZm9jdXNOb2RlIGNhbiBiZSBcImFub255bW91cyBkaXZzXCIsIGUuZy4gdGhlXG4gIC8vIHVwL2Rvd24gYnV0dG9ucyBvbiBhbiA8aW5wdXQgdHlwZT1cIm51bWJlclwiPi4gQW5vbnltb3VzIGRpdnMgZG8gbm90IHNlZW0gdG9cbiAgLy8gZXhwb3NlIHByb3BlcnRpZXMsIHRyaWdnZXJpbmcgYSBcIlBlcm1pc3Npb24gZGVuaWVkIGVycm9yXCIgaWYgYW55IG9mIGl0c1xuICAvLyBwcm9wZXJ0aWVzIGFyZSBhY2Nlc3NlZC4gVGhlIG9ubHkgc2VlbWluZ2x5IHBvc3NpYmxlIHdheSB0byBhdm9pZCBlcnJvcmluZ1xuICAvLyBpcyB0byBhY2Nlc3MgYSBwcm9wZXJ0eSB0aGF0IHR5cGljYWxseSB3b3JrcyBmb3Igbm9uLWFub255bW91cyBkaXZzIGFuZFxuICAvLyBjYXRjaCBhbnkgZXJyb3IgdGhhdCBtYXkgb3RoZXJ3aXNlIGFyaXNlLiBTZWVcbiAgLy8gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjA4NDI3XG5cbiAgdHJ5IHtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtZXhwcmVzc2lvbnMgKi9cbiAgICBhbmNob3JOb2RlLm5vZGVUeXBlO1xuICAgIGZvY3VzTm9kZS5ub2RlVHlwZTtcbiAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLXVudXNlZC1leHByZXNzaW9ucyAqL1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gZ2V0TW9kZXJuT2Zmc2V0c0Zyb21Qb2ludHMob3V0ZXJOb2RlLCBhbmNob3JOb2RlLCBhbmNob3JPZmZzZXQsIGZvY3VzTm9kZSwgZm9jdXNPZmZzZXQpO1xufVxuLyoqXG4gKiBSZXR1cm5zIHtzdGFydCwgZW5kfSB3aGVyZSBgc3RhcnRgIGlzIHRoZSBjaGFyYWN0ZXIvY29kZXBvaW50IGluZGV4IG9mXG4gKiAoYW5jaG9yTm9kZSwgYW5jaG9yT2Zmc2V0KSB3aXRoaW4gdGhlIHRleHRDb250ZW50IG9mIGBvdXRlck5vZGVgLCBhbmRcbiAqIGBlbmRgIGlzIHRoZSBpbmRleCBvZiAoZm9jdXNOb2RlLCBmb2N1c09mZnNldCkuXG4gKlxuICogUmV0dXJucyBudWxsIGlmIHlvdSBwYXNzIGluIGdhcmJhZ2UgaW5wdXQgYnV0IHdlIHNob3VsZCBwcm9iYWJseSBqdXN0IGNyYXNoLlxuICpcbiAqIEV4cG9ydGVkIG9ubHkgZm9yIHRlc3RpbmcuXG4gKi9cblxuZnVuY3Rpb24gZ2V0TW9kZXJuT2Zmc2V0c0Zyb21Qb2ludHMob3V0ZXJOb2RlLCBhbmNob3JOb2RlLCBhbmNob3JPZmZzZXQsIGZvY3VzTm9kZSwgZm9jdXNPZmZzZXQpIHtcbiAgdmFyIGxlbmd0aCA9IDA7XG4gIHZhciBzdGFydCA9IC0xO1xuICB2YXIgZW5kID0gLTE7XG4gIHZhciBpbmRleFdpdGhpbkFuY2hvciA9IDA7XG4gIHZhciBpbmRleFdpdGhpbkZvY3VzID0gMDtcbiAgdmFyIG5vZGUgPSBvdXRlck5vZGU7XG4gIHZhciBwYXJlbnROb2RlID0gbnVsbDtcblxuICBvdXRlcjogd2hpbGUgKHRydWUpIHtcbiAgICB2YXIgbmV4dCA9IG51bGw7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKG5vZGUgPT09IGFuY2hvck5vZGUgJiYgKGFuY2hvck9mZnNldCA9PT0gMCB8fCBub2RlLm5vZGVUeXBlID09PSBURVhUX05PREUpKSB7XG4gICAgICAgIHN0YXJ0ID0gbGVuZ3RoICsgYW5jaG9yT2Zmc2V0O1xuICAgICAgfVxuXG4gICAgICBpZiAobm9kZSA9PT0gZm9jdXNOb2RlICYmIChmb2N1c09mZnNldCA9PT0gMCB8fCBub2RlLm5vZGVUeXBlID09PSBURVhUX05PREUpKSB7XG4gICAgICAgIGVuZCA9IGxlbmd0aCArIGZvY3VzT2Zmc2V0O1xuICAgICAgfVxuXG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gVEVYVF9OT0RFKSB7XG4gICAgICAgIGxlbmd0aCArPSBub2RlLm5vZGVWYWx1ZS5sZW5ndGg7XG4gICAgICB9XG5cbiAgICAgIGlmICgobmV4dCA9IG5vZGUuZmlyc3RDaGlsZCkgPT09IG51bGwpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9IC8vIE1vdmluZyBmcm9tIGBub2RlYCB0byBpdHMgZmlyc3QgY2hpbGQgYG5leHRgLlxuXG5cbiAgICAgIHBhcmVudE5vZGUgPSBub2RlO1xuICAgICAgbm9kZSA9IG5leHQ7XG4gICAgfVxuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGlmIChub2RlID09PSBvdXRlck5vZGUpIHtcbiAgICAgICAgLy8gSWYgYG91dGVyTm9kZWAgaGFzIGNoaWxkcmVuLCB0aGlzIGlzIGFsd2F5cyB0aGUgc2Vjb25kIHRpbWUgdmlzaXRpbmdcbiAgICAgICAgLy8gaXQuIElmIGl0IGhhcyBubyBjaGlsZHJlbiwgdGhpcyBpcyBzdGlsbCB0aGUgZmlyc3QgbG9vcCwgYW5kIHRoZSBvbmx5XG4gICAgICAgIC8vIHZhbGlkIHNlbGVjdGlvbiBpcyBhbmNob3JOb2RlIGFuZCBmb2N1c05vZGUgYm90aCBlcXVhbCB0byB0aGlzIG5vZGVcbiAgICAgICAgLy8gYW5kIGJvdGggb2Zmc2V0cyAwLCBpbiB3aGljaCBjYXNlIHdlIHdpbGwgaGF2ZSBoYW5kbGVkIGFib3ZlLlxuICAgICAgICBicmVhayBvdXRlcjtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmVudE5vZGUgPT09IGFuY2hvck5vZGUgJiYgKytpbmRleFdpdGhpbkFuY2hvciA9PT0gYW5jaG9yT2Zmc2V0KSB7XG4gICAgICAgIHN0YXJ0ID0gbGVuZ3RoO1xuICAgICAgfVxuXG4gICAgICBpZiAocGFyZW50Tm9kZSA9PT0gZm9jdXNOb2RlICYmICsraW5kZXhXaXRoaW5Gb2N1cyA9PT0gZm9jdXNPZmZzZXQpIHtcbiAgICAgICAgZW5kID0gbGVuZ3RoO1xuICAgICAgfVxuXG4gICAgICBpZiAoKG5leHQgPSBub2RlLm5leHRTaWJsaW5nKSAhPT0gbnVsbCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgbm9kZSA9IHBhcmVudE5vZGU7XG4gICAgICBwYXJlbnROb2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICAgIH0gLy8gTW92aW5nIGZyb20gYG5vZGVgIHRvIGl0cyBuZXh0IHNpYmxpbmcgYG5leHRgLlxuXG5cbiAgICBub2RlID0gbmV4dDtcbiAgfVxuXG4gIGlmIChzdGFydCA9PT0gLTEgfHwgZW5kID09PSAtMSkge1xuICAgIC8vIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbi4gKFdvdWxkIGhhcHBlbiBpZiB0aGUgYW5jaG9yL2ZvY3VzIG5vZGVzIGFyZW4ndFxuICAgIC8vIGFjdHVhbGx5IGluc2lkZSB0aGUgcGFzc2VkLWluIG5vZGUuKVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBzdGFydDogc3RhcnQsXG4gICAgZW5kOiBlbmRcbiAgfTtcbn1cbi8qKlxuICogSW4gbW9kZXJuIG5vbi1JRSBicm93c2Vycywgd2UgY2FuIHN1cHBvcnQgYm90aCBmb3J3YXJkIGFuZCBiYWNrd2FyZFxuICogc2VsZWN0aW9ucy5cbiAqXG4gKiBOb3RlOiBJRTEwKyBzdXBwb3J0cyB0aGUgU2VsZWN0aW9uIG9iamVjdCwgYnV0IGl0IGRvZXMgbm90IHN1cHBvcnRcbiAqIHRoZSBgZXh0ZW5kYCBtZXRob2QsIHdoaWNoIG1lYW5zIHRoYXQgZXZlbiBpbiBtb2Rlcm4gSUUsIGl0J3Mgbm90IHBvc3NpYmxlXG4gKiB0byBwcm9ncmFtbWF0aWNhbGx5IGNyZWF0ZSBhIGJhY2t3YXJkIHNlbGVjdGlvbi4gVGh1cywgZm9yIGFsbCBJRVxuICogdmVyc2lvbnMsIHdlIHVzZSB0aGUgb2xkIElFIEFQSSB0byBjcmVhdGUgb3VyIHNlbGVjdGlvbnMuXG4gKlxuICogQHBhcmFtIHtET01FbGVtZW50fERPTVRleHROb2RlfSBub2RlXG4gKiBAcGFyYW0ge29iamVjdH0gb2Zmc2V0c1xuICovXG5cbmZ1bmN0aW9uIHNldE9mZnNldHMobm9kZSwgb2Zmc2V0cykge1xuICB2YXIgZG9jID0gbm9kZS5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50O1xuICB2YXIgd2luID0gZG9jICYmIGRvYy5kZWZhdWx0VmlldyB8fCB3aW5kb3c7IC8vIEVkZ2UgZmFpbHMgd2l0aCBcIk9iamVjdCBleHBlY3RlZFwiIGluIHNvbWUgc2NlbmFyaW9zLlxuICAvLyAoRm9yIGluc3RhbmNlOiBUaW55TUNFIGVkaXRvciB1c2VkIGluIGEgbGlzdCBjb21wb25lbnQgdGhhdCBzdXBwb3J0cyBwYXN0aW5nIHRvIGFkZCBtb3JlLFxuICAvLyBmYWlscyB3aGVuIHBhc3RpbmcgMTAwKyBpdGVtcylcblxuICBpZiAoIXdpbi5nZXRTZWxlY3Rpb24pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgc2VsZWN0aW9uID0gd2luLmdldFNlbGVjdGlvbigpO1xuICB2YXIgbGVuZ3RoID0gbm9kZS50ZXh0Q29udGVudC5sZW5ndGg7XG4gIHZhciBzdGFydCA9IE1hdGgubWluKG9mZnNldHMuc3RhcnQsIGxlbmd0aCk7XG4gIHZhciBlbmQgPSBvZmZzZXRzLmVuZCA9PT0gdW5kZWZpbmVkID8gc3RhcnQgOiBNYXRoLm1pbihvZmZzZXRzLmVuZCwgbGVuZ3RoKTsgLy8gSUUgMTEgdXNlcyBtb2Rlcm4gc2VsZWN0aW9uLCBidXQgZG9lc24ndCBzdXBwb3J0IHRoZSBleHRlbmQgbWV0aG9kLlxuICAvLyBGbGlwIGJhY2t3YXJkIHNlbGVjdGlvbnMsIHNvIHdlIGNhbiBzZXQgd2l0aCBhIHNpbmdsZSByYW5nZS5cblxuICBpZiAoIXNlbGVjdGlvbi5leHRlbmQgJiYgc3RhcnQgPiBlbmQpIHtcbiAgICB2YXIgdGVtcCA9IGVuZDtcbiAgICBlbmQgPSBzdGFydDtcbiAgICBzdGFydCA9IHRlbXA7XG4gIH1cblxuICB2YXIgc3RhcnRNYXJrZXIgPSBnZXROb2RlRm9yQ2hhcmFjdGVyT2Zmc2V0KG5vZGUsIHN0YXJ0KTtcbiAgdmFyIGVuZE1hcmtlciA9IGdldE5vZGVGb3JDaGFyYWN0ZXJPZmZzZXQobm9kZSwgZW5kKTtcblxuICBpZiAoc3RhcnRNYXJrZXIgJiYgZW5kTWFya2VyKSB7XG4gICAgaWYgKHNlbGVjdGlvbi5yYW5nZUNvdW50ID09PSAxICYmIHNlbGVjdGlvbi5hbmNob3JOb2RlID09PSBzdGFydE1hcmtlci5ub2RlICYmIHNlbGVjdGlvbi5hbmNob3JPZmZzZXQgPT09IHN0YXJ0TWFya2VyLm9mZnNldCAmJiBzZWxlY3Rpb24uZm9jdXNOb2RlID09PSBlbmRNYXJrZXIubm9kZSAmJiBzZWxlY3Rpb24uZm9jdXNPZmZzZXQgPT09IGVuZE1hcmtlci5vZmZzZXQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcmFuZ2UgPSBkb2MuY3JlYXRlUmFuZ2UoKTtcbiAgICByYW5nZS5zZXRTdGFydChzdGFydE1hcmtlci5ub2RlLCBzdGFydE1hcmtlci5vZmZzZXQpO1xuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcblxuICAgIGlmIChzdGFydCA+IGVuZCkge1xuICAgICAgc2VsZWN0aW9uLmFkZFJhbmdlKHJhbmdlKTtcbiAgICAgIHNlbGVjdGlvbi5leHRlbmQoZW5kTWFya2VyLm5vZGUsIGVuZE1hcmtlci5vZmZzZXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByYW5nZS5zZXRFbmQoZW5kTWFya2VyLm5vZGUsIGVuZE1hcmtlci5vZmZzZXQpO1xuICAgICAgc2VsZWN0aW9uLmFkZFJhbmdlKHJhbmdlKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNUZXh0Tm9kZShub2RlKSB7XG4gIHJldHVybiBub2RlICYmIG5vZGUubm9kZVR5cGUgPT09IFRFWFRfTk9ERTtcbn1cblxuZnVuY3Rpb24gY29udGFpbnNOb2RlKG91dGVyTm9kZSwgaW5uZXJOb2RlKSB7XG4gIGlmICghb3V0ZXJOb2RlIHx8ICFpbm5lck5vZGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gZWxzZSBpZiAob3V0ZXJOb2RlID09PSBpbm5lck5vZGUpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChpc1RleHROb2RlKG91dGVyTm9kZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gZWxzZSBpZiAoaXNUZXh0Tm9kZShpbm5lck5vZGUpKSB7XG4gICAgcmV0dXJuIGNvbnRhaW5zTm9kZShvdXRlck5vZGUsIGlubmVyTm9kZS5wYXJlbnROb2RlKTtcbiAgfSBlbHNlIGlmICgnY29udGFpbnMnIGluIG91dGVyTm9kZSkge1xuICAgIHJldHVybiBvdXRlck5vZGUuY29udGFpbnMoaW5uZXJOb2RlKTtcbiAgfSBlbHNlIGlmIChvdXRlck5vZGUuY29tcGFyZURvY3VtZW50UG9zaXRpb24pIHtcbiAgICByZXR1cm4gISEob3V0ZXJOb2RlLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGlubmVyTm9kZSkgJiAxNik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzSW5Eb2N1bWVudChub2RlKSB7XG4gIHJldHVybiBub2RlICYmIG5vZGUub3duZXJEb2N1bWVudCAmJiBjb250YWluc05vZGUobm9kZS5vd25lckRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgbm9kZSk7XG59XG5cbmZ1bmN0aW9uIGlzU2FtZU9yaWdpbkZyYW1lKGlmcmFtZSkge1xuICB0cnkge1xuICAgIC8vIEFjY2Vzc2luZyB0aGUgY29udGVudERvY3VtZW50IG9mIGEgSFRNTElmcmFtZUVsZW1lbnQgY2FuIGNhdXNlIHRoZSBicm93c2VyXG4gICAgLy8gdG8gdGhyb3csIGUuZy4gaWYgaXQgaGFzIGEgY3Jvc3Mtb3JpZ2luIHNyYyBhdHRyaWJ1dGUuXG4gICAgLy8gU2FmYXJpIHdpbGwgc2hvdyBhbiBlcnJvciBpbiB0aGUgY29uc29sZSB3aGVuIHRoZSBhY2Nlc3MgcmVzdWx0cyBpbiBcIkJsb2NrZWQgYSBmcmFtZSB3aXRoIG9yaWdpblwiLiBlLmc6XG4gICAgLy8gaWZyYW1lLmNvbnRlbnREb2N1bWVudC5kZWZhdWx0VmlldztcbiAgICAvLyBBIHNhZmV0eSB3YXkgaXMgdG8gYWNjZXNzIG9uZSBvZiB0aGUgY3Jvc3Mgb3JpZ2luIHByb3BlcnRpZXM6IFdpbmRvdyBvciBMb2NhdGlvblxuICAgIC8vIFdoaWNoIG1pZ2h0IHJlc3VsdCBpbiBcIlNlY3VyaXR5RXJyb3JcIiBET00gRXhjZXB0aW9uIGFuZCBpdCBpcyBjb21wYXRpYmxlIHRvIFNhZmFyaS5cbiAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9icm93c2Vycy5odG1sI2ludGVncmF0aW9uLXdpdGgtaWRsXG4gICAgcmV0dXJuIHR5cGVvZiBpZnJhbWUuY29udGVudFdpbmRvdy5sb2NhdGlvbi5ocmVmID09PSAnc3RyaW5nJztcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldEFjdGl2ZUVsZW1lbnREZWVwKCkge1xuICB2YXIgd2luID0gd2luZG93O1xuICB2YXIgZWxlbWVudCA9IGdldEFjdGl2ZUVsZW1lbnQoKTtcblxuICB3aGlsZSAoZWxlbWVudCBpbnN0YW5jZW9mIHdpbi5IVE1MSUZyYW1lRWxlbWVudCkge1xuICAgIGlmIChpc1NhbWVPcmlnaW5GcmFtZShlbGVtZW50KSkge1xuICAgICAgd2luID0gZWxlbWVudC5jb250ZW50V2luZG93O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG5cbiAgICBlbGVtZW50ID0gZ2V0QWN0aXZlRWxlbWVudCh3aW4uZG9jdW1lbnQpO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59XG4vKipcbiAqIEBSZWFjdElucHV0U2VsZWN0aW9uOiBSZWFjdCBpbnB1dCBzZWxlY3Rpb24gbW9kdWxlLiBCYXNlZCBvbiBTZWxlY3Rpb24uanMsXG4gKiBidXQgbW9kaWZpZWQgdG8gYmUgc3VpdGFibGUgZm9yIHJlYWN0IGFuZCBoYXMgYSBjb3VwbGUgb2YgYnVnIGZpeGVzIChkb2Vzbid0XG4gKiBhc3N1bWUgYnV0dG9ucyBoYXZlIHJhbmdlIHNlbGVjdGlvbnMgYWxsb3dlZCkuXG4gKiBJbnB1dCBzZWxlY3Rpb24gbW9kdWxlIGZvciBSZWFjdC5cbiAqL1xuXG4vKipcbiAqIEBoYXNTZWxlY3Rpb25DYXBhYmlsaXRpZXM6IHdlIGdldCB0aGUgZWxlbWVudCB0eXBlcyB0aGF0IHN1cHBvcnQgc2VsZWN0aW9uXG4gKiBmcm9tIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI2RvLW5vdC1hcHBseSwgbG9va2luZyBhdCBgc2VsZWN0aW9uU3RhcnRgXG4gKiBhbmQgYHNlbGVjdGlvbkVuZGAgcm93cy5cbiAqL1xuXG5cbmZ1bmN0aW9uIGhhc1NlbGVjdGlvbkNhcGFiaWxpdGllcyhlbGVtKSB7XG4gIHZhciBub2RlTmFtZSA9IGVsZW0gJiYgZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiBub2RlTmFtZSAmJiAobm9kZU5hbWUgPT09ICdpbnB1dCcgJiYgKGVsZW0udHlwZSA9PT0gJ3RleHQnIHx8IGVsZW0udHlwZSA9PT0gJ3NlYXJjaCcgfHwgZWxlbS50eXBlID09PSAndGVsJyB8fCBlbGVtLnR5cGUgPT09ICd1cmwnIHx8IGVsZW0udHlwZSA9PT0gJ3Bhc3N3b3JkJykgfHwgbm9kZU5hbWUgPT09ICd0ZXh0YXJlYScgfHwgZWxlbS5jb250ZW50RWRpdGFibGUgPT09ICd0cnVlJyk7XG59XG5mdW5jdGlvbiBnZXRTZWxlY3Rpb25JbmZvcm1hdGlvbigpIHtcbiAgdmFyIGZvY3VzZWRFbGVtID0gZ2V0QWN0aXZlRWxlbWVudERlZXAoKTtcbiAgcmV0dXJuIHtcbiAgICBmb2N1c2VkRWxlbTogZm9jdXNlZEVsZW0sXG4gICAgc2VsZWN0aW9uUmFuZ2U6IGhhc1NlbGVjdGlvbkNhcGFiaWxpdGllcyhmb2N1c2VkRWxlbSkgPyBnZXRTZWxlY3Rpb24oZm9jdXNlZEVsZW0pIDogbnVsbFxuICB9O1xufVxuLyoqXG4gKiBAcmVzdG9yZVNlbGVjdGlvbjogSWYgYW55IHNlbGVjdGlvbiBpbmZvcm1hdGlvbiB3YXMgcG90ZW50aWFsbHkgbG9zdCxcbiAqIHJlc3RvcmUgaXQuIFRoaXMgaXMgdXNlZnVsIHdoZW4gcGVyZm9ybWluZyBvcGVyYXRpb25zIHRoYXQgY291bGQgcmVtb3ZlIGRvbVxuICogbm9kZXMgYW5kIHBsYWNlIHRoZW0gYmFjayBpbiwgcmVzdWx0aW5nIGluIGZvY3VzIGJlaW5nIGxvc3QuXG4gKi9cblxuZnVuY3Rpb24gcmVzdG9yZVNlbGVjdGlvbihwcmlvclNlbGVjdGlvbkluZm9ybWF0aW9uKSB7XG4gIHZhciBjdXJGb2N1c2VkRWxlbSA9IGdldEFjdGl2ZUVsZW1lbnREZWVwKCk7XG4gIHZhciBwcmlvckZvY3VzZWRFbGVtID0gcHJpb3JTZWxlY3Rpb25JbmZvcm1hdGlvbi5mb2N1c2VkRWxlbTtcbiAgdmFyIHByaW9yU2VsZWN0aW9uUmFuZ2UgPSBwcmlvclNlbGVjdGlvbkluZm9ybWF0aW9uLnNlbGVjdGlvblJhbmdlO1xuXG4gIGlmIChjdXJGb2N1c2VkRWxlbSAhPT0gcHJpb3JGb2N1c2VkRWxlbSAmJiBpc0luRG9jdW1lbnQocHJpb3JGb2N1c2VkRWxlbSkpIHtcbiAgICBpZiAocHJpb3JTZWxlY3Rpb25SYW5nZSAhPT0gbnVsbCAmJiBoYXNTZWxlY3Rpb25DYXBhYmlsaXRpZXMocHJpb3JGb2N1c2VkRWxlbSkpIHtcbiAgICAgIHNldFNlbGVjdGlvbihwcmlvckZvY3VzZWRFbGVtLCBwcmlvclNlbGVjdGlvblJhbmdlKTtcbiAgICB9IC8vIEZvY3VzaW5nIGEgbm9kZSBjYW4gY2hhbmdlIHRoZSBzY3JvbGwgcG9zaXRpb24sIHdoaWNoIGlzIHVuZGVzaXJhYmxlXG5cblxuICAgIHZhciBhbmNlc3RvcnMgPSBbXTtcbiAgICB2YXIgYW5jZXN0b3IgPSBwcmlvckZvY3VzZWRFbGVtO1xuXG4gICAgd2hpbGUgKGFuY2VzdG9yID0gYW5jZXN0b3IucGFyZW50Tm9kZSkge1xuICAgICAgaWYgKGFuY2VzdG9yLm5vZGVUeXBlID09PSBFTEVNRU5UX05PREUpIHtcbiAgICAgICAgYW5jZXN0b3JzLnB1c2goe1xuICAgICAgICAgIGVsZW1lbnQ6IGFuY2VzdG9yLFxuICAgICAgICAgIGxlZnQ6IGFuY2VzdG9yLnNjcm9sbExlZnQsXG4gICAgICAgICAgdG9wOiBhbmNlc3Rvci5zY3JvbGxUb3BcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBwcmlvckZvY3VzZWRFbGVtLmZvY3VzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcmlvckZvY3VzZWRFbGVtLmZvY3VzKCk7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbmNlc3RvcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBpbmZvID0gYW5jZXN0b3JzW2ldO1xuICAgICAgaW5mby5lbGVtZW50LnNjcm9sbExlZnQgPSBpbmZvLmxlZnQ7XG4gICAgICBpbmZvLmVsZW1lbnQuc2Nyb2xsVG9wID0gaW5mby50b3A7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBnZXRTZWxlY3Rpb246IEdldHMgdGhlIHNlbGVjdGlvbiBib3VuZHMgb2YgYSBmb2N1c2VkIHRleHRhcmVhLCBpbnB1dCBvclxuICogY29udGVudEVkaXRhYmxlIG5vZGUuXG4gKiAtQGlucHV0OiBMb29rIHVwIHNlbGVjdGlvbiBib3VuZHMgb2YgdGhpcyBpbnB1dFxuICogLUByZXR1cm4ge3N0YXJ0OiBzZWxlY3Rpb25TdGFydCwgZW5kOiBzZWxlY3Rpb25FbmR9XG4gKi9cblxuZnVuY3Rpb24gZ2V0U2VsZWN0aW9uKGlucHV0KSB7XG4gIHZhciBzZWxlY3Rpb247XG5cbiAgaWYgKCdzZWxlY3Rpb25TdGFydCcgaW4gaW5wdXQpIHtcbiAgICAvLyBNb2Rlcm4gYnJvd3NlciB3aXRoIGlucHV0IG9yIHRleHRhcmVhLlxuICAgIHNlbGVjdGlvbiA9IHtcbiAgICAgIHN0YXJ0OiBpbnB1dC5zZWxlY3Rpb25TdGFydCxcbiAgICAgIGVuZDogaW5wdXQuc2VsZWN0aW9uRW5kXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICAvLyBDb250ZW50IGVkaXRhYmxlIG9yIG9sZCBJRSB0ZXh0YXJlYS5cbiAgICBzZWxlY3Rpb24gPSBnZXRPZmZzZXRzKGlucHV0KTtcbiAgfVxuXG4gIHJldHVybiBzZWxlY3Rpb24gfHwge1xuICAgIHN0YXJ0OiAwLFxuICAgIGVuZDogMFxuICB9O1xufVxuLyoqXG4gKiBAc2V0U2VsZWN0aW9uOiBTZXRzIHRoZSBzZWxlY3Rpb24gYm91bmRzIG9mIGEgdGV4dGFyZWEgb3IgaW5wdXQgYW5kIGZvY3VzZXNcbiAqIHRoZSBpbnB1dC5cbiAqIC1AaW5wdXQgICAgIFNldCBzZWxlY3Rpb24gYm91bmRzIG9mIHRoaXMgaW5wdXQgb3IgdGV4dGFyZWFcbiAqIC1Ab2Zmc2V0cyAgIE9iamVjdCBvZiBzYW1lIGZvcm0gdGhhdCBpcyByZXR1cm5lZCBmcm9tIGdldCpcbiAqL1xuXG5mdW5jdGlvbiBzZXRTZWxlY3Rpb24oaW5wdXQsIG9mZnNldHMpIHtcbiAgdmFyIHN0YXJ0ID0gb2Zmc2V0cy5zdGFydDtcbiAgdmFyIGVuZCA9IG9mZnNldHMuZW5kO1xuXG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuZCA9IHN0YXJ0O1xuICB9XG5cbiAgaWYgKCdzZWxlY3Rpb25TdGFydCcgaW4gaW5wdXQpIHtcbiAgICBpbnB1dC5zZWxlY3Rpb25TdGFydCA9IHN0YXJ0O1xuICAgIGlucHV0LnNlbGVjdGlvbkVuZCA9IE1hdGgubWluKGVuZCwgaW5wdXQudmFsdWUubGVuZ3RoKTtcbiAgfSBlbHNlIHtcbiAgICBzZXRPZmZzZXRzKGlucHV0LCBvZmZzZXRzKTtcbiAgfVxufVxuXG52YXIgc2tpcFNlbGVjdGlvbkNoYW5nZUV2ZW50ID0gY2FuVXNlRE9NICYmICdkb2N1bWVudE1vZGUnIGluIGRvY3VtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50TW9kZSA8PSAxMTtcblxuZnVuY3Rpb24gcmVnaXN0ZXJFdmVudHMkMygpIHtcbiAgcmVnaXN0ZXJUd29QaGFzZUV2ZW50KCdvblNlbGVjdCcsIFsnZm9jdXNvdXQnLCAnY29udGV4dG1lbnUnLCAnZHJhZ2VuZCcsICdmb2N1c2luJywgJ2tleWRvd24nLCAna2V5dXAnLCAnbW91c2Vkb3duJywgJ21vdXNldXAnLCAnc2VsZWN0aW9uY2hhbmdlJ10pO1xufVxuXG52YXIgYWN0aXZlRWxlbWVudCQxID0gbnVsbDtcbnZhciBhY3RpdmVFbGVtZW50SW5zdCQxID0gbnVsbDtcbnZhciBsYXN0U2VsZWN0aW9uID0gbnVsbDtcbnZhciBtb3VzZURvd24gPSBmYWxzZTtcbi8qKlxuICogR2V0IGFuIG9iamVjdCB3aGljaCBpcyBhIHVuaXF1ZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgY3VycmVudCBzZWxlY3Rpb24uXG4gKlxuICogVGhlIHJldHVybiB2YWx1ZSB3aWxsIG5vdCBiZSBjb25zaXN0ZW50IGFjcm9zcyBub2RlcyBvciBicm93c2VycywgYnV0XG4gKiB0d28gaWRlbnRpY2FsIHNlbGVjdGlvbnMgb24gdGhlIHNhbWUgbm9kZSB3aWxsIHJldHVybiBpZGVudGljYWwgb2JqZWN0cy5cbiAqL1xuXG5mdW5jdGlvbiBnZXRTZWxlY3Rpb24kMShub2RlKSB7XG4gIGlmICgnc2VsZWN0aW9uU3RhcnQnIGluIG5vZGUgJiYgaGFzU2VsZWN0aW9uQ2FwYWJpbGl0aWVzKG5vZGUpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXJ0OiBub2RlLnNlbGVjdGlvblN0YXJ0LFxuICAgICAgZW5kOiBub2RlLnNlbGVjdGlvbkVuZFxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgdmFyIHdpbiA9IG5vZGUub3duZXJEb2N1bWVudCAmJiBub2RlLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcgfHwgd2luZG93O1xuICAgIHZhciBzZWxlY3Rpb24gPSB3aW4uZ2V0U2VsZWN0aW9uKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGFuY2hvck5vZGU6IHNlbGVjdGlvbi5hbmNob3JOb2RlLFxuICAgICAgYW5jaG9yT2Zmc2V0OiBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0LFxuICAgICAgZm9jdXNOb2RlOiBzZWxlY3Rpb24uZm9jdXNOb2RlLFxuICAgICAgZm9jdXNPZmZzZXQ6IHNlbGVjdGlvbi5mb2N1c09mZnNldFxuICAgIH07XG4gIH1cbn1cbi8qKlxuICogR2V0IGRvY3VtZW50IGFzc29jaWF0ZWQgd2l0aCB0aGUgZXZlbnQgdGFyZ2V0LlxuICovXG5cblxuZnVuY3Rpb24gZ2V0RXZlbnRUYXJnZXREb2N1bWVudChldmVudFRhcmdldCkge1xuICByZXR1cm4gZXZlbnRUYXJnZXQud2luZG93ID09PSBldmVudFRhcmdldCA/IGV2ZW50VGFyZ2V0LmRvY3VtZW50IDogZXZlbnRUYXJnZXQubm9kZVR5cGUgPT09IERPQ1VNRU5UX05PREUgPyBldmVudFRhcmdldCA6IGV2ZW50VGFyZ2V0Lm93bmVyRG9jdW1lbnQ7XG59XG4vKipcbiAqIFBvbGwgc2VsZWN0aW9uIHRvIHNlZSB3aGV0aGVyIGl0J3MgY2hhbmdlZC5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnRcbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudFRhcmdldFxuICogQHJldHVybiB7P1N5bnRoZXRpY0V2ZW50fVxuICovXG5cblxuZnVuY3Rpb24gY29uc3RydWN0U2VsZWN0RXZlbnQoZGlzcGF0Y2hRdWV1ZSwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KSB7XG4gIC8vIEVuc3VyZSB3ZSBoYXZlIHRoZSByaWdodCBlbGVtZW50LCBhbmQgdGhhdCB0aGUgdXNlciBpcyBub3QgZHJhZ2dpbmcgYVxuICAvLyBzZWxlY3Rpb24gKHRoaXMgbWF0Y2hlcyBuYXRpdmUgYHNlbGVjdGAgZXZlbnQgYmVoYXZpb3IpLiBJbiBIVE1MNSwgc2VsZWN0XG4gIC8vIGZpcmVzIG9ubHkgb24gaW5wdXQgYW5kIHRleHRhcmVhIHRodXMgaWYgdGhlcmUncyBubyBmb2N1c2VkIGVsZW1lbnQgd2VcbiAgLy8gd29uJ3QgZGlzcGF0Y2guXG4gIHZhciBkb2MgPSBnZXRFdmVudFRhcmdldERvY3VtZW50KG5hdGl2ZUV2ZW50VGFyZ2V0KTtcblxuICBpZiAobW91c2VEb3duIHx8IGFjdGl2ZUVsZW1lbnQkMSA9PSBudWxsIHx8IGFjdGl2ZUVsZW1lbnQkMSAhPT0gZ2V0QWN0aXZlRWxlbWVudChkb2MpKSB7XG4gICAgcmV0dXJuO1xuICB9IC8vIE9ubHkgZmlyZSB3aGVuIHNlbGVjdGlvbiBoYXMgYWN0dWFsbHkgY2hhbmdlZC5cblxuXG4gIHZhciBjdXJyZW50U2VsZWN0aW9uID0gZ2V0U2VsZWN0aW9uJDEoYWN0aXZlRWxlbWVudCQxKTtcblxuICBpZiAoIWxhc3RTZWxlY3Rpb24gfHwgIXNoYWxsb3dFcXVhbChsYXN0U2VsZWN0aW9uLCBjdXJyZW50U2VsZWN0aW9uKSkge1xuICAgIGxhc3RTZWxlY3Rpb24gPSBjdXJyZW50U2VsZWN0aW9uO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhY2N1bXVsYXRlVHdvUGhhc2VMaXN0ZW5lcnMoYWN0aXZlRWxlbWVudEluc3QkMSwgJ29uU2VsZWN0Jyk7XG5cbiAgICBpZiAobGlzdGVuZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgIHZhciBldmVudCA9IG5ldyBTeW50aGV0aWNFdmVudCgnb25TZWxlY3QnLCAnc2VsZWN0JywgbnVsbCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgICAgIGRpc3BhdGNoUXVldWUucHVzaCh7XG4gICAgICAgIGV2ZW50OiBldmVudCxcbiAgICAgICAgbGlzdGVuZXJzOiBsaXN0ZW5lcnNcbiAgICAgIH0pO1xuICAgICAgZXZlbnQudGFyZ2V0ID0gYWN0aXZlRWxlbWVudCQxO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBUaGlzIHBsdWdpbiBjcmVhdGVzIGFuIGBvblNlbGVjdGAgZXZlbnQgdGhhdCBub3JtYWxpemVzIHNlbGVjdCBldmVudHNcbiAqIGFjcm9zcyBmb3JtIGVsZW1lbnRzLlxuICpcbiAqIFN1cHBvcnRlZCBlbGVtZW50cyBhcmU6XG4gKiAtIGlucHV0IChzZWUgYGlzVGV4dElucHV0RWxlbWVudGApXG4gKiAtIHRleHRhcmVhXG4gKiAtIGNvbnRlbnRFZGl0YWJsZVxuICpcbiAqIFRoaXMgZGlmZmVycyBmcm9tIG5hdGl2ZSBicm93c2VyIGltcGxlbWVudGF0aW9ucyBpbiB0aGUgZm9sbG93aW5nIHdheXM6XG4gKiAtIEZpcmVzIG9uIGNvbnRlbnRFZGl0YWJsZSBmaWVsZHMgYXMgd2VsbCBhcyBpbnB1dHMuXG4gKiAtIEZpcmVzIGZvciBjb2xsYXBzZWQgc2VsZWN0aW9uLlxuICogLSBGaXJlcyBhZnRlciB1c2VyIGlucHV0LlxuICovXG5cblxuZnVuY3Rpb24gZXh0cmFjdEV2ZW50cyQzKGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0LCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIpIHtcbiAgdmFyIHRhcmdldE5vZGUgPSB0YXJnZXRJbnN0ID8gZ2V0Tm9kZUZyb21JbnN0YW5jZSh0YXJnZXRJbnN0KSA6IHdpbmRvdztcblxuICBzd2l0Y2ggKGRvbUV2ZW50TmFtZSkge1xuICAgIC8vIFRyYWNrIHRoZSBpbnB1dCBub2RlIHRoYXQgaGFzIGZvY3VzLlxuICAgIGNhc2UgJ2ZvY3VzaW4nOlxuICAgICAgaWYgKGlzVGV4dElucHV0RWxlbWVudCh0YXJnZXROb2RlKSB8fCB0YXJnZXROb2RlLmNvbnRlbnRFZGl0YWJsZSA9PT0gJ3RydWUnKSB7XG4gICAgICAgIGFjdGl2ZUVsZW1lbnQkMSA9IHRhcmdldE5vZGU7XG4gICAgICAgIGFjdGl2ZUVsZW1lbnRJbnN0JDEgPSB0YXJnZXRJbnN0O1xuICAgICAgICBsYXN0U2VsZWN0aW9uID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdmb2N1c291dCc6XG4gICAgICBhY3RpdmVFbGVtZW50JDEgPSBudWxsO1xuICAgICAgYWN0aXZlRWxlbWVudEluc3QkMSA9IG51bGw7XG4gICAgICBsYXN0U2VsZWN0aW9uID0gbnVsbDtcbiAgICAgIGJyZWFrO1xuICAgIC8vIERvbid0IGZpcmUgdGhlIGV2ZW50IHdoaWxlIHRoZSB1c2VyIGlzIGRyYWdnaW5nLiBUaGlzIG1hdGNoZXMgdGhlXG4gICAgLy8gc2VtYW50aWNzIG9mIHRoZSBuYXRpdmUgc2VsZWN0IGV2ZW50LlxuXG4gICAgY2FzZSAnbW91c2Vkb3duJzpcbiAgICAgIG1vdXNlRG93biA9IHRydWU7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2NvbnRleHRtZW51JzpcbiAgICBjYXNlICdtb3VzZXVwJzpcbiAgICBjYXNlICdkcmFnZW5kJzpcbiAgICAgIG1vdXNlRG93biA9IGZhbHNlO1xuICAgICAgY29uc3RydWN0U2VsZWN0RXZlbnQoZGlzcGF0Y2hRdWV1ZSwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIENocm9tZSBhbmQgSUUgZmlyZSBub24tc3RhbmRhcmQgZXZlbnQgd2hlbiBzZWxlY3Rpb24gaXMgY2hhbmdlZCAoYW5kXG4gICAgLy8gc29tZXRpbWVzIHdoZW4gaXQgaGFzbid0KS4gSUUncyBldmVudCBmaXJlcyBvdXQgb2Ygb3JkZXIgd2l0aCByZXNwZWN0XG4gICAgLy8gdG8ga2V5IGFuZCBpbnB1dCBldmVudHMgb24gZGVsZXRpb24sIHNvIHdlIGRpc2NhcmQgaXQuXG4gICAgLy9cbiAgICAvLyBGaXJlZm94IGRvZXNuJ3Qgc3VwcG9ydCBzZWxlY3Rpb25jaGFuZ2UsIHNvIGNoZWNrIHNlbGVjdGlvbiBzdGF0dXNcbiAgICAvLyBhZnRlciBlYWNoIGtleSBlbnRyeS4gVGhlIHNlbGVjdGlvbiBjaGFuZ2VzIGFmdGVyIGtleWRvd24gYW5kIGJlZm9yZVxuICAgIC8vIGtleXVwLCBidXQgd2UgY2hlY2sgb24ga2V5ZG93biBhcyB3ZWxsIGluIHRoZSBjYXNlIG9mIGhvbGRpbmcgZG93biBhXG4gICAgLy8ga2V5LCB3aGVuIG11bHRpcGxlIGtleWRvd24gZXZlbnRzIGFyZSBmaXJlZCBidXQgb25seSBvbmUga2V5dXAgaXMuXG4gICAgLy8gVGhpcyBpcyBhbHNvIG91ciBhcHByb2FjaCBmb3IgSUUgaGFuZGxpbmcsIGZvciB0aGUgcmVhc29uIGFib3ZlLlxuXG4gICAgY2FzZSAnc2VsZWN0aW9uY2hhbmdlJzpcbiAgICAgIGlmIChza2lwU2VsZWN0aW9uQ2hhbmdlRXZlbnQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAvLyBmYWxscyB0aHJvdWdoXG5cbiAgICBjYXNlICdrZXlkb3duJzpcbiAgICBjYXNlICdrZXl1cCc6XG4gICAgICBjb25zdHJ1Y3RTZWxlY3RFdmVudChkaXNwYXRjaFF1ZXVlLCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuICB9XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYSBtYXBwaW5nIG9mIHN0YW5kYXJkIHZlbmRvciBwcmVmaXhlcyB1c2luZyB0aGUgZGVmaW5lZCBzdHlsZSBwcm9wZXJ0eSBhbmQgZXZlbnQgbmFtZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3R5bGVQcm9wXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXG4gKiBAcmV0dXJucyB7b2JqZWN0fVxuICovXG5cbmZ1bmN0aW9uIG1ha2VQcmVmaXhNYXAoc3R5bGVQcm9wLCBldmVudE5hbWUpIHtcbiAgdmFyIHByZWZpeGVzID0ge307XG4gIHByZWZpeGVzW3N0eWxlUHJvcC50b0xvd2VyQ2FzZSgpXSA9IGV2ZW50TmFtZS50b0xvd2VyQ2FzZSgpO1xuICBwcmVmaXhlc1snV2Via2l0JyArIHN0eWxlUHJvcF0gPSAnd2Via2l0JyArIGV2ZW50TmFtZTtcbiAgcHJlZml4ZXNbJ01veicgKyBzdHlsZVByb3BdID0gJ21veicgKyBldmVudE5hbWU7XG4gIHJldHVybiBwcmVmaXhlcztcbn1cbi8qKlxuICogQSBsaXN0IG9mIGV2ZW50IG5hbWVzIHRvIGEgY29uZmlndXJhYmxlIGxpc3Qgb2YgdmVuZG9yIHByZWZpeGVzLlxuICovXG5cblxudmFyIHZlbmRvclByZWZpeGVzID0ge1xuICBhbmltYXRpb25lbmQ6IG1ha2VQcmVmaXhNYXAoJ0FuaW1hdGlvbicsICdBbmltYXRpb25FbmQnKSxcbiAgYW5pbWF0aW9uaXRlcmF0aW9uOiBtYWtlUHJlZml4TWFwKCdBbmltYXRpb24nLCAnQW5pbWF0aW9uSXRlcmF0aW9uJyksXG4gIGFuaW1hdGlvbnN0YXJ0OiBtYWtlUHJlZml4TWFwKCdBbmltYXRpb24nLCAnQW5pbWF0aW9uU3RhcnQnKSxcbiAgdHJhbnNpdGlvbmVuZDogbWFrZVByZWZpeE1hcCgnVHJhbnNpdGlvbicsICdUcmFuc2l0aW9uRW5kJylcbn07XG4vKipcbiAqIEV2ZW50IG5hbWVzIHRoYXQgaGF2ZSBhbHJlYWR5IGJlZW4gZGV0ZWN0ZWQgYW5kIHByZWZpeGVkIChpZiBhcHBsaWNhYmxlKS5cbiAqL1xuXG52YXIgcHJlZml4ZWRFdmVudE5hbWVzID0ge307XG4vKipcbiAqIEVsZW1lbnQgdG8gY2hlY2sgZm9yIHByZWZpeGVzIG9uLlxuICovXG5cbnZhciBzdHlsZSA9IHt9O1xuLyoqXG4gKiBCb290c3RyYXAgaWYgYSBET00gZXhpc3RzLlxuICovXG5cbmlmIChjYW5Vc2VET00pIHtcbiAgc3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKS5zdHlsZTsgLy8gT24gc29tZSBwbGF0Zm9ybXMsIGluIHBhcnRpY3VsYXIgc29tZSByZWxlYXNlcyBvZiBBbmRyb2lkIDQueCxcbiAgLy8gdGhlIHVuLXByZWZpeGVkIFwiYW5pbWF0aW9uXCIgYW5kIFwidHJhbnNpdGlvblwiIHByb3BlcnRpZXMgYXJlIGRlZmluZWQgb24gdGhlXG4gIC8vIHN0eWxlIG9iamVjdCBidXQgdGhlIGV2ZW50cyB0aGF0IGZpcmUgd2lsbCBzdGlsbCBiZSBwcmVmaXhlZCwgc28gd2UgbmVlZFxuICAvLyB0byBjaGVjayBpZiB0aGUgdW4tcHJlZml4ZWQgZXZlbnRzIGFyZSB1c2FibGUsIGFuZCBpZiBub3QgcmVtb3ZlIHRoZW0gZnJvbSB0aGUgbWFwLlxuXG4gIGlmICghKCdBbmltYXRpb25FdmVudCcgaW4gd2luZG93KSkge1xuICAgIGRlbGV0ZSB2ZW5kb3JQcmVmaXhlcy5hbmltYXRpb25lbmQuYW5pbWF0aW9uO1xuICAgIGRlbGV0ZSB2ZW5kb3JQcmVmaXhlcy5hbmltYXRpb25pdGVyYXRpb24uYW5pbWF0aW9uO1xuICAgIGRlbGV0ZSB2ZW5kb3JQcmVmaXhlcy5hbmltYXRpb25zdGFydC5hbmltYXRpb247XG4gIH0gLy8gU2FtZSBhcyBhYm92ZVxuXG5cbiAgaWYgKCEoJ1RyYW5zaXRpb25FdmVudCcgaW4gd2luZG93KSkge1xuICAgIGRlbGV0ZSB2ZW5kb3JQcmVmaXhlcy50cmFuc2l0aW9uZW5kLnRyYW5zaXRpb247XG4gIH1cbn1cbi8qKlxuICogQXR0ZW1wdHMgdG8gZGV0ZXJtaW5lIHRoZSBjb3JyZWN0IHZlbmRvciBwcmVmaXhlZCBldmVudCBuYW1lLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWVcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKi9cblxuXG5mdW5jdGlvbiBnZXRWZW5kb3JQcmVmaXhlZEV2ZW50TmFtZShldmVudE5hbWUpIHtcbiAgaWYgKHByZWZpeGVkRXZlbnROYW1lc1tldmVudE5hbWVdKSB7XG4gICAgcmV0dXJuIHByZWZpeGVkRXZlbnROYW1lc1tldmVudE5hbWVdO1xuICB9IGVsc2UgaWYgKCF2ZW5kb3JQcmVmaXhlc1tldmVudE5hbWVdKSB7XG4gICAgcmV0dXJuIGV2ZW50TmFtZTtcbiAgfVxuXG4gIHZhciBwcmVmaXhNYXAgPSB2ZW5kb3JQcmVmaXhlc1tldmVudE5hbWVdO1xuXG4gIGZvciAodmFyIHN0eWxlUHJvcCBpbiBwcmVmaXhNYXApIHtcbiAgICBpZiAocHJlZml4TWFwLmhhc093blByb3BlcnR5KHN0eWxlUHJvcCkgJiYgc3R5bGVQcm9wIGluIHN0eWxlKSB7XG4gICAgICByZXR1cm4gcHJlZml4ZWRFdmVudE5hbWVzW2V2ZW50TmFtZV0gPSBwcmVmaXhNYXBbc3R5bGVQcm9wXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXZlbnROYW1lO1xufVxuXG52YXIgQU5JTUFUSU9OX0VORCA9IGdldFZlbmRvclByZWZpeGVkRXZlbnROYW1lKCdhbmltYXRpb25lbmQnKTtcbnZhciBBTklNQVRJT05fSVRFUkFUSU9OID0gZ2V0VmVuZG9yUHJlZml4ZWRFdmVudE5hbWUoJ2FuaW1hdGlvbml0ZXJhdGlvbicpO1xudmFyIEFOSU1BVElPTl9TVEFSVCA9IGdldFZlbmRvclByZWZpeGVkRXZlbnROYW1lKCdhbmltYXRpb25zdGFydCcpO1xudmFyIFRSQU5TSVRJT05fRU5EID0gZ2V0VmVuZG9yUHJlZml4ZWRFdmVudE5hbWUoJ3RyYW5zaXRpb25lbmQnKTtcblxudmFyIHRvcExldmVsRXZlbnRzVG9SZWFjdE5hbWVzID0gbmV3IE1hcCgpOyAvLyBOT1RFOiBDYXBpdGFsaXphdGlvbiBpcyBpbXBvcnRhbnQgaW4gdGhpcyBsaXN0IVxuLy9cbi8vIEUuZy4gaXQgbmVlZHMgXCJwb2ludGVyRG93blwiLCBub3QgXCJwb2ludGVyZG93blwiLlxuLy8gVGhpcyBpcyBiZWNhdXNlIHdlIGRlcml2ZSBib3RoIFJlYWN0IG5hbWUgKFwib25Qb2ludGVyRG93blwiKVxuLy8gYW5kIERPTSBuYW1lIChcInBvaW50ZXJkb3duXCIpIGZyb20gdGhlIHNhbWUgbGlzdC5cbi8vXG4vLyBFeGNlcHRpb25zIHRoYXQgZG9uJ3QgbWF0Y2ggdGhpcyBjb252ZW50aW9uIGFyZSBsaXN0ZWQgc2VwYXJhdGVseS5cbi8vXG4vLyBwcmV0dGllci1pZ25vcmVcblxudmFyIHNpbXBsZUV2ZW50UGx1Z2luRXZlbnRzID0gWydhYm9ydCcsICdhdXhDbGljaycsICdjYW5jZWwnLCAnY2FuUGxheScsICdjYW5QbGF5VGhyb3VnaCcsICdjbGljaycsICdjbG9zZScsICdjb250ZXh0TWVudScsICdjb3B5JywgJ2N1dCcsICdkcmFnJywgJ2RyYWdFbmQnLCAnZHJhZ0VudGVyJywgJ2RyYWdFeGl0JywgJ2RyYWdMZWF2ZScsICdkcmFnT3ZlcicsICdkcmFnU3RhcnQnLCAnZHJvcCcsICdkdXJhdGlvbkNoYW5nZScsICdlbXB0aWVkJywgJ2VuY3J5cHRlZCcsICdlbmRlZCcsICdlcnJvcicsICdnb3RQb2ludGVyQ2FwdHVyZScsICdpbnB1dCcsICdpbnZhbGlkJywgJ2tleURvd24nLCAna2V5UHJlc3MnLCAna2V5VXAnLCAnbG9hZCcsICdsb2FkZWREYXRhJywgJ2xvYWRlZE1ldGFkYXRhJywgJ2xvYWRTdGFydCcsICdsb3N0UG9pbnRlckNhcHR1cmUnLCAnbW91c2VEb3duJywgJ21vdXNlTW92ZScsICdtb3VzZU91dCcsICdtb3VzZU92ZXInLCAnbW91c2VVcCcsICdwYXN0ZScsICdwYXVzZScsICdwbGF5JywgJ3BsYXlpbmcnLCAncG9pbnRlckNhbmNlbCcsICdwb2ludGVyRG93bicsICdwb2ludGVyTW92ZScsICdwb2ludGVyT3V0JywgJ3BvaW50ZXJPdmVyJywgJ3BvaW50ZXJVcCcsICdwcm9ncmVzcycsICdyYXRlQ2hhbmdlJywgJ3Jlc2V0JywgJ3Jlc2l6ZScsICdzZWVrZWQnLCAnc2Vla2luZycsICdzdGFsbGVkJywgJ3N1Ym1pdCcsICdzdXNwZW5kJywgJ3RpbWVVcGRhdGUnLCAndG91Y2hDYW5jZWwnLCAndG91Y2hFbmQnLCAndG91Y2hTdGFydCcsICd2b2x1bWVDaGFuZ2UnLCAnc2Nyb2xsJywgJ3RvZ2dsZScsICd0b3VjaE1vdmUnLCAnd2FpdGluZycsICd3aGVlbCddO1xuXG5mdW5jdGlvbiByZWdpc3RlclNpbXBsZUV2ZW50KGRvbUV2ZW50TmFtZSwgcmVhY3ROYW1lKSB7XG4gIHRvcExldmVsRXZlbnRzVG9SZWFjdE5hbWVzLnNldChkb21FdmVudE5hbWUsIHJlYWN0TmFtZSk7XG4gIHJlZ2lzdGVyVHdvUGhhc2VFdmVudChyZWFjdE5hbWUsIFtkb21FdmVudE5hbWVdKTtcbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJTaW1wbGVFdmVudHMoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc2ltcGxlRXZlbnRQbHVnaW5FdmVudHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZXZlbnROYW1lID0gc2ltcGxlRXZlbnRQbHVnaW5FdmVudHNbaV07XG4gICAgdmFyIGRvbUV2ZW50TmFtZSA9IGV2ZW50TmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhciBjYXBpdGFsaXplZEV2ZW50ID0gZXZlbnROYW1lWzBdLnRvVXBwZXJDYXNlKCkgKyBldmVudE5hbWUuc2xpY2UoMSk7XG4gICAgcmVnaXN0ZXJTaW1wbGVFdmVudChkb21FdmVudE5hbWUsICdvbicgKyBjYXBpdGFsaXplZEV2ZW50KTtcbiAgfSAvLyBTcGVjaWFsIGNhc2VzIHdoZXJlIGV2ZW50IG5hbWVzIGRvbid0IG1hdGNoLlxuXG5cbiAgcmVnaXN0ZXJTaW1wbGVFdmVudChBTklNQVRJT05fRU5ELCAnb25BbmltYXRpb25FbmQnKTtcbiAgcmVnaXN0ZXJTaW1wbGVFdmVudChBTklNQVRJT05fSVRFUkFUSU9OLCAnb25BbmltYXRpb25JdGVyYXRpb24nKTtcbiAgcmVnaXN0ZXJTaW1wbGVFdmVudChBTklNQVRJT05fU1RBUlQsICdvbkFuaW1hdGlvblN0YXJ0Jyk7XG4gIHJlZ2lzdGVyU2ltcGxlRXZlbnQoJ2RibGNsaWNrJywgJ29uRG91YmxlQ2xpY2snKTtcbiAgcmVnaXN0ZXJTaW1wbGVFdmVudCgnZm9jdXNpbicsICdvbkZvY3VzJyk7XG4gIHJlZ2lzdGVyU2ltcGxlRXZlbnQoJ2ZvY3Vzb3V0JywgJ29uQmx1cicpO1xuICByZWdpc3RlclNpbXBsZUV2ZW50KFRSQU5TSVRJT05fRU5ELCAnb25UcmFuc2l0aW9uRW5kJyk7XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RFdmVudHMkNChkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyKSB7XG4gIHZhciByZWFjdE5hbWUgPSB0b3BMZXZlbEV2ZW50c1RvUmVhY3ROYW1lcy5nZXQoZG9tRXZlbnROYW1lKTtcblxuICBpZiAocmVhY3ROYW1lID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljRXZlbnQ7XG4gIHZhciByZWFjdEV2ZW50VHlwZSA9IGRvbUV2ZW50TmFtZTtcblxuICBzd2l0Y2ggKGRvbUV2ZW50TmFtZSkge1xuICAgIGNhc2UgJ2tleXByZXNzJzpcbiAgICAgIC8vIEZpcmVmb3ggY3JlYXRlcyBhIGtleXByZXNzIGV2ZW50IGZvciBmdW5jdGlvbiBrZXlzIHRvby4gVGhpcyByZW1vdmVzXG4gICAgICAvLyB0aGUgdW53YW50ZWQga2V5cHJlc3MgZXZlbnRzLiBFbnRlciBpcyBob3dldmVyIGJvdGggcHJpbnRhYmxlIGFuZFxuICAgICAgLy8gbm9uLXByaW50YWJsZS4gT25lIHdvdWxkIGV4cGVjdCBUYWIgdG8gYmUgYXMgd2VsbCAoYnV0IGl0IGlzbid0KS5cbiAgICAgIGlmIChnZXRFdmVudENoYXJDb2RlKG5hdGl2ZUV2ZW50KSA9PT0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAvKiBmYWxscyB0aHJvdWdoICovXG5cbiAgICBjYXNlICdrZXlkb3duJzpcbiAgICBjYXNlICdrZXl1cCc6XG4gICAgICBTeW50aGV0aWNFdmVudEN0b3IgPSBTeW50aGV0aWNLZXlib2FyZEV2ZW50O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdmb2N1c2luJzpcbiAgICAgIHJlYWN0RXZlbnRUeXBlID0gJ2ZvY3VzJztcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY0ZvY3VzRXZlbnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2ZvY3Vzb3V0JzpcbiAgICAgIHJlYWN0RXZlbnRUeXBlID0gJ2JsdXInO1xuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljRm9jdXNFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnYmVmb3JlYmx1cic6XG4gICAgY2FzZSAnYWZ0ZXJibHVyJzpcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY0ZvY3VzRXZlbnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2NsaWNrJzpcbiAgICAgIC8vIEZpcmVmb3ggY3JlYXRlcyBhIGNsaWNrIGV2ZW50IG9uIHJpZ2h0IG1vdXNlIGNsaWNrcy4gVGhpcyByZW1vdmVzIHRoZVxuICAgICAgLy8gdW53YW50ZWQgY2xpY2sgZXZlbnRzLlxuICAgICAgaWYgKG5hdGl2ZUV2ZW50LmJ1dHRvbiA9PT0gMikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAvKiBmYWxscyB0aHJvdWdoICovXG5cbiAgICBjYXNlICdhdXhjbGljayc6XG4gICAgY2FzZSAnZGJsY2xpY2snOlxuICAgIGNhc2UgJ21vdXNlZG93bic6XG4gICAgY2FzZSAnbW91c2Vtb3ZlJzpcbiAgICBjYXNlICdtb3VzZXVwJzogLy8gVE9ETzogRGlzYWJsZWQgZWxlbWVudHMgc2hvdWxkIG5vdCByZXNwb25kIHRvIG1vdXNlIGV2ZW50c1xuXG4gICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuXG4gICAgY2FzZSAnbW91c2VvdXQnOlxuICAgIGNhc2UgJ21vdXNlb3Zlcic6XG4gICAgY2FzZSAnY29udGV4dG1lbnUnOlxuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljTW91c2VFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnZHJhZyc6XG4gICAgY2FzZSAnZHJhZ2VuZCc6XG4gICAgY2FzZSAnZHJhZ2VudGVyJzpcbiAgICBjYXNlICdkcmFnZXhpdCc6XG4gICAgY2FzZSAnZHJhZ2xlYXZlJzpcbiAgICBjYXNlICdkcmFnb3Zlcic6XG4gICAgY2FzZSAnZHJhZ3N0YXJ0JzpcbiAgICBjYXNlICdkcm9wJzpcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY0RyYWdFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAndG91Y2hjYW5jZWwnOlxuICAgIGNhc2UgJ3RvdWNoZW5kJzpcbiAgICBjYXNlICd0b3VjaG1vdmUnOlxuICAgIGNhc2UgJ3RvdWNoc3RhcnQnOlxuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljVG91Y2hFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBBTklNQVRJT05fRU5EOlxuICAgIGNhc2UgQU5JTUFUSU9OX0lURVJBVElPTjpcbiAgICBjYXNlIEFOSU1BVElPTl9TVEFSVDpcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY0FuaW1hdGlvbkV2ZW50O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFRSQU5TSVRJT05fRU5EOlxuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljVHJhbnNpdGlvbkV2ZW50O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdzY3JvbGwnOlxuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljVUlFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnd2hlZWwnOlxuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljV2hlZWxFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnY29weSc6XG4gICAgY2FzZSAnY3V0JzpcbiAgICBjYXNlICdwYXN0ZSc6XG4gICAgICBTeW50aGV0aWNFdmVudEN0b3IgPSBTeW50aGV0aWNDbGlwYm9hcmRFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnZ290cG9pbnRlcmNhcHR1cmUnOlxuICAgIGNhc2UgJ2xvc3Rwb2ludGVyY2FwdHVyZSc6XG4gICAgY2FzZSAncG9pbnRlcmNhbmNlbCc6XG4gICAgY2FzZSAncG9pbnRlcmRvd24nOlxuICAgIGNhc2UgJ3BvaW50ZXJtb3ZlJzpcbiAgICBjYXNlICdwb2ludGVyb3V0JzpcbiAgICBjYXNlICdwb2ludGVyb3Zlcic6XG4gICAgY2FzZSAncG9pbnRlcnVwJzpcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY1BvaW50ZXJFdmVudDtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgdmFyIGluQ2FwdHVyZVBoYXNlID0gKGV2ZW50U3lzdGVtRmxhZ3MgJiBJU19DQVBUVVJFX1BIQVNFKSAhPT0gMDtcblxuICB7XG4gICAgLy8gU29tZSBldmVudHMgZG9uJ3QgYnViYmxlIGluIHRoZSBicm93c2VyLlxuICAgIC8vIEluIHRoZSBwYXN0LCBSZWFjdCBoYXMgYWx3YXlzIGJ1YmJsZWQgdGhlbSwgYnV0IHRoaXMgY2FuIGJlIHN1cnByaXNpbmcuXG4gICAgLy8gV2UncmUgZ29pbmcgdG8gdHJ5IGFsaWduaW5nIGNsb3NlciB0byB0aGUgYnJvd3NlciBiZWhhdmlvciBieSBub3QgYnViYmxpbmdcbiAgICAvLyB0aGVtIGluIFJlYWN0IGVpdGhlci4gV2UnbGwgc3RhcnQgYnkgbm90IGJ1YmJsaW5nIG9uU2Nyb2xsLCBhbmQgdGhlbiBleHBhbmQuXG4gICAgdmFyIGFjY3VtdWxhdGVUYXJnZXRPbmx5ID0gIWluQ2FwdHVyZVBoYXNlICYmIC8vIFRPRE86IGlkZWFsbHksIHdlJ2QgZXZlbnR1YWxseSBhZGQgYWxsIGV2ZW50cyBmcm9tXG4gICAgLy8gbm9uRGVsZWdhdGVkRXZlbnRzIGxpc3QgaW4gRE9NUGx1Z2luRXZlbnRTeXN0ZW0uXG4gICAgLy8gVGhlbiB3ZSBjYW4gcmVtb3ZlIHRoaXMgc3BlY2lhbCBsaXN0LlxuICAgIC8vIFRoaXMgaXMgYSBicmVha2luZyBjaGFuZ2UgdGhhdCBjYW4gd2FpdCB1bnRpbCBSZWFjdCAxOC5cbiAgICBkb21FdmVudE5hbWUgPT09ICdzY3JvbGwnO1xuXG4gICAgdmFyIF9saXN0ZW5lcnMgPSBhY2N1bXVsYXRlU2luZ2xlUGhhc2VMaXN0ZW5lcnModGFyZ2V0SW5zdCwgcmVhY3ROYW1lLCBuYXRpdmVFdmVudC50eXBlLCBpbkNhcHR1cmVQaGFzZSwgYWNjdW11bGF0ZVRhcmdldE9ubHkpO1xuXG4gICAgaWYgKF9saXN0ZW5lcnMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gSW50ZW50aW9uYWxseSBjcmVhdGUgZXZlbnQgbGF6aWx5LlxuICAgICAgdmFyIF9ldmVudCA9IG5ldyBTeW50aGV0aWNFdmVudEN0b3IocmVhY3ROYW1lLCByZWFjdEV2ZW50VHlwZSwgbnVsbCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcblxuICAgICAgZGlzcGF0Y2hRdWV1ZS5wdXNoKHtcbiAgICAgICAgZXZlbnQ6IF9ldmVudCxcbiAgICAgICAgbGlzdGVuZXJzOiBfbGlzdGVuZXJzXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuLy8gVE9ETzogcmVtb3ZlIHRvcC1sZXZlbCBzaWRlIGVmZmVjdC5cbnJlZ2lzdGVyU2ltcGxlRXZlbnRzKCk7XG5yZWdpc3RlckV2ZW50cyQyKCk7XG5yZWdpc3RlckV2ZW50cyQxKCk7XG5yZWdpc3RlckV2ZW50cyQzKCk7XG5yZWdpc3RlckV2ZW50cygpO1xuXG5mdW5jdGlvbiBleHRyYWN0RXZlbnRzJDUoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lcikge1xuICAvLyBUT0RPOiB3ZSBzaG91bGQgcmVtb3ZlIHRoZSBjb25jZXB0IG9mIGEgXCJTaW1wbGVFdmVudFBsdWdpblwiLlxuICAvLyBUaGlzIGlzIHRoZSBiYXNpYyBmdW5jdGlvbmFsaXR5IG9mIHRoZSBldmVudCBzeXN0ZW0uIEFsbFxuICAvLyB0aGUgb3RoZXIgcGx1Z2lucyBhcmUgZXNzZW50aWFsbHkgcG9seWZpbGxzLiBTbyB0aGUgcGx1Z2luXG4gIC8vIHNob3VsZCBwcm9iYWJseSBiZSBpbmxpbmVkIHNvbWV3aGVyZSBhbmQgaGF2ZSBpdHMgbG9naWNcbiAgLy8gYmUgY29yZSB0aGUgdG8gZXZlbnQgc3lzdGVtLiBUaGlzIHdvdWxkIHBvdGVudGlhbGx5IGFsbG93XG4gIC8vIHVzIHRvIHNoaXAgYnVpbGRzIG9mIFJlYWN0IHdpdGhvdXQgdGhlIHBvbHlmaWxsZWQgcGx1Z2lucyBiZWxvdy5cbiAgZXh0cmFjdEV2ZW50cyQ0KGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0LCBldmVudFN5c3RlbUZsYWdzKTtcbiAgdmFyIHNob3VsZFByb2Nlc3NQb2x5ZmlsbFBsdWdpbnMgPSAoZXZlbnRTeXN0ZW1GbGFncyAmIFNIT1VMRF9OT1RfUFJPQ0VTU19QT0xZRklMTF9FVkVOVF9QTFVHSU5TKSA9PT0gMDsgLy8gV2UgZG9uJ3QgcHJvY2VzcyB0aGVzZSBldmVudHMgdW5sZXNzIHdlIGFyZSBpbiB0aGVcbiAgLy8gZXZlbnQncyBuYXRpdmUgXCJidWJibGVcIiBwaGFzZSwgd2hpY2ggbWVhbnMgdGhhdCB3ZSdyZVxuICAvLyBub3QgaW4gdGhlIGNhcHR1cmUgcGhhc2UuIFRoYXQncyBiZWNhdXNlIHdlIGVtdWxhdGVcbiAgLy8gdGhlIGNhcHR1cmUgcGhhc2UgaGVyZSBzdGlsbC4gVGhpcyBpcyBhIHRyYWRlLW9mZixcbiAgLy8gYmVjYXVzZSBpbiBhbiBpZGVhbCB3b3JsZCB3ZSB3b3VsZCBub3QgZW11bGF0ZSBhbmQgdXNlXG4gIC8vIHRoZSBwaGFzZXMgcHJvcGVybHksIGxpa2Ugd2UgZG8gd2l0aCB0aGUgU2ltcGxlRXZlbnRcbiAgLy8gcGx1Z2luLiBIb3dldmVyLCB0aGUgcGx1Z2lucyBiZWxvdyBlaXRoZXIgZXhwZWN0XG4gIC8vIGVtdWxhdGlvbiAoRW50ZXJMZWF2ZSkgb3IgdXNlIHN0YXRlIGxvY2FsaXplZCB0byB0aGF0XG4gIC8vIHBsdWdpbiAoQmVmb3JlSW5wdXQsIENoYW5nZSwgU2VsZWN0KS4gVGhlIHN0YXRlIGluXG4gIC8vIHRoZXNlIG1vZHVsZXMgY29tcGxpY2F0ZXMgdGhpbmdzLCBhcyB5b3UnbGwgZXNzZW50aWFsbHlcbiAgLy8gZ2V0IHRoZSBjYXNlIHdoZXJlIHRoZSBjYXB0dXJlIHBoYXNlIGV2ZW50IG1pZ2h0IGNoYW5nZVxuICAvLyBzdGF0ZSwgb25seSBmb3IgdGhlIGZvbGxvd2luZyBidWJibGUgZXZlbnQgdG8gY29tZSBpblxuICAvLyBsYXRlciBhbmQgbm90IHRyaWdnZXIgYW55dGhpbmcgYXMgdGhlIHN0YXRlIG5vd1xuICAvLyBpbnZhbGlkYXRlcyB0aGUgaGV1cmlzdGljcyBvZiB0aGUgZXZlbnQgcGx1Z2luLiBXZVxuICAvLyBjb3VsZCBhbHRlciBhbGwgdGhlc2UgcGx1Z2lucyB0byB3b3JrIGluIHN1Y2ggd2F5cywgYnV0XG4gIC8vIHRoYXQgbWlnaHQgY2F1c2Ugb3RoZXIgdW5rbm93biBzaWRlLWVmZmVjdHMgdGhhdCB3ZVxuICAvLyBjYW4ndCBmb3Jlc2VlIHJpZ2h0IG5vdy5cblxuICBpZiAoc2hvdWxkUHJvY2Vzc1BvbHlmaWxsUGx1Z2lucykge1xuICAgIGV4dHJhY3RFdmVudHMkMihkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgZXh0cmFjdEV2ZW50cyQxKGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgICBleHRyYWN0RXZlbnRzJDMoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuICAgIGV4dHJhY3RFdmVudHMoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuICB9XG59IC8vIExpc3Qgb2YgZXZlbnRzIHRoYXQgbmVlZCB0byBiZSBpbmRpdmlkdWFsbHkgYXR0YWNoZWQgdG8gbWVkaWEgZWxlbWVudHMuXG5cblxudmFyIG1lZGlhRXZlbnRUeXBlcyA9IFsnYWJvcnQnLCAnY2FucGxheScsICdjYW5wbGF5dGhyb3VnaCcsICdkdXJhdGlvbmNoYW5nZScsICdlbXB0aWVkJywgJ2VuY3J5cHRlZCcsICdlbmRlZCcsICdlcnJvcicsICdsb2FkZWRkYXRhJywgJ2xvYWRlZG1ldGFkYXRhJywgJ2xvYWRzdGFydCcsICdwYXVzZScsICdwbGF5JywgJ3BsYXlpbmcnLCAncHJvZ3Jlc3MnLCAncmF0ZWNoYW5nZScsICdyZXNpemUnLCAnc2Vla2VkJywgJ3NlZWtpbmcnLCAnc3RhbGxlZCcsICdzdXNwZW5kJywgJ3RpbWV1cGRhdGUnLCAndm9sdW1lY2hhbmdlJywgJ3dhaXRpbmcnXTsgLy8gV2Ugc2hvdWxkIG5vdCBkZWxlZ2F0ZSB0aGVzZSBldmVudHMgdG8gdGhlIGNvbnRhaW5lciwgYnV0IHJhdGhlclxuLy8gc2V0IHRoZW0gb24gdGhlIGFjdHVhbCB0YXJnZXQgZWxlbWVudCBpdHNlbGYuIFRoaXMgaXMgcHJpbWFyaWx5XG4vLyBiZWNhdXNlIHRoZXNlIGV2ZW50cyBkbyBub3QgY29uc2lzdGVudGx5IGJ1YmJsZSBpbiB0aGUgRE9NLlxuXG52YXIgbm9uRGVsZWdhdGVkRXZlbnRzID0gbmV3IFNldChbJ2NhbmNlbCcsICdjbG9zZScsICdpbnZhbGlkJywgJ2xvYWQnLCAnc2Nyb2xsJywgJ3RvZ2dsZSddLmNvbmNhdChtZWRpYUV2ZW50VHlwZXMpKTtcblxuZnVuY3Rpb24gZXhlY3V0ZURpc3BhdGNoKGV2ZW50LCBsaXN0ZW5lciwgY3VycmVudFRhcmdldCkge1xuICB2YXIgdHlwZSA9IGV2ZW50LnR5cGUgfHwgJ3Vua25vd24tZXZlbnQnO1xuICBldmVudC5jdXJyZW50VGFyZ2V0ID0gY3VycmVudFRhcmdldDtcbiAgaW52b2tlR3VhcmRlZENhbGxiYWNrQW5kQ2F0Y2hGaXJzdEVycm9yKHR5cGUsIGxpc3RlbmVyLCB1bmRlZmluZWQsIGV2ZW50KTtcbiAgZXZlbnQuY3VycmVudFRhcmdldCA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NEaXNwYXRjaFF1ZXVlSXRlbXNJbk9yZGVyKGV2ZW50LCBkaXNwYXRjaExpc3RlbmVycywgaW5DYXB0dXJlUGhhc2UpIHtcbiAgdmFyIHByZXZpb3VzSW5zdGFuY2U7XG5cbiAgaWYgKGluQ2FwdHVyZVBoYXNlKSB7XG4gICAgZm9yICh2YXIgaSA9IGRpc3BhdGNoTGlzdGVuZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgX2Rpc3BhdGNoTGlzdGVuZXJzJGkgPSBkaXNwYXRjaExpc3RlbmVyc1tpXSxcbiAgICAgICAgICBpbnN0YW5jZSA9IF9kaXNwYXRjaExpc3RlbmVycyRpLmluc3RhbmNlLFxuICAgICAgICAgIGN1cnJlbnRUYXJnZXQgPSBfZGlzcGF0Y2hMaXN0ZW5lcnMkaS5jdXJyZW50VGFyZ2V0LFxuICAgICAgICAgIGxpc3RlbmVyID0gX2Rpc3BhdGNoTGlzdGVuZXJzJGkubGlzdGVuZXI7XG5cbiAgICAgIGlmIChpbnN0YW5jZSAhPT0gcHJldmlvdXNJbnN0YW5jZSAmJiBldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgZXhlY3V0ZURpc3BhdGNoKGV2ZW50LCBsaXN0ZW5lciwgY3VycmVudFRhcmdldCk7XG4gICAgICBwcmV2aW91c0luc3RhbmNlID0gaW5zdGFuY2U7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBkaXNwYXRjaExpc3RlbmVycy5sZW5ndGg7IF9pKyspIHtcbiAgICAgIHZhciBfZGlzcGF0Y2hMaXN0ZW5lcnMkX2kgPSBkaXNwYXRjaExpc3RlbmVyc1tfaV0sXG4gICAgICAgICAgX2luc3RhbmNlID0gX2Rpc3BhdGNoTGlzdGVuZXJzJF9pLmluc3RhbmNlLFxuICAgICAgICAgIF9jdXJyZW50VGFyZ2V0ID0gX2Rpc3BhdGNoTGlzdGVuZXJzJF9pLmN1cnJlbnRUYXJnZXQsXG4gICAgICAgICAgX2xpc3RlbmVyID0gX2Rpc3BhdGNoTGlzdGVuZXJzJF9pLmxpc3RlbmVyO1xuXG4gICAgICBpZiAoX2luc3RhbmNlICE9PSBwcmV2aW91c0luc3RhbmNlICYmIGV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBleGVjdXRlRGlzcGF0Y2goZXZlbnQsIF9saXN0ZW5lciwgX2N1cnJlbnRUYXJnZXQpO1xuICAgICAgcHJldmlvdXNJbnN0YW5jZSA9IF9pbnN0YW5jZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJvY2Vzc0Rpc3BhdGNoUXVldWUoZGlzcGF0Y2hRdWV1ZSwgZXZlbnRTeXN0ZW1GbGFncykge1xuICB2YXIgaW5DYXB0dXJlUGhhc2UgPSAoZXZlbnRTeXN0ZW1GbGFncyAmIElTX0NBUFRVUkVfUEhBU0UpICE9PSAwO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZGlzcGF0Y2hRdWV1ZS5sZW5ndGg7IGkrKykge1xuICAgIHZhciBfZGlzcGF0Y2hRdWV1ZSRpID0gZGlzcGF0Y2hRdWV1ZVtpXSxcbiAgICAgICAgZXZlbnQgPSBfZGlzcGF0Y2hRdWV1ZSRpLmV2ZW50LFxuICAgICAgICBsaXN0ZW5lcnMgPSBfZGlzcGF0Y2hRdWV1ZSRpLmxpc3RlbmVycztcbiAgICBwcm9jZXNzRGlzcGF0Y2hRdWV1ZUl0ZW1zSW5PcmRlcihldmVudCwgbGlzdGVuZXJzLCBpbkNhcHR1cmVQaGFzZSk7IC8vICBldmVudCBzeXN0ZW0gZG9lc24ndCB1c2UgcG9vbGluZy5cbiAgfSAvLyBUaGlzIHdvdWxkIGJlIGEgZ29vZCB0aW1lIHRvIHJldGhyb3cgaWYgYW55IG9mIHRoZSBldmVudCBoYW5kbGVycyB0aHJldy5cblxuXG4gIHJldGhyb3dDYXVnaHRFcnJvcigpO1xufVxuXG5mdW5jdGlvbiBkaXNwYXRjaEV2ZW50c0ZvclBsdWdpbnMoZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCBuYXRpdmVFdmVudCwgdGFyZ2V0SW5zdCwgdGFyZ2V0Q29udGFpbmVyKSB7XG4gIHZhciBuYXRpdmVFdmVudFRhcmdldCA9IGdldEV2ZW50VGFyZ2V0KG5hdGl2ZUV2ZW50KTtcbiAgdmFyIGRpc3BhdGNoUXVldWUgPSBbXTtcbiAgZXh0cmFjdEV2ZW50cyQ1KGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0LCBldmVudFN5c3RlbUZsYWdzKTtcbiAgcHJvY2Vzc0Rpc3BhdGNoUXVldWUoZGlzcGF0Y2hRdWV1ZSwgZXZlbnRTeXN0ZW1GbGFncyk7XG59XG5cbmZ1bmN0aW9uIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoZG9tRXZlbnROYW1lLCB0YXJnZXRFbGVtZW50KSB7XG4gIHtcbiAgICBpZiAoIW5vbkRlbGVnYXRlZEV2ZW50cy5oYXMoZG9tRXZlbnROYW1lKSkge1xuICAgICAgZXJyb3IoJ0RpZCBub3QgZXhwZWN0IGEgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgpIGNhbGwgZm9yIFwiJXNcIi4gJyArICdUaGlzIGlzIGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBkb21FdmVudE5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBpc0NhcHR1cmVQaGFzZUxpc3RlbmVyID0gZmFsc2U7XG4gIHZhciBsaXN0ZW5lclNldCA9IGdldEV2ZW50TGlzdGVuZXJTZXQodGFyZ2V0RWxlbWVudCk7XG4gIHZhciBsaXN0ZW5lclNldEtleSA9IGdldExpc3RlbmVyU2V0S2V5KGRvbUV2ZW50TmFtZSwgaXNDYXB0dXJlUGhhc2VMaXN0ZW5lcik7XG5cbiAgaWYgKCFsaXN0ZW5lclNldC5oYXMobGlzdGVuZXJTZXRLZXkpKSB7XG4gICAgYWRkVHJhcHBlZEV2ZW50TGlzdGVuZXIodGFyZ2V0RWxlbWVudCwgZG9tRXZlbnROYW1lLCBJU19OT05fREVMRUdBVEVELCBpc0NhcHR1cmVQaGFzZUxpc3RlbmVyKTtcbiAgICBsaXN0ZW5lclNldC5hZGQobGlzdGVuZXJTZXRLZXkpO1xuICB9XG59XG5mdW5jdGlvbiBsaXN0ZW5Ub05hdGl2ZUV2ZW50KGRvbUV2ZW50TmFtZSwgaXNDYXB0dXJlUGhhc2VMaXN0ZW5lciwgdGFyZ2V0KSB7XG4gIHtcbiAgICBpZiAobm9uRGVsZWdhdGVkRXZlbnRzLmhhcyhkb21FdmVudE5hbWUpICYmICFpc0NhcHR1cmVQaGFzZUxpc3RlbmVyKSB7XG4gICAgICBlcnJvcignRGlkIG5vdCBleHBlY3QgYSBsaXN0ZW5Ub05hdGl2ZUV2ZW50KCkgY2FsbCBmb3IgXCIlc1wiIGluIHRoZSBidWJibGUgcGhhc2UuICcgKyAnVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJywgZG9tRXZlbnROYW1lKTtcbiAgICB9XG4gIH1cblxuICB2YXIgZXZlbnRTeXN0ZW1GbGFncyA9IDA7XG5cbiAgaWYgKGlzQ2FwdHVyZVBoYXNlTGlzdGVuZXIpIHtcbiAgICBldmVudFN5c3RlbUZsYWdzIHw9IElTX0NBUFRVUkVfUEhBU0U7XG4gIH1cblxuICBhZGRUcmFwcGVkRXZlbnRMaXN0ZW5lcih0YXJnZXQsIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgaXNDYXB0dXJlUGhhc2VMaXN0ZW5lcik7XG59IC8vIFRoaXMgaXMgb25seSB1c2VkIGJ5IGNyZWF0ZUV2ZW50SGFuZGxlIHdoZW4gdGhlXG52YXIgbGlzdGVuaW5nTWFya2VyID0gJ19yZWFjdExpc3RlbmluZycgKyBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyKTtcbmZ1bmN0aW9uIGxpc3RlblRvQWxsU3VwcG9ydGVkRXZlbnRzKHJvb3RDb250YWluZXJFbGVtZW50KSB7XG4gIGlmICghcm9vdENvbnRhaW5lckVsZW1lbnRbbGlzdGVuaW5nTWFya2VyXSkge1xuICAgIHJvb3RDb250YWluZXJFbGVtZW50W2xpc3RlbmluZ01hcmtlcl0gPSB0cnVlO1xuICAgIGFsbE5hdGl2ZUV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChkb21FdmVudE5hbWUpIHtcbiAgICAgIC8vIFdlIGhhbmRsZSBzZWxlY3Rpb25jaGFuZ2Ugc2VwYXJhdGVseSBiZWNhdXNlIGl0XG4gICAgICAvLyBkb2Vzbid0IGJ1YmJsZSBhbmQgbmVlZHMgdG8gYmUgb24gdGhlIGRvY3VtZW50LlxuICAgICAgaWYgKGRvbUV2ZW50TmFtZSAhPT0gJ3NlbGVjdGlvbmNoYW5nZScpIHtcbiAgICAgICAgaWYgKCFub25EZWxlZ2F0ZWRFdmVudHMuaGFzKGRvbUV2ZW50TmFtZSkpIHtcbiAgICAgICAgICBsaXN0ZW5Ub05hdGl2ZUV2ZW50KGRvbUV2ZW50TmFtZSwgZmFsc2UsIHJvb3RDb250YWluZXJFbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxpc3RlblRvTmF0aXZlRXZlbnQoZG9tRXZlbnROYW1lLCB0cnVlLCByb290Q29udGFpbmVyRWxlbWVudCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdmFyIG93bmVyRG9jdW1lbnQgPSByb290Q29udGFpbmVyRWxlbWVudC5ub2RlVHlwZSA9PT0gRE9DVU1FTlRfTk9ERSA/IHJvb3RDb250YWluZXJFbGVtZW50IDogcm9vdENvbnRhaW5lckVsZW1lbnQub3duZXJEb2N1bWVudDtcblxuICAgIGlmIChvd25lckRvY3VtZW50ICE9PSBudWxsKSB7XG4gICAgICAvLyBUaGUgc2VsZWN0aW9uY2hhbmdlIGV2ZW50IGFsc28gbmVlZHMgZGVkdXBsaWNhdGlvblxuICAgICAgLy8gYnV0IGl0IGlzIGF0dGFjaGVkIHRvIHRoZSBkb2N1bWVudC5cbiAgICAgIGlmICghb3duZXJEb2N1bWVudFtsaXN0ZW5pbmdNYXJrZXJdKSB7XG4gICAgICAgIG93bmVyRG9jdW1lbnRbbGlzdGVuaW5nTWFya2VyXSA9IHRydWU7XG4gICAgICAgIGxpc3RlblRvTmF0aXZlRXZlbnQoJ3NlbGVjdGlvbmNoYW5nZScsIGZhbHNlLCBvd25lckRvY3VtZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWRkVHJhcHBlZEV2ZW50TGlzdGVuZXIodGFyZ2V0Q29udGFpbmVyLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIGlzQ2FwdHVyZVBoYXNlTGlzdGVuZXIsIGlzRGVmZXJyZWRMaXN0ZW5lckZvckxlZ2FjeUZCU3VwcG9ydCkge1xuICB2YXIgbGlzdGVuZXIgPSBjcmVhdGVFdmVudExpc3RlbmVyV3JhcHBlcldpdGhQcmlvcml0eSh0YXJnZXRDb250YWluZXIsIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncyk7IC8vIElmIHBhc3NpdmUgb3B0aW9uIGlzIG5vdCBzdXBwb3J0ZWQsIHRoZW4gdGhlIGV2ZW50IHdpbGwgYmVcbiAgLy8gYWN0aXZlIGFuZCBub3QgcGFzc2l2ZS5cblxuICB2YXIgaXNQYXNzaXZlTGlzdGVuZXIgPSB1bmRlZmluZWQ7XG5cbiAgaWYgKHBhc3NpdmVCcm93c2VyRXZlbnRzU3VwcG9ydGVkKSB7XG4gICAgLy8gQnJvd3NlcnMgaW50cm9kdWNlZCBhbiBpbnRlcnZlbnRpb24sIG1ha2luZyB0aGVzZSBldmVudHNcbiAgICAvLyBwYXNzaXZlIGJ5IGRlZmF1bHQgb24gZG9jdW1lbnQuIFJlYWN0IGRvZXNuJ3QgYmluZCB0aGVtXG4gICAgLy8gdG8gZG9jdW1lbnQgYW55bW9yZSwgYnV0IGNoYW5naW5nIHRoaXMgbm93IHdvdWxkIHVuZG9cbiAgICAvLyB0aGUgcGVyZm9ybWFuY2Ugd2lucyBmcm9tIHRoZSBjaGFuZ2UuIFNvIHdlIGVtdWxhdGVcbiAgICAvLyB0aGUgZXhpc3RpbmcgYmVoYXZpb3IgbWFudWFsbHkgb24gdGhlIHJvb3RzIG5vdy5cbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzE5NjUxXG4gICAgaWYgKGRvbUV2ZW50TmFtZSA9PT0gJ3RvdWNoc3RhcnQnIHx8IGRvbUV2ZW50TmFtZSA9PT0gJ3RvdWNobW92ZScgfHwgZG9tRXZlbnROYW1lID09PSAnd2hlZWwnKSB7XG4gICAgICBpc1Bhc3NpdmVMaXN0ZW5lciA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgdGFyZ2V0Q29udGFpbmVyID0gIHRhcmdldENvbnRhaW5lcjtcbiAgdmFyIHVuc3Vic2NyaWJlTGlzdGVuZXI7IC8vIFdoZW4gbGVnYWN5RkJTdXBwb3J0IGlzIGVuYWJsZWQsIGl0J3MgZm9yIHdoZW4gd2VcblxuXG4gIGlmIChpc0NhcHR1cmVQaGFzZUxpc3RlbmVyKSB7XG4gICAgaWYgKGlzUGFzc2l2ZUxpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHVuc3Vic2NyaWJlTGlzdGVuZXIgPSBhZGRFdmVudENhcHR1cmVMaXN0ZW5lcldpdGhQYXNzaXZlRmxhZyh0YXJnZXRDb250YWluZXIsIGRvbUV2ZW50TmFtZSwgbGlzdGVuZXIsIGlzUGFzc2l2ZUxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdW5zdWJzY3JpYmVMaXN0ZW5lciA9IGFkZEV2ZW50Q2FwdHVyZUxpc3RlbmVyKHRhcmdldENvbnRhaW5lciwgZG9tRXZlbnROYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChpc1Bhc3NpdmVMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB1bnN1YnNjcmliZUxpc3RlbmVyID0gYWRkRXZlbnRCdWJibGVMaXN0ZW5lcldpdGhQYXNzaXZlRmxhZyh0YXJnZXRDb250YWluZXIsIGRvbUV2ZW50TmFtZSwgbGlzdGVuZXIsIGlzUGFzc2l2ZUxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdW5zdWJzY3JpYmVMaXN0ZW5lciA9IGFkZEV2ZW50QnViYmxlTGlzdGVuZXIodGFyZ2V0Q29udGFpbmVyLCBkb21FdmVudE5hbWUsIGxpc3RlbmVyKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNNYXRjaGluZ1Jvb3RDb250YWluZXIoZ3JhbmRDb250YWluZXIsIHRhcmdldENvbnRhaW5lcikge1xuICByZXR1cm4gZ3JhbmRDb250YWluZXIgPT09IHRhcmdldENvbnRhaW5lciB8fCBncmFuZENvbnRhaW5lci5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFICYmIGdyYW5kQ29udGFpbmVyLnBhcmVudE5vZGUgPT09IHRhcmdldENvbnRhaW5lcjtcbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hFdmVudEZvclBsdWdpbkV2ZW50U3lzdGVtKGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgbmF0aXZlRXZlbnQsIHRhcmdldEluc3QsIHRhcmdldENvbnRhaW5lcikge1xuICB2YXIgYW5jZXN0b3JJbnN0ID0gdGFyZ2V0SW5zdDtcblxuICBpZiAoKGV2ZW50U3lzdGVtRmxhZ3MgJiBJU19FVkVOVF9IQU5ETEVfTk9OX01BTkFHRURfTk9ERSkgPT09IDAgJiYgKGV2ZW50U3lzdGVtRmxhZ3MgJiBJU19OT05fREVMRUdBVEVEKSA9PT0gMCkge1xuICAgIHZhciB0YXJnZXRDb250YWluZXJOb2RlID0gdGFyZ2V0Q29udGFpbmVyOyAvLyBJZiB3ZSBhcmUgdXNpbmcgdGhlIGxlZ2FjeSBGQiBzdXBwb3J0IGZsYWcsIHdlXG5cbiAgICBpZiAodGFyZ2V0SW5zdCAhPT0gbnVsbCkge1xuICAgICAgLy8gVGhlIGJlbG93IGxvZ2ljIGF0dGVtcHRzIHRvIHdvcmsgb3V0IGlmIHdlIG5lZWQgdG8gY2hhbmdlXG4gICAgICAvLyB0aGUgdGFyZ2V0IGZpYmVyIHRvIGEgZGlmZmVyZW50IGFuY2VzdG9yLiBXZSBoYWQgc2ltaWxhciBsb2dpY1xuICAgICAgLy8gaW4gdGhlIGxlZ2FjeSBldmVudCBzeXN0ZW0sIGV4Y2VwdCB0aGUgYmlnIGRpZmZlcmVuY2UgYmV0d2VlblxuICAgICAgLy8gc3lzdGVtcyBpcyB0aGF0IHRoZSBtb2Rlcm4gZXZlbnQgc3lzdGVtIG5vdyBoYXMgYW4gZXZlbnQgbGlzdGVuZXJcbiAgICAgIC8vIGF0dGFjaGVkIHRvIGVhY2ggUmVhY3QgUm9vdCBhbmQgUmVhY3QgUG9ydGFsIFJvb3QuIFRvZ2V0aGVyLFxuICAgICAgLy8gdGhlIERPTSBub2RlcyByZXByZXNlbnRpbmcgdGhlc2Ugcm9vdHMgYXJlIHRoZSBcInJvb3RDb250YWluZXJcIi5cbiAgICAgIC8vIFRvIGZpZ3VyZSBvdXQgd2hpY2ggYW5jZXN0b3IgaW5zdGFuY2Ugd2Ugc2hvdWxkIHVzZSwgd2UgdHJhdmVyc2VcbiAgICAgIC8vIHVwIHRoZSBmaWJlciB0cmVlIGZyb20gdGhlIHRhcmdldCBpbnN0YW5jZSBhbmQgYXR0ZW1wdCB0byBmaW5kXG4gICAgICAvLyByb290IGJvdW5kYXJpZXMgdGhhdCBtYXRjaCB0aGF0IG9mIG91ciBjdXJyZW50IFwicm9vdENvbnRhaW5lclwiLlxuICAgICAgLy8gSWYgd2UgZmluZCB0aGF0IFwicm9vdENvbnRhaW5lclwiLCB3ZSBmaW5kIHRoZSBwYXJlbnQgZmliZXJcbiAgICAgIC8vIHN1Yi10cmVlIGZvciB0aGF0IHJvb3QgYW5kIG1ha2UgdGhhdCBvdXIgYW5jZXN0b3IgaW5zdGFuY2UuXG4gICAgICB2YXIgbm9kZSA9IHRhcmdldEluc3Q7XG5cbiAgICAgIG1haW5Mb29wOiB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBpZiAobm9kZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBub2RlVGFnID0gbm9kZS50YWc7XG5cbiAgICAgICAgaWYgKG5vZGVUYWcgPT09IEhvc3RSb290IHx8IG5vZGVUYWcgPT09IEhvc3RQb3J0YWwpIHtcbiAgICAgICAgICB2YXIgY29udGFpbmVyID0gbm9kZS5zdGF0ZU5vZGUuY29udGFpbmVySW5mbztcblxuICAgICAgICAgIGlmIChpc01hdGNoaW5nUm9vdENvbnRhaW5lcihjb250YWluZXIsIHRhcmdldENvbnRhaW5lck5vZGUpKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobm9kZVRhZyA9PT0gSG9zdFBvcnRhbCkge1xuICAgICAgICAgICAgLy8gVGhlIHRhcmdldCBpcyBhIHBvcnRhbCwgYnV0IGl0J3Mgbm90IHRoZSByb290Q29udGFpbmVyIHdlJ3JlIGxvb2tpbmcgZm9yLlxuICAgICAgICAgICAgLy8gTm9ybWFsbHkgcG9ydGFscyBoYW5kbGUgdGhlaXIgb3duIGV2ZW50cyBhbGwgdGhlIHdheSBkb3duIHRvIHRoZSByb290LlxuICAgICAgICAgICAgLy8gU28gd2Ugc2hvdWxkIGJlIGFibGUgdG8gc3RvcCBub3cuIEhvd2V2ZXIsIHdlIGRvbid0IGtub3cgaWYgdGhpcyBwb3J0YWxcbiAgICAgICAgICAgIC8vIHdhcyBwYXJ0IG9mICpvdXIqIHJvb3QuXG4gICAgICAgICAgICB2YXIgZ3JhbmROb2RlID0gbm9kZS5yZXR1cm47XG5cbiAgICAgICAgICAgIHdoaWxlIChncmFuZE5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdmFyIGdyYW5kVGFnID0gZ3JhbmROb2RlLnRhZztcblxuICAgICAgICAgICAgICBpZiAoZ3JhbmRUYWcgPT09IEhvc3RSb290IHx8IGdyYW5kVGFnID09PSBIb3N0UG9ydGFsKSB7XG4gICAgICAgICAgICAgICAgdmFyIGdyYW5kQ29udGFpbmVyID0gZ3JhbmROb2RlLnN0YXRlTm9kZS5jb250YWluZXJJbmZvO1xuXG4gICAgICAgICAgICAgICAgaWYgKGlzTWF0Y2hpbmdSb290Q29udGFpbmVyKGdyYW5kQ29udGFpbmVyLCB0YXJnZXRDb250YWluZXJOb2RlKSkge1xuICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgcm9vdENvbnRhaW5lciB3ZSdyZSBsb29raW5nIGZvciBhbmQgd2UgZm91bmQgaXQgYXNcbiAgICAgICAgICAgICAgICAgIC8vIGEgcGFyZW50IG9mIHRoZSBQb3J0YWwuIFRoYXQgbWVhbnMgd2UgY2FuIGlnbm9yZSBpdCBiZWNhdXNlIHRoZVxuICAgICAgICAgICAgICAgICAgLy8gUG9ydGFsIHdpbGwgYnViYmxlIHRocm91Z2ggdG8gdXMuXG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgZ3JhbmROb2RlID0gZ3JhbmROb2RlLnJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IC8vIE5vdyB3ZSBuZWVkIHRvIGZpbmQgaXQncyBjb3JyZXNwb25kaW5nIGhvc3QgZmliZXIgaW4gdGhlIG90aGVyXG4gICAgICAgICAgLy8gdHJlZS4gVG8gZG8gdGhpcyB3ZSBjYW4gdXNlIGdldENsb3Nlc3RJbnN0YW5jZUZyb21Ob2RlLCBidXQgd2VcbiAgICAgICAgICAvLyBuZWVkIHRvIHZhbGlkYXRlIHRoYXQgdGhlIGZpYmVyIGlzIGEgaG9zdCBpbnN0YW5jZSwgb3RoZXJ3aXNlXG4gICAgICAgICAgLy8gd2UgbmVlZCB0byB0cmF2ZXJzZSB1cCB0aHJvdWdoIHRoZSBET00gdGlsbCB3ZSBmaW5kIHRoZSBjb3JyZWN0XG4gICAgICAgICAgLy8gbm9kZSB0aGF0IGlzIGZyb20gdGhlIG90aGVyIHRyZWUuXG5cblxuICAgICAgICAgIHdoaWxlIChjb250YWluZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBwYXJlbnROb2RlID0gZ2V0Q2xvc2VzdEluc3RhbmNlRnJvbU5vZGUoY29udGFpbmVyKTtcblxuICAgICAgICAgICAgaWYgKHBhcmVudE5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgcGFyZW50VGFnID0gcGFyZW50Tm9kZS50YWc7XG5cbiAgICAgICAgICAgIGlmIChwYXJlbnRUYWcgPT09IEhvc3RDb21wb25lbnQgfHwgcGFyZW50VGFnID09PSBIb3N0VGV4dCkge1xuICAgICAgICAgICAgICBub2RlID0gYW5jZXN0b3JJbnN0ID0gcGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgY29udGludWUgbWFpbkxvb3A7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnRhaW5lciA9IGNvbnRhaW5lci5wYXJlbnROb2RlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBiYXRjaGVkVXBkYXRlcyhmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGRpc3BhdGNoRXZlbnRzRm9yUGx1Z2lucyhkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIG5hdGl2ZUV2ZW50LCBhbmNlc3Rvckluc3QpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGlzcGF0Y2hMaXN0ZW5lcihpbnN0YW5jZSwgbGlzdGVuZXIsIGN1cnJlbnRUYXJnZXQpIHtcbiAgcmV0dXJuIHtcbiAgICBpbnN0YW5jZTogaW5zdGFuY2UsXG4gICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgIGN1cnJlbnRUYXJnZXQ6IGN1cnJlbnRUYXJnZXRcbiAgfTtcbn1cblxuZnVuY3Rpb24gYWNjdW11bGF0ZVNpbmdsZVBoYXNlTGlzdGVuZXJzKHRhcmdldEZpYmVyLCByZWFjdE5hbWUsIG5hdGl2ZUV2ZW50VHlwZSwgaW5DYXB0dXJlUGhhc2UsIGFjY3VtdWxhdGVUYXJnZXRPbmx5LCBuYXRpdmVFdmVudCkge1xuICB2YXIgY2FwdHVyZU5hbWUgPSByZWFjdE5hbWUgIT09IG51bGwgPyByZWFjdE5hbWUgKyAnQ2FwdHVyZScgOiBudWxsO1xuICB2YXIgcmVhY3RFdmVudE5hbWUgPSBpbkNhcHR1cmVQaGFzZSA/IGNhcHR1cmVOYW1lIDogcmVhY3ROYW1lO1xuICB2YXIgbGlzdGVuZXJzID0gW107XG4gIHZhciBpbnN0YW5jZSA9IHRhcmdldEZpYmVyO1xuICB2YXIgbGFzdEhvc3RDb21wb25lbnQgPSBudWxsOyAvLyBBY2N1bXVsYXRlIGFsbCBpbnN0YW5jZXMgYW5kIGxpc3RlbmVycyB2aWEgdGhlIHRhcmdldCAtPiByb290IHBhdGguXG5cbiAgd2hpbGUgKGluc3RhbmNlICE9PSBudWxsKSB7XG4gICAgdmFyIF9pbnN0YW5jZTIgPSBpbnN0YW5jZSxcbiAgICAgICAgc3RhdGVOb2RlID0gX2luc3RhbmNlMi5zdGF0ZU5vZGUsXG4gICAgICAgIHRhZyA9IF9pbnN0YW5jZTIudGFnOyAvLyBIYW5kbGUgbGlzdGVuZXJzIHRoYXQgYXJlIG9uIEhvc3RDb21wb25lbnRzIChpLmUuIDxkaXY+KVxuXG4gICAgaWYgKHRhZyA9PT0gSG9zdENvbXBvbmVudCAmJiBzdGF0ZU5vZGUgIT09IG51bGwpIHtcbiAgICAgIGxhc3RIb3N0Q29tcG9uZW50ID0gc3RhdGVOb2RlOyAvLyBjcmVhdGVFdmVudEhhbmRsZSBsaXN0ZW5lcnNcblxuXG4gICAgICBpZiAocmVhY3RFdmVudE5hbWUgIT09IG51bGwpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVyID0gZ2V0TGlzdGVuZXIoaW5zdGFuY2UsIHJlYWN0RXZlbnROYW1lKTtcblxuICAgICAgICBpZiAobGlzdGVuZXIgIT0gbnVsbCkge1xuICAgICAgICAgIGxpc3RlbmVycy5wdXNoKGNyZWF0ZURpc3BhdGNoTGlzdGVuZXIoaW5zdGFuY2UsIGxpc3RlbmVyLCBsYXN0SG9zdENvbXBvbmVudCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSAvLyBJZiB3ZSBhcmUgb25seSBhY2N1bXVsYXRpbmcgZXZlbnRzIGZvciB0aGUgdGFyZ2V0LCB0aGVuIHdlIGRvbid0XG4gICAgLy8gY29udGludWUgdG8gcHJvcGFnYXRlIHRocm91Z2ggdGhlIFJlYWN0IGZpYmVyIHRyZWUgdG8gZmluZCBvdGhlclxuICAgIC8vIGxpc3RlbmVycy5cblxuXG4gICAgaWYgKGFjY3VtdWxhdGVUYXJnZXRPbmx5KSB7XG4gICAgICBicmVhaztcbiAgICB9IC8vIElmIHdlIGFyZSBwcm9jZXNzaW5nIHRoZSBvbkJlZm9yZUJsdXIgZXZlbnQsIHRoZW4gd2UgbmVlZCB0byB0YWtlXG5cbiAgICBpbnN0YW5jZSA9IGluc3RhbmNlLnJldHVybjtcbiAgfVxuXG4gIHJldHVybiBsaXN0ZW5lcnM7XG59IC8vIFdlIHNob3VsZCBvbmx5IHVzZSB0aGlzIGZ1bmN0aW9uIGZvcjpcbi8vIC0gQmVmb3JlSW5wdXRFdmVudFBsdWdpblxuLy8gLSBDaGFuZ2VFdmVudFBsdWdpblxuLy8gLSBTZWxlY3RFdmVudFBsdWdpblxuLy8gVGhpcyBpcyBiZWNhdXNlIHdlIG9ubHkgcHJvY2VzcyB0aGVzZSBwbHVnaW5zXG4vLyBpbiB0aGUgYnViYmxlIHBoYXNlLCBzbyB3ZSBuZWVkIHRvIGFjY3VtdWxhdGUgdHdvXG4vLyBwaGFzZSBldmVudCBsaXN0ZW5lcnMgKHZpYSBlbXVsYXRpb24pLlxuXG5mdW5jdGlvbiBhY2N1bXVsYXRlVHdvUGhhc2VMaXN0ZW5lcnModGFyZ2V0RmliZXIsIHJlYWN0TmFtZSkge1xuICB2YXIgY2FwdHVyZU5hbWUgPSByZWFjdE5hbWUgKyAnQ2FwdHVyZSc7XG4gIHZhciBsaXN0ZW5lcnMgPSBbXTtcbiAgdmFyIGluc3RhbmNlID0gdGFyZ2V0RmliZXI7IC8vIEFjY3VtdWxhdGUgYWxsIGluc3RhbmNlcyBhbmQgbGlzdGVuZXJzIHZpYSB0aGUgdGFyZ2V0IC0+IHJvb3QgcGF0aC5cblxuICB3aGlsZSAoaW5zdGFuY2UgIT09IG51bGwpIHtcbiAgICB2YXIgX2luc3RhbmNlMyA9IGluc3RhbmNlLFxuICAgICAgICBzdGF0ZU5vZGUgPSBfaW5zdGFuY2UzLnN0YXRlTm9kZSxcbiAgICAgICAgdGFnID0gX2luc3RhbmNlMy50YWc7IC8vIEhhbmRsZSBsaXN0ZW5lcnMgdGhhdCBhcmUgb24gSG9zdENvbXBvbmVudHMgKGkuZS4gPGRpdj4pXG5cbiAgICBpZiAodGFnID09PSBIb3N0Q29tcG9uZW50ICYmIHN0YXRlTm9kZSAhPT0gbnVsbCkge1xuICAgICAgdmFyIGN1cnJlbnRUYXJnZXQgPSBzdGF0ZU5vZGU7XG4gICAgICB2YXIgY2FwdHVyZUxpc3RlbmVyID0gZ2V0TGlzdGVuZXIoaW5zdGFuY2UsIGNhcHR1cmVOYW1lKTtcblxuICAgICAgaWYgKGNhcHR1cmVMaXN0ZW5lciAhPSBudWxsKSB7XG4gICAgICAgIGxpc3RlbmVycy51bnNoaWZ0KGNyZWF0ZURpc3BhdGNoTGlzdGVuZXIoaW5zdGFuY2UsIGNhcHR1cmVMaXN0ZW5lciwgY3VycmVudFRhcmdldCkpO1xuICAgICAgfVxuXG4gICAgICB2YXIgYnViYmxlTGlzdGVuZXIgPSBnZXRMaXN0ZW5lcihpbnN0YW5jZSwgcmVhY3ROYW1lKTtcblxuICAgICAgaWYgKGJ1YmJsZUxpc3RlbmVyICE9IG51bGwpIHtcbiAgICAgICAgbGlzdGVuZXJzLnB1c2goY3JlYXRlRGlzcGF0Y2hMaXN0ZW5lcihpbnN0YW5jZSwgYnViYmxlTGlzdGVuZXIsIGN1cnJlbnRUYXJnZXQpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpbnN0YW5jZSA9IGluc3RhbmNlLnJldHVybjtcbiAgfVxuXG4gIHJldHVybiBsaXN0ZW5lcnM7XG59XG5cbmZ1bmN0aW9uIGdldFBhcmVudChpbnN0KSB7XG4gIGlmIChpbnN0ID09PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBkbyB7XG4gICAgaW5zdCA9IGluc3QucmV0dXJuOyAvLyBUT0RPOiBJZiB0aGlzIGlzIGEgSG9zdFJvb3Qgd2UgbWlnaHQgd2FudCB0byBiYWlsIG91dC5cbiAgICAvLyBUaGF0IGlzIGRlcGVuZGluZyBvbiBpZiB3ZSB3YW50IG5lc3RlZCBzdWJ0cmVlcyAobGF5ZXJzKSB0byBidWJibGVcbiAgICAvLyBldmVudHMgdG8gdGhlaXIgcGFyZW50LiBXZSBjb3VsZCBhbHNvIGdvIHRocm91Z2ggcGFyZW50Tm9kZSBvbiB0aGVcbiAgICAvLyBob3N0IG5vZGUgYnV0IHRoYXQgd291bGRuJ3Qgd29yayBmb3IgUmVhY3QgTmF0aXZlIGFuZCBkb2Vzbid0IGxldCB1c1xuICAgIC8vIGRvIHRoZSBwb3J0YWwgZmVhdHVyZS5cbiAgfSB3aGlsZSAoaW5zdCAmJiBpbnN0LnRhZyAhPT0gSG9zdENvbXBvbmVudCk7XG5cbiAgaWYgKGluc3QpIHtcbiAgICByZXR1cm4gaW5zdDtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuLyoqXG4gKiBSZXR1cm4gdGhlIGxvd2VzdCBjb21tb24gYW5jZXN0b3Igb2YgQSBhbmQgQiwgb3IgbnVsbCBpZiB0aGV5IGFyZSBpblxuICogZGlmZmVyZW50IHRyZWVzLlxuICovXG5cblxuZnVuY3Rpb24gZ2V0TG93ZXN0Q29tbW9uQW5jZXN0b3IoaW5zdEEsIGluc3RCKSB7XG4gIHZhciBub2RlQSA9IGluc3RBO1xuICB2YXIgbm9kZUIgPSBpbnN0QjtcbiAgdmFyIGRlcHRoQSA9IDA7XG5cbiAgZm9yICh2YXIgdGVtcEEgPSBub2RlQTsgdGVtcEE7IHRlbXBBID0gZ2V0UGFyZW50KHRlbXBBKSkge1xuICAgIGRlcHRoQSsrO1xuICB9XG5cbiAgdmFyIGRlcHRoQiA9IDA7XG5cbiAgZm9yICh2YXIgdGVtcEIgPSBub2RlQjsgdGVtcEI7IHRlbXBCID0gZ2V0UGFyZW50KHRlbXBCKSkge1xuICAgIGRlcHRoQisrO1xuICB9IC8vIElmIEEgaXMgZGVlcGVyLCBjcmF3bCB1cC5cblxuXG4gIHdoaWxlIChkZXB0aEEgLSBkZXB0aEIgPiAwKSB7XG4gICAgbm9kZUEgPSBnZXRQYXJlbnQobm9kZUEpO1xuICAgIGRlcHRoQS0tO1xuICB9IC8vIElmIEIgaXMgZGVlcGVyLCBjcmF3bCB1cC5cblxuXG4gIHdoaWxlIChkZXB0aEIgLSBkZXB0aEEgPiAwKSB7XG4gICAgbm9kZUIgPSBnZXRQYXJlbnQobm9kZUIpO1xuICAgIGRlcHRoQi0tO1xuICB9IC8vIFdhbGsgaW4gbG9ja3N0ZXAgdW50aWwgd2UgZmluZCBhIG1hdGNoLlxuXG5cbiAgdmFyIGRlcHRoID0gZGVwdGhBO1xuXG4gIHdoaWxlIChkZXB0aC0tKSB7XG4gICAgaWYgKG5vZGVBID09PSBub2RlQiB8fCBub2RlQiAhPT0gbnVsbCAmJiBub2RlQSA9PT0gbm9kZUIuYWx0ZXJuYXRlKSB7XG4gICAgICByZXR1cm4gbm9kZUE7XG4gICAgfVxuXG4gICAgbm9kZUEgPSBnZXRQYXJlbnQobm9kZUEpO1xuICAgIG5vZGVCID0gZ2V0UGFyZW50KG5vZGVCKTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBhY2N1bXVsYXRlRW50ZXJMZWF2ZUxpc3RlbmVyc0ZvckV2ZW50KGRpc3BhdGNoUXVldWUsIGV2ZW50LCB0YXJnZXQsIGNvbW1vbiwgaW5DYXB0dXJlUGhhc2UpIHtcbiAgdmFyIHJlZ2lzdHJhdGlvbk5hbWUgPSBldmVudC5fcmVhY3ROYW1lO1xuICB2YXIgbGlzdGVuZXJzID0gW107XG4gIHZhciBpbnN0YW5jZSA9IHRhcmdldDtcblxuICB3aGlsZSAoaW5zdGFuY2UgIT09IG51bGwpIHtcbiAgICBpZiAoaW5zdGFuY2UgPT09IGNvbW1vbikge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgdmFyIF9pbnN0YW5jZTQgPSBpbnN0YW5jZSxcbiAgICAgICAgYWx0ZXJuYXRlID0gX2luc3RhbmNlNC5hbHRlcm5hdGUsXG4gICAgICAgIHN0YXRlTm9kZSA9IF9pbnN0YW5jZTQuc3RhdGVOb2RlLFxuICAgICAgICB0YWcgPSBfaW5zdGFuY2U0LnRhZztcblxuICAgIGlmIChhbHRlcm5hdGUgIT09IG51bGwgJiYgYWx0ZXJuYXRlID09PSBjb21tb24pIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGlmICh0YWcgPT09IEhvc3RDb21wb25lbnQgJiYgc3RhdGVOb2RlICE9PSBudWxsKSB7XG4gICAgICB2YXIgY3VycmVudFRhcmdldCA9IHN0YXRlTm9kZTtcblxuICAgICAgaWYgKGluQ2FwdHVyZVBoYXNlKSB7XG4gICAgICAgIHZhciBjYXB0dXJlTGlzdGVuZXIgPSBnZXRMaXN0ZW5lcihpbnN0YW5jZSwgcmVnaXN0cmF0aW9uTmFtZSk7XG5cbiAgICAgICAgaWYgKGNhcHR1cmVMaXN0ZW5lciAhPSBudWxsKSB7XG4gICAgICAgICAgbGlzdGVuZXJzLnVuc2hpZnQoY3JlYXRlRGlzcGF0Y2hMaXN0ZW5lcihpbnN0YW5jZSwgY2FwdHVyZUxpc3RlbmVyLCBjdXJyZW50VGFyZ2V0KSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIWluQ2FwdHVyZVBoYXNlKSB7XG4gICAgICAgIHZhciBidWJibGVMaXN0ZW5lciA9IGdldExpc3RlbmVyKGluc3RhbmNlLCByZWdpc3RyYXRpb25OYW1lKTtcblxuICAgICAgICBpZiAoYnViYmxlTGlzdGVuZXIgIT0gbnVsbCkge1xuICAgICAgICAgIGxpc3RlbmVycy5wdXNoKGNyZWF0ZURpc3BhdGNoTGlzdGVuZXIoaW5zdGFuY2UsIGJ1YmJsZUxpc3RlbmVyLCBjdXJyZW50VGFyZ2V0KSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpbnN0YW5jZSA9IGluc3RhbmNlLnJldHVybjtcbiAgfVxuXG4gIGlmIChsaXN0ZW5lcnMubGVuZ3RoICE9PSAwKSB7XG4gICAgZGlzcGF0Y2hRdWV1ZS5wdXNoKHtcbiAgICAgIGV2ZW50OiBldmVudCxcbiAgICAgIGxpc3RlbmVyczogbGlzdGVuZXJzXG4gICAgfSk7XG4gIH1cbn0gLy8gV2Ugc2hvdWxkIG9ubHkgdXNlIHRoaXMgZnVuY3Rpb24gZm9yOlxuLy8gLSBFbnRlckxlYXZlRXZlbnRQbHVnaW5cbi8vIFRoaXMgaXMgYmVjYXVzZSB3ZSBvbmx5IHByb2Nlc3MgdGhpcyBwbHVnaW5cbi8vIGluIHRoZSBidWJibGUgcGhhc2UsIHNvIHdlIG5lZWQgdG8gYWNjdW11bGF0ZSB0d29cbi8vIHBoYXNlIGV2ZW50IGxpc3RlbmVycy5cblxuXG5mdW5jdGlvbiBhY2N1bXVsYXRlRW50ZXJMZWF2ZVR3b1BoYXNlTGlzdGVuZXJzKGRpc3BhdGNoUXVldWUsIGxlYXZlRXZlbnQsIGVudGVyRXZlbnQsIGZyb20sIHRvKSB7XG4gIHZhciBjb21tb24gPSBmcm9tICYmIHRvID8gZ2V0TG93ZXN0Q29tbW9uQW5jZXN0b3IoZnJvbSwgdG8pIDogbnVsbDtcblxuICBpZiAoZnJvbSAhPT0gbnVsbCkge1xuICAgIGFjY3VtdWxhdGVFbnRlckxlYXZlTGlzdGVuZXJzRm9yRXZlbnQoZGlzcGF0Y2hRdWV1ZSwgbGVhdmVFdmVudCwgZnJvbSwgY29tbW9uLCBmYWxzZSk7XG4gIH1cblxuICBpZiAodG8gIT09IG51bGwgJiYgZW50ZXJFdmVudCAhPT0gbnVsbCkge1xuICAgIGFjY3VtdWxhdGVFbnRlckxlYXZlTGlzdGVuZXJzRm9yRXZlbnQoZGlzcGF0Y2hRdWV1ZSwgZW50ZXJFdmVudCwgdG8sIGNvbW1vbiwgdHJ1ZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGdldExpc3RlbmVyU2V0S2V5KGRvbUV2ZW50TmFtZSwgY2FwdHVyZSkge1xuICByZXR1cm4gZG9tRXZlbnROYW1lICsgXCJfX1wiICsgKGNhcHR1cmUgPyAnY2FwdHVyZScgOiAnYnViYmxlJyk7XG59XG5cbnZhciBkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbiA9IGZhbHNlO1xudmFyIERBTkdFUk9VU0xZX1NFVF9JTk5FUl9IVE1MID0gJ2Rhbmdlcm91c2x5U2V0SW5uZXJIVE1MJztcbnZhciBTVVBQUkVTU19DT05URU5UX0VESVRBQkxFX1dBUk5JTkcgPSAnc3VwcHJlc3NDb250ZW50RWRpdGFibGVXYXJuaW5nJztcbnZhciBTVVBQUkVTU19IWURSQVRJT05fV0FSTklORyA9ICdzdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmcnO1xudmFyIEFVVE9GT0NVUyA9ICdhdXRvRm9jdXMnO1xudmFyIENISUxEUkVOID0gJ2NoaWxkcmVuJztcbnZhciBTVFlMRSA9ICdzdHlsZSc7XG52YXIgSFRNTCQxID0gJ19faHRtbCc7XG52YXIgd2FybmVkVW5rbm93blRhZ3M7XG52YXIgdmFsaWRhdGVQcm9wZXJ0aWVzSW5EZXZlbG9wbWVudDtcbnZhciB3YXJuRm9yUHJvcERpZmZlcmVuY2U7XG52YXIgd2FybkZvckV4dHJhQXR0cmlidXRlcztcbnZhciB3YXJuRm9ySW52YWxpZEV2ZW50TGlzdGVuZXI7XG52YXIgY2FuRGlmZlN0eWxlRm9ySHlkcmF0aW9uV2FybmluZztcbnZhciBub3JtYWxpemVIVE1MO1xuXG57XG4gIHdhcm5lZFVua25vd25UYWdzID0ge1xuICAgIC8vIFRoZXJlIGFyZSB3b3JraW5nIHBvbHlmaWxscyBmb3IgPGRpYWxvZz4uIExldCBwZW9wbGUgdXNlIGl0LlxuICAgIGRpYWxvZzogdHJ1ZSxcbiAgICAvLyBFbGVjdHJvbiBzaGlwcyBhIGN1c3RvbSA8d2Vidmlldz4gdGFnIHRvIGRpc3BsYXkgZXh0ZXJuYWwgd2ViIGNvbnRlbnQgaW5cbiAgICAvLyBhbiBpc29sYXRlZCBmcmFtZSBhbmQgcHJvY2Vzcy5cbiAgICAvLyBUaGlzIHRhZyBpcyBub3QgcHJlc2VudCBpbiBub24gRWxlY3Ryb24gZW52aXJvbm1lbnRzIHN1Y2ggYXMgSlNEb20gd2hpY2hcbiAgICAvLyBpcyBvZnRlbiB1c2VkIGZvciB0ZXN0aW5nIHB1cnBvc2VzLlxuICAgIC8vIEBzZWUgaHR0cHM6Ly9lbGVjdHJvbmpzLm9yZy9kb2NzL2FwaS93ZWJ2aWV3LXRhZ1xuICAgIHdlYnZpZXc6IHRydWVcbiAgfTtcblxuICB2YWxpZGF0ZVByb3BlcnRpZXNJbkRldmVsb3BtZW50ID0gZnVuY3Rpb24gKHR5cGUsIHByb3BzKSB7XG4gICAgdmFsaWRhdGVQcm9wZXJ0aWVzKHR5cGUsIHByb3BzKTtcbiAgICB2YWxpZGF0ZVByb3BlcnRpZXMkMSh0eXBlLCBwcm9wcyk7XG4gICAgdmFsaWRhdGVQcm9wZXJ0aWVzJDIodHlwZSwgcHJvcHMsIHtcbiAgICAgIHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXM6IHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMsXG4gICAgICBwb3NzaWJsZVJlZ2lzdHJhdGlvbk5hbWVzOiBwb3NzaWJsZVJlZ2lzdHJhdGlvbk5hbWVzXG4gICAgfSk7XG4gIH07IC8vIElFIDExIHBhcnNlcyAmIG5vcm1hbGl6ZXMgdGhlIHN0eWxlIGF0dHJpYnV0ZSBhcyBvcHBvc2VkIHRvIG90aGVyXG4gIC8vIGJyb3dzZXJzLiBJdCBhZGRzIHNwYWNlcyBhbmQgc29ydHMgdGhlIHByb3BlcnRpZXMgaW4gc29tZVxuICAvLyBub24tYWxwaGFiZXRpY2FsIG9yZGVyLiBIYW5kbGluZyB0aGF0IHdvdWxkIHJlcXVpcmUgc29ydGluZyBDU1NcbiAgLy8gcHJvcGVydGllcyBpbiB0aGUgY2xpZW50ICYgc2VydmVyIHZlcnNpb25zIG9yIGFwcGx5aW5nXG4gIC8vIGBleHBlY3RlZFN0eWxlYCB0byBhIHRlbXBvcmFyeSBET00gbm9kZSB0byByZWFkIGl0cyBgc3R5bGVgIGF0dHJpYnV0ZVxuICAvLyBub3JtYWxpemVkLiBTaW5jZSBpdCBvbmx5IGFmZmVjdHMgSUUsIHdlJ3JlIHNraXBwaW5nIHN0eWxlIHdhcm5pbmdzXG4gIC8vIGluIHRoYXQgYnJvd3NlciBjb21wbGV0ZWx5IGluIGZhdm9yIG9mIGRvaW5nIGFsbCB0aGF0IHdvcmsuXG4gIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzExODA3XG5cblxuICBjYW5EaWZmU3R5bGVGb3JIeWRyYXRpb25XYXJuaW5nID0gY2FuVXNlRE9NICYmICFkb2N1bWVudC5kb2N1bWVudE1vZGU7XG5cbiAgd2FybkZvclByb3BEaWZmZXJlbmNlID0gZnVuY3Rpb24gKHByb3BOYW1lLCBzZXJ2ZXJWYWx1ZSwgY2xpZW50VmFsdWUpIHtcbiAgICBpZiAoZGlkV2FybkludmFsaWRIeWRyYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgbm9ybWFsaXplZENsaWVudFZhbHVlID0gbm9ybWFsaXplTWFya3VwRm9yVGV4dE9yQXR0cmlidXRlKGNsaWVudFZhbHVlKTtcbiAgICB2YXIgbm9ybWFsaXplZFNlcnZlclZhbHVlID0gbm9ybWFsaXplTWFya3VwRm9yVGV4dE9yQXR0cmlidXRlKHNlcnZlclZhbHVlKTtcblxuICAgIGlmIChub3JtYWxpemVkU2VydmVyVmFsdWUgPT09IG5vcm1hbGl6ZWRDbGllbnRWYWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uID0gdHJ1ZTtcblxuICAgIGVycm9yKCdQcm9wIGAlc2AgZGlkIG5vdCBtYXRjaC4gU2VydmVyOiAlcyBDbGllbnQ6ICVzJywgcHJvcE5hbWUsIEpTT04uc3RyaW5naWZ5KG5vcm1hbGl6ZWRTZXJ2ZXJWYWx1ZSksIEpTT04uc3RyaW5naWZ5KG5vcm1hbGl6ZWRDbGllbnRWYWx1ZSkpO1xuICB9O1xuXG4gIHdhcm5Gb3JFeHRyYUF0dHJpYnV0ZXMgPSBmdW5jdGlvbiAoYXR0cmlidXRlTmFtZXMpIHtcbiAgICBpZiAoZGlkV2FybkludmFsaWRIeWRyYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbiA9IHRydWU7XG4gICAgdmFyIG5hbWVzID0gW107XG4gICAgYXR0cmlidXRlTmFtZXMuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICAgICAgbmFtZXMucHVzaChuYW1lKTtcbiAgICB9KTtcblxuICAgIGVycm9yKCdFeHRyYSBhdHRyaWJ1dGVzIGZyb20gdGhlIHNlcnZlcjogJXMnLCBuYW1lcyk7XG4gIH07XG5cbiAgd2FybkZvckludmFsaWRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHJlZ2lzdHJhdGlvbk5hbWUsIGxpc3RlbmVyKSB7XG4gICAgaWYgKGxpc3RlbmVyID09PSBmYWxzZSkge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIGAlc2AgbGlzdGVuZXIgdG8gYmUgYSBmdW5jdGlvbiwgaW5zdGVhZCBnb3QgYGZhbHNlYC5cXG5cXG4nICsgJ0lmIHlvdSB1c2VkIHRvIGNvbmRpdGlvbmFsbHkgb21pdCBpdCB3aXRoICVzPXtjb25kaXRpb24gJiYgdmFsdWV9LCAnICsgJ3Bhc3MgJXM9e2NvbmRpdGlvbiA/IHZhbHVlIDogdW5kZWZpbmVkfSBpbnN0ZWFkLicsIHJlZ2lzdHJhdGlvbk5hbWUsIHJlZ2lzdHJhdGlvbk5hbWUsIHJlZ2lzdHJhdGlvbk5hbWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlcnJvcignRXhwZWN0ZWQgYCVzYCBsaXN0ZW5lciB0byBiZSBhIGZ1bmN0aW9uLCBpbnN0ZWFkIGdvdCBhIHZhbHVlIG9mIGAlc2AgdHlwZS4nLCByZWdpc3RyYXRpb25OYW1lLCB0eXBlb2YgbGlzdGVuZXIpO1xuICAgIH1cbiAgfTsgLy8gUGFyc2UgdGhlIEhUTUwgYW5kIHJlYWQgaXQgYmFjayB0byBub3JtYWxpemUgdGhlIEhUTUwgc3RyaW5nIHNvIHRoYXQgaXRcbiAgLy8gY2FuIGJlIHVzZWQgZm9yIGNvbXBhcmlzb24uXG5cblxuICBub3JtYWxpemVIVE1MID0gZnVuY3Rpb24gKHBhcmVudCwgaHRtbCkge1xuICAgIC8vIFdlIGNvdWxkIGhhdmUgY3JlYXRlZCBhIHNlcGFyYXRlIGRvY3VtZW50IGhlcmUgdG8gYXZvaWRcbiAgICAvLyByZS1pbml0aWFsaXppbmcgY3VzdG9tIGVsZW1lbnRzIGlmIHRoZXkgZXhpc3QuIEJ1dCB0aGlzIGJyZWFrc1xuICAgIC8vIGhvdyA8bm9zY3JpcHQ+IGlzIGJlaW5nIGhhbmRsZWQuIFNvIHdlIHVzZSB0aGUgc2FtZSBkb2N1bWVudC5cbiAgICAvLyBTZWUgdGhlIGRpc2N1c3Npb24gaW4gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L3B1bGwvMTExNTcuXG4gICAgdmFyIHRlc3RFbGVtZW50ID0gcGFyZW50Lm5hbWVzcGFjZVVSSSA9PT0gSFRNTF9OQU1FU1BBQ0UgPyBwYXJlbnQub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KHBhcmVudC50YWdOYW1lKSA6IHBhcmVudC5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhwYXJlbnQubmFtZXNwYWNlVVJJLCBwYXJlbnQudGFnTmFtZSk7XG4gICAgdGVzdEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICByZXR1cm4gdGVzdEVsZW1lbnQuaW5uZXJIVE1MO1xuICB9O1xufSAvLyBIVE1MIHBhcnNpbmcgbm9ybWFsaXplcyBDUiBhbmQgQ1JMRiB0byBMRi5cbi8vIEl0IGFsc28gY2FuIHR1cm4gXFx1MDAwMCBpbnRvIFxcdUZGRkQgaW5zaWRlIGF0dHJpYnV0ZXMuXG4vLyBodHRwczovL3d3dy53My5vcmcvVFIvaHRtbDUvc2luZ2xlLXBhZ2UuaHRtbCNwcmVwcm9jZXNzaW5nLXRoZS1pbnB1dC1zdHJlYW1cbi8vIElmIHdlIGhhdmUgYSBtaXNtYXRjaCwgaXQgbWlnaHQgYmUgY2F1c2VkIGJ5IHRoYXQuXG4vLyBXZSB3aWxsIHN0aWxsIHBhdGNoIHVwIGluIHRoaXMgY2FzZSBidXQgbm90IGZpcmUgdGhlIHdhcm5pbmcuXG5cblxudmFyIE5PUk1BTElaRV9ORVdMSU5FU19SRUdFWCA9IC9cXHJcXG4/L2c7XG52YXIgTk9STUFMSVpFX05VTExfQU5EX1JFUExBQ0VNRU5UX1JFR0VYID0gL1xcdTAwMDB8XFx1RkZGRC9nO1xuXG5mdW5jdGlvbiBub3JtYWxpemVNYXJrdXBGb3JUZXh0T3JBdHRyaWJ1dGUobWFya3VwKSB7XG4gIHtcbiAgICBjaGVja0h0bWxTdHJpbmdDb2VyY2lvbihtYXJrdXApO1xuICB9XG5cbiAgdmFyIG1hcmt1cFN0cmluZyA9IHR5cGVvZiBtYXJrdXAgPT09ICdzdHJpbmcnID8gbWFya3VwIDogJycgKyBtYXJrdXA7XG4gIHJldHVybiBtYXJrdXBTdHJpbmcucmVwbGFjZShOT1JNQUxJWkVfTkVXTElORVNfUkVHRVgsICdcXG4nKS5yZXBsYWNlKE5PUk1BTElaRV9OVUxMX0FORF9SRVBMQUNFTUVOVF9SRUdFWCwgJycpO1xufVxuXG5mdW5jdGlvbiBjaGVja0ZvclVubWF0Y2hlZFRleHQoc2VydmVyVGV4dCwgY2xpZW50VGV4dCwgaXNDb25jdXJyZW50TW9kZSwgc2hvdWxkV2FybkRldikge1xuICB2YXIgbm9ybWFsaXplZENsaWVudFRleHQgPSBub3JtYWxpemVNYXJrdXBGb3JUZXh0T3JBdHRyaWJ1dGUoY2xpZW50VGV4dCk7XG4gIHZhciBub3JtYWxpemVkU2VydmVyVGV4dCA9IG5vcm1hbGl6ZU1hcmt1cEZvclRleHRPckF0dHJpYnV0ZShzZXJ2ZXJUZXh0KTtcblxuICBpZiAobm9ybWFsaXplZFNlcnZlclRleHQgPT09IG5vcm1hbGl6ZWRDbGllbnRUZXh0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHNob3VsZFdhcm5EZXYpIHtcbiAgICB7XG4gICAgICBpZiAoIWRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uKSB7XG4gICAgICAgIGRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uID0gdHJ1ZTtcblxuICAgICAgICBlcnJvcignVGV4dCBjb250ZW50IGRpZCBub3QgbWF0Y2guIFNlcnZlcjogXCIlc1wiIENsaWVudDogXCIlc1wiJywgbm9ybWFsaXplZFNlcnZlclRleHQsIG5vcm1hbGl6ZWRDbGllbnRUZXh0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoaXNDb25jdXJyZW50TW9kZSAmJiBlbmFibGVDbGllbnRSZW5kZXJGYWxsYmFja09uVGV4dE1pc21hdGNoKSB7XG4gICAgLy8gSW4gY29uY3VycmVudCByb290cywgd2UgdGhyb3cgd2hlbiB0aGVyZSdzIGEgdGV4dCBtaXNtYXRjaCBhbmQgcmV2ZXJ0IHRvXG4gICAgLy8gY2xpZW50IHJlbmRlcmluZywgdXAgdG8gdGhlIG5lYXJlc3QgU3VzcGVuc2UgYm91bmRhcnkuXG4gICAgdGhyb3cgbmV3IEVycm9yKCdUZXh0IGNvbnRlbnQgZG9lcyBub3QgbWF0Y2ggc2VydmVyLXJlbmRlcmVkIEhUTUwuJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0T3duZXJEb2N1bWVudEZyb21Sb290Q29udGFpbmVyKHJvb3RDb250YWluZXJFbGVtZW50KSB7XG4gIHJldHVybiByb290Q29udGFpbmVyRWxlbWVudC5ub2RlVHlwZSA9PT0gRE9DVU1FTlRfTk9ERSA/IHJvb3RDb250YWluZXJFbGVtZW50IDogcm9vdENvbnRhaW5lckVsZW1lbnQub3duZXJEb2N1bWVudDtcbn1cblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbmZ1bmN0aW9uIHRyYXBDbGlja09uTm9uSW50ZXJhY3RpdmVFbGVtZW50KG5vZGUpIHtcbiAgLy8gTW9iaWxlIFNhZmFyaSBkb2VzIG5vdCBmaXJlIHByb3Blcmx5IGJ1YmJsZSBjbGljayBldmVudHMgb25cbiAgLy8gbm9uLWludGVyYWN0aXZlIGVsZW1lbnRzLCB3aGljaCBtZWFucyBkZWxlZ2F0ZWQgY2xpY2sgbGlzdGVuZXJzIGRvIG5vdFxuICAvLyBmaXJlLiBUaGUgd29ya2Fyb3VuZCBmb3IgdGhpcyBidWcgaW52b2x2ZXMgYXR0YWNoaW5nIGFuIGVtcHR5IGNsaWNrXG4gIC8vIGxpc3RlbmVyIG9uIHRoZSB0YXJnZXQgbm9kZS5cbiAgLy8gaHR0cHM6Ly93d3cucXVpcmtzbW9kZS5vcmcvYmxvZy9hcmNoaXZlcy8yMDEwLzA5L2NsaWNrX2V2ZW50X2RlbC5odG1sXG4gIC8vIEp1c3Qgc2V0IGl0IHVzaW5nIHRoZSBvbmNsaWNrIHByb3BlcnR5IHNvIHRoYXQgd2UgZG9uJ3QgaGF2ZSB0byBtYW5hZ2UgYW55XG4gIC8vIGJvb2trZWVwaW5nIGZvciBpdC4gTm90IHN1cmUgaWYgd2UgbmVlZCB0byBjbGVhciBpdCB3aGVuIHRoZSBsaXN0ZW5lciBpc1xuICAvLyByZW1vdmVkLlxuICAvLyBUT0RPOiBPbmx5IGRvIHRoaXMgZm9yIHRoZSByZWxldmFudCBTYWZhcmlzIG1heWJlP1xuICBub2RlLm9uY2xpY2sgPSBub29wO1xufVxuXG5mdW5jdGlvbiBzZXRJbml0aWFsRE9NUHJvcGVydGllcyh0YWcsIGRvbUVsZW1lbnQsIHJvb3RDb250YWluZXJFbGVtZW50LCBuZXh0UHJvcHMsIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSB7XG4gIGZvciAodmFyIHByb3BLZXkgaW4gbmV4dFByb3BzKSB7XG4gICAgaWYgKCFuZXh0UHJvcHMuaGFzT3duUHJvcGVydHkocHJvcEtleSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHZhciBuZXh0UHJvcCA9IG5leHRQcm9wc1twcm9wS2V5XTtcblxuICAgIGlmIChwcm9wS2V5ID09PSBTVFlMRSkge1xuICAgICAge1xuICAgICAgICBpZiAobmV4dFByb3ApIHtcbiAgICAgICAgICAvLyBGcmVlemUgdGhlIG5leHQgc3R5bGUgb2JqZWN0IHNvIHRoYXQgd2UgY2FuIGFzc3VtZSBpdCB3b24ndCBiZVxuICAgICAgICAgIC8vIG11dGF0ZWQuIFdlIGhhdmUgYWxyZWFkeSB3YXJuZWQgZm9yIHRoaXMgaW4gdGhlIHBhc3QuXG4gICAgICAgICAgT2JqZWN0LmZyZWV6ZShuZXh0UHJvcCk7XG4gICAgICAgIH1cbiAgICAgIH0gLy8gUmVsaWVzIG9uIGB1cGRhdGVTdHlsZXNCeUlEYCBub3QgbXV0YXRpbmcgYHN0eWxlVXBkYXRlc2AuXG5cblxuICAgICAgc2V0VmFsdWVGb3JTdHlsZXMoZG9tRWxlbWVudCwgbmV4dFByb3ApO1xuICAgIH0gZWxzZSBpZiAocHJvcEtleSA9PT0gREFOR0VST1VTTFlfU0VUX0lOTkVSX0hUTUwpIHtcbiAgICAgIHZhciBuZXh0SHRtbCA9IG5leHRQcm9wID8gbmV4dFByb3BbSFRNTCQxXSA6IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKG5leHRIdG1sICE9IG51bGwpIHtcbiAgICAgICAgc2V0SW5uZXJIVE1MKGRvbUVsZW1lbnQsIG5leHRIdG1sKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHByb3BLZXkgPT09IENISUxEUkVOKSB7XG4gICAgICBpZiAodHlwZW9mIG5leHRQcm9wID09PSAnc3RyaW5nJykge1xuICAgICAgICAvLyBBdm9pZCBzZXR0aW5nIGluaXRpYWwgdGV4dENvbnRlbnQgd2hlbiB0aGUgdGV4dCBpcyBlbXB0eS4gSW4gSUUxMSBzZXR0aW5nXG4gICAgICAgIC8vIHRleHRDb250ZW50IG9uIGEgPHRleHRhcmVhPiB3aWxsIGNhdXNlIHRoZSBwbGFjZWhvbGRlciB0byBub3RcbiAgICAgICAgLy8gc2hvdyB3aXRoaW4gdGhlIDx0ZXh0YXJlYT4gdW50aWwgaXQgaGFzIGJlZW4gZm9jdXNlZCBhbmQgYmx1cnJlZCBhZ2Fpbi5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy82NzMxI2lzc3VlY29tbWVudC0yNTQ4NzQ1NTNcbiAgICAgICAgdmFyIGNhblNldFRleHRDb250ZW50ID0gdGFnICE9PSAndGV4dGFyZWEnIHx8IG5leHRQcm9wICE9PSAnJztcblxuICAgICAgICBpZiAoY2FuU2V0VGV4dENvbnRlbnQpIHtcbiAgICAgICAgICBzZXRUZXh0Q29udGVudChkb21FbGVtZW50LCBuZXh0UHJvcCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG5leHRQcm9wID09PSAnbnVtYmVyJykge1xuICAgICAgICBzZXRUZXh0Q29udGVudChkb21FbGVtZW50LCAnJyArIG5leHRQcm9wKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHByb3BLZXkgPT09IFNVUFBSRVNTX0NPTlRFTlRfRURJVEFCTEVfV0FSTklORyB8fCBwcm9wS2V5ID09PSBTVVBQUkVTU19IWURSQVRJT05fV0FSTklORykgOyBlbHNlIGlmIChwcm9wS2V5ID09PSBBVVRPRk9DVVMpIDsgZWxzZSBpZiAocmVnaXN0cmF0aW9uTmFtZURlcGVuZGVuY2llcy5oYXNPd25Qcm9wZXJ0eShwcm9wS2V5KSkge1xuICAgICAgaWYgKG5leHRQcm9wICE9IG51bGwpIHtcbiAgICAgICAgaWYgKCB0eXBlb2YgbmV4dFByb3AgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB3YXJuRm9ySW52YWxpZEV2ZW50TGlzdGVuZXIocHJvcEtleSwgbmV4dFByb3ApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHByb3BLZXkgPT09ICdvblNjcm9sbCcpIHtcbiAgICAgICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdzY3JvbGwnLCBkb21FbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobmV4dFByb3AgIT0gbnVsbCkge1xuICAgICAgc2V0VmFsdWVGb3JQcm9wZXJ0eShkb21FbGVtZW50LCBwcm9wS2V5LCBuZXh0UHJvcCwgaXNDdXN0b21Db21wb25lbnRUYWcpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB1cGRhdGVET01Qcm9wZXJ0aWVzKGRvbUVsZW1lbnQsIHVwZGF0ZVBheWxvYWQsIHdhc0N1c3RvbUNvbXBvbmVudFRhZywgaXNDdXN0b21Db21wb25lbnRUYWcpIHtcbiAgLy8gVE9ETzogSGFuZGxlIHdhc0N1c3RvbUNvbXBvbmVudFRhZ1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHVwZGF0ZVBheWxvYWQubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIgcHJvcEtleSA9IHVwZGF0ZVBheWxvYWRbaV07XG4gICAgdmFyIHByb3BWYWx1ZSA9IHVwZGF0ZVBheWxvYWRbaSArIDFdO1xuXG4gICAgaWYgKHByb3BLZXkgPT09IFNUWUxFKSB7XG4gICAgICBzZXRWYWx1ZUZvclN0eWxlcyhkb21FbGVtZW50LCBwcm9wVmFsdWUpO1xuICAgIH0gZWxzZSBpZiAocHJvcEtleSA9PT0gREFOR0VST1VTTFlfU0VUX0lOTkVSX0hUTUwpIHtcbiAgICAgIHNldElubmVySFRNTChkb21FbGVtZW50LCBwcm9wVmFsdWUpO1xuICAgIH0gZWxzZSBpZiAocHJvcEtleSA9PT0gQ0hJTERSRU4pIHtcbiAgICAgIHNldFRleHRDb250ZW50KGRvbUVsZW1lbnQsIHByb3BWYWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldFZhbHVlRm9yUHJvcGVydHkoZG9tRWxlbWVudCwgcHJvcEtleSwgcHJvcFZhbHVlLCBpc0N1c3RvbUNvbXBvbmVudFRhZyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQodHlwZSwgcHJvcHMsIHJvb3RDb250YWluZXJFbGVtZW50LCBwYXJlbnROYW1lc3BhY2UpIHtcbiAgdmFyIGlzQ3VzdG9tQ29tcG9uZW50VGFnOyAvLyBXZSBjcmVhdGUgdGFncyBpbiB0aGUgbmFtZXNwYWNlIG9mIHRoZWlyIHBhcmVudCBjb250YWluZXIsIGV4Y2VwdCBIVE1MXG4gIC8vIHRhZ3MgZ2V0IG5vIG5hbWVzcGFjZS5cblxuICB2YXIgb3duZXJEb2N1bWVudCA9IGdldE93bmVyRG9jdW1lbnRGcm9tUm9vdENvbnRhaW5lcihyb290Q29udGFpbmVyRWxlbWVudCk7XG4gIHZhciBkb21FbGVtZW50O1xuICB2YXIgbmFtZXNwYWNlVVJJID0gcGFyZW50TmFtZXNwYWNlO1xuXG4gIGlmIChuYW1lc3BhY2VVUkkgPT09IEhUTUxfTkFNRVNQQUNFKSB7XG4gICAgbmFtZXNwYWNlVVJJID0gZ2V0SW50cmluc2ljTmFtZXNwYWNlKHR5cGUpO1xuICB9XG5cbiAgaWYgKG5hbWVzcGFjZVVSSSA9PT0gSFRNTF9OQU1FU1BBQ0UpIHtcbiAgICB7XG4gICAgICBpc0N1c3RvbUNvbXBvbmVudFRhZyA9IGlzQ3VzdG9tQ29tcG9uZW50KHR5cGUsIHByb3BzKTsgLy8gU2hvdWxkIHRoaXMgY2hlY2sgYmUgZ2F0ZWQgYnkgcGFyZW50IG5hbWVzcGFjZT8gTm90IHN1cmUgd2Ugd2FudCB0b1xuICAgICAgLy8gYWxsb3cgPFNWRz4gb3IgPG1BVEg+LlxuXG4gICAgICBpZiAoIWlzQ3VzdG9tQ29tcG9uZW50VGFnICYmIHR5cGUgIT09IHR5cGUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICBlcnJvcignPCVzIC8+IGlzIHVzaW5nIGluY29ycmVjdCBjYXNpbmcuICcgKyAnVXNlIFBhc2NhbENhc2UgZm9yIFJlYWN0IGNvbXBvbmVudHMsICcgKyAnb3IgbG93ZXJjYXNlIGZvciBIVE1MIGVsZW1lbnRzLicsIHR5cGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlID09PSAnc2NyaXB0Jykge1xuICAgICAgLy8gQ3JlYXRlIHRoZSBzY3JpcHQgdmlhIC5pbm5lckhUTUwgc28gaXRzIFwicGFyc2VyLWluc2VydGVkXCIgZmxhZyBpc1xuICAgICAgLy8gc2V0IHRvIHRydWUgYW5kIGl0IGRvZXMgbm90IGV4ZWN1dGVcbiAgICAgIHZhciBkaXYgPSBvd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG4gICAgICBkaXYuaW5uZXJIVE1MID0gJzxzY3JpcHQ+PCcgKyAnL3NjcmlwdD4nOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgICAvLyBUaGlzIGlzIGd1YXJhbnRlZWQgdG8geWllbGQgYSBzY3JpcHQgZWxlbWVudC5cblxuICAgICAgdmFyIGZpcnN0Q2hpbGQgPSBkaXYuZmlyc3RDaGlsZDtcbiAgICAgIGRvbUVsZW1lbnQgPSBkaXYucmVtb3ZlQ2hpbGQoZmlyc3RDaGlsZCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcHJvcHMuaXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyAkRmxvd0lzc3VlIGBjcmVhdGVFbGVtZW50YCBzaG91bGQgYmUgdXBkYXRlZCBmb3IgV2ViIENvbXBvbmVudHNcbiAgICAgIGRvbUVsZW1lbnQgPSBvd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodHlwZSwge1xuICAgICAgICBpczogcHJvcHMuaXNcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBTZXBhcmF0ZSBlbHNlIGJyYW5jaCBpbnN0ZWFkIG9mIHVzaW5nIGBwcm9wcy5pcyB8fCB1bmRlZmluZWRgIGFib3ZlIGJlY2F1c2Ugb2YgYSBGaXJlZm94IGJ1Zy5cbiAgICAgIC8vIFNlZSBkaXNjdXNzaW9uIGluIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzY4OTZcbiAgICAgIC8vIGFuZCBkaXNjdXNzaW9uIGluIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTEyNzYyNDBcbiAgICAgIGRvbUVsZW1lbnQgPSBvd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodHlwZSk7IC8vIE5vcm1hbGx5IGF0dHJpYnV0ZXMgYXJlIGFzc2lnbmVkIGluIGBzZXRJbml0aWFsRE9NUHJvcGVydGllc2AsIGhvd2V2ZXIgdGhlIGBtdWx0aXBsZWAgYW5kIGBzaXplYFxuICAgICAgLy8gYXR0cmlidXRlcyBvbiBgc2VsZWN0YHMgbmVlZHMgdG8gYmUgYWRkZWQgYmVmb3JlIGBvcHRpb25gcyBhcmUgaW5zZXJ0ZWQuXG4gICAgICAvLyBUaGlzIHByZXZlbnRzOlxuICAgICAgLy8gLSBhIGJ1ZyB3aGVyZSB0aGUgYHNlbGVjdGAgZG9lcyBub3Qgc2Nyb2xsIHRvIHRoZSBjb3JyZWN0IG9wdGlvbiBiZWNhdXNlIHNpbmd1bGFyXG4gICAgICAvLyAgYHNlbGVjdGAgZWxlbWVudHMgYXV0b21hdGljYWxseSBwaWNrIHRoZSBmaXJzdCBpdGVtICMxMzIyMlxuICAgICAgLy8gLSBhIGJ1ZyB3aGVyZSB0aGUgYHNlbGVjdGAgc2V0IHRoZSBmaXJzdCBpdGVtIGFzIHNlbGVjdGVkIGRlc3BpdGUgdGhlIGBzaXplYCBhdHRyaWJ1dGUgIzE0MjM5XG4gICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xMzIyMlxuICAgICAgLy8gYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTQyMzlcblxuICAgICAgaWYgKHR5cGUgPT09ICdzZWxlY3QnKSB7XG4gICAgICAgIHZhciBub2RlID0gZG9tRWxlbWVudDtcblxuICAgICAgICBpZiAocHJvcHMubXVsdGlwbGUpIHtcbiAgICAgICAgICBub2RlLm11bHRpcGxlID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChwcm9wcy5zaXplKSB7XG4gICAgICAgICAgLy8gU2V0dGluZyBhIHNpemUgZ3JlYXRlciB0aGFuIDEgY2F1c2VzIGEgc2VsZWN0IHRvIGJlaGF2ZSBsaWtlIGBtdWx0aXBsZT10cnVlYCwgd2hlcmVcbiAgICAgICAgICAvLyBpdCBpcyBwb3NzaWJsZSB0aGF0IG5vIG9wdGlvbiBpcyBzZWxlY3RlZC5cbiAgICAgICAgICAvL1xuICAgICAgICAgIC8vIFRoaXMgaXMgb25seSBuZWNlc3Nhcnkgd2hlbiBhIHNlbGVjdCBpbiBcInNpbmdsZSBzZWxlY3Rpb24gbW9kZVwiLlxuICAgICAgICAgIG5vZGUuc2l6ZSA9IHByb3BzLnNpemU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZG9tRWxlbWVudCA9IG93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSwgdHlwZSk7XG4gIH1cblxuICB7XG4gICAgaWYgKG5hbWVzcGFjZVVSSSA9PT0gSFRNTF9OQU1FU1BBQ0UpIHtcbiAgICAgIGlmICghaXNDdXN0b21Db21wb25lbnRUYWcgJiYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRvbUVsZW1lbnQpID09PSAnW29iamVjdCBIVE1MVW5rbm93bkVsZW1lbnRdJyAmJiAhaGFzT3duUHJvcGVydHkuY2FsbCh3YXJuZWRVbmtub3duVGFncywgdHlwZSkpIHtcbiAgICAgICAgd2FybmVkVW5rbm93blRhZ3NbdHlwZV0gPSB0cnVlO1xuXG4gICAgICAgIGVycm9yKCdUaGUgdGFnIDwlcz4gaXMgdW5yZWNvZ25pemVkIGluIHRoaXMgYnJvd3Nlci4gJyArICdJZiB5b3UgbWVhbnQgdG8gcmVuZGVyIGEgUmVhY3QgY29tcG9uZW50LCBzdGFydCBpdHMgbmFtZSB3aXRoICcgKyAnYW4gdXBwZXJjYXNlIGxldHRlci4nLCB0eXBlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZG9tRWxlbWVudDtcbn1cbmZ1bmN0aW9uIGNyZWF0ZVRleHROb2RlKHRleHQsIHJvb3RDb250YWluZXJFbGVtZW50KSB7XG4gIHJldHVybiBnZXRPd25lckRvY3VtZW50RnJvbVJvb3RDb250YWluZXIocm9vdENvbnRhaW5lckVsZW1lbnQpLmNyZWF0ZVRleHROb2RlKHRleHQpO1xufVxuZnVuY3Rpb24gc2V0SW5pdGlhbFByb3BlcnRpZXMoZG9tRWxlbWVudCwgdGFnLCByYXdQcm9wcywgcm9vdENvbnRhaW5lckVsZW1lbnQpIHtcbiAgdmFyIGlzQ3VzdG9tQ29tcG9uZW50VGFnID0gaXNDdXN0b21Db21wb25lbnQodGFnLCByYXdQcm9wcyk7XG5cbiAge1xuICAgIHZhbGlkYXRlUHJvcGVydGllc0luRGV2ZWxvcG1lbnQodGFnLCByYXdQcm9wcyk7XG4gIH0gLy8gVE9ETzogTWFrZSBzdXJlIHRoYXQgd2UgY2hlY2sgaXNNb3VudGVkIGJlZm9yZSBmaXJpbmcgYW55IG9mIHRoZXNlIGV2ZW50cy5cblxuXG4gIHZhciBwcm9wcztcblxuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgJ2RpYWxvZyc6XG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdjYW5jZWwnLCBkb21FbGVtZW50KTtcbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2Nsb3NlJywgZG9tRWxlbWVudCk7XG4gICAgICBwcm9wcyA9IHJhd1Byb3BzO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdpZnJhbWUnOlxuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgY2FzZSAnZW1iZWQnOlxuICAgICAgLy8gV2UgbGlzdGVuIHRvIHRoaXMgZXZlbnQgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgdGhlIGxvYWQgZXZlbnQuXG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdsb2FkJywgZG9tRWxlbWVudCk7XG4gICAgICBwcm9wcyA9IHJhd1Byb3BzO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICd2aWRlbyc6XG4gICAgY2FzZSAnYXVkaW8nOlxuICAgICAgLy8gV2UgbGlzdGVuIHRvIHRoZXNlIGV2ZW50cyBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciBhbGwgdGhlIG1lZGlhIGV2ZW50cy5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVkaWFFdmVudFR5cGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQobWVkaWFFdmVudFR5cGVzW2ldLCBkb21FbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgcHJvcHMgPSByYXdQcm9wcztcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnc291cmNlJzpcbiAgICAgIC8vIFdlIGxpc3RlbiB0byB0aGlzIGV2ZW50IGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIHRoZSBlcnJvciBldmVudC5cbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2Vycm9yJywgZG9tRWxlbWVudCk7XG4gICAgICBwcm9wcyA9IHJhd1Byb3BzO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdpbWcnOlxuICAgIGNhc2UgJ2ltYWdlJzpcbiAgICBjYXNlICdsaW5rJzpcbiAgICAgIC8vIFdlIGxpc3RlbiB0byB0aGVzZSBldmVudHMgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgZXJyb3IgYW5kIGxvYWQgZXZlbnRzLlxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnZXJyb3InLCBkb21FbGVtZW50KTtcbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2xvYWQnLCBkb21FbGVtZW50KTtcbiAgICAgIHByb3BzID0gcmF3UHJvcHM7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2RldGFpbHMnOlxuICAgICAgLy8gV2UgbGlzdGVuIHRvIHRoaXMgZXZlbnQgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgdGhlIHRvZ2dsZSBldmVudC5cbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ3RvZ2dsZScsIGRvbUVsZW1lbnQpO1xuICAgICAgcHJvcHMgPSByYXdQcm9wcztcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnaW5wdXQnOlxuICAgICAgaW5pdFdyYXBwZXJTdGF0ZShkb21FbGVtZW50LCByYXdQcm9wcyk7XG4gICAgICBwcm9wcyA9IGdldEhvc3RQcm9wcyhkb21FbGVtZW50LCByYXdQcm9wcyk7IC8vIFdlIGxpc3RlbiB0byB0aGlzIGV2ZW50IGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIHRoZSBpbnZhbGlkIGV2ZW50LlxuXG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdpbnZhbGlkJywgZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ29wdGlvbic6XG4gICAgICB2YWxpZGF0ZVByb3BzKGRvbUVsZW1lbnQsIHJhd1Byb3BzKTtcbiAgICAgIHByb3BzID0gcmF3UHJvcHM7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgICBpbml0V3JhcHBlclN0YXRlJDEoZG9tRWxlbWVudCwgcmF3UHJvcHMpO1xuICAgICAgcHJvcHMgPSBnZXRIb3N0UHJvcHMkMShkb21FbGVtZW50LCByYXdQcm9wcyk7IC8vIFdlIGxpc3RlbiB0byB0aGlzIGV2ZW50IGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIHRoZSBpbnZhbGlkIGV2ZW50LlxuXG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdpbnZhbGlkJywgZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3RleHRhcmVhJzpcbiAgICAgIGluaXRXcmFwcGVyU3RhdGUkMihkb21FbGVtZW50LCByYXdQcm9wcyk7XG4gICAgICBwcm9wcyA9IGdldEhvc3RQcm9wcyQyKGRvbUVsZW1lbnQsIHJhd1Byb3BzKTsgLy8gV2UgbGlzdGVuIHRvIHRoaXMgZXZlbnQgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgdGhlIGludmFsaWQgZXZlbnQuXG5cbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2ludmFsaWQnLCBkb21FbGVtZW50KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHByb3BzID0gcmF3UHJvcHM7XG4gIH1cblxuICBhc3NlcnRWYWxpZFByb3BzKHRhZywgcHJvcHMpO1xuICBzZXRJbml0aWFsRE9NUHJvcGVydGllcyh0YWcsIGRvbUVsZW1lbnQsIHJvb3RDb250YWluZXJFbGVtZW50LCBwcm9wcywgaXNDdXN0b21Db21wb25lbnRUYWcpO1xuXG4gIHN3aXRjaCAodGFnKSB7XG4gICAgY2FzZSAnaW5wdXQnOlxuICAgICAgLy8gVE9ETzogTWFrZSBzdXJlIHdlIGNoZWNrIGlmIHRoaXMgaXMgc3RpbGwgdW5tb3VudGVkIG9yIGRvIGFueSBjbGVhblxuICAgICAgLy8gdXAgbmVjZXNzYXJ5IHNpbmNlIHdlIG5ldmVyIHN0b3AgdHJhY2tpbmcgYW55bW9yZS5cbiAgICAgIHRyYWNrKGRvbUVsZW1lbnQpO1xuICAgICAgcG9zdE1vdW50V3JhcHBlcihkb21FbGVtZW50LCByYXdQcm9wcywgZmFsc2UpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICAvLyBUT0RPOiBNYWtlIHN1cmUgd2UgY2hlY2sgaWYgdGhpcyBpcyBzdGlsbCB1bm1vdW50ZWQgb3IgZG8gYW55IGNsZWFuXG4gICAgICAvLyB1cCBuZWNlc3Nhcnkgc2luY2Ugd2UgbmV2ZXIgc3RvcCB0cmFja2luZyBhbnltb3JlLlxuICAgICAgdHJhY2soZG9tRWxlbWVudCk7XG4gICAgICBwb3N0TW91bnRXcmFwcGVyJDMoZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ29wdGlvbic6XG4gICAgICBwb3N0TW91bnRXcmFwcGVyJDEoZG9tRWxlbWVudCwgcmF3UHJvcHMpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgcG9zdE1vdW50V3JhcHBlciQyKGRvbUVsZW1lbnQsIHJhd1Byb3BzKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIGlmICh0eXBlb2YgcHJvcHMub25DbGljayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBUT0RPOiBUaGlzIGNhc3QgbWF5IG5vdCBiZSBzb3VuZCBmb3IgU1ZHLCBNYXRoTUwgb3IgY3VzdG9tIGVsZW1lbnRzLlxuICAgICAgICB0cmFwQ2xpY2tPbk5vbkludGVyYWN0aXZlRWxlbWVudChkb21FbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG4gIH1cbn0gLy8gQ2FsY3VsYXRlIHRoZSBkaWZmIGJldHdlZW4gdGhlIHR3byBvYmplY3RzLlxuXG5mdW5jdGlvbiBkaWZmUHJvcGVydGllcyhkb21FbGVtZW50LCB0YWcsIGxhc3RSYXdQcm9wcywgbmV4dFJhd1Byb3BzLCByb290Q29udGFpbmVyRWxlbWVudCkge1xuICB7XG4gICAgdmFsaWRhdGVQcm9wZXJ0aWVzSW5EZXZlbG9wbWVudCh0YWcsIG5leHRSYXdQcm9wcyk7XG4gIH1cblxuICB2YXIgdXBkYXRlUGF5bG9hZCA9IG51bGw7XG4gIHZhciBsYXN0UHJvcHM7XG4gIHZhciBuZXh0UHJvcHM7XG5cbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlICdpbnB1dCc6XG4gICAgICBsYXN0UHJvcHMgPSBnZXRIb3N0UHJvcHMoZG9tRWxlbWVudCwgbGFzdFJhd1Byb3BzKTtcbiAgICAgIG5leHRQcm9wcyA9IGdldEhvc3RQcm9wcyhkb21FbGVtZW50LCBuZXh0UmF3UHJvcHMpO1xuICAgICAgdXBkYXRlUGF5bG9hZCA9IFtdO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgbGFzdFByb3BzID0gZ2V0SG9zdFByb3BzJDEoZG9tRWxlbWVudCwgbGFzdFJhd1Byb3BzKTtcbiAgICAgIG5leHRQcm9wcyA9IGdldEhvc3RQcm9wcyQxKGRvbUVsZW1lbnQsIG5leHRSYXdQcm9wcyk7XG4gICAgICB1cGRhdGVQYXlsb2FkID0gW107XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3RleHRhcmVhJzpcbiAgICAgIGxhc3RQcm9wcyA9IGdldEhvc3RQcm9wcyQyKGRvbUVsZW1lbnQsIGxhc3RSYXdQcm9wcyk7XG4gICAgICBuZXh0UHJvcHMgPSBnZXRIb3N0UHJvcHMkMihkb21FbGVtZW50LCBuZXh0UmF3UHJvcHMpO1xuICAgICAgdXBkYXRlUGF5bG9hZCA9IFtdO1xuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgbGFzdFByb3BzID0gbGFzdFJhd1Byb3BzO1xuICAgICAgbmV4dFByb3BzID0gbmV4dFJhd1Byb3BzO1xuXG4gICAgICBpZiAodHlwZW9mIGxhc3RQcm9wcy5vbkNsaWNrICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBuZXh0UHJvcHMub25DbGljayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBUT0RPOiBUaGlzIGNhc3QgbWF5IG5vdCBiZSBzb3VuZCBmb3IgU1ZHLCBNYXRoTUwgb3IgY3VzdG9tIGVsZW1lbnRzLlxuICAgICAgICB0cmFwQ2xpY2tPbk5vbkludGVyYWN0aXZlRWxlbWVudChkb21FbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG4gIH1cblxuICBhc3NlcnRWYWxpZFByb3BzKHRhZywgbmV4dFByb3BzKTtcbiAgdmFyIHByb3BLZXk7XG4gIHZhciBzdHlsZU5hbWU7XG4gIHZhciBzdHlsZVVwZGF0ZXMgPSBudWxsO1xuXG4gIGZvciAocHJvcEtleSBpbiBsYXN0UHJvcHMpIHtcbiAgICBpZiAobmV4dFByb3BzLmhhc093blByb3BlcnR5KHByb3BLZXkpIHx8ICFsYXN0UHJvcHMuaGFzT3duUHJvcGVydHkocHJvcEtleSkgfHwgbGFzdFByb3BzW3Byb3BLZXldID09IG51bGwpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChwcm9wS2V5ID09PSBTVFlMRSkge1xuICAgICAgdmFyIGxhc3RTdHlsZSA9IGxhc3RQcm9wc1twcm9wS2V5XTtcblxuICAgICAgZm9yIChzdHlsZU5hbWUgaW4gbGFzdFN0eWxlKSB7XG4gICAgICAgIGlmIChsYXN0U3R5bGUuaGFzT3duUHJvcGVydHkoc3R5bGVOYW1lKSkge1xuICAgICAgICAgIGlmICghc3R5bGVVcGRhdGVzKSB7XG4gICAgICAgICAgICBzdHlsZVVwZGF0ZXMgPSB7fTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzdHlsZVVwZGF0ZXNbc3R5bGVOYW1lXSA9ICcnO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwcm9wS2V5ID09PSBEQU5HRVJPVVNMWV9TRVRfSU5ORVJfSFRNTCB8fCBwcm9wS2V5ID09PSBDSElMRFJFTikgOyBlbHNlIGlmIChwcm9wS2V5ID09PSBTVVBQUkVTU19DT05URU5UX0VESVRBQkxFX1dBUk5JTkcgfHwgcHJvcEtleSA9PT0gU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkcpIDsgZWxzZSBpZiAocHJvcEtleSA9PT0gQVVUT0ZPQ1VTKSA7IGVsc2UgaWYgKHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkocHJvcEtleSkpIHtcbiAgICAgIC8vIFRoaXMgaXMgYSBzcGVjaWFsIGNhc2UuIElmIGFueSBsaXN0ZW5lciB1cGRhdGVzIHdlIG5lZWQgdG8gZW5zdXJlXG4gICAgICAvLyB0aGF0IHRoZSBcImN1cnJlbnRcIiBmaWJlciBwb2ludGVyIGdldHMgdXBkYXRlZCBzbyB3ZSBuZWVkIGEgY29tbWl0XG4gICAgICAvLyB0byB1cGRhdGUgdGhpcyBlbGVtZW50LlxuICAgICAgaWYgKCF1cGRhdGVQYXlsb2FkKSB7XG4gICAgICAgIHVwZGF0ZVBheWxvYWQgPSBbXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRm9yIGFsbCBvdGhlciBkZWxldGVkIHByb3BlcnRpZXMgd2UgYWRkIGl0IHRvIHRoZSBxdWV1ZS4gV2UgdXNlXG4gICAgICAvLyB0aGUgYWxsb3dlZCBwcm9wZXJ0eSBsaXN0IGluIHRoZSBjb21taXQgcGhhc2UgaW5zdGVhZC5cbiAgICAgICh1cGRhdGVQYXlsb2FkID0gdXBkYXRlUGF5bG9hZCB8fCBbXSkucHVzaChwcm9wS2V5LCBudWxsKTtcbiAgICB9XG4gIH1cblxuICBmb3IgKHByb3BLZXkgaW4gbmV4dFByb3BzKSB7XG4gICAgdmFyIG5leHRQcm9wID0gbmV4dFByb3BzW3Byb3BLZXldO1xuICAgIHZhciBsYXN0UHJvcCA9IGxhc3RQcm9wcyAhPSBudWxsID8gbGFzdFByb3BzW3Byb3BLZXldIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKCFuZXh0UHJvcHMuaGFzT3duUHJvcGVydHkocHJvcEtleSkgfHwgbmV4dFByb3AgPT09IGxhc3RQcm9wIHx8IG5leHRQcm9wID09IG51bGwgJiYgbGFzdFByb3AgPT0gbnVsbCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHByb3BLZXkgPT09IFNUWUxFKSB7XG4gICAgICB7XG4gICAgICAgIGlmIChuZXh0UHJvcCkge1xuICAgICAgICAgIC8vIEZyZWV6ZSB0aGUgbmV4dCBzdHlsZSBvYmplY3Qgc28gdGhhdCB3ZSBjYW4gYXNzdW1lIGl0IHdvbid0IGJlXG4gICAgICAgICAgLy8gbXV0YXRlZC4gV2UgaGF2ZSBhbHJlYWR5IHdhcm5lZCBmb3IgdGhpcyBpbiB0aGUgcGFzdC5cbiAgICAgICAgICBPYmplY3QuZnJlZXplKG5leHRQcm9wKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAobGFzdFByb3ApIHtcbiAgICAgICAgLy8gVW5zZXQgc3R5bGVzIG9uIGBsYXN0UHJvcGAgYnV0IG5vdCBvbiBgbmV4dFByb3BgLlxuICAgICAgICBmb3IgKHN0eWxlTmFtZSBpbiBsYXN0UHJvcCkge1xuICAgICAgICAgIGlmIChsYXN0UHJvcC5oYXNPd25Qcm9wZXJ0eShzdHlsZU5hbWUpICYmICghbmV4dFByb3AgfHwgIW5leHRQcm9wLmhhc093blByb3BlcnR5KHN0eWxlTmFtZSkpKSB7XG4gICAgICAgICAgICBpZiAoIXN0eWxlVXBkYXRlcykge1xuICAgICAgICAgICAgICBzdHlsZVVwZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc3R5bGVVcGRhdGVzW3N0eWxlTmFtZV0gPSAnJztcbiAgICAgICAgICB9XG4gICAgICAgIH0gLy8gVXBkYXRlIHN0eWxlcyB0aGF0IGNoYW5nZWQgc2luY2UgYGxhc3RQcm9wYC5cblxuXG4gICAgICAgIGZvciAoc3R5bGVOYW1lIGluIG5leHRQcm9wKSB7XG4gICAgICAgICAgaWYgKG5leHRQcm9wLmhhc093blByb3BlcnR5KHN0eWxlTmFtZSkgJiYgbGFzdFByb3Bbc3R5bGVOYW1lXSAhPT0gbmV4dFByb3Bbc3R5bGVOYW1lXSkge1xuICAgICAgICAgICAgaWYgKCFzdHlsZVVwZGF0ZXMpIHtcbiAgICAgICAgICAgICAgc3R5bGVVcGRhdGVzID0ge307XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0eWxlVXBkYXRlc1tzdHlsZU5hbWVdID0gbmV4dFByb3Bbc3R5bGVOYW1lXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFJlbGllcyBvbiBgdXBkYXRlU3R5bGVzQnlJRGAgbm90IG11dGF0aW5nIGBzdHlsZVVwZGF0ZXNgLlxuICAgICAgICBpZiAoIXN0eWxlVXBkYXRlcykge1xuICAgICAgICAgIGlmICghdXBkYXRlUGF5bG9hZCkge1xuICAgICAgICAgICAgdXBkYXRlUGF5bG9hZCA9IFtdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHVwZGF0ZVBheWxvYWQucHVzaChwcm9wS2V5LCBzdHlsZVVwZGF0ZXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3R5bGVVcGRhdGVzID0gbmV4dFByb3A7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwcm9wS2V5ID09PSBEQU5HRVJPVVNMWV9TRVRfSU5ORVJfSFRNTCkge1xuICAgICAgdmFyIG5leHRIdG1sID0gbmV4dFByb3AgPyBuZXh0UHJvcFtIVE1MJDFdIDogdW5kZWZpbmVkO1xuICAgICAgdmFyIGxhc3RIdG1sID0gbGFzdFByb3AgPyBsYXN0UHJvcFtIVE1MJDFdIDogdW5kZWZpbmVkO1xuXG4gICAgICBpZiAobmV4dEh0bWwgIT0gbnVsbCkge1xuICAgICAgICBpZiAobGFzdEh0bWwgIT09IG5leHRIdG1sKSB7XG4gICAgICAgICAgKHVwZGF0ZVBheWxvYWQgPSB1cGRhdGVQYXlsb2FkIHx8IFtdKS5wdXNoKHByb3BLZXksIG5leHRIdG1sKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocHJvcEtleSA9PT0gQ0hJTERSRU4pIHtcbiAgICAgIGlmICh0eXBlb2YgbmV4dFByb3AgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBuZXh0UHJvcCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgKHVwZGF0ZVBheWxvYWQgPSB1cGRhdGVQYXlsb2FkIHx8IFtdKS5wdXNoKHByb3BLZXksICcnICsgbmV4dFByb3ApO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocHJvcEtleSA9PT0gU1VQUFJFU1NfQ09OVEVOVF9FRElUQUJMRV9XQVJOSU5HIHx8IHByb3BLZXkgPT09IFNVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HKSA7IGVsc2UgaWYgKHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkocHJvcEtleSkpIHtcbiAgICAgIGlmIChuZXh0UHJvcCAhPSBudWxsKSB7XG4gICAgICAgIC8vIFdlIGVhZ2VybHkgbGlzdGVuIHRvIHRoaXMgZXZlbiB0aG91Z2ggd2UgaGF2ZW4ndCBjb21taXR0ZWQgeWV0LlxuICAgICAgICBpZiAoIHR5cGVvZiBuZXh0UHJvcCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHdhcm5Gb3JJbnZhbGlkRXZlbnRMaXN0ZW5lcihwcm9wS2V5LCBuZXh0UHJvcCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHJvcEtleSA9PT0gJ29uU2Nyb2xsJykge1xuICAgICAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ3Njcm9sbCcsIGRvbUVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghdXBkYXRlUGF5bG9hZCAmJiBsYXN0UHJvcCAhPT0gbmV4dFByb3ApIHtcbiAgICAgICAgLy8gVGhpcyBpcyBhIHNwZWNpYWwgY2FzZS4gSWYgYW55IGxpc3RlbmVyIHVwZGF0ZXMgd2UgbmVlZCB0byBlbnN1cmVcbiAgICAgICAgLy8gdGhhdCB0aGUgXCJjdXJyZW50XCIgcHJvcHMgcG9pbnRlciBnZXRzIHVwZGF0ZWQgc28gd2UgbmVlZCBhIGNvbW1pdFxuICAgICAgICAvLyB0byB1cGRhdGUgdGhpcyBlbGVtZW50LlxuICAgICAgICB1cGRhdGVQYXlsb2FkID0gW107XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZvciBhbnkgb3RoZXIgcHJvcGVydHkgd2UgYWx3YXlzIGFkZCBpdCB0byB0aGUgcXVldWUgYW5kIHRoZW4gd2VcbiAgICAgIC8vIGZpbHRlciBpdCBvdXQgdXNpbmcgdGhlIGFsbG93ZWQgcHJvcGVydHkgbGlzdCBkdXJpbmcgdGhlIGNvbW1pdC5cbiAgICAgICh1cGRhdGVQYXlsb2FkID0gdXBkYXRlUGF5bG9hZCB8fCBbXSkucHVzaChwcm9wS2V5LCBuZXh0UHJvcCk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHN0eWxlVXBkYXRlcykge1xuICAgIHtcbiAgICAgIHZhbGlkYXRlU2hvcnRoYW5kUHJvcGVydHlDb2xsaXNpb25JbkRldihzdHlsZVVwZGF0ZXMsIG5leHRQcm9wc1tTVFlMRV0pO1xuICAgIH1cblxuICAgICh1cGRhdGVQYXlsb2FkID0gdXBkYXRlUGF5bG9hZCB8fCBbXSkucHVzaChTVFlMRSwgc3R5bGVVcGRhdGVzKTtcbiAgfVxuXG4gIHJldHVybiB1cGRhdGVQYXlsb2FkO1xufSAvLyBBcHBseSB0aGUgZGlmZi5cblxuZnVuY3Rpb24gdXBkYXRlUHJvcGVydGllcyhkb21FbGVtZW50LCB1cGRhdGVQYXlsb2FkLCB0YWcsIGxhc3RSYXdQcm9wcywgbmV4dFJhd1Byb3BzKSB7XG4gIC8vIFVwZGF0ZSBjaGVja2VkICpiZWZvcmUqIG5hbWUuXG4gIC8vIEluIHRoZSBtaWRkbGUgb2YgYW4gdXBkYXRlLCBpdCBpcyBwb3NzaWJsZSB0byBoYXZlIG11bHRpcGxlIGNoZWNrZWQuXG4gIC8vIFdoZW4gYSBjaGVja2VkIHJhZGlvIHRyaWVzIHRvIGNoYW5nZSBuYW1lLCBicm93c2VyIG1ha2VzIGFub3RoZXIgcmFkaW8ncyBjaGVja2VkIGZhbHNlLlxuICBpZiAodGFnID09PSAnaW5wdXQnICYmIG5leHRSYXdQcm9wcy50eXBlID09PSAncmFkaW8nICYmIG5leHRSYXdQcm9wcy5uYW1lICE9IG51bGwpIHtcbiAgICB1cGRhdGVDaGVja2VkKGRvbUVsZW1lbnQsIG5leHRSYXdQcm9wcyk7XG4gIH1cblxuICB2YXIgd2FzQ3VzdG9tQ29tcG9uZW50VGFnID0gaXNDdXN0b21Db21wb25lbnQodGFnLCBsYXN0UmF3UHJvcHMpO1xuICB2YXIgaXNDdXN0b21Db21wb25lbnRUYWcgPSBpc0N1c3RvbUNvbXBvbmVudCh0YWcsIG5leHRSYXdQcm9wcyk7IC8vIEFwcGx5IHRoZSBkaWZmLlxuXG4gIHVwZGF0ZURPTVByb3BlcnRpZXMoZG9tRWxlbWVudCwgdXBkYXRlUGF5bG9hZCwgd2FzQ3VzdG9tQ29tcG9uZW50VGFnLCBpc0N1c3RvbUNvbXBvbmVudFRhZyk7IC8vIFRPRE86IEVuc3VyZSB0aGF0IGFuIHVwZGF0ZSBnZXRzIHNjaGVkdWxlZCBpZiBhbnkgb2YgdGhlIHNwZWNpYWwgcHJvcHNcbiAgLy8gY2hhbmdlZC5cblxuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgJ2lucHV0JzpcbiAgICAgIC8vIFVwZGF0ZSB0aGUgd3JhcHBlciBhcm91bmQgaW5wdXRzICphZnRlciogdXBkYXRpbmcgcHJvcHMuIFRoaXMgaGFzIHRvXG4gICAgICAvLyBoYXBwZW4gYWZ0ZXIgYHVwZGF0ZURPTVByb3BlcnRpZXNgLiBPdGhlcndpc2UgSFRNTDUgaW5wdXQgdmFsaWRhdGlvbnNcbiAgICAgIC8vIHJhaXNlIHdhcm5pbmdzIGFuZCBwcmV2ZW50IHRoZSBuZXcgdmFsdWUgZnJvbSBiZWluZyBhc3NpZ25lZC5cbiAgICAgIHVwZGF0ZVdyYXBwZXIoZG9tRWxlbWVudCwgbmV4dFJhd1Byb3BzKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAndGV4dGFyZWEnOlxuICAgICAgdXBkYXRlV3JhcHBlciQxKGRvbUVsZW1lbnQsIG5leHRSYXdQcm9wcyk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgICAvLyA8c2VsZWN0PiB2YWx1ZSB1cGRhdGUgbmVlZHMgdG8gb2NjdXIgYWZ0ZXIgPG9wdGlvbj4gY2hpbGRyZW5cbiAgICAgIC8vIHJlY29uY2lsaWF0aW9uXG4gICAgICBwb3N0VXBkYXRlV3JhcHBlcihkb21FbGVtZW50LCBuZXh0UmF3UHJvcHMpO1xuICAgICAgYnJlYWs7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0UG9zc2libGVTdGFuZGFyZE5hbWUocHJvcE5hbWUpIHtcbiAge1xuICAgIHZhciBsb3dlckNhc2VkTmFtZSA9IHByb3BOYW1lLnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAoIXBvc3NpYmxlU3RhbmRhcmROYW1lcy5oYXNPd25Qcm9wZXJ0eShsb3dlckNhc2VkTmFtZSkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBwb3NzaWJsZVN0YW5kYXJkTmFtZXNbbG93ZXJDYXNlZE5hbWVdIHx8IG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGlmZkh5ZHJhdGVkUHJvcGVydGllcyhkb21FbGVtZW50LCB0YWcsIHJhd1Byb3BzLCBwYXJlbnROYW1lc3BhY2UsIHJvb3RDb250YWluZXJFbGVtZW50LCBpc0NvbmN1cnJlbnRNb2RlLCBzaG91bGRXYXJuRGV2KSB7XG4gIHZhciBpc0N1c3RvbUNvbXBvbmVudFRhZztcbiAgdmFyIGV4dHJhQXR0cmlidXRlTmFtZXM7XG5cbiAge1xuICAgIGlzQ3VzdG9tQ29tcG9uZW50VGFnID0gaXNDdXN0b21Db21wb25lbnQodGFnLCByYXdQcm9wcyk7XG4gICAgdmFsaWRhdGVQcm9wZXJ0aWVzSW5EZXZlbG9wbWVudCh0YWcsIHJhd1Byb3BzKTtcbiAgfSAvLyBUT0RPOiBNYWtlIHN1cmUgdGhhdCB3ZSBjaGVjayBpc01vdW50ZWQgYmVmb3JlIGZpcmluZyBhbnkgb2YgdGhlc2UgZXZlbnRzLlxuXG5cbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlICdkaWFsb2cnOlxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnY2FuY2VsJywgZG9tRWxlbWVudCk7XG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdjbG9zZScsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdpZnJhbWUnOlxuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgY2FzZSAnZW1iZWQnOlxuICAgICAgLy8gV2UgbGlzdGVuIHRvIHRoaXMgZXZlbnQgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgdGhlIGxvYWQgZXZlbnQuXG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdsb2FkJywgZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3ZpZGVvJzpcbiAgICBjYXNlICdhdWRpbyc6XG4gICAgICAvLyBXZSBsaXN0ZW4gdG8gdGhlc2UgZXZlbnRzIGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIGFsbCB0aGUgbWVkaWEgZXZlbnRzLlxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZWRpYUV2ZW50VHlwZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudChtZWRpYUV2ZW50VHlwZXNbaV0sIGRvbUVsZW1lbnQpO1xuICAgICAgfVxuXG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3NvdXJjZSc6XG4gICAgICAvLyBXZSBsaXN0ZW4gdG8gdGhpcyBldmVudCBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciB0aGUgZXJyb3IgZXZlbnQuXG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdlcnJvcicsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdpbWcnOlxuICAgIGNhc2UgJ2ltYWdlJzpcbiAgICBjYXNlICdsaW5rJzpcbiAgICAgIC8vIFdlIGxpc3RlbiB0byB0aGVzZSBldmVudHMgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgZXJyb3IgYW5kIGxvYWQgZXZlbnRzLlxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnZXJyb3InLCBkb21FbGVtZW50KTtcbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2xvYWQnLCBkb21FbGVtZW50KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnZGV0YWlscyc6XG4gICAgICAvLyBXZSBsaXN0ZW4gdG8gdGhpcyBldmVudCBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciB0aGUgdG9nZ2xlIGV2ZW50LlxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgndG9nZ2xlJywgZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2lucHV0JzpcbiAgICAgIGluaXRXcmFwcGVyU3RhdGUoZG9tRWxlbWVudCwgcmF3UHJvcHMpOyAvLyBXZSBsaXN0ZW4gdG8gdGhpcyBldmVudCBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciB0aGUgaW52YWxpZCBldmVudC5cblxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnaW52YWxpZCcsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdvcHRpb24nOlxuICAgICAgdmFsaWRhdGVQcm9wcyhkb21FbGVtZW50LCByYXdQcm9wcyk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgICBpbml0V3JhcHBlclN0YXRlJDEoZG9tRWxlbWVudCwgcmF3UHJvcHMpOyAvLyBXZSBsaXN0ZW4gdG8gdGhpcyBldmVudCBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciB0aGUgaW52YWxpZCBldmVudC5cblxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnaW52YWxpZCcsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICBpbml0V3JhcHBlclN0YXRlJDIoZG9tRWxlbWVudCwgcmF3UHJvcHMpOyAvLyBXZSBsaXN0ZW4gdG8gdGhpcyBldmVudCBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciB0aGUgaW52YWxpZCBldmVudC5cblxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnaW52YWxpZCcsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG4gIH1cblxuICBhc3NlcnRWYWxpZFByb3BzKHRhZywgcmF3UHJvcHMpO1xuXG4gIHtcbiAgICBleHRyYUF0dHJpYnV0ZU5hbWVzID0gbmV3IFNldCgpO1xuICAgIHZhciBhdHRyaWJ1dGVzID0gZG9tRWxlbWVudC5hdHRyaWJ1dGVzO1xuXG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICB2YXIgbmFtZSA9IGF0dHJpYnV0ZXNbX2ldLm5hbWUudG9Mb3dlckNhc2UoKTtcblxuICAgICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICAgIC8vIENvbnRyb2xsZWQgYXR0cmlidXRlcyBhcmUgbm90IHZhbGlkYXRlZFxuICAgICAgICAvLyBUT0RPOiBPbmx5IGlnbm9yZSB0aGVtIG9uIGNvbnRyb2xsZWQgdGFncy5cbiAgICAgICAgY2FzZSAndmFsdWUnOlxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ2NoZWNrZWQnOlxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ3NlbGVjdGVkJzpcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8vIEludGVudGlvbmFsbHkgdXNlIHRoZSBvcmlnaW5hbCBuYW1lLlxuICAgICAgICAgIC8vIFNlZSBkaXNjdXNzaW9uIGluIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzEwNjc2LlxuICAgICAgICAgIGV4dHJhQXR0cmlidXRlTmFtZXMuYWRkKGF0dHJpYnV0ZXNbX2ldLm5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciB1cGRhdGVQYXlsb2FkID0gbnVsbDtcblxuICBmb3IgKHZhciBwcm9wS2V5IGluIHJhd1Byb3BzKSB7XG4gICAgaWYgKCFyYXdQcm9wcy5oYXNPd25Qcm9wZXJ0eShwcm9wS2V5KSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIG5leHRQcm9wID0gcmF3UHJvcHNbcHJvcEtleV07XG5cbiAgICBpZiAocHJvcEtleSA9PT0gQ0hJTERSRU4pIHtcbiAgICAgIC8vIEZvciB0ZXh0IGNvbnRlbnQgY2hpbGRyZW4gd2UgY29tcGFyZSBhZ2FpbnN0IHRleHRDb250ZW50LiBUaGlzXG4gICAgICAvLyBtaWdodCBtYXRjaCBhZGRpdGlvbmFsIEhUTUwgdGhhdCBpcyBoaWRkZW4gd2hlbiB3ZSByZWFkIGl0IHVzaW5nXG4gICAgICAvLyB0ZXh0Q29udGVudC4gRS5nLiBcImZvb1wiIHdpbGwgbWF0Y2ggXCJmPHNwYW4+b288L3NwYW4+XCIgYnV0IHRoYXQgc3RpbGxcbiAgICAgIC8vIHNhdGlzZmllcyBvdXIgcmVxdWlyZW1lbnQuIE91ciByZXF1aXJlbWVudCBpcyBub3QgdG8gcHJvZHVjZSBwZXJmZWN0XG4gICAgICAvLyBIVE1MIGFuZCBhdHRyaWJ1dGVzLiBJZGVhbGx5IHdlIHNob3VsZCBwcmVzZXJ2ZSBzdHJ1Y3R1cmUgYnV0IGl0J3NcbiAgICAgIC8vIG9rIG5vdCB0byBpZiB0aGUgdmlzaWJsZSBjb250ZW50IGlzIHN0aWxsIGVub3VnaCB0byBpbmRpY2F0ZSB3aGF0XG4gICAgICAvLyBldmVuIGxpc3RlbmVycyB0aGVzZSBub2RlcyBtaWdodCBiZSB3aXJlZCB1cCB0by5cbiAgICAgIC8vIFRPRE86IFdhcm4gaWYgdGhlcmUgaXMgbW9yZSB0aGFuIGEgc2luZ2xlIHRleHROb2RlIGFzIGEgY2hpbGQuXG4gICAgICAvLyBUT0RPOiBTaG91bGQgd2UgdXNlIGRvbUVsZW1lbnQuZmlyc3RDaGlsZC5ub2RlVmFsdWUgdG8gY29tcGFyZT9cbiAgICAgIGlmICh0eXBlb2YgbmV4dFByb3AgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmIChkb21FbGVtZW50LnRleHRDb250ZW50ICE9PSBuZXh0UHJvcCkge1xuICAgICAgICAgIGlmIChyYXdQcm9wc1tTVVBQUkVTU19IWURSQVRJT05fV0FSTklOR10gIT09IHRydWUpIHtcbiAgICAgICAgICAgIGNoZWNrRm9yVW5tYXRjaGVkVGV4dChkb21FbGVtZW50LnRleHRDb250ZW50LCBuZXh0UHJvcCwgaXNDb25jdXJyZW50TW9kZSwgc2hvdWxkV2FybkRldik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdXBkYXRlUGF5bG9hZCA9IFtDSElMRFJFTiwgbmV4dFByb3BdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBuZXh0UHJvcCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgaWYgKGRvbUVsZW1lbnQudGV4dENvbnRlbnQgIT09ICcnICsgbmV4dFByb3ApIHtcbiAgICAgICAgICBpZiAocmF3UHJvcHNbU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkddICE9PSB0cnVlKSB7XG4gICAgICAgICAgICBjaGVja0ZvclVubWF0Y2hlZFRleHQoZG9tRWxlbWVudC50ZXh0Q29udGVudCwgbmV4dFByb3AsIGlzQ29uY3VycmVudE1vZGUsIHNob3VsZFdhcm5EZXYpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHVwZGF0ZVBheWxvYWQgPSBbQ0hJTERSRU4sICcnICsgbmV4dFByb3BdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChyZWdpc3RyYXRpb25OYW1lRGVwZW5kZW5jaWVzLmhhc093blByb3BlcnR5KHByb3BLZXkpKSB7XG4gICAgICBpZiAobmV4dFByb3AgIT0gbnVsbCkge1xuICAgICAgICBpZiAoIHR5cGVvZiBuZXh0UHJvcCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHdhcm5Gb3JJbnZhbGlkRXZlbnRMaXN0ZW5lcihwcm9wS2V5LCBuZXh0UHJvcCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHJvcEtleSA9PT0gJ29uU2Nyb2xsJykge1xuICAgICAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ3Njcm9sbCcsIGRvbUVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzaG91bGRXYXJuRGV2ICYmIHRydWUgJiYgLy8gQ29udmluY2UgRmxvdyB3ZSd2ZSBjYWxjdWxhdGVkIGl0IChpdCdzIERFVi1vbmx5IGluIHRoaXMgbWV0aG9kLilcbiAgICB0eXBlb2YgaXNDdXN0b21Db21wb25lbnRUYWcgPT09ICdib29sZWFuJykge1xuICAgICAgLy8gVmFsaWRhdGUgdGhhdCB0aGUgcHJvcGVydGllcyBjb3JyZXNwb25kIHRvIHRoZWlyIGV4cGVjdGVkIHZhbHVlcy5cbiAgICAgIHZhciBzZXJ2ZXJWYWx1ZSA9IHZvaWQgMDtcbiAgICAgIHZhciBwcm9wZXJ0eUluZm8gPSBpc0N1c3RvbUNvbXBvbmVudFRhZyAmJiBlbmFibGVDdXN0b21FbGVtZW50UHJvcGVydHlTdXBwb3J0ID8gbnVsbCA6IGdldFByb3BlcnR5SW5mbyhwcm9wS2V5KTtcblxuICAgICAgaWYgKHJhd1Byb3BzW1NVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HXSA9PT0gdHJ1ZSkgOyBlbHNlIGlmIChwcm9wS2V5ID09PSBTVVBQUkVTU19DT05URU5UX0VESVRBQkxFX1dBUk5JTkcgfHwgcHJvcEtleSA9PT0gU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkcgfHwgLy8gQ29udHJvbGxlZCBhdHRyaWJ1dGVzIGFyZSBub3QgdmFsaWRhdGVkXG4gICAgICAvLyBUT0RPOiBPbmx5IGlnbm9yZSB0aGVtIG9uIGNvbnRyb2xsZWQgdGFncy5cbiAgICAgIHByb3BLZXkgPT09ICd2YWx1ZScgfHwgcHJvcEtleSA9PT0gJ2NoZWNrZWQnIHx8IHByb3BLZXkgPT09ICdzZWxlY3RlZCcpIDsgZWxzZSBpZiAocHJvcEtleSA9PT0gREFOR0VST1VTTFlfU0VUX0lOTkVSX0hUTUwpIHtcbiAgICAgICAgdmFyIHNlcnZlckhUTUwgPSBkb21FbGVtZW50LmlubmVySFRNTDtcbiAgICAgICAgdmFyIG5leHRIdG1sID0gbmV4dFByb3AgPyBuZXh0UHJvcFtIVE1MJDFdIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmIChuZXh0SHRtbCAhPSBudWxsKSB7XG4gICAgICAgICAgdmFyIGV4cGVjdGVkSFRNTCA9IG5vcm1hbGl6ZUhUTUwoZG9tRWxlbWVudCwgbmV4dEh0bWwpO1xuXG4gICAgICAgICAgaWYgKGV4cGVjdGVkSFRNTCAhPT0gc2VydmVySFRNTCkge1xuICAgICAgICAgICAgd2FybkZvclByb3BEaWZmZXJlbmNlKHByb3BLZXksIHNlcnZlckhUTUwsIGV4cGVjdGVkSFRNTCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHByb3BLZXkgPT09IFNUWUxFKSB7XG4gICAgICAgIC8vICRGbG93Rml4TWUgLSBTaG91bGQgYmUgaW5mZXJyZWQgYXMgbm90IHVuZGVmaW5lZC5cbiAgICAgICAgZXh0cmFBdHRyaWJ1dGVOYW1lcy5kZWxldGUocHJvcEtleSk7XG5cbiAgICAgICAgaWYgKGNhbkRpZmZTdHlsZUZvckh5ZHJhdGlvbldhcm5pbmcpIHtcbiAgICAgICAgICB2YXIgZXhwZWN0ZWRTdHlsZSA9IGNyZWF0ZURhbmdlcm91c1N0cmluZ0ZvclN0eWxlcyhuZXh0UHJvcCk7XG4gICAgICAgICAgc2VydmVyVmFsdWUgPSBkb21FbGVtZW50LmdldEF0dHJpYnV0ZSgnc3R5bGUnKTtcblxuICAgICAgICAgIGlmIChleHBlY3RlZFN0eWxlICE9PSBzZXJ2ZXJWYWx1ZSkge1xuICAgICAgICAgICAgd2FybkZvclByb3BEaWZmZXJlbmNlKHByb3BLZXksIHNlcnZlclZhbHVlLCBleHBlY3RlZFN0eWxlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNDdXN0b21Db21wb25lbnRUYWcgJiYgIWVuYWJsZUN1c3RvbUVsZW1lbnRQcm9wZXJ0eVN1cHBvcnQpIHtcbiAgICAgICAgLy8gJEZsb3dGaXhNZSAtIFNob3VsZCBiZSBpbmZlcnJlZCBhcyBub3QgdW5kZWZpbmVkLlxuICAgICAgICBleHRyYUF0dHJpYnV0ZU5hbWVzLmRlbGV0ZShwcm9wS2V5LnRvTG93ZXJDYXNlKCkpO1xuICAgICAgICBzZXJ2ZXJWYWx1ZSA9IGdldFZhbHVlRm9yQXR0cmlidXRlKGRvbUVsZW1lbnQsIHByb3BLZXksIG5leHRQcm9wKTtcblxuICAgICAgICBpZiAobmV4dFByb3AgIT09IHNlcnZlclZhbHVlKSB7XG4gICAgICAgICAgd2FybkZvclByb3BEaWZmZXJlbmNlKHByb3BLZXksIHNlcnZlclZhbHVlLCBuZXh0UHJvcCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIXNob3VsZElnbm9yZUF0dHJpYnV0ZShwcm9wS2V5LCBwcm9wZXJ0eUluZm8sIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSAmJiAhc2hvdWxkUmVtb3ZlQXR0cmlidXRlKHByb3BLZXksIG5leHRQcm9wLCBwcm9wZXJ0eUluZm8sIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSkge1xuICAgICAgICB2YXIgaXNNaXNtYXRjaER1ZVRvQmFkQ2FzaW5nID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHByb3BlcnR5SW5mbyAhPT0gbnVsbCkge1xuICAgICAgICAgIC8vICRGbG93Rml4TWUgLSBTaG91bGQgYmUgaW5mZXJyZWQgYXMgbm90IHVuZGVmaW5lZC5cbiAgICAgICAgICBleHRyYUF0dHJpYnV0ZU5hbWVzLmRlbGV0ZShwcm9wZXJ0eUluZm8uYXR0cmlidXRlTmFtZSk7XG4gICAgICAgICAgc2VydmVyVmFsdWUgPSBnZXRWYWx1ZUZvclByb3BlcnR5KGRvbUVsZW1lbnQsIHByb3BLZXksIG5leHRQcm9wLCBwcm9wZXJ0eUluZm8pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBvd25OYW1lc3BhY2UgPSBwYXJlbnROYW1lc3BhY2U7XG5cbiAgICAgICAgICBpZiAob3duTmFtZXNwYWNlID09PSBIVE1MX05BTUVTUEFDRSkge1xuICAgICAgICAgICAgb3duTmFtZXNwYWNlID0gZ2V0SW50cmluc2ljTmFtZXNwYWNlKHRhZyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG93bk5hbWVzcGFjZSA9PT0gSFRNTF9OQU1FU1BBQ0UpIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWUgLSBTaG91bGQgYmUgaW5mZXJyZWQgYXMgbm90IHVuZGVmaW5lZC5cbiAgICAgICAgICAgIGV4dHJhQXR0cmlidXRlTmFtZXMuZGVsZXRlKHByb3BLZXkudG9Mb3dlckNhc2UoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBzdGFuZGFyZE5hbWUgPSBnZXRQb3NzaWJsZVN0YW5kYXJkTmFtZShwcm9wS2V5KTtcblxuICAgICAgICAgICAgaWYgKHN0YW5kYXJkTmFtZSAhPT0gbnVsbCAmJiBzdGFuZGFyZE5hbWUgIT09IHByb3BLZXkpIHtcbiAgICAgICAgICAgICAgLy8gSWYgYW4gU1ZHIHByb3AgaXMgc3VwcGxpZWQgd2l0aCBiYWQgY2FzaW5nLCBpdCB3aWxsXG4gICAgICAgICAgICAgIC8vIGJlIHN1Y2Nlc3NmdWxseSBwYXJzZWQgZnJvbSBIVE1MLCBidXQgd2lsbCBwcm9kdWNlIGEgbWlzbWF0Y2hcbiAgICAgICAgICAgICAgLy8gKGFuZCB3b3VsZCBiZSBpbmNvcnJlY3RseSByZW5kZXJlZCBvbiB0aGUgY2xpZW50KS5cbiAgICAgICAgICAgICAgLy8gSG93ZXZlciwgd2UgYWxyZWFkeSB3YXJuIGFib3V0IGJhZCBjYXNpbmcgZWxzZXdoZXJlLlxuICAgICAgICAgICAgICAvLyBTbyB3ZSdsbCBza2lwIHRoZSBtaXNsZWFkaW5nIGV4dHJhIG1pc21hdGNoIHdhcm5pbmcgaW4gdGhpcyBjYXNlLlxuICAgICAgICAgICAgICBpc01pc21hdGNoRHVlVG9CYWRDYXNpbmcgPSB0cnVlOyAvLyAkRmxvd0ZpeE1lIC0gU2hvdWxkIGJlIGluZmVycmVkIGFzIG5vdCB1bmRlZmluZWQuXG5cbiAgICAgICAgICAgICAgZXh0cmFBdHRyaWJ1dGVOYW1lcy5kZWxldGUoc3RhbmRhcmROYW1lKTtcbiAgICAgICAgICAgIH0gLy8gJEZsb3dGaXhNZSAtIFNob3VsZCBiZSBpbmZlcnJlZCBhcyBub3QgdW5kZWZpbmVkLlxuXG5cbiAgICAgICAgICAgIGV4dHJhQXR0cmlidXRlTmFtZXMuZGVsZXRlKHByb3BLZXkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHNlcnZlclZhbHVlID0gZ2V0VmFsdWVGb3JBdHRyaWJ1dGUoZG9tRWxlbWVudCwgcHJvcEtleSwgbmV4dFByb3ApO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGRvbnRXYXJuQ3VzdG9tRWxlbWVudCA9IGVuYWJsZUN1c3RvbUVsZW1lbnRQcm9wZXJ0eVN1cHBvcnQgIDtcblxuICAgICAgICBpZiAoIWRvbnRXYXJuQ3VzdG9tRWxlbWVudCAmJiBuZXh0UHJvcCAhPT0gc2VydmVyVmFsdWUgJiYgIWlzTWlzbWF0Y2hEdWVUb0JhZENhc2luZykge1xuICAgICAgICAgIHdhcm5Gb3JQcm9wRGlmZmVyZW5jZShwcm9wS2V5LCBzZXJ2ZXJWYWx1ZSwgbmV4dFByb3ApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAge1xuICAgIGlmIChzaG91bGRXYXJuRGV2KSB7XG4gICAgICBpZiAoIC8vICRGbG93Rml4TWUgLSBTaG91bGQgYmUgaW5mZXJyZWQgYXMgbm90IHVuZGVmaW5lZC5cbiAgICAgIGV4dHJhQXR0cmlidXRlTmFtZXMuc2l6ZSA+IDAgJiYgcmF3UHJvcHNbU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkddICE9PSB0cnVlKSB7XG4gICAgICAgIC8vICRGbG93Rml4TWUgLSBTaG91bGQgYmUgaW5mZXJyZWQgYXMgbm90IHVuZGVmaW5lZC5cbiAgICAgICAgd2FybkZvckV4dHJhQXR0cmlidXRlcyhleHRyYUF0dHJpYnV0ZU5hbWVzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgJ2lucHV0JzpcbiAgICAgIC8vIFRPRE86IE1ha2Ugc3VyZSB3ZSBjaGVjayBpZiB0aGlzIGlzIHN0aWxsIHVubW91bnRlZCBvciBkbyBhbnkgY2xlYW5cbiAgICAgIC8vIHVwIG5lY2Vzc2FyeSBzaW5jZSB3ZSBuZXZlciBzdG9wIHRyYWNraW5nIGFueW1vcmUuXG4gICAgICB0cmFjayhkb21FbGVtZW50KTtcbiAgICAgIHBvc3RNb3VudFdyYXBwZXIoZG9tRWxlbWVudCwgcmF3UHJvcHMsIHRydWUpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICAvLyBUT0RPOiBNYWtlIHN1cmUgd2UgY2hlY2sgaWYgdGhpcyBpcyBzdGlsbCB1bm1vdW50ZWQgb3IgZG8gYW55IGNsZWFuXG4gICAgICAvLyB1cCBuZWNlc3Nhcnkgc2luY2Ugd2UgbmV2ZXIgc3RvcCB0cmFja2luZyBhbnltb3JlLlxuICAgICAgdHJhY2soZG9tRWxlbWVudCk7XG4gICAgICBwb3N0TW91bnRXcmFwcGVyJDMoZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgY2FzZSAnb3B0aW9uJzpcbiAgICAgIC8vIEZvciBpbnB1dCBhbmQgdGV4dGFyZWEgd2UgY3VycmVudCBhbHdheXMgc2V0IHRoZSB2YWx1ZSBwcm9wZXJ0eSBhdFxuICAgICAgLy8gcG9zdCBtb3VudCB0byBmb3JjZSBpdCB0byBkaXZlcmdlIGZyb20gYXR0cmlidXRlcy4gSG93ZXZlciwgZm9yXG4gICAgICAvLyBvcHRpb24gYW5kIHNlbGVjdCB3ZSBkb24ndCBxdWl0ZSBkbyB0aGUgc2FtZSB0aGluZyBhbmQgc2VsZWN0XG4gICAgICAvLyBpcyBub3QgcmVzaWxpZW50IHRvIHRoZSBET00gc3RhdGUgY2hhbmdpbmcgc28gd2UgZG9uJ3QgZG8gdGhhdCBoZXJlLlxuICAgICAgLy8gVE9ETzogQ29uc2lkZXIgbm90IGRvaW5nIHRoaXMgZm9yIGlucHV0IGFuZCB0ZXh0YXJlYS5cbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIGlmICh0eXBlb2YgcmF3UHJvcHMub25DbGljayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBUT0RPOiBUaGlzIGNhc3QgbWF5IG5vdCBiZSBzb3VuZCBmb3IgU1ZHLCBNYXRoTUwgb3IgY3VzdG9tIGVsZW1lbnRzLlxuICAgICAgICB0cmFwQ2xpY2tPbk5vbkludGVyYWN0aXZlRWxlbWVudChkb21FbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG4gIH1cblxuICByZXR1cm4gdXBkYXRlUGF5bG9hZDtcbn1cbmZ1bmN0aW9uIGRpZmZIeWRyYXRlZFRleHQodGV4dE5vZGUsIHRleHQsIGlzQ29uY3VycmVudE1vZGUpIHtcbiAgdmFyIGlzRGlmZmVyZW50ID0gdGV4dE5vZGUubm9kZVZhbHVlICE9PSB0ZXh0O1xuICByZXR1cm4gaXNEaWZmZXJlbnQ7XG59XG5mdW5jdGlvbiB3YXJuRm9yRGVsZXRlZEh5ZHJhdGFibGVFbGVtZW50KHBhcmVudE5vZGUsIGNoaWxkKSB7XG4gIHtcbiAgICBpZiAoZGlkV2FybkludmFsaWRIeWRyYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbiA9IHRydWU7XG5cbiAgICBlcnJvcignRGlkIG5vdCBleHBlY3Qgc2VydmVyIEhUTUwgdG8gY29udGFpbiBhIDwlcz4gaW4gPCVzPi4nLCBjaGlsZC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLCBwYXJlbnROb2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpO1xuICB9XG59XG5mdW5jdGlvbiB3YXJuRm9yRGVsZXRlZEh5ZHJhdGFibGVUZXh0KHBhcmVudE5vZGUsIGNoaWxkKSB7XG4gIHtcbiAgICBpZiAoZGlkV2FybkludmFsaWRIeWRyYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbiA9IHRydWU7XG5cbiAgICBlcnJvcignRGlkIG5vdCBleHBlY3Qgc2VydmVyIEhUTUwgdG8gY29udGFpbiB0aGUgdGV4dCBub2RlIFwiJXNcIiBpbiA8JXM+LicsIGNoaWxkLm5vZGVWYWx1ZSwgcGFyZW50Tm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgfVxufVxuZnVuY3Rpb24gd2FybkZvckluc2VydGVkSHlkcmF0ZWRFbGVtZW50KHBhcmVudE5vZGUsIHRhZywgcHJvcHMpIHtcbiAge1xuICAgIGlmIChkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uID0gdHJ1ZTtcblxuICAgIGVycm9yKCdFeHBlY3RlZCBzZXJ2ZXIgSFRNTCB0byBjb250YWluIGEgbWF0Y2hpbmcgPCVzPiBpbiA8JXM+LicsIHRhZywgcGFyZW50Tm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgfVxufVxuZnVuY3Rpb24gd2FybkZvckluc2VydGVkSHlkcmF0ZWRUZXh0KHBhcmVudE5vZGUsIHRleHQpIHtcbiAge1xuICAgIGlmICh0ZXh0ID09PSAnJykge1xuICAgICAgLy8gV2UgZXhwZWN0IHRvIGluc2VydCBlbXB0eSB0ZXh0IG5vZGVzIHNpbmNlIHRoZXkncmUgbm90IHJlcHJlc2VudGVkIGluXG4gICAgICAvLyB0aGUgSFRNTC5cbiAgICAgIC8vIFRPRE86IFJlbW92ZSB0aGlzIHNwZWNpYWwgY2FzZSBpZiB3ZSBjYW4ganVzdCBhdm9pZCBpbnNlcnRpbmcgZW1wdHlcbiAgICAgIC8vIHRleHQgbm9kZXMuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZGlkV2FybkludmFsaWRIeWRyYXRpb24gPSB0cnVlO1xuXG4gICAgZXJyb3IoJ0V4cGVjdGVkIHNlcnZlciBIVE1MIHRvIGNvbnRhaW4gYSBtYXRjaGluZyB0ZXh0IG5vZGUgZm9yIFwiJXNcIiBpbiA8JXM+LicsIHRleHQsIHBhcmVudE5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSk7XG4gIH1cbn1cbmZ1bmN0aW9uIHJlc3RvcmVDb250cm9sbGVkU3RhdGUkMyhkb21FbGVtZW50LCB0YWcsIHByb3BzKSB7XG4gIHN3aXRjaCAodGFnKSB7XG4gICAgY2FzZSAnaW5wdXQnOlxuICAgICAgcmVzdG9yZUNvbnRyb2xsZWRTdGF0ZShkb21FbGVtZW50LCBwcm9wcyk7XG4gICAgICByZXR1cm47XG5cbiAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICByZXN0b3JlQ29udHJvbGxlZFN0YXRlJDIoZG9tRWxlbWVudCwgcHJvcHMpO1xuICAgICAgcmV0dXJuO1xuXG4gICAgY2FzZSAnc2VsZWN0JzpcbiAgICAgIHJlc3RvcmVDb250cm9sbGVkU3RhdGUkMShkb21FbGVtZW50LCBwcm9wcyk7XG4gICAgICByZXR1cm47XG4gIH1cbn1cblxudmFyIHZhbGlkYXRlRE9NTmVzdGluZyA9IGZ1bmN0aW9uICgpIHt9O1xuXG52YXIgdXBkYXRlZEFuY2VzdG9ySW5mbyA9IGZ1bmN0aW9uICgpIHt9O1xuXG57XG4gIC8vIFRoaXMgdmFsaWRhdGlvbiBjb2RlIHdhcyB3cml0dGVuIGJhc2VkIG9uIHRoZSBIVE1MNSBwYXJzaW5nIHNwZWM6XG4gIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI2hhcy1hbi1lbGVtZW50LWluLXNjb3BlXG4gIC8vXG4gIC8vIE5vdGU6IHRoaXMgZG9lcyBub3QgY2F0Y2ggYWxsIGludmFsaWQgbmVzdGluZywgbm9yIGRvZXMgaXQgdHJ5IHRvIChhcyBpdCdzXG4gIC8vIG5vdCBjbGVhciB3aGF0IHByYWN0aWNhbCBiZW5lZml0IGRvaW5nIHNvIHByb3ZpZGVzKTsgaW5zdGVhZCwgd2Ugd2FybiBvbmx5XG4gIC8vIGZvciBjYXNlcyB3aGVyZSB0aGUgcGFyc2VyIHdpbGwgZ2l2ZSBhIHBhcnNlIHRyZWUgZGlmZmVyaW5nIGZyb20gd2hhdCBSZWFjdFxuICAvLyBpbnRlbmRlZC4gRm9yIGV4YW1wbGUsIDxiPjxkaXY+PC9kaXY+PC9iPiBpcyBpbnZhbGlkIGJ1dCB3ZSBkb24ndCB3YXJuXG4gIC8vIGJlY2F1c2UgaXQgc3RpbGwgcGFyc2VzIGNvcnJlY3RseTsgd2UgZG8gd2FybiBmb3Igb3RoZXIgY2FzZXMgbGlrZSBuZXN0ZWRcbiAgLy8gPHA+IHRhZ3Mgd2hlcmUgdGhlIGJlZ2lubmluZyBvZiB0aGUgc2Vjb25kIGVsZW1lbnQgaW1wbGljaXRseSBjbG9zZXMgdGhlXG4gIC8vIGZpcnN0LCBjYXVzaW5nIGEgY29uZnVzaW5nIG1lc3MuXG4gIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3NwZWNpYWxcbiAgdmFyIHNwZWNpYWxUYWdzID0gWydhZGRyZXNzJywgJ2FwcGxldCcsICdhcmVhJywgJ2FydGljbGUnLCAnYXNpZGUnLCAnYmFzZScsICdiYXNlZm9udCcsICdiZ3NvdW5kJywgJ2Jsb2NrcXVvdGUnLCAnYm9keScsICdicicsICdidXR0b24nLCAnY2FwdGlvbicsICdjZW50ZXInLCAnY29sJywgJ2NvbGdyb3VwJywgJ2RkJywgJ2RldGFpbHMnLCAnZGlyJywgJ2RpdicsICdkbCcsICdkdCcsICdlbWJlZCcsICdmaWVsZHNldCcsICdmaWdjYXB0aW9uJywgJ2ZpZ3VyZScsICdmb290ZXInLCAnZm9ybScsICdmcmFtZScsICdmcmFtZXNldCcsICdoMScsICdoMicsICdoMycsICdoNCcsICdoNScsICdoNicsICdoZWFkJywgJ2hlYWRlcicsICdoZ3JvdXAnLCAnaHInLCAnaHRtbCcsICdpZnJhbWUnLCAnaW1nJywgJ2lucHV0JywgJ2lzaW5kZXgnLCAnbGknLCAnbGluaycsICdsaXN0aW5nJywgJ21haW4nLCAnbWFycXVlZScsICdtZW51JywgJ21lbnVpdGVtJywgJ21ldGEnLCAnbmF2JywgJ25vZW1iZWQnLCAnbm9mcmFtZXMnLCAnbm9zY3JpcHQnLCAnb2JqZWN0JywgJ29sJywgJ3AnLCAncGFyYW0nLCAncGxhaW50ZXh0JywgJ3ByZScsICdzY3JpcHQnLCAnc2VjdGlvbicsICdzZWxlY3QnLCAnc291cmNlJywgJ3N0eWxlJywgJ3N1bW1hcnknLCAndGFibGUnLCAndGJvZHknLCAndGQnLCAndGVtcGxhdGUnLCAndGV4dGFyZWEnLCAndGZvb3QnLCAndGgnLCAndGhlYWQnLCAndGl0bGUnLCAndHInLCAndHJhY2snLCAndWwnLCAnd2JyJywgJ3htcCddOyAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNoYXMtYW4tZWxlbWVudC1pbi1zY29wZVxuXG4gIHZhciBpblNjb3BlVGFncyA9IFsnYXBwbGV0JywgJ2NhcHRpb24nLCAnaHRtbCcsICd0YWJsZScsICd0ZCcsICd0aCcsICdtYXJxdWVlJywgJ29iamVjdCcsICd0ZW1wbGF0ZScsIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI2h0bWwtaW50ZWdyYXRpb24tcG9pbnRcbiAgLy8gVE9ETzogRGlzdGluZ3Vpc2ggYnkgbmFtZXNwYWNlIGhlcmUgLS0gZm9yIDx0aXRsZT4sIGluY2x1ZGluZyBpdCBoZXJlXG4gIC8vIGVycnMgb24gdGhlIHNpZGUgb2YgZmV3ZXIgd2FybmluZ3NcbiAgJ2ZvcmVpZ25PYmplY3QnLCAnZGVzYycsICd0aXRsZSddOyAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNoYXMtYW4tZWxlbWVudC1pbi1idXR0b24tc2NvcGVcblxuICB2YXIgYnV0dG9uU2NvcGVUYWdzID0gaW5TY29wZVRhZ3MuY29uY2F0KFsnYnV0dG9uJ10pOyAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNnZW5lcmF0ZS1pbXBsaWVkLWVuZC10YWdzXG5cbiAgdmFyIGltcGxpZWRFbmRUYWdzID0gWydkZCcsICdkdCcsICdsaScsICdvcHRpb24nLCAnb3B0Z3JvdXAnLCAncCcsICdycCcsICdydCddO1xuICB2YXIgZW1wdHlBbmNlc3RvckluZm8gPSB7XG4gICAgY3VycmVudDogbnVsbCxcbiAgICBmb3JtVGFnOiBudWxsLFxuICAgIGFUYWdJblNjb3BlOiBudWxsLFxuICAgIGJ1dHRvblRhZ0luU2NvcGU6IG51bGwsXG4gICAgbm9iclRhZ0luU2NvcGU6IG51bGwsXG4gICAgcFRhZ0luQnV0dG9uU2NvcGU6IG51bGwsXG4gICAgbGlzdEl0ZW1UYWdBdXRvY2xvc2luZzogbnVsbCxcbiAgICBkbEl0ZW1UYWdBdXRvY2xvc2luZzogbnVsbFxuICB9O1xuXG4gIHVwZGF0ZWRBbmNlc3RvckluZm8gPSBmdW5jdGlvbiAob2xkSW5mbywgdGFnKSB7XG4gICAgdmFyIGFuY2VzdG9ySW5mbyA9IGFzc2lnbih7fSwgb2xkSW5mbyB8fCBlbXB0eUFuY2VzdG9ySW5mbyk7XG5cbiAgICB2YXIgaW5mbyA9IHtcbiAgICAgIHRhZzogdGFnXG4gICAgfTtcblxuICAgIGlmIChpblNjb3BlVGFncy5pbmRleE9mKHRhZykgIT09IC0xKSB7XG4gICAgICBhbmNlc3RvckluZm8uYVRhZ0luU2NvcGUgPSBudWxsO1xuICAgICAgYW5jZXN0b3JJbmZvLmJ1dHRvblRhZ0luU2NvcGUgPSBudWxsO1xuICAgICAgYW5jZXN0b3JJbmZvLm5vYnJUYWdJblNjb3BlID0gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoYnV0dG9uU2NvcGVUYWdzLmluZGV4T2YodGFnKSAhPT0gLTEpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5wVGFnSW5CdXR0b25TY29wZSA9IG51bGw7XG4gICAgfSAvLyBTZWUgcnVsZXMgZm9yICdsaScsICdkZCcsICdkdCcgc3RhcnQgdGFncyBpblxuICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbmJvZHlcblxuXG4gICAgaWYgKHNwZWNpYWxUYWdzLmluZGV4T2YodGFnKSAhPT0gLTEgJiYgdGFnICE9PSAnYWRkcmVzcycgJiYgdGFnICE9PSAnZGl2JyAmJiB0YWcgIT09ICdwJykge1xuICAgICAgYW5jZXN0b3JJbmZvLmxpc3RJdGVtVGFnQXV0b2Nsb3NpbmcgPSBudWxsO1xuICAgICAgYW5jZXN0b3JJbmZvLmRsSXRlbVRhZ0F1dG9jbG9zaW5nID0gbnVsbDtcbiAgICB9XG5cbiAgICBhbmNlc3RvckluZm8uY3VycmVudCA9IGluZm87XG5cbiAgICBpZiAodGFnID09PSAnZm9ybScpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5mb3JtVGFnID0gaW5mbztcbiAgICB9XG5cbiAgICBpZiAodGFnID09PSAnYScpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5hVGFnSW5TY29wZSA9IGluZm87XG4gICAgfVxuXG4gICAgaWYgKHRhZyA9PT0gJ2J1dHRvbicpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5idXR0b25UYWdJblNjb3BlID0gaW5mbztcbiAgICB9XG5cbiAgICBpZiAodGFnID09PSAnbm9icicpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5ub2JyVGFnSW5TY29wZSA9IGluZm87XG4gICAgfVxuXG4gICAgaWYgKHRhZyA9PT0gJ3AnKSB7XG4gICAgICBhbmNlc3RvckluZm8ucFRhZ0luQnV0dG9uU2NvcGUgPSBpbmZvO1xuICAgIH1cblxuICAgIGlmICh0YWcgPT09ICdsaScpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5saXN0SXRlbVRhZ0F1dG9jbG9zaW5nID0gaW5mbztcbiAgICB9XG5cbiAgICBpZiAodGFnID09PSAnZGQnIHx8IHRhZyA9PT0gJ2R0Jykge1xuICAgICAgYW5jZXN0b3JJbmZvLmRsSXRlbVRhZ0F1dG9jbG9zaW5nID0gaW5mbztcbiAgICB9XG5cbiAgICByZXR1cm4gYW5jZXN0b3JJbmZvO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyXG4gICAqL1xuXG5cbiAgdmFyIGlzVGFnVmFsaWRXaXRoUGFyZW50ID0gZnVuY3Rpb24gKHRhZywgcGFyZW50VGFnKSB7XG4gICAgLy8gRmlyc3QsIGxldCdzIGNoZWNrIGlmIHdlJ3JlIGluIGFuIHVudXN1YWwgcGFyc2luZyBtb2RlLi4uXG4gICAgc3dpdGNoIChwYXJlbnRUYWcpIHtcbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbnNlbGVjdFxuICAgICAgY2FzZSAnc2VsZWN0JzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ29wdGlvbicgfHwgdGFnID09PSAnb3B0Z3JvdXAnIHx8IHRhZyA9PT0gJyN0ZXh0JztcblxuICAgICAgY2FzZSAnb3B0Z3JvdXAnOlxuICAgICAgICByZXR1cm4gdGFnID09PSAnb3B0aW9uJyB8fCB0YWcgPT09ICcjdGV4dCc7XG4gICAgICAvLyBTdHJpY3RseSBzcGVha2luZywgc2VlaW5nIGFuIDxvcHRpb24+IGRvZXNuJ3QgbWVhbiB3ZSdyZSBpbiBhIDxzZWxlY3Q+XG4gICAgICAvLyBidXRcblxuICAgICAgY2FzZSAnb3B0aW9uJzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJyN0ZXh0JztcbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbnRkXG4gICAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW5jYXB0aW9uXG4gICAgICAvLyBObyBzcGVjaWFsIGJlaGF2aW9yIHNpbmNlIHRoZXNlIHJ1bGVzIGZhbGwgYmFjayB0byBcImluIGJvZHlcIiBtb2RlIGZvclxuICAgICAgLy8gYWxsIGV4Y2VwdCBzcGVjaWFsIHRhYmxlIG5vZGVzIHdoaWNoIGNhdXNlIGJhZCBwYXJzaW5nIGJlaGF2aW9yIGFueXdheS5cbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbnRyXG5cbiAgICAgIGNhc2UgJ3RyJzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ3RoJyB8fCB0YWcgPT09ICd0ZCcgfHwgdGFnID09PSAnc3R5bGUnIHx8IHRhZyA9PT0gJ3NjcmlwdCcgfHwgdGFnID09PSAndGVtcGxhdGUnO1xuICAgICAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjcGFyc2luZy1tYWluLWludGJvZHlcblxuICAgICAgY2FzZSAndGJvZHknOlxuICAgICAgY2FzZSAndGhlYWQnOlxuICAgICAgY2FzZSAndGZvb3QnOlxuICAgICAgICByZXR1cm4gdGFnID09PSAndHInIHx8IHRhZyA9PT0gJ3N0eWxlJyB8fCB0YWcgPT09ICdzY3JpcHQnIHx8IHRhZyA9PT0gJ3RlbXBsYXRlJztcbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbmNvbGdyb3VwXG5cbiAgICAgIGNhc2UgJ2NvbGdyb3VwJzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ2NvbCcgfHwgdGFnID09PSAndGVtcGxhdGUnO1xuICAgICAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjcGFyc2luZy1tYWluLWludGFibGVcblxuICAgICAgY2FzZSAndGFibGUnOlxuICAgICAgICByZXR1cm4gdGFnID09PSAnY2FwdGlvbicgfHwgdGFnID09PSAnY29sZ3JvdXAnIHx8IHRhZyA9PT0gJ3Rib2R5JyB8fCB0YWcgPT09ICd0Zm9vdCcgfHwgdGFnID09PSAndGhlYWQnIHx8IHRhZyA9PT0gJ3N0eWxlJyB8fCB0YWcgPT09ICdzY3JpcHQnIHx8IHRhZyA9PT0gJ3RlbXBsYXRlJztcbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbmhlYWRcblxuICAgICAgY2FzZSAnaGVhZCc6XG4gICAgICAgIHJldHVybiB0YWcgPT09ICdiYXNlJyB8fCB0YWcgPT09ICdiYXNlZm9udCcgfHwgdGFnID09PSAnYmdzb3VuZCcgfHwgdGFnID09PSAnbGluaycgfHwgdGFnID09PSAnbWV0YScgfHwgdGFnID09PSAndGl0bGUnIHx8IHRhZyA9PT0gJ25vc2NyaXB0JyB8fCB0YWcgPT09ICdub2ZyYW1lcycgfHwgdGFnID09PSAnc3R5bGUnIHx8IHRhZyA9PT0gJ3NjcmlwdCcgfHwgdGFnID09PSAndGVtcGxhdGUnO1xuICAgICAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc2VtYW50aWNzLmh0bWwjdGhlLWh0bWwtZWxlbWVudFxuXG4gICAgICBjYXNlICdodG1sJzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ2hlYWQnIHx8IHRhZyA9PT0gJ2JvZHknIHx8IHRhZyA9PT0gJ2ZyYW1lc2V0JztcblxuICAgICAgY2FzZSAnZnJhbWVzZXQnOlxuICAgICAgICByZXR1cm4gdGFnID09PSAnZnJhbWUnO1xuXG4gICAgICBjYXNlICcjZG9jdW1lbnQnOlxuICAgICAgICByZXR1cm4gdGFnID09PSAnaHRtbCc7XG4gICAgfSAvLyBQcm9iYWJseSBpbiB0aGUgXCJpbiBib2R5XCIgcGFyc2luZyBtb2RlLCBzbyB3ZSBvdXRsYXcgb25seSB0YWcgY29tYm9zXG4gICAgLy8gd2hlcmUgdGhlIHBhcnNpbmcgcnVsZXMgY2F1c2UgaW1wbGljaXQgb3BlbnMgb3IgY2xvc2VzIHRvIGJlIGFkZGVkLlxuICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbmJvZHlcblxuXG4gICAgc3dpdGNoICh0YWcpIHtcbiAgICAgIGNhc2UgJ2gxJzpcbiAgICAgIGNhc2UgJ2gyJzpcbiAgICAgIGNhc2UgJ2gzJzpcbiAgICAgIGNhc2UgJ2g0JzpcbiAgICAgIGNhc2UgJ2g1JzpcbiAgICAgIGNhc2UgJ2g2JzpcbiAgICAgICAgcmV0dXJuIHBhcmVudFRhZyAhPT0gJ2gxJyAmJiBwYXJlbnRUYWcgIT09ICdoMicgJiYgcGFyZW50VGFnICE9PSAnaDMnICYmIHBhcmVudFRhZyAhPT0gJ2g0JyAmJiBwYXJlbnRUYWcgIT09ICdoNScgJiYgcGFyZW50VGFnICE9PSAnaDYnO1xuXG4gICAgICBjYXNlICdycCc6XG4gICAgICBjYXNlICdydCc6XG4gICAgICAgIHJldHVybiBpbXBsaWVkRW5kVGFncy5pbmRleE9mKHBhcmVudFRhZykgPT09IC0xO1xuXG4gICAgICBjYXNlICdib2R5JzpcbiAgICAgIGNhc2UgJ2NhcHRpb24nOlxuICAgICAgY2FzZSAnY29sJzpcbiAgICAgIGNhc2UgJ2NvbGdyb3VwJzpcbiAgICAgIGNhc2UgJ2ZyYW1lc2V0JzpcbiAgICAgIGNhc2UgJ2ZyYW1lJzpcbiAgICAgIGNhc2UgJ2hlYWQnOlxuICAgICAgY2FzZSAnaHRtbCc6XG4gICAgICBjYXNlICd0Ym9keSc6XG4gICAgICBjYXNlICd0ZCc6XG4gICAgICBjYXNlICd0Zm9vdCc6XG4gICAgICBjYXNlICd0aCc6XG4gICAgICBjYXNlICd0aGVhZCc6XG4gICAgICBjYXNlICd0cic6XG4gICAgICAgIC8vIFRoZXNlIHRhZ3MgYXJlIG9ubHkgdmFsaWQgd2l0aCBhIGZldyBwYXJlbnRzIHRoYXQgaGF2ZSBzcGVjaWFsIGNoaWxkXG4gICAgICAgIC8vIHBhcnNpbmcgcnVsZXMgLS0gaWYgd2UncmUgZG93biBoZXJlLCB0aGVuIG5vbmUgb2YgdGhvc2UgbWF0Y2hlZCBhbmRcbiAgICAgICAgLy8gc28gd2UgYWxsb3cgaXQgb25seSBpZiB3ZSBkb24ndCBrbm93IHdoYXQgdGhlIHBhcmVudCBpcywgYXMgYWxsIG90aGVyXG4gICAgICAgIC8vIGNhc2VzIGFyZSBpbnZhbGlkLlxuICAgICAgICByZXR1cm4gcGFyZW50VGFnID09IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoZXRoZXJcbiAgICovXG5cblxuICB2YXIgZmluZEludmFsaWRBbmNlc3RvckZvclRhZyA9IGZ1bmN0aW9uICh0YWcsIGFuY2VzdG9ySW5mbykge1xuICAgIHN3aXRjaCAodGFnKSB7XG4gICAgICBjYXNlICdhZGRyZXNzJzpcbiAgICAgIGNhc2UgJ2FydGljbGUnOlxuICAgICAgY2FzZSAnYXNpZGUnOlxuICAgICAgY2FzZSAnYmxvY2txdW90ZSc6XG4gICAgICBjYXNlICdjZW50ZXInOlxuICAgICAgY2FzZSAnZGV0YWlscyc6XG4gICAgICBjYXNlICdkaWFsb2cnOlxuICAgICAgY2FzZSAnZGlyJzpcbiAgICAgIGNhc2UgJ2Rpdic6XG4gICAgICBjYXNlICdkbCc6XG4gICAgICBjYXNlICdmaWVsZHNldCc6XG4gICAgICBjYXNlICdmaWdjYXB0aW9uJzpcbiAgICAgIGNhc2UgJ2ZpZ3VyZSc6XG4gICAgICBjYXNlICdmb290ZXInOlxuICAgICAgY2FzZSAnaGVhZGVyJzpcbiAgICAgIGNhc2UgJ2hncm91cCc6XG4gICAgICBjYXNlICdtYWluJzpcbiAgICAgIGNhc2UgJ21lbnUnOlxuICAgICAgY2FzZSAnbmF2JzpcbiAgICAgIGNhc2UgJ29sJzpcbiAgICAgIGNhc2UgJ3AnOlxuICAgICAgY2FzZSAnc2VjdGlvbic6XG4gICAgICBjYXNlICdzdW1tYXJ5JzpcbiAgICAgIGNhc2UgJ3VsJzpcbiAgICAgIGNhc2UgJ3ByZSc6XG4gICAgICBjYXNlICdsaXN0aW5nJzpcbiAgICAgIGNhc2UgJ3RhYmxlJzpcbiAgICAgIGNhc2UgJ2hyJzpcbiAgICAgIGNhc2UgJ3htcCc6XG4gICAgICBjYXNlICdoMSc6XG4gICAgICBjYXNlICdoMic6XG4gICAgICBjYXNlICdoMyc6XG4gICAgICBjYXNlICdoNCc6XG4gICAgICBjYXNlICdoNSc6XG4gICAgICBjYXNlICdoNic6XG4gICAgICAgIHJldHVybiBhbmNlc3RvckluZm8ucFRhZ0luQnV0dG9uU2NvcGU7XG5cbiAgICAgIGNhc2UgJ2Zvcm0nOlxuICAgICAgICByZXR1cm4gYW5jZXN0b3JJbmZvLmZvcm1UYWcgfHwgYW5jZXN0b3JJbmZvLnBUYWdJbkJ1dHRvblNjb3BlO1xuXG4gICAgICBjYXNlICdsaSc6XG4gICAgICAgIHJldHVybiBhbmNlc3RvckluZm8ubGlzdEl0ZW1UYWdBdXRvY2xvc2luZztcblxuICAgICAgY2FzZSAnZGQnOlxuICAgICAgY2FzZSAnZHQnOlxuICAgICAgICByZXR1cm4gYW5jZXN0b3JJbmZvLmRsSXRlbVRhZ0F1dG9jbG9zaW5nO1xuXG4gICAgICBjYXNlICdidXR0b24nOlxuICAgICAgICByZXR1cm4gYW5jZXN0b3JJbmZvLmJ1dHRvblRhZ0luU2NvcGU7XG5cbiAgICAgIGNhc2UgJ2EnOlxuICAgICAgICAvLyBTcGVjIHNheXMgc29tZXRoaW5nIGFib3V0IHN0b3JpbmcgYSBsaXN0IG9mIG1hcmtlcnMsIGJ1dCBpdCBzb3VuZHNcbiAgICAgICAgLy8gZXF1aXZhbGVudCB0byB0aGlzIGNoZWNrLlxuICAgICAgICByZXR1cm4gYW5jZXN0b3JJbmZvLmFUYWdJblNjb3BlO1xuXG4gICAgICBjYXNlICdub2JyJzpcbiAgICAgICAgcmV0dXJuIGFuY2VzdG9ySW5mby5ub2JyVGFnSW5TY29wZTtcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuICB2YXIgZGlkV2FybiQxID0ge307XG5cbiAgdmFsaWRhdGVET01OZXN0aW5nID0gZnVuY3Rpb24gKGNoaWxkVGFnLCBjaGlsZFRleHQsIGFuY2VzdG9ySW5mbykge1xuICAgIGFuY2VzdG9ySW5mbyA9IGFuY2VzdG9ySW5mbyB8fCBlbXB0eUFuY2VzdG9ySW5mbztcbiAgICB2YXIgcGFyZW50SW5mbyA9IGFuY2VzdG9ySW5mby5jdXJyZW50O1xuICAgIHZhciBwYXJlbnRUYWcgPSBwYXJlbnRJbmZvICYmIHBhcmVudEluZm8udGFnO1xuXG4gICAgaWYgKGNoaWxkVGV4dCAhPSBudWxsKSB7XG4gICAgICBpZiAoY2hpbGRUYWcgIT0gbnVsbCkge1xuICAgICAgICBlcnJvcigndmFsaWRhdGVET01OZXN0aW5nOiB3aGVuIGNoaWxkVGV4dCBpcyBwYXNzZWQsIGNoaWxkVGFnIHNob3VsZCBiZSBudWxsJyk7XG4gICAgICB9XG5cbiAgICAgIGNoaWxkVGFnID0gJyN0ZXh0JztcbiAgICB9XG5cbiAgICB2YXIgaW52YWxpZFBhcmVudCA9IGlzVGFnVmFsaWRXaXRoUGFyZW50KGNoaWxkVGFnLCBwYXJlbnRUYWcpID8gbnVsbCA6IHBhcmVudEluZm87XG4gICAgdmFyIGludmFsaWRBbmNlc3RvciA9IGludmFsaWRQYXJlbnQgPyBudWxsIDogZmluZEludmFsaWRBbmNlc3RvckZvclRhZyhjaGlsZFRhZywgYW5jZXN0b3JJbmZvKTtcbiAgICB2YXIgaW52YWxpZFBhcmVudE9yQW5jZXN0b3IgPSBpbnZhbGlkUGFyZW50IHx8IGludmFsaWRBbmNlc3RvcjtcblxuICAgIGlmICghaW52YWxpZFBhcmVudE9yQW5jZXN0b3IpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgYW5jZXN0b3JUYWcgPSBpbnZhbGlkUGFyZW50T3JBbmNlc3Rvci50YWc7XG4gICAgdmFyIHdhcm5LZXkgPSAhIWludmFsaWRQYXJlbnQgKyAnfCcgKyBjaGlsZFRhZyArICd8JyArIGFuY2VzdG9yVGFnO1xuXG4gICAgaWYgKGRpZFdhcm4kMVt3YXJuS2V5XSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRpZFdhcm4kMVt3YXJuS2V5XSA9IHRydWU7XG4gICAgdmFyIHRhZ0Rpc3BsYXlOYW1lID0gY2hpbGRUYWc7XG4gICAgdmFyIHdoaXRlc3BhY2VJbmZvID0gJyc7XG5cbiAgICBpZiAoY2hpbGRUYWcgPT09ICcjdGV4dCcpIHtcbiAgICAgIGlmICgvXFxTLy50ZXN0KGNoaWxkVGV4dCkpIHtcbiAgICAgICAgdGFnRGlzcGxheU5hbWUgPSAnVGV4dCBub2Rlcyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YWdEaXNwbGF5TmFtZSA9ICdXaGl0ZXNwYWNlIHRleHQgbm9kZXMnO1xuICAgICAgICB3aGl0ZXNwYWNlSW5mbyA9IFwiIE1ha2Ugc3VyZSB5b3UgZG9uJ3QgaGF2ZSBhbnkgZXh0cmEgd2hpdGVzcGFjZSBiZXR3ZWVuIHRhZ3Mgb24gXCIgKyAnZWFjaCBsaW5lIG9mIHlvdXIgc291cmNlIGNvZGUuJztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGFnRGlzcGxheU5hbWUgPSAnPCcgKyBjaGlsZFRhZyArICc+JztcbiAgICB9XG5cbiAgICBpZiAoaW52YWxpZFBhcmVudCkge1xuICAgICAgdmFyIGluZm8gPSAnJztcblxuICAgICAgaWYgKGFuY2VzdG9yVGFnID09PSAndGFibGUnICYmIGNoaWxkVGFnID09PSAndHInKSB7XG4gICAgICAgIGluZm8gKz0gJyBBZGQgYSA8dGJvZHk+LCA8dGhlYWQ+IG9yIDx0Zm9vdD4gdG8geW91ciBjb2RlIHRvIG1hdGNoIHRoZSBET00gdHJlZSBnZW5lcmF0ZWQgYnkgJyArICd0aGUgYnJvd3Nlci4nO1xuICAgICAgfVxuXG4gICAgICBlcnJvcigndmFsaWRhdGVET01OZXN0aW5nKC4uLik6ICVzIGNhbm5vdCBhcHBlYXIgYXMgYSBjaGlsZCBvZiA8JXM+LiVzJXMnLCB0YWdEaXNwbGF5TmFtZSwgYW5jZXN0b3JUYWcsIHdoaXRlc3BhY2VJbmZvLCBpbmZvKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXJyb3IoJ3ZhbGlkYXRlRE9NTmVzdGluZyguLi4pOiAlcyBjYW5ub3QgYXBwZWFyIGFzIGEgZGVzY2VuZGFudCBvZiAnICsgJzwlcz4uJywgdGFnRGlzcGxheU5hbWUsIGFuY2VzdG9yVGFnKTtcbiAgICB9XG4gIH07XG59XG5cbnZhciBTVVBQUkVTU19IWURSQVRJT05fV0FSTklORyQxID0gJ3N1cHByZXNzSHlkcmF0aW9uV2FybmluZyc7XG52YXIgU1VTUEVOU0VfU1RBUlRfREFUQSA9ICckJztcbnZhciBTVVNQRU5TRV9FTkRfREFUQSA9ICcvJCc7XG52YXIgU1VTUEVOU0VfUEVORElOR19TVEFSVF9EQVRBID0gJyQ/JztcbnZhciBTVVNQRU5TRV9GQUxMQkFDS19TVEFSVF9EQVRBID0gJyQhJztcbnZhciBTVFlMRSQxID0gJ3N0eWxlJztcbnZhciBldmVudHNFbmFibGVkID0gbnVsbDtcbnZhciBzZWxlY3Rpb25JbmZvcm1hdGlvbiA9IG51bGw7XG5mdW5jdGlvbiBnZXRSb290SG9zdENvbnRleHQocm9vdENvbnRhaW5lckluc3RhbmNlKSB7XG4gIHZhciB0eXBlO1xuICB2YXIgbmFtZXNwYWNlO1xuICB2YXIgbm9kZVR5cGUgPSByb290Q29udGFpbmVySW5zdGFuY2Uubm9kZVR5cGU7XG5cbiAgc3dpdGNoIChub2RlVHlwZSkge1xuICAgIGNhc2UgRE9DVU1FTlRfTk9ERTpcbiAgICBjYXNlIERPQ1VNRU5UX0ZSQUdNRU5UX05PREU6XG4gICAgICB7XG4gICAgICAgIHR5cGUgPSBub2RlVHlwZSA9PT0gRE9DVU1FTlRfTk9ERSA/ICcjZG9jdW1lbnQnIDogJyNmcmFnbWVudCc7XG4gICAgICAgIHZhciByb290ID0gcm9vdENvbnRhaW5lckluc3RhbmNlLmRvY3VtZW50RWxlbWVudDtcbiAgICAgICAgbmFtZXNwYWNlID0gcm9vdCA/IHJvb3QubmFtZXNwYWNlVVJJIDogZ2V0Q2hpbGROYW1lc3BhY2UobnVsbCwgJycpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSBub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFID8gcm9vdENvbnRhaW5lckluc3RhbmNlLnBhcmVudE5vZGUgOiByb290Q29udGFpbmVySW5zdGFuY2U7XG4gICAgICAgIHZhciBvd25OYW1lc3BhY2UgPSBjb250YWluZXIubmFtZXNwYWNlVVJJIHx8IG51bGw7XG4gICAgICAgIHR5cGUgPSBjb250YWluZXIudGFnTmFtZTtcbiAgICAgICAgbmFtZXNwYWNlID0gZ2V0Q2hpbGROYW1lc3BhY2Uob3duTmFtZXNwYWNlLCB0eXBlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gIH1cblxuICB7XG4gICAgdmFyIHZhbGlkYXRlZFRhZyA9IHR5cGUudG9Mb3dlckNhc2UoKTtcbiAgICB2YXIgYW5jZXN0b3JJbmZvID0gdXBkYXRlZEFuY2VzdG9ySW5mbyhudWxsLCB2YWxpZGF0ZWRUYWcpO1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lc3BhY2U6IG5hbWVzcGFjZSxcbiAgICAgIGFuY2VzdG9ySW5mbzogYW5jZXN0b3JJbmZvXG4gICAgfTtcbiAgfVxufVxuZnVuY3Rpb24gZ2V0Q2hpbGRIb3N0Q29udGV4dChwYXJlbnRIb3N0Q29udGV4dCwgdHlwZSwgcm9vdENvbnRhaW5lckluc3RhbmNlKSB7XG4gIHtcbiAgICB2YXIgcGFyZW50SG9zdENvbnRleHREZXYgPSBwYXJlbnRIb3N0Q29udGV4dDtcbiAgICB2YXIgbmFtZXNwYWNlID0gZ2V0Q2hpbGROYW1lc3BhY2UocGFyZW50SG9zdENvbnRleHREZXYubmFtZXNwYWNlLCB0eXBlKTtcbiAgICB2YXIgYW5jZXN0b3JJbmZvID0gdXBkYXRlZEFuY2VzdG9ySW5mbyhwYXJlbnRIb3N0Q29udGV4dERldi5hbmNlc3RvckluZm8sIHR5cGUpO1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lc3BhY2U6IG5hbWVzcGFjZSxcbiAgICAgIGFuY2VzdG9ySW5mbzogYW5jZXN0b3JJbmZvXG4gICAgfTtcbiAgfVxufVxuZnVuY3Rpb24gZ2V0UHVibGljSW5zdGFuY2UoaW5zdGFuY2UpIHtcbiAgcmV0dXJuIGluc3RhbmNlO1xufVxuZnVuY3Rpb24gcHJlcGFyZUZvckNvbW1pdChjb250YWluZXJJbmZvKSB7XG4gIGV2ZW50c0VuYWJsZWQgPSBpc0VuYWJsZWQoKTtcbiAgc2VsZWN0aW9uSW5mb3JtYXRpb24gPSBnZXRTZWxlY3Rpb25JbmZvcm1hdGlvbigpO1xuICB2YXIgYWN0aXZlSW5zdGFuY2UgPSBudWxsO1xuXG4gIHNldEVuYWJsZWQoZmFsc2UpO1xuICByZXR1cm4gYWN0aXZlSW5zdGFuY2U7XG59XG5mdW5jdGlvbiByZXNldEFmdGVyQ29tbWl0KGNvbnRhaW5lckluZm8pIHtcbiAgcmVzdG9yZVNlbGVjdGlvbihzZWxlY3Rpb25JbmZvcm1hdGlvbik7XG4gIHNldEVuYWJsZWQoZXZlbnRzRW5hYmxlZCk7XG4gIGV2ZW50c0VuYWJsZWQgPSBudWxsO1xuICBzZWxlY3Rpb25JbmZvcm1hdGlvbiA9IG51bGw7XG59XG5mdW5jdGlvbiBjcmVhdGVJbnN0YW5jZSh0eXBlLCBwcm9wcywgcm9vdENvbnRhaW5lckluc3RhbmNlLCBob3N0Q29udGV4dCwgaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSkge1xuICB2YXIgcGFyZW50TmFtZXNwYWNlO1xuXG4gIHtcbiAgICAvLyBUT0RPOiB0YWtlIG5hbWVzcGFjZSBpbnRvIGFjY291bnQgd2hlbiB2YWxpZGF0aW5nLlxuICAgIHZhciBob3N0Q29udGV4dERldiA9IGhvc3RDb250ZXh0O1xuICAgIHZhbGlkYXRlRE9NTmVzdGluZyh0eXBlLCBudWxsLCBob3N0Q29udGV4dERldi5hbmNlc3RvckluZm8pO1xuXG4gICAgaWYgKHR5cGVvZiBwcm9wcy5jaGlsZHJlbiA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHByb3BzLmNoaWxkcmVuID09PSAnbnVtYmVyJykge1xuICAgICAgdmFyIHN0cmluZyA9ICcnICsgcHJvcHMuY2hpbGRyZW47XG4gICAgICB2YXIgb3duQW5jZXN0b3JJbmZvID0gdXBkYXRlZEFuY2VzdG9ySW5mbyhob3N0Q29udGV4dERldi5hbmNlc3RvckluZm8sIHR5cGUpO1xuICAgICAgdmFsaWRhdGVET01OZXN0aW5nKG51bGwsIHN0cmluZywgb3duQW5jZXN0b3JJbmZvKTtcbiAgICB9XG5cbiAgICBwYXJlbnROYW1lc3BhY2UgPSBob3N0Q29udGV4dERldi5uYW1lc3BhY2U7XG4gIH1cblxuICB2YXIgZG9tRWxlbWVudCA9IGNyZWF0ZUVsZW1lbnQodHlwZSwgcHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgcGFyZW50TmFtZXNwYWNlKTtcbiAgcHJlY2FjaGVGaWJlck5vZGUoaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSwgZG9tRWxlbWVudCk7XG4gIHVwZGF0ZUZpYmVyUHJvcHMoZG9tRWxlbWVudCwgcHJvcHMpO1xuICByZXR1cm4gZG9tRWxlbWVudDtcbn1cbmZ1bmN0aW9uIGFwcGVuZEluaXRpYWxDaGlsZChwYXJlbnRJbnN0YW5jZSwgY2hpbGQpIHtcbiAgcGFyZW50SW5zdGFuY2UuYXBwZW5kQ2hpbGQoY2hpbGQpO1xufVxuZnVuY3Rpb24gZmluYWxpemVJbml0aWFsQ2hpbGRyZW4oZG9tRWxlbWVudCwgdHlwZSwgcHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaG9zdENvbnRleHQpIHtcbiAgc2V0SW5pdGlhbFByb3BlcnRpZXMoZG9tRWxlbWVudCwgdHlwZSwgcHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSk7XG5cbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnYnV0dG9uJzpcbiAgICBjYXNlICdpbnB1dCc6XG4gICAgY2FzZSAnc2VsZWN0JzpcbiAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICByZXR1cm4gISFwcm9wcy5hdXRvRm9jdXM7XG5cbiAgICBjYXNlICdpbWcnOlxuICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5mdW5jdGlvbiBwcmVwYXJlVXBkYXRlKGRvbUVsZW1lbnQsIHR5cGUsIG9sZFByb3BzLCBuZXdQcm9wcywgcm9vdENvbnRhaW5lckluc3RhbmNlLCBob3N0Q29udGV4dCkge1xuICB7XG4gICAgdmFyIGhvc3RDb250ZXh0RGV2ID0gaG9zdENvbnRleHQ7XG5cbiAgICBpZiAodHlwZW9mIG5ld1Byb3BzLmNoaWxkcmVuICE9PSB0eXBlb2Ygb2xkUHJvcHMuY2hpbGRyZW4gJiYgKHR5cGVvZiBuZXdQcm9wcy5jaGlsZHJlbiA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIG5ld1Byb3BzLmNoaWxkcmVuID09PSAnbnVtYmVyJykpIHtcbiAgICAgIHZhciBzdHJpbmcgPSAnJyArIG5ld1Byb3BzLmNoaWxkcmVuO1xuICAgICAgdmFyIG93bkFuY2VzdG9ySW5mbyA9IHVwZGF0ZWRBbmNlc3RvckluZm8oaG9zdENvbnRleHREZXYuYW5jZXN0b3JJbmZvLCB0eXBlKTtcbiAgICAgIHZhbGlkYXRlRE9NTmVzdGluZyhudWxsLCBzdHJpbmcsIG93bkFuY2VzdG9ySW5mbyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGRpZmZQcm9wZXJ0aWVzKGRvbUVsZW1lbnQsIHR5cGUsIG9sZFByb3BzLCBuZXdQcm9wcyk7XG59XG5mdW5jdGlvbiBzaG91bGRTZXRUZXh0Q29udGVudCh0eXBlLCBwcm9wcykge1xuICByZXR1cm4gdHlwZSA9PT0gJ3RleHRhcmVhJyB8fCB0eXBlID09PSAnbm9zY3JpcHQnIHx8IHR5cGVvZiBwcm9wcy5jaGlsZHJlbiA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHByb3BzLmNoaWxkcmVuID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgcHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwgPT09ICdvYmplY3QnICYmIHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MICE9PSBudWxsICYmIHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MLl9faHRtbCAhPSBudWxsO1xufVxuZnVuY3Rpb24gY3JlYXRlVGV4dEluc3RhbmNlKHRleHQsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaG9zdENvbnRleHQsIGludGVybmFsSW5zdGFuY2VIYW5kbGUpIHtcbiAge1xuICAgIHZhciBob3N0Q29udGV4dERldiA9IGhvc3RDb250ZXh0O1xuICAgIHZhbGlkYXRlRE9NTmVzdGluZyhudWxsLCB0ZXh0LCBob3N0Q29udGV4dERldi5hbmNlc3RvckluZm8pO1xuICB9XG5cbiAgdmFyIHRleHROb2RlID0gY3JlYXRlVGV4dE5vZGUodGV4dCwgcm9vdENvbnRhaW5lckluc3RhbmNlKTtcbiAgcHJlY2FjaGVGaWJlck5vZGUoaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSwgdGV4dE5vZGUpO1xuICByZXR1cm4gdGV4dE5vZGU7XG59XG5mdW5jdGlvbiBnZXRDdXJyZW50RXZlbnRQcmlvcml0eSgpIHtcbiAgdmFyIGN1cnJlbnRFdmVudCA9IHdpbmRvdy5ldmVudDtcblxuICBpZiAoY3VycmVudEV2ZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gRGVmYXVsdEV2ZW50UHJpb3JpdHk7XG4gIH1cblxuICByZXR1cm4gZ2V0RXZlbnRQcmlvcml0eShjdXJyZW50RXZlbnQudHlwZSk7XG59XG4vLyBpZiBhIGNvbXBvbmVudCBqdXN0IGltcG9ydHMgUmVhY3RET00gKGUuZy4gZm9yIGZpbmRET01Ob2RlKS5cbi8vIFNvbWUgZW52aXJvbm1lbnRzIG1pZ2h0IG5vdCBoYXZlIHNldFRpbWVvdXQgb3IgY2xlYXJUaW1lb3V0LlxuXG52YXIgc2NoZWR1bGVUaW1lb3V0ID0gdHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicgPyBzZXRUaW1lb3V0IDogdW5kZWZpbmVkO1xudmFyIGNhbmNlbFRpbWVvdXQgPSB0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nID8gY2xlYXJUaW1lb3V0IDogdW5kZWZpbmVkO1xudmFyIG5vVGltZW91dCA9IC0xO1xudmFyIGxvY2FsUHJvbWlzZSA9IHR5cGVvZiBQcm9taXNlID09PSAnZnVuY3Rpb24nID8gUHJvbWlzZSA6IHVuZGVmaW5lZDsgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLVxudmFyIHNjaGVkdWxlTWljcm90YXNrID0gdHlwZW9mIHF1ZXVlTWljcm90YXNrID09PSAnZnVuY3Rpb24nID8gcXVldWVNaWNyb3Rhc2sgOiB0eXBlb2YgbG9jYWxQcm9taXNlICE9PSAndW5kZWZpbmVkJyA/IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICByZXR1cm4gbG9jYWxQcm9taXNlLnJlc29sdmUobnVsbCkudGhlbihjYWxsYmFjaykuY2F0Y2goaGFuZGxlRXJyb3JJbk5leHRUaWNrKTtcbn0gOiBzY2hlZHVsZVRpbWVvdXQ7IC8vIFRPRE86IERldGVybWluZSB0aGUgYmVzdCBmYWxsYmFjayBoZXJlLlxuXG5mdW5jdGlvbiBoYW5kbGVFcnJvckluTmV4dFRpY2soZXJyb3IpIHtcbiAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH0pO1xufSAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBjb21taXRNb3VudChkb21FbGVtZW50LCB0eXBlLCBuZXdQcm9wcywgaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSkge1xuICAvLyBEZXNwaXRlIHRoZSBuYW1pbmcgdGhhdCBtaWdodCBpbXBseSBvdGhlcndpc2UsIHRoaXMgbWV0aG9kIG9ubHlcbiAgLy8gZmlyZXMgaWYgdGhlcmUgaXMgYW4gYFVwZGF0ZWAgZWZmZWN0IHNjaGVkdWxlZCBkdXJpbmcgbW91bnRpbmcuXG4gIC8vIFRoaXMgaGFwcGVucyBpZiBgZmluYWxpemVJbml0aWFsQ2hpbGRyZW5gIHJldHVybnMgYHRydWVgICh3aGljaCBpdFxuICAvLyBkb2VzIHRvIGltcGxlbWVudCB0aGUgYGF1dG9Gb2N1c2AgYXR0cmlidXRlIG9uIHRoZSBjbGllbnQpLiBCdXRcbiAgLy8gdGhlcmUgYXJlIGFsc28gb3RoZXIgY2FzZXMgd2hlbiB0aGlzIG1pZ2h0IGhhcHBlbiAoc3VjaCBhcyBwYXRjaGluZ1xuICAvLyB1cCB0ZXh0IGNvbnRlbnQgZHVyaW5nIGh5ZHJhdGlvbiBtaXNtYXRjaCkuIFNvIHdlJ2xsIGNoZWNrIHRoaXMgYWdhaW4uXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ2J1dHRvbic6XG4gICAgY2FzZSAnaW5wdXQnOlxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgY2FzZSAndGV4dGFyZWEnOlxuICAgICAgaWYgKG5ld1Byb3BzLmF1dG9Gb2N1cykge1xuICAgICAgICBkb21FbGVtZW50LmZvY3VzKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcblxuICAgIGNhc2UgJ2ltZyc6XG4gICAgICB7XG4gICAgICAgIGlmIChuZXdQcm9wcy5zcmMpIHtcbiAgICAgICAgICBkb21FbGVtZW50LnNyYyA9IG5ld1Byb3BzLnNyYztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gY29tbWl0VXBkYXRlKGRvbUVsZW1lbnQsIHVwZGF0ZVBheWxvYWQsIHR5cGUsIG9sZFByb3BzLCBuZXdQcm9wcywgaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSkge1xuICAvLyBBcHBseSB0aGUgZGlmZiB0byB0aGUgRE9NIG5vZGUuXG4gIHVwZGF0ZVByb3BlcnRpZXMoZG9tRWxlbWVudCwgdXBkYXRlUGF5bG9hZCwgdHlwZSwgb2xkUHJvcHMsIG5ld1Byb3BzKTsgLy8gVXBkYXRlIHRoZSBwcm9wcyBoYW5kbGUgc28gdGhhdCB3ZSBrbm93IHdoaWNoIHByb3BzIGFyZSB0aGUgb25lcyB3aXRoXG4gIC8vIHdpdGggY3VycmVudCBldmVudCBoYW5kbGVycy5cblxuICB1cGRhdGVGaWJlclByb3BzKGRvbUVsZW1lbnQsIG5ld1Byb3BzKTtcbn1cbmZ1bmN0aW9uIHJlc2V0VGV4dENvbnRlbnQoZG9tRWxlbWVudCkge1xuICBzZXRUZXh0Q29udGVudChkb21FbGVtZW50LCAnJyk7XG59XG5mdW5jdGlvbiBjb21taXRUZXh0VXBkYXRlKHRleHRJbnN0YW5jZSwgb2xkVGV4dCwgbmV3VGV4dCkge1xuICB0ZXh0SW5zdGFuY2Uubm9kZVZhbHVlID0gbmV3VGV4dDtcbn1cbmZ1bmN0aW9uIGFwcGVuZENoaWxkKHBhcmVudEluc3RhbmNlLCBjaGlsZCkge1xuICBwYXJlbnRJbnN0YW5jZS5hcHBlbmRDaGlsZChjaGlsZCk7XG59XG5mdW5jdGlvbiBhcHBlbmRDaGlsZFRvQ29udGFpbmVyKGNvbnRhaW5lciwgY2hpbGQpIHtcbiAgdmFyIHBhcmVudE5vZGU7XG5cbiAgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgcGFyZW50Tm9kZSA9IGNvbnRhaW5lci5wYXJlbnROb2RlO1xuICAgIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGNoaWxkLCBjb250YWluZXIpO1xuICB9IGVsc2Uge1xuICAgIHBhcmVudE5vZGUgPSBjb250YWluZXI7XG4gICAgcGFyZW50Tm9kZS5hcHBlbmRDaGlsZChjaGlsZCk7XG4gIH0gLy8gVGhpcyBjb250YWluZXIgbWlnaHQgYmUgdXNlZCBmb3IgYSBwb3J0YWwuXG4gIC8vIElmIHNvbWV0aGluZyBpbnNpZGUgYSBwb3J0YWwgaXMgY2xpY2tlZCwgdGhhdCBjbGljayBzaG91bGQgYnViYmxlXG4gIC8vIHRocm91Z2ggdGhlIFJlYWN0IHRyZWUuIEhvd2V2ZXIsIG9uIE1vYmlsZSBTYWZhcmkgdGhlIGNsaWNrIHdvdWxkXG4gIC8vIG5ldmVyIGJ1YmJsZSB0aHJvdWdoIHRoZSAqRE9NKiB0cmVlIHVubGVzcyBhbiBhbmNlc3RvciB3aXRoIG9uY2xpY2tcbiAgLy8gZXZlbnQgZXhpc3RzLiBTbyB3ZSB3b3VsZG4ndCBzZWUgaXQgYW5kIGRpc3BhdGNoIGl0LlxuICAvLyBUaGlzIGlzIHdoeSB3ZSBlbnN1cmUgdGhhdCBub24gUmVhY3Qgcm9vdCBjb250YWluZXJzIGhhdmUgaW5saW5lIG9uY2xpY2tcbiAgLy8gZGVmaW5lZC5cbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xMTkxOFxuXG5cbiAgdmFyIHJlYWN0Um9vdENvbnRhaW5lciA9IGNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyO1xuXG4gIGlmICgocmVhY3RSb290Q29udGFpbmVyID09PSBudWxsIHx8IHJlYWN0Um9vdENvbnRhaW5lciA9PT0gdW5kZWZpbmVkKSAmJiBwYXJlbnROb2RlLm9uY2xpY2sgPT09IG51bGwpIHtcbiAgICAvLyBUT0RPOiBUaGlzIGNhc3QgbWF5IG5vdCBiZSBzb3VuZCBmb3IgU1ZHLCBNYXRoTUwgb3IgY3VzdG9tIGVsZW1lbnRzLlxuICAgIHRyYXBDbGlja09uTm9uSW50ZXJhY3RpdmVFbGVtZW50KHBhcmVudE5vZGUpO1xuICB9XG59XG5mdW5jdGlvbiBpbnNlcnRCZWZvcmUocGFyZW50SW5zdGFuY2UsIGNoaWxkLCBiZWZvcmVDaGlsZCkge1xuICBwYXJlbnRJbnN0YW5jZS5pbnNlcnRCZWZvcmUoY2hpbGQsIGJlZm9yZUNoaWxkKTtcbn1cbmZ1bmN0aW9uIGluc2VydEluQ29udGFpbmVyQmVmb3JlKGNvbnRhaW5lciwgY2hpbGQsIGJlZm9yZUNoaWxkKSB7XG4gIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkge1xuICAgIGNvbnRhaW5lci5wYXJlbnROb2RlLmluc2VydEJlZm9yZShjaGlsZCwgYmVmb3JlQ2hpbGQpO1xuICB9IGVsc2Uge1xuICAgIGNvbnRhaW5lci5pbnNlcnRCZWZvcmUoY2hpbGQsIGJlZm9yZUNoaWxkKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW1vdmVDaGlsZChwYXJlbnRJbnN0YW5jZSwgY2hpbGQpIHtcbiAgcGFyZW50SW5zdGFuY2UucmVtb3ZlQ2hpbGQoY2hpbGQpO1xufVxuZnVuY3Rpb24gcmVtb3ZlQ2hpbGRGcm9tQ29udGFpbmVyKGNvbnRhaW5lciwgY2hpbGQpIHtcbiAgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgY29udGFpbmVyLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY2hpbGQpO1xuICB9IGVsc2Uge1xuICAgIGNvbnRhaW5lci5yZW1vdmVDaGlsZChjaGlsZCk7XG4gIH1cbn1cbmZ1bmN0aW9uIGNsZWFyU3VzcGVuc2VCb3VuZGFyeShwYXJlbnRJbnN0YW5jZSwgc3VzcGVuc2VJbnN0YW5jZSkge1xuICB2YXIgbm9kZSA9IHN1c3BlbnNlSW5zdGFuY2U7IC8vIERlbGV0ZSBhbGwgbm9kZXMgd2l0aGluIHRoaXMgc3VzcGVuc2UgYm91bmRhcnkuXG4gIC8vIFRoZXJlIG1pZ2h0IGJlIG5lc3RlZCBub2RlcyBzbyB3ZSBuZWVkIHRvIGtlZXAgdHJhY2sgb2YgaG93XG4gIC8vIGRlZXAgd2UgYXJlIGFuZCBvbmx5IGJyZWFrIG91dCB3aGVuIHdlJ3JlIGJhY2sgb24gdG9wLlxuXG4gIHZhciBkZXB0aCA9IDA7XG5cbiAgZG8ge1xuICAgIHZhciBuZXh0Tm9kZSA9IG5vZGUubmV4dFNpYmxpbmc7XG4gICAgcGFyZW50SW5zdGFuY2UucmVtb3ZlQ2hpbGQobm9kZSk7XG5cbiAgICBpZiAobmV4dE5vZGUgJiYgbmV4dE5vZGUubm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkge1xuICAgICAgdmFyIGRhdGEgPSBuZXh0Tm9kZS5kYXRhO1xuXG4gICAgICBpZiAoZGF0YSA9PT0gU1VTUEVOU0VfRU5EX0RBVEEpIHtcbiAgICAgICAgaWYgKGRlcHRoID09PSAwKSB7XG4gICAgICAgICAgcGFyZW50SW5zdGFuY2UucmVtb3ZlQ2hpbGQobmV4dE5vZGUpOyAvLyBSZXRyeSBpZiBhbnkgZXZlbnQgcmVwbGF5aW5nIHdhcyBibG9ja2VkIG9uIHRoaXMuXG5cbiAgICAgICAgICByZXRyeUlmQmxvY2tlZE9uKHN1c3BlbnNlSW5zdGFuY2UpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZXB0aC0tO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGRhdGEgPT09IFNVU1BFTlNFX1NUQVJUX0RBVEEgfHwgZGF0YSA9PT0gU1VTUEVOU0VfUEVORElOR19TVEFSVF9EQVRBIHx8IGRhdGEgPT09IFNVU1BFTlNFX0ZBTExCQUNLX1NUQVJUX0RBVEEpIHtcbiAgICAgICAgZGVwdGgrKztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBub2RlID0gbmV4dE5vZGU7XG4gIH0gd2hpbGUgKG5vZGUpOyAvLyBUT0RPOiBXYXJuLCB3ZSBkaWRuJ3QgZmluZCB0aGUgZW5kIGNvbW1lbnQgYm91bmRhcnkuXG4gIC8vIFJldHJ5IGlmIGFueSBldmVudCByZXBsYXlpbmcgd2FzIGJsb2NrZWQgb24gdGhpcy5cblxuXG4gIHJldHJ5SWZCbG9ja2VkT24oc3VzcGVuc2VJbnN0YW5jZSk7XG59XG5mdW5jdGlvbiBjbGVhclN1c3BlbnNlQm91bmRhcnlGcm9tQ29udGFpbmVyKGNvbnRhaW5lciwgc3VzcGVuc2VJbnN0YW5jZSkge1xuICBpZiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUpIHtcbiAgICBjbGVhclN1c3BlbnNlQm91bmRhcnkoY29udGFpbmVyLnBhcmVudE5vZGUsIHN1c3BlbnNlSW5zdGFuY2UpO1xuICB9IGVsc2UgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgY2xlYXJTdXNwZW5zZUJvdW5kYXJ5KGNvbnRhaW5lciwgc3VzcGVuc2VJbnN0YW5jZSk7XG4gIH0gLy8gUmV0cnkgaWYgYW55IGV2ZW50IHJlcGxheWluZyB3YXMgYmxvY2tlZCBvbiB0aGlzLlxuXG5cbiAgcmV0cnlJZkJsb2NrZWRPbihjb250YWluZXIpO1xufVxuZnVuY3Rpb24gaGlkZUluc3RhbmNlKGluc3RhbmNlKSB7XG4gIC8vIFRPRE86IERvZXMgdGhpcyB3b3JrIGZvciBhbGwgZWxlbWVudCB0eXBlcz8gV2hhdCBhYm91dCBNYXRoTUw/IFNob3VsZCB3ZVxuICAvLyBwYXNzIGhvc3QgY29udGV4dCB0byB0aGlzIG1ldGhvZD9cbiAgaW5zdGFuY2UgPSBpbnN0YW5jZTtcbiAgdmFyIHN0eWxlID0gaW5zdGFuY2Uuc3R5bGU7XG5cbiAgaWYgKHR5cGVvZiBzdHlsZS5zZXRQcm9wZXJ0eSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHN0eWxlLnNldFByb3BlcnR5KCdkaXNwbGF5JywgJ25vbmUnLCAnaW1wb3J0YW50Jyk7XG4gIH0gZWxzZSB7XG4gICAgc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgfVxufVxuZnVuY3Rpb24gaGlkZVRleHRJbnN0YW5jZSh0ZXh0SW5zdGFuY2UpIHtcbiAgdGV4dEluc3RhbmNlLm5vZGVWYWx1ZSA9ICcnO1xufVxuZnVuY3Rpb24gdW5oaWRlSW5zdGFuY2UoaW5zdGFuY2UsIHByb3BzKSB7XG4gIGluc3RhbmNlID0gaW5zdGFuY2U7XG4gIHZhciBzdHlsZVByb3AgPSBwcm9wc1tTVFlMRSQxXTtcbiAgdmFyIGRpc3BsYXkgPSBzdHlsZVByb3AgIT09IHVuZGVmaW5lZCAmJiBzdHlsZVByb3AgIT09IG51bGwgJiYgc3R5bGVQcm9wLmhhc093blByb3BlcnR5KCdkaXNwbGF5JykgPyBzdHlsZVByb3AuZGlzcGxheSA6IG51bGw7XG4gIGluc3RhbmNlLnN0eWxlLmRpc3BsYXkgPSBkYW5nZXJvdXNTdHlsZVZhbHVlKCdkaXNwbGF5JywgZGlzcGxheSk7XG59XG5mdW5jdGlvbiB1bmhpZGVUZXh0SW5zdGFuY2UodGV4dEluc3RhbmNlLCB0ZXh0KSB7XG4gIHRleHRJbnN0YW5jZS5ub2RlVmFsdWUgPSB0ZXh0O1xufVxuZnVuY3Rpb24gY2xlYXJDb250YWluZXIoY29udGFpbmVyKSB7XG4gIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSkge1xuICAgIGNvbnRhaW5lci50ZXh0Q29udGVudCA9ICcnO1xuICB9IGVsc2UgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gRE9DVU1FTlRfTk9ERSkge1xuICAgIGlmIChjb250YWluZXIuZG9jdW1lbnRFbGVtZW50KSB7XG4gICAgICBjb250YWluZXIucmVtb3ZlQ2hpbGQoY29udGFpbmVyLmRvY3VtZW50RWxlbWVudCk7XG4gICAgfVxuICB9XG59IC8vIC0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIGNhbkh5ZHJhdGVJbnN0YW5jZShpbnN0YW5jZSwgdHlwZSwgcHJvcHMpIHtcbiAgaWYgKGluc3RhbmNlLm5vZGVUeXBlICE9PSBFTEVNRU5UX05PREUgfHwgdHlwZS50b0xvd2VyQ2FzZSgpICE9PSBpbnN0YW5jZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH0gLy8gVGhpcyBoYXMgbm93IGJlZW4gcmVmaW5lZCB0byBhbiBlbGVtZW50IG5vZGUuXG5cblxuICByZXR1cm4gaW5zdGFuY2U7XG59XG5mdW5jdGlvbiBjYW5IeWRyYXRlVGV4dEluc3RhbmNlKGluc3RhbmNlLCB0ZXh0KSB7XG4gIGlmICh0ZXh0ID09PSAnJyB8fCBpbnN0YW5jZS5ub2RlVHlwZSAhPT0gVEVYVF9OT0RFKSB7XG4gICAgLy8gRW1wdHkgc3RyaW5ncyBhcmUgbm90IHBhcnNlZCBieSBIVE1MIHNvIHRoZXJlIHdvbid0IGJlIGEgY29ycmVjdCBtYXRjaCBoZXJlLlxuICAgIHJldHVybiBudWxsO1xuICB9IC8vIFRoaXMgaGFzIG5vdyBiZWVuIHJlZmluZWQgdG8gYSB0ZXh0IG5vZGUuXG5cblxuICByZXR1cm4gaW5zdGFuY2U7XG59XG5mdW5jdGlvbiBjYW5IeWRyYXRlU3VzcGVuc2VJbnN0YW5jZShpbnN0YW5jZSkge1xuICBpZiAoaW5zdGFuY2Uubm9kZVR5cGUgIT09IENPTU1FTlRfTk9ERSkge1xuICAgIC8vIEVtcHR5IHN0cmluZ3MgYXJlIG5vdCBwYXJzZWQgYnkgSFRNTCBzbyB0aGVyZSB3b24ndCBiZSBhIGNvcnJlY3QgbWF0Y2ggaGVyZS5cbiAgICByZXR1cm4gbnVsbDtcbiAgfSAvLyBUaGlzIGhhcyBub3cgYmVlbiByZWZpbmVkIHRvIGEgc3VzcGVuc2Ugbm9kZS5cblxuXG4gIHJldHVybiBpbnN0YW5jZTtcbn1cbmZ1bmN0aW9uIGlzU3VzcGVuc2VJbnN0YW5jZVBlbmRpbmcoaW5zdGFuY2UpIHtcbiAgcmV0dXJuIGluc3RhbmNlLmRhdGEgPT09IFNVU1BFTlNFX1BFTkRJTkdfU1RBUlRfREFUQTtcbn1cbmZ1bmN0aW9uIGlzU3VzcGVuc2VJbnN0YW5jZUZhbGxiYWNrKGluc3RhbmNlKSB7XG4gIHJldHVybiBpbnN0YW5jZS5kYXRhID09PSBTVVNQRU5TRV9GQUxMQkFDS19TVEFSVF9EQVRBO1xufVxuZnVuY3Rpb24gZ2V0U3VzcGVuc2VJbnN0YW5jZUZhbGxiYWNrRXJyb3JEZXRhaWxzKGluc3RhbmNlKSB7XG4gIHZhciBkYXRhc2V0ID0gaW5zdGFuY2UubmV4dFNpYmxpbmcgJiYgaW5zdGFuY2UubmV4dFNpYmxpbmcuZGF0YXNldDtcbiAgdmFyIGRpZ2VzdCwgbWVzc2FnZSwgc3RhY2s7XG5cbiAgaWYgKGRhdGFzZXQpIHtcbiAgICBkaWdlc3QgPSBkYXRhc2V0LmRnc3Q7XG5cbiAgICB7XG4gICAgICBtZXNzYWdlID0gZGF0YXNldC5tc2c7XG4gICAgICBzdGFjayA9IGRhdGFzZXQuc3RjaztcbiAgICB9XG4gIH1cblxuICB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICBkaWdlc3Q6IGRpZ2VzdCxcbiAgICAgIHN0YWNrOiBzdGFja1xuICAgIH07XG4gIH0gLy8gbGV0IHZhbHVlID0ge21lc3NhZ2U6IHVuZGVmaW5lZCwgaGFzaDogdW5kZWZpbmVkfTtcbiAgLy8gY29uc3QgbmV4dFNpYmxpbmcgPSBpbnN0YW5jZS5uZXh0U2libGluZztcbiAgLy8gaWYgKG5leHRTaWJsaW5nKSB7XG4gIC8vICAgY29uc3QgZGF0YXNldCA9ICgobmV4dFNpYmxpbmc6IGFueSk6IEhUTUxUZW1wbGF0ZUVsZW1lbnQpLmRhdGFzZXQ7XG4gIC8vICAgdmFsdWUubWVzc2FnZSA9IGRhdGFzZXQubXNnO1xuICAvLyAgIHZhbHVlLmhhc2ggPSBkYXRhc2V0Lmhhc2g7XG4gIC8vICAgaWYgKHRydWUpIHtcbiAgLy8gICAgIHZhbHVlLnN0YWNrID0gZGF0YXNldC5zdGFjaztcbiAgLy8gICB9XG4gIC8vIH1cbiAgLy8gcmV0dXJuIHZhbHVlO1xuXG59XG5mdW5jdGlvbiByZWdpc3RlclN1c3BlbnNlSW5zdGFuY2VSZXRyeShpbnN0YW5jZSwgY2FsbGJhY2spIHtcbiAgaW5zdGFuY2UuX3JlYWN0UmV0cnkgPSBjYWxsYmFjaztcbn1cblxuZnVuY3Rpb24gZ2V0TmV4dEh5ZHJhdGFibGUobm9kZSkge1xuICAvLyBTa2lwIG5vbi1oeWRyYXRhYmxlIG5vZGVzLlxuICBmb3IgKDsgbm9kZSAhPSBudWxsOyBub2RlID0gbm9kZS5uZXh0U2libGluZykge1xuICAgIHZhciBub2RlVHlwZSA9IG5vZGUubm9kZVR5cGU7XG5cbiAgICBpZiAobm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSB8fCBub2RlVHlwZSA9PT0gVEVYVF9OT0RFKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAobm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkge1xuICAgICAgdmFyIG5vZGVEYXRhID0gbm9kZS5kYXRhO1xuXG4gICAgICBpZiAobm9kZURhdGEgPT09IFNVU1BFTlNFX1NUQVJUX0RBVEEgfHwgbm9kZURhdGEgPT09IFNVU1BFTlNFX0ZBTExCQUNLX1NUQVJUX0RBVEEgfHwgbm9kZURhdGEgPT09IFNVU1BFTlNFX1BFTkRJTkdfU1RBUlRfREFUQSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGVEYXRhID09PSBTVVNQRU5TRV9FTkRfREFUQSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbm9kZTtcbn1cblxuZnVuY3Rpb24gZ2V0TmV4dEh5ZHJhdGFibGVTaWJsaW5nKGluc3RhbmNlKSB7XG4gIHJldHVybiBnZXROZXh0SHlkcmF0YWJsZShpbnN0YW5jZS5uZXh0U2libGluZyk7XG59XG5mdW5jdGlvbiBnZXRGaXJzdEh5ZHJhdGFibGVDaGlsZChwYXJlbnRJbnN0YW5jZSkge1xuICByZXR1cm4gZ2V0TmV4dEh5ZHJhdGFibGUocGFyZW50SW5zdGFuY2UuZmlyc3RDaGlsZCk7XG59XG5mdW5jdGlvbiBnZXRGaXJzdEh5ZHJhdGFibGVDaGlsZFdpdGhpbkNvbnRhaW5lcihwYXJlbnRDb250YWluZXIpIHtcbiAgcmV0dXJuIGdldE5leHRIeWRyYXRhYmxlKHBhcmVudENvbnRhaW5lci5maXJzdENoaWxkKTtcbn1cbmZ1bmN0aW9uIGdldEZpcnN0SHlkcmF0YWJsZUNoaWxkV2l0aGluU3VzcGVuc2VJbnN0YW5jZShwYXJlbnRJbnN0YW5jZSkge1xuICByZXR1cm4gZ2V0TmV4dEh5ZHJhdGFibGUocGFyZW50SW5zdGFuY2UubmV4dFNpYmxpbmcpO1xufVxuZnVuY3Rpb24gaHlkcmF0ZUluc3RhbmNlKGluc3RhbmNlLCB0eXBlLCBwcm9wcywgcm9vdENvbnRhaW5lckluc3RhbmNlLCBob3N0Q29udGV4dCwgaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSwgc2hvdWxkV2FybkRldikge1xuICBwcmVjYWNoZUZpYmVyTm9kZShpbnRlcm5hbEluc3RhbmNlSGFuZGxlLCBpbnN0YW5jZSk7IC8vIFRPRE86IFBvc3NpYmx5IGRlZmVyIHRoaXMgdW50aWwgdGhlIGNvbW1pdCBwaGFzZSB3aGVyZSBhbGwgdGhlIGV2ZW50c1xuICAvLyBnZXQgYXR0YWNoZWQuXG5cbiAgdXBkYXRlRmliZXJQcm9wcyhpbnN0YW5jZSwgcHJvcHMpO1xuICB2YXIgcGFyZW50TmFtZXNwYWNlO1xuXG4gIHtcbiAgICB2YXIgaG9zdENvbnRleHREZXYgPSBob3N0Q29udGV4dDtcbiAgICBwYXJlbnROYW1lc3BhY2UgPSBob3N0Q29udGV4dERldi5uYW1lc3BhY2U7XG4gIH0gLy8gVE9ETzogVGVtcG9yYXJ5IGhhY2sgdG8gY2hlY2sgaWYgd2UncmUgaW4gYSBjb25jdXJyZW50IHJvb3QuIFdlIGNhbiBkZWxldGVcbiAgLy8gd2hlbiB0aGUgbGVnYWN5IHJvb3QgQVBJIGlzIHJlbW92ZWQuXG5cblxuICB2YXIgaXNDb25jdXJyZW50TW9kZSA9IChpbnRlcm5hbEluc3RhbmNlSGFuZGxlLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZTtcbiAgcmV0dXJuIGRpZmZIeWRyYXRlZFByb3BlcnRpZXMoaW5zdGFuY2UsIHR5cGUsIHByb3BzLCBwYXJlbnROYW1lc3BhY2UsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaXNDb25jdXJyZW50TW9kZSwgc2hvdWxkV2FybkRldik7XG59XG5mdW5jdGlvbiBoeWRyYXRlVGV4dEluc3RhbmNlKHRleHRJbnN0YW5jZSwgdGV4dCwgaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSwgc2hvdWxkV2FybkRldikge1xuICBwcmVjYWNoZUZpYmVyTm9kZShpbnRlcm5hbEluc3RhbmNlSGFuZGxlLCB0ZXh0SW5zdGFuY2UpOyAvLyBUT0RPOiBUZW1wb3JhcnkgaGFjayB0byBjaGVjayBpZiB3ZSdyZSBpbiBhIGNvbmN1cnJlbnQgcm9vdC4gV2UgY2FuIGRlbGV0ZVxuICAvLyB3aGVuIHRoZSBsZWdhY3kgcm9vdCBBUEkgaXMgcmVtb3ZlZC5cblxuICB2YXIgaXNDb25jdXJyZW50TW9kZSA9IChpbnRlcm5hbEluc3RhbmNlSGFuZGxlLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZTtcbiAgcmV0dXJuIGRpZmZIeWRyYXRlZFRleHQodGV4dEluc3RhbmNlLCB0ZXh0KTtcbn1cbmZ1bmN0aW9uIGh5ZHJhdGVTdXNwZW5zZUluc3RhbmNlKHN1c3BlbnNlSW5zdGFuY2UsIGludGVybmFsSW5zdGFuY2VIYW5kbGUpIHtcbiAgcHJlY2FjaGVGaWJlck5vZGUoaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSwgc3VzcGVuc2VJbnN0YW5jZSk7XG59XG5mdW5jdGlvbiBnZXROZXh0SHlkcmF0YWJsZUluc3RhbmNlQWZ0ZXJTdXNwZW5zZUluc3RhbmNlKHN1c3BlbnNlSW5zdGFuY2UpIHtcbiAgdmFyIG5vZGUgPSBzdXNwZW5zZUluc3RhbmNlLm5leHRTaWJsaW5nOyAvLyBTa2lwIHBhc3QgYWxsIG5vZGVzIHdpdGhpbiB0aGlzIHN1c3BlbnNlIGJvdW5kYXJ5LlxuICAvLyBUaGVyZSBtaWdodCBiZSBuZXN0ZWQgbm9kZXMgc28gd2UgbmVlZCB0byBrZWVwIHRyYWNrIG9mIGhvd1xuICAvLyBkZWVwIHdlIGFyZSBhbmQgb25seSBicmVhayBvdXQgd2hlbiB3ZSdyZSBiYWNrIG9uIHRvcC5cblxuICB2YXIgZGVwdGggPSAwO1xuXG4gIHdoaWxlIChub2RlKSB7XG4gICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkge1xuICAgICAgdmFyIGRhdGEgPSBub2RlLmRhdGE7XG5cbiAgICAgIGlmIChkYXRhID09PSBTVVNQRU5TRV9FTkRfREFUQSkge1xuICAgICAgICBpZiAoZGVwdGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gZ2V0TmV4dEh5ZHJhdGFibGVTaWJsaW5nKG5vZGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlcHRoLS07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZGF0YSA9PT0gU1VTUEVOU0VfU1RBUlRfREFUQSB8fCBkYXRhID09PSBTVVNQRU5TRV9GQUxMQkFDS19TVEFSVF9EQVRBIHx8IGRhdGEgPT09IFNVU1BFTlNFX1BFTkRJTkdfU1RBUlRfREFUQSkge1xuICAgICAgICBkZXB0aCsrO1xuICAgICAgfVxuICAgIH1cblxuICAgIG5vZGUgPSBub2RlLm5leHRTaWJsaW5nO1xuICB9IC8vIFRPRE86IFdhcm4sIHdlIGRpZG4ndCBmaW5kIHRoZSBlbmQgY29tbWVudCBib3VuZGFyeS5cblxuXG4gIHJldHVybiBudWxsO1xufSAvLyBSZXR1cm5zIHRoZSBTdXNwZW5zZUluc3RhbmNlIGlmIHRoaXMgbm9kZSBpcyBhIGRpcmVjdCBjaGlsZCBvZiBhXG4vLyBTdXNwZW5zZUluc3RhbmNlLiBJLmUuIGlmIGl0cyBwcmV2aW91cyBzaWJsaW5nIGlzIGEgQ29tbWVudCB3aXRoXG4vLyBTVVNQRU5TRV94X1NUQVJUX0RBVEEuIE90aGVyd2lzZSwgbnVsbC5cblxuZnVuY3Rpb24gZ2V0UGFyZW50U3VzcGVuc2VJbnN0YW5jZSh0YXJnZXRJbnN0YW5jZSkge1xuICB2YXIgbm9kZSA9IHRhcmdldEluc3RhbmNlLnByZXZpb3VzU2libGluZzsgLy8gU2tpcCBwYXN0IGFsbCBub2RlcyB3aXRoaW4gdGhpcyBzdXNwZW5zZSBib3VuZGFyeS5cbiAgLy8gVGhlcmUgbWlnaHQgYmUgbmVzdGVkIG5vZGVzIHNvIHdlIG5lZWQgdG8ga2VlcCB0cmFjayBvZiBob3dcbiAgLy8gZGVlcCB3ZSBhcmUgYW5kIG9ubHkgYnJlYWsgb3V0IHdoZW4gd2UncmUgYmFjayBvbiB0b3AuXG5cbiAgdmFyIGRlcHRoID0gMDtcblxuICB3aGlsZSAobm9kZSkge1xuICAgIGlmIChub2RlLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUpIHtcbiAgICAgIHZhciBkYXRhID0gbm9kZS5kYXRhO1xuXG4gICAgICBpZiAoZGF0YSA9PT0gU1VTUEVOU0VfU1RBUlRfREFUQSB8fCBkYXRhID09PSBTVVNQRU5TRV9GQUxMQkFDS19TVEFSVF9EQVRBIHx8IGRhdGEgPT09IFNVU1BFTlNFX1BFTkRJTkdfU1RBUlRfREFUQSkge1xuICAgICAgICBpZiAoZGVwdGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZXB0aC0tO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGRhdGEgPT09IFNVU1BFTlNFX0VORF9EQVRBKSB7XG4gICAgICAgIGRlcHRoKys7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbm9kZSA9IG5vZGUucHJldmlvdXNTaWJsaW5nO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBjb21taXRIeWRyYXRlZENvbnRhaW5lcihjb250YWluZXIpIHtcbiAgLy8gUmV0cnkgaWYgYW55IGV2ZW50IHJlcGxheWluZyB3YXMgYmxvY2tlZCBvbiB0aGlzLlxuICByZXRyeUlmQmxvY2tlZE9uKGNvbnRhaW5lcik7XG59XG5mdW5jdGlvbiBjb21taXRIeWRyYXRlZFN1c3BlbnNlSW5zdGFuY2Uoc3VzcGVuc2VJbnN0YW5jZSkge1xuICAvLyBSZXRyeSBpZiBhbnkgZXZlbnQgcmVwbGF5aW5nIHdhcyBibG9ja2VkIG9uIHRoaXMuXG4gIHJldHJ5SWZCbG9ja2VkT24oc3VzcGVuc2VJbnN0YW5jZSk7XG59XG5mdW5jdGlvbiBzaG91bGREZWxldGVVbmh5ZHJhdGVkVGFpbEluc3RhbmNlcyhwYXJlbnRUeXBlKSB7XG4gIHJldHVybiBwYXJlbnRUeXBlICE9PSAnaGVhZCcgJiYgcGFyZW50VHlwZSAhPT0gJ2JvZHknO1xufVxuZnVuY3Rpb24gZGlkTm90TWF0Y2hIeWRyYXRlZENvbnRhaW5lclRleHRJbnN0YW5jZShwYXJlbnRDb250YWluZXIsIHRleHRJbnN0YW5jZSwgdGV4dCwgaXNDb25jdXJyZW50TW9kZSkge1xuICB2YXIgc2hvdWxkV2FybkRldiA9IHRydWU7XG4gIGNoZWNrRm9yVW5tYXRjaGVkVGV4dCh0ZXh0SW5zdGFuY2Uubm9kZVZhbHVlLCB0ZXh0LCBpc0NvbmN1cnJlbnRNb2RlLCBzaG91bGRXYXJuRGV2KTtcbn1cbmZ1bmN0aW9uIGRpZE5vdE1hdGNoSHlkcmF0ZWRUZXh0SW5zdGFuY2UocGFyZW50VHlwZSwgcGFyZW50UHJvcHMsIHBhcmVudEluc3RhbmNlLCB0ZXh0SW5zdGFuY2UsIHRleHQsIGlzQ29uY3VycmVudE1vZGUpIHtcbiAgaWYgKHBhcmVudFByb3BzW1NVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HJDFdICE9PSB0cnVlKSB7XG4gICAgdmFyIHNob3VsZFdhcm5EZXYgPSB0cnVlO1xuICAgIGNoZWNrRm9yVW5tYXRjaGVkVGV4dCh0ZXh0SW5zdGFuY2Uubm9kZVZhbHVlLCB0ZXh0LCBpc0NvbmN1cnJlbnRNb2RlLCBzaG91bGRXYXJuRGV2KTtcbiAgfVxufVxuZnVuY3Rpb24gZGlkTm90SHlkcmF0ZUluc3RhbmNlV2l0aGluQ29udGFpbmVyKHBhcmVudENvbnRhaW5lciwgaW5zdGFuY2UpIHtcbiAge1xuICAgIGlmIChpbnN0YW5jZS5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICB3YXJuRm9yRGVsZXRlZEh5ZHJhdGFibGVFbGVtZW50KHBhcmVudENvbnRhaW5lciwgaW5zdGFuY2UpO1xuICAgIH0gZWxzZSBpZiAoaW5zdGFuY2Uubm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkgOyBlbHNlIHtcbiAgICAgIHdhcm5Gb3JEZWxldGVkSHlkcmF0YWJsZVRleHQocGFyZW50Q29udGFpbmVyLCBpbnN0YW5jZSk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBkaWROb3RIeWRyYXRlSW5zdGFuY2VXaXRoaW5TdXNwZW5zZUluc3RhbmNlKHBhcmVudEluc3RhbmNlLCBpbnN0YW5jZSkge1xuICB7XG4gICAgLy8gJEZsb3dGaXhNZTogT25seSBFbGVtZW50IG9yIERvY3VtZW50IGNhbiBiZSBwYXJlbnQgbm9kZXMuXG4gICAgdmFyIHBhcmVudE5vZGUgPSBwYXJlbnRJbnN0YW5jZS5wYXJlbnROb2RlO1xuXG4gICAgaWYgKHBhcmVudE5vZGUgIT09IG51bGwpIHtcbiAgICAgIGlmIChpbnN0YW5jZS5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgIHdhcm5Gb3JEZWxldGVkSHlkcmF0YWJsZUVsZW1lbnQocGFyZW50Tm9kZSwgaW5zdGFuY2UpO1xuICAgICAgfSBlbHNlIGlmIChpbnN0YW5jZS5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFKSA7IGVsc2Uge1xuICAgICAgICB3YXJuRm9yRGVsZXRlZEh5ZHJhdGFibGVUZXh0KHBhcmVudE5vZGUsIGluc3RhbmNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGRpZE5vdEh5ZHJhdGVJbnN0YW5jZShwYXJlbnRUeXBlLCBwYXJlbnRQcm9wcywgcGFyZW50SW5zdGFuY2UsIGluc3RhbmNlLCBpc0NvbmN1cnJlbnRNb2RlKSB7XG4gIHtcbiAgICBpZiAoaXNDb25jdXJyZW50TW9kZSB8fCBwYXJlbnRQcm9wc1tTVVBQUkVTU19IWURSQVRJT05fV0FSTklORyQxXSAhPT0gdHJ1ZSkge1xuICAgICAgaWYgKGluc3RhbmNlLm5vZGVUeXBlID09PSBFTEVNRU5UX05PREUpIHtcbiAgICAgICAgd2FybkZvckRlbGV0ZWRIeWRyYXRhYmxlRWxlbWVudChwYXJlbnRJbnN0YW5jZSwgaW5zdGFuY2UpO1xuICAgICAgfSBlbHNlIGlmIChpbnN0YW5jZS5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFKSA7IGVsc2Uge1xuICAgICAgICB3YXJuRm9yRGVsZXRlZEh5ZHJhdGFibGVUZXh0KHBhcmVudEluc3RhbmNlLCBpbnN0YW5jZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBkaWROb3RGaW5kSHlkcmF0YWJsZUluc3RhbmNlV2l0aGluQ29udGFpbmVyKHBhcmVudENvbnRhaW5lciwgdHlwZSwgcHJvcHMpIHtcbiAge1xuICAgIHdhcm5Gb3JJbnNlcnRlZEh5ZHJhdGVkRWxlbWVudChwYXJlbnRDb250YWluZXIsIHR5cGUpO1xuICB9XG59XG5mdW5jdGlvbiBkaWROb3RGaW5kSHlkcmF0YWJsZVRleHRJbnN0YW5jZVdpdGhpbkNvbnRhaW5lcihwYXJlbnRDb250YWluZXIsIHRleHQpIHtcbiAge1xuICAgIHdhcm5Gb3JJbnNlcnRlZEh5ZHJhdGVkVGV4dChwYXJlbnRDb250YWluZXIsIHRleHQpO1xuICB9XG59XG5mdW5jdGlvbiBkaWROb3RGaW5kSHlkcmF0YWJsZUluc3RhbmNlV2l0aGluU3VzcGVuc2VJbnN0YW5jZShwYXJlbnRJbnN0YW5jZSwgdHlwZSwgcHJvcHMpIHtcbiAge1xuICAgIC8vICRGbG93Rml4TWU6IE9ubHkgRWxlbWVudCBvciBEb2N1bWVudCBjYW4gYmUgcGFyZW50IG5vZGVzLlxuICAgIHZhciBwYXJlbnROb2RlID0gcGFyZW50SW5zdGFuY2UucGFyZW50Tm9kZTtcbiAgICBpZiAocGFyZW50Tm9kZSAhPT0gbnVsbCkgd2FybkZvckluc2VydGVkSHlkcmF0ZWRFbGVtZW50KHBhcmVudE5vZGUsIHR5cGUpO1xuICB9XG59XG5mdW5jdGlvbiBkaWROb3RGaW5kSHlkcmF0YWJsZVRleHRJbnN0YW5jZVdpdGhpblN1c3BlbnNlSW5zdGFuY2UocGFyZW50SW5zdGFuY2UsIHRleHQpIHtcbiAge1xuICAgIC8vICRGbG93Rml4TWU6IE9ubHkgRWxlbWVudCBvciBEb2N1bWVudCBjYW4gYmUgcGFyZW50IG5vZGVzLlxuICAgIHZhciBwYXJlbnROb2RlID0gcGFyZW50SW5zdGFuY2UucGFyZW50Tm9kZTtcbiAgICBpZiAocGFyZW50Tm9kZSAhPT0gbnVsbCkgd2FybkZvckluc2VydGVkSHlkcmF0ZWRUZXh0KHBhcmVudE5vZGUsIHRleHQpO1xuICB9XG59XG5mdW5jdGlvbiBkaWROb3RGaW5kSHlkcmF0YWJsZUluc3RhbmNlKHBhcmVudFR5cGUsIHBhcmVudFByb3BzLCBwYXJlbnRJbnN0YW5jZSwgdHlwZSwgcHJvcHMsIGlzQ29uY3VycmVudE1vZGUpIHtcbiAge1xuICAgIGlmIChpc0NvbmN1cnJlbnRNb2RlIHx8IHBhcmVudFByb3BzW1NVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HJDFdICE9PSB0cnVlKSB7XG4gICAgICB3YXJuRm9ySW5zZXJ0ZWRIeWRyYXRlZEVsZW1lbnQocGFyZW50SW5zdGFuY2UsIHR5cGUpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gZGlkTm90RmluZEh5ZHJhdGFibGVUZXh0SW5zdGFuY2UocGFyZW50VHlwZSwgcGFyZW50UHJvcHMsIHBhcmVudEluc3RhbmNlLCB0ZXh0LCBpc0NvbmN1cnJlbnRNb2RlKSB7XG4gIHtcbiAgICBpZiAoaXNDb25jdXJyZW50TW9kZSB8fCBwYXJlbnRQcm9wc1tTVVBQUkVTU19IWURSQVRJT05fV0FSTklORyQxXSAhPT0gdHJ1ZSkge1xuICAgICAgd2FybkZvckluc2VydGVkSHlkcmF0ZWRUZXh0KHBhcmVudEluc3RhbmNlLCB0ZXh0KTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGVycm9ySHlkcmF0aW5nQ29udGFpbmVyKHBhcmVudENvbnRhaW5lcikge1xuICB7XG4gICAgLy8gVE9ETzogVGhpcyBnZXRzIGxvZ2dlZCBieSBvblJlY292ZXJhYmxlRXJyb3IsIHRvbywgc28gd2Ugc2hvdWxkIGJlXG4gICAgLy8gYWJsZSB0byByZW1vdmUgaXQuXG4gICAgZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIGR1cmluZyBoeWRyYXRpb24uIFRoZSBzZXJ2ZXIgSFRNTCB3YXMgcmVwbGFjZWQgd2l0aCBjbGllbnQgY29udGVudCBpbiA8JXM+LicsIHBhcmVudENvbnRhaW5lci5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgfVxufVxuZnVuY3Rpb24gcHJlcGFyZVBvcnRhbE1vdW50KHBvcnRhbEluc3RhbmNlKSB7XG4gIGxpc3RlblRvQWxsU3VwcG9ydGVkRXZlbnRzKHBvcnRhbEluc3RhbmNlKTtcbn1cblxudmFyIHJhbmRvbUtleSA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnNsaWNlKDIpO1xudmFyIGludGVybmFsSW5zdGFuY2VLZXkgPSAnX19yZWFjdEZpYmVyJCcgKyByYW5kb21LZXk7XG52YXIgaW50ZXJuYWxQcm9wc0tleSA9ICdfX3JlYWN0UHJvcHMkJyArIHJhbmRvbUtleTtcbnZhciBpbnRlcm5hbENvbnRhaW5lckluc3RhbmNlS2V5ID0gJ19fcmVhY3RDb250YWluZXIkJyArIHJhbmRvbUtleTtcbnZhciBpbnRlcm5hbEV2ZW50SGFuZGxlcnNLZXkgPSAnX19yZWFjdEV2ZW50cyQnICsgcmFuZG9tS2V5O1xudmFyIGludGVybmFsRXZlbnRIYW5kbGVyTGlzdGVuZXJzS2V5ID0gJ19fcmVhY3RMaXN0ZW5lcnMkJyArIHJhbmRvbUtleTtcbnZhciBpbnRlcm5hbEV2ZW50SGFuZGxlc1NldEtleSA9ICdfX3JlYWN0SGFuZGxlcyQnICsgcmFuZG9tS2V5O1xuZnVuY3Rpb24gZGV0YWNoRGVsZXRlZEluc3RhbmNlKG5vZGUpIHtcbiAgLy8gVE9ETzogVGhpcyBmdW5jdGlvbiBpcyBvbmx5IGNhbGxlZCBvbiBob3N0IGNvbXBvbmVudHMuIEkgZG9uJ3QgdGhpbmsgYWxsIG9mXG4gIC8vIHRoZXNlIGZpZWxkcyBhcmUgcmVsZXZhbnQuXG4gIGRlbGV0ZSBub2RlW2ludGVybmFsSW5zdGFuY2VLZXldO1xuICBkZWxldGUgbm9kZVtpbnRlcm5hbFByb3BzS2V5XTtcbiAgZGVsZXRlIG5vZGVbaW50ZXJuYWxFdmVudEhhbmRsZXJzS2V5XTtcbiAgZGVsZXRlIG5vZGVbaW50ZXJuYWxFdmVudEhhbmRsZXJMaXN0ZW5lcnNLZXldO1xuICBkZWxldGUgbm9kZVtpbnRlcm5hbEV2ZW50SGFuZGxlc1NldEtleV07XG59XG5mdW5jdGlvbiBwcmVjYWNoZUZpYmVyTm9kZShob3N0SW5zdCwgbm9kZSkge1xuICBub2RlW2ludGVybmFsSW5zdGFuY2VLZXldID0gaG9zdEluc3Q7XG59XG5mdW5jdGlvbiBtYXJrQ29udGFpbmVyQXNSb290KGhvc3RSb290LCBub2RlKSB7XG4gIG5vZGVbaW50ZXJuYWxDb250YWluZXJJbnN0YW5jZUtleV0gPSBob3N0Um9vdDtcbn1cbmZ1bmN0aW9uIHVubWFya0NvbnRhaW5lckFzUm9vdChub2RlKSB7XG4gIG5vZGVbaW50ZXJuYWxDb250YWluZXJJbnN0YW5jZUtleV0gPSBudWxsO1xufVxuZnVuY3Rpb24gaXNDb250YWluZXJNYXJrZWRBc1Jvb3Qobm9kZSkge1xuICByZXR1cm4gISFub2RlW2ludGVybmFsQ29udGFpbmVySW5zdGFuY2VLZXldO1xufSAvLyBHaXZlbiBhIERPTSBub2RlLCByZXR1cm4gdGhlIGNsb3Nlc3QgSG9zdENvbXBvbmVudCBvciBIb3N0VGV4dCBmaWJlciBhbmNlc3Rvci5cbi8vIElmIHRoZSB0YXJnZXQgbm9kZSBpcyBwYXJ0IG9mIGEgaHlkcmF0ZWQgb3Igbm90IHlldCByZW5kZXJlZCBzdWJ0cmVlLCB0aGVuXG4vLyB0aGlzIG1heSBhbHNvIHJldHVybiBhIFN1c3BlbnNlQ29tcG9uZW50IG9yIEhvc3RSb290IHRvIGluZGljYXRlIHRoYXQuXG4vLyBDb25jZXB0dWFsbHkgdGhlIEhvc3RSb290IGZpYmVyIGlzIGEgY2hpbGQgb2YgdGhlIENvbnRhaW5lciBub2RlLiBTbyBpZiB5b3Vcbi8vIHBhc3MgdGhlIENvbnRhaW5lciBub2RlIGFzIHRoZSB0YXJnZXROb2RlLCB5b3Ugd2lsbCBub3QgYWN0dWFsbHkgZ2V0IHRoZVxuLy8gSG9zdFJvb3QgYmFjay4gVG8gZ2V0IHRvIHRoZSBIb3N0Um9vdCwgeW91IG5lZWQgdG8gcGFzcyBhIGNoaWxkIG9mIGl0LlxuLy8gVGhlIHNhbWUgdGhpbmcgYXBwbGllcyB0byBTdXNwZW5zZSBib3VuZGFyaWVzLlxuXG5mdW5jdGlvbiBnZXRDbG9zZXN0SW5zdGFuY2VGcm9tTm9kZSh0YXJnZXROb2RlKSB7XG4gIHZhciB0YXJnZXRJbnN0ID0gdGFyZ2V0Tm9kZVtpbnRlcm5hbEluc3RhbmNlS2V5XTtcblxuICBpZiAodGFyZ2V0SW5zdCkge1xuICAgIC8vIERvbid0IHJldHVybiBIb3N0Um9vdCBvciBTdXNwZW5zZUNvbXBvbmVudCBoZXJlLlxuICAgIHJldHVybiB0YXJnZXRJbnN0O1xuICB9IC8vIElmIHRoZSBkaXJlY3QgZXZlbnQgdGFyZ2V0IGlzbid0IGEgUmVhY3Qgb3duZWQgRE9NIG5vZGUsIHdlIG5lZWQgdG8gbG9va1xuICAvLyB0byBzZWUgaWYgb25lIG9mIGl0cyBwYXJlbnRzIGlzIGEgUmVhY3Qgb3duZWQgRE9NIG5vZGUuXG5cblxuICB2YXIgcGFyZW50Tm9kZSA9IHRhcmdldE5vZGUucGFyZW50Tm9kZTtcblxuICB3aGlsZSAocGFyZW50Tm9kZSkge1xuICAgIC8vIFdlJ2xsIGNoZWNrIGlmIHRoaXMgaXMgYSBjb250YWluZXIgcm9vdCB0aGF0IGNvdWxkIGluY2x1ZGVcbiAgICAvLyBSZWFjdCBub2RlcyBpbiB0aGUgZnV0dXJlLiBXZSBuZWVkIHRvIGNoZWNrIHRoaXMgZmlyc3QgYmVjYXVzZVxuICAgIC8vIGlmIHdlJ3JlIGEgY2hpbGQgb2YgYSBkZWh5ZHJhdGVkIGNvbnRhaW5lciwgd2UgbmVlZCB0byBmaXJzdFxuICAgIC8vIGZpbmQgdGhhdCBpbm5lciBjb250YWluZXIgYmVmb3JlIG1vdmluZyBvbiB0byBmaW5kaW5nIHRoZSBwYXJlbnRcbiAgICAvLyBpbnN0YW5jZS4gTm90ZSB0aGF0IHdlIGRvbid0IGNoZWNrIHRoaXMgZmllbGQgb24gIHRoZSB0YXJnZXROb2RlXG4gICAgLy8gaXRzZWxmIGJlY2F1c2UgdGhlIGZpYmVycyBhcmUgY29uY2VwdHVhbGx5IGJldHdlZW4gdGhlIGNvbnRhaW5lclxuICAgIC8vIG5vZGUgYW5kIHRoZSBmaXJzdCBjaGlsZC4gSXQgaXNuJ3Qgc3Vycm91bmRpbmcgdGhlIGNvbnRhaW5lciBub2RlLlxuICAgIC8vIElmIGl0J3Mgbm90IGEgY29udGFpbmVyLCB3ZSBjaGVjayBpZiBpdCdzIGFuIGluc3RhbmNlLlxuICAgIHRhcmdldEluc3QgPSBwYXJlbnROb2RlW2ludGVybmFsQ29udGFpbmVySW5zdGFuY2VLZXldIHx8IHBhcmVudE5vZGVbaW50ZXJuYWxJbnN0YW5jZUtleV07XG5cbiAgICBpZiAodGFyZ2V0SW5zdCkge1xuICAgICAgLy8gU2luY2UgdGhpcyB3YXNuJ3QgdGhlIGRpcmVjdCB0YXJnZXQgb2YgdGhlIGV2ZW50LCB3ZSBtaWdodCBoYXZlXG4gICAgICAvLyBzdGVwcGVkIHBhc3QgZGVoeWRyYXRlZCBET00gbm9kZXMgdG8gZ2V0IGhlcmUuIEhvd2V2ZXIgdGhleSBjb3VsZFxuICAgICAgLy8gYWxzbyBoYXZlIGJlZW4gbm9uLVJlYWN0IG5vZGVzLiBXZSBuZWVkIHRvIGFuc3dlciB3aGljaCBvbmUuXG4gICAgICAvLyBJZiB3ZSB0aGUgaW5zdGFuY2UgZG9lc24ndCBoYXZlIGFueSBjaGlsZHJlbiwgdGhlbiB0aGVyZSBjYW4ndCBiZVxuICAgICAgLy8gYSBuZXN0ZWQgc3VzcGVuc2UgYm91bmRhcnkgd2l0aGluIGl0LiBTbyB3ZSBjYW4gdXNlIHRoaXMgYXMgYSBmYXN0XG4gICAgICAvLyBiYWlsb3V0LiBNb3N0IG9mIHRoZSB0aW1lLCB3aGVuIHBlb3BsZSBhZGQgbm9uLVJlYWN0IGNoaWxkcmVuIHRvXG4gICAgICAvLyB0aGUgdHJlZSwgaXQgaXMgdXNpbmcgYSByZWYgdG8gYSBjaGlsZC1sZXNzIERPTSBub2RlLlxuICAgICAgLy8gTm9ybWFsbHkgd2UnZCBvbmx5IG5lZWQgdG8gY2hlY2sgb25lIG9mIHRoZSBmaWJlcnMgYmVjYXVzZSBpZiBpdFxuICAgICAgLy8gaGFzIGV2ZXIgZ29uZSBmcm9tIGhhdmluZyBjaGlsZHJlbiB0byBkZWxldGluZyB0aGVtIG9yIHZpY2UgdmVyc2FcbiAgICAgIC8vIGl0IHdvdWxkIGhhdmUgZGVsZXRlZCB0aGUgZGVoeWRyYXRlZCBib3VuZGFyeSBuZXN0ZWQgaW5zaWRlIGFscmVhZHkuXG4gICAgICAvLyBIb3dldmVyLCBzaW5jZSB0aGUgSG9zdFJvb3Qgc3RhcnRzIG91dCB3aXRoIGFuIGFsdGVybmF0ZSBpdCBtaWdodFxuICAgICAgLy8gaGF2ZSBvbmUgb24gdGhlIGFsdGVybmF0ZSBzbyB3ZSBuZWVkIHRvIGNoZWNrIGluIGNhc2UgdGhpcyB3YXMgYVxuICAgICAgLy8gcm9vdC5cbiAgICAgIHZhciBhbHRlcm5hdGUgPSB0YXJnZXRJbnN0LmFsdGVybmF0ZTtcblxuICAgICAgaWYgKHRhcmdldEluc3QuY2hpbGQgIT09IG51bGwgfHwgYWx0ZXJuYXRlICE9PSBudWxsICYmIGFsdGVybmF0ZS5jaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICAvLyBOZXh0IHdlIG5lZWQgdG8gZmlndXJlIG91dCBpZiB0aGUgbm9kZSB0aGF0IHNraXBwZWQgcGFzdCBpc1xuICAgICAgICAvLyBuZXN0ZWQgd2l0aGluIGEgZGVoeWRyYXRlZCBib3VuZGFyeSBhbmQgaWYgc28sIHdoaWNoIG9uZS5cbiAgICAgICAgdmFyIHN1c3BlbnNlSW5zdGFuY2UgPSBnZXRQYXJlbnRTdXNwZW5zZUluc3RhbmNlKHRhcmdldE5vZGUpO1xuXG4gICAgICAgIHdoaWxlIChzdXNwZW5zZUluc3RhbmNlICE9PSBudWxsKSB7XG4gICAgICAgICAgLy8gV2UgZm91bmQgYSBzdXNwZW5zZSBpbnN0YW5jZS4gVGhhdCBtZWFucyB0aGF0IHdlIGhhdmVuJ3RcbiAgICAgICAgICAvLyBoeWRyYXRlZCBpdCB5ZXQuIEV2ZW4gdGhvdWdoIHdlIGxlYXZlIHRoZSBjb21tZW50cyBpbiB0aGVcbiAgICAgICAgICAvLyBET00gYWZ0ZXIgaHlkcmF0aW5nLCBhbmQgdGhlcmUgYXJlIGJvdW5kYXJpZXMgaW4gdGhlIERPTVxuICAgICAgICAgIC8vIHRoYXQgY291bGQgYWxyZWFkeSBiZSBoeWRyYXRlZCwgd2Ugd291bGRuJ3QgaGF2ZSBmb3VuZCB0aGVtXG4gICAgICAgICAgLy8gdGhyb3VnaCB0aGlzIHBhc3Mgc2luY2UgaWYgdGhlIHRhcmdldCBpcyBoeWRyYXRlZCBpdCB3b3VsZFxuICAgICAgICAgIC8vIGhhdmUgaGFkIGFuIGludGVybmFsSW5zdGFuY2VLZXkgb24gaXQuXG4gICAgICAgICAgLy8gTGV0J3MgZ2V0IHRoZSBmaWJlciBhc3NvY2lhdGVkIHdpdGggdGhlIFN1c3BlbnNlQ29tcG9uZW50XG4gICAgICAgICAgLy8gYXMgdGhlIGRlZXBlc3QgaW5zdGFuY2UuXG4gICAgICAgICAgdmFyIHRhcmdldFN1c3BlbnNlSW5zdCA9IHN1c3BlbnNlSW5zdGFuY2VbaW50ZXJuYWxJbnN0YW5jZUtleV07XG5cbiAgICAgICAgICBpZiAodGFyZ2V0U3VzcGVuc2VJbnN0KSB7XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0U3VzcGVuc2VJbnN0O1xuICAgICAgICAgIH0gLy8gSWYgd2UgZG9uJ3QgZmluZCBhIEZpYmVyIG9uIHRoZSBjb21tZW50LCBpdCBtaWdodCBiZSBiZWNhdXNlXG4gICAgICAgICAgLy8gd2UgaGF2ZW4ndCBnb3R0ZW4gdG8gaHlkcmF0ZSBpdCB5ZXQuIFRoZXJlIG1pZ2h0IHN0aWxsIGJlIGFcbiAgICAgICAgICAvLyBwYXJlbnQgYm91bmRhcnkgdGhhdCBoYXNuJ3QgYWJvdmUgdGhpcyBvbmUgc28gd2UgbmVlZCB0byBmaW5kXG4gICAgICAgICAgLy8gdGhlIG91dGVyIG1vc3QgdGhhdCBpcyBrbm93bi5cblxuXG4gICAgICAgICAgc3VzcGVuc2VJbnN0YW5jZSA9IGdldFBhcmVudFN1c3BlbnNlSW5zdGFuY2Uoc3VzcGVuc2VJbnN0YW5jZSk7IC8vIElmIHdlIGRvbid0IGZpbmQgb25lLCB0aGVuIHRoYXQgc2hvdWxkIG1lYW4gdGhhdCB0aGUgcGFyZW50XG4gICAgICAgICAgLy8gaG9zdCBjb21wb25lbnQgYWxzbyBoYXNuJ3QgaHlkcmF0ZWQgeWV0LiBXZSBjYW4gcmV0dXJuIGl0XG4gICAgICAgICAgLy8gYmVsb3cgc2luY2UgaXQgd2lsbCBiYWlsIG91dCBvbiB0aGUgaXNNb3VudGVkIGNoZWNrIGxhdGVyLlxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0YXJnZXRJbnN0O1xuICAgIH1cblxuICAgIHRhcmdldE5vZGUgPSBwYXJlbnROb2RlO1xuICAgIHBhcmVudE5vZGUgPSB0YXJnZXROb2RlLnBhcmVudE5vZGU7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cbi8qKlxuICogR2l2ZW4gYSBET00gbm9kZSwgcmV0dXJuIHRoZSBSZWFjdERPTUNvbXBvbmVudCBvciBSZWFjdERPTVRleHRDb21wb25lbnRcbiAqIGluc3RhbmNlLCBvciBudWxsIGlmIHRoZSBub2RlIHdhcyBub3QgcmVuZGVyZWQgYnkgdGhpcyBSZWFjdC5cbiAqL1xuXG5mdW5jdGlvbiBnZXRJbnN0YW5jZUZyb21Ob2RlKG5vZGUpIHtcbiAgdmFyIGluc3QgPSBub2RlW2ludGVybmFsSW5zdGFuY2VLZXldIHx8IG5vZGVbaW50ZXJuYWxDb250YWluZXJJbnN0YW5jZUtleV07XG5cbiAgaWYgKGluc3QpIHtcbiAgICBpZiAoaW5zdC50YWcgPT09IEhvc3RDb21wb25lbnQgfHwgaW5zdC50YWcgPT09IEhvc3RUZXh0IHx8IGluc3QudGFnID09PSBTdXNwZW5zZUNvbXBvbmVudCB8fCBpbnN0LnRhZyA9PT0gSG9zdFJvb3QpIHtcbiAgICAgIHJldHVybiBpbnN0O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cbi8qKlxuICogR2l2ZW4gYSBSZWFjdERPTUNvbXBvbmVudCBvciBSZWFjdERPTVRleHRDb21wb25lbnQsIHJldHVybiB0aGUgY29ycmVzcG9uZGluZ1xuICogRE9NIG5vZGUuXG4gKi9cblxuZnVuY3Rpb24gZ2V0Tm9kZUZyb21JbnN0YW5jZShpbnN0KSB7XG4gIGlmIChpbnN0LnRhZyA9PT0gSG9zdENvbXBvbmVudCB8fCBpbnN0LnRhZyA9PT0gSG9zdFRleHQpIHtcbiAgICAvLyBJbiBGaWJlciB0aGlzLCBpcyBqdXN0IHRoZSBzdGF0ZSBub2RlIHJpZ2h0IG5vdy4gV2UgYXNzdW1lIGl0IHdpbGwgYmVcbiAgICAvLyBhIGhvc3QgY29tcG9uZW50IG9yIGhvc3QgdGV4dC5cbiAgICByZXR1cm4gaW5zdC5zdGF0ZU5vZGU7XG4gIH0gLy8gV2l0aG91dCB0aGlzIGZpcnN0IGludmFyaWFudCwgcGFzc2luZyBhIG5vbi1ET00tY29tcG9uZW50IHRyaWdnZXJzIHRoZSBuZXh0XG4gIC8vIGludmFyaWFudCBmb3IgYSBtaXNzaW5nIHBhcmVudCwgd2hpY2ggaXMgc3VwZXIgY29uZnVzaW5nLlxuXG5cbiAgdGhyb3cgbmV3IEVycm9yKCdnZXROb2RlRnJvbUluc3RhbmNlOiBJbnZhbGlkIGFyZ3VtZW50LicpO1xufVxuZnVuY3Rpb24gZ2V0RmliZXJDdXJyZW50UHJvcHNGcm9tTm9kZShub2RlKSB7XG4gIHJldHVybiBub2RlW2ludGVybmFsUHJvcHNLZXldIHx8IG51bGw7XG59XG5mdW5jdGlvbiB1cGRhdGVGaWJlclByb3BzKG5vZGUsIHByb3BzKSB7XG4gIG5vZGVbaW50ZXJuYWxQcm9wc0tleV0gPSBwcm9wcztcbn1cbmZ1bmN0aW9uIGdldEV2ZW50TGlzdGVuZXJTZXQobm9kZSkge1xuICB2YXIgZWxlbWVudExpc3RlbmVyU2V0ID0gbm9kZVtpbnRlcm5hbEV2ZW50SGFuZGxlcnNLZXldO1xuXG4gIGlmIChlbGVtZW50TGlzdGVuZXJTZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVsZW1lbnRMaXN0ZW5lclNldCA9IG5vZGVbaW50ZXJuYWxFdmVudEhhbmRsZXJzS2V5XSA9IG5ldyBTZXQoKTtcbiAgfVxuXG4gIHJldHVybiBlbGVtZW50TGlzdGVuZXJTZXQ7XG59XG5cbnZhciBsb2dnZWRUeXBlRmFpbHVyZXMgPSB7fTtcbnZhciBSZWFjdERlYnVnQ3VycmVudEZyYW1lJDEgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdERlYnVnQ3VycmVudEZyYW1lO1xuXG5mdW5jdGlvbiBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChlbGVtZW50KSB7XG4gIHtcbiAgICBpZiAoZWxlbWVudCkge1xuICAgICAgdmFyIG93bmVyID0gZWxlbWVudC5fb3duZXI7XG4gICAgICB2YXIgc3RhY2sgPSBkZXNjcmliZVVua25vd25FbGVtZW50VHlwZUZyYW1lSW5ERVYoZWxlbWVudC50eXBlLCBlbGVtZW50Ll9zb3VyY2UsIG93bmVyID8gb3duZXIudHlwZSA6IG51bGwpO1xuICAgICAgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSQxLnNldEV4dHJhU3RhY2tGcmFtZShzdGFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIFJlYWN0RGVidWdDdXJyZW50RnJhbWUkMS5zZXRFeHRyYVN0YWNrRnJhbWUobnVsbCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNoZWNrUHJvcFR5cGVzKHR5cGVTcGVjcywgdmFsdWVzLCBsb2NhdGlvbiwgY29tcG9uZW50TmFtZSwgZWxlbWVudCkge1xuICB7XG4gICAgLy8gJEZsb3dGaXhNZSBUaGlzIGlzIG9rYXkgYnV0IEZsb3cgZG9lc24ndCBrbm93IGl0LlxuICAgIHZhciBoYXMgPSBGdW5jdGlvbi5jYWxsLmJpbmQoaGFzT3duUHJvcGVydHkpO1xuXG4gICAgZm9yICh2YXIgdHlwZVNwZWNOYW1lIGluIHR5cGVTcGVjcykge1xuICAgICAgaWYgKGhhcyh0eXBlU3BlY3MsIHR5cGVTcGVjTmFtZSkpIHtcbiAgICAgICAgdmFyIGVycm9yJDEgPSB2b2lkIDA7IC8vIFByb3AgdHlwZSB2YWxpZGF0aW9uIG1heSB0aHJvdy4gSW4gY2FzZSB0aGV5IGRvLCB3ZSBkb24ndCB3YW50IHRvXG4gICAgICAgIC8vIGZhaWwgdGhlIHJlbmRlciBwaGFzZSB3aGVyZSBpdCBkaWRuJ3QgZmFpbCBiZWZvcmUuIFNvIHdlIGxvZyBpdC5cbiAgICAgICAgLy8gQWZ0ZXIgdGhlc2UgaGF2ZSBiZWVuIGNsZWFuZWQgdXAsIHdlJ2xsIGxldCB0aGVtIHRocm93LlxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gVGhpcyBpcyBpbnRlbnRpb25hbGx5IGFuIGludmFyaWFudCB0aGF0IGdldHMgY2F1Z2h0LiBJdCdzIHRoZSBzYW1lXG4gICAgICAgICAgLy8gYmVoYXZpb3IgYXMgd2l0aG91dCB0aGlzIHN0YXRlbWVudCBleGNlcHQgd2l0aCBhIGJldHRlciBtZXNzYWdlLlxuICAgICAgICAgIGlmICh0eXBlb2YgdHlwZVNwZWNzW3R5cGVTcGVjTmFtZV0gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9wcm9kLWVycm9yLWNvZGVzXG4gICAgICAgICAgICB2YXIgZXJyID0gRXJyb3IoKGNvbXBvbmVudE5hbWUgfHwgJ1JlYWN0IGNsYXNzJykgKyAnOiAnICsgbG9jYXRpb24gKyAnIHR5cGUgYCcgKyB0eXBlU3BlY05hbWUgKyAnYCBpcyBpbnZhbGlkOyAnICsgJ2l0IG11c3QgYmUgYSBmdW5jdGlvbiwgdXN1YWxseSBmcm9tIHRoZSBgcHJvcC10eXBlc2AgcGFja2FnZSwgYnV0IHJlY2VpdmVkIGAnICsgdHlwZW9mIHR5cGVTcGVjc1t0eXBlU3BlY05hbWVdICsgJ2AuJyArICdUaGlzIG9mdGVuIGhhcHBlbnMgYmVjYXVzZSBvZiB0eXBvcyBzdWNoIGFzIGBQcm9wVHlwZXMuZnVuY3Rpb25gIGluc3RlYWQgb2YgYFByb3BUeXBlcy5mdW5jYC4nKTtcbiAgICAgICAgICAgIGVyci5uYW1lID0gJ0ludmFyaWFudCBWaW9sYXRpb24nO1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGVycm9yJDEgPSB0eXBlU3BlY3NbdHlwZVNwZWNOYW1lXSh2YWx1ZXMsIHR5cGVTcGVjTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIG51bGwsICdTRUNSRVRfRE9fTk9UX1BBU1NfVEhJU19PUl9ZT1VfV0lMTF9CRV9GSVJFRCcpO1xuICAgICAgICB9IGNhdGNoIChleCkge1xuICAgICAgICAgIGVycm9yJDEgPSBleDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlcnJvciQxICYmICEoZXJyb3IkMSBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgICAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KGVsZW1lbnQpO1xuXG4gICAgICAgICAgZXJyb3IoJyVzOiB0eXBlIHNwZWNpZmljYXRpb24gb2YgJXMnICsgJyBgJXNgIGlzIGludmFsaWQ7IHRoZSB0eXBlIGNoZWNrZXIgJyArICdmdW5jdGlvbiBtdXN0IHJldHVybiBgbnVsbGAgb3IgYW4gYEVycm9yYCBidXQgcmV0dXJuZWQgYSAlcy4gJyArICdZb3UgbWF5IGhhdmUgZm9yZ290dGVuIHRvIHBhc3MgYW4gYXJndW1lbnQgdG8gdGhlIHR5cGUgY2hlY2tlciAnICsgJ2NyZWF0b3IgKGFycmF5T2YsIGluc3RhbmNlT2YsIG9iamVjdE9mLCBvbmVPZiwgb25lT2ZUeXBlLCBhbmQgJyArICdzaGFwZSBhbGwgcmVxdWlyZSBhbiBhcmd1bWVudCkuJywgY29tcG9uZW50TmFtZSB8fCAnUmVhY3QgY2xhc3MnLCBsb2NhdGlvbiwgdHlwZVNwZWNOYW1lLCB0eXBlb2YgZXJyb3IkMSk7XG5cbiAgICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChudWxsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlcnJvciQxIGluc3RhbmNlb2YgRXJyb3IgJiYgIShlcnJvciQxLm1lc3NhZ2UgaW4gbG9nZ2VkVHlwZUZhaWx1cmVzKSkge1xuICAgICAgICAgIC8vIE9ubHkgbW9uaXRvciB0aGlzIGZhaWx1cmUgb25jZSBiZWNhdXNlIHRoZXJlIHRlbmRzIHRvIGJlIGEgbG90IG9mIHRoZVxuICAgICAgICAgIC8vIHNhbWUgZXJyb3IuXG4gICAgICAgICAgbG9nZ2VkVHlwZUZhaWx1cmVzW2Vycm9yJDEubWVzc2FnZV0gPSB0cnVlO1xuICAgICAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KGVsZW1lbnQpO1xuXG4gICAgICAgICAgZXJyb3IoJ0ZhaWxlZCAlcyB0eXBlOiAlcycsIGxvY2F0aW9uLCBlcnJvciQxLm1lc3NhZ2UpO1xuXG4gICAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQobnVsbCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIHZhbHVlU3RhY2sgPSBbXTtcbnZhciBmaWJlclN0YWNrO1xuXG57XG4gIGZpYmVyU3RhY2sgPSBbXTtcbn1cblxudmFyIGluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNyZWF0ZUN1cnNvcihkZWZhdWx0VmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICBjdXJyZW50OiBkZWZhdWx0VmFsdWVcbiAgfTtcbn1cblxuZnVuY3Rpb24gcG9wKGN1cnNvciwgZmliZXIpIHtcbiAgaWYgKGluZGV4IDwgMCkge1xuICAgIHtcbiAgICAgIGVycm9yKCdVbmV4cGVjdGVkIHBvcC4nKTtcbiAgICB9XG5cbiAgICByZXR1cm47XG4gIH1cblxuICB7XG4gICAgaWYgKGZpYmVyICE9PSBmaWJlclN0YWNrW2luZGV4XSkge1xuICAgICAgZXJyb3IoJ1VuZXhwZWN0ZWQgRmliZXIgcG9wcGVkLicpO1xuICAgIH1cbiAgfVxuXG4gIGN1cnNvci5jdXJyZW50ID0gdmFsdWVTdGFja1tpbmRleF07XG4gIHZhbHVlU3RhY2tbaW5kZXhdID0gbnVsbDtcblxuICB7XG4gICAgZmliZXJTdGFja1tpbmRleF0gPSBudWxsO1xuICB9XG5cbiAgaW5kZXgtLTtcbn1cblxuZnVuY3Rpb24gcHVzaChjdXJzb3IsIHZhbHVlLCBmaWJlcikge1xuICBpbmRleCsrO1xuICB2YWx1ZVN0YWNrW2luZGV4XSA9IGN1cnNvci5jdXJyZW50O1xuXG4gIHtcbiAgICBmaWJlclN0YWNrW2luZGV4XSA9IGZpYmVyO1xuICB9XG5cbiAgY3Vyc29yLmN1cnJlbnQgPSB2YWx1ZTtcbn1cblxudmFyIHdhcm5lZEFib3V0TWlzc2luZ0dldENoaWxkQ29udGV4dDtcblxue1xuICB3YXJuZWRBYm91dE1pc3NpbmdHZXRDaGlsZENvbnRleHQgPSB7fTtcbn1cblxudmFyIGVtcHR5Q29udGV4dE9iamVjdCA9IHt9O1xuXG57XG4gIE9iamVjdC5mcmVlemUoZW1wdHlDb250ZXh0T2JqZWN0KTtcbn0gLy8gQSBjdXJzb3IgdG8gdGhlIGN1cnJlbnQgbWVyZ2VkIGNvbnRleHQgb2JqZWN0IG9uIHRoZSBzdGFjay5cblxuXG52YXIgY29udGV4dFN0YWNrQ3Vyc29yID0gY3JlYXRlQ3Vyc29yKGVtcHR5Q29udGV4dE9iamVjdCk7IC8vIEEgY3Vyc29yIHRvIGEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGNvbnRleHQgaGFzIGNoYW5nZWQuXG5cbnZhciBkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yID0gY3JlYXRlQ3Vyc29yKGZhbHNlKTsgLy8gS2VlcCB0cmFjayBvZiB0aGUgcHJldmlvdXMgY29udGV4dCBvYmplY3QgdGhhdCB3YXMgb24gdGhlIHN0YWNrLlxuLy8gV2UgdXNlIHRoaXMgdG8gZ2V0IGFjY2VzcyB0byB0aGUgcGFyZW50IGNvbnRleHQgYWZ0ZXIgd2UgaGF2ZSBhbHJlYWR5XG4vLyBwdXNoZWQgdGhlIG5leHQgY29udGV4dCBwcm92aWRlciwgYW5kIG5vdyBuZWVkIHRvIG1lcmdlIHRoZWlyIGNvbnRleHRzLlxuXG52YXIgcHJldmlvdXNDb250ZXh0ID0gZW1wdHlDb250ZXh0T2JqZWN0O1xuXG5mdW5jdGlvbiBnZXRVbm1hc2tlZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgZGlkUHVzaE93bkNvbnRleHRJZlByb3ZpZGVyKSB7XG4gIHtcbiAgICBpZiAoZGlkUHVzaE93bkNvbnRleHRJZlByb3ZpZGVyICYmIGlzQ29udGV4dFByb3ZpZGVyKENvbXBvbmVudCkpIHtcbiAgICAgIC8vIElmIHRoZSBmaWJlciBpcyBhIGNvbnRleHQgcHJvdmlkZXIgaXRzZWxmLCB3aGVuIHdlIHJlYWQgaXRzIGNvbnRleHRcbiAgICAgIC8vIHdlIG1heSBoYXZlIGFscmVhZHkgcHVzaGVkIGl0cyBvd24gY2hpbGQgY29udGV4dCBvbiB0aGUgc3RhY2suIEEgY29udGV4dFxuICAgICAgLy8gcHJvdmlkZXIgc2hvdWxkIG5vdCBcInNlZVwiIGl0cyBvd24gY2hpbGQgY29udGV4dC4gVGhlcmVmb3JlIHdlIHJlYWQgdGhlXG4gICAgICAvLyBwcmV2aW91cyAocGFyZW50KSBjb250ZXh0IGluc3RlYWQgZm9yIGEgY29udGV4dCBwcm92aWRlci5cbiAgICAgIHJldHVybiBwcmV2aW91c0NvbnRleHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRleHRTdGFja0N1cnNvci5jdXJyZW50O1xuICB9XG59XG5cbmZ1bmN0aW9uIGNhY2hlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgdW5tYXNrZWRDb250ZXh0LCBtYXNrZWRDb250ZXh0KSB7XG4gIHtcbiAgICB2YXIgaW5zdGFuY2UgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG4gICAgaW5zdGFuY2UuX19yZWFjdEludGVybmFsTWVtb2l6ZWRVbm1hc2tlZENoaWxkQ29udGV4dCA9IHVubWFza2VkQ29udGV4dDtcbiAgICBpbnN0YW5jZS5fX3JlYWN0SW50ZXJuYWxNZW1vaXplZE1hc2tlZENoaWxkQ29udGV4dCA9IG1hc2tlZENvbnRleHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0TWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgdW5tYXNrZWRDb250ZXh0KSB7XG4gIHtcbiAgICB2YXIgdHlwZSA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gICAgdmFyIGNvbnRleHRUeXBlcyA9IHR5cGUuY29udGV4dFR5cGVzO1xuXG4gICAgaWYgKCFjb250ZXh0VHlwZXMpIHtcbiAgICAgIHJldHVybiBlbXB0eUNvbnRleHRPYmplY3Q7XG4gICAgfSAvLyBBdm9pZCByZWNyZWF0aW5nIG1hc2tlZCBjb250ZXh0IHVubGVzcyB1bm1hc2tlZCBjb250ZXh0IGhhcyBjaGFuZ2VkLlxuICAgIC8vIEZhaWxpbmcgdG8gZG8gdGhpcyB3aWxsIHJlc3VsdCBpbiB1bm5lY2Vzc2FyeSBjYWxscyB0byBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzLlxuICAgIC8vIFRoaXMgbWF5IHRyaWdnZXIgaW5maW5pdGUgbG9vcHMgaWYgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyBjYWxscyBzZXRTdGF0ZS5cblxuXG4gICAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuXG4gICAgaWYgKGluc3RhbmNlICYmIGluc3RhbmNlLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkVW5tYXNrZWRDaGlsZENvbnRleHQgPT09IHVubWFza2VkQ29udGV4dCkge1xuICAgICAgcmV0dXJuIGluc3RhbmNlLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkTWFza2VkQ2hpbGRDb250ZXh0O1xuICAgIH1cblxuICAgIHZhciBjb250ZXh0ID0ge307XG5cbiAgICBmb3IgKHZhciBrZXkgaW4gY29udGV4dFR5cGVzKSB7XG4gICAgICBjb250ZXh0W2tleV0gPSB1bm1hc2tlZENvbnRleHRba2V5XTtcbiAgICB9XG5cbiAgICB7XG4gICAgICB2YXIgbmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIod29ya0luUHJvZ3Jlc3MpIHx8ICdVbmtub3duJztcbiAgICAgIGNoZWNrUHJvcFR5cGVzKGNvbnRleHRUeXBlcywgY29udGV4dCwgJ2NvbnRleHQnLCBuYW1lKTtcbiAgICB9IC8vIENhY2hlIHVubWFza2VkIGNvbnRleHQgc28gd2UgY2FuIGF2b2lkIHJlY3JlYXRpbmcgbWFza2VkIGNvbnRleHQgdW5sZXNzIG5lY2Vzc2FyeS5cbiAgICAvLyBDb250ZXh0IGlzIGNyZWF0ZWQgYmVmb3JlIHRoZSBjbGFzcyBjb21wb25lbnQgaXMgaW5zdGFudGlhdGVkIHNvIGNoZWNrIGZvciBpbnN0YW5jZS5cblxuXG4gICAgaWYgKGluc3RhbmNlKSB7XG4gICAgICBjYWNoZUNvbnRleHQod29ya0luUHJvZ3Jlc3MsIHVubWFza2VkQ29udGV4dCwgY29udGV4dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRleHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFzQ29udGV4dENoYW5nZWQoKSB7XG4gIHtcbiAgICByZXR1cm4gZGlkUGVyZm9ybVdvcmtTdGFja0N1cnNvci5jdXJyZW50O1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQ29udGV4dFByb3ZpZGVyKHR5cGUpIHtcbiAge1xuICAgIHZhciBjaGlsZENvbnRleHRUeXBlcyA9IHR5cGUuY2hpbGRDb250ZXh0VHlwZXM7XG4gICAgcmV0dXJuIGNoaWxkQ29udGV4dFR5cGVzICE9PSBudWxsICYmIGNoaWxkQ29udGV4dFR5cGVzICE9PSB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gcG9wQ29udGV4dChmaWJlcikge1xuICB7XG4gICAgcG9wKGRpZFBlcmZvcm1Xb3JrU3RhY2tDdXJzb3IsIGZpYmVyKTtcbiAgICBwb3AoY29udGV4dFN0YWNrQ3Vyc29yLCBmaWJlcik7XG4gIH1cbn1cblxuZnVuY3Rpb24gcG9wVG9wTGV2ZWxDb250ZXh0T2JqZWN0KGZpYmVyKSB7XG4gIHtcbiAgICBwb3AoZGlkUGVyZm9ybVdvcmtTdGFja0N1cnNvciwgZmliZXIpO1xuICAgIHBvcChjb250ZXh0U3RhY2tDdXJzb3IsIGZpYmVyKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwdXNoVG9wTGV2ZWxDb250ZXh0T2JqZWN0KGZpYmVyLCBjb250ZXh0LCBkaWRDaGFuZ2UpIHtcbiAge1xuICAgIGlmIChjb250ZXh0U3RhY2tDdXJzb3IuY3VycmVudCAhPT0gZW1wdHlDb250ZXh0T2JqZWN0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgY29udGV4dCBmb3VuZCBvbiBzdGFjay4gJyArICdUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cblxuICAgIHB1c2goY29udGV4dFN0YWNrQ3Vyc29yLCBjb250ZXh0LCBmaWJlcik7XG4gICAgcHVzaChkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yLCBkaWRDaGFuZ2UsIGZpYmVyKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9jZXNzQ2hpbGRDb250ZXh0KGZpYmVyLCB0eXBlLCBwYXJlbnRDb250ZXh0KSB7XG4gIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGU7XG4gICAgdmFyIGNoaWxkQ29udGV4dFR5cGVzID0gdHlwZS5jaGlsZENvbnRleHRUeXBlczsgLy8gVE9ETyAoYnZhdWdobikgUmVwbGFjZSB0aGlzIGJlaGF2aW9yIHdpdGggYW4gaW52YXJpYW50KCkgaW4gdGhlIGZ1dHVyZS5cbiAgICAvLyBJdCBoYXMgb25seSBiZWVuIGFkZGVkIGluIEZpYmVyIHRvIG1hdGNoIHRoZSAodW5pbnRlbnRpb25hbCkgYmVoYXZpb3IgaW4gU3RhY2suXG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmdldENoaWxkQ29udGV4dCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAge1xuICAgICAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdVbmtub3duJztcblxuICAgICAgICBpZiAoIXdhcm5lZEFib3V0TWlzc2luZ0dldENoaWxkQ29udGV4dFtjb21wb25lbnROYW1lXSkge1xuICAgICAgICAgIHdhcm5lZEFib3V0TWlzc2luZ0dldENoaWxkQ29udGV4dFtjb21wb25lbnROYW1lXSA9IHRydWU7XG5cbiAgICAgICAgICBlcnJvcignJXMuY2hpbGRDb250ZXh0VHlwZXMgaXMgc3BlY2lmaWVkIGJ1dCB0aGVyZSBpcyBubyBnZXRDaGlsZENvbnRleHQoKSBtZXRob2QgJyArICdvbiB0aGUgaW5zdGFuY2UuIFlvdSBjYW4gZWl0aGVyIGRlZmluZSBnZXRDaGlsZENvbnRleHQoKSBvbiAlcyBvciByZW1vdmUgJyArICdjaGlsZENvbnRleHRUeXBlcyBmcm9tIGl0LicsIGNvbXBvbmVudE5hbWUsIGNvbXBvbmVudE5hbWUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXJlbnRDb250ZXh0O1xuICAgIH1cblxuICAgIHZhciBjaGlsZENvbnRleHQgPSBpbnN0YW5jZS5nZXRDaGlsZENvbnRleHQoKTtcblxuICAgIGZvciAodmFyIGNvbnRleHRLZXkgaW4gY2hpbGRDb250ZXh0KSB7XG4gICAgICBpZiAoIShjb250ZXh0S2V5IGluIGNoaWxkQ29udGV4dFR5cGVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdVbmtub3duJykgKyBcIi5nZXRDaGlsZENvbnRleHQoKToga2V5IFxcXCJcIiArIGNvbnRleHRLZXkgKyBcIlxcXCIgaXMgbm90IGRlZmluZWQgaW4gY2hpbGRDb250ZXh0VHlwZXMuXCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHtcbiAgICAgIHZhciBuYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ1Vua25vd24nO1xuICAgICAgY2hlY2tQcm9wVHlwZXMoY2hpbGRDb250ZXh0VHlwZXMsIGNoaWxkQ29udGV4dCwgJ2NoaWxkIGNvbnRleHQnLCBuYW1lKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXNzaWduKHt9LCBwYXJlbnRDb250ZXh0LCBjaGlsZENvbnRleHQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHB1c2hDb250ZXh0UHJvdmlkZXIod29ya0luUHJvZ3Jlc3MpIHtcbiAge1xuICAgIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTsgLy8gV2UgcHVzaCB0aGUgY29udGV4dCBhcyBlYXJseSBhcyBwb3NzaWJsZSB0byBlbnN1cmUgc3RhY2sgaW50ZWdyaXR5LlxuICAgIC8vIElmIHRoZSBpbnN0YW5jZSBkb2VzIG5vdCBleGlzdCB5ZXQsIHdlIHdpbGwgcHVzaCBudWxsIGF0IGZpcnN0LFxuICAgIC8vIGFuZCByZXBsYWNlIGl0IG9uIHRoZSBzdGFjayBsYXRlciB3aGVuIGludmFsaWRhdGluZyB0aGUgY29udGV4dC5cblxuICAgIHZhciBtZW1vaXplZE1lcmdlZENoaWxkQ29udGV4dCA9IGluc3RhbmNlICYmIGluc3RhbmNlLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkTWVyZ2VkQ2hpbGRDb250ZXh0IHx8IGVtcHR5Q29udGV4dE9iamVjdDsgLy8gUmVtZW1iZXIgdGhlIHBhcmVudCBjb250ZXh0IHNvIHdlIGNhbiBtZXJnZSB3aXRoIGl0IGxhdGVyLlxuICAgIC8vIEluaGVyaXQgdGhlIHBhcmVudCdzIGRpZC1wZXJmb3JtLXdvcmsgdmFsdWUgdG8gYXZvaWQgaW5hZHZlcnRlbnRseSBibG9ja2luZyB1cGRhdGVzLlxuXG4gICAgcHJldmlvdXNDb250ZXh0ID0gY29udGV4dFN0YWNrQ3Vyc29yLmN1cnJlbnQ7XG4gICAgcHVzaChjb250ZXh0U3RhY2tDdXJzb3IsIG1lbW9pemVkTWVyZ2VkQ2hpbGRDb250ZXh0LCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgcHVzaChkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yLCBkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yLmN1cnJlbnQsIHdvcmtJblByb2dyZXNzKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnZhbGlkYXRlQ29udGV4dFByb3ZpZGVyKHdvcmtJblByb2dyZXNzLCB0eXBlLCBkaWRDaGFuZ2UpIHtcbiAge1xuICAgIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcblxuICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgdG8gaGF2ZSBhbiBpbnN0YW5jZSBieSB0aGlzIHBvaW50LiAnICsgJ1RoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuXG4gICAgaWYgKGRpZENoYW5nZSkge1xuICAgICAgLy8gTWVyZ2UgcGFyZW50IGFuZCBvd24gY29udGV4dC5cbiAgICAgIC8vIFNraXAgdGhpcyBpZiB3ZSdyZSBub3QgdXBkYXRpbmcgZHVlIHRvIHNDVS5cbiAgICAgIC8vIFRoaXMgYXZvaWRzIHVubmVjZXNzYXJpbHkgcmVjb21wdXRpbmcgbWVtb2l6ZWQgdmFsdWVzLlxuICAgICAgdmFyIG1lcmdlZENvbnRleHQgPSBwcm9jZXNzQ2hpbGRDb250ZXh0KHdvcmtJblByb2dyZXNzLCB0eXBlLCBwcmV2aW91c0NvbnRleHQpO1xuICAgICAgaW5zdGFuY2UuX19yZWFjdEludGVybmFsTWVtb2l6ZWRNZXJnZWRDaGlsZENvbnRleHQgPSBtZXJnZWRDb250ZXh0OyAvLyBSZXBsYWNlIHRoZSBvbGQgKG9yIGVtcHR5KSBjb250ZXh0IHdpdGggdGhlIG5ldyBvbmUuXG4gICAgICAvLyBJdCBpcyBpbXBvcnRhbnQgdG8gdW53aW5kIHRoZSBjb250ZXh0IGluIHRoZSByZXZlcnNlIG9yZGVyLlxuXG4gICAgICBwb3AoZGlkUGVyZm9ybVdvcmtTdGFja0N1cnNvciwgd29ya0luUHJvZ3Jlc3MpO1xuICAgICAgcG9wKGNvbnRleHRTdGFja0N1cnNvciwgd29ya0luUHJvZ3Jlc3MpOyAvLyBOb3cgcHVzaCB0aGUgbmV3IGNvbnRleHQgYW5kIG1hcmsgdGhhdCBpdCBoYXMgY2hhbmdlZC5cblxuICAgICAgcHVzaChjb250ZXh0U3RhY2tDdXJzb3IsIG1lcmdlZENvbnRleHQsIHdvcmtJblByb2dyZXNzKTtcbiAgICAgIHB1c2goZGlkUGVyZm9ybVdvcmtTdGFja0N1cnNvciwgZGlkQ2hhbmdlLCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBvcChkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yLCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICBwdXNoKGRpZFBlcmZvcm1Xb3JrU3RhY2tDdXJzb3IsIGRpZENoYW5nZSwgd29ya0luUHJvZ3Jlc3MpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5kQ3VycmVudFVubWFza2VkQ29udGV4dChmaWJlcikge1xuICB7XG4gICAgLy8gQ3VycmVudGx5IHRoaXMgaXMgb25seSB1c2VkIHdpdGggcmVuZGVyU3VidHJlZUludG9Db250YWluZXI7IG5vdCBzdXJlIGlmIGl0XG4gICAgLy8gbWFrZXMgc2Vuc2UgZWxzZXdoZXJlXG4gICAgaWYgKCFpc0ZpYmVyTW91bnRlZChmaWJlcikgfHwgZmliZXIudGFnICE9PSBDbGFzc0NvbXBvbmVudCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCBzdWJ0cmVlIHBhcmVudCB0byBiZSBhIG1vdW50ZWQgY2xhc3MgY29tcG9uZW50LiAnICsgJ1RoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuXG4gICAgdmFyIG5vZGUgPSBmaWJlcjtcblxuICAgIGRvIHtcbiAgICAgIHN3aXRjaCAobm9kZS50YWcpIHtcbiAgICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAgICByZXR1cm4gbm9kZS5zdGF0ZU5vZGUuY29udGV4dDtcblxuICAgICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBDb21wb25lbnQgPSBub2RlLnR5cGU7XG5cbiAgICAgICAgICAgIGlmIChpc0NvbnRleHRQcm92aWRlcihDb21wb25lbnQpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBub2RlLnN0YXRlTm9kZS5fX3JlYWN0SW50ZXJuYWxNZW1vaXplZE1lcmdlZENoaWxkQ29udGV4dDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBub2RlID0gbm9kZS5yZXR1cm47XG4gICAgfSB3aGlsZSAobm9kZSAhPT0gbnVsbCk7XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZvdW5kIHVuZXhwZWN0ZWQgZGV0YWNoZWQgc3VidHJlZSBwYXJlbnQuICcgKyAnVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgfVxufVxuXG52YXIgTGVnYWN5Um9vdCA9IDA7XG52YXIgQ29uY3VycmVudFJvb3QgPSAxO1xuXG52YXIgc3luY1F1ZXVlID0gbnVsbDtcbnZhciBpbmNsdWRlc0xlZ2FjeVN5bmNDYWxsYmFja3MgPSBmYWxzZTtcbnZhciBpc0ZsdXNoaW5nU3luY1F1ZXVlID0gZmFsc2U7XG5mdW5jdGlvbiBzY2hlZHVsZVN5bmNDYWxsYmFjayhjYWxsYmFjaykge1xuICAvLyBQdXNoIHRoaXMgY2FsbGJhY2sgaW50byBhbiBpbnRlcm5hbCBxdWV1ZS4gV2UnbGwgZmx1c2ggdGhlc2UgZWl0aGVyIGluXG4gIC8vIHRoZSBuZXh0IHRpY2ssIG9yIGVhcmxpZXIgaWYgc29tZXRoaW5nIGNhbGxzIGBmbHVzaFN5bmNDYWxsYmFja1F1ZXVlYC5cbiAgaWYgKHN5bmNRdWV1ZSA9PT0gbnVsbCkge1xuICAgIHN5bmNRdWV1ZSA9IFtjYWxsYmFja107XG4gIH0gZWxzZSB7XG4gICAgLy8gUHVzaCBvbnRvIGV4aXN0aW5nIHF1ZXVlLiBEb24ndCBuZWVkIHRvIHNjaGVkdWxlIGEgY2FsbGJhY2sgYmVjYXVzZVxuICAgIC8vIHdlIGFscmVhZHkgc2NoZWR1bGVkIG9uZSB3aGVuIHdlIGNyZWF0ZWQgdGhlIHF1ZXVlLlxuICAgIHN5bmNRdWV1ZS5wdXNoKGNhbGxiYWNrKTtcbiAgfVxufVxuZnVuY3Rpb24gc2NoZWR1bGVMZWdhY3lTeW5jQ2FsbGJhY2soY2FsbGJhY2spIHtcbiAgaW5jbHVkZXNMZWdhY3lTeW5jQ2FsbGJhY2tzID0gdHJ1ZTtcbiAgc2NoZWR1bGVTeW5jQ2FsbGJhY2soY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gZmx1c2hTeW5jQ2FsbGJhY2tzT25seUluTGVnYWN5TW9kZSgpIHtcbiAgLy8gT25seSBmbHVzaGVzIHRoZSBxdWV1ZSBpZiB0aGVyZSdzIGEgbGVnYWN5IHN5bmMgY2FsbGJhY2sgc2NoZWR1bGVkLlxuICAvLyBUT0RPOiBUaGVyZSdzIG9ubHkgYSBzaW5nbGUgdHlwZSBvZiBjYWxsYmFjazogcGVyZm9ybVN5bmNPbldvcmtPblJvb3QuIFNvXG4gIC8vIGl0IG1pZ2h0IG1ha2UgbW9yZSBzZW5zZSBmb3IgdGhlIHF1ZXVlIHRvIGJlIGEgbGlzdCBvZiByb290cyBpbnN0ZWFkIG9mIGFcbiAgLy8gbGlzdCBvZiBnZW5lcmljIGNhbGxiYWNrcy4gVGhlbiB3ZSBjYW4gaGF2ZSB0d286IG9uZSBmb3IgbGVnYWN5IHJvb3RzLCBvbmVcbiAgLy8gZm9yIGNvbmN1cnJlbnQgcm9vdHMuIEFuZCB0aGlzIG1ldGhvZCB3b3VsZCBvbmx5IGZsdXNoIHRoZSBsZWdhY3kgb25lcy5cbiAgaWYgKGluY2x1ZGVzTGVnYWN5U3luY0NhbGxiYWNrcykge1xuICAgIGZsdXNoU3luY0NhbGxiYWNrcygpO1xuICB9XG59XG5mdW5jdGlvbiBmbHVzaFN5bmNDYWxsYmFja3MoKSB7XG4gIGlmICghaXNGbHVzaGluZ1N5bmNRdWV1ZSAmJiBzeW5jUXVldWUgIT09IG51bGwpIHtcbiAgICAvLyBQcmV2ZW50IHJlLWVudHJhbmNlLlxuICAgIGlzRmx1c2hpbmdTeW5jUXVldWUgPSB0cnVlO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIgcHJldmlvdXNVcGRhdGVQcmlvcml0eSA9IGdldEN1cnJlbnRVcGRhdGVQcmlvcml0eSgpO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciBpc1N5bmMgPSB0cnVlO1xuICAgICAgdmFyIHF1ZXVlID0gc3luY1F1ZXVlOyAvLyBUT0RPOiBJcyB0aGlzIG5lY2Vzc2FyeSBhbnltb3JlPyBUaGUgb25seSB1c2VyIGNvZGUgdGhhdCBydW5zIGluIHRoaXNcbiAgICAgIC8vIHF1ZXVlIGlzIGluIHRoZSByZW5kZXIgb3IgY29tbWl0IHBoYXNlcy5cblxuICAgICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KERpc2NyZXRlRXZlbnRQcmlvcml0eSk7XG5cbiAgICAgIGZvciAoOyBpIDwgcXVldWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gcXVldWVbaV07XG5cbiAgICAgICAgZG8ge1xuICAgICAgICAgIGNhbGxiYWNrID0gY2FsbGJhY2soaXNTeW5jKTtcbiAgICAgICAgfSB3aGlsZSAoY2FsbGJhY2sgIT09IG51bGwpO1xuICAgICAgfVxuXG4gICAgICBzeW5jUXVldWUgPSBudWxsO1xuICAgICAgaW5jbHVkZXNMZWdhY3lTeW5jQ2FsbGJhY2tzID0gZmFsc2U7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIElmIHNvbWV0aGluZyB0aHJvd3MsIGxlYXZlIHRoZSByZW1haW5pbmcgY2FsbGJhY2tzIG9uIHRoZSBxdWV1ZS5cbiAgICAgIGlmIChzeW5jUXVldWUgIT09IG51bGwpIHtcbiAgICAgICAgc3luY1F1ZXVlID0gc3luY1F1ZXVlLnNsaWNlKGkgKyAxKTtcbiAgICAgIH0gLy8gUmVzdW1lIGZsdXNoaW5nIGluIHRoZSBuZXh0IHRpY2tcblxuXG4gICAgICBzY2hlZHVsZUNhbGxiYWNrKEltbWVkaWF0ZVByaW9yaXR5LCBmbHVzaFN5bmNDYWxsYmFja3MpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmV2aW91c1VwZGF0ZVByaW9yaXR5KTtcbiAgICAgIGlzRmx1c2hpbmdTeW5jUXVldWUgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuLy8gVE9ETzogVXNlIHRoZSB1bmlmaWVkIGZpYmVyIHN0YWNrIG1vZHVsZSBpbnN0ZWFkIG9mIHRoaXMgbG9jYWwgb25lP1xuLy8gSW50ZW50aW9uYWxseSBub3QgdXNpbmcgaXQgeWV0IHRvIGRlcmlzayB0aGUgaW5pdGlhbCBpbXBsZW1lbnRhdGlvbiwgYmVjYXVzZVxuLy8gdGhlIHdheSB3ZSBwdXNoL3BvcCB0aGVzZSB2YWx1ZXMgaXMgYSBiaXQgdW51c3VhbC4gSWYgdGhlcmUncyBhIG1pc3Rha2UsIEknZFxuLy8gcmF0aGVyIHRoZSBpZHMgYmUgd3JvbmcgdGhhbiBjcmFzaCB0aGUgd2hvbGUgcmVjb25jaWxlci5cbnZhciBmb3JrU3RhY2sgPSBbXTtcbnZhciBmb3JrU3RhY2tJbmRleCA9IDA7XG52YXIgdHJlZUZvcmtQcm92aWRlciA9IG51bGw7XG52YXIgdHJlZUZvcmtDb3VudCA9IDA7XG52YXIgaWRTdGFjayA9IFtdO1xudmFyIGlkU3RhY2tJbmRleCA9IDA7XG52YXIgdHJlZUNvbnRleHRQcm92aWRlciA9IG51bGw7XG52YXIgdHJlZUNvbnRleHRJZCA9IDE7XG52YXIgdHJlZUNvbnRleHRPdmVyZmxvdyA9ICcnO1xuZnVuY3Rpb24gaXNGb3JrZWRDaGlsZCh3b3JrSW5Qcm9ncmVzcykge1xuICB3YXJuSWZOb3RIeWRyYXRpbmcoKTtcbiAgcmV0dXJuICh3b3JrSW5Qcm9ncmVzcy5mbGFncyAmIEZvcmtlZCkgIT09IE5vRmxhZ3M7XG59XG5mdW5jdGlvbiBnZXRGb3Jrc0F0TGV2ZWwod29ya0luUHJvZ3Jlc3MpIHtcbiAgd2FybklmTm90SHlkcmF0aW5nKCk7XG4gIHJldHVybiB0cmVlRm9ya0NvdW50O1xufVxuZnVuY3Rpb24gZ2V0VHJlZUlkKCkge1xuICB2YXIgb3ZlcmZsb3cgPSB0cmVlQ29udGV4dE92ZXJmbG93O1xuICB2YXIgaWRXaXRoTGVhZGluZ0JpdCA9IHRyZWVDb250ZXh0SWQ7XG4gIHZhciBpZCA9IGlkV2l0aExlYWRpbmdCaXQgJiB+Z2V0TGVhZGluZ0JpdChpZFdpdGhMZWFkaW5nQml0KTtcbiAgcmV0dXJuIGlkLnRvU3RyaW5nKDMyKSArIG92ZXJmbG93O1xufVxuZnVuY3Rpb24gcHVzaFRyZWVGb3JrKHdvcmtJblByb2dyZXNzLCB0b3RhbENoaWxkcmVuKSB7XG4gIC8vIFRoaXMgaXMgY2FsbGVkIHJpZ2h0IGFmdGVyIHdlIHJlY29uY2lsZSBhbiBhcnJheSAob3IgaXRlcmF0b3IpIG9mIGNoaWxkXG4gIC8vIGZpYmVycywgYmVjYXVzZSB0aGF0J3MgdGhlIG9ubHkgcGxhY2Ugd2hlcmUgd2Uga25vdyBob3cgbWFueSBjaGlsZHJlbiBpblxuICAvLyB0aGUgd2hvbGUgc2V0IHdpdGhvdXQgZG9pbmcgZXh0cmEgd29yayBsYXRlciwgb3Igc3RvcmluZyBhZGR0aW9uYWxcbiAgLy8gaW5mb3JtYXRpb24gb24gdGhlIGZpYmVyLlxuICAvL1xuICAvLyBUaGF0J3Mgd2h5IHRoaXMgZnVuY3Rpb24gaXMgc2VwYXJhdGUgZnJvbSBwdXNoVHJlZUlkIOKAlCBpdCdzIGNhbGxlZCBkdXJpbmdcbiAgLy8gdGhlIHJlbmRlciBwaGFzZSBvZiB0aGUgZm9yayBwYXJlbnQsIG5vdCB0aGUgY2hpbGQsIHdoaWNoIGlzIHdoZXJlIHdlIHB1c2hcbiAgLy8gdGhlIG90aGVyIGNvbnRleHQgdmFsdWVzLlxuICAvL1xuICAvLyBJbiB0aGUgRml6eiBpbXBsZW1lbnRhdGlvbiB0aGlzIGlzIG11Y2ggc2ltcGxlciBiZWNhdXNlIHRoZSBjaGlsZCBpc1xuICAvLyByZW5kZXJlZCBpbiB0aGUgc2FtZSBjYWxsc3RhY2sgYXMgdGhlIHBhcmVudC5cbiAgLy9cbiAgLy8gSXQgbWlnaHQgYmUgYmV0dGVyIHRvIGp1c3QgYWRkIGEgYGZvcmtzYCBmaWVsZCB0byB0aGUgRmliZXIgdHlwZS4gSXQgd291bGRcbiAgLy8gbWFrZSB0aGlzIG1vZHVsZSBzaW1wbGVyLlxuICB3YXJuSWZOb3RIeWRyYXRpbmcoKTtcbiAgZm9ya1N0YWNrW2ZvcmtTdGFja0luZGV4KytdID0gdHJlZUZvcmtDb3VudDtcbiAgZm9ya1N0YWNrW2ZvcmtTdGFja0luZGV4KytdID0gdHJlZUZvcmtQcm92aWRlcjtcbiAgdHJlZUZvcmtQcm92aWRlciA9IHdvcmtJblByb2dyZXNzO1xuICB0cmVlRm9ya0NvdW50ID0gdG90YWxDaGlsZHJlbjtcbn1cbmZ1bmN0aW9uIHB1c2hUcmVlSWQod29ya0luUHJvZ3Jlc3MsIHRvdGFsQ2hpbGRyZW4sIGluZGV4KSB7XG4gIHdhcm5JZk5vdEh5ZHJhdGluZygpO1xuICBpZFN0YWNrW2lkU3RhY2tJbmRleCsrXSA9IHRyZWVDb250ZXh0SWQ7XG4gIGlkU3RhY2tbaWRTdGFja0luZGV4KytdID0gdHJlZUNvbnRleHRPdmVyZmxvdztcbiAgaWRTdGFja1tpZFN0YWNrSW5kZXgrK10gPSB0cmVlQ29udGV4dFByb3ZpZGVyO1xuICB0cmVlQ29udGV4dFByb3ZpZGVyID0gd29ya0luUHJvZ3Jlc3M7XG4gIHZhciBiYXNlSWRXaXRoTGVhZGluZ0JpdCA9IHRyZWVDb250ZXh0SWQ7XG4gIHZhciBiYXNlT3ZlcmZsb3cgPSB0cmVlQ29udGV4dE92ZXJmbG93OyAvLyBUaGUgbGVmdG1vc3QgMSBtYXJrcyB0aGUgZW5kIG9mIHRoZSBzZXF1ZW5jZSwgbm9uLWluY2x1c2l2ZS4gSXQncyBub3QgcGFydFxuICAvLyBvZiB0aGUgaWQ7IHdlIHVzZSBpdCB0byBhY2NvdW50IGZvciBsZWFkaW5nIDBzLlxuXG4gIHZhciBiYXNlTGVuZ3RoID0gZ2V0Qml0TGVuZ3RoKGJhc2VJZFdpdGhMZWFkaW5nQml0KSAtIDE7XG4gIHZhciBiYXNlSWQgPSBiYXNlSWRXaXRoTGVhZGluZ0JpdCAmIH4oMSA8PCBiYXNlTGVuZ3RoKTtcbiAgdmFyIHNsb3QgPSBpbmRleCArIDE7XG4gIHZhciBsZW5ndGggPSBnZXRCaXRMZW5ndGgodG90YWxDaGlsZHJlbikgKyBiYXNlTGVuZ3RoOyAvLyAzMCBpcyB0aGUgbWF4IGxlbmd0aCB3ZSBjYW4gc3RvcmUgd2l0aG91dCBvdmVyZmxvd2luZywgdGFraW5nIGludG9cbiAgLy8gY29uc2lkZXJhdGlvbiB0aGUgbGVhZGluZyAxIHdlIHVzZSB0byBtYXJrIHRoZSBlbmQgb2YgdGhlIHNlcXVlbmNlLlxuXG4gIGlmIChsZW5ndGggPiAzMCkge1xuICAgIC8vIFdlIG92ZXJmbG93ZWQgdGhlIGJpdHdpc2Utc2FmZSByYW5nZS4gRmFsbCBiYWNrIHRvIHNsb3dlciBhbGdvcml0aG0uXG4gICAgLy8gVGhpcyBicmFuY2ggYXNzdW1lcyB0aGUgbGVuZ3RoIG9mIHRoZSBiYXNlIGlkIGlzIGdyZWF0ZXIgdGhhbiA1OyBpdCB3b24ndFxuICAgIC8vIHdvcmsgZm9yIHNtYWxsZXIgaWRzLCBiZWNhdXNlIHlvdSBuZWVkIDUgYml0cyBwZXIgY2hhcmFjdGVyLlxuICAgIC8vXG4gICAgLy8gV2UgZW5jb2RlIHRoZSBpZCBpbiBtdWx0aXBsZSBzdGVwczogZmlyc3QgdGhlIGJhc2UgaWQsIHRoZW4gdGhlXG4gICAgLy8gcmVtYWluaW5nIGRpZ2l0cy5cbiAgICAvL1xuICAgIC8vIEVhY2ggNSBiaXQgc2VxdWVuY2UgY29ycmVzcG9uZHMgdG8gYSBzaW5nbGUgYmFzZSAzMiBjaGFyYWN0ZXIuIFNvIGZvclxuICAgIC8vIGV4YW1wbGUsIGlmIHRoZSBjdXJyZW50IGlkIGlzIDIzIGJpdHMgbG9uZywgd2UgY2FuIGNvbnZlcnQgMjAgb2YgdGhvc2VcbiAgICAvLyBiaXRzIGludG8gYSBzdHJpbmcgb2YgNCBjaGFyYWN0ZXJzLCB3aXRoIDMgYml0cyBsZWZ0IG92ZXIuXG4gICAgLy9cbiAgICAvLyBGaXJzdCBjYWxjdWxhdGUgaG93IG1hbnkgYml0cyBpbiB0aGUgYmFzZSBpZCByZXByZXNlbnQgYSBjb21wbGV0ZVxuICAgIC8vIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMuXG4gICAgdmFyIG51bWJlck9mT3ZlcmZsb3dCaXRzID0gYmFzZUxlbmd0aCAtIGJhc2VMZW5ndGggJSA1OyAvLyBUaGVuIGNyZWF0ZSBhIGJpdG1hc2sgdGhhdCBzZWxlY3RzIG9ubHkgdGhvc2UgYml0cy5cblxuICAgIHZhciBuZXdPdmVyZmxvd0JpdHMgPSAoMSA8PCBudW1iZXJPZk92ZXJmbG93Qml0cykgLSAxOyAvLyBTZWxlY3QgdGhlIGJpdHMsIGFuZCBjb252ZXJ0IHRoZW0gdG8gYSBiYXNlIDMyIHN0cmluZy5cblxuICAgIHZhciBuZXdPdmVyZmxvdyA9IChiYXNlSWQgJiBuZXdPdmVyZmxvd0JpdHMpLnRvU3RyaW5nKDMyKTsgLy8gTm93IHdlIGNhbiByZW1vdmUgdGhvc2UgYml0cyBmcm9tIHRoZSBiYXNlIGlkLlxuXG4gICAgdmFyIHJlc3RPZkJhc2VJZCA9IGJhc2VJZCA+PiBudW1iZXJPZk92ZXJmbG93Qml0cztcbiAgICB2YXIgcmVzdE9mQmFzZUxlbmd0aCA9IGJhc2VMZW5ndGggLSBudW1iZXJPZk92ZXJmbG93Qml0czsgLy8gRmluYWxseSwgZW5jb2RlIHRoZSByZXN0IG9mIHRoZSBiaXRzIHVzaW5nIHRoZSBub3JtYWwgYWxnb3JpdGhtLiBCZWNhdXNlXG4gICAgLy8gd2UgbWFkZSBtb3JlIHJvb20sIHRoaXMgdGltZSBpdCB3b24ndCBvdmVyZmxvdy5cblxuICAgIHZhciByZXN0T2ZMZW5ndGggPSBnZXRCaXRMZW5ndGgodG90YWxDaGlsZHJlbikgKyByZXN0T2ZCYXNlTGVuZ3RoO1xuICAgIHZhciByZXN0T2ZOZXdCaXRzID0gc2xvdCA8PCByZXN0T2ZCYXNlTGVuZ3RoO1xuICAgIHZhciBpZCA9IHJlc3RPZk5ld0JpdHMgfCByZXN0T2ZCYXNlSWQ7XG4gICAgdmFyIG92ZXJmbG93ID0gbmV3T3ZlcmZsb3cgKyBiYXNlT3ZlcmZsb3c7XG4gICAgdHJlZUNvbnRleHRJZCA9IDEgPDwgcmVzdE9mTGVuZ3RoIHwgaWQ7XG4gICAgdHJlZUNvbnRleHRPdmVyZmxvdyA9IG92ZXJmbG93O1xuICB9IGVsc2Uge1xuICAgIC8vIE5vcm1hbCBwYXRoXG4gICAgdmFyIG5ld0JpdHMgPSBzbG90IDw8IGJhc2VMZW5ndGg7XG5cbiAgICB2YXIgX2lkID0gbmV3Qml0cyB8IGJhc2VJZDtcblxuICAgIHZhciBfb3ZlcmZsb3cgPSBiYXNlT3ZlcmZsb3c7XG4gICAgdHJlZUNvbnRleHRJZCA9IDEgPDwgbGVuZ3RoIHwgX2lkO1xuICAgIHRyZWVDb250ZXh0T3ZlcmZsb3cgPSBfb3ZlcmZsb3c7XG4gIH1cbn1cbmZ1bmN0aW9uIHB1c2hNYXRlcmlhbGl6ZWRUcmVlSWQod29ya0luUHJvZ3Jlc3MpIHtcbiAgd2FybklmTm90SHlkcmF0aW5nKCk7IC8vIFRoaXMgY29tcG9uZW50IG1hdGVyaWFsaXplZCBhbiBpZC4gVGhpcyB3aWxsIGFmZmVjdCBhbnkgaWRzIHRoYXQgYXBwZWFyXG4gIC8vIGluIGl0cyBjaGlsZHJlbi5cblxuICB2YXIgcmV0dXJuRmliZXIgPSB3b3JrSW5Qcm9ncmVzcy5yZXR1cm47XG5cbiAgaWYgKHJldHVybkZpYmVyICE9PSBudWxsKSB7XG4gICAgdmFyIG51bWJlck9mRm9ya3MgPSAxO1xuICAgIHZhciBzbG90SW5kZXggPSAwO1xuICAgIHB1c2hUcmVlRm9yayh3b3JrSW5Qcm9ncmVzcywgbnVtYmVyT2ZGb3Jrcyk7XG4gICAgcHVzaFRyZWVJZCh3b3JrSW5Qcm9ncmVzcywgbnVtYmVyT2ZGb3Jrcywgc2xvdEluZGV4KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRCaXRMZW5ndGgobnVtYmVyKSB7XG4gIHJldHVybiAzMiAtIGNsejMyKG51bWJlcik7XG59XG5cbmZ1bmN0aW9uIGdldExlYWRpbmdCaXQoaWQpIHtcbiAgcmV0dXJuIDEgPDwgZ2V0Qml0TGVuZ3RoKGlkKSAtIDE7XG59XG5cbmZ1bmN0aW9uIHBvcFRyZWVDb250ZXh0KHdvcmtJblByb2dyZXNzKSB7XG4gIC8vIFJlc3RvcmUgdGhlIHByZXZpb3VzIHZhbHVlcy5cbiAgLy8gVGhpcyBpcyBhIGJpdCBtb3JlIGNvbXBsaWNhdGVkIHRoYW4gb3RoZXIgY29udGV4dC1saWtlIG1vZHVsZXMgaW4gRmliZXJcbiAgLy8gYmVjYXVzZSB0aGUgc2FtZSBGaWJlciBtYXkgYXBwZWFyIG9uIHRoZSBzdGFjayBtdWx0aXBsZSB0aW1lcyBhbmQgZm9yXG4gIC8vIGRpZmZlcmVudCByZWFzb25zLiBXZSBoYXZlIHRvIGtlZXAgcG9wcGluZyB1bnRpbCB0aGUgd29yay1pbi1wcm9ncmVzcyBpc1xuICAvLyBubyBsb25nZXIgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2suXG4gIHdoaWxlICh3b3JrSW5Qcm9ncmVzcyA9PT0gdHJlZUZvcmtQcm92aWRlcikge1xuICAgIHRyZWVGb3JrUHJvdmlkZXIgPSBmb3JrU3RhY2tbLS1mb3JrU3RhY2tJbmRleF07XG4gICAgZm9ya1N0YWNrW2ZvcmtTdGFja0luZGV4XSA9IG51bGw7XG4gICAgdHJlZUZvcmtDb3VudCA9IGZvcmtTdGFja1stLWZvcmtTdGFja0luZGV4XTtcbiAgICBmb3JrU3RhY2tbZm9ya1N0YWNrSW5kZXhdID0gbnVsbDtcbiAgfVxuXG4gIHdoaWxlICh3b3JrSW5Qcm9ncmVzcyA9PT0gdHJlZUNvbnRleHRQcm92aWRlcikge1xuICAgIHRyZWVDb250ZXh0UHJvdmlkZXIgPSBpZFN0YWNrWy0taWRTdGFja0luZGV4XTtcbiAgICBpZFN0YWNrW2lkU3RhY2tJbmRleF0gPSBudWxsO1xuICAgIHRyZWVDb250ZXh0T3ZlcmZsb3cgPSBpZFN0YWNrWy0taWRTdGFja0luZGV4XTtcbiAgICBpZFN0YWNrW2lkU3RhY2tJbmRleF0gPSBudWxsO1xuICAgIHRyZWVDb250ZXh0SWQgPSBpZFN0YWNrWy0taWRTdGFja0luZGV4XTtcbiAgICBpZFN0YWNrW2lkU3RhY2tJbmRleF0gPSBudWxsO1xuICB9XG59XG5mdW5jdGlvbiBnZXRTdXNwZW5kZWRUcmVlQ29udGV4dCgpIHtcbiAgd2FybklmTm90SHlkcmF0aW5nKCk7XG5cbiAgaWYgKHRyZWVDb250ZXh0UHJvdmlkZXIgIT09IG51bGwpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHRyZWVDb250ZXh0SWQsXG4gICAgICBvdmVyZmxvdzogdHJlZUNvbnRleHRPdmVyZmxvd1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cbmZ1bmN0aW9uIHJlc3RvcmVTdXNwZW5kZWRUcmVlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgc3VzcGVuZGVkQ29udGV4dCkge1xuICB3YXJuSWZOb3RIeWRyYXRpbmcoKTtcbiAgaWRTdGFja1tpZFN0YWNrSW5kZXgrK10gPSB0cmVlQ29udGV4dElkO1xuICBpZFN0YWNrW2lkU3RhY2tJbmRleCsrXSA9IHRyZWVDb250ZXh0T3ZlcmZsb3c7XG4gIGlkU3RhY2tbaWRTdGFja0luZGV4KytdID0gdHJlZUNvbnRleHRQcm92aWRlcjtcbiAgdHJlZUNvbnRleHRJZCA9IHN1c3BlbmRlZENvbnRleHQuaWQ7XG4gIHRyZWVDb250ZXh0T3ZlcmZsb3cgPSBzdXNwZW5kZWRDb250ZXh0Lm92ZXJmbG93O1xuICB0cmVlQ29udGV4dFByb3ZpZGVyID0gd29ya0luUHJvZ3Jlc3M7XG59XG5cbmZ1bmN0aW9uIHdhcm5JZk5vdEh5ZHJhdGluZygpIHtcbiAge1xuICAgIGlmICghZ2V0SXNIeWRyYXRpbmcoKSkge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIHRvIGJlIGh5ZHJhdGluZy4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgJyArICdhbiBpc3N1ZS4nKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhpcyBtYXkgaGF2ZSBiZWVuIGFuIGluc2VydGlvbiBvciBhIGh5ZHJhdGlvbi5cblxudmFyIGh5ZHJhdGlvblBhcmVudEZpYmVyID0gbnVsbDtcbnZhciBuZXh0SHlkcmF0YWJsZUluc3RhbmNlID0gbnVsbDtcbnZhciBpc0h5ZHJhdGluZyA9IGZhbHNlOyAvLyBUaGlzIGZsYWcgYWxsb3dzIGZvciB3YXJuaW5nIHN1cHJlc3Npb24gd2hlbiB3ZSBleHBlY3QgdGhlcmUgdG8gYmUgbWlzbWF0Y2hlc1xuLy8gZHVlIHRvIGVhcmxpZXIgbWlzbWF0Y2hlcyBvciBhIHN1c3BlbmRlZCBmaWJlci5cblxudmFyIGRpZFN1c3BlbmRPckVycm9yREVWID0gZmFsc2U7IC8vIEh5ZHJhdGlvbiBlcnJvcnMgdGhhdCB3ZXJlIHRocm93biBpbnNpZGUgdGhpcyBib3VuZGFyeVxuXG52YXIgaHlkcmF0aW9uRXJyb3JzID0gbnVsbDtcblxuZnVuY3Rpb24gd2FybklmSHlkcmF0aW5nKCkge1xuICB7XG4gICAgaWYgKGlzSHlkcmF0aW5nKSB7XG4gICAgICBlcnJvcignV2Ugc2hvdWxkIG5vdCBiZSBoeWRyYXRpbmcgaGVyZS4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYSBidWcuJyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1hcmtEaWRUaHJvd1doaWxlSHlkcmF0aW5nREVWKCkge1xuICB7XG4gICAgZGlkU3VzcGVuZE9yRXJyb3JERVYgPSB0cnVlO1xuICB9XG59XG5mdW5jdGlvbiBkaWRTdXNwZW5kT3JFcnJvcldoaWxlSHlkcmF0aW5nREVWKCkge1xuICB7XG4gICAgcmV0dXJuIGRpZFN1c3BlbmRPckVycm9yREVWO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVudGVySHlkcmF0aW9uU3RhdGUoZmliZXIpIHtcblxuICB2YXIgcGFyZW50SW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGUuY29udGFpbmVySW5mbztcbiAgbmV4dEh5ZHJhdGFibGVJbnN0YW5jZSA9IGdldEZpcnN0SHlkcmF0YWJsZUNoaWxkV2l0aGluQ29udGFpbmVyKHBhcmVudEluc3RhbmNlKTtcbiAgaHlkcmF0aW9uUGFyZW50RmliZXIgPSBmaWJlcjtcbiAgaXNIeWRyYXRpbmcgPSB0cnVlO1xuICBoeWRyYXRpb25FcnJvcnMgPSBudWxsO1xuICBkaWRTdXNwZW5kT3JFcnJvckRFViA9IGZhbHNlO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmVlbnRlckh5ZHJhdGlvblN0YXRlRnJvbURlaHlkcmF0ZWRTdXNwZW5zZUluc3RhbmNlKGZpYmVyLCBzdXNwZW5zZUluc3RhbmNlLCB0cmVlQ29udGV4dCkge1xuXG4gIG5leHRIeWRyYXRhYmxlSW5zdGFuY2UgPSBnZXRGaXJzdEh5ZHJhdGFibGVDaGlsZFdpdGhpblN1c3BlbnNlSW5zdGFuY2Uoc3VzcGVuc2VJbnN0YW5jZSk7XG4gIGh5ZHJhdGlvblBhcmVudEZpYmVyID0gZmliZXI7XG4gIGlzSHlkcmF0aW5nID0gdHJ1ZTtcbiAgaHlkcmF0aW9uRXJyb3JzID0gbnVsbDtcbiAgZGlkU3VzcGVuZE9yRXJyb3JERVYgPSBmYWxzZTtcblxuICBpZiAodHJlZUNvbnRleHQgIT09IG51bGwpIHtcbiAgICByZXN0b3JlU3VzcGVuZGVkVHJlZUNvbnRleHQoZmliZXIsIHRyZWVDb250ZXh0KTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiB3YXJuVW5oeWRyYXRlZEluc3RhbmNlKHJldHVybkZpYmVyLCBpbnN0YW5jZSkge1xuICB7XG4gICAgc3dpdGNoIChyZXR1cm5GaWJlci50YWcpIHtcbiAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgIHtcbiAgICAgICAgICBkaWROb3RIeWRyYXRlSW5zdGFuY2VXaXRoaW5Db250YWluZXIocmV0dXJuRmliZXIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm8sIGluc3RhbmNlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgaXNDb25jdXJyZW50TW9kZSA9IChyZXR1cm5GaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG4gICAgICAgICAgZGlkTm90SHlkcmF0ZUluc3RhbmNlKHJldHVybkZpYmVyLnR5cGUsIHJldHVybkZpYmVyLm1lbW9pemVkUHJvcHMsIHJldHVybkZpYmVyLnN0YXRlTm9kZSwgaW5zdGFuY2UsIC8vIFRPRE86IERlbGV0ZSB0aGlzIGFyZ3VtZW50IHdoZW4gd2UgcmVtb3ZlIHRoZSBsZWdhY3kgcm9vdCBBUEkuXG4gICAgICAgICAgaXNDb25jdXJyZW50TW9kZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBTdXNwZW5zZUNvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBzdXNwZW5zZVN0YXRlID0gcmV0dXJuRmliZXIubWVtb2l6ZWRTdGF0ZTtcbiAgICAgICAgICBpZiAoc3VzcGVuc2VTdGF0ZS5kZWh5ZHJhdGVkICE9PSBudWxsKSBkaWROb3RIeWRyYXRlSW5zdGFuY2VXaXRoaW5TdXNwZW5zZUluc3RhbmNlKHN1c3BlbnNlU3RhdGUuZGVoeWRyYXRlZCwgaW5zdGFuY2UpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGRlbGV0ZUh5ZHJhdGFibGVJbnN0YW5jZShyZXR1cm5GaWJlciwgaW5zdGFuY2UpIHtcbiAgd2FyblVuaHlkcmF0ZWRJbnN0YW5jZShyZXR1cm5GaWJlciwgaW5zdGFuY2UpO1xuICB2YXIgY2hpbGRUb0RlbGV0ZSA9IGNyZWF0ZUZpYmVyRnJvbUhvc3RJbnN0YW5jZUZvckRlbGV0aW9uKCk7XG4gIGNoaWxkVG9EZWxldGUuc3RhdGVOb2RlID0gaW5zdGFuY2U7XG4gIGNoaWxkVG9EZWxldGUucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gIHZhciBkZWxldGlvbnMgPSByZXR1cm5GaWJlci5kZWxldGlvbnM7XG5cbiAgaWYgKGRlbGV0aW9ucyA9PT0gbnVsbCkge1xuICAgIHJldHVybkZpYmVyLmRlbGV0aW9ucyA9IFtjaGlsZFRvRGVsZXRlXTtcbiAgICByZXR1cm5GaWJlci5mbGFncyB8PSBDaGlsZERlbGV0aW9uO1xuICB9IGVsc2Uge1xuICAgIGRlbGV0aW9ucy5wdXNoKGNoaWxkVG9EZWxldGUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHdhcm5Ob25oeWRyYXRlZEluc3RhbmNlKHJldHVybkZpYmVyLCBmaWJlcikge1xuICB7XG4gICAgaWYgKGRpZFN1c3BlbmRPckVycm9yREVWKSB7XG4gICAgICAvLyBJbnNpZGUgYSBib3VuZGFyeSB0aGF0IGFscmVhZHkgc3VzcGVuZGVkLiBXZSdyZSBjdXJyZW50bHkgcmVuZGVyaW5nIHRoZVxuICAgICAgLy8gc2libGluZ3Mgb2YgYSBzdXNwZW5kZWQgbm9kZS4gVGhlIG1pc21hdGNoIG1heSBiZSBkdWUgdG8gdGhlIG1pc3NpbmdcbiAgICAgIC8vIGRhdGEsIHNvIGl0J3MgcHJvYmFibHkgYSBmYWxzZSBwb3NpdGl2ZS5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHJldHVybkZpYmVyLnRhZykge1xuICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBwYXJlbnRDb250YWluZXIgPSByZXR1cm5GaWJlci5zdGF0ZU5vZGUuY29udGFpbmVySW5mbztcblxuICAgICAgICAgIHN3aXRjaCAoZmliZXIudGFnKSB7XG4gICAgICAgICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgICAgICAgIHZhciB0eXBlID0gZmliZXIudHlwZTtcbiAgICAgICAgICAgICAgdmFyIHByb3BzID0gZmliZXIucGVuZGluZ1Byb3BzO1xuICAgICAgICAgICAgICBkaWROb3RGaW5kSHlkcmF0YWJsZUluc3RhbmNlV2l0aGluQ29udGFpbmVyKHBhcmVudENvbnRhaW5lciwgdHlwZSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlIEhvc3RUZXh0OlxuICAgICAgICAgICAgICB2YXIgdGV4dCA9IGZpYmVyLnBlbmRpbmdQcm9wcztcbiAgICAgICAgICAgICAgZGlkTm90RmluZEh5ZHJhdGFibGVUZXh0SW5zdGFuY2VXaXRoaW5Db250YWluZXIocGFyZW50Q29udGFpbmVyLCB0ZXh0KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHBhcmVudFR5cGUgPSByZXR1cm5GaWJlci50eXBlO1xuICAgICAgICAgIHZhciBwYXJlbnRQcm9wcyA9IHJldHVybkZpYmVyLm1lbW9pemVkUHJvcHM7XG4gICAgICAgICAgdmFyIHBhcmVudEluc3RhbmNlID0gcmV0dXJuRmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICAgICAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZhciBfdHlwZSA9IGZpYmVyLnR5cGU7XG4gICAgICAgICAgICAgICAgdmFyIF9wcm9wcyA9IGZpYmVyLnBlbmRpbmdQcm9wcztcbiAgICAgICAgICAgICAgICB2YXIgaXNDb25jdXJyZW50TW9kZSA9IChyZXR1cm5GaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG4gICAgICAgICAgICAgICAgZGlkTm90RmluZEh5ZHJhdGFibGVJbnN0YW5jZShwYXJlbnRUeXBlLCBwYXJlbnRQcm9wcywgcGFyZW50SW5zdGFuY2UsIF90eXBlLCBfcHJvcHMsIC8vIFRPRE86IERlbGV0ZSB0aGlzIGFyZ3VtZW50IHdoZW4gd2UgcmVtb3ZlIHRoZSBsZWdhY3kgcm9vdCBBUEkuXG4gICAgICAgICAgICAgICAgaXNDb25jdXJyZW50TW9kZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSBIb3N0VGV4dDpcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZhciBfdGV4dCA9IGZpYmVyLnBlbmRpbmdQcm9wcztcblxuICAgICAgICAgICAgICAgIHZhciBfaXNDb25jdXJyZW50TW9kZSA9IChyZXR1cm5GaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG5cbiAgICAgICAgICAgICAgICBkaWROb3RGaW5kSHlkcmF0YWJsZVRleHRJbnN0YW5jZShwYXJlbnRUeXBlLCBwYXJlbnRQcm9wcywgcGFyZW50SW5zdGFuY2UsIF90ZXh0LCAvLyBUT0RPOiBEZWxldGUgdGhpcyBhcmd1bWVudCB3aGVuIHdlIHJlbW92ZSB0aGUgbGVnYWN5IHJvb3QgQVBJLlxuICAgICAgICAgICAgICAgIF9pc0NvbmN1cnJlbnRNb2RlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgc3VzcGVuc2VTdGF0ZSA9IHJldHVybkZpYmVyLm1lbW9pemVkU3RhdGU7XG4gICAgICAgICAgdmFyIF9wYXJlbnRJbnN0YW5jZSA9IHN1c3BlbnNlU3RhdGUuZGVoeWRyYXRlZDtcbiAgICAgICAgICBpZiAoX3BhcmVudEluc3RhbmNlICE9PSBudWxsKSBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgICAgICAgICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAgICAgICAgICB2YXIgX3R5cGUyID0gZmliZXIudHlwZTtcbiAgICAgICAgICAgICAgdmFyIF9wcm9wczIgPSBmaWJlci5wZW5kaW5nUHJvcHM7XG4gICAgICAgICAgICAgIGRpZE5vdEZpbmRIeWRyYXRhYmxlSW5zdGFuY2VXaXRoaW5TdXNwZW5zZUluc3RhbmNlKF9wYXJlbnRJbnN0YW5jZSwgX3R5cGUyKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgSG9zdFRleHQ6XG4gICAgICAgICAgICAgIHZhciBfdGV4dDIgPSBmaWJlci5wZW5kaW5nUHJvcHM7XG4gICAgICAgICAgICAgIGRpZE5vdEZpbmRIeWRyYXRhYmxlVGV4dEluc3RhbmNlV2l0aGluU3VzcGVuc2VJbnN0YW5jZShfcGFyZW50SW5zdGFuY2UsIF90ZXh0Mik7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm47XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGluc2VydE5vbkh5ZHJhdGVkSW5zdGFuY2UocmV0dXJuRmliZXIsIGZpYmVyKSB7XG4gIGZpYmVyLmZsYWdzID0gZmliZXIuZmxhZ3MgJiB+SHlkcmF0aW5nIHwgUGxhY2VtZW50O1xuICB3YXJuTm9uaHlkcmF0ZWRJbnN0YW5jZShyZXR1cm5GaWJlciwgZmliZXIpO1xufVxuXG5mdW5jdGlvbiB0cnlIeWRyYXRlKGZpYmVyLCBuZXh0SW5zdGFuY2UpIHtcbiAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciB0eXBlID0gZmliZXIudHlwZTtcbiAgICAgICAgdmFyIHByb3BzID0gZmliZXIucGVuZGluZ1Byb3BzO1xuICAgICAgICB2YXIgaW5zdGFuY2UgPSBjYW5IeWRyYXRlSW5zdGFuY2UobmV4dEluc3RhbmNlLCB0eXBlKTtcblxuICAgICAgICBpZiAoaW5zdGFuY2UgIT09IG51bGwpIHtcbiAgICAgICAgICBmaWJlci5zdGF0ZU5vZGUgPSBpbnN0YW5jZTtcbiAgICAgICAgICBoeWRyYXRpb25QYXJlbnRGaWJlciA9IGZpYmVyO1xuICAgICAgICAgIG5leHRIeWRyYXRhYmxlSW5zdGFuY2UgPSBnZXRGaXJzdEh5ZHJhdGFibGVDaGlsZChpbnN0YW5jZSk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RUZXh0OlxuICAgICAge1xuICAgICAgICB2YXIgdGV4dCA9IGZpYmVyLnBlbmRpbmdQcm9wcztcbiAgICAgICAgdmFyIHRleHRJbnN0YW5jZSA9IGNhbkh5ZHJhdGVUZXh0SW5zdGFuY2UobmV4dEluc3RhbmNlLCB0ZXh0KTtcblxuICAgICAgICBpZiAodGV4dEluc3RhbmNlICE9PSBudWxsKSB7XG4gICAgICAgICAgZmliZXIuc3RhdGVOb2RlID0gdGV4dEluc3RhbmNlO1xuICAgICAgICAgIGh5ZHJhdGlvblBhcmVudEZpYmVyID0gZmliZXI7IC8vIFRleHQgSW5zdGFuY2VzIGRvbid0IGhhdmUgY2hpbGRyZW4gc28gdGhlcmUncyBub3RoaW5nIHRvIGh5ZHJhdGUuXG5cbiAgICAgICAgICBuZXh0SHlkcmF0YWJsZUluc3RhbmNlID0gbnVsbDtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBzdXNwZW5zZUluc3RhbmNlID0gY2FuSHlkcmF0ZVN1c3BlbnNlSW5zdGFuY2UobmV4dEluc3RhbmNlKTtcblxuICAgICAgICBpZiAoc3VzcGVuc2VJbnN0YW5jZSAhPT0gbnVsbCkge1xuICAgICAgICAgIHZhciBzdXNwZW5zZVN0YXRlID0ge1xuICAgICAgICAgICAgZGVoeWRyYXRlZDogc3VzcGVuc2VJbnN0YW5jZSxcbiAgICAgICAgICAgIHRyZWVDb250ZXh0OiBnZXRTdXNwZW5kZWRUcmVlQ29udGV4dCgpLFxuICAgICAgICAgICAgcmV0cnlMYW5lOiBPZmZzY3JlZW5MYW5lXG4gICAgICAgICAgfTtcbiAgICAgICAgICBmaWJlci5tZW1vaXplZFN0YXRlID0gc3VzcGVuc2VTdGF0ZTsgLy8gU3RvcmUgdGhlIGRlaHlkcmF0ZWQgZnJhZ21lbnQgYXMgYSBjaGlsZCBmaWJlci5cbiAgICAgICAgICAvLyBUaGlzIHNpbXBsaWZpZXMgdGhlIGNvZGUgZm9yIGdldEhvc3RTaWJsaW5nIGFuZCBkZWxldGluZyBub2RlcyxcbiAgICAgICAgICAvLyBzaW5jZSBpdCBkb2Vzbid0IGhhdmUgdG8gY29uc2lkZXIgYWxsIFN1c3BlbnNlIGJvdW5kYXJpZXMgYW5kXG4gICAgICAgICAgLy8gY2hlY2sgaWYgdGhleSdyZSBkZWh5ZHJhdGVkIG9uZXMgb3Igbm90LlxuXG4gICAgICAgICAgdmFyIGRlaHlkcmF0ZWRGcmFnbWVudCA9IGNyZWF0ZUZpYmVyRnJvbURlaHlkcmF0ZWRGcmFnbWVudChzdXNwZW5zZUluc3RhbmNlKTtcbiAgICAgICAgICBkZWh5ZHJhdGVkRnJhZ21lbnQucmV0dXJuID0gZmliZXI7XG4gICAgICAgICAgZmliZXIuY2hpbGQgPSBkZWh5ZHJhdGVkRnJhZ21lbnQ7XG4gICAgICAgICAgaHlkcmF0aW9uUGFyZW50RmliZXIgPSBmaWJlcjsgLy8gV2hpbGUgYSBTdXNwZW5zZSBJbnN0YW5jZSBkb2VzIGhhdmUgY2hpbGRyZW4sIHdlIHdvbid0IHN0ZXAgaW50b1xuICAgICAgICAgIC8vIGl0IGR1cmluZyB0aGUgZmlyc3QgcGFzcy4gSW5zdGVhZCwgd2UnbGwgcmVlbnRlciBpdCBsYXRlci5cblxuICAgICAgICAgIG5leHRIeWRyYXRhYmxlSW5zdGFuY2UgPSBudWxsO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzaG91bGRDbGllbnRSZW5kZXJPbk1pc21hdGNoKGZpYmVyKSB7XG4gIHJldHVybiAoZmliZXIubW9kZSAmIENvbmN1cnJlbnRNb2RlKSAhPT0gTm9Nb2RlICYmIChmaWJlci5mbGFncyAmIERpZENhcHR1cmUpID09PSBOb0ZsYWdzO1xufVxuXG5mdW5jdGlvbiB0aHJvd09uSHlkcmF0aW9uTWlzbWF0Y2goZmliZXIpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdIeWRyYXRpb24gZmFpbGVkIGJlY2F1c2UgdGhlIGluaXRpYWwgVUkgZG9lcyBub3QgbWF0Y2ggd2hhdCB3YXMgJyArICdyZW5kZXJlZCBvbiB0aGUgc2VydmVyLicpO1xufVxuXG5mdW5jdGlvbiB0cnlUb0NsYWltTmV4dEh5ZHJhdGFibGVJbnN0YW5jZShmaWJlcikge1xuICBpZiAoIWlzSHlkcmF0aW5nKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG5leHRJbnN0YW5jZSA9IG5leHRIeWRyYXRhYmxlSW5zdGFuY2U7XG5cbiAgaWYgKCFuZXh0SW5zdGFuY2UpIHtcbiAgICBpZiAoc2hvdWxkQ2xpZW50UmVuZGVyT25NaXNtYXRjaChmaWJlcikpIHtcbiAgICAgIHdhcm5Ob25oeWRyYXRlZEluc3RhbmNlKGh5ZHJhdGlvblBhcmVudEZpYmVyLCBmaWJlcik7XG4gICAgICB0aHJvd09uSHlkcmF0aW9uTWlzbWF0Y2goKTtcbiAgICB9IC8vIE5vdGhpbmcgdG8gaHlkcmF0ZS4gTWFrZSBpdCBhbiBpbnNlcnRpb24uXG5cblxuICAgIGluc2VydE5vbkh5ZHJhdGVkSW5zdGFuY2UoaHlkcmF0aW9uUGFyZW50RmliZXIsIGZpYmVyKTtcbiAgICBpc0h5ZHJhdGluZyA9IGZhbHNlO1xuICAgIGh5ZHJhdGlvblBhcmVudEZpYmVyID0gZmliZXI7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGZpcnN0QXR0ZW1wdGVkSW5zdGFuY2UgPSBuZXh0SW5zdGFuY2U7XG5cbiAgaWYgKCF0cnlIeWRyYXRlKGZpYmVyLCBuZXh0SW5zdGFuY2UpKSB7XG4gICAgaWYgKHNob3VsZENsaWVudFJlbmRlck9uTWlzbWF0Y2goZmliZXIpKSB7XG4gICAgICB3YXJuTm9uaHlkcmF0ZWRJbnN0YW5jZShoeWRyYXRpb25QYXJlbnRGaWJlciwgZmliZXIpO1xuICAgICAgdGhyb3dPbkh5ZHJhdGlvbk1pc21hdGNoKCk7XG4gICAgfSAvLyBJZiB3ZSBjYW4ndCBoeWRyYXRlIHRoaXMgaW5zdGFuY2UgbGV0J3MgdHJ5IHRoZSBuZXh0IG9uZS5cbiAgICAvLyBXZSB1c2UgdGhpcyBhcyBhIGhldXJpc3RpYy4gSXQncyBiYXNlZCBvbiBpbnR1aXRpb24gYW5kIG5vdCBkYXRhIHNvIGl0XG4gICAgLy8gbWlnaHQgYmUgZmxhd2VkIG9yIHVubmVjZXNzYXJ5LlxuXG5cbiAgICBuZXh0SW5zdGFuY2UgPSBnZXROZXh0SHlkcmF0YWJsZVNpYmxpbmcoZmlyc3RBdHRlbXB0ZWRJbnN0YW5jZSk7XG4gICAgdmFyIHByZXZIeWRyYXRpb25QYXJlbnRGaWJlciA9IGh5ZHJhdGlvblBhcmVudEZpYmVyO1xuXG4gICAgaWYgKCFuZXh0SW5zdGFuY2UgfHwgIXRyeUh5ZHJhdGUoZmliZXIsIG5leHRJbnN0YW5jZSkpIHtcbiAgICAgIC8vIE5vdGhpbmcgdG8gaHlkcmF0ZS4gTWFrZSBpdCBhbiBpbnNlcnRpb24uXG4gICAgICBpbnNlcnROb25IeWRyYXRlZEluc3RhbmNlKGh5ZHJhdGlvblBhcmVudEZpYmVyLCBmaWJlcik7XG4gICAgICBpc0h5ZHJhdGluZyA9IGZhbHNlO1xuICAgICAgaHlkcmF0aW9uUGFyZW50RmliZXIgPSBmaWJlcjtcbiAgICAgIHJldHVybjtcbiAgICB9IC8vIFdlIG1hdGNoZWQgdGhlIG5leHQgb25lLCB3ZSdsbCBub3cgYXNzdW1lIHRoYXQgdGhlIGZpcnN0IG9uZSB3YXNcbiAgICAvLyBzdXBlcmZsdW91cyBhbmQgd2UnbGwgZGVsZXRlIGl0LiBTaW5jZSB3ZSBjYW4ndCBlYWdlcmx5IGRlbGV0ZSBpdFxuICAgIC8vIHdlJ2xsIGhhdmUgdG8gc2NoZWR1bGUgYSBkZWxldGlvbi4gVG8gZG8gdGhhdCwgdGhpcyBub2RlIG5lZWRzIGEgZHVtbXlcbiAgICAvLyBmaWJlciBhc3NvY2lhdGVkIHdpdGggaXQuXG5cblxuICAgIGRlbGV0ZUh5ZHJhdGFibGVJbnN0YW5jZShwcmV2SHlkcmF0aW9uUGFyZW50RmliZXIsIGZpcnN0QXR0ZW1wdGVkSW5zdGFuY2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHByZXBhcmVUb0h5ZHJhdGVIb3N0SW5zdGFuY2UoZmliZXIsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaG9zdENvbnRleHQpIHtcblxuICB2YXIgaW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGU7XG4gIHZhciBzaG91bGRXYXJuSWZNaXNtYXRjaERldiA9ICFkaWRTdXNwZW5kT3JFcnJvckRFVjtcbiAgdmFyIHVwZGF0ZVBheWxvYWQgPSBoeWRyYXRlSW5zdGFuY2UoaW5zdGFuY2UsIGZpYmVyLnR5cGUsIGZpYmVyLm1lbW9pemVkUHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaG9zdENvbnRleHQsIGZpYmVyLCBzaG91bGRXYXJuSWZNaXNtYXRjaERldik7IC8vIFRPRE86IFR5cGUgdGhpcyBzcGVjaWZpYyB0byB0aGlzIHR5cGUgb2YgY29tcG9uZW50LlxuXG4gIGZpYmVyLnVwZGF0ZVF1ZXVlID0gdXBkYXRlUGF5bG9hZDsgLy8gSWYgdGhlIHVwZGF0ZSBwYXlsb2FkIGluZGljYXRlcyB0aGF0IHRoZXJlIGlzIGEgY2hhbmdlIG9yIGlmIHRoZXJlXG4gIC8vIGlzIGEgbmV3IHJlZiB3ZSBtYXJrIHRoaXMgYXMgYW4gdXBkYXRlLlxuXG4gIGlmICh1cGRhdGVQYXlsb2FkICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHByZXBhcmVUb0h5ZHJhdGVIb3N0VGV4dEluc3RhbmNlKGZpYmVyKSB7XG5cbiAgdmFyIHRleHRJbnN0YW5jZSA9IGZpYmVyLnN0YXRlTm9kZTtcbiAgdmFyIHRleHRDb250ZW50ID0gZmliZXIubWVtb2l6ZWRQcm9wcztcbiAgdmFyIHNob3VsZFVwZGF0ZSA9IGh5ZHJhdGVUZXh0SW5zdGFuY2UodGV4dEluc3RhbmNlLCB0ZXh0Q29udGVudCwgZmliZXIpO1xuXG4gIGlmIChzaG91bGRVcGRhdGUpIHtcbiAgICAvLyBXZSBhc3N1bWUgdGhhdCBwcmVwYXJlVG9IeWRyYXRlSG9zdFRleHRJbnN0YW5jZSBpcyBjYWxsZWQgaW4gYSBjb250ZXh0IHdoZXJlIHRoZVxuICAgIC8vIGh5ZHJhdGlvbiBwYXJlbnQgaXMgdGhlIHBhcmVudCBob3N0IGNvbXBvbmVudCBvZiB0aGlzIGhvc3QgdGV4dC5cbiAgICB2YXIgcmV0dXJuRmliZXIgPSBoeWRyYXRpb25QYXJlbnRGaWJlcjtcblxuICAgIGlmIChyZXR1cm5GaWJlciAhPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChyZXR1cm5GaWJlci50YWcpIHtcbiAgICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgcGFyZW50Q29udGFpbmVyID0gcmV0dXJuRmliZXIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm87XG4gICAgICAgICAgICB2YXIgaXNDb25jdXJyZW50TW9kZSA9IChyZXR1cm5GaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG4gICAgICAgICAgICBkaWROb3RNYXRjaEh5ZHJhdGVkQ29udGFpbmVyVGV4dEluc3RhbmNlKHBhcmVudENvbnRhaW5lciwgdGV4dEluc3RhbmNlLCB0ZXh0Q29udGVudCwgLy8gVE9ETzogRGVsZXRlIHRoaXMgYXJndW1lbnQgd2hlbiB3ZSByZW1vdmUgdGhlIGxlZ2FjeSByb290IEFQSS5cbiAgICAgICAgICAgIGlzQ29uY3VycmVudE1vZGUpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgcGFyZW50VHlwZSA9IHJldHVybkZpYmVyLnR5cGU7XG4gICAgICAgICAgICB2YXIgcGFyZW50UHJvcHMgPSByZXR1cm5GaWJlci5tZW1vaXplZFByb3BzO1xuICAgICAgICAgICAgdmFyIHBhcmVudEluc3RhbmNlID0gcmV0dXJuRmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgICB2YXIgX2lzQ29uY3VycmVudE1vZGUyID0gKHJldHVybkZpYmVyLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZTtcblxuICAgICAgICAgICAgZGlkTm90TWF0Y2hIeWRyYXRlZFRleHRJbnN0YW5jZShwYXJlbnRUeXBlLCBwYXJlbnRQcm9wcywgcGFyZW50SW5zdGFuY2UsIHRleHRJbnN0YW5jZSwgdGV4dENvbnRlbnQsIC8vIFRPRE86IERlbGV0ZSB0aGlzIGFyZ3VtZW50IHdoZW4gd2UgcmVtb3ZlIHRoZSBsZWdhY3kgcm9vdCBBUEkuXG4gICAgICAgICAgICBfaXNDb25jdXJyZW50TW9kZTIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzaG91bGRVcGRhdGU7XG59XG5cbmZ1bmN0aW9uIHByZXBhcmVUb0h5ZHJhdGVIb3N0U3VzcGVuc2VJbnN0YW5jZShmaWJlcikge1xuXG4gIHZhciBzdXNwZW5zZVN0YXRlID0gZmliZXIubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIHN1c3BlbnNlSW5zdGFuY2UgPSBzdXNwZW5zZVN0YXRlICE9PSBudWxsID8gc3VzcGVuc2VTdGF0ZS5kZWh5ZHJhdGVkIDogbnVsbDtcblxuICBpZiAoIXN1c3BlbnNlSW5zdGFuY2UpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHRvIGhhdmUgYSBoeWRyYXRlZCBzdXNwZW5zZSBpbnN0YW5jZS4gJyArICdUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICB9XG5cbiAgaHlkcmF0ZVN1c3BlbnNlSW5zdGFuY2Uoc3VzcGVuc2VJbnN0YW5jZSwgZmliZXIpO1xufVxuXG5mdW5jdGlvbiBza2lwUGFzdERlaHlkcmF0ZWRTdXNwZW5zZUluc3RhbmNlKGZpYmVyKSB7XG5cbiAgdmFyIHN1c3BlbnNlU3RhdGUgPSBmaWJlci5tZW1vaXplZFN0YXRlO1xuICB2YXIgc3VzcGVuc2VJbnN0YW5jZSA9IHN1c3BlbnNlU3RhdGUgIT09IG51bGwgPyBzdXNwZW5zZVN0YXRlLmRlaHlkcmF0ZWQgOiBudWxsO1xuXG4gIGlmICghc3VzcGVuc2VJbnN0YW5jZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgdG8gaGF2ZSBhIGh5ZHJhdGVkIHN1c3BlbnNlIGluc3RhbmNlLiAnICsgJ1RoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gIH1cblxuICByZXR1cm4gZ2V0TmV4dEh5ZHJhdGFibGVJbnN0YW5jZUFmdGVyU3VzcGVuc2VJbnN0YW5jZShzdXNwZW5zZUluc3RhbmNlKTtcbn1cblxuZnVuY3Rpb24gcG9wVG9OZXh0SG9zdFBhcmVudChmaWJlcikge1xuICB2YXIgcGFyZW50ID0gZmliZXIucmV0dXJuO1xuXG4gIHdoaWxlIChwYXJlbnQgIT09IG51bGwgJiYgcGFyZW50LnRhZyAhPT0gSG9zdENvbXBvbmVudCAmJiBwYXJlbnQudGFnICE9PSBIb3N0Um9vdCAmJiBwYXJlbnQudGFnICE9PSBTdXNwZW5zZUNvbXBvbmVudCkge1xuICAgIHBhcmVudCA9IHBhcmVudC5yZXR1cm47XG4gIH1cblxuICBoeWRyYXRpb25QYXJlbnRGaWJlciA9IHBhcmVudDtcbn1cblxuZnVuY3Rpb24gcG9wSHlkcmF0aW9uU3RhdGUoZmliZXIpIHtcblxuICBpZiAoZmliZXIgIT09IGh5ZHJhdGlvblBhcmVudEZpYmVyKSB7XG4gICAgLy8gV2UncmUgZGVlcGVyIHRoYW4gdGhlIGN1cnJlbnQgaHlkcmF0aW9uIGNvbnRleHQsIGluc2lkZSBhbiBpbnNlcnRlZFxuICAgIC8vIHRyZWUuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKCFpc0h5ZHJhdGluZykge1xuICAgIC8vIElmIHdlJ3JlIG5vdCBjdXJyZW50bHkgaHlkcmF0aW5nIGJ1dCB3ZSdyZSBpbiBhIGh5ZHJhdGlvbiBjb250ZXh0LCB0aGVuXG4gICAgLy8gd2Ugd2VyZSBhbiBpbnNlcnRpb24gYW5kIG5vdyBuZWVkIHRvIHBvcCB1cCByZWVudGVyIGh5ZHJhdGlvbiBvZiBvdXJcbiAgICAvLyBzaWJsaW5ncy5cbiAgICBwb3BUb05leHRIb3N0UGFyZW50KGZpYmVyKTtcbiAgICBpc0h5ZHJhdGluZyA9IHRydWU7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IC8vIElmIHdlIGhhdmUgYW55IHJlbWFpbmluZyBoeWRyYXRhYmxlIG5vZGVzLCB3ZSBuZWVkIHRvIGRlbGV0ZSB0aGVtIG5vdy5cbiAgLy8gV2Ugb25seSBkbyB0aGlzIGRlZXBlciB0aGFuIGhlYWQgYW5kIGJvZHkgc2luY2UgdGhleSB0ZW5kIHRvIGhhdmUgcmFuZG9tXG4gIC8vIG90aGVyIG5vZGVzIGluIHRoZW0uIFdlIGFsc28gaWdub3JlIGNvbXBvbmVudHMgd2l0aCBwdXJlIHRleHQgY29udGVudCBpblxuICAvLyBzaWRlIG9mIHRoZW0uIFdlIGFsc28gZG9uJ3QgZGVsZXRlIGFueXRoaW5nIGluc2lkZSB0aGUgcm9vdCBjb250YWluZXIuXG5cblxuICBpZiAoZmliZXIudGFnICE9PSBIb3N0Um9vdCAmJiAoZmliZXIudGFnICE9PSBIb3N0Q29tcG9uZW50IHx8IHNob3VsZERlbGV0ZVVuaHlkcmF0ZWRUYWlsSW5zdGFuY2VzKGZpYmVyLnR5cGUpICYmICFzaG91bGRTZXRUZXh0Q29udGVudChmaWJlci50eXBlLCBmaWJlci5tZW1vaXplZFByb3BzKSkpIHtcbiAgICB2YXIgbmV4dEluc3RhbmNlID0gbmV4dEh5ZHJhdGFibGVJbnN0YW5jZTtcblxuICAgIGlmIChuZXh0SW5zdGFuY2UpIHtcbiAgICAgIGlmIChzaG91bGRDbGllbnRSZW5kZXJPbk1pc21hdGNoKGZpYmVyKSkge1xuICAgICAgICB3YXJuSWZVbmh5ZHJhdGVkVGFpbE5vZGVzKGZpYmVyKTtcbiAgICAgICAgdGhyb3dPbkh5ZHJhdGlvbk1pc21hdGNoKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aGlsZSAobmV4dEluc3RhbmNlKSB7XG4gICAgICAgICAgZGVsZXRlSHlkcmF0YWJsZUluc3RhbmNlKGZpYmVyLCBuZXh0SW5zdGFuY2UpO1xuICAgICAgICAgIG5leHRJbnN0YW5jZSA9IGdldE5leHRIeWRyYXRhYmxlU2libGluZyhuZXh0SW5zdGFuY2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcG9wVG9OZXh0SG9zdFBhcmVudChmaWJlcik7XG5cbiAgaWYgKGZpYmVyLnRhZyA9PT0gU3VzcGVuc2VDb21wb25lbnQpIHtcbiAgICBuZXh0SHlkcmF0YWJsZUluc3RhbmNlID0gc2tpcFBhc3REZWh5ZHJhdGVkU3VzcGVuc2VJbnN0YW5jZShmaWJlcik7XG4gIH0gZWxzZSB7XG4gICAgbmV4dEh5ZHJhdGFibGVJbnN0YW5jZSA9IGh5ZHJhdGlvblBhcmVudEZpYmVyID8gZ2V0TmV4dEh5ZHJhdGFibGVTaWJsaW5nKGZpYmVyLnN0YXRlTm9kZSkgOiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGhhc1VuaHlkcmF0ZWRUYWlsTm9kZXMoKSB7XG4gIHJldHVybiBpc0h5ZHJhdGluZyAmJiBuZXh0SHlkcmF0YWJsZUluc3RhbmNlICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiB3YXJuSWZVbmh5ZHJhdGVkVGFpbE5vZGVzKGZpYmVyKSB7XG4gIHZhciBuZXh0SW5zdGFuY2UgPSBuZXh0SHlkcmF0YWJsZUluc3RhbmNlO1xuXG4gIHdoaWxlIChuZXh0SW5zdGFuY2UpIHtcbiAgICB3YXJuVW5oeWRyYXRlZEluc3RhbmNlKGZpYmVyLCBuZXh0SW5zdGFuY2UpO1xuICAgIG5leHRJbnN0YW5jZSA9IGdldE5leHRIeWRyYXRhYmxlU2libGluZyhuZXh0SW5zdGFuY2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc2V0SHlkcmF0aW9uU3RhdGUoKSB7XG5cbiAgaHlkcmF0aW9uUGFyZW50RmliZXIgPSBudWxsO1xuICBuZXh0SHlkcmF0YWJsZUluc3RhbmNlID0gbnVsbDtcbiAgaXNIeWRyYXRpbmcgPSBmYWxzZTtcbiAgZGlkU3VzcGVuZE9yRXJyb3JERVYgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gdXBncmFkZUh5ZHJhdGlvbkVycm9yc1RvUmVjb3ZlcmFibGUoKSB7XG4gIGlmIChoeWRyYXRpb25FcnJvcnMgIT09IG51bGwpIHtcbiAgICAvLyBTdWNjZXNzZnVsbHkgY29tcGxldGVkIGEgZm9yY2VkIGNsaWVudCByZW5kZXIuIFRoZSBlcnJvcnMgdGhhdCBvY2N1cnJlZFxuICAgIC8vIGR1cmluZyB0aGUgaHlkcmF0aW9uIGF0dGVtcHQgYXJlIG5vdyByZWNvdmVyZWQuIFdlIHdpbGwgbG9nIHRoZW0gaW5cbiAgICAvLyBjb21taXQgcGhhc2UsIG9uY2UgdGhlIGVudGlyZSB0cmVlIGhhcyBmaW5pc2hlZC5cbiAgICBxdWV1ZVJlY292ZXJhYmxlRXJyb3JzKGh5ZHJhdGlvbkVycm9ycyk7XG4gICAgaHlkcmF0aW9uRXJyb3JzID0gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRJc0h5ZHJhdGluZygpIHtcbiAgcmV0dXJuIGlzSHlkcmF0aW5nO1xufVxuXG5mdW5jdGlvbiBxdWV1ZUh5ZHJhdGlvbkVycm9yKGVycm9yKSB7XG4gIGlmIChoeWRyYXRpb25FcnJvcnMgPT09IG51bGwpIHtcbiAgICBoeWRyYXRpb25FcnJvcnMgPSBbZXJyb3JdO1xuICB9IGVsc2Uge1xuICAgIGh5ZHJhdGlvbkVycm9ycy5wdXNoKGVycm9yKTtcbiAgfVxufVxuXG52YXIgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudEJhdGNoQ29uZmlnO1xudmFyIE5vVHJhbnNpdGlvbiA9IG51bGw7XG5mdW5jdGlvbiByZXF1ZXN0Q3VycmVudFRyYW5zaXRpb24oKSB7XG4gIHJldHVybiBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQxLnRyYW5zaXRpb247XG59XG5cbnZhciBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncyA9IHtcbiAgcmVjb3JkVW5zYWZlTGlmZWN5Y2xlV2FybmluZ3M6IGZ1bmN0aW9uIChmaWJlciwgaW5zdGFuY2UpIHt9LFxuICBmbHVzaFBlbmRpbmdVbnNhZmVMaWZlY3ljbGVXYXJuaW5nczogZnVuY3Rpb24gKCkge30sXG4gIHJlY29yZExlZ2FjeUNvbnRleHRXYXJuaW5nOiBmdW5jdGlvbiAoZmliZXIsIGluc3RhbmNlKSB7fSxcbiAgZmx1c2hMZWdhY3lDb250ZXh0V2FybmluZzogZnVuY3Rpb24gKCkge30sXG4gIGRpc2NhcmRQZW5kaW5nV2FybmluZ3M6IGZ1bmN0aW9uICgpIHt9XG59O1xuXG57XG4gIHZhciBmaW5kU3RyaWN0Um9vdCA9IGZ1bmN0aW9uIChmaWJlcikge1xuICAgIHZhciBtYXliZVN0cmljdFJvb3QgPSBudWxsO1xuICAgIHZhciBub2RlID0gZmliZXI7XG5cbiAgICB3aGlsZSAobm9kZSAhPT0gbnVsbCkge1xuICAgICAgaWYgKG5vZGUubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgICAgbWF5YmVTdHJpY3RSb290ID0gbm9kZTtcbiAgICAgIH1cblxuICAgICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICAgIH1cblxuICAgIHJldHVybiBtYXliZVN0cmljdFJvb3Q7XG4gIH07XG5cbiAgdmFyIHNldFRvU29ydGVkU3RyaW5nID0gZnVuY3Rpb24gKHNldCkge1xuICAgIHZhciBhcnJheSA9IFtdO1xuICAgIHNldC5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgYXJyYXkucHVzaCh2YWx1ZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFycmF5LnNvcnQoKS5qb2luKCcsICcpO1xuICB9O1xuXG4gIHZhciBwZW5kaW5nQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgdmFyIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgdmFyIHBlbmRpbmdDb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzV2FybmluZ3MgPSBbXTtcbiAgdmFyIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1dhcm5pbmdzID0gW107XG4gIHZhciBwZW5kaW5nQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzID0gW107XG4gIHZhciBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxVcGRhdGVXYXJuaW5ncyA9IFtdOyAvLyBUcmFja3MgY29tcG9uZW50cyB3ZSBoYXZlIGFscmVhZHkgd2FybmVkIGFib3V0LlxuXG4gIHZhciBkaWRXYXJuQWJvdXRVbnNhZmVMaWZlY3ljbGVzID0gbmV3IFNldCgpO1xuXG4gIFJlYWN0U3RyaWN0TW9kZVdhcm5pbmdzLnJlY29yZFVuc2FmZUxpZmVjeWNsZVdhcm5pbmdzID0gZnVuY3Rpb24gKGZpYmVyLCBpbnN0YW5jZSkge1xuICAgIC8vIERlZHVwZSBzdHJhdGVneTogV2FybiBvbmNlIHBlciBjb21wb25lbnQuXG4gICAgaWYgKGRpZFdhcm5BYm91dFVuc2FmZUxpZmVjeWNsZXMuaGFzKGZpYmVyLnR5cGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicgJiYgLy8gRG9uJ3Qgd2FybiBhYm91dCByZWFjdC1saWZlY3ljbGVzLWNvbXBhdCBwb2x5ZmlsbGVkIGNvbXBvbmVudHMuXG4gICAgaW5zdGFuY2UuY29tcG9uZW50V2lsbE1vdW50Ll9fc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmcgIT09IHRydWUpIHtcbiAgICAgIHBlbmRpbmdDb21wb25lbnRXaWxsTW91bnRXYXJuaW5ncy5wdXNoKGZpYmVyKTtcbiAgICB9XG5cbiAgICBpZiAoZmliZXIubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUgJiYgdHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MucHVzaChmaWJlcik7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzID09PSAnZnVuY3Rpb24nICYmIGluc3RhbmNlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMuX19zdXBwcmVzc0RlcHJlY2F0aW9uV2FybmluZyAhPT0gdHJ1ZSkge1xuICAgICAgcGVuZGluZ0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5wdXNoKGZpYmVyKTtcbiAgICB9XG5cbiAgICBpZiAoZmliZXIubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUgJiYgdHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5wdXNoKGZpYmVyKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVcGRhdGUgPT09ICdmdW5jdGlvbicgJiYgaW5zdGFuY2UuY29tcG9uZW50V2lsbFVwZGF0ZS5fX3N1cHByZXNzRGVwcmVjYXRpb25XYXJuaW5nICE9PSB0cnVlKSB7XG4gICAgICBwZW5kaW5nQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLnB1c2goZmliZXIpO1xuICAgIH1cblxuICAgIGlmIChmaWJlci5tb2RlICYgU3RyaWN0TGVnYWN5TW9kZSAmJiB0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLnB1c2goZmliZXIpO1xuICAgIH1cbiAgfTtcblxuICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5mbHVzaFBlbmRpbmdVbnNhZmVMaWZlY3ljbGVXYXJuaW5ncyA9IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBXZSBkbyBhbiBpbml0aWFsIHBhc3MgdG8gZ2F0aGVyIGNvbXBvbmVudCBuYW1lc1xuICAgIHZhciBjb21wb25lbnRXaWxsTW91bnRVbmlxdWVOYW1lcyA9IG5ldyBTZXQoKTtcblxuICAgIGlmIChwZW5kaW5nQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MubGVuZ3RoID4gMCkge1xuICAgICAgcGVuZGluZ0NvbXBvbmVudFdpbGxNb3VudFdhcm5pbmdzLmZvckVhY2goZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgICAgIGNvbXBvbmVudFdpbGxNb3VudFVuaXF1ZU5hbWVzLmFkZChnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpYmVyKSB8fCAnQ29tcG9uZW50Jyk7XG4gICAgICAgIGRpZFdhcm5BYm91dFVuc2FmZUxpZmVjeWNsZXMuYWRkKGZpYmVyLnR5cGUpO1xuICAgICAgfSk7XG4gICAgICBwZW5kaW5nQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgICB9XG5cbiAgICB2YXIgVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudFVuaXF1ZU5hbWVzID0gbmV3IFNldCgpO1xuXG4gICAgaWYgKHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MubGVuZ3RoID4gMCkge1xuICAgICAgcGVuZGluZ1VOU0FGRV9Db21wb25lbnRXaWxsTW91bnRXYXJuaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChmaWJlcikge1xuICAgICAgICBVTlNBRkVfY29tcG9uZW50V2lsbE1vdW50VW5pcXVlTmFtZXMuYWRkKGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdDb21wb25lbnQnKTtcbiAgICAgICAgZGlkV2FybkFib3V0VW5zYWZlTGlmZWN5Y2xlcy5hZGQoZmliZXIudHlwZSk7XG4gICAgICB9KTtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgICB9XG5cbiAgICB2YXIgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1VuaXF1ZU5hbWVzID0gbmV3IFNldCgpO1xuXG4gICAgaWYgKHBlbmRpbmdDb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzV2FybmluZ3MubGVuZ3RoID4gMCkge1xuICAgICAgcGVuZGluZ0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChmaWJlcikge1xuICAgICAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzVW5pcXVlTmFtZXMuYWRkKGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdDb21wb25lbnQnKTtcbiAgICAgICAgZGlkV2FybkFib3V0VW5zYWZlTGlmZWN5Y2xlcy5hZGQoZmliZXIudHlwZSk7XG4gICAgICB9KTtcbiAgICAgIHBlbmRpbmdDb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzV2FybmluZ3MgPSBbXTtcbiAgICB9XG5cbiAgICB2YXIgVU5TQUZFX2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNVbmlxdWVOYW1lcyA9IG5ldyBTZXQoKTtcblxuICAgIGlmIChwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5sZW5ndGggPiAwKSB7XG4gICAgICBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChmaWJlcikge1xuICAgICAgICBVTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1VuaXF1ZU5hbWVzLmFkZChnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpYmVyKSB8fCAnQ29tcG9uZW50Jyk7XG4gICAgICAgIGRpZFdhcm5BYm91dFVuc2FmZUxpZmVjeWNsZXMuYWRkKGZpYmVyLnR5cGUpO1xuICAgICAgfSk7XG4gICAgICBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncyA9IFtdO1xuICAgIH1cblxuICAgIHZhciBjb21wb25lbnRXaWxsVXBkYXRlVW5pcXVlTmFtZXMgPSBuZXcgU2V0KCk7XG5cbiAgICBpZiAocGVuZGluZ0NvbXBvbmVudFdpbGxVcGRhdGVXYXJuaW5ncy5sZW5ndGggPiAwKSB7XG4gICAgICBwZW5kaW5nQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLmZvckVhY2goZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgICAgIGNvbXBvbmVudFdpbGxVcGRhdGVVbmlxdWVOYW1lcy5hZGQoZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ0NvbXBvbmVudCcpO1xuICAgICAgICBkaWRXYXJuQWJvdXRVbnNhZmVMaWZlY3ljbGVzLmFkZChmaWJlci50eXBlKTtcbiAgICAgIH0pO1xuICAgICAgcGVuZGluZ0NvbXBvbmVudFdpbGxVcGRhdGVXYXJuaW5ncyA9IFtdO1xuICAgIH1cblxuICAgIHZhciBVTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZVVuaXF1ZU5hbWVzID0gbmV3IFNldCgpO1xuXG4gICAgaWYgKHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLmxlbmd0aCA+IDApIHtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLmZvckVhY2goZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgICAgIFVOU0FGRV9jb21wb25lbnRXaWxsVXBkYXRlVW5pcXVlTmFtZXMuYWRkKGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdDb21wb25lbnQnKTtcbiAgICAgICAgZGlkV2FybkFib3V0VW5zYWZlTGlmZWN5Y2xlcy5hZGQoZmliZXIudHlwZSk7XG4gICAgICB9KTtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzID0gW107XG4gICAgfSAvLyBGaW5hbGx5LCB3ZSBmbHVzaCBhbGwgdGhlIHdhcm5pbmdzXG4gICAgLy8gVU5TQUZFXyBvbmVzIGJlZm9yZSB0aGUgZGVwcmVjYXRlZCBvbmVzLCBzaW5jZSB0aGV5J2xsIGJlICdsb3VkZXInXG5cblxuICAgIGlmIChVTlNBRkVfY29tcG9uZW50V2lsbE1vdW50VW5pcXVlTmFtZXMuc2l6ZSA+IDApIHtcbiAgICAgIHZhciBzb3J0ZWROYW1lcyA9IHNldFRvU29ydGVkU3RyaW5nKFVOU0FGRV9jb21wb25lbnRXaWxsTW91bnRVbmlxdWVOYW1lcyk7XG5cbiAgICAgIGVycm9yKCdVc2luZyBVTlNBRkVfY29tcG9uZW50V2lsbE1vdW50IGluIHN0cmljdCBtb2RlIGlzIG5vdCByZWNvbW1lbmRlZCBhbmQgbWF5IGluZGljYXRlIGJ1Z3MgaW4geW91ciBjb2RlLiAnICsgJ1NlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvdW5zYWZlLWNvbXBvbmVudC1saWZlY3ljbGVzIGZvciBkZXRhaWxzLlxcblxcbicgKyAnKiBNb3ZlIGNvZGUgd2l0aCBzaWRlIGVmZmVjdHMgdG8gY29tcG9uZW50RGlkTW91bnQsIGFuZCBzZXQgaW5pdGlhbCBzdGF0ZSBpbiB0aGUgY29uc3RydWN0b3IuXFxuJyArICdcXG5QbGVhc2UgdXBkYXRlIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czogJXMnLCBzb3J0ZWROYW1lcyk7XG4gICAgfVxuXG4gICAgaWYgKFVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzVW5pcXVlTmFtZXMuc2l6ZSA+IDApIHtcbiAgICAgIHZhciBfc29ydGVkTmFtZXMgPSBzZXRUb1NvcnRlZFN0cmluZyhVTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1VuaXF1ZU5hbWVzKTtcblxuICAgICAgZXJyb3IoJ1VzaW5nIFVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzIGluIHN0cmljdCBtb2RlIGlzIG5vdCByZWNvbW1lbmRlZCAnICsgJ2FuZCBtYXkgaW5kaWNhdGUgYnVncyBpbiB5b3VyIGNvZGUuICcgKyAnU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay91bnNhZmUtY29tcG9uZW50LWxpZmVjeWNsZXMgZm9yIGRldGFpbHMuXFxuXFxuJyArICcqIE1vdmUgZGF0YSBmZXRjaGluZyBjb2RlIG9yIHNpZGUgZWZmZWN0cyB0byBjb21wb25lbnREaWRVcGRhdGUuXFxuJyArIFwiKiBJZiB5b3UncmUgdXBkYXRpbmcgc3RhdGUgd2hlbmV2ZXIgcHJvcHMgY2hhbmdlLCBcIiArICdyZWZhY3RvciB5b3VyIGNvZGUgdG8gdXNlIG1lbW9pemF0aW9uIHRlY2huaXF1ZXMgb3IgbW92ZSBpdCB0byAnICsgJ3N0YXRpYyBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMuIExlYXJuIG1vcmUgYXQ6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9kZXJpdmVkLXN0YXRlXFxuJyArICdcXG5QbGVhc2UgdXBkYXRlIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czogJXMnLCBfc29ydGVkTmFtZXMpO1xuICAgIH1cblxuICAgIGlmIChVTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZVVuaXF1ZU5hbWVzLnNpemUgPiAwKSB7XG4gICAgICB2YXIgX3NvcnRlZE5hbWVzMiA9IHNldFRvU29ydGVkU3RyaW5nKFVOU0FGRV9jb21wb25lbnRXaWxsVXBkYXRlVW5pcXVlTmFtZXMpO1xuXG4gICAgICBlcnJvcignVXNpbmcgVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUgaW4gc3RyaWN0IG1vZGUgaXMgbm90IHJlY29tbWVuZGVkICcgKyAnYW5kIG1heSBpbmRpY2F0ZSBidWdzIGluIHlvdXIgY29kZS4gJyArICdTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3Vuc2FmZS1jb21wb25lbnQtbGlmZWN5Y2xlcyBmb3IgZGV0YWlscy5cXG5cXG4nICsgJyogTW92ZSBkYXRhIGZldGNoaW5nIGNvZGUgb3Igc2lkZSBlZmZlY3RzIHRvIGNvbXBvbmVudERpZFVwZGF0ZS5cXG4nICsgJ1xcblBsZWFzZSB1cGRhdGUgdGhlIGZvbGxvd2luZyBjb21wb25lbnRzOiAlcycsIF9zb3J0ZWROYW1lczIpO1xuICAgIH1cblxuICAgIGlmIChjb21wb25lbnRXaWxsTW91bnRVbmlxdWVOYW1lcy5zaXplID4gMCkge1xuICAgICAgdmFyIF9zb3J0ZWROYW1lczMgPSBzZXRUb1NvcnRlZFN0cmluZyhjb21wb25lbnRXaWxsTW91bnRVbmlxdWVOYW1lcyk7XG5cbiAgICAgIHdhcm4oJ2NvbXBvbmVudFdpbGxNb3VudCBoYXMgYmVlbiByZW5hbWVkLCBhbmQgaXMgbm90IHJlY29tbWVuZGVkIGZvciB1c2UuICcgKyAnU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay91bnNhZmUtY29tcG9uZW50LWxpZmVjeWNsZXMgZm9yIGRldGFpbHMuXFxuXFxuJyArICcqIE1vdmUgY29kZSB3aXRoIHNpZGUgZWZmZWN0cyB0byBjb21wb25lbnREaWRNb3VudCwgYW5kIHNldCBpbml0aWFsIHN0YXRlIGluIHRoZSBjb25zdHJ1Y3Rvci5cXG4nICsgJyogUmVuYW1lIGNvbXBvbmVudFdpbGxNb3VudCB0byBVTlNBRkVfY29tcG9uZW50V2lsbE1vdW50IHRvIHN1cHByZXNzICcgKyAndGhpcyB3YXJuaW5nIGluIG5vbi1zdHJpY3QgbW9kZS4gSW4gUmVhY3QgMTgueCwgb25seSB0aGUgVU5TQUZFXyBuYW1lIHdpbGwgd29yay4gJyArICdUbyByZW5hbWUgYWxsIGRlcHJlY2F0ZWQgbGlmZWN5Y2xlcyB0byB0aGVpciBuZXcgbmFtZXMsIHlvdSBjYW4gcnVuICcgKyAnYG5weCByZWFjdC1jb2RlbW9kIHJlbmFtZS11bnNhZmUtbGlmZWN5Y2xlc2AgaW4geW91ciBwcm9qZWN0IHNvdXJjZSBmb2xkZXIuXFxuJyArICdcXG5QbGVhc2UgdXBkYXRlIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czogJXMnLCBfc29ydGVkTmFtZXMzKTtcbiAgICB9XG5cbiAgICBpZiAoY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1VuaXF1ZU5hbWVzLnNpemUgPiAwKSB7XG4gICAgICB2YXIgX3NvcnRlZE5hbWVzNCA9IHNldFRvU29ydGVkU3RyaW5nKGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNVbmlxdWVOYW1lcyk7XG5cbiAgICAgIHdhcm4oJ2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgaGFzIGJlZW4gcmVuYW1lZCwgYW5kIGlzIG5vdCByZWNvbW1lbmRlZCBmb3IgdXNlLiAnICsgJ1NlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvdW5zYWZlLWNvbXBvbmVudC1saWZlY3ljbGVzIGZvciBkZXRhaWxzLlxcblxcbicgKyAnKiBNb3ZlIGRhdGEgZmV0Y2hpbmcgY29kZSBvciBzaWRlIGVmZmVjdHMgdG8gY29tcG9uZW50RGlkVXBkYXRlLlxcbicgKyBcIiogSWYgeW91J3JlIHVwZGF0aW5nIHN0YXRlIHdoZW5ldmVyIHByb3BzIGNoYW5nZSwgcmVmYWN0b3IgeW91ciBcIiArICdjb2RlIHRvIHVzZSBtZW1vaXphdGlvbiB0ZWNobmlxdWVzIG9yIG1vdmUgaXQgdG8gJyArICdzdGF0aWMgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzLiBMZWFybiBtb3JlIGF0OiBodHRwczovL3JlYWN0anMub3JnL2xpbmsvZGVyaXZlZC1zdGF0ZVxcbicgKyAnKiBSZW5hbWUgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyB0byBVTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyB0byBzdXBwcmVzcyAnICsgJ3RoaXMgd2FybmluZyBpbiBub24tc3RyaWN0IG1vZGUuIEluIFJlYWN0IDE4LngsIG9ubHkgdGhlIFVOU0FGRV8gbmFtZSB3aWxsIHdvcmsuICcgKyAnVG8gcmVuYW1lIGFsbCBkZXByZWNhdGVkIGxpZmVjeWNsZXMgdG8gdGhlaXIgbmV3IG5hbWVzLCB5b3UgY2FuIHJ1biAnICsgJ2BucHggcmVhY3QtY29kZW1vZCByZW5hbWUtdW5zYWZlLWxpZmVjeWNsZXNgIGluIHlvdXIgcHJvamVjdCBzb3VyY2UgZm9sZGVyLlxcbicgKyAnXFxuUGxlYXNlIHVwZGF0ZSB0aGUgZm9sbG93aW5nIGNvbXBvbmVudHM6ICVzJywgX3NvcnRlZE5hbWVzNCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbXBvbmVudFdpbGxVcGRhdGVVbmlxdWVOYW1lcy5zaXplID4gMCkge1xuICAgICAgdmFyIF9zb3J0ZWROYW1lczUgPSBzZXRUb1NvcnRlZFN0cmluZyhjb21wb25lbnRXaWxsVXBkYXRlVW5pcXVlTmFtZXMpO1xuXG4gICAgICB3YXJuKCdjb21wb25lbnRXaWxsVXBkYXRlIGhhcyBiZWVuIHJlbmFtZWQsIGFuZCBpcyBub3QgcmVjb21tZW5kZWQgZm9yIHVzZS4gJyArICdTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3Vuc2FmZS1jb21wb25lbnQtbGlmZWN5Y2xlcyBmb3IgZGV0YWlscy5cXG5cXG4nICsgJyogTW92ZSBkYXRhIGZldGNoaW5nIGNvZGUgb3Igc2lkZSBlZmZlY3RzIHRvIGNvbXBvbmVudERpZFVwZGF0ZS5cXG4nICsgJyogUmVuYW1lIGNvbXBvbmVudFdpbGxVcGRhdGUgdG8gVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUgdG8gc3VwcHJlc3MgJyArICd0aGlzIHdhcm5pbmcgaW4gbm9uLXN0cmljdCBtb2RlLiBJbiBSZWFjdCAxOC54LCBvbmx5IHRoZSBVTlNBRkVfIG5hbWUgd2lsbCB3b3JrLiAnICsgJ1RvIHJlbmFtZSBhbGwgZGVwcmVjYXRlZCBsaWZlY3ljbGVzIHRvIHRoZWlyIG5ldyBuYW1lcywgeW91IGNhbiBydW4gJyArICdgbnB4IHJlYWN0LWNvZGVtb2QgcmVuYW1lLXVuc2FmZS1saWZlY3ljbGVzYCBpbiB5b3VyIHByb2plY3Qgc291cmNlIGZvbGRlci5cXG4nICsgJ1xcblBsZWFzZSB1cGRhdGUgdGhlIGZvbGxvd2luZyBjb21wb25lbnRzOiAlcycsIF9zb3J0ZWROYW1lczUpO1xuICAgIH1cbiAgfTtcblxuICB2YXIgcGVuZGluZ0xlZ2FjeUNvbnRleHRXYXJuaW5nID0gbmV3IE1hcCgpOyAvLyBUcmFja3MgY29tcG9uZW50cyB3ZSBoYXZlIGFscmVhZHkgd2FybmVkIGFib3V0LlxuXG4gIHZhciBkaWRXYXJuQWJvdXRMZWdhY3lDb250ZXh0ID0gbmV3IFNldCgpO1xuXG4gIFJlYWN0U3RyaWN0TW9kZVdhcm5pbmdzLnJlY29yZExlZ2FjeUNvbnRleHRXYXJuaW5nID0gZnVuY3Rpb24gKGZpYmVyLCBpbnN0YW5jZSkge1xuICAgIHZhciBzdHJpY3RSb290ID0gZmluZFN0cmljdFJvb3QoZmliZXIpO1xuXG4gICAgaWYgKHN0cmljdFJvb3QgPT09IG51bGwpIHtcbiAgICAgIGVycm9yKCdFeHBlY3RlZCB0byBmaW5kIGEgU3RyaWN0TW9kZSBjb21wb25lbnQgaW4gYSBzdHJpY3QgbW9kZSB0cmVlLiAnICsgJ1RoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9IC8vIERlZHVwIHN0cmF0ZWd5OiBXYXJuIG9uY2UgcGVyIGNvbXBvbmVudC5cblxuXG4gICAgaWYgKGRpZFdhcm5BYm91dExlZ2FjeUNvbnRleHQuaGFzKGZpYmVyLnR5cGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHdhcm5pbmdzRm9yUm9vdCA9IHBlbmRpbmdMZWdhY3lDb250ZXh0V2FybmluZy5nZXQoc3RyaWN0Um9vdCk7XG5cbiAgICBpZiAoZmliZXIudHlwZS5jb250ZXh0VHlwZXMgIT0gbnVsbCB8fCBmaWJlci50eXBlLmNoaWxkQ29udGV4dFR5cGVzICE9IG51bGwgfHwgaW5zdGFuY2UgIT09IG51bGwgJiYgdHlwZW9mIGluc3RhbmNlLmdldENoaWxkQ29udGV4dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKHdhcm5pbmdzRm9yUm9vdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHdhcm5pbmdzRm9yUm9vdCA9IFtdO1xuICAgICAgICBwZW5kaW5nTGVnYWN5Q29udGV4dFdhcm5pbmcuc2V0KHN0cmljdFJvb3QsIHdhcm5pbmdzRm9yUm9vdCk7XG4gICAgICB9XG5cbiAgICAgIHdhcm5pbmdzRm9yUm9vdC5wdXNoKGZpYmVyKTtcbiAgICB9XG4gIH07XG5cbiAgUmVhY3RTdHJpY3RNb2RlV2FybmluZ3MuZmx1c2hMZWdhY3lDb250ZXh0V2FybmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICBwZW5kaW5nTGVnYWN5Q29udGV4dFdhcm5pbmcuZm9yRWFjaChmdW5jdGlvbiAoZmliZXJBcnJheSwgc3RyaWN0Um9vdCkge1xuICAgICAgaWYgKGZpYmVyQXJyYXkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGZpcnN0RmliZXIgPSBmaWJlckFycmF5WzBdO1xuICAgICAgdmFyIHVuaXF1ZU5hbWVzID0gbmV3IFNldCgpO1xuICAgICAgZmliZXJBcnJheS5mb3JFYWNoKGZ1bmN0aW9uIChmaWJlcikge1xuICAgICAgICB1bmlxdWVOYW1lcy5hZGQoZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ0NvbXBvbmVudCcpO1xuICAgICAgICBkaWRXYXJuQWJvdXRMZWdhY3lDb250ZXh0LmFkZChmaWJlci50eXBlKTtcbiAgICAgIH0pO1xuICAgICAgdmFyIHNvcnRlZE5hbWVzID0gc2V0VG9Tb3J0ZWRTdHJpbmcodW5pcXVlTmFtZXMpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBzZXRDdXJyZW50RmliZXIoZmlyc3RGaWJlcik7XG5cbiAgICAgICAgZXJyb3IoJ0xlZ2FjeSBjb250ZXh0IEFQSSBoYXMgYmVlbiBkZXRlY3RlZCB3aXRoaW4gYSBzdHJpY3QtbW9kZSB0cmVlLicgKyAnXFxuXFxuVGhlIG9sZCBBUEkgd2lsbCBiZSBzdXBwb3J0ZWQgaW4gYWxsIDE2LnggcmVsZWFzZXMsIGJ1dCBhcHBsaWNhdGlvbnMgJyArICd1c2luZyBpdCBzaG91bGQgbWlncmF0ZSB0byB0aGUgbmV3IHZlcnNpb24uJyArICdcXG5cXG5QbGVhc2UgdXBkYXRlIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czogJXMnICsgJ1xcblxcbkxlYXJuIG1vcmUgYWJvdXQgdGhpcyB3YXJuaW5nIGhlcmU6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9sZWdhY3ktY29udGV4dCcsIHNvcnRlZE5hbWVzKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgUmVhY3RTdHJpY3RNb2RlV2FybmluZ3MuZGlzY2FyZFBlbmRpbmdXYXJuaW5ncyA9IGZ1bmN0aW9uICgpIHtcbiAgICBwZW5kaW5nQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgICBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxNb3VudFdhcm5pbmdzID0gW107XG4gICAgcGVuZGluZ0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncyA9IFtdO1xuICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1dhcm5pbmdzID0gW107XG4gICAgcGVuZGluZ0NvbXBvbmVudFdpbGxVcGRhdGVXYXJuaW5ncyA9IFtdO1xuICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzID0gW107XG4gICAgcGVuZGluZ0xlZ2FjeUNvbnRleHRXYXJuaW5nID0gbmV3IE1hcCgpO1xuICB9O1xufVxuXG5mdW5jdGlvbiByZXNvbHZlRGVmYXVsdFByb3BzKENvbXBvbmVudCwgYmFzZVByb3BzKSB7XG4gIGlmIChDb21wb25lbnQgJiYgQ29tcG9uZW50LmRlZmF1bHRQcm9wcykge1xuICAgIC8vIFJlc29sdmUgZGVmYXVsdCBwcm9wcy4gVGFrZW4gZnJvbSBSZWFjdEVsZW1lbnRcbiAgICB2YXIgcHJvcHMgPSBhc3NpZ24oe30sIGJhc2VQcm9wcyk7XG4gICAgdmFyIGRlZmF1bHRQcm9wcyA9IENvbXBvbmVudC5kZWZhdWx0UHJvcHM7XG5cbiAgICBmb3IgKHZhciBwcm9wTmFtZSBpbiBkZWZhdWx0UHJvcHMpIHtcbiAgICAgIGlmIChwcm9wc1twcm9wTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwcm9wc1twcm9wTmFtZV0gPSBkZWZhdWx0UHJvcHNbcHJvcE5hbWVdO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwcm9wcztcbiAgfVxuXG4gIHJldHVybiBiYXNlUHJvcHM7XG59XG5cbnZhciB2YWx1ZUN1cnNvciA9IGNyZWF0ZUN1cnNvcihudWxsKTtcbnZhciByZW5kZXJlclNpZ2lsO1xuXG57XG4gIC8vIFVzZSB0aGlzIHRvIGRldGVjdCBtdWx0aXBsZSByZW5kZXJlcnMgdXNpbmcgdGhlIHNhbWUgY29udGV4dFxuICByZW5kZXJlclNpZ2lsID0ge307XG59XG5cbnZhciBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciA9IG51bGw7XG52YXIgbGFzdENvbnRleHREZXBlbmRlbmN5ID0gbnVsbDtcbnZhciBsYXN0RnVsbHlPYnNlcnZlZENvbnRleHQgPSBudWxsO1xudmFyIGlzRGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYgPSBmYWxzZTtcbmZ1bmN0aW9uIHJlc2V0Q29udGV4dERlcGVuZGVuY2llcygpIHtcbiAgLy8gVGhpcyBpcyBjYWxsZWQgcmlnaHQgYmVmb3JlIFJlYWN0IHlpZWxkcyBleGVjdXRpb24sIHRvIGVuc3VyZSBgcmVhZENvbnRleHRgXG4gIC8vIGNhbm5vdCBiZSBjYWxsZWQgb3V0c2lkZSB0aGUgcmVuZGVyIHBoYXNlLlxuICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciA9IG51bGw7XG4gIGxhc3RDb250ZXh0RGVwZW5kZW5jeSA9IG51bGw7XG4gIGxhc3RGdWxseU9ic2VydmVkQ29udGV4dCA9IG51bGw7XG5cbiAge1xuICAgIGlzRGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYgPSBmYWxzZTtcbiAgfVxufVxuZnVuY3Rpb24gZW50ZXJEaXNhbGxvd2VkQ29udGV4dFJlYWRJbkRFVigpIHtcbiAge1xuICAgIGlzRGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYgPSB0cnVlO1xuICB9XG59XG5mdW5jdGlvbiBleGl0RGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYoKSB7XG4gIHtcbiAgICBpc0Rpc2FsbG93ZWRDb250ZXh0UmVhZEluREVWID0gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIHB1c2hQcm92aWRlcihwcm92aWRlckZpYmVyLCBjb250ZXh0LCBuZXh0VmFsdWUpIHtcbiAge1xuICAgIHB1c2godmFsdWVDdXJzb3IsIGNvbnRleHQuX2N1cnJlbnRWYWx1ZSwgcHJvdmlkZXJGaWJlcik7XG4gICAgY29udGV4dC5fY3VycmVudFZhbHVlID0gbmV4dFZhbHVlO1xuXG4gICAge1xuICAgICAgaWYgKGNvbnRleHQuX2N1cnJlbnRSZW5kZXJlciAhPT0gdW5kZWZpbmVkICYmIGNvbnRleHQuX2N1cnJlbnRSZW5kZXJlciAhPT0gbnVsbCAmJiBjb250ZXh0Ll9jdXJyZW50UmVuZGVyZXIgIT09IHJlbmRlcmVyU2lnaWwpIHtcbiAgICAgICAgZXJyb3IoJ0RldGVjdGVkIG11bHRpcGxlIHJlbmRlcmVycyBjb25jdXJyZW50bHkgcmVuZGVyaW5nIHRoZSAnICsgJ3NhbWUgY29udGV4dCBwcm92aWRlci4gVGhpcyBpcyBjdXJyZW50bHkgdW5zdXBwb3J0ZWQuJyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRleHQuX2N1cnJlbnRSZW5kZXJlciA9IHJlbmRlcmVyU2lnaWw7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBwb3BQcm92aWRlcihjb250ZXh0LCBwcm92aWRlckZpYmVyKSB7XG4gIHZhciBjdXJyZW50VmFsdWUgPSB2YWx1ZUN1cnNvci5jdXJyZW50O1xuICBwb3AodmFsdWVDdXJzb3IsIHByb3ZpZGVyRmliZXIpO1xuXG4gIHtcbiAgICB7XG4gICAgICBjb250ZXh0Ll9jdXJyZW50VmFsdWUgPSBjdXJyZW50VmFsdWU7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBzY2hlZHVsZUNvbnRleHRXb3JrT25QYXJlbnRQYXRoKHBhcmVudCwgcmVuZGVyTGFuZXMsIHByb3BhZ2F0aW9uUm9vdCkge1xuICAvLyBVcGRhdGUgdGhlIGNoaWxkIGxhbmVzIG9mIGFsbCB0aGUgYW5jZXN0b3JzLCBpbmNsdWRpbmcgdGhlIGFsdGVybmF0ZXMuXG4gIHZhciBub2RlID0gcGFyZW50O1xuXG4gIHdoaWxlIChub2RlICE9PSBudWxsKSB7XG4gICAgdmFyIGFsdGVybmF0ZSA9IG5vZGUuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKCFpc1N1YnNldE9mTGFuZXMobm9kZS5jaGlsZExhbmVzLCByZW5kZXJMYW5lcykpIHtcbiAgICAgIG5vZGUuY2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMobm9kZS5jaGlsZExhbmVzLCByZW5kZXJMYW5lcyk7XG5cbiAgICAgIGlmIChhbHRlcm5hdGUgIT09IG51bGwpIHtcbiAgICAgICAgYWx0ZXJuYXRlLmNoaWxkTGFuZXMgPSBtZXJnZUxhbmVzKGFsdGVybmF0ZS5jaGlsZExhbmVzLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChhbHRlcm5hdGUgIT09IG51bGwgJiYgIWlzU3Vic2V0T2ZMYW5lcyhhbHRlcm5hdGUuY2hpbGRMYW5lcywgcmVuZGVyTGFuZXMpKSB7XG4gICAgICBhbHRlcm5hdGUuY2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMoYWx0ZXJuYXRlLmNoaWxkTGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgICB9XG5cbiAgICBpZiAobm9kZSA9PT0gcHJvcGFnYXRpb25Sb290KSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBub2RlID0gbm9kZS5yZXR1cm47XG4gIH1cblxuICB7XG4gICAgaWYgKG5vZGUgIT09IHByb3BhZ2F0aW9uUm9vdCkge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIHRvIGZpbmQgdGhlIHByb3BhZ2F0aW9uIHJvb3Qgd2hlbiBzY2hlZHVsaW5nIGNvbnRleHQgd29yay4gJyArICdUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gcHJvcGFnYXRlQ29udGV4dENoYW5nZSh3b3JrSW5Qcm9ncmVzcywgY29udGV4dCwgcmVuZGVyTGFuZXMpIHtcbiAge1xuICAgIHByb3BhZ2F0ZUNvbnRleHRDaGFuZ2VfZWFnZXIod29ya0luUHJvZ3Jlc3MsIGNvbnRleHQsIHJlbmRlckxhbmVzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9wYWdhdGVDb250ZXh0Q2hhbmdlX2VhZ2VyKHdvcmtJblByb2dyZXNzLCBjb250ZXh0LCByZW5kZXJMYW5lcykge1xuXG4gIHZhciBmaWJlciA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuXG4gIGlmIChmaWJlciAhPT0gbnVsbCkge1xuICAgIC8vIFNldCB0aGUgcmV0dXJuIHBvaW50ZXIgb2YgdGhlIGNoaWxkIHRvIHRoZSB3b3JrLWluLXByb2dyZXNzIGZpYmVyLlxuICAgIGZpYmVyLnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICB9XG5cbiAgd2hpbGUgKGZpYmVyICE9PSBudWxsKSB7XG4gICAgdmFyIG5leHRGaWJlciA9IHZvaWQgMDsgLy8gVmlzaXQgdGhpcyBmaWJlci5cblxuICAgIHZhciBsaXN0ID0gZmliZXIuZGVwZW5kZW5jaWVzO1xuXG4gICAgaWYgKGxpc3QgIT09IG51bGwpIHtcbiAgICAgIG5leHRGaWJlciA9IGZpYmVyLmNoaWxkO1xuICAgICAgdmFyIGRlcGVuZGVuY3kgPSBsaXN0LmZpcnN0Q29udGV4dDtcblxuICAgICAgd2hpbGUgKGRlcGVuZGVuY3kgIT09IG51bGwpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGNvbnRleHQgbWF0Y2hlcy5cbiAgICAgICAgaWYgKGRlcGVuZGVuY3kuY29udGV4dCA9PT0gY29udGV4dCkge1xuICAgICAgICAgIC8vIE1hdGNoISBTY2hlZHVsZSBhbiB1cGRhdGUgb24gdGhpcyBmaWJlci5cbiAgICAgICAgICBpZiAoZmliZXIudGFnID09PSBDbGFzc0NvbXBvbmVudCkge1xuICAgICAgICAgICAgLy8gU2NoZWR1bGUgYSBmb3JjZSB1cGRhdGUgb24gdGhlIHdvcmstaW4tcHJvZ3Jlc3MuXG4gICAgICAgICAgICB2YXIgbGFuZSA9IHBpY2tBcmJpdHJhcnlMYW5lKHJlbmRlckxhbmVzKTtcbiAgICAgICAgICAgIHZhciB1cGRhdGUgPSBjcmVhdGVVcGRhdGUoTm9UaW1lc3RhbXAsIGxhbmUpO1xuICAgICAgICAgICAgdXBkYXRlLnRhZyA9IEZvcmNlVXBkYXRlOyAvLyBUT0RPOiBCZWNhdXNlIHdlIGRvbid0IGhhdmUgYSB3b3JrLWluLXByb2dyZXNzLCB0aGlzIHdpbGwgYWRkIHRoZVxuICAgICAgICAgICAgLy8gdXBkYXRlIHRvIHRoZSBjdXJyZW50IGZpYmVyLCB0b28sIHdoaWNoIG1lYW5zIGl0IHdpbGwgcGVyc2lzdCBldmVuIGlmXG4gICAgICAgICAgICAvLyB0aGlzIHJlbmRlciBpcyB0aHJvd24gYXdheS4gU2luY2UgaXQncyBhIHJhY2UgY29uZGl0aW9uLCBub3Qgc3VyZSBpdCdzXG4gICAgICAgICAgICAvLyB3b3J0aCBmaXhpbmcuXG4gICAgICAgICAgICAvLyBJbmxpbmVkIGBlbnF1ZXVlVXBkYXRlYCB0byByZW1vdmUgaW50ZXJsZWF2ZWQgdXBkYXRlIGNoZWNrXG5cbiAgICAgICAgICAgIHZhciB1cGRhdGVRdWV1ZSA9IGZpYmVyLnVwZGF0ZVF1ZXVlO1xuXG4gICAgICAgICAgICBpZiAodXBkYXRlUXVldWUgPT09IG51bGwpIDsgZWxzZSB7XG4gICAgICAgICAgICAgIHZhciBzaGFyZWRRdWV1ZSA9IHVwZGF0ZVF1ZXVlLnNoYXJlZDtcbiAgICAgICAgICAgICAgdmFyIHBlbmRpbmcgPSBzaGFyZWRRdWV1ZS5wZW5kaW5nO1xuXG4gICAgICAgICAgICAgIGlmIChwZW5kaW5nID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgdXBkYXRlLiBDcmVhdGUgYSBjaXJjdWxhciBsaXN0LlxuICAgICAgICAgICAgICAgIHVwZGF0ZS5uZXh0ID0gdXBkYXRlO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHVwZGF0ZS5uZXh0ID0gcGVuZGluZy5uZXh0O1xuICAgICAgICAgICAgICAgIHBlbmRpbmcubmV4dCA9IHVwZGF0ZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHNoYXJlZFF1ZXVlLnBlbmRpbmcgPSB1cGRhdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZmliZXIubGFuZXMgPSBtZXJnZUxhbmVzKGZpYmVyLmxhbmVzLCByZW5kZXJMYW5lcyk7XG4gICAgICAgICAgdmFyIGFsdGVybmF0ZSA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICAgICAgICAgIGlmIChhbHRlcm5hdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGFsdGVybmF0ZS5sYW5lcyA9IG1lcmdlTGFuZXMoYWx0ZXJuYXRlLmxhbmVzLCByZW5kZXJMYW5lcyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc2NoZWR1bGVDb250ZXh0V29ya09uUGFyZW50UGF0aChmaWJlci5yZXR1cm4sIHJlbmRlckxhbmVzLCB3b3JrSW5Qcm9ncmVzcyk7IC8vIE1hcmsgdGhlIHVwZGF0ZWQgbGFuZXMgb24gdGhlIGxpc3QsIHRvby5cblxuICAgICAgICAgIGxpc3QubGFuZXMgPSBtZXJnZUxhbmVzKGxpc3QubGFuZXMsIHJlbmRlckxhbmVzKTsgLy8gU2luY2Ugd2UgYWxyZWFkeSBmb3VuZCBhIG1hdGNoLCB3ZSBjYW4gc3RvcCB0cmF2ZXJzaW5nIHRoZVxuICAgICAgICAgIC8vIGRlcGVuZGVuY3kgbGlzdC5cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgZGVwZW5kZW5jeSA9IGRlcGVuZGVuY3kubmV4dDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGZpYmVyLnRhZyA9PT0gQ29udGV4dFByb3ZpZGVyKSB7XG4gICAgICAvLyBEb24ndCBzY2FuIGRlZXBlciBpZiB0aGlzIGlzIGEgbWF0Y2hpbmcgcHJvdmlkZXJcbiAgICAgIG5leHRGaWJlciA9IGZpYmVyLnR5cGUgPT09IHdvcmtJblByb2dyZXNzLnR5cGUgPyBudWxsIDogZmliZXIuY2hpbGQ7XG4gICAgfSBlbHNlIGlmIChmaWJlci50YWcgPT09IERlaHlkcmF0ZWRGcmFnbWVudCkge1xuICAgICAgLy8gSWYgYSBkZWh5ZHJhdGVkIHN1c3BlbnNlIGJvdW5kYXJ5IGlzIGluIHRoaXMgc3VidHJlZSwgd2UgZG9uJ3Qga25vd1xuICAgICAgLy8gaWYgaXQgd2lsbCBoYXZlIGFueSBjb250ZXh0IGNvbnN1bWVycyBpbiBpdC4gVGhlIGJlc3Qgd2UgY2FuIGRvIGlzXG4gICAgICAvLyBtYXJrIGl0IGFzIGhhdmluZyB1cGRhdGVzLlxuICAgICAgdmFyIHBhcmVudFN1c3BlbnNlID0gZmliZXIucmV0dXJuO1xuXG4gICAgICBpZiAocGFyZW50U3VzcGVuc2UgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZSBqdXN0IGNhbWUgZnJvbSBhIHBhcmVudCBzbyB3ZSBtdXN0IGhhdmUgaGFkIGEgcGFyZW50LiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0LicpO1xuICAgICAgfVxuXG4gICAgICBwYXJlbnRTdXNwZW5zZS5sYW5lcyA9IG1lcmdlTGFuZXMocGFyZW50U3VzcGVuc2UubGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgICAgIHZhciBfYWx0ZXJuYXRlID0gcGFyZW50U3VzcGVuc2UuYWx0ZXJuYXRlO1xuXG4gICAgICBpZiAoX2FsdGVybmF0ZSAhPT0gbnVsbCkge1xuICAgICAgICBfYWx0ZXJuYXRlLmxhbmVzID0gbWVyZ2VMYW5lcyhfYWx0ZXJuYXRlLmxhbmVzLCByZW5kZXJMYW5lcyk7XG4gICAgICB9IC8vIFRoaXMgaXMgaW50ZW50aW9uYWxseSBwYXNzaW5nIHRoaXMgZmliZXIgYXMgdGhlIHBhcmVudFxuICAgICAgLy8gYmVjYXVzZSB3ZSB3YW50IHRvIHNjaGVkdWxlIHRoaXMgZmliZXIgYXMgaGF2aW5nIHdvcmtcbiAgICAgIC8vIG9uIGl0cyBjaGlsZHJlbi4gV2UnbGwgdXNlIHRoZSBjaGlsZExhbmVzIG9uXG4gICAgICAvLyB0aGlzIGZpYmVyIHRvIGluZGljYXRlIHRoYXQgYSBjb250ZXh0IGhhcyBjaGFuZ2VkLlxuXG5cbiAgICAgIHNjaGVkdWxlQ29udGV4dFdvcmtPblBhcmVudFBhdGgocGFyZW50U3VzcGVuc2UsIHJlbmRlckxhbmVzLCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICBuZXh0RmliZXIgPSBmaWJlci5zaWJsaW5nO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUcmF2ZXJzZSBkb3duLlxuICAgICAgbmV4dEZpYmVyID0gZmliZXIuY2hpbGQ7XG4gICAgfVxuXG4gICAgaWYgKG5leHRGaWJlciAhPT0gbnVsbCkge1xuICAgICAgLy8gU2V0IHRoZSByZXR1cm4gcG9pbnRlciBvZiB0aGUgY2hpbGQgdG8gdGhlIHdvcmstaW4tcHJvZ3Jlc3MgZmliZXIuXG4gICAgICBuZXh0RmliZXIucmV0dXJuID0gZmliZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vIGNoaWxkLiBUcmF2ZXJzZSB0byBuZXh0IHNpYmxpbmcuXG4gICAgICBuZXh0RmliZXIgPSBmaWJlcjtcblxuICAgICAgd2hpbGUgKG5leHRGaWJlciAhPT0gbnVsbCkge1xuICAgICAgICBpZiAobmV4dEZpYmVyID09PSB3b3JrSW5Qcm9ncmVzcykge1xuICAgICAgICAgIC8vIFdlJ3JlIGJhY2sgdG8gdGhlIHJvb3Qgb2YgdGhpcyBzdWJ0cmVlLiBFeGl0LlxuICAgICAgICAgIG5leHRGaWJlciA9IG51bGw7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc2libGluZyA9IG5leHRGaWJlci5zaWJsaW5nO1xuXG4gICAgICAgIGlmIChzaWJsaW5nICE9PSBudWxsKSB7XG4gICAgICAgICAgLy8gU2V0IHRoZSByZXR1cm4gcG9pbnRlciBvZiB0aGUgc2libGluZyB0byB0aGUgd29yay1pbi1wcm9ncmVzcyBmaWJlci5cbiAgICAgICAgICBzaWJsaW5nLnJldHVybiA9IG5leHRGaWJlci5yZXR1cm47XG4gICAgICAgICAgbmV4dEZpYmVyID0gc2libGluZztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfSAvLyBObyBtb3JlIHNpYmxpbmdzLiBUcmF2ZXJzZSB1cC5cblxuXG4gICAgICAgIG5leHRGaWJlciA9IG5leHRGaWJlci5yZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgZmliZXIgPSBuZXh0RmliZXI7XG4gIH1cbn1cbmZ1bmN0aW9uIHByZXBhcmVUb1JlYWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcykge1xuICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciA9IHdvcmtJblByb2dyZXNzO1xuICBsYXN0Q29udGV4dERlcGVuZGVuY3kgPSBudWxsO1xuICBsYXN0RnVsbHlPYnNlcnZlZENvbnRleHQgPSBudWxsO1xuICB2YXIgZGVwZW5kZW5jaWVzID0gd29ya0luUHJvZ3Jlc3MuZGVwZW5kZW5jaWVzO1xuXG4gIGlmIChkZXBlbmRlbmNpZXMgIT09IG51bGwpIHtcbiAgICB7XG4gICAgICB2YXIgZmlyc3RDb250ZXh0ID0gZGVwZW5kZW5jaWVzLmZpcnN0Q29udGV4dDtcblxuICAgICAgaWYgKGZpcnN0Q29udGV4dCAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoaW5jbHVkZXNTb21lTGFuZShkZXBlbmRlbmNpZXMubGFuZXMsIHJlbmRlckxhbmVzKSkge1xuICAgICAgICAgIC8vIENvbnRleHQgbGlzdCBoYXMgYSBwZW5kaW5nIHVwZGF0ZS4gTWFyayB0aGF0IHRoaXMgZmliZXIgcGVyZm9ybWVkIHdvcmsuXG4gICAgICAgICAgbWFya1dvcmtJblByb2dyZXNzUmVjZWl2ZWRVcGRhdGUoKTtcbiAgICAgICAgfSAvLyBSZXNldCB0aGUgd29yay1pbi1wcm9ncmVzcyBsaXN0XG5cblxuICAgICAgICBkZXBlbmRlbmNpZXMuZmlyc3RDb250ZXh0ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIHJlYWRDb250ZXh0KGNvbnRleHQpIHtcbiAge1xuICAgIC8vIFRoaXMgd2FybmluZyB3b3VsZCBmaXJlIGlmIHlvdSByZWFkIGNvbnRleHQgaW5zaWRlIGEgSG9vayBsaWtlIHVzZU1lbW8uXG4gICAgLy8gVW5saWtlIHRoZSBjbGFzcyBjaGVjayBiZWxvdywgaXQncyBub3QgZW5mb3JjZWQgaW4gcHJvZHVjdGlvbiBmb3IgcGVyZi5cbiAgICBpZiAoaXNEaXNhbGxvd2VkQ29udGV4dFJlYWRJbkRFVikge1xuICAgICAgZXJyb3IoJ0NvbnRleHQgY2FuIG9ubHkgYmUgcmVhZCB3aGlsZSBSZWFjdCBpcyByZW5kZXJpbmcuICcgKyAnSW4gY2xhc3NlcywgeW91IGNhbiByZWFkIGl0IGluIHRoZSByZW5kZXIgbWV0aG9kIG9yIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcy4gJyArICdJbiBmdW5jdGlvbiBjb21wb25lbnRzLCB5b3UgY2FuIHJlYWQgaXQgZGlyZWN0bHkgaW4gdGhlIGZ1bmN0aW9uIGJvZHksIGJ1dCBub3QgJyArICdpbnNpZGUgSG9va3MgbGlrZSB1c2VSZWR1Y2VyKCkgb3IgdXNlTWVtbygpLicpO1xuICAgIH1cbiAgfVxuXG4gIHZhciB2YWx1ZSA9ICBjb250ZXh0Ll9jdXJyZW50VmFsdWUgO1xuXG4gIGlmIChsYXN0RnVsbHlPYnNlcnZlZENvbnRleHQgPT09IGNvbnRleHQpIDsgZWxzZSB7XG4gICAgdmFyIGNvbnRleHRJdGVtID0ge1xuICAgICAgY29udGV4dDogY29udGV4dCxcbiAgICAgIG1lbW9pemVkVmFsdWU6IHZhbHVlLFxuICAgICAgbmV4dDogbnVsbFxuICAgIH07XG5cbiAgICBpZiAobGFzdENvbnRleHREZXBlbmRlbmN5ID09PSBudWxsKSB7XG4gICAgICBpZiAoY3VycmVudGx5UmVuZGVyaW5nRmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb250ZXh0IGNhbiBvbmx5IGJlIHJlYWQgd2hpbGUgUmVhY3QgaXMgcmVuZGVyaW5nLiAnICsgJ0luIGNsYXNzZXMsIHlvdSBjYW4gcmVhZCBpdCBpbiB0aGUgcmVuZGVyIG1ldGhvZCBvciBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMuICcgKyAnSW4gZnVuY3Rpb24gY29tcG9uZW50cywgeW91IGNhbiByZWFkIGl0IGRpcmVjdGx5IGluIHRoZSBmdW5jdGlvbiBib2R5LCBidXQgbm90ICcgKyAnaW5zaWRlIEhvb2tzIGxpa2UgdXNlUmVkdWNlcigpIG9yIHVzZU1lbW8oKS4nKTtcbiAgICAgIH0gLy8gVGhpcyBpcyB0aGUgZmlyc3QgZGVwZW5kZW5jeSBmb3IgdGhpcyBjb21wb25lbnQuIENyZWF0ZSBhIG5ldyBsaXN0LlxuXG5cbiAgICAgIGxhc3RDb250ZXh0RGVwZW5kZW5jeSA9IGNvbnRleHRJdGVtO1xuICAgICAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIuZGVwZW5kZW5jaWVzID0ge1xuICAgICAgICBsYW5lczogTm9MYW5lcyxcbiAgICAgICAgZmlyc3RDb250ZXh0OiBjb250ZXh0SXRlbVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXBwZW5kIGEgbmV3IGNvbnRleHQgaXRlbS5cbiAgICAgIGxhc3RDb250ZXh0RGVwZW5kZW5jeSA9IGxhc3RDb250ZXh0RGVwZW5kZW5jeS5uZXh0ID0gY29udGV4dEl0ZW07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG4vLyByZW5kZXIuIFdoZW4gdGhpcyByZW5kZXIgZXhpdHMsIGVpdGhlciBiZWNhdXNlIGl0IGZpbmlzaGVzIG9yIGJlY2F1c2UgaXQgaXNcbi8vIGludGVycnVwdGVkLCB0aGUgaW50ZXJsZWF2ZWQgdXBkYXRlcyB3aWxsIGJlIHRyYW5zZmVycmVkIG9udG8gdGhlIG1haW4gcGFydFxuLy8gb2YgdGhlIHF1ZXVlLlxuXG52YXIgY29uY3VycmVudFF1ZXVlcyA9IG51bGw7XG5mdW5jdGlvbiBwdXNoQ29uY3VycmVudFVwZGF0ZVF1ZXVlKHF1ZXVlKSB7XG4gIGlmIChjb25jdXJyZW50UXVldWVzID09PSBudWxsKSB7XG4gICAgY29uY3VycmVudFF1ZXVlcyA9IFtxdWV1ZV07XG4gIH0gZWxzZSB7XG4gICAgY29uY3VycmVudFF1ZXVlcy5wdXNoKHF1ZXVlKTtcbiAgfVxufVxuZnVuY3Rpb24gZmluaXNoUXVldWVpbmdDb25jdXJyZW50VXBkYXRlcygpIHtcbiAgLy8gVHJhbnNmZXIgdGhlIGludGVybGVhdmVkIHVwZGF0ZXMgb250byB0aGUgbWFpbiBxdWV1ZS4gRWFjaCBxdWV1ZSBoYXMgYVxuICAvLyBgcGVuZGluZ2AgZmllbGQgYW5kIGFuIGBpbnRlcmxlYXZlZGAgZmllbGQuIFdoZW4gdGhleSBhcmUgbm90IG51bGwsIHRoZXlcbiAgLy8gcG9pbnQgdG8gdGhlIGxhc3Qgbm9kZSBpbiBhIGNpcmN1bGFyIGxpbmtlZCBsaXN0LiBXZSBuZWVkIHRvIGFwcGVuZCB0aGVcbiAgLy8gaW50ZXJsZWF2ZWQgbGlzdCB0byB0aGUgZW5kIG9mIHRoZSBwZW5kaW5nIGxpc3QgYnkgam9pbmluZyB0aGVtIGludG8gYVxuICAvLyBzaW5nbGUsIGNpcmN1bGFyIGxpc3QuXG4gIGlmIChjb25jdXJyZW50UXVldWVzICE9PSBudWxsKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb25jdXJyZW50UXVldWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcXVldWUgPSBjb25jdXJyZW50UXVldWVzW2ldO1xuICAgICAgdmFyIGxhc3RJbnRlcmxlYXZlZFVwZGF0ZSA9IHF1ZXVlLmludGVybGVhdmVkO1xuXG4gICAgICBpZiAobGFzdEludGVybGVhdmVkVXBkYXRlICE9PSBudWxsKSB7XG4gICAgICAgIHF1ZXVlLmludGVybGVhdmVkID0gbnVsbDtcbiAgICAgICAgdmFyIGZpcnN0SW50ZXJsZWF2ZWRVcGRhdGUgPSBsYXN0SW50ZXJsZWF2ZWRVcGRhdGUubmV4dDtcbiAgICAgICAgdmFyIGxhc3RQZW5kaW5nVXBkYXRlID0gcXVldWUucGVuZGluZztcblxuICAgICAgICBpZiAobGFzdFBlbmRpbmdVcGRhdGUgIT09IG51bGwpIHtcbiAgICAgICAgICB2YXIgZmlyc3RQZW5kaW5nVXBkYXRlID0gbGFzdFBlbmRpbmdVcGRhdGUubmV4dDtcbiAgICAgICAgICBsYXN0UGVuZGluZ1VwZGF0ZS5uZXh0ID0gZmlyc3RJbnRlcmxlYXZlZFVwZGF0ZTtcbiAgICAgICAgICBsYXN0SW50ZXJsZWF2ZWRVcGRhdGUubmV4dCA9IGZpcnN0UGVuZGluZ1VwZGF0ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHF1ZXVlLnBlbmRpbmcgPSBsYXN0SW50ZXJsZWF2ZWRVcGRhdGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uY3VycmVudFF1ZXVlcyA9IG51bGw7XG4gIH1cbn1cbmZ1bmN0aW9uIGVucXVldWVDb25jdXJyZW50SG9va1VwZGF0ZShmaWJlciwgcXVldWUsIHVwZGF0ZSwgbGFuZSkge1xuICB2YXIgaW50ZXJsZWF2ZWQgPSBxdWV1ZS5pbnRlcmxlYXZlZDtcblxuICBpZiAoaW50ZXJsZWF2ZWQgPT09IG51bGwpIHtcbiAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCB1cGRhdGUuIENyZWF0ZSBhIGNpcmN1bGFyIGxpc3QuXG4gICAgdXBkYXRlLm5leHQgPSB1cGRhdGU7IC8vIEF0IHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgcmVuZGVyLCB0aGlzIHF1ZXVlJ3MgaW50ZXJsZWF2ZWQgdXBkYXRlcyB3aWxsXG4gICAgLy8gYmUgdHJhbnNmZXJyZWQgdG8gdGhlIHBlbmRpbmcgcXVldWUuXG5cbiAgICBwdXNoQ29uY3VycmVudFVwZGF0ZVF1ZXVlKHF1ZXVlKTtcbiAgfSBlbHNlIHtcbiAgICB1cGRhdGUubmV4dCA9IGludGVybGVhdmVkLm5leHQ7XG4gICAgaW50ZXJsZWF2ZWQubmV4dCA9IHVwZGF0ZTtcbiAgfVxuXG4gIHF1ZXVlLmludGVybGVhdmVkID0gdXBkYXRlO1xuICByZXR1cm4gbWFya1VwZGF0ZUxhbmVGcm9tRmliZXJUb1Jvb3QoZmliZXIsIGxhbmUpO1xufVxuZnVuY3Rpb24gZW5xdWV1ZUNvbmN1cnJlbnRIb29rVXBkYXRlQW5kRWFnZXJseUJhaWxvdXQoZmliZXIsIHF1ZXVlLCB1cGRhdGUsIGxhbmUpIHtcbiAgdmFyIGludGVybGVhdmVkID0gcXVldWUuaW50ZXJsZWF2ZWQ7XG5cbiAgaWYgKGludGVybGVhdmVkID09PSBudWxsKSB7XG4gICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgdXBkYXRlLiBDcmVhdGUgYSBjaXJjdWxhciBsaXN0LlxuICAgIHVwZGF0ZS5uZXh0ID0gdXBkYXRlOyAvLyBBdCB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IHJlbmRlciwgdGhpcyBxdWV1ZSdzIGludGVybGVhdmVkIHVwZGF0ZXMgd2lsbFxuICAgIC8vIGJlIHRyYW5zZmVycmVkIHRvIHRoZSBwZW5kaW5nIHF1ZXVlLlxuXG4gICAgcHVzaENvbmN1cnJlbnRVcGRhdGVRdWV1ZShxdWV1ZSk7XG4gIH0gZWxzZSB7XG4gICAgdXBkYXRlLm5leHQgPSBpbnRlcmxlYXZlZC5uZXh0O1xuICAgIGludGVybGVhdmVkLm5leHQgPSB1cGRhdGU7XG4gIH1cblxuICBxdWV1ZS5pbnRlcmxlYXZlZCA9IHVwZGF0ZTtcbn1cbmZ1bmN0aW9uIGVucXVldWVDb25jdXJyZW50Q2xhc3NVcGRhdGUoZmliZXIsIHF1ZXVlLCB1cGRhdGUsIGxhbmUpIHtcbiAgdmFyIGludGVybGVhdmVkID0gcXVldWUuaW50ZXJsZWF2ZWQ7XG5cbiAgaWYgKGludGVybGVhdmVkID09PSBudWxsKSB7XG4gICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgdXBkYXRlLiBDcmVhdGUgYSBjaXJjdWxhciBsaXN0LlxuICAgIHVwZGF0ZS5uZXh0ID0gdXBkYXRlOyAvLyBBdCB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IHJlbmRlciwgdGhpcyBxdWV1ZSdzIGludGVybGVhdmVkIHVwZGF0ZXMgd2lsbFxuICAgIC8vIGJlIHRyYW5zZmVycmVkIHRvIHRoZSBwZW5kaW5nIHF1ZXVlLlxuXG4gICAgcHVzaENvbmN1cnJlbnRVcGRhdGVRdWV1ZShxdWV1ZSk7XG4gIH0gZWxzZSB7XG4gICAgdXBkYXRlLm5leHQgPSBpbnRlcmxlYXZlZC5uZXh0O1xuICAgIGludGVybGVhdmVkLm5leHQgPSB1cGRhdGU7XG4gIH1cblxuICBxdWV1ZS5pbnRlcmxlYXZlZCA9IHVwZGF0ZTtcbiAgcmV0dXJuIG1hcmtVcGRhdGVMYW5lRnJvbUZpYmVyVG9Sb290KGZpYmVyLCBsYW5lKTtcbn1cbmZ1bmN0aW9uIGVucXVldWVDb25jdXJyZW50UmVuZGVyRm9yTGFuZShmaWJlciwgbGFuZSkge1xuICByZXR1cm4gbWFya1VwZGF0ZUxhbmVGcm9tRmliZXJUb1Jvb3QoZmliZXIsIGxhbmUpO1xufSAvLyBDYWxsaW5nIHRoaXMgZnVuY3Rpb24gb3V0c2lkZSB0aGlzIG1vZHVsZSBzaG91bGQgb25seSBiZSBkb25lIGZvciBiYWNrd2FyZHNcbi8vIGNvbXBhdGliaWxpdHkgYW5kIHNob3VsZCBhbHdheXMgYmUgYWNjb21wYW5pZWQgYnkgYSB3YXJuaW5nLlxuXG52YXIgdW5zYWZlX21hcmtVcGRhdGVMYW5lRnJvbUZpYmVyVG9Sb290ID0gbWFya1VwZGF0ZUxhbmVGcm9tRmliZXJUb1Jvb3Q7XG5cbmZ1bmN0aW9uIG1hcmtVcGRhdGVMYW5lRnJvbUZpYmVyVG9Sb290KHNvdXJjZUZpYmVyLCBsYW5lKSB7XG4gIC8vIFVwZGF0ZSB0aGUgc291cmNlIGZpYmVyJ3MgbGFuZXNcbiAgc291cmNlRmliZXIubGFuZXMgPSBtZXJnZUxhbmVzKHNvdXJjZUZpYmVyLmxhbmVzLCBsYW5lKTtcbiAgdmFyIGFsdGVybmF0ZSA9IHNvdXJjZUZpYmVyLmFsdGVybmF0ZTtcblxuICBpZiAoYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgYWx0ZXJuYXRlLmxhbmVzID0gbWVyZ2VMYW5lcyhhbHRlcm5hdGUubGFuZXMsIGxhbmUpO1xuICB9XG5cbiAge1xuICAgIGlmIChhbHRlcm5hdGUgPT09IG51bGwgJiYgKHNvdXJjZUZpYmVyLmZsYWdzICYgKFBsYWNlbWVudCB8IEh5ZHJhdGluZykpICE9PSBOb0ZsYWdzKSB7XG4gICAgICB3YXJuQWJvdXRVcGRhdGVPbk5vdFlldE1vdW50ZWRGaWJlckluREVWKHNvdXJjZUZpYmVyKTtcbiAgICB9XG4gIH0gLy8gV2FsayB0aGUgcGFyZW50IHBhdGggdG8gdGhlIHJvb3QgYW5kIHVwZGF0ZSB0aGUgY2hpbGQgbGFuZXMuXG5cblxuICB2YXIgbm9kZSA9IHNvdXJjZUZpYmVyO1xuICB2YXIgcGFyZW50ID0gc291cmNlRmliZXIucmV0dXJuO1xuXG4gIHdoaWxlIChwYXJlbnQgIT09IG51bGwpIHtcbiAgICBwYXJlbnQuY2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMocGFyZW50LmNoaWxkTGFuZXMsIGxhbmUpO1xuICAgIGFsdGVybmF0ZSA9IHBhcmVudC5hbHRlcm5hdGU7XG5cbiAgICBpZiAoYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgICBhbHRlcm5hdGUuY2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMoYWx0ZXJuYXRlLmNoaWxkTGFuZXMsIGxhbmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB7XG4gICAgICAgIGlmICgocGFyZW50LmZsYWdzICYgKFBsYWNlbWVudCB8IEh5ZHJhdGluZykpICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgICAgd2FybkFib3V0VXBkYXRlT25Ob3RZZXRNb3VudGVkRmliZXJJbkRFVihzb3VyY2VGaWJlcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBub2RlID0gcGFyZW50O1xuICAgIHBhcmVudCA9IHBhcmVudC5yZXR1cm47XG4gIH1cblxuICBpZiAobm9kZS50YWcgPT09IEhvc3RSb290KSB7XG4gICAgdmFyIHJvb3QgPSBub2RlLnN0YXRlTm9kZTtcbiAgICByZXR1cm4gcm9vdDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG52YXIgVXBkYXRlU3RhdGUgPSAwO1xudmFyIFJlcGxhY2VTdGF0ZSA9IDE7XG52YXIgRm9yY2VVcGRhdGUgPSAyO1xudmFyIENhcHR1cmVVcGRhdGUgPSAzOyAvLyBHbG9iYWwgc3RhdGUgdGhhdCBpcyByZXNldCBhdCB0aGUgYmVnaW5uaW5nIG9mIGNhbGxpbmcgYHByb2Nlc3NVcGRhdGVRdWV1ZWAuXG4vLyBJdCBzaG91bGQgb25seSBiZSByZWFkIHJpZ2h0IGFmdGVyIGNhbGxpbmcgYHByb2Nlc3NVcGRhdGVRdWV1ZWAsIHZpYVxuLy8gYGNoZWNrSGFzRm9yY2VVcGRhdGVBZnRlclByb2Nlc3NpbmdgLlxuXG52YXIgaGFzRm9yY2VVcGRhdGUgPSBmYWxzZTtcbnZhciBkaWRXYXJuVXBkYXRlSW5zaWRlVXBkYXRlO1xudmFyIGN1cnJlbnRseVByb2Nlc3NpbmdRdWV1ZTtcblxue1xuICBkaWRXYXJuVXBkYXRlSW5zaWRlVXBkYXRlID0gZmFsc2U7XG4gIGN1cnJlbnRseVByb2Nlc3NpbmdRdWV1ZSA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGluaXRpYWxpemVVcGRhdGVRdWV1ZShmaWJlcikge1xuICB2YXIgcXVldWUgPSB7XG4gICAgYmFzZVN0YXRlOiBmaWJlci5tZW1vaXplZFN0YXRlLFxuICAgIGZpcnN0QmFzZVVwZGF0ZTogbnVsbCxcbiAgICBsYXN0QmFzZVVwZGF0ZTogbnVsbCxcbiAgICBzaGFyZWQ6IHtcbiAgICAgIHBlbmRpbmc6IG51bGwsXG4gICAgICBpbnRlcmxlYXZlZDogbnVsbCxcbiAgICAgIGxhbmVzOiBOb0xhbmVzXG4gICAgfSxcbiAgICBlZmZlY3RzOiBudWxsXG4gIH07XG4gIGZpYmVyLnVwZGF0ZVF1ZXVlID0gcXVldWU7XG59XG5mdW5jdGlvbiBjbG9uZVVwZGF0ZVF1ZXVlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKSB7XG4gIC8vIENsb25lIHRoZSB1cGRhdGUgcXVldWUgZnJvbSBjdXJyZW50LiBVbmxlc3MgaXQncyBhbHJlYWR5IGEgY2xvbmUuXG4gIHZhciBxdWV1ZSA9IHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlO1xuICB2YXIgY3VycmVudFF1ZXVlID0gY3VycmVudC51cGRhdGVRdWV1ZTtcblxuICBpZiAocXVldWUgPT09IGN1cnJlbnRRdWV1ZSkge1xuICAgIHZhciBjbG9uZSA9IHtcbiAgICAgIGJhc2VTdGF0ZTogY3VycmVudFF1ZXVlLmJhc2VTdGF0ZSxcbiAgICAgIGZpcnN0QmFzZVVwZGF0ZTogY3VycmVudFF1ZXVlLmZpcnN0QmFzZVVwZGF0ZSxcbiAgICAgIGxhc3RCYXNlVXBkYXRlOiBjdXJyZW50UXVldWUubGFzdEJhc2VVcGRhdGUsXG4gICAgICBzaGFyZWQ6IGN1cnJlbnRRdWV1ZS5zaGFyZWQsXG4gICAgICBlZmZlY3RzOiBjdXJyZW50UXVldWUuZWZmZWN0c1xuICAgIH07XG4gICAgd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWUgPSBjbG9uZTtcbiAgfVxufVxuZnVuY3Rpb24gY3JlYXRlVXBkYXRlKGV2ZW50VGltZSwgbGFuZSkge1xuICB2YXIgdXBkYXRlID0ge1xuICAgIGV2ZW50VGltZTogZXZlbnRUaW1lLFxuICAgIGxhbmU6IGxhbmUsXG4gICAgdGFnOiBVcGRhdGVTdGF0ZSxcbiAgICBwYXlsb2FkOiBudWxsLFxuICAgIGNhbGxiYWNrOiBudWxsLFxuICAgIG5leHQ6IG51bGxcbiAgfTtcbiAgcmV0dXJuIHVwZGF0ZTtcbn1cbmZ1bmN0aW9uIGVucXVldWVVcGRhdGUoZmliZXIsIHVwZGF0ZSwgbGFuZSkge1xuICB2YXIgdXBkYXRlUXVldWUgPSBmaWJlci51cGRhdGVRdWV1ZTtcblxuICBpZiAodXBkYXRlUXVldWUgPT09IG51bGwpIHtcbiAgICAvLyBPbmx5IG9jY3VycyBpZiB0aGUgZmliZXIgaGFzIGJlZW4gdW5tb3VudGVkLlxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIHNoYXJlZFF1ZXVlID0gdXBkYXRlUXVldWUuc2hhcmVkO1xuXG4gIHtcbiAgICBpZiAoY3VycmVudGx5UHJvY2Vzc2luZ1F1ZXVlID09PSBzaGFyZWRRdWV1ZSAmJiAhZGlkV2FyblVwZGF0ZUluc2lkZVVwZGF0ZSkge1xuICAgICAgZXJyb3IoJ0FuIHVwZGF0ZSAoc2V0U3RhdGUsIHJlcGxhY2VTdGF0ZSwgb3IgZm9yY2VVcGRhdGUpIHdhcyBzY2hlZHVsZWQgJyArICdmcm9tIGluc2lkZSBhbiB1cGRhdGUgZnVuY3Rpb24uIFVwZGF0ZSBmdW5jdGlvbnMgc2hvdWxkIGJlIHB1cmUsICcgKyAnd2l0aCB6ZXJvIHNpZGUtZWZmZWN0cy4gQ29uc2lkZXIgdXNpbmcgY29tcG9uZW50RGlkVXBkYXRlIG9yIGEgJyArICdjYWxsYmFjay4nKTtcblxuICAgICAgZGlkV2FyblVwZGF0ZUluc2lkZVVwZGF0ZSA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzVW5zYWZlQ2xhc3NSZW5kZXJQaGFzZVVwZGF0ZSgpKSB7XG4gICAgLy8gVGhpcyBpcyBhbiB1bnNhZmUgcmVuZGVyIHBoYXNlIHVwZGF0ZS4gQWRkIGRpcmVjdGx5IHRvIHRoZSB1cGRhdGVcbiAgICAvLyBxdWV1ZSBzbyB3ZSBjYW4gcHJvY2VzcyBpdCBpbW1lZGlhdGVseSBkdXJpbmcgdGhlIGN1cnJlbnQgcmVuZGVyLlxuICAgIHZhciBwZW5kaW5nID0gc2hhcmVkUXVldWUucGVuZGluZztcblxuICAgIGlmIChwZW5kaW5nID09PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCB1cGRhdGUuIENyZWF0ZSBhIGNpcmN1bGFyIGxpc3QuXG4gICAgICB1cGRhdGUubmV4dCA9IHVwZGF0ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXBkYXRlLm5leHQgPSBwZW5kaW5nLm5leHQ7XG4gICAgICBwZW5kaW5nLm5leHQgPSB1cGRhdGU7XG4gICAgfVxuXG4gICAgc2hhcmVkUXVldWUucGVuZGluZyA9IHVwZGF0ZTsgLy8gVXBkYXRlIHRoZSBjaGlsZExhbmVzIGV2ZW4gdGhvdWdoIHdlJ3JlIG1vc3QgbGlrZWx5IGFscmVhZHkgcmVuZGVyaW5nXG4gICAgLy8gdGhpcyBmaWJlci4gVGhpcyBpcyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgaW4gdGhlIGNhc2Ugd2hlcmUgeW91XG4gICAgLy8gdXBkYXRlIGEgZGlmZmVyZW50IGNvbXBvbmVudCBkdXJpbmcgcmVuZGVyIHBoYXNlIHRoYW4gdGhlIG9uZSB0aGF0IGlzXG4gICAgLy8gY3VycmVudGx5IHJlbmRlcmluZ3MgKGEgcGF0dGVybiB0aGF0IGlzIGFjY29tcGFuaWVkIGJ5IGEgd2FybmluZykuXG5cbiAgICByZXR1cm4gdW5zYWZlX21hcmtVcGRhdGVMYW5lRnJvbUZpYmVyVG9Sb290KGZpYmVyLCBsYW5lKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZW5xdWV1ZUNvbmN1cnJlbnRDbGFzc1VwZGF0ZShmaWJlciwgc2hhcmVkUXVldWUsIHVwZGF0ZSwgbGFuZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVudGFuZ2xlVHJhbnNpdGlvbnMocm9vdCwgZmliZXIsIGxhbmUpIHtcbiAgdmFyIHVwZGF0ZVF1ZXVlID0gZmliZXIudXBkYXRlUXVldWU7XG5cbiAgaWYgKHVwZGF0ZVF1ZXVlID09PSBudWxsKSB7XG4gICAgLy8gT25seSBvY2N1cnMgaWYgdGhlIGZpYmVyIGhhcyBiZWVuIHVubW91bnRlZC5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgc2hhcmVkUXVldWUgPSB1cGRhdGVRdWV1ZS5zaGFyZWQ7XG5cbiAgaWYgKGlzVHJhbnNpdGlvbkxhbmUobGFuZSkpIHtcbiAgICB2YXIgcXVldWVMYW5lcyA9IHNoYXJlZFF1ZXVlLmxhbmVzOyAvLyBJZiBhbnkgZW50YW5nbGVkIGxhbmVzIGFyZSBubyBsb25nZXIgcGVuZGluZyBvbiB0aGUgcm9vdCwgdGhlbiB0aGV5IG11c3RcbiAgICAvLyBoYXZlIGZpbmlzaGVkLiBXZSBjYW4gcmVtb3ZlIHRoZW0gZnJvbSB0aGUgc2hhcmVkIHF1ZXVlLCB3aGljaCByZXByZXNlbnRzXG4gICAgLy8gYSBzdXBlcnNldCBvZiB0aGUgYWN0dWFsbHkgcGVuZGluZyBsYW5lcy4gSW4gc29tZSBjYXNlcyB3ZSBtYXkgZW50YW5nbGVcbiAgICAvLyBtb3JlIHRoYW4gd2UgbmVlZCB0bywgYnV0IHRoYXQncyBPSy4gSW4gZmFjdCBpdCdzIHdvcnNlIGlmIHdlICpkb24ndCpcbiAgICAvLyBlbnRhbmdsZSB3aGVuIHdlIHNob3VsZC5cblxuICAgIHF1ZXVlTGFuZXMgPSBpbnRlcnNlY3RMYW5lcyhxdWV1ZUxhbmVzLCByb290LnBlbmRpbmdMYW5lcyk7IC8vIEVudGFuZ2xlIHRoZSBuZXcgdHJhbnNpdGlvbiBsYW5lIHdpdGggdGhlIG90aGVyIHRyYW5zaXRpb24gbGFuZXMuXG5cbiAgICB2YXIgbmV3UXVldWVMYW5lcyA9IG1lcmdlTGFuZXMocXVldWVMYW5lcywgbGFuZSk7XG4gICAgc2hhcmVkUXVldWUubGFuZXMgPSBuZXdRdWV1ZUxhbmVzOyAvLyBFdmVuIGlmIHF1ZXVlLmxhbmVzIGFscmVhZHkgaW5jbHVkZSBsYW5lLCB3ZSBkb24ndCBrbm93IGZvciBjZXJ0YWluIGlmXG4gICAgLy8gdGhlIGxhbmUgZmluaXNoZWQgc2luY2UgdGhlIGxhc3QgdGltZSB3ZSBlbnRhbmdsZWQgaXQuIFNvIHdlIG5lZWQgdG9cbiAgICAvLyBlbnRhbmdsZSBpdCBhZ2FpbiwganVzdCB0byBiZSBzdXJlLlxuXG4gICAgbWFya1Jvb3RFbnRhbmdsZWQocm9vdCwgbmV3UXVldWVMYW5lcyk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVucXVldWVDYXB0dXJlZFVwZGF0ZSh3b3JrSW5Qcm9ncmVzcywgY2FwdHVyZWRVcGRhdGUpIHtcbiAgLy8gQ2FwdHVyZWQgdXBkYXRlcyBhcmUgdXBkYXRlcyB0aGF0IGFyZSB0aHJvd24gYnkgYSBjaGlsZCBkdXJpbmcgdGhlIHJlbmRlclxuICAvLyBwaGFzZS4gVGhleSBzaG91bGQgYmUgZGlzY2FyZGVkIGlmIHRoZSByZW5kZXIgaXMgYWJvcnRlZC4gVGhlcmVmb3JlLFxuICAvLyB3ZSBzaG91bGQgb25seSBwdXQgdGhlbSBvbiB0aGUgd29yay1pbi1wcm9ncmVzcyBxdWV1ZSwgbm90IHRoZSBjdXJyZW50IG9uZS5cbiAgdmFyIHF1ZXVlID0gd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWU7IC8vIENoZWNrIGlmIHRoZSB3b3JrLWluLXByb2dyZXNzIHF1ZXVlIGlzIGEgY2xvbmUuXG5cbiAgdmFyIGN1cnJlbnQgPSB3b3JrSW5Qcm9ncmVzcy5hbHRlcm5hdGU7XG5cbiAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICB2YXIgY3VycmVudFF1ZXVlID0gY3VycmVudC51cGRhdGVRdWV1ZTtcblxuICAgIGlmIChxdWV1ZSA9PT0gY3VycmVudFF1ZXVlKSB7XG4gICAgICAvLyBUaGUgd29yay1pbi1wcm9ncmVzcyBxdWV1ZSBpcyB0aGUgc2FtZSBhcyBjdXJyZW50LiBUaGlzIGhhcHBlbnMgd2hlblxuICAgICAgLy8gd2UgYmFpbCBvdXQgb24gYSBwYXJlbnQgZmliZXIgdGhhdCB0aGVuIGNhcHR1cmVzIGFuIGVycm9yIHRocm93biBieVxuICAgICAgLy8gYSBjaGlsZC4gU2luY2Ugd2Ugd2FudCB0byBhcHBlbmQgdGhlIHVwZGF0ZSBvbmx5IHRvIHRoZSB3b3JrLWluXG4gICAgICAvLyAtcHJvZ3Jlc3MgcXVldWUsIHdlIG5lZWQgdG8gY2xvbmUgdGhlIHVwZGF0ZXMuIFdlIHVzdWFsbHkgY2xvbmUgZHVyaW5nXG4gICAgICAvLyBwcm9jZXNzVXBkYXRlUXVldWUsIGJ1dCB0aGF0IGRpZG4ndCBoYXBwZW4gaW4gdGhpcyBjYXNlIGJlY2F1c2Ugd2VcbiAgICAgIC8vIHNraXBwZWQgb3ZlciB0aGUgcGFyZW50IHdoZW4gd2UgYmFpbGVkIG91dC5cbiAgICAgIHZhciBuZXdGaXJzdCA9IG51bGw7XG4gICAgICB2YXIgbmV3TGFzdCA9IG51bGw7XG4gICAgICB2YXIgZmlyc3RCYXNlVXBkYXRlID0gcXVldWUuZmlyc3RCYXNlVXBkYXRlO1xuXG4gICAgICBpZiAoZmlyc3RCYXNlVXBkYXRlICE9PSBudWxsKSB7XG4gICAgICAgIC8vIExvb3AgdGhyb3VnaCB0aGUgdXBkYXRlcyBhbmQgY2xvbmUgdGhlbS5cbiAgICAgICAgdmFyIHVwZGF0ZSA9IGZpcnN0QmFzZVVwZGF0ZTtcblxuICAgICAgICBkbyB7XG4gICAgICAgICAgdmFyIGNsb25lID0ge1xuICAgICAgICAgICAgZXZlbnRUaW1lOiB1cGRhdGUuZXZlbnRUaW1lLFxuICAgICAgICAgICAgbGFuZTogdXBkYXRlLmxhbmUsXG4gICAgICAgICAgICB0YWc6IHVwZGF0ZS50YWcsXG4gICAgICAgICAgICBwYXlsb2FkOiB1cGRhdGUucGF5bG9hZCxcbiAgICAgICAgICAgIGNhbGxiYWNrOiB1cGRhdGUuY2FsbGJhY2ssXG4gICAgICAgICAgICBuZXh0OiBudWxsXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGlmIChuZXdMYXN0ID09PSBudWxsKSB7XG4gICAgICAgICAgICBuZXdGaXJzdCA9IG5ld0xhc3QgPSBjbG9uZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3TGFzdC5uZXh0ID0gY2xvbmU7XG4gICAgICAgICAgICBuZXdMYXN0ID0gY2xvbmU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdXBkYXRlID0gdXBkYXRlLm5leHQ7XG4gICAgICAgIH0gd2hpbGUgKHVwZGF0ZSAhPT0gbnVsbCk7IC8vIEFwcGVuZCB0aGUgY2FwdHVyZWQgdXBkYXRlIHRoZSBlbmQgb2YgdGhlIGNsb25lZCBsaXN0LlxuXG5cbiAgICAgICAgaWYgKG5ld0xhc3QgPT09IG51bGwpIHtcbiAgICAgICAgICBuZXdGaXJzdCA9IG5ld0xhc3QgPSBjYXB0dXJlZFVwZGF0ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdMYXN0Lm5leHQgPSBjYXB0dXJlZFVwZGF0ZTtcbiAgICAgICAgICBuZXdMYXN0ID0gY2FwdHVyZWRVcGRhdGU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRoZXJlIGFyZSBubyBiYXNlIHVwZGF0ZXMuXG4gICAgICAgIG5ld0ZpcnN0ID0gbmV3TGFzdCA9IGNhcHR1cmVkVXBkYXRlO1xuICAgICAgfVxuXG4gICAgICBxdWV1ZSA9IHtcbiAgICAgICAgYmFzZVN0YXRlOiBjdXJyZW50UXVldWUuYmFzZVN0YXRlLFxuICAgICAgICBmaXJzdEJhc2VVcGRhdGU6IG5ld0ZpcnN0LFxuICAgICAgICBsYXN0QmFzZVVwZGF0ZTogbmV3TGFzdCxcbiAgICAgICAgc2hhcmVkOiBjdXJyZW50UXVldWUuc2hhcmVkLFxuICAgICAgICBlZmZlY3RzOiBjdXJyZW50UXVldWUuZWZmZWN0c1xuICAgICAgfTtcbiAgICAgIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gcXVldWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9IC8vIEFwcGVuZCB0aGUgdXBkYXRlIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3QuXG5cblxuICB2YXIgbGFzdEJhc2VVcGRhdGUgPSBxdWV1ZS5sYXN0QmFzZVVwZGF0ZTtcblxuICBpZiAobGFzdEJhc2VVcGRhdGUgPT09IG51bGwpIHtcbiAgICBxdWV1ZS5maXJzdEJhc2VVcGRhdGUgPSBjYXB0dXJlZFVwZGF0ZTtcbiAgfSBlbHNlIHtcbiAgICBsYXN0QmFzZVVwZGF0ZS5uZXh0ID0gY2FwdHVyZWRVcGRhdGU7XG4gIH1cblxuICBxdWV1ZS5sYXN0QmFzZVVwZGF0ZSA9IGNhcHR1cmVkVXBkYXRlO1xufVxuXG5mdW5jdGlvbiBnZXRTdGF0ZUZyb21VcGRhdGUod29ya0luUHJvZ3Jlc3MsIHF1ZXVlLCB1cGRhdGUsIHByZXZTdGF0ZSwgbmV4dFByb3BzLCBpbnN0YW5jZSkge1xuICBzd2l0Y2ggKHVwZGF0ZS50YWcpIHtcbiAgICBjYXNlIFJlcGxhY2VTdGF0ZTpcbiAgICAgIHtcbiAgICAgICAgdmFyIHBheWxvYWQgPSB1cGRhdGUucGF5bG9hZDtcblxuICAgICAgICBpZiAodHlwZW9mIHBheWxvYWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAvLyBVcGRhdGVyIGZ1bmN0aW9uXG4gICAgICAgICAge1xuICAgICAgICAgICAgZW50ZXJEaXNhbGxvd2VkQ29udGV4dFJlYWRJbkRFVigpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBuZXh0U3RhdGUgPSBwYXlsb2FkLmNhbGwoaW5zdGFuY2UsIHByZXZTdGF0ZSwgbmV4dFByb3BzKTtcblxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgICAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHModHJ1ZSk7XG5cbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBwYXlsb2FkLmNhbGwoaW5zdGFuY2UsIHByZXZTdGF0ZSwgbmV4dFByb3BzKTtcbiAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICBzZXRJc1N0cmljdE1vZGVGb3JEZXZ0b29scyhmYWxzZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZXhpdERpc2FsbG93ZWRDb250ZXh0UmVhZEluREVWKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIG5leHRTdGF0ZTtcbiAgICAgICAgfSAvLyBTdGF0ZSBvYmplY3RcblxuXG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgfVxuXG4gICAgY2FzZSBDYXB0dXJlVXBkYXRlOlxuICAgICAge1xuICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyA9IHdvcmtJblByb2dyZXNzLmZsYWdzICYgflNob3VsZENhcHR1cmUgfCBEaWRDYXB0dXJlO1xuICAgICAgfVxuICAgIC8vIEludGVudGlvbmFsIGZhbGx0aHJvdWdoXG5cbiAgICBjYXNlIFVwZGF0ZVN0YXRlOlxuICAgICAge1xuICAgICAgICB2YXIgX3BheWxvYWQgPSB1cGRhdGUucGF5bG9hZDtcbiAgICAgICAgdmFyIHBhcnRpYWxTdGF0ZTtcblxuICAgICAgICBpZiAodHlwZW9mIF9wYXlsb2FkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgLy8gVXBkYXRlciBmdW5jdGlvblxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGVudGVyRGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBwYXJ0aWFsU3RhdGUgPSBfcGF5bG9hZC5jYWxsKGluc3RhbmNlLCBwcmV2U3RhdGUsIG5leHRQcm9wcyk7XG5cbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZiAoIHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICAgICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgX3BheWxvYWQuY2FsbChpbnN0YW5jZSwgcHJldlN0YXRlLCBuZXh0UHJvcHMpO1xuICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKGZhbHNlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBleGl0RGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gUGFydGlhbCBzdGF0ZSBvYmplY3RcbiAgICAgICAgICBwYXJ0aWFsU3RhdGUgPSBfcGF5bG9hZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0aWFsU3RhdGUgPT09IG51bGwgfHwgcGFydGlhbFN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyBOdWxsIGFuZCB1bmRlZmluZWQgYXJlIHRyZWF0ZWQgYXMgbm8tb3BzLlxuICAgICAgICAgIHJldHVybiBwcmV2U3RhdGU7XG4gICAgICAgIH0gLy8gTWVyZ2UgdGhlIHBhcnRpYWwgc3RhdGUgYW5kIHRoZSBwcmV2aW91cyBzdGF0ZS5cblxuXG4gICAgICAgIHJldHVybiBhc3NpZ24oe30sIHByZXZTdGF0ZSwgcGFydGlhbFN0YXRlKTtcbiAgICAgIH1cblxuICAgIGNhc2UgRm9yY2VVcGRhdGU6XG4gICAgICB7XG4gICAgICAgIGhhc0ZvcmNlVXBkYXRlID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHByZXZTdGF0ZTtcbiAgICAgIH1cbiAgfVxuXG4gIHJldHVybiBwcmV2U3RhdGU7XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NVcGRhdGVRdWV1ZSh3b3JrSW5Qcm9ncmVzcywgcHJvcHMsIGluc3RhbmNlLCByZW5kZXJMYW5lcykge1xuICAvLyBUaGlzIGlzIGFsd2F5cyBub24tbnVsbCBvbiBhIENsYXNzQ29tcG9uZW50IG9yIEhvc3RSb290XG4gIHZhciBxdWV1ZSA9IHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlO1xuICBoYXNGb3JjZVVwZGF0ZSA9IGZhbHNlO1xuXG4gIHtcbiAgICBjdXJyZW50bHlQcm9jZXNzaW5nUXVldWUgPSBxdWV1ZS5zaGFyZWQ7XG4gIH1cblxuICB2YXIgZmlyc3RCYXNlVXBkYXRlID0gcXVldWUuZmlyc3RCYXNlVXBkYXRlO1xuICB2YXIgbGFzdEJhc2VVcGRhdGUgPSBxdWV1ZS5sYXN0QmFzZVVwZGF0ZTsgLy8gQ2hlY2sgaWYgdGhlcmUgYXJlIHBlbmRpbmcgdXBkYXRlcy4gSWYgc28sIHRyYW5zZmVyIHRoZW0gdG8gdGhlIGJhc2UgcXVldWUuXG5cbiAgdmFyIHBlbmRpbmdRdWV1ZSA9IHF1ZXVlLnNoYXJlZC5wZW5kaW5nO1xuXG4gIGlmIChwZW5kaW5nUXVldWUgIT09IG51bGwpIHtcbiAgICBxdWV1ZS5zaGFyZWQucGVuZGluZyA9IG51bGw7IC8vIFRoZSBwZW5kaW5nIHF1ZXVlIGlzIGNpcmN1bGFyLiBEaXNjb25uZWN0IHRoZSBwb2ludGVyIGJldHdlZW4gZmlyc3RcbiAgICAvLyBhbmQgbGFzdCBzbyB0aGF0IGl0J3Mgbm9uLWNpcmN1bGFyLlxuXG4gICAgdmFyIGxhc3RQZW5kaW5nVXBkYXRlID0gcGVuZGluZ1F1ZXVlO1xuICAgIHZhciBmaXJzdFBlbmRpbmdVcGRhdGUgPSBsYXN0UGVuZGluZ1VwZGF0ZS5uZXh0O1xuICAgIGxhc3RQZW5kaW5nVXBkYXRlLm5leHQgPSBudWxsOyAvLyBBcHBlbmQgcGVuZGluZyB1cGRhdGVzIHRvIGJhc2UgcXVldWVcblxuICAgIGlmIChsYXN0QmFzZVVwZGF0ZSA9PT0gbnVsbCkge1xuICAgICAgZmlyc3RCYXNlVXBkYXRlID0gZmlyc3RQZW5kaW5nVXBkYXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICBsYXN0QmFzZVVwZGF0ZS5uZXh0ID0gZmlyc3RQZW5kaW5nVXBkYXRlO1xuICAgIH1cblxuICAgIGxhc3RCYXNlVXBkYXRlID0gbGFzdFBlbmRpbmdVcGRhdGU7IC8vIElmIHRoZXJlJ3MgYSBjdXJyZW50IHF1ZXVlLCBhbmQgaXQncyBkaWZmZXJlbnQgZnJvbSB0aGUgYmFzZSBxdWV1ZSwgdGhlblxuICAgIC8vIHdlIG5lZWQgdG8gdHJhbnNmZXIgdGhlIHVwZGF0ZXMgdG8gdGhhdCBxdWV1ZSwgdG9vLiBCZWNhdXNlIHRoZSBiYXNlXG4gICAgLy8gcXVldWUgaXMgYSBzaW5nbHktbGlua2VkIGxpc3Qgd2l0aCBubyBjeWNsZXMsIHdlIGNhbiBhcHBlbmQgdG8gYm90aFxuICAgIC8vIGxpc3RzIGFuZCB0YWtlIGFkdmFudGFnZSBvZiBzdHJ1Y3R1cmFsIHNoYXJpbmcuXG4gICAgLy8gVE9ETzogUGFzcyBgY3VycmVudGAgYXMgYXJndW1lbnRcblxuICAgIHZhciBjdXJyZW50ID0gd29ya0luUHJvZ3Jlc3MuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgIC8vIFRoaXMgaXMgYWx3YXlzIG5vbi1udWxsIG9uIGEgQ2xhc3NDb21wb25lbnQgb3IgSG9zdFJvb3RcbiAgICAgIHZhciBjdXJyZW50UXVldWUgPSBjdXJyZW50LnVwZGF0ZVF1ZXVlO1xuICAgICAgdmFyIGN1cnJlbnRMYXN0QmFzZVVwZGF0ZSA9IGN1cnJlbnRRdWV1ZS5sYXN0QmFzZVVwZGF0ZTtcblxuICAgICAgaWYgKGN1cnJlbnRMYXN0QmFzZVVwZGF0ZSAhPT0gbGFzdEJhc2VVcGRhdGUpIHtcbiAgICAgICAgaWYgKGN1cnJlbnRMYXN0QmFzZVVwZGF0ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIGN1cnJlbnRRdWV1ZS5maXJzdEJhc2VVcGRhdGUgPSBmaXJzdFBlbmRpbmdVcGRhdGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY3VycmVudExhc3RCYXNlVXBkYXRlLm5leHQgPSBmaXJzdFBlbmRpbmdVcGRhdGU7XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50UXVldWUubGFzdEJhc2VVcGRhdGUgPSBsYXN0UGVuZGluZ1VwZGF0ZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gLy8gVGhlc2UgdmFsdWVzIG1heSBjaGFuZ2UgYXMgd2UgcHJvY2VzcyB0aGUgcXVldWUuXG5cblxuICBpZiAoZmlyc3RCYXNlVXBkYXRlICE9PSBudWxsKSB7XG4gICAgLy8gSXRlcmF0ZSB0aHJvdWdoIHRoZSBsaXN0IG9mIHVwZGF0ZXMgdG8gY29tcHV0ZSB0aGUgcmVzdWx0LlxuICAgIHZhciBuZXdTdGF0ZSA9IHF1ZXVlLmJhc2VTdGF0ZTsgLy8gVE9ETzogRG9uJ3QgbmVlZCB0byBhY2N1bXVsYXRlIHRoaXMuIEluc3RlYWQsIHdlIGNhbiByZW1vdmUgcmVuZGVyTGFuZXNcbiAgICAvLyBmcm9tIHRoZSBvcmlnaW5hbCBsYW5lcy5cblxuICAgIHZhciBuZXdMYW5lcyA9IE5vTGFuZXM7XG4gICAgdmFyIG5ld0Jhc2VTdGF0ZSA9IG51bGw7XG4gICAgdmFyIG5ld0ZpcnN0QmFzZVVwZGF0ZSA9IG51bGw7XG4gICAgdmFyIG5ld0xhc3RCYXNlVXBkYXRlID0gbnVsbDtcbiAgICB2YXIgdXBkYXRlID0gZmlyc3RCYXNlVXBkYXRlO1xuXG4gICAgZG8ge1xuICAgICAgdmFyIHVwZGF0ZUxhbmUgPSB1cGRhdGUubGFuZTtcbiAgICAgIHZhciB1cGRhdGVFdmVudFRpbWUgPSB1cGRhdGUuZXZlbnRUaW1lO1xuXG4gICAgICBpZiAoIWlzU3Vic2V0T2ZMYW5lcyhyZW5kZXJMYW5lcywgdXBkYXRlTGFuZSkpIHtcbiAgICAgICAgLy8gUHJpb3JpdHkgaXMgaW5zdWZmaWNpZW50LiBTa2lwIHRoaXMgdXBkYXRlLiBJZiB0aGlzIGlzIHRoZSBmaXJzdFxuICAgICAgICAvLyBza2lwcGVkIHVwZGF0ZSwgdGhlIHByZXZpb3VzIHVwZGF0ZS9zdGF0ZSBpcyB0aGUgbmV3IGJhc2VcbiAgICAgICAgLy8gdXBkYXRlL3N0YXRlLlxuICAgICAgICB2YXIgY2xvbmUgPSB7XG4gICAgICAgICAgZXZlbnRUaW1lOiB1cGRhdGVFdmVudFRpbWUsXG4gICAgICAgICAgbGFuZTogdXBkYXRlTGFuZSxcbiAgICAgICAgICB0YWc6IHVwZGF0ZS50YWcsXG4gICAgICAgICAgcGF5bG9hZDogdXBkYXRlLnBheWxvYWQsXG4gICAgICAgICAgY2FsbGJhY2s6IHVwZGF0ZS5jYWxsYmFjayxcbiAgICAgICAgICBuZXh0OiBudWxsXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG5ld0xhc3RCYXNlVXBkYXRlID09PSBudWxsKSB7XG4gICAgICAgICAgbmV3Rmlyc3RCYXNlVXBkYXRlID0gbmV3TGFzdEJhc2VVcGRhdGUgPSBjbG9uZTtcbiAgICAgICAgICBuZXdCYXNlU3RhdGUgPSBuZXdTdGF0ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdMYXN0QmFzZVVwZGF0ZSA9IG5ld0xhc3RCYXNlVXBkYXRlLm5leHQgPSBjbG9uZTtcbiAgICAgICAgfSAvLyBVcGRhdGUgdGhlIHJlbWFpbmluZyBwcmlvcml0eSBpbiB0aGUgcXVldWUuXG5cblxuICAgICAgICBuZXdMYW5lcyA9IG1lcmdlTGFuZXMobmV3TGFuZXMsIHVwZGF0ZUxhbmUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVGhpcyB1cGRhdGUgZG9lcyBoYXZlIHN1ZmZpY2llbnQgcHJpb3JpdHkuXG4gICAgICAgIGlmIChuZXdMYXN0QmFzZVVwZGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIHZhciBfY2xvbmUgPSB7XG4gICAgICAgICAgICBldmVudFRpbWU6IHVwZGF0ZUV2ZW50VGltZSxcbiAgICAgICAgICAgIC8vIFRoaXMgdXBkYXRlIGlzIGdvaW5nIHRvIGJlIGNvbW1pdHRlZCBzbyB3ZSBuZXZlciB3YW50IHVuY29tbWl0XG4gICAgICAgICAgICAvLyBpdC4gVXNpbmcgTm9MYW5lIHdvcmtzIGJlY2F1c2UgMCBpcyBhIHN1YnNldCBvZiBhbGwgYml0bWFza3MsIHNvXG4gICAgICAgICAgICAvLyB0aGlzIHdpbGwgbmV2ZXIgYmUgc2tpcHBlZCBieSB0aGUgY2hlY2sgYWJvdmUuXG4gICAgICAgICAgICBsYW5lOiBOb0xhbmUsXG4gICAgICAgICAgICB0YWc6IHVwZGF0ZS50YWcsXG4gICAgICAgICAgICBwYXlsb2FkOiB1cGRhdGUucGF5bG9hZCxcbiAgICAgICAgICAgIGNhbGxiYWNrOiB1cGRhdGUuY2FsbGJhY2ssXG4gICAgICAgICAgICBuZXh0OiBudWxsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBuZXdMYXN0QmFzZVVwZGF0ZSA9IG5ld0xhc3RCYXNlVXBkYXRlLm5leHQgPSBfY2xvbmU7XG4gICAgICAgIH0gLy8gUHJvY2VzcyB0aGlzIHVwZGF0ZS5cblxuXG4gICAgICAgIG5ld1N0YXRlID0gZ2V0U3RhdGVGcm9tVXBkYXRlKHdvcmtJblByb2dyZXNzLCBxdWV1ZSwgdXBkYXRlLCBuZXdTdGF0ZSwgcHJvcHMsIGluc3RhbmNlKTtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gdXBkYXRlLmNhbGxiYWNrO1xuXG4gICAgICAgIGlmIChjYWxsYmFjayAhPT0gbnVsbCAmJiAvLyBJZiB0aGUgdXBkYXRlIHdhcyBhbHJlYWR5IGNvbW1pdHRlZCwgd2Ugc2hvdWxkIG5vdCBxdWV1ZSBpdHNcbiAgICAgICAgLy8gY2FsbGJhY2sgYWdhaW4uXG4gICAgICAgIHVwZGF0ZS5sYW5lICE9PSBOb0xhbmUpIHtcbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBDYWxsYmFjaztcbiAgICAgICAgICB2YXIgZWZmZWN0cyA9IHF1ZXVlLmVmZmVjdHM7XG5cbiAgICAgICAgICBpZiAoZWZmZWN0cyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcXVldWUuZWZmZWN0cyA9IFt1cGRhdGVdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlZmZlY3RzLnB1c2godXBkYXRlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdXBkYXRlID0gdXBkYXRlLm5leHQ7XG5cbiAgICAgIGlmICh1cGRhdGUgPT09IG51bGwpIHtcbiAgICAgICAgcGVuZGluZ1F1ZXVlID0gcXVldWUuc2hhcmVkLnBlbmRpbmc7XG5cbiAgICAgICAgaWYgKHBlbmRpbmdRdWV1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEFuIHVwZGF0ZSB3YXMgc2NoZWR1bGVkIGZyb20gaW5zaWRlIGEgcmVkdWNlci4gQWRkIHRoZSBuZXdcbiAgICAgICAgICAvLyBwZW5kaW5nIHVwZGF0ZXMgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdCBhbmQga2VlcCBwcm9jZXNzaW5nLlxuICAgICAgICAgIHZhciBfbGFzdFBlbmRpbmdVcGRhdGUgPSBwZW5kaW5nUXVldWU7IC8vIEludGVudGlvbmFsbHkgdW5zb3VuZC4gUGVuZGluZyB1cGRhdGVzIGZvcm0gYSBjaXJjdWxhciBsaXN0LCBidXQgd2VcbiAgICAgICAgICAvLyB1bnJhdmVsIHRoZW0gd2hlbiB0cmFuc2ZlcnJpbmcgdGhlbSB0byB0aGUgYmFzZSBxdWV1ZS5cblxuICAgICAgICAgIHZhciBfZmlyc3RQZW5kaW5nVXBkYXRlID0gX2xhc3RQZW5kaW5nVXBkYXRlLm5leHQ7XG4gICAgICAgICAgX2xhc3RQZW5kaW5nVXBkYXRlLm5leHQgPSBudWxsO1xuICAgICAgICAgIHVwZGF0ZSA9IF9maXJzdFBlbmRpbmdVcGRhdGU7XG4gICAgICAgICAgcXVldWUubGFzdEJhc2VVcGRhdGUgPSBfbGFzdFBlbmRpbmdVcGRhdGU7XG4gICAgICAgICAgcXVldWUuc2hhcmVkLnBlbmRpbmcgPSBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSB3aGlsZSAodHJ1ZSk7XG5cbiAgICBpZiAobmV3TGFzdEJhc2VVcGRhdGUgPT09IG51bGwpIHtcbiAgICAgIG5ld0Jhc2VTdGF0ZSA9IG5ld1N0YXRlO1xuICAgIH1cblxuICAgIHF1ZXVlLmJhc2VTdGF0ZSA9IG5ld0Jhc2VTdGF0ZTtcbiAgICBxdWV1ZS5maXJzdEJhc2VVcGRhdGUgPSBuZXdGaXJzdEJhc2VVcGRhdGU7XG4gICAgcXVldWUubGFzdEJhc2VVcGRhdGUgPSBuZXdMYXN0QmFzZVVwZGF0ZTsgLy8gSW50ZXJsZWF2ZWQgdXBkYXRlcyBhcmUgc3RvcmVkIG9uIGEgc2VwYXJhdGUgcXVldWUuIFdlIGFyZW4ndCBnb2luZyB0b1xuICAgIC8vIHByb2Nlc3MgdGhlbSBkdXJpbmcgdGhpcyByZW5kZXIsIGJ1dCB3ZSBkbyBuZWVkIHRvIHRyYWNrIHdoaWNoIGxhbmVzXG4gICAgLy8gYXJlIHJlbWFpbmluZy5cblxuICAgIHZhciBsYXN0SW50ZXJsZWF2ZWQgPSBxdWV1ZS5zaGFyZWQuaW50ZXJsZWF2ZWQ7XG5cbiAgICBpZiAobGFzdEludGVybGVhdmVkICE9PSBudWxsKSB7XG4gICAgICB2YXIgaW50ZXJsZWF2ZWQgPSBsYXN0SW50ZXJsZWF2ZWQ7XG5cbiAgICAgIGRvIHtcbiAgICAgICAgbmV3TGFuZXMgPSBtZXJnZUxhbmVzKG5ld0xhbmVzLCBpbnRlcmxlYXZlZC5sYW5lKTtcbiAgICAgICAgaW50ZXJsZWF2ZWQgPSBpbnRlcmxlYXZlZC5uZXh0O1xuICAgICAgfSB3aGlsZSAoaW50ZXJsZWF2ZWQgIT09IGxhc3RJbnRlcmxlYXZlZCk7XG4gICAgfSBlbHNlIGlmIChmaXJzdEJhc2VVcGRhdGUgPT09IG51bGwpIHtcbiAgICAgIC8vIGBxdWV1ZS5sYW5lc2AgaXMgdXNlZCBmb3IgZW50YW5nbGluZyB0cmFuc2l0aW9ucy4gV2UgY2FuIHNldCBpdCBiYWNrIHRvXG4gICAgICAvLyB6ZXJvIG9uY2UgdGhlIHF1ZXVlIGlzIGVtcHR5LlxuICAgICAgcXVldWUuc2hhcmVkLmxhbmVzID0gTm9MYW5lcztcbiAgICB9IC8vIFNldCB0aGUgcmVtYWluaW5nIGV4cGlyYXRpb24gdGltZSB0byBiZSB3aGF0ZXZlciBpcyByZW1haW5pbmcgaW4gdGhlIHF1ZXVlLlxuICAgIC8vIFRoaXMgc2hvdWxkIGJlIGZpbmUgYmVjYXVzZSB0aGUgb25seSB0d28gb3RoZXIgdGhpbmdzIHRoYXQgY29udHJpYnV0ZSB0b1xuICAgIC8vIGV4cGlyYXRpb24gdGltZSBhcmUgcHJvcHMgYW5kIGNvbnRleHQuIFdlJ3JlIGFscmVhZHkgaW4gdGhlIG1pZGRsZSBvZiB0aGVcbiAgICAvLyBiZWdpbiBwaGFzZSBieSB0aGUgdGltZSB3ZSBzdGFydCBwcm9jZXNzaW5nIHRoZSBxdWV1ZSwgc28gd2UndmUgYWxyZWFkeVxuICAgIC8vIGRlYWx0IHdpdGggdGhlIHByb3BzLiBDb250ZXh0IGluIGNvbXBvbmVudHMgdGhhdCBzcGVjaWZ5XG4gICAgLy8gc2hvdWxkQ29tcG9uZW50VXBkYXRlIGlzIHRyaWNreTsgYnV0IHdlJ2xsIGhhdmUgdG8gYWNjb3VudCBmb3JcbiAgICAvLyB0aGF0IHJlZ2FyZGxlc3MuXG5cblxuICAgIG1hcmtTa2lwcGVkVXBkYXRlTGFuZXMobmV3TGFuZXMpO1xuICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gbmV3TGFuZXM7XG4gICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG5ld1N0YXRlO1xuICB9XG5cbiAge1xuICAgIGN1cnJlbnRseVByb2Nlc3NpbmdRdWV1ZSA9IG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2FsbENhbGxiYWNrKGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYXJndW1lbnQgcGFzc2VkIGFzIGNhbGxiYWNrLiBFeHBlY3RlZCBhIGZ1bmN0aW9uLiBJbnN0ZWFkICcgKyAoXCJyZWNlaXZlZDogXCIgKyBjYWxsYmFjaykpO1xuICB9XG5cbiAgY2FsbGJhY2suY2FsbChjb250ZXh0KTtcbn1cblxuZnVuY3Rpb24gcmVzZXRIYXNGb3JjZVVwZGF0ZUJlZm9yZVByb2Nlc3NpbmcoKSB7XG4gIGhhc0ZvcmNlVXBkYXRlID0gZmFsc2U7XG59XG5mdW5jdGlvbiBjaGVja0hhc0ZvcmNlVXBkYXRlQWZ0ZXJQcm9jZXNzaW5nKCkge1xuICByZXR1cm4gaGFzRm9yY2VVcGRhdGU7XG59XG5mdW5jdGlvbiBjb21taXRVcGRhdGVRdWV1ZShmaW5pc2hlZFdvcmssIGZpbmlzaGVkUXVldWUsIGluc3RhbmNlKSB7XG4gIC8vIENvbW1pdCB0aGUgZWZmZWN0c1xuICB2YXIgZWZmZWN0cyA9IGZpbmlzaGVkUXVldWUuZWZmZWN0cztcbiAgZmluaXNoZWRRdWV1ZS5lZmZlY3RzID0gbnVsbDtcblxuICBpZiAoZWZmZWN0cyAhPT0gbnVsbCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWZmZWN0cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGVmZmVjdCA9IGVmZmVjdHNbaV07XG4gICAgICB2YXIgY2FsbGJhY2sgPSBlZmZlY3QuY2FsbGJhY2s7XG5cbiAgICAgIGlmIChjYWxsYmFjayAhPT0gbnVsbCkge1xuICAgICAgICBlZmZlY3QuY2FsbGJhY2sgPSBudWxsO1xuICAgICAgICBjYWxsQ2FsbGJhY2soY2FsbGJhY2ssIGluc3RhbmNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIGZha2VJbnRlcm5hbEluc3RhbmNlID0ge307IC8vIFJlYWN0LkNvbXBvbmVudCB1c2VzIGEgc2hhcmVkIGZyb3plbiBvYmplY3QgYnkgZGVmYXVsdC5cbi8vIFdlJ2xsIHVzZSBpdCB0byBkZXRlcm1pbmUgd2hldGhlciB3ZSBuZWVkIHRvIGluaXRpYWxpemUgbGVnYWN5IHJlZnMuXG5cbnZhciBlbXB0eVJlZnNPYmplY3QgPSBuZXcgUmVhY3QuQ29tcG9uZW50KCkucmVmcztcbnZhciBkaWRXYXJuQWJvdXRTdGF0ZUFzc2lnbm1lbnRGb3JDb21wb25lbnQ7XG52YXIgZGlkV2FybkFib3V0VW5pbml0aWFsaXplZFN0YXRlO1xudmFyIGRpZFdhcm5BYm91dEdldFNuYXBzaG90QmVmb3JlVXBkYXRlV2l0aG91dERpZFVwZGF0ZTtcbnZhciBkaWRXYXJuQWJvdXRMZWdhY3lMaWZlY3ljbGVzQW5kRGVyaXZlZFN0YXRlO1xudmFyIGRpZFdhcm5BYm91dFVuZGVmaW5lZERlcml2ZWRTdGF0ZTtcbnZhciB3YXJuT25VbmRlZmluZWREZXJpdmVkU3RhdGU7XG52YXIgd2Fybk9uSW52YWxpZENhbGxiYWNrO1xudmFyIGRpZFdhcm5BYm91dERpcmVjdGx5QXNzaWduaW5nUHJvcHNUb1N0YXRlO1xudmFyIGRpZFdhcm5BYm91dENvbnRleHRUeXBlQW5kQ29udGV4dFR5cGVzO1xudmFyIGRpZFdhcm5BYm91dEludmFsaWRhdGVDb250ZXh0VHlwZTtcblxue1xuICBkaWRXYXJuQWJvdXRTdGF0ZUFzc2lnbm1lbnRGb3JDb21wb25lbnQgPSBuZXcgU2V0KCk7XG4gIGRpZFdhcm5BYm91dFVuaW5pdGlhbGl6ZWRTdGF0ZSA9IG5ldyBTZXQoKTtcbiAgZGlkV2FybkFib3V0R2V0U25hcHNob3RCZWZvcmVVcGRhdGVXaXRob3V0RGlkVXBkYXRlID0gbmV3IFNldCgpO1xuICBkaWRXYXJuQWJvdXRMZWdhY3lMaWZlY3ljbGVzQW5kRGVyaXZlZFN0YXRlID0gbmV3IFNldCgpO1xuICBkaWRXYXJuQWJvdXREaXJlY3RseUFzc2lnbmluZ1Byb3BzVG9TdGF0ZSA9IG5ldyBTZXQoKTtcbiAgZGlkV2FybkFib3V0VW5kZWZpbmVkRGVyaXZlZFN0YXRlID0gbmV3IFNldCgpO1xuICBkaWRXYXJuQWJvdXRDb250ZXh0VHlwZUFuZENvbnRleHRUeXBlcyA9IG5ldyBTZXQoKTtcbiAgZGlkV2FybkFib3V0SW52YWxpZGF0ZUNvbnRleHRUeXBlID0gbmV3IFNldCgpO1xuICB2YXIgZGlkV2Fybk9uSW52YWxpZENhbGxiYWNrID0gbmV3IFNldCgpO1xuXG4gIHdhcm5PbkludmFsaWRDYWxsYmFjayA9IGZ1bmN0aW9uIChjYWxsYmFjaywgY2FsbGVyTmFtZSkge1xuICAgIGlmIChjYWxsYmFjayA9PT0gbnVsbCB8fCB0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIga2V5ID0gY2FsbGVyTmFtZSArICdfJyArIGNhbGxiYWNrO1xuXG4gICAgaWYgKCFkaWRXYXJuT25JbnZhbGlkQ2FsbGJhY2suaGFzKGtleSkpIHtcbiAgICAgIGRpZFdhcm5PbkludmFsaWRDYWxsYmFjay5hZGQoa2V5KTtcblxuICAgICAgZXJyb3IoJyVzKC4uLik6IEV4cGVjdGVkIHRoZSBsYXN0IG9wdGlvbmFsIGBjYWxsYmFja2AgYXJndW1lbnQgdG8gYmUgYSAnICsgJ2Z1bmN0aW9uLiBJbnN0ZWFkIHJlY2VpdmVkOiAlcy4nLCBjYWxsZXJOYW1lLCBjYWxsYmFjayk7XG4gICAgfVxuICB9O1xuXG4gIHdhcm5PblVuZGVmaW5lZERlcml2ZWRTdGF0ZSA9IGZ1bmN0aW9uICh0eXBlLCBwYXJ0aWFsU3RhdGUpIHtcbiAgICBpZiAocGFydGlhbFN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhciBjb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKHR5cGUpIHx8ICdDb21wb25lbnQnO1xuXG4gICAgICBpZiAoIWRpZFdhcm5BYm91dFVuZGVmaW5lZERlcml2ZWRTdGF0ZS5oYXMoY29tcG9uZW50TmFtZSkpIHtcbiAgICAgICAgZGlkV2FybkFib3V0VW5kZWZpbmVkRGVyaXZlZFN0YXRlLmFkZChjb21wb25lbnROYW1lKTtcblxuICAgICAgICBlcnJvcignJXMuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzKCk6IEEgdmFsaWQgc3RhdGUgb2JqZWN0IChvciBudWxsKSBtdXN0IGJlIHJldHVybmVkLiAnICsgJ1lvdSBoYXZlIHJldHVybmVkIHVuZGVmaW5lZC4nLCBjb21wb25lbnROYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH07IC8vIFRoaXMgaXMgc28gZ3Jvc3MgYnV0IGl0J3MgYXQgbGVhc3Qgbm9uLWNyaXRpY2FsIGFuZCBjYW4gYmUgcmVtb3ZlZCBpZlxuICAvLyBpdCBjYXVzZXMgcHJvYmxlbXMuIFRoaXMgaXMgbWVhbnQgdG8gZ2l2ZSBhIG5pY2VyIGVycm9yIG1lc3NhZ2UgZm9yXG4gIC8vIFJlYWN0RE9NMTUudW5zdGFibGVfcmVuZGVyU3VidHJlZUludG9Db250YWluZXIocmVhY3RET00xNkNvbXBvbmVudCxcbiAgLy8gLi4uKSkgd2hpY2ggb3RoZXJ3aXNlIHRocm93cyBhIFwiX3Byb2Nlc3NDaGlsZENvbnRleHQgaXMgbm90IGEgZnVuY3Rpb25cIlxuICAvLyBleGNlcHRpb24uXG5cblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZmFrZUludGVybmFsSW5zdGFuY2UsICdfcHJvY2Vzc0NoaWxkQ29udGV4dCcsIHtcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdfcHJvY2Vzc0NoaWxkQ29udGV4dCBpcyBub3QgYXZhaWxhYmxlIGluIFJlYWN0IDE2Ky4gVGhpcyBsaWtlbHkgJyArICdtZWFucyB5b3UgaGF2ZSBtdWx0aXBsZSBjb3BpZXMgb2YgUmVhY3QgYW5kIGFyZSBhdHRlbXB0aW5nIHRvIG5lc3QgJyArICdhIFJlYWN0IDE1IHRyZWUgaW5zaWRlIGEgUmVhY3QgMTYgdHJlZSB1c2luZyAnICsgXCJ1bnN0YWJsZV9yZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lciwgd2hpY2ggaXNuJ3Qgc3VwcG9ydGVkLiBUcnkgXCIgKyAndG8gbWFrZSBzdXJlIHlvdSBoYXZlIG9ubHkgb25lIGNvcHkgb2YgUmVhY3QgKGFuZCBpZGVhbGx5LCBzd2l0Y2ggJyArICd0byBSZWFjdERPTS5jcmVhdGVQb3J0YWwpLicpO1xuICAgIH1cbiAgfSk7XG4gIE9iamVjdC5mcmVlemUoZmFrZUludGVybmFsSW5zdGFuY2UpO1xufVxuXG5mdW5jdGlvbiBhcHBseURlcml2ZWRTdGF0ZUZyb21Qcm9wcyh3b3JrSW5Qcm9ncmVzcywgY3RvciwgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzLCBuZXh0UHJvcHMpIHtcbiAgdmFyIHByZXZTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG4gIHZhciBwYXJ0aWFsU3RhdGUgPSBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMobmV4dFByb3BzLCBwcmV2U3RhdGUpO1xuXG4gIHtcbiAgICBpZiAoIHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICBzZXRJc1N0cmljdE1vZGVGb3JEZXZ0b29scyh0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gSW52b2tlIHRoZSBmdW5jdGlvbiBhbiBleHRyYSB0aW1lIHRvIGhlbHAgZGV0ZWN0IHNpZGUtZWZmZWN0cy5cbiAgICAgICAgcGFydGlhbFN0YXRlID0gZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzKG5leHRQcm9wcywgcHJldlN0YXRlKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB3YXJuT25VbmRlZmluZWREZXJpdmVkU3RhdGUoY3RvciwgcGFydGlhbFN0YXRlKTtcbiAgfSAvLyBNZXJnZSB0aGUgcGFydGlhbCBzdGF0ZSBhbmQgdGhlIHByZXZpb3VzIHN0YXRlLlxuXG5cbiAgdmFyIG1lbW9pemVkU3RhdGUgPSBwYXJ0aWFsU3RhdGUgPT09IG51bGwgfHwgcGFydGlhbFN0YXRlID09PSB1bmRlZmluZWQgPyBwcmV2U3RhdGUgOiBhc3NpZ24oe30sIHByZXZTdGF0ZSwgcGFydGlhbFN0YXRlKTtcbiAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG1lbW9pemVkU3RhdGU7IC8vIE9uY2UgdGhlIHVwZGF0ZSBxdWV1ZSBpcyBlbXB0eSwgcGVyc2lzdCB0aGUgZGVyaXZlZCBzdGF0ZSBvbnRvIHRoZVxuICAvLyBiYXNlIHN0YXRlLlxuXG4gIGlmICh3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9PT0gTm9MYW5lcykge1xuICAgIC8vIFF1ZXVlIGlzIGFsd2F5cyBub24tbnVsbCBmb3IgY2xhc3Nlc1xuICAgIHZhciB1cGRhdGVRdWV1ZSA9IHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlO1xuICAgIHVwZGF0ZVF1ZXVlLmJhc2VTdGF0ZSA9IG1lbW9pemVkU3RhdGU7XG4gIH1cbn1cblxudmFyIGNsYXNzQ29tcG9uZW50VXBkYXRlciA9IHtcbiAgaXNNb3VudGVkOiBpc01vdW50ZWQsXG4gIGVucXVldWVTZXRTdGF0ZTogZnVuY3Rpb24gKGluc3QsIHBheWxvYWQsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGZpYmVyID0gZ2V0KGluc3QpO1xuICAgIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gICAgdmFyIGxhbmUgPSByZXF1ZXN0VXBkYXRlTGFuZShmaWJlcik7XG4gICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVVwZGF0ZShldmVudFRpbWUsIGxhbmUpO1xuICAgIHVwZGF0ZS5wYXlsb2FkID0gcGF5bG9hZDtcblxuICAgIGlmIChjYWxsYmFjayAhPT0gdW5kZWZpbmVkICYmIGNhbGxiYWNrICE9PSBudWxsKSB7XG4gICAgICB7XG4gICAgICAgIHdhcm5PbkludmFsaWRDYWxsYmFjayhjYWxsYmFjaywgJ3NldFN0YXRlJyk7XG4gICAgICB9XG5cbiAgICAgIHVwZGF0ZS5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIH1cblxuICAgIHZhciByb290ID0gZW5xdWV1ZVVwZGF0ZShmaWJlciwgdXBkYXRlLCBsYW5lKTtcblxuICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIGxhbmUsIGV2ZW50VGltZSk7XG4gICAgICBlbnRhbmdsZVRyYW5zaXRpb25zKHJvb3QsIGZpYmVyLCBsYW5lKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBtYXJrU3RhdGVVcGRhdGVTY2hlZHVsZWQoZmliZXIsIGxhbmUpO1xuICAgIH1cbiAgfSxcbiAgZW5xdWV1ZVJlcGxhY2VTdGF0ZTogZnVuY3Rpb24gKGluc3QsIHBheWxvYWQsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGZpYmVyID0gZ2V0KGluc3QpO1xuICAgIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gICAgdmFyIGxhbmUgPSByZXF1ZXN0VXBkYXRlTGFuZShmaWJlcik7XG4gICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVVwZGF0ZShldmVudFRpbWUsIGxhbmUpO1xuICAgIHVwZGF0ZS50YWcgPSBSZXBsYWNlU3RhdGU7XG4gICAgdXBkYXRlLnBheWxvYWQgPSBwYXlsb2FkO1xuXG4gICAgaWYgKGNhbGxiYWNrICE9PSB1bmRlZmluZWQgJiYgY2FsbGJhY2sgIT09IG51bGwpIHtcbiAgICAgIHtcbiAgICAgICAgd2Fybk9uSW52YWxpZENhbGxiYWNrKGNhbGxiYWNrLCAncmVwbGFjZVN0YXRlJyk7XG4gICAgICB9XG5cbiAgICAgIHVwZGF0ZS5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIH1cblxuICAgIHZhciByb290ID0gZW5xdWV1ZVVwZGF0ZShmaWJlciwgdXBkYXRlLCBsYW5lKTtcblxuICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIGxhbmUsIGV2ZW50VGltZSk7XG4gICAgICBlbnRhbmdsZVRyYW5zaXRpb25zKHJvb3QsIGZpYmVyLCBsYW5lKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBtYXJrU3RhdGVVcGRhdGVTY2hlZHVsZWQoZmliZXIsIGxhbmUpO1xuICAgIH1cbiAgfSxcbiAgZW5xdWV1ZUZvcmNlVXBkYXRlOiBmdW5jdGlvbiAoaW5zdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgZmliZXIgPSBnZXQoaW5zdCk7XG4gICAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgICB2YXIgbGFuZSA9IHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKTtcbiAgICB2YXIgdXBkYXRlID0gY3JlYXRlVXBkYXRlKGV2ZW50VGltZSwgbGFuZSk7XG4gICAgdXBkYXRlLnRhZyA9IEZvcmNlVXBkYXRlO1xuXG4gICAgaWYgKGNhbGxiYWNrICE9PSB1bmRlZmluZWQgJiYgY2FsbGJhY2sgIT09IG51bGwpIHtcbiAgICAgIHtcbiAgICAgICAgd2Fybk9uSW52YWxpZENhbGxiYWNrKGNhbGxiYWNrLCAnZm9yY2VVcGRhdGUnKTtcbiAgICAgIH1cblxuICAgICAgdXBkYXRlLmNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgfVxuXG4gICAgdmFyIHJvb3QgPSBlbnF1ZXVlVXBkYXRlKGZpYmVyLCB1cGRhdGUsIGxhbmUpO1xuXG4gICAgaWYgKHJvb3QgIT09IG51bGwpIHtcbiAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgbGFuZSwgZXZlbnRUaW1lKTtcbiAgICAgIGVudGFuZ2xlVHJhbnNpdGlvbnMocm9vdCwgZmliZXIsIGxhbmUpO1xuICAgIH1cblxuICAgIHtcbiAgICAgIG1hcmtGb3JjZVVwZGF0ZVNjaGVkdWxlZChmaWJlciwgbGFuZSk7XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiBjaGVja1Nob3VsZENvbXBvbmVudFVwZGF0ZSh3b3JrSW5Qcm9ncmVzcywgY3Rvciwgb2xkUHJvcHMsIG5ld1Byb3BzLCBvbGRTdGF0ZSwgbmV3U3RhdGUsIG5leHRDb250ZXh0KSB7XG4gIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcblxuICBpZiAodHlwZW9mIGluc3RhbmNlLnNob3VsZENvbXBvbmVudFVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHZhciBzaG91bGRVcGRhdGUgPSBpbnN0YW5jZS5zaG91bGRDb21wb25lbnRVcGRhdGUobmV3UHJvcHMsIG5ld1N0YXRlLCBuZXh0Q29udGV4dCk7XG5cbiAgICB7XG4gICAgICBpZiAoIHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gSW52b2tlIHRoZSBmdW5jdGlvbiBhbiBleHRyYSB0aW1lIHRvIGhlbHAgZGV0ZWN0IHNpZGUtZWZmZWN0cy5cbiAgICAgICAgICBzaG91bGRVcGRhdGUgPSBpbnN0YW5jZS5zaG91bGRDb21wb25lbnRVcGRhdGUobmV3UHJvcHMsIG5ld1N0YXRlLCBuZXh0Q29udGV4dCk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChzaG91bGRVcGRhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlcnJvcignJXMuc2hvdWxkQ29tcG9uZW50VXBkYXRlKCk6IFJldHVybmVkIHVuZGVmaW5lZCBpbnN0ZWFkIG9mIGEgJyArICdib29sZWFuIHZhbHVlLiBNYWtlIHN1cmUgdG8gcmV0dXJuIHRydWUgb3IgZmFsc2UuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGN0b3IpIHx8ICdDb21wb25lbnQnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2hvdWxkVXBkYXRlO1xuICB9XG5cbiAgaWYgKGN0b3IucHJvdG90eXBlICYmIGN0b3IucHJvdG90eXBlLmlzUHVyZVJlYWN0Q29tcG9uZW50KSB7XG4gICAgcmV0dXJuICFzaGFsbG93RXF1YWwob2xkUHJvcHMsIG5ld1Byb3BzKSB8fCAhc2hhbGxvd0VxdWFsKG9sZFN0YXRlLCBuZXdTdGF0ZSk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY2hlY2tDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCBjdG9yLCBuZXdQcm9wcykge1xuICB2YXIgaW5zdGFuY2UgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG5cbiAge1xuICAgIHZhciBuYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGN0b3IpIHx8ICdDb21wb25lbnQnO1xuICAgIHZhciByZW5kZXJQcmVzZW50ID0gaW5zdGFuY2UucmVuZGVyO1xuXG4gICAgaWYgKCFyZW5kZXJQcmVzZW50KSB7XG4gICAgICBpZiAoY3Rvci5wcm90b3R5cGUgJiYgdHlwZW9mIGN0b3IucHJvdG90eXBlLnJlbmRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBlcnJvcignJXMoLi4uKTogTm8gYHJlbmRlcmAgbWV0aG9kIGZvdW5kIG9uIHRoZSByZXR1cm5lZCBjb21wb25lbnQgJyArICdpbnN0YW5jZTogZGlkIHlvdSBhY2NpZGVudGFsbHkgcmV0dXJuIGFuIG9iamVjdCBmcm9tIHRoZSBjb25zdHJ1Y3Rvcj8nLCBuYW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yKCclcyguLi4pOiBObyBgcmVuZGVyYCBtZXRob2QgZm91bmQgb24gdGhlIHJldHVybmVkIGNvbXBvbmVudCAnICsgJ2luc3RhbmNlOiB5b3UgbWF5IGhhdmUgZm9yZ290dGVuIHRvIGRlZmluZSBgcmVuZGVyYC4nLCBuYW1lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaW5zdGFuY2UuZ2V0SW5pdGlhbFN0YXRlICYmICFpbnN0YW5jZS5nZXRJbml0aWFsU3RhdGUuaXNSZWFjdENsYXNzQXBwcm92ZWQgJiYgIWluc3RhbmNlLnN0YXRlKSB7XG4gICAgICBlcnJvcignZ2V0SW5pdGlhbFN0YXRlIHdhcyBkZWZpbmVkIG9uICVzLCBhIHBsYWluIEphdmFTY3JpcHQgY2xhc3MuICcgKyAnVGhpcyBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgY2xhc3NlcyBjcmVhdGVkIHVzaW5nIFJlYWN0LmNyZWF0ZUNsYXNzLiAnICsgJ0RpZCB5b3UgbWVhbiB0byBkZWZpbmUgYSBzdGF0ZSBwcm9wZXJ0eSBpbnN0ZWFkPycsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmIChpbnN0YW5jZS5nZXREZWZhdWx0UHJvcHMgJiYgIWluc3RhbmNlLmdldERlZmF1bHRQcm9wcy5pc1JlYWN0Q2xhc3NBcHByb3ZlZCkge1xuICAgICAgZXJyb3IoJ2dldERlZmF1bHRQcm9wcyB3YXMgZGVmaW5lZCBvbiAlcywgYSBwbGFpbiBKYXZhU2NyaXB0IGNsYXNzLiAnICsgJ1RoaXMgaXMgb25seSBzdXBwb3J0ZWQgZm9yIGNsYXNzZXMgY3JlYXRlZCB1c2luZyBSZWFjdC5jcmVhdGVDbGFzcy4gJyArICdVc2UgYSBzdGF0aWMgcHJvcGVydHkgdG8gZGVmaW5lIGRlZmF1bHRQcm9wcyBpbnN0ZWFkLicsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmIChpbnN0YW5jZS5wcm9wVHlwZXMpIHtcbiAgICAgIGVycm9yKCdwcm9wVHlwZXMgd2FzIGRlZmluZWQgYXMgYW4gaW5zdGFuY2UgcHJvcGVydHkgb24gJXMuIFVzZSBhIHN0YXRpYyAnICsgJ3Byb3BlcnR5IHRvIGRlZmluZSBwcm9wVHlwZXMgaW5zdGVhZC4nLCBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoaW5zdGFuY2UuY29udGV4dFR5cGUpIHtcbiAgICAgIGVycm9yKCdjb250ZXh0VHlwZSB3YXMgZGVmaW5lZCBhcyBhbiBpbnN0YW5jZSBwcm9wZXJ0eSBvbiAlcy4gVXNlIGEgc3RhdGljICcgKyAncHJvcGVydHkgdG8gZGVmaW5lIGNvbnRleHRUeXBlIGluc3RlYWQuJywgbmFtZSk7XG4gICAgfVxuXG4gICAge1xuICAgICAgaWYgKGluc3RhbmNlLmNvbnRleHRUeXBlcykge1xuICAgICAgICBlcnJvcignY29udGV4dFR5cGVzIHdhcyBkZWZpbmVkIGFzIGFuIGluc3RhbmNlIHByb3BlcnR5IG9uICVzLiBVc2UgYSBzdGF0aWMgJyArICdwcm9wZXJ0eSB0byBkZWZpbmUgY29udGV4dFR5cGVzIGluc3RlYWQuJywgbmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjdG9yLmNvbnRleHRUeXBlICYmIGN0b3IuY29udGV4dFR5cGVzICYmICFkaWRXYXJuQWJvdXRDb250ZXh0VHlwZUFuZENvbnRleHRUeXBlcy5oYXMoY3RvcikpIHtcbiAgICAgICAgZGlkV2FybkFib3V0Q29udGV4dFR5cGVBbmRDb250ZXh0VHlwZXMuYWRkKGN0b3IpO1xuXG4gICAgICAgIGVycm9yKCclcyBkZWNsYXJlcyBib3RoIGNvbnRleHRUeXBlcyBhbmQgY29udGV4dFR5cGUgc3RhdGljIHByb3BlcnRpZXMuICcgKyAnVGhlIGxlZ2FjeSBjb250ZXh0VHlwZXMgcHJvcGVydHkgd2lsbCBiZSBpZ25vcmVkLicsIG5hbWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50U2hvdWxkVXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcignJXMgaGFzIGEgbWV0aG9kIGNhbGxlZCAnICsgJ2NvbXBvbmVudFNob3VsZFVwZGF0ZSgpLiBEaWQgeW91IG1lYW4gc2hvdWxkQ29tcG9uZW50VXBkYXRlKCk/ICcgKyAnVGhlIG5hbWUgaXMgcGhyYXNlZCBhcyBhIHF1ZXN0aW9uIGJlY2F1c2UgdGhlIGZ1bmN0aW9uIGlzICcgKyAnZXhwZWN0ZWQgdG8gcmV0dXJuIGEgdmFsdWUuJywgbmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKGN0b3IucHJvdG90eXBlICYmIGN0b3IucHJvdG90eXBlLmlzUHVyZVJlYWN0Q29tcG9uZW50ICYmIHR5cGVvZiBpbnN0YW5jZS5zaG91bGRDb21wb25lbnRVcGRhdGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBlcnJvcignJXMgaGFzIGEgbWV0aG9kIGNhbGxlZCBzaG91bGRDb21wb25lbnRVcGRhdGUoKS4gJyArICdzaG91bGRDb21wb25lbnRVcGRhdGUgc2hvdWxkIG5vdCBiZSB1c2VkIHdoZW4gZXh0ZW5kaW5nIFJlYWN0LlB1cmVDb21wb25lbnQuICcgKyAnUGxlYXNlIGV4dGVuZCBSZWFjdC5Db21wb25lbnQgaWYgc2hvdWxkQ29tcG9uZW50VXBkYXRlIGlzIHVzZWQuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGN0b3IpIHx8ICdBIHB1cmUgY29tcG9uZW50Jyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRVbm1vdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcignJXMgaGFzIGEgbWV0aG9kIGNhbGxlZCAnICsgJ2NvbXBvbmVudERpZFVubW91bnQoKS4gQnV0IHRoZXJlIGlzIG5vIHN1Y2ggbGlmZWN5Y2xlIG1ldGhvZC4gJyArICdEaWQgeW91IG1lYW4gY29tcG9uZW50V2lsbFVubW91bnQoKT8nLCBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudERpZFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJyVzIGhhcyBhIG1ldGhvZCBjYWxsZWQgJyArICdjb21wb25lbnREaWRSZWNlaXZlUHJvcHMoKS4gQnV0IHRoZXJlIGlzIG5vIHN1Y2ggbGlmZWN5Y2xlIG1ldGhvZC4gJyArICdJZiB5b3UgbWVhbnQgdG8gdXBkYXRlIHRoZSBzdGF0ZSBpbiByZXNwb25zZSB0byBjaGFuZ2luZyBwcm9wcywgJyArICd1c2UgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcygpLiBJZiB5b3UgbWVhbnQgdG8gZmV0Y2ggZGF0YSBvciAnICsgJ3J1biBzaWRlLWVmZmVjdHMgb3IgbXV0YXRpb25zIGFmdGVyIFJlYWN0IGhhcyB1cGRhdGVkIHRoZSBVSSwgdXNlIGNvbXBvbmVudERpZFVwZGF0ZSgpLicsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbFJlY2lldmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJyVzIGhhcyBhIG1ldGhvZCBjYWxsZWQgJyArICdjb21wb25lbnRXaWxsUmVjaWV2ZVByb3BzKCkuIERpZCB5b3UgbWVhbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKCk/JywgbmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2lldmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJyVzIGhhcyBhIG1ldGhvZCBjYWxsZWQgJyArICdVTlNBRkVfY29tcG9uZW50V2lsbFJlY2lldmVQcm9wcygpLiBEaWQgeW91IG1lYW4gVU5TQUZFX2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMoKT8nLCBuYW1lKTtcbiAgICB9XG5cbiAgICB2YXIgaGFzTXV0YXRlZFByb3BzID0gaW5zdGFuY2UucHJvcHMgIT09IG5ld1Byb3BzO1xuXG4gICAgaWYgKGluc3RhbmNlLnByb3BzICE9PSB1bmRlZmluZWQgJiYgaGFzTXV0YXRlZFByb3BzKSB7XG4gICAgICBlcnJvcignJXMoLi4uKTogV2hlbiBjYWxsaW5nIHN1cGVyKCkgaW4gYCVzYCwgbWFrZSBzdXJlIHRvIHBhc3MgJyArIFwidXAgdGhlIHNhbWUgcHJvcHMgdGhhdCB5b3VyIGNvbXBvbmVudCdzIGNvbnN0cnVjdG9yIHdhcyBwYXNzZWQuXCIsIG5hbWUsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmIChpbnN0YW5jZS5kZWZhdWx0UHJvcHMpIHtcbiAgICAgIGVycm9yKCdTZXR0aW5nIGRlZmF1bHRQcm9wcyBhcyBhbiBpbnN0YW5jZSBwcm9wZXJ0eSBvbiAlcyBpcyBub3Qgc3VwcG9ydGVkIGFuZCB3aWxsIGJlIGlnbm9yZWQuJyArICcgSW5zdGVhZCwgZGVmaW5lIGRlZmF1bHRQcm9wcyBhcyBhIHN0YXRpYyBwcm9wZXJ0eSBvbiAlcy4nLCBuYW1lLCBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRVcGRhdGUgIT09ICdmdW5jdGlvbicgJiYgIWRpZFdhcm5BYm91dEdldFNuYXBzaG90QmVmb3JlVXBkYXRlV2l0aG91dERpZFVwZGF0ZS5oYXMoY3RvcikpIHtcbiAgICAgIGRpZFdhcm5BYm91dEdldFNuYXBzaG90QmVmb3JlVXBkYXRlV2l0aG91dERpZFVwZGF0ZS5hZGQoY3Rvcik7XG5cbiAgICAgIGVycm9yKCclczogZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUoKSBzaG91bGQgYmUgdXNlZCB3aXRoIGNvbXBvbmVudERpZFVwZGF0ZSgpLiAnICsgJ1RoaXMgY29tcG9uZW50IGRlZmluZXMgZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUoKSBvbmx5LicsIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShjdG9yKSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGVycm9yKCclczogZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzKCkgaXMgZGVmaW5lZCBhcyBhbiBpbnN0YW5jZSBtZXRob2QgJyArICdhbmQgd2lsbCBiZSBpZ25vcmVkLiBJbnN0ZWFkLCBkZWNsYXJlIGl0IGFzIGEgc3RhdGljIG1ldGhvZC4nLCBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmdldERlcml2ZWRTdGF0ZUZyb21FcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJyVzOiBnZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IoKSBpcyBkZWZpbmVkIGFzIGFuIGluc3RhbmNlIG1ldGhvZCAnICsgJ2FuZCB3aWxsIGJlIGlnbm9yZWQuIEluc3RlYWQsIGRlY2xhcmUgaXQgYXMgYSBzdGF0aWMgbWV0aG9kLicsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgY3Rvci5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJyVzOiBnZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSgpIGlzIGRlZmluZWQgYXMgYSBzdGF0aWMgbWV0aG9kICcgKyAnYW5kIHdpbGwgYmUgaWdub3JlZC4gSW5zdGVhZCwgZGVjbGFyZSBpdCBhcyBhbiBpbnN0YW5jZSBtZXRob2QuJywgbmFtZSk7XG4gICAgfVxuXG4gICAgdmFyIF9zdGF0ZSA9IGluc3RhbmNlLnN0YXRlO1xuXG4gICAgaWYgKF9zdGF0ZSAmJiAodHlwZW9mIF9zdGF0ZSAhPT0gJ29iamVjdCcgfHwgaXNBcnJheShfc3RhdGUpKSkge1xuICAgICAgZXJyb3IoJyVzLnN0YXRlOiBtdXN0IGJlIHNldCB0byBhbiBvYmplY3Qgb3IgbnVsbCcsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZ2V0Q2hpbGRDb250ZXh0ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBjdG9yLmNoaWxkQ29udGV4dFR5cGVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgZXJyb3IoJyVzLmdldENoaWxkQ29udGV4dCgpOiBjaGlsZENvbnRleHRUeXBlcyBtdXN0IGJlIGRlZmluZWQgaW4gb3JkZXIgdG8gJyArICd1c2UgZ2V0Q2hpbGRDb250ZXh0KCkuJywgbmFtZSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFkb3B0Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgaW5zdGFuY2UpIHtcbiAgaW5zdGFuY2UudXBkYXRlciA9IGNsYXNzQ29tcG9uZW50VXBkYXRlcjtcbiAgd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlID0gaW5zdGFuY2U7IC8vIFRoZSBpbnN0YW5jZSBuZWVkcyBhY2Nlc3MgdG8gdGhlIGZpYmVyIHNvIHRoYXQgaXQgY2FuIHNjaGVkdWxlIHVwZGF0ZXNcblxuICBzZXQoaW5zdGFuY2UsIHdvcmtJblByb2dyZXNzKTtcblxuICB7XG4gICAgaW5zdGFuY2UuX3JlYWN0SW50ZXJuYWxJbnN0YW5jZSA9IGZha2VJbnRlcm5hbEluc3RhbmNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdENsYXNzSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIGN0b3IsIHByb3BzKSB7XG4gIHZhciBpc0xlZ2FjeUNvbnRleHRDb25zdW1lciA9IGZhbHNlO1xuICB2YXIgdW5tYXNrZWRDb250ZXh0ID0gZW1wdHlDb250ZXh0T2JqZWN0O1xuICB2YXIgY29udGV4dCA9IGVtcHR5Q29udGV4dE9iamVjdDtcbiAgdmFyIGNvbnRleHRUeXBlID0gY3Rvci5jb250ZXh0VHlwZTtcblxuICB7XG4gICAgaWYgKCdjb250ZXh0VHlwZScgaW4gY3Rvcikge1xuICAgICAgdmFyIGlzVmFsaWQgPSAvLyBBbGxvdyBudWxsIGZvciBjb25kaXRpb25hbCBkZWNsYXJhdGlvblxuICAgICAgY29udGV4dFR5cGUgPT09IG51bGwgfHwgY29udGV4dFR5cGUgIT09IHVuZGVmaW5lZCAmJiBjb250ZXh0VHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfQ09OVEVYVF9UWVBFICYmIGNvbnRleHRUeXBlLl9jb250ZXh0ID09PSB1bmRlZmluZWQ7IC8vIE5vdCBhIDxDb250ZXh0LkNvbnN1bWVyPlxuXG4gICAgICBpZiAoIWlzVmFsaWQgJiYgIWRpZFdhcm5BYm91dEludmFsaWRhdGVDb250ZXh0VHlwZS5oYXMoY3RvcikpIHtcbiAgICAgICAgZGlkV2FybkFib3V0SW52YWxpZGF0ZUNvbnRleHRUeXBlLmFkZChjdG9yKTtcbiAgICAgICAgdmFyIGFkZGVuZHVtID0gJyc7XG5cbiAgICAgICAgaWYgKGNvbnRleHRUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBhZGRlbmR1bSA9ICcgSG93ZXZlciwgaXQgaXMgc2V0IHRvIHVuZGVmaW5lZC4gJyArICdUaGlzIGNhbiBiZSBjYXVzZWQgYnkgYSB0eXBvIG9yIGJ5IG1peGluZyB1cCBuYW1lZCBhbmQgZGVmYXVsdCBpbXBvcnRzLiAnICsgJ1RoaXMgY2FuIGFsc28gaGFwcGVuIGR1ZSB0byBhIGNpcmN1bGFyIGRlcGVuZGVuY3ksIHNvICcgKyAndHJ5IG1vdmluZyB0aGUgY3JlYXRlQ29udGV4dCgpIGNhbGwgdG8gYSBzZXBhcmF0ZSBmaWxlLic7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGNvbnRleHRUeXBlICE9PSAnb2JqZWN0Jykge1xuICAgICAgICAgIGFkZGVuZHVtID0gJyBIb3dldmVyLCBpdCBpcyBzZXQgdG8gYSAnICsgdHlwZW9mIGNvbnRleHRUeXBlICsgJy4nO1xuICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHRUeXBlLiQkdHlwZW9mID09PSBSRUFDVF9QUk9WSURFUl9UWVBFKSB7XG4gICAgICAgICAgYWRkZW5kdW0gPSAnIERpZCB5b3UgYWNjaWRlbnRhbGx5IHBhc3MgdGhlIENvbnRleHQuUHJvdmlkZXIgaW5zdGVhZD8nO1xuICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHRUeXBlLl9jb250ZXh0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyA8Q29udGV4dC5Db25zdW1lcj5cbiAgICAgICAgICBhZGRlbmR1bSA9ICcgRGlkIHlvdSBhY2NpZGVudGFsbHkgcGFzcyB0aGUgQ29udGV4dC5Db25zdW1lciBpbnN0ZWFkPyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYWRkZW5kdW0gPSAnIEhvd2V2ZXIsIGl0IGlzIHNldCB0byBhbiBvYmplY3Qgd2l0aCBrZXlzIHsnICsgT2JqZWN0LmtleXMoY29udGV4dFR5cGUpLmpvaW4oJywgJykgKyAnfS4nO1xuICAgICAgICB9XG5cbiAgICAgICAgZXJyb3IoJyVzIGRlZmluZXMgYW4gaW52YWxpZCBjb250ZXh0VHlwZS4gJyArICdjb250ZXh0VHlwZSBzaG91bGQgcG9pbnQgdG8gdGhlIENvbnRleHQgb2JqZWN0IHJldHVybmVkIGJ5IFJlYWN0LmNyZWF0ZUNvbnRleHQoKS4lcycsIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShjdG9yKSB8fCAnQ29tcG9uZW50JywgYWRkZW5kdW0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdvYmplY3QnICYmIGNvbnRleHRUeXBlICE9PSBudWxsKSB7XG4gICAgY29udGV4dCA9IHJlYWRDb250ZXh0KGNvbnRleHRUeXBlKTtcbiAgfSBlbHNlIHtcbiAgICB1bm1hc2tlZENvbnRleHQgPSBnZXRVbm1hc2tlZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIGN0b3IsIHRydWUpO1xuICAgIHZhciBjb250ZXh0VHlwZXMgPSBjdG9yLmNvbnRleHRUeXBlcztcbiAgICBpc0xlZ2FjeUNvbnRleHRDb25zdW1lciA9IGNvbnRleHRUeXBlcyAhPT0gbnVsbCAmJiBjb250ZXh0VHlwZXMgIT09IHVuZGVmaW5lZDtcbiAgICBjb250ZXh0ID0gaXNMZWdhY3lDb250ZXh0Q29uc3VtZXIgPyBnZXRNYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCB1bm1hc2tlZENvbnRleHQpIDogZW1wdHlDb250ZXh0T2JqZWN0O1xuICB9XG5cbiAgdmFyIGluc3RhbmNlID0gbmV3IGN0b3IocHJvcHMsIGNvbnRleHQpOyAvLyBJbnN0YW50aWF0ZSB0d2ljZSB0byBoZWxwIGRldGVjdCBzaWRlLWVmZmVjdHMuXG5cbiAge1xuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBpbnN0YW5jZSA9IG5ldyBjdG9yKHByb3BzLCBjb250ZXh0KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgc3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gaW5zdGFuY2Uuc3RhdGUgIT09IG51bGwgJiYgaW5zdGFuY2Uuc3RhdGUgIT09IHVuZGVmaW5lZCA/IGluc3RhbmNlLnN0YXRlIDogbnVsbDtcbiAgYWRvcHRDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCBpbnN0YW5jZSk7XG5cbiAge1xuICAgIGlmICh0eXBlb2YgY3Rvci5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMgPT09ICdmdW5jdGlvbicgJiYgc3RhdGUgPT09IG51bGwpIHtcbiAgICAgIHZhciBjb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGN0b3IpIHx8ICdDb21wb25lbnQnO1xuXG4gICAgICBpZiAoIWRpZFdhcm5BYm91dFVuaW5pdGlhbGl6ZWRTdGF0ZS5oYXMoY29tcG9uZW50TmFtZSkpIHtcbiAgICAgICAgZGlkV2FybkFib3V0VW5pbml0aWFsaXplZFN0YXRlLmFkZChjb21wb25lbnROYW1lKTtcblxuICAgICAgICBlcnJvcignYCVzYCB1c2VzIGBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHNgIGJ1dCBpdHMgaW5pdGlhbCBzdGF0ZSBpcyAnICsgJyVzLiBUaGlzIGlzIG5vdCByZWNvbW1lbmRlZC4gSW5zdGVhZCwgZGVmaW5lIHRoZSBpbml0aWFsIHN0YXRlIGJ5ICcgKyAnYXNzaWduaW5nIGFuIG9iamVjdCB0byBgdGhpcy5zdGF0ZWAgaW4gdGhlIGNvbnN0cnVjdG9yIG9mIGAlc2AuICcgKyAnVGhpcyBlbnN1cmVzIHRoYXQgYGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wc2AgYXJndW1lbnRzIGhhdmUgYSBjb25zaXN0ZW50IHNoYXBlLicsIGNvbXBvbmVudE5hbWUsIGluc3RhbmNlLnN0YXRlID09PSBudWxsID8gJ251bGwnIDogJ3VuZGVmaW5lZCcsIGNvbXBvbmVudE5hbWUpO1xuICAgICAgfVxuICAgIH0gLy8gSWYgbmV3IGNvbXBvbmVudCBBUElzIGFyZSBkZWZpbmVkLCBcInVuc2FmZVwiIGxpZmVjeWNsZXMgd29uJ3QgYmUgY2FsbGVkLlxuICAgIC8vIFdhcm4gYWJvdXQgdGhlc2UgbGlmZWN5Y2xlcyBpZiB0aGV5IGFyZSBwcmVzZW50LlxuICAgIC8vIERvbid0IHdhcm4gYWJvdXQgcmVhY3QtbGlmZWN5Y2xlcy1jb21wYXQgcG9seWZpbGxlZCBtZXRob2RzIHRob3VnaC5cblxuXG4gICAgaWYgKHR5cGVvZiBjdG9yLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgaW5zdGFuY2UuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciBmb3VuZFdpbGxNb3VudE5hbWUgPSBudWxsO1xuICAgICAgdmFyIGZvdW5kV2lsbFJlY2VpdmVQcm9wc05hbWUgPSBudWxsO1xuICAgICAgdmFyIGZvdW5kV2lsbFVwZGF0ZU5hbWUgPSBudWxsO1xuXG4gICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxNb3VudCA9PT0gJ2Z1bmN0aW9uJyAmJiBpbnN0YW5jZS5jb21wb25lbnRXaWxsTW91bnQuX19zdXBwcmVzc0RlcHJlY2F0aW9uV2FybmluZyAhPT0gdHJ1ZSkge1xuICAgICAgICBmb3VuZFdpbGxNb3VudE5hbWUgPSAnY29tcG9uZW50V2lsbE1vdW50JztcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZm91bmRXaWxsTW91bnROYW1lID0gJ1VOU0FGRV9jb21wb25lbnRXaWxsTW91bnQnO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPT09ICdmdW5jdGlvbicgJiYgaW5zdGFuY2UuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcy5fX3N1cHByZXNzRGVwcmVjYXRpb25XYXJuaW5nICE9PSB0cnVlKSB7XG4gICAgICAgIGZvdW5kV2lsbFJlY2VpdmVQcm9wc05hbWUgPSAnY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyc7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmb3VuZFdpbGxSZWNlaXZlUHJvcHNOYW1lID0gJ1VOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzJztcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsVXBkYXRlID09PSAnZnVuY3Rpb24nICYmIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVcGRhdGUuX19zdXBwcmVzc0RlcHJlY2F0aW9uV2FybmluZyAhPT0gdHJ1ZSkge1xuICAgICAgICBmb3VuZFdpbGxVcGRhdGVOYW1lID0gJ2NvbXBvbmVudFdpbGxVcGRhdGUnO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZm91bmRXaWxsVXBkYXRlTmFtZSA9ICdVTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZSc7XG4gICAgICB9XG5cbiAgICAgIGlmIChmb3VuZFdpbGxNb3VudE5hbWUgIT09IG51bGwgfHwgZm91bmRXaWxsUmVjZWl2ZVByb3BzTmFtZSAhPT0gbnVsbCB8fCBmb3VuZFdpbGxVcGRhdGVOYW1lICE9PSBudWxsKSB7XG4gICAgICAgIHZhciBfY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShjdG9yKSB8fCAnQ29tcG9uZW50JztcblxuICAgICAgICB2YXIgbmV3QXBpTmFtZSA9IHR5cGVvZiBjdG9yLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9PT0gJ2Z1bmN0aW9uJyA/ICdnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMoKScgOiAnZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUoKSc7XG5cbiAgICAgICAgaWYgKCFkaWRXYXJuQWJvdXRMZWdhY3lMaWZlY3ljbGVzQW5kRGVyaXZlZFN0YXRlLmhhcyhfY29tcG9uZW50TmFtZSkpIHtcbiAgICAgICAgICBkaWRXYXJuQWJvdXRMZWdhY3lMaWZlY3ljbGVzQW5kRGVyaXZlZFN0YXRlLmFkZChfY29tcG9uZW50TmFtZSk7XG5cbiAgICAgICAgICBlcnJvcignVW5zYWZlIGxlZ2FjeSBsaWZlY3ljbGVzIHdpbGwgbm90IGJlIGNhbGxlZCBmb3IgY29tcG9uZW50cyB1c2luZyBuZXcgY29tcG9uZW50IEFQSXMuXFxuXFxuJyArICclcyB1c2VzICVzIGJ1dCBhbHNvIGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgbGVnYWN5IGxpZmVjeWNsZXM6JXMlcyVzXFxuXFxuJyArICdUaGUgYWJvdmUgbGlmZWN5Y2xlcyBzaG91bGQgYmUgcmVtb3ZlZC4gTGVhcm4gbW9yZSBhYm91dCB0aGlzIHdhcm5pbmcgaGVyZTpcXG4nICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay91bnNhZmUtY29tcG9uZW50LWxpZmVjeWNsZXMnLCBfY29tcG9uZW50TmFtZSwgbmV3QXBpTmFtZSwgZm91bmRXaWxsTW91bnROYW1lICE9PSBudWxsID8gXCJcXG4gIFwiICsgZm91bmRXaWxsTW91bnROYW1lIDogJycsIGZvdW5kV2lsbFJlY2VpdmVQcm9wc05hbWUgIT09IG51bGwgPyBcIlxcbiAgXCIgKyBmb3VuZFdpbGxSZWNlaXZlUHJvcHNOYW1lIDogJycsIGZvdW5kV2lsbFVwZGF0ZU5hbWUgIT09IG51bGwgPyBcIlxcbiAgXCIgKyBmb3VuZFdpbGxVcGRhdGVOYW1lIDogJycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IC8vIENhY2hlIHVubWFza2VkIGNvbnRleHQgc28gd2UgY2FuIGF2b2lkIHJlY3JlYXRpbmcgbWFza2VkIGNvbnRleHQgdW5sZXNzIG5lY2Vzc2FyeS5cbiAgLy8gUmVhY3RGaWJlckNvbnRleHQgdXN1YWxseSB1cGRhdGVzIHRoaXMgY2FjaGUgYnV0IGNhbid0IGZvciBuZXdseS1jcmVhdGVkIGluc3RhbmNlcy5cblxuXG4gIGlmIChpc0xlZ2FjeUNvbnRleHRDb25zdW1lcikge1xuICAgIGNhY2hlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgdW5tYXNrZWRDb250ZXh0LCBjb250ZXh0KTtcbiAgfVxuXG4gIHJldHVybiBpbnN0YW5jZTtcbn1cblxuZnVuY3Rpb24gY2FsbENvbXBvbmVudFdpbGxNb3VudCh3b3JrSW5Qcm9ncmVzcywgaW5zdGFuY2UpIHtcbiAgdmFyIG9sZFN0YXRlID0gaW5zdGFuY2Uuc3RhdGU7XG5cbiAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICBpbnN0YW5jZS5jb21wb25lbnRXaWxsTW91bnQoKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQoKTtcbiAgfVxuXG4gIGlmIChvbGRTdGF0ZSAhPT0gaW5zdGFuY2Uuc3RhdGUpIHtcbiAgICB7XG4gICAgICBlcnJvcignJXMuY29tcG9uZW50V2lsbE1vdW50KCk6IEFzc2lnbmluZyBkaXJlY3RseSB0byB0aGlzLnN0YXRlIGlzICcgKyBcImRlcHJlY2F0ZWQgKGV4Y2VwdCBpbnNpZGUgYSBjb21wb25lbnQncyBcIiArICdjb25zdHJ1Y3RvcikuIFVzZSBzZXRTdGF0ZSBpbnN0ZWFkLicsIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIod29ya0luUHJvZ3Jlc3MpIHx8ICdDb21wb25lbnQnKTtcbiAgICB9XG5cbiAgICBjbGFzc0NvbXBvbmVudFVwZGF0ZXIuZW5xdWV1ZVJlcGxhY2VTdGF0ZShpbnN0YW5jZSwgaW5zdGFuY2Uuc3RhdGUsIG51bGwpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNhbGxDb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKHdvcmtJblByb2dyZXNzLCBpbnN0YW5jZSwgbmV3UHJvcHMsIG5leHRDb250ZXh0KSB7XG4gIHZhciBvbGRTdGF0ZSA9IGluc3RhbmNlLnN0YXRlO1xuXG4gIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGluc3RhbmNlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV3UHJvcHMsIG5leHRDb250ZXh0KTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXdQcm9wcywgbmV4dENvbnRleHQpO1xuICB9XG5cbiAgaWYgKGluc3RhbmNlLnN0YXRlICE9PSBvbGRTdGF0ZSkge1xuICAgIHtcbiAgICAgIHZhciBjb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcih3b3JrSW5Qcm9ncmVzcykgfHwgJ0NvbXBvbmVudCc7XG5cbiAgICAgIGlmICghZGlkV2FybkFib3V0U3RhdGVBc3NpZ25tZW50Rm9yQ29tcG9uZW50Lmhhcyhjb21wb25lbnROYW1lKSkge1xuICAgICAgICBkaWRXYXJuQWJvdXRTdGF0ZUFzc2lnbm1lbnRGb3JDb21wb25lbnQuYWRkKGNvbXBvbmVudE5hbWUpO1xuXG4gICAgICAgIGVycm9yKCclcy5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKCk6IEFzc2lnbmluZyBkaXJlY3RseSB0byAnICsgXCJ0aGlzLnN0YXRlIGlzIGRlcHJlY2F0ZWQgKGV4Y2VwdCBpbnNpZGUgYSBjb21wb25lbnQncyBcIiArICdjb25zdHJ1Y3RvcikuIFVzZSBzZXRTdGF0ZSBpbnN0ZWFkLicsIGNvbXBvbmVudE5hbWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNsYXNzQ29tcG9uZW50VXBkYXRlci5lbnF1ZXVlUmVwbGFjZVN0YXRlKGluc3RhbmNlLCBpbnN0YW5jZS5zdGF0ZSwgbnVsbCk7XG4gIH1cbn0gLy8gSW52b2tlcyB0aGUgbW91bnQgbGlmZS1jeWNsZXMgb24gYSBwcmV2aW91c2x5IG5ldmVyIHJlbmRlcmVkIGluc3RhbmNlLlxuXG5cbmZ1bmN0aW9uIG1vdW50Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgY3RvciwgbmV3UHJvcHMsIHJlbmRlckxhbmVzKSB7XG4gIHtcbiAgICBjaGVja0NsYXNzSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIGN0b3IsIG5ld1Byb3BzKTtcbiAgfVxuXG4gIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcbiAgaW5zdGFuY2UucHJvcHMgPSBuZXdQcm9wcztcbiAgaW5zdGFuY2Uuc3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuICBpbnN0YW5jZS5yZWZzID0gZW1wdHlSZWZzT2JqZWN0O1xuICBpbml0aWFsaXplVXBkYXRlUXVldWUod29ya0luUHJvZ3Jlc3MpO1xuICB2YXIgY29udGV4dFR5cGUgPSBjdG9yLmNvbnRleHRUeXBlO1xuXG4gIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdvYmplY3QnICYmIGNvbnRleHRUeXBlICE9PSBudWxsKSB7XG4gICAgaW5zdGFuY2UuY29udGV4dCA9IHJlYWRDb250ZXh0KGNvbnRleHRUeXBlKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgdW5tYXNrZWRDb250ZXh0ID0gZ2V0VW5tYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCBjdG9yLCB0cnVlKTtcbiAgICBpbnN0YW5jZS5jb250ZXh0ID0gZ2V0TWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgdW5tYXNrZWRDb250ZXh0KTtcbiAgfVxuXG4gIHtcbiAgICBpZiAoaW5zdGFuY2Uuc3RhdGUgPT09IG5ld1Byb3BzKSB7XG4gICAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShjdG9yKSB8fCAnQ29tcG9uZW50JztcblxuICAgICAgaWYgKCFkaWRXYXJuQWJvdXREaXJlY3RseUFzc2lnbmluZ1Byb3BzVG9TdGF0ZS5oYXMoY29tcG9uZW50TmFtZSkpIHtcbiAgICAgICAgZGlkV2FybkFib3V0RGlyZWN0bHlBc3NpZ25pbmdQcm9wc1RvU3RhdGUuYWRkKGNvbXBvbmVudE5hbWUpO1xuXG4gICAgICAgIGVycm9yKCclczogSXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIGFzc2lnbiBwcm9wcyBkaXJlY3RseSB0byBzdGF0ZSAnICsgXCJiZWNhdXNlIHVwZGF0ZXMgdG8gcHJvcHMgd29uJ3QgYmUgcmVmbGVjdGVkIGluIHN0YXRlLiBcIiArICdJbiBtb3N0IGNhc2VzLCBpdCBpcyBiZXR0ZXIgdG8gdXNlIHByb3BzIGRpcmVjdGx5LicsIGNvbXBvbmVudE5hbWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgU3RyaWN0TGVnYWN5TW9kZSkge1xuICAgICAgUmVhY3RTdHJpY3RNb2RlV2FybmluZ3MucmVjb3JkTGVnYWN5Q29udGV4dFdhcm5pbmcod29ya0luUHJvZ3Jlc3MsIGluc3RhbmNlKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5yZWNvcmRVbnNhZmVMaWZlY3ljbGVXYXJuaW5ncyh3b3JrSW5Qcm9ncmVzcywgaW5zdGFuY2UpO1xuICAgIH1cbiAgfVxuXG4gIGluc3RhbmNlLnN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9IGN0b3IuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzO1xuXG4gIGlmICh0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgYXBwbHlEZXJpdmVkU3RhdGVGcm9tUHJvcHMod29ya0luUHJvZ3Jlc3MsIGN0b3IsIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcywgbmV3UHJvcHMpO1xuICAgIGluc3RhbmNlLnN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgfSAvLyBJbiBvcmRlciB0byBzdXBwb3J0IHJlYWN0LWxpZmVjeWNsZXMtY29tcGF0IHBvbHlmaWxsZWQgY29tcG9uZW50cyxcbiAgLy8gVW5zYWZlIGxpZmVjeWNsZXMgc2hvdWxkIG5vdCBiZSBpbnZva2VkIGZvciBjb21wb25lbnRzIHVzaW5nIHRoZSBuZXcgQVBJcy5cblxuXG4gIGlmICh0eXBlb2YgY3Rvci5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGluc3RhbmNlLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlICE9PSAnZnVuY3Rpb24nICYmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbE1vdW50ID09PSAnZnVuY3Rpb24nKSkge1xuICAgIGNhbGxDb21wb25lbnRXaWxsTW91bnQod29ya0luUHJvZ3Jlc3MsIGluc3RhbmNlKTsgLy8gSWYgd2UgaGFkIGFkZGl0aW9uYWwgc3RhdGUgdXBkYXRlcyBkdXJpbmcgdGhpcyBsaWZlLWN5Y2xlLCBsZXQnc1xuICAgIC8vIHByb2Nlc3MgdGhlbSBub3cuXG5cbiAgICBwcm9jZXNzVXBkYXRlUXVldWUod29ya0luUHJvZ3Jlc3MsIG5ld1Byb3BzLCBpbnN0YW5jZSwgcmVuZGVyTGFuZXMpO1xuICAgIGluc3RhbmNlLnN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICB2YXIgZmliZXJGbGFncyA9IFVwZGF0ZTtcblxuICAgIHtcbiAgICAgIGZpYmVyRmxhZ3MgfD0gTGF5b3V0U3RhdGljO1xuICAgIH1cblxuICAgIGlmICggKHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RFZmZlY3RzTW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgZmliZXJGbGFncyB8PSBNb3VudExheW91dERldjtcbiAgICB9XG5cbiAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBmaWJlckZsYWdzO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc3VtZU1vdW50Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgY3RvciwgbmV3UHJvcHMsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcbiAgdmFyIG9sZFByb3BzID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRQcm9wcztcbiAgaW5zdGFuY2UucHJvcHMgPSBvbGRQcm9wcztcbiAgdmFyIG9sZENvbnRleHQgPSBpbnN0YW5jZS5jb250ZXh0O1xuICB2YXIgY29udGV4dFR5cGUgPSBjdG9yLmNvbnRleHRUeXBlO1xuICB2YXIgbmV4dENvbnRleHQgPSBlbXB0eUNvbnRleHRPYmplY3Q7XG5cbiAgaWYgKHR5cGVvZiBjb250ZXh0VHlwZSA9PT0gJ29iamVjdCcgJiYgY29udGV4dFR5cGUgIT09IG51bGwpIHtcbiAgICBuZXh0Q29udGV4dCA9IHJlYWRDb250ZXh0KGNvbnRleHRUeXBlKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgbmV4dExlZ2FjeVVubWFza2VkQ29udGV4dCA9IGdldFVubWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgY3RvciwgdHJ1ZSk7XG4gICAgbmV4dENvbnRleHQgPSBnZXRNYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCBuZXh0TGVnYWN5VW5tYXNrZWRDb250ZXh0KTtcbiAgfVxuXG4gIHZhciBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMgPSBjdG9yLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcztcbiAgdmFyIGhhc05ld0xpZmVjeWNsZXMgPSB0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID09PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBpbnN0YW5jZS5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJzsgLy8gTm90ZTogRHVyaW5nIHRoZXNlIGxpZmUtY3ljbGVzLCBpbnN0YW5jZS5wcm9wcy9pbnN0YW5jZS5zdGF0ZSBhcmUgd2hhdFxuICAvLyBldmVyIHRoZSBwcmV2aW91c2x5IGF0dGVtcHRlZCB0byByZW5kZXIgLSBub3QgdGhlIFwiY3VycmVudFwiLiBIb3dldmVyLFxuICAvLyBkdXJpbmcgY29tcG9uZW50RGlkVXBkYXRlIHdlIHBhc3MgdGhlIFwiY3VycmVudFwiIHByb3BzLlxuICAvLyBJbiBvcmRlciB0byBzdXBwb3J0IHJlYWN0LWxpZmVjeWNsZXMtY29tcGF0IHBvbHlmaWxsZWQgY29tcG9uZW50cyxcbiAgLy8gVW5zYWZlIGxpZmVjeWNsZXMgc2hvdWxkIG5vdCBiZSBpbnZva2VkIGZvciBjb21wb25lbnRzIHVzaW5nIHRoZSBuZXcgQVBJcy5cblxuICBpZiAoIWhhc05ld0xpZmVjeWNsZXMgJiYgKHR5cGVvZiBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICBpZiAob2xkUHJvcHMgIT09IG5ld1Byb3BzIHx8IG9sZENvbnRleHQgIT09IG5leHRDb250ZXh0KSB7XG4gICAgICBjYWxsQ29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyh3b3JrSW5Qcm9ncmVzcywgaW5zdGFuY2UsIG5ld1Byb3BzLCBuZXh0Q29udGV4dCk7XG4gICAgfVxuICB9XG5cbiAgcmVzZXRIYXNGb3JjZVVwZGF0ZUJlZm9yZVByb2Nlc3NpbmcoKTtcbiAgdmFyIG9sZFN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIG5ld1N0YXRlID0gaW5zdGFuY2Uuc3RhdGUgPSBvbGRTdGF0ZTtcbiAgcHJvY2Vzc1VwZGF0ZVF1ZXVlKHdvcmtJblByb2dyZXNzLCBuZXdQcm9wcywgaW5zdGFuY2UsIHJlbmRlckxhbmVzKTtcbiAgbmV3U3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gIGlmIChvbGRQcm9wcyA9PT0gbmV3UHJvcHMgJiYgb2xkU3RhdGUgPT09IG5ld1N0YXRlICYmICFoYXNDb250ZXh0Q2hhbmdlZCgpICYmICFjaGVja0hhc0ZvcmNlVXBkYXRlQWZ0ZXJQcm9jZXNzaW5nKCkpIHtcbiAgICAvLyBJZiBhbiB1cGRhdGUgd2FzIGFscmVhZHkgaW4gcHJvZ3Jlc3MsIHdlIHNob3VsZCBzY2hlZHVsZSBhbiBVcGRhdGVcbiAgICAvLyBlZmZlY3QgZXZlbiB0aG91Z2ggd2UncmUgYmFpbGluZyBvdXQsIHNvIHRoYXQgY1dVL2NEVSBhcmUgY2FsbGVkLlxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciBmaWJlckZsYWdzID0gVXBkYXRlO1xuXG4gICAgICB7XG4gICAgICAgIGZpYmVyRmxhZ3MgfD0gTGF5b3V0U3RhdGljO1xuICAgICAgfVxuXG4gICAgICBpZiAoICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgU3RyaWN0RWZmZWN0c01vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgZmliZXJGbGFncyB8PSBNb3VudExheW91dERldjtcbiAgICAgIH1cblxuICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gZmliZXJGbGFncztcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAodHlwZW9mIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGFwcGx5RGVyaXZlZFN0YXRlRnJvbVByb3BzKHdvcmtJblByb2dyZXNzLCBjdG9yLCBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMsIG5ld1Byb3BzKTtcbiAgICBuZXdTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG4gIH1cblxuICB2YXIgc2hvdWxkVXBkYXRlID0gY2hlY2tIYXNGb3JjZVVwZGF0ZUFmdGVyUHJvY2Vzc2luZygpIHx8IGNoZWNrU2hvdWxkQ29tcG9uZW50VXBkYXRlKHdvcmtJblByb2dyZXNzLCBjdG9yLCBvbGRQcm9wcywgbmV3UHJvcHMsIG9sZFN0YXRlLCBuZXdTdGF0ZSwgbmV4dENvbnRleHQpO1xuXG4gIGlmIChzaG91bGRVcGRhdGUpIHtcbiAgICAvLyBJbiBvcmRlciB0byBzdXBwb3J0IHJlYWN0LWxpZmVjeWNsZXMtY29tcGF0IHBvbHlmaWxsZWQgY29tcG9uZW50cyxcbiAgICAvLyBVbnNhZmUgbGlmZWN5Y2xlcyBzaG91bGQgbm90IGJlIGludm9rZWQgZm9yIGNvbXBvbmVudHMgdXNpbmcgdGhlIG5ldyBBUElzLlxuICAgIGlmICghaGFzTmV3TGlmZWN5Y2xlcyAmJiAodHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxNb3VudCA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbE1vdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGluc3RhbmNlLmNvbXBvbmVudFdpbGxNb3VudCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciBfZmliZXJGbGFncyA9IFVwZGF0ZTtcblxuICAgICAge1xuICAgICAgICBfZmliZXJGbGFncyB8PSBMYXlvdXRTdGF0aWM7XG4gICAgICB9XG5cbiAgICAgIGlmICggKHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RFZmZlY3RzTW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgICBfZmliZXJGbGFncyB8PSBNb3VudExheW91dERldjtcbiAgICAgIH1cblxuICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gX2ZpYmVyRmxhZ3M7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIElmIGFuIHVwZGF0ZSB3YXMgYWxyZWFkeSBpbiBwcm9ncmVzcywgd2Ugc2hvdWxkIHNjaGVkdWxlIGFuIFVwZGF0ZVxuICAgIC8vIGVmZmVjdCBldmVuIHRob3VnaCB3ZSdyZSBiYWlsaW5nIG91dCwgc28gdGhhdCBjV1UvY0RVIGFyZSBjYWxsZWQuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRNb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIF9maWJlckZsYWdzMiA9IFVwZGF0ZTtcblxuICAgICAge1xuICAgICAgICBfZmliZXJGbGFnczIgfD0gTGF5b3V0U3RhdGljO1xuICAgICAgfVxuXG4gICAgICBpZiAoICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgU3RyaWN0RWZmZWN0c01vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgX2ZpYmVyRmxhZ3MyIHw9IE1vdW50TGF5b3V0RGV2O1xuICAgICAgfVxuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBfZmliZXJGbGFnczI7XG4gICAgfSAvLyBJZiBzaG91bGRDb21wb25lbnRVcGRhdGUgcmV0dXJuZWQgZmFsc2UsIHdlIHNob3VsZCBzdGlsbCB1cGRhdGUgdGhlXG4gICAgLy8gbWVtb2l6ZWQgc3RhdGUgdG8gaW5kaWNhdGUgdGhhdCB0aGlzIHdvcmsgY2FuIGJlIHJldXNlZC5cblxuXG4gICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRQcm9wcyA9IG5ld1Byb3BzO1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBuZXdTdGF0ZTtcbiAgfSAvLyBVcGRhdGUgdGhlIGV4aXN0aW5nIGluc3RhbmNlJ3Mgc3RhdGUsIHByb3BzLCBhbmQgY29udGV4dCBwb2ludGVycyBldmVuXG4gIC8vIGlmIHNob3VsZENvbXBvbmVudFVwZGF0ZSByZXR1cm5zIGZhbHNlLlxuXG5cbiAgaW5zdGFuY2UucHJvcHMgPSBuZXdQcm9wcztcbiAgaW5zdGFuY2Uuc3RhdGUgPSBuZXdTdGF0ZTtcbiAgaW5zdGFuY2UuY29udGV4dCA9IG5leHRDb250ZXh0O1xuICByZXR1cm4gc2hvdWxkVXBkYXRlO1xufSAvLyBJbnZva2VzIHRoZSB1cGRhdGUgbGlmZS1jeWNsZXMgYW5kIHJldHVybnMgZmFsc2UgaWYgaXQgc2hvdWxkbid0IHJlcmVuZGVyLlxuXG5cbmZ1bmN0aW9uIHVwZGF0ZUNsYXNzSW5zdGFuY2UoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIGN0b3IsIG5ld1Byb3BzLCByZW5kZXJMYW5lcykge1xuICB2YXIgaW5zdGFuY2UgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG4gIGNsb25lVXBkYXRlUXVldWUoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuICB2YXIgdW5yZXNvbHZlZE9sZFByb3BzID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRQcm9wcztcbiAgdmFyIG9sZFByb3BzID0gd29ya0luUHJvZ3Jlc3MudHlwZSA9PT0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGUgPyB1bnJlc29sdmVkT2xkUHJvcHMgOiByZXNvbHZlRGVmYXVsdFByb3BzKHdvcmtJblByb2dyZXNzLnR5cGUsIHVucmVzb2x2ZWRPbGRQcm9wcyk7XG4gIGluc3RhbmNlLnByb3BzID0gb2xkUHJvcHM7XG4gIHZhciB1bnJlc29sdmVkTmV3UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciBvbGRDb250ZXh0ID0gaW5zdGFuY2UuY29udGV4dDtcbiAgdmFyIGNvbnRleHRUeXBlID0gY3Rvci5jb250ZXh0VHlwZTtcbiAgdmFyIG5leHRDb250ZXh0ID0gZW1wdHlDb250ZXh0T2JqZWN0O1xuXG4gIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdvYmplY3QnICYmIGNvbnRleHRUeXBlICE9PSBudWxsKSB7XG4gICAgbmV4dENvbnRleHQgPSByZWFkQ29udGV4dChjb250ZXh0VHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIG5leHRVbm1hc2tlZENvbnRleHQgPSBnZXRVbm1hc2tlZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIGN0b3IsIHRydWUpO1xuICAgIG5leHRDb250ZXh0ID0gZ2V0TWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgbmV4dFVubWFza2VkQ29udGV4dCk7XG4gIH1cblxuICB2YXIgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID0gY3Rvci5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHM7XG4gIHZhciBoYXNOZXdMaWZlY3ljbGVzID0gdHlwZW9mIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgaW5zdGFuY2UuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUgPT09ICdmdW5jdGlvbic7IC8vIE5vdGU6IER1cmluZyB0aGVzZSBsaWZlLWN5Y2xlcywgaW5zdGFuY2UucHJvcHMvaW5zdGFuY2Uuc3RhdGUgYXJlIHdoYXRcbiAgLy8gZXZlciB0aGUgcHJldmlvdXNseSBhdHRlbXB0ZWQgdG8gcmVuZGVyIC0gbm90IHRoZSBcImN1cnJlbnRcIi4gSG93ZXZlcixcbiAgLy8gZHVyaW5nIGNvbXBvbmVudERpZFVwZGF0ZSB3ZSBwYXNzIHRoZSBcImN1cnJlbnRcIiBwcm9wcy5cbiAgLy8gSW4gb3JkZXIgdG8gc3VwcG9ydCByZWFjdC1saWZlY3ljbGVzLWNvbXBhdCBwb2x5ZmlsbGVkIGNvbXBvbmVudHMsXG4gIC8vIFVuc2FmZSBsaWZlY3ljbGVzIHNob3VsZCBub3QgYmUgaW52b2tlZCBmb3IgY29tcG9uZW50cyB1c2luZyB0aGUgbmV3IEFQSXMuXG5cbiAgaWYgKCFoYXNOZXdMaWZlY3ljbGVzICYmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgaWYgKHVucmVzb2x2ZWRPbGRQcm9wcyAhPT0gdW5yZXNvbHZlZE5ld1Byb3BzIHx8IG9sZENvbnRleHQgIT09IG5leHRDb250ZXh0KSB7XG4gICAgICBjYWxsQ29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyh3b3JrSW5Qcm9ncmVzcywgaW5zdGFuY2UsIG5ld1Byb3BzLCBuZXh0Q29udGV4dCk7XG4gICAgfVxuICB9XG5cbiAgcmVzZXRIYXNGb3JjZVVwZGF0ZUJlZm9yZVByb2Nlc3NpbmcoKTtcbiAgdmFyIG9sZFN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIG5ld1N0YXRlID0gaW5zdGFuY2Uuc3RhdGUgPSBvbGRTdGF0ZTtcbiAgcHJvY2Vzc1VwZGF0ZVF1ZXVlKHdvcmtJblByb2dyZXNzLCBuZXdQcm9wcywgaW5zdGFuY2UsIHJlbmRlckxhbmVzKTtcbiAgbmV3U3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gIGlmICh1bnJlc29sdmVkT2xkUHJvcHMgPT09IHVucmVzb2x2ZWROZXdQcm9wcyAmJiBvbGRTdGF0ZSA9PT0gbmV3U3RhdGUgJiYgIWhhc0NvbnRleHRDaGFuZ2VkKCkgJiYgIWNoZWNrSGFzRm9yY2VVcGRhdGVBZnRlclByb2Nlc3NpbmcoKSAmJiAhKGVuYWJsZUxhenlDb250ZXh0UHJvcGFnYXRpb24gICApKSB7XG4gICAgLy8gSWYgYW4gdXBkYXRlIHdhcyBhbHJlYWR5IGluIHByb2dyZXNzLCB3ZSBzaG91bGQgc2NoZWR1bGUgYW4gVXBkYXRlXG4gICAgLy8gZWZmZWN0IGV2ZW4gdGhvdWdoIHdlJ3JlIGJhaWxpbmcgb3V0LCBzbyB0aGF0IGNXVS9jRFUgYXJlIGNhbGxlZC5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudERpZFVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKHVucmVzb2x2ZWRPbGRQcm9wcyAhPT0gY3VycmVudC5tZW1vaXplZFByb3BzIHx8IG9sZFN0YXRlICE9PSBjdXJyZW50Lm1lbW9pemVkU3RhdGUpIHtcbiAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gVXBkYXRlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmICh1bnJlc29sdmVkT2xkUHJvcHMgIT09IGN1cnJlbnQubWVtb2l6ZWRQcm9wcyB8fCBvbGRTdGF0ZSAhPT0gY3VycmVudC5tZW1vaXplZFN0YXRlKSB7XG4gICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFNuYXBzaG90O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgYXBwbHlEZXJpdmVkU3RhdGVGcm9tUHJvcHMod29ya0luUHJvZ3Jlc3MsIGN0b3IsIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcywgbmV3UHJvcHMpO1xuICAgIG5ld1N0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgfVxuXG4gIHZhciBzaG91bGRVcGRhdGUgPSBjaGVja0hhc0ZvcmNlVXBkYXRlQWZ0ZXJQcm9jZXNzaW5nKCkgfHwgY2hlY2tTaG91bGRDb21wb25lbnRVcGRhdGUod29ya0luUHJvZ3Jlc3MsIGN0b3IsIG9sZFByb3BzLCBuZXdQcm9wcywgb2xkU3RhdGUsIG5ld1N0YXRlLCBuZXh0Q29udGV4dCkgfHwgLy8gVE9ETzogSW4gc29tZSBjYXNlcywgd2UnbGwgZW5kIHVwIGNoZWNraW5nIGlmIGNvbnRleHQgaGFzIGNoYW5nZWQgdHdpY2UsXG4gIC8vIGJvdGggYmVmb3JlIGFuZCBhZnRlciBgc2hvdWxkQ29tcG9uZW50VXBkYXRlYCBoYXMgYmVlbiBjYWxsZWQuIE5vdCBpZGVhbCxcbiAgLy8gYnV0IEknbSBsb2F0aCB0byByZWZhY3RvciB0aGlzIGZ1bmN0aW9uLiBUaGlzIG9ubHkgaGFwcGVucyBmb3IgbWVtb2l6ZWRcbiAgLy8gY29tcG9uZW50cyBzbyBpdCdzIG5vdCB0aGF0IGNvbW1vbi5cbiAgZW5hYmxlTGF6eUNvbnRleHRQcm9wYWdhdGlvbiAgIDtcblxuICBpZiAoc2hvdWxkVXBkYXRlKSB7XG4gICAgLy8gSW4gb3JkZXIgdG8gc3VwcG9ydCByZWFjdC1saWZlY3ljbGVzLWNvbXBhdCBwb2x5ZmlsbGVkIGNvbXBvbmVudHMsXG4gICAgLy8gVW5zYWZlIGxpZmVjeWNsZXMgc2hvdWxkIG5vdCBiZSBpbnZva2VkIGZvciBjb21wb25lbnRzIHVzaW5nIHRoZSBuZXcgQVBJcy5cbiAgICBpZiAoIWhhc05ld0xpZmVjeWNsZXMgJiYgKHR5cGVvZiBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbFVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbFVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBpbnN0YW5jZS5jb21wb25lbnRXaWxsVXBkYXRlKG5ld1Byb3BzLCBuZXdTdGF0ZSwgbmV4dENvbnRleHQpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsVXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsVXBkYXRlKG5ld1Byb3BzLCBuZXdTdGF0ZSwgbmV4dENvbnRleHQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50RGlkVXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBVcGRhdGU7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gU25hcHNob3Q7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIElmIGFuIHVwZGF0ZSB3YXMgYWxyZWFkeSBpbiBwcm9ncmVzcywgd2Ugc2hvdWxkIHNjaGVkdWxlIGFuIFVwZGF0ZVxuICAgIC8vIGVmZmVjdCBldmVuIHRob3VnaCB3ZSdyZSBiYWlsaW5nIG91dCwgc28gdGhhdCBjV1UvY0RVIGFyZSBjYWxsZWQuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmICh1bnJlc29sdmVkT2xkUHJvcHMgIT09IGN1cnJlbnQubWVtb2l6ZWRQcm9wcyB8fCBvbGRTdGF0ZSAhPT0gY3VycmVudC5tZW1vaXplZFN0YXRlKSB7XG4gICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFVwZGF0ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAodW5yZXNvbHZlZE9sZFByb3BzICE9PSBjdXJyZW50Lm1lbW9pemVkUHJvcHMgfHwgb2xkU3RhdGUgIT09IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZSkge1xuICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBTbmFwc2hvdDtcbiAgICAgIH1cbiAgICB9IC8vIElmIHNob3VsZENvbXBvbmVudFVwZGF0ZSByZXR1cm5lZCBmYWxzZSwgd2Ugc2hvdWxkIHN0aWxsIHVwZGF0ZSB0aGVcbiAgICAvLyBtZW1vaXplZCBwcm9wcy9zdGF0ZSB0byBpbmRpY2F0ZSB0aGF0IHRoaXMgd29yayBjYW4gYmUgcmV1c2VkLlxuXG5cbiAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFByb3BzID0gbmV3UHJvcHM7XG4gICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG5ld1N0YXRlO1xuICB9IC8vIFVwZGF0ZSB0aGUgZXhpc3RpbmcgaW5zdGFuY2UncyBzdGF0ZSwgcHJvcHMsIGFuZCBjb250ZXh0IHBvaW50ZXJzIGV2ZW5cbiAgLy8gaWYgc2hvdWxkQ29tcG9uZW50VXBkYXRlIHJldHVybnMgZmFsc2UuXG5cblxuICBpbnN0YW5jZS5wcm9wcyA9IG5ld1Byb3BzO1xuICBpbnN0YW5jZS5zdGF0ZSA9IG5ld1N0YXRlO1xuICBpbnN0YW5jZS5jb250ZXh0ID0gbmV4dENvbnRleHQ7XG4gIHJldHVybiBzaG91bGRVcGRhdGU7XG59XG5cbnZhciBkaWRXYXJuQWJvdXRNYXBzO1xudmFyIGRpZFdhcm5BYm91dEdlbmVyYXRvcnM7XG52YXIgZGlkV2FybkFib3V0U3RyaW5nUmVmcztcbnZhciBvd25lckhhc0tleVVzZVdhcm5pbmc7XG52YXIgb3duZXJIYXNGdW5jdGlvblR5cGVXYXJuaW5nO1xuXG52YXIgd2FybkZvck1pc3NpbmdLZXkgPSBmdW5jdGlvbiAoY2hpbGQsIHJldHVybkZpYmVyKSB7fTtcblxue1xuICBkaWRXYXJuQWJvdXRNYXBzID0gZmFsc2U7XG4gIGRpZFdhcm5BYm91dEdlbmVyYXRvcnMgPSBmYWxzZTtcbiAgZGlkV2FybkFib3V0U3RyaW5nUmVmcyA9IHt9O1xuICAvKipcbiAgICogV2FybiBpZiB0aGVyZSdzIG5vIGtleSBleHBsaWNpdGx5IHNldCBvbiBkeW5hbWljIGFycmF5cyBvZiBjaGlsZHJlbiBvclxuICAgKiBvYmplY3Qga2V5cyBhcmUgbm90IHZhbGlkLiBUaGlzIGFsbG93cyB1cyB0byBrZWVwIHRyYWNrIG9mIGNoaWxkcmVuIGJldHdlZW5cbiAgICogdXBkYXRlcy5cbiAgICovXG5cbiAgb3duZXJIYXNLZXlVc2VXYXJuaW5nID0ge307XG4gIG93bmVySGFzRnVuY3Rpb25UeXBlV2FybmluZyA9IHt9O1xuXG4gIHdhcm5Gb3JNaXNzaW5nS2V5ID0gZnVuY3Rpb24gKGNoaWxkLCByZXR1cm5GaWJlcikge1xuICAgIGlmIChjaGlsZCA9PT0gbnVsbCB8fCB0eXBlb2YgY2hpbGQgIT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjaGlsZC5fc3RvcmUgfHwgY2hpbGQuX3N0b3JlLnZhbGlkYXRlZCB8fCBjaGlsZC5rZXkgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgY2hpbGQuX3N0b3JlICE9PSAnb2JqZWN0Jykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZWFjdCBDb21wb25lbnQgaW4gd2FybkZvck1pc3NpbmdLZXkgc2hvdWxkIGhhdmUgYSBfc3RvcmUuICcgKyAnVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG5cbiAgICBjaGlsZC5fc3RvcmUudmFsaWRhdGVkID0gdHJ1ZTtcbiAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIocmV0dXJuRmliZXIpIHx8ICdDb21wb25lbnQnO1xuXG4gICAgaWYgKG93bmVySGFzS2V5VXNlV2FybmluZ1tjb21wb25lbnROYW1lXSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG93bmVySGFzS2V5VXNlV2FybmluZ1tjb21wb25lbnROYW1lXSA9IHRydWU7XG5cbiAgICBlcnJvcignRWFjaCBjaGlsZCBpbiBhIGxpc3Qgc2hvdWxkIGhhdmUgYSB1bmlxdWUgJyArICdcImtleVwiIHByb3AuIFNlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvd2FybmluZy1rZXlzIGZvciAnICsgJ21vcmUgaW5mb3JtYXRpb24uJyk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvZXJjZVJlZihyZXR1cm5GaWJlciwgY3VycmVudCwgZWxlbWVudCkge1xuICB2YXIgbWl4ZWRSZWYgPSBlbGVtZW50LnJlZjtcblxuICBpZiAobWl4ZWRSZWYgIT09IG51bGwgJiYgdHlwZW9mIG1peGVkUmVmICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBtaXhlZFJlZiAhPT0gJ29iamVjdCcpIHtcbiAgICB7XG4gICAgICAvLyBUT0RPOiBDbGVhbiB0aGlzIHVwIG9uY2Ugd2UgdHVybiBvbiB0aGUgc3RyaW5nIHJlZiB3YXJuaW5nIGZvclxuICAgICAgLy8gZXZlcnlvbmUsIGJlY2F1c2UgdGhlIHN0cmljdCBtb2RlIGNhc2Ugd2lsbCBubyBsb25nZXIgYmUgcmVsZXZhbnRcbiAgICAgIGlmICgocmV0dXJuRmliZXIubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUgfHwgd2FybkFib3V0U3RyaW5nUmVmcykgJiYgLy8gV2Ugd2FybiBpbiBSZWFjdEVsZW1lbnQuanMgaWYgb3duZXIgYW5kIHNlbGYgYXJlIGVxdWFsIGZvciBzdHJpbmcgcmVmc1xuICAgICAgLy8gYmVjYXVzZSB0aGVzZSBjYW5ub3QgYmUgYXV0b21hdGljYWxseSBjb252ZXJ0ZWQgdG8gYW4gYXJyb3cgZnVuY3Rpb25cbiAgICAgIC8vIHVzaW5nIGEgY29kZW1vZC4gVGhlcmVmb3JlLCB3ZSBkb24ndCBoYXZlIHRvIHdhcm4gYWJvdXQgc3RyaW5nIHJlZnMgYWdhaW4uXG4gICAgICAhKGVsZW1lbnQuX293bmVyICYmIGVsZW1lbnQuX3NlbGYgJiYgZWxlbWVudC5fb3duZXIuc3RhdGVOb2RlICE9PSBlbGVtZW50Ll9zZWxmKSkge1xuICAgICAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIocmV0dXJuRmliZXIpIHx8ICdDb21wb25lbnQnO1xuXG4gICAgICAgIGlmICghZGlkV2FybkFib3V0U3RyaW5nUmVmc1tjb21wb25lbnROYW1lXSkge1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGVycm9yKCdBIHN0cmluZyByZWYsIFwiJXNcIiwgaGFzIGJlZW4gZm91bmQgd2l0aGluIGEgc3RyaWN0IG1vZGUgdHJlZS4gJyArICdTdHJpbmcgcmVmcyBhcmUgYSBzb3VyY2Ugb2YgcG90ZW50aWFsIGJ1Z3MgYW5kIHNob3VsZCBiZSBhdm9pZGVkLiAnICsgJ1dlIHJlY29tbWVuZCB1c2luZyB1c2VSZWYoKSBvciBjcmVhdGVSZWYoKSBpbnN0ZWFkLiAnICsgJ0xlYXJuIG1vcmUgYWJvdXQgdXNpbmcgcmVmcyBzYWZlbHkgaGVyZTogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3RyaWN0LW1vZGUtc3RyaW5nLXJlZicsIG1peGVkUmVmKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkaWRXYXJuQWJvdXRTdHJpbmdSZWZzW2NvbXBvbmVudE5hbWVdID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlbGVtZW50Ll9vd25lcikge1xuICAgICAgdmFyIG93bmVyID0gZWxlbWVudC5fb3duZXI7XG4gICAgICB2YXIgaW5zdDtcblxuICAgICAgaWYgKG93bmVyKSB7XG4gICAgICAgIHZhciBvd25lckZpYmVyID0gb3duZXI7XG5cbiAgICAgICAgaWYgKG93bmVyRmliZXIudGFnICE9PSBDbGFzc0NvbXBvbmVudCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRnVuY3Rpb24gY29tcG9uZW50cyBjYW5ub3QgaGF2ZSBzdHJpbmcgcmVmcy4gJyArICdXZSByZWNvbW1lbmQgdXNpbmcgdXNlUmVmKCkgaW5zdGVhZC4gJyArICdMZWFybiBtb3JlIGFib3V0IHVzaW5nIHJlZnMgc2FmZWx5IGhlcmU6ICcgKyAnaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3N0cmljdC1tb2RlLXN0cmluZy1yZWYnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGluc3QgPSBvd25lckZpYmVyLnN0YXRlTm9kZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpbnN0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3Npbmcgb3duZXIgZm9yIHN0cmluZyByZWYgXCIgKyBtaXhlZFJlZiArIFwiLiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBcIiArICdidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgICAgfSAvLyBBc3NpZ25pbmcgdGhpcyB0byBhIGNvbnN0IHNvIEZsb3cga25vd3MgaXQgd29uJ3QgY2hhbmdlIGluIHRoZSBjbG9zdXJlXG5cblxuICAgICAgdmFyIHJlc29sdmVkSW5zdCA9IGluc3Q7XG5cbiAgICAgIHtcbiAgICAgICAgY2hlY2tQcm9wU3RyaW5nQ29lcmNpb24obWl4ZWRSZWYsICdyZWYnKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHN0cmluZ1JlZiA9ICcnICsgbWl4ZWRSZWY7IC8vIENoZWNrIGlmIHByZXZpb3VzIHN0cmluZyByZWYgbWF0Y2hlcyBuZXcgc3RyaW5nIHJlZlxuXG4gICAgICBpZiAoY3VycmVudCAhPT0gbnVsbCAmJiBjdXJyZW50LnJlZiAhPT0gbnVsbCAmJiB0eXBlb2YgY3VycmVudC5yZWYgPT09ICdmdW5jdGlvbicgJiYgY3VycmVudC5yZWYuX3N0cmluZ1JlZiA9PT0gc3RyaW5nUmVmKSB7XG4gICAgICAgIHJldHVybiBjdXJyZW50LnJlZjtcbiAgICAgIH1cblxuICAgICAgdmFyIHJlZiA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgcmVmcyA9IHJlc29sdmVkSW5zdC5yZWZzO1xuXG4gICAgICAgIGlmIChyZWZzID09PSBlbXB0eVJlZnNPYmplY3QpIHtcbiAgICAgICAgICAvLyBUaGlzIGlzIGEgbGF6eSBwb29sZWQgZnJvemVuIG9iamVjdCwgc28gd2UgbmVlZCB0byBpbml0aWFsaXplLlxuICAgICAgICAgIHJlZnMgPSByZXNvbHZlZEluc3QucmVmcyA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgZGVsZXRlIHJlZnNbc3RyaW5nUmVmXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZWZzW3N0cmluZ1JlZl0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgcmVmLl9zdHJpbmdSZWYgPSBzdHJpbmdSZWY7XG4gICAgICByZXR1cm4gcmVmO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodHlwZW9mIG1peGVkUmVmICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHJlZiB0byBiZSBhIGZ1bmN0aW9uLCBhIHN0cmluZywgYW4gb2JqZWN0IHJldHVybmVkIGJ5IFJlYWN0LmNyZWF0ZVJlZigpLCBvciBudWxsLicpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWVsZW1lbnQuX293bmVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkVsZW1lbnQgcmVmIHdhcyBzcGVjaWZpZWQgYXMgYSBzdHJpbmcgKFwiICsgbWl4ZWRSZWYgKyBcIikgYnV0IG5vIG93bmVyIHdhcyBzZXQuIFRoaXMgY291bGQgaGFwcGVuIGZvciBvbmUgb2ZcIiArICcgdGhlIGZvbGxvd2luZyByZWFzb25zOlxcbicgKyAnMS4gWW91IG1heSBiZSBhZGRpbmcgYSByZWYgdG8gYSBmdW5jdGlvbiBjb21wb25lbnRcXG4nICsgXCIyLiBZb3UgbWF5IGJlIGFkZGluZyBhIHJlZiB0byBhIGNvbXBvbmVudCB0aGF0IHdhcyBub3QgY3JlYXRlZCBpbnNpZGUgYSBjb21wb25lbnQncyByZW5kZXIgbWV0aG9kXFxuXCIgKyAnMy4gWW91IGhhdmUgbXVsdGlwbGUgY29waWVzIG9mIFJlYWN0IGxvYWRlZFxcbicgKyAnU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9yZWZzLW11c3QtaGF2ZS1vd25lciBmb3IgbW9yZSBpbmZvcm1hdGlvbi4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWl4ZWRSZWY7XG59XG5cbmZ1bmN0aW9uIHRocm93T25JbnZhbGlkT2JqZWN0VHlwZShyZXR1cm5GaWJlciwgbmV3Q2hpbGQpIHtcbiAgdmFyIGNoaWxkU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG5ld0NoaWxkKTtcbiAgdGhyb3cgbmV3IEVycm9yKFwiT2JqZWN0cyBhcmUgbm90IHZhbGlkIGFzIGEgUmVhY3QgY2hpbGQgKGZvdW5kOiBcIiArIChjaGlsZFN0cmluZyA9PT0gJ1tvYmplY3QgT2JqZWN0XScgPyAnb2JqZWN0IHdpdGgga2V5cyB7JyArIE9iamVjdC5rZXlzKG5ld0NoaWxkKS5qb2luKCcsICcpICsgJ30nIDogY2hpbGRTdHJpbmcpICsgXCIpLiBcIiArICdJZiB5b3UgbWVhbnQgdG8gcmVuZGVyIGEgY29sbGVjdGlvbiBvZiBjaGlsZHJlbiwgdXNlIGFuIGFycmF5ICcgKyAnaW5zdGVhZC4nKTtcbn1cblxuZnVuY3Rpb24gd2Fybk9uRnVuY3Rpb25UeXBlKHJldHVybkZpYmVyKSB7XG4gIHtcbiAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIocmV0dXJuRmliZXIpIHx8ICdDb21wb25lbnQnO1xuXG4gICAgaWYgKG93bmVySGFzRnVuY3Rpb25UeXBlV2FybmluZ1tjb21wb25lbnROYW1lXSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG93bmVySGFzRnVuY3Rpb25UeXBlV2FybmluZ1tjb21wb25lbnROYW1lXSA9IHRydWU7XG5cbiAgICBlcnJvcignRnVuY3Rpb25zIGFyZSBub3QgdmFsaWQgYXMgYSBSZWFjdCBjaGlsZC4gVGhpcyBtYXkgaGFwcGVuIGlmICcgKyAneW91IHJldHVybiBhIENvbXBvbmVudCBpbnN0ZWFkIG9mIDxDb21wb25lbnQgLz4gZnJvbSByZW5kZXIuICcgKyAnT3IgbWF5YmUgeW91IG1lYW50IHRvIGNhbGwgdGhpcyBmdW5jdGlvbiByYXRoZXIgdGhhbiByZXR1cm4gaXQuJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzb2x2ZUxhenkobGF6eVR5cGUpIHtcbiAgdmFyIHBheWxvYWQgPSBsYXp5VHlwZS5fcGF5bG9hZDtcbiAgdmFyIGluaXQgPSBsYXp5VHlwZS5faW5pdDtcbiAgcmV0dXJuIGluaXQocGF5bG9hZCk7XG59IC8vIFRoaXMgd3JhcHBlciBmdW5jdGlvbiBleGlzdHMgYmVjYXVzZSBJIGV4cGVjdCB0byBjbG9uZSB0aGUgY29kZSBpbiBlYWNoIHBhdGhcbi8vIHRvIGJlIGFibGUgdG8gb3B0aW1pemUgZWFjaCBwYXRoIGluZGl2aWR1YWxseSBieSBicmFuY2hpbmcgZWFybHkuIFRoaXMgbmVlZHNcbi8vIGEgY29tcGlsZXIgb3Igd2UgY2FuIGRvIGl0IG1hbnVhbGx5LiBIZWxwZXJzIHRoYXQgZG9uJ3QgbmVlZCB0aGlzIGJyYW5jaGluZ1xuLy8gbGl2ZSBvdXRzaWRlIG9mIHRoaXMgZnVuY3Rpb24uXG5cblxuZnVuY3Rpb24gQ2hpbGRSZWNvbmNpbGVyKHNob3VsZFRyYWNrU2lkZUVmZmVjdHMpIHtcbiAgZnVuY3Rpb24gZGVsZXRlQ2hpbGQocmV0dXJuRmliZXIsIGNoaWxkVG9EZWxldGUpIHtcbiAgICBpZiAoIXNob3VsZFRyYWNrU2lkZUVmZmVjdHMpIHtcbiAgICAgIC8vIE5vb3AuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGRlbGV0aW9ucyA9IHJldHVybkZpYmVyLmRlbGV0aW9ucztcblxuICAgIGlmIChkZWxldGlvbnMgPT09IG51bGwpIHtcbiAgICAgIHJldHVybkZpYmVyLmRlbGV0aW9ucyA9IFtjaGlsZFRvRGVsZXRlXTtcbiAgICAgIHJldHVybkZpYmVyLmZsYWdzIHw9IENoaWxkRGVsZXRpb247XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbGV0aW9ucy5wdXNoKGNoaWxkVG9EZWxldGUpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGRlbGV0ZVJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCkge1xuICAgIGlmICghc2hvdWxkVHJhY2tTaWRlRWZmZWN0cykge1xuICAgICAgLy8gTm9vcC5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gLy8gVE9ETzogRm9yIHRoZSBzaG91bGRDbG9uZSBjYXNlLCB0aGlzIGNvdWxkIGJlIG1pY3JvLW9wdGltaXplZCBhIGJpdCBieVxuICAgIC8vIGFzc3VtaW5nIHRoYXQgYWZ0ZXIgdGhlIGZpcnN0IGNoaWxkIHdlJ3ZlIGFscmVhZHkgYWRkZWQgZXZlcnl0aGluZy5cblxuXG4gICAgdmFyIGNoaWxkVG9EZWxldGUgPSBjdXJyZW50Rmlyc3RDaGlsZDtcblxuICAgIHdoaWxlIChjaGlsZFRvRGVsZXRlICE9PSBudWxsKSB7XG4gICAgICBkZWxldGVDaGlsZChyZXR1cm5GaWJlciwgY2hpbGRUb0RlbGV0ZSk7XG4gICAgICBjaGlsZFRvRGVsZXRlID0gY2hpbGRUb0RlbGV0ZS5zaWJsaW5nO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gbWFwUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkKSB7XG4gICAgLy8gQWRkIHRoZSByZW1haW5pbmcgY2hpbGRyZW4gdG8gYSB0ZW1wb3JhcnkgbWFwIHNvIHRoYXQgd2UgY2FuIGZpbmQgdGhlbSBieVxuICAgIC8vIGtleXMgcXVpY2tseS4gSW1wbGljaXQgKG51bGwpIGtleXMgZ2V0IGFkZGVkIHRvIHRoaXMgc2V0IHdpdGggdGhlaXIgaW5kZXhcbiAgICAvLyBpbnN0ZWFkLlxuICAgIHZhciBleGlzdGluZ0NoaWxkcmVuID0gbmV3IE1hcCgpO1xuICAgIHZhciBleGlzdGluZ0NoaWxkID0gY3VycmVudEZpcnN0Q2hpbGQ7XG5cbiAgICB3aGlsZSAoZXhpc3RpbmdDaGlsZCAhPT0gbnVsbCkge1xuICAgICAgaWYgKGV4aXN0aW5nQ2hpbGQua2V5ICE9PSBudWxsKSB7XG4gICAgICAgIGV4aXN0aW5nQ2hpbGRyZW4uc2V0KGV4aXN0aW5nQ2hpbGQua2V5LCBleGlzdGluZ0NoaWxkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGV4aXN0aW5nQ2hpbGRyZW4uc2V0KGV4aXN0aW5nQ2hpbGQuaW5kZXgsIGV4aXN0aW5nQ2hpbGQpO1xuICAgICAgfVxuXG4gICAgICBleGlzdGluZ0NoaWxkID0gZXhpc3RpbmdDaGlsZC5zaWJsaW5nO1xuICAgIH1cblxuICAgIHJldHVybiBleGlzdGluZ0NoaWxkcmVuO1xuICB9XG5cbiAgZnVuY3Rpb24gdXNlRmliZXIoZmliZXIsIHBlbmRpbmdQcm9wcykge1xuICAgIC8vIFdlIGN1cnJlbnRseSBzZXQgc2libGluZyB0byBudWxsIGFuZCBpbmRleCB0byAwIGhlcmUgYmVjYXVzZSBpdCBpcyBlYXN5XG4gICAgLy8gdG8gZm9yZ2V0IHRvIGRvIGJlZm9yZSByZXR1cm5pbmcgaXQuIEUuZy4gZm9yIHRoZSBzaW5nbGUgY2hpbGQgY2FzZS5cbiAgICB2YXIgY2xvbmUgPSBjcmVhdGVXb3JrSW5Qcm9ncmVzcyhmaWJlciwgcGVuZGluZ1Byb3BzKTtcbiAgICBjbG9uZS5pbmRleCA9IDA7XG4gICAgY2xvbmUuc2libGluZyA9IG51bGw7XG4gICAgcmV0dXJuIGNsb25lO1xuICB9XG5cbiAgZnVuY3Rpb24gcGxhY2VDaGlsZChuZXdGaWJlciwgbGFzdFBsYWNlZEluZGV4LCBuZXdJbmRleCkge1xuICAgIG5ld0ZpYmVyLmluZGV4ID0gbmV3SW5kZXg7XG5cbiAgICBpZiAoIXNob3VsZFRyYWNrU2lkZUVmZmVjdHMpIHtcbiAgICAgIC8vIER1cmluZyBoeWRyYXRpb24sIHRoZSB1c2VJZCBhbGdvcml0aG0gbmVlZHMgdG8ga25vdyB3aGljaCBmaWJlcnMgYXJlXG4gICAgICAvLyBwYXJ0IG9mIGEgbGlzdCBvZiBjaGlsZHJlbiAoYXJyYXlzLCBpdGVyYXRvcnMpLlxuICAgICAgbmV3RmliZXIuZmxhZ3MgfD0gRm9ya2VkO1xuICAgICAgcmV0dXJuIGxhc3RQbGFjZWRJbmRleDtcbiAgICB9XG5cbiAgICB2YXIgY3VycmVudCA9IG5ld0ZpYmVyLmFsdGVybmF0ZTtcblxuICAgIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgICB2YXIgb2xkSW5kZXggPSBjdXJyZW50LmluZGV4O1xuXG4gICAgICBpZiAob2xkSW5kZXggPCBsYXN0UGxhY2VkSW5kZXgpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBhIG1vdmUuXG4gICAgICAgIG5ld0ZpYmVyLmZsYWdzIHw9IFBsYWNlbWVudDtcbiAgICAgICAgcmV0dXJuIGxhc3RQbGFjZWRJbmRleDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRoaXMgaXRlbSBjYW4gc3RheSBpbiBwbGFjZS5cbiAgICAgICAgcmV0dXJuIG9sZEluZGV4O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUaGlzIGlzIGFuIGluc2VydGlvbi5cbiAgICAgIG5ld0ZpYmVyLmZsYWdzIHw9IFBsYWNlbWVudDtcbiAgICAgIHJldHVybiBsYXN0UGxhY2VkSW5kZXg7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcGxhY2VTaW5nbGVDaGlsZChuZXdGaWJlcikge1xuICAgIC8vIFRoaXMgaXMgc2ltcGxlciBmb3IgdGhlIHNpbmdsZSBjaGlsZCBjYXNlLiBXZSBvbmx5IG5lZWQgdG8gZG8gYVxuICAgIC8vIHBsYWNlbWVudCBmb3IgaW5zZXJ0aW5nIG5ldyBjaGlsZHJlbi5cbiAgICBpZiAoc2hvdWxkVHJhY2tTaWRlRWZmZWN0cyAmJiBuZXdGaWJlci5hbHRlcm5hdGUgPT09IG51bGwpIHtcbiAgICAgIG5ld0ZpYmVyLmZsYWdzIHw9IFBsYWNlbWVudDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3RmliZXI7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVUZXh0Tm9kZShyZXR1cm5GaWJlciwgY3VycmVudCwgdGV4dENvbnRlbnQsIGxhbmVzKSB7XG4gICAgaWYgKGN1cnJlbnQgPT09IG51bGwgfHwgY3VycmVudC50YWcgIT09IEhvc3RUZXh0KSB7XG4gICAgICAvLyBJbnNlcnRcbiAgICAgIHZhciBjcmVhdGVkID0gY3JlYXRlRmliZXJGcm9tVGV4dCh0ZXh0Q29udGVudCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMpO1xuICAgICAgY3JlYXRlZC5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgIHJldHVybiBjcmVhdGVkO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBVcGRhdGVcbiAgICAgIHZhciBleGlzdGluZyA9IHVzZUZpYmVyKGN1cnJlbnQsIHRleHRDb250ZW50KTtcbiAgICAgIGV4aXN0aW5nLnJldHVybiA9IHJldHVybkZpYmVyO1xuICAgICAgcmV0dXJuIGV4aXN0aW5nO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUVsZW1lbnQocmV0dXJuRmliZXIsIGN1cnJlbnQsIGVsZW1lbnQsIGxhbmVzKSB7XG4gICAgdmFyIGVsZW1lbnRUeXBlID0gZWxlbWVudC50eXBlO1xuXG4gICAgaWYgKGVsZW1lbnRUeXBlID09PSBSRUFDVF9GUkFHTUVOVF9UWVBFKSB7XG4gICAgICByZXR1cm4gdXBkYXRlRnJhZ21lbnQocmV0dXJuRmliZXIsIGN1cnJlbnQsIGVsZW1lbnQucHJvcHMuY2hpbGRyZW4sIGxhbmVzLCBlbGVtZW50LmtleSk7XG4gICAgfVxuXG4gICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgIGlmIChjdXJyZW50LmVsZW1lbnRUeXBlID09PSBlbGVtZW50VHlwZSB8fCAoIC8vIEtlZXAgdGhpcyBjaGVjayBpbmxpbmUgc28gaXQgb25seSBydW5zIG9uIHRoZSBmYWxzZSBwYXRoOlxuICAgICAgIGlzQ29tcGF0aWJsZUZhbWlseUZvckhvdFJlbG9hZGluZyhjdXJyZW50LCBlbGVtZW50KSApIHx8IC8vIExhenkgdHlwZXMgc2hvdWxkIHJlY29uY2lsZSB0aGVpciByZXNvbHZlZCB0eXBlLlxuICAgICAgLy8gV2UgbmVlZCB0byBkbyB0aGlzIGFmdGVyIHRoZSBIb3QgUmVsb2FkaW5nIGNoZWNrIGFib3ZlLFxuICAgICAgLy8gYmVjYXVzZSBob3QgcmVsb2FkaW5nIGhhcyBkaWZmZXJlbnQgc2VtYW50aWNzIHRoYW4gcHJvZCBiZWNhdXNlXG4gICAgICAvLyBpdCBkb2Vzbid0IHJlc3VzcGVuZC4gU28gd2UgY2FuJ3QgbGV0IHRoZSBjYWxsIGJlbG93IHN1c3BlbmQuXG4gICAgICB0eXBlb2YgZWxlbWVudFR5cGUgPT09ICdvYmplY3QnICYmIGVsZW1lbnRUeXBlICE9PSBudWxsICYmIGVsZW1lbnRUeXBlLiQkdHlwZW9mID09PSBSRUFDVF9MQVpZX1RZUEUgJiYgcmVzb2x2ZUxhenkoZWxlbWVudFR5cGUpID09PSBjdXJyZW50LnR5cGUpIHtcbiAgICAgICAgLy8gTW92ZSBiYXNlZCBvbiBpbmRleFxuICAgICAgICB2YXIgZXhpc3RpbmcgPSB1c2VGaWJlcihjdXJyZW50LCBlbGVtZW50LnByb3BzKTtcbiAgICAgICAgZXhpc3RpbmcucmVmID0gY29lcmNlUmVmKHJldHVybkZpYmVyLCBjdXJyZW50LCBlbGVtZW50KTtcbiAgICAgICAgZXhpc3RpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG5cbiAgICAgICAge1xuICAgICAgICAgIGV4aXN0aW5nLl9kZWJ1Z1NvdXJjZSA9IGVsZW1lbnQuX3NvdXJjZTtcbiAgICAgICAgICBleGlzdGluZy5fZGVidWdPd25lciA9IGVsZW1lbnQuX293bmVyO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGV4aXN0aW5nO1xuICAgICAgfVxuICAgIH0gLy8gSW5zZXJ0XG5cblxuICAgIHZhciBjcmVhdGVkID0gY3JlYXRlRmliZXJGcm9tRWxlbWVudChlbGVtZW50LCByZXR1cm5GaWJlci5tb2RlLCBsYW5lcyk7XG4gICAgY3JlYXRlZC5yZWYgPSBjb2VyY2VSZWYocmV0dXJuRmliZXIsIGN1cnJlbnQsIGVsZW1lbnQpO1xuICAgIGNyZWF0ZWQucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgcmV0dXJuIGNyZWF0ZWQ7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVQb3J0YWwocmV0dXJuRmliZXIsIGN1cnJlbnQsIHBvcnRhbCwgbGFuZXMpIHtcbiAgICBpZiAoY3VycmVudCA9PT0gbnVsbCB8fCBjdXJyZW50LnRhZyAhPT0gSG9zdFBvcnRhbCB8fCBjdXJyZW50LnN0YXRlTm9kZS5jb250YWluZXJJbmZvICE9PSBwb3J0YWwuY29udGFpbmVySW5mbyB8fCBjdXJyZW50LnN0YXRlTm9kZS5pbXBsZW1lbnRhdGlvbiAhPT0gcG9ydGFsLmltcGxlbWVudGF0aW9uKSB7XG4gICAgICAvLyBJbnNlcnRcbiAgICAgIHZhciBjcmVhdGVkID0gY3JlYXRlRmliZXJGcm9tUG9ydGFsKHBvcnRhbCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMpO1xuICAgICAgY3JlYXRlZC5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgIHJldHVybiBjcmVhdGVkO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBVcGRhdGVcbiAgICAgIHZhciBleGlzdGluZyA9IHVzZUZpYmVyKGN1cnJlbnQsIHBvcnRhbC5jaGlsZHJlbiB8fCBbXSk7XG4gICAgICBleGlzdGluZy5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgIHJldHVybiBleGlzdGluZztcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVGcmFnbWVudChyZXR1cm5GaWJlciwgY3VycmVudCwgZnJhZ21lbnQsIGxhbmVzLCBrZXkpIHtcbiAgICBpZiAoY3VycmVudCA9PT0gbnVsbCB8fCBjdXJyZW50LnRhZyAhPT0gRnJhZ21lbnQpIHtcbiAgICAgIC8vIEluc2VydFxuICAgICAgdmFyIGNyZWF0ZWQgPSBjcmVhdGVGaWJlckZyb21GcmFnbWVudChmcmFnbWVudCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMsIGtleSk7XG4gICAgICBjcmVhdGVkLnJldHVybiA9IHJldHVybkZpYmVyO1xuICAgICAgcmV0dXJuIGNyZWF0ZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFVwZGF0ZVxuICAgICAgdmFyIGV4aXN0aW5nID0gdXNlRmliZXIoY3VycmVudCwgZnJhZ21lbnQpO1xuICAgICAgZXhpc3RpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICByZXR1cm4gZXhpc3Rpbmc7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlQ2hpbGQocmV0dXJuRmliZXIsIG5ld0NoaWxkLCBsYW5lcykge1xuICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdzdHJpbmcnICYmIG5ld0NoaWxkICE9PSAnJyB8fCB0eXBlb2YgbmV3Q2hpbGQgPT09ICdudW1iZXInKSB7XG4gICAgICAvLyBUZXh0IG5vZGVzIGRvbid0IGhhdmUga2V5cy4gSWYgdGhlIHByZXZpb3VzIG5vZGUgaXMgaW1wbGljaXRseSBrZXllZFxuICAgICAgLy8gd2UgY2FuIGNvbnRpbnVlIHRvIHJlcGxhY2UgaXQgd2l0aG91dCBhYm9ydGluZyBldmVuIGlmIGl0IGlzIG5vdCBhIHRleHRcbiAgICAgIC8vIG5vZGUuXG4gICAgICB2YXIgY3JlYXRlZCA9IGNyZWF0ZUZpYmVyRnJvbVRleHQoJycgKyBuZXdDaGlsZCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMpO1xuICAgICAgY3JlYXRlZC5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgIHJldHVybiBjcmVhdGVkO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdvYmplY3QnICYmIG5ld0NoaWxkICE9PSBudWxsKSB7XG4gICAgICBzd2l0Y2ggKG5ld0NoaWxkLiQkdHlwZW9mKSB7XG4gICAgICAgIGNhc2UgUkVBQ1RfRUxFTUVOVF9UWVBFOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBfY3JlYXRlZCA9IGNyZWF0ZUZpYmVyRnJvbUVsZW1lbnQobmV3Q2hpbGQsIHJldHVybkZpYmVyLm1vZGUsIGxhbmVzKTtcblxuICAgICAgICAgICAgX2NyZWF0ZWQucmVmID0gY29lcmNlUmVmKHJldHVybkZpYmVyLCBudWxsLCBuZXdDaGlsZCk7XG4gICAgICAgICAgICBfY3JlYXRlZC5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgICAgICAgIHJldHVybiBfY3JlYXRlZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgX2NyZWF0ZWQyID0gY3JlYXRlRmliZXJGcm9tUG9ydGFsKG5ld0NoaWxkLCByZXR1cm5GaWJlci5tb2RlLCBsYW5lcyk7XG5cbiAgICAgICAgICAgIF9jcmVhdGVkMi5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgICAgICAgIHJldHVybiBfY3JlYXRlZDI7XG4gICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBwYXlsb2FkID0gbmV3Q2hpbGQuX3BheWxvYWQ7XG4gICAgICAgICAgICB2YXIgaW5pdCA9IG5ld0NoaWxkLl9pbml0O1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUNoaWxkKHJldHVybkZpYmVyLCBpbml0KHBheWxvYWQpLCBsYW5lcyk7XG4gICAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJheShuZXdDaGlsZCkgfHwgZ2V0SXRlcmF0b3JGbihuZXdDaGlsZCkpIHtcbiAgICAgICAgdmFyIF9jcmVhdGVkMyA9IGNyZWF0ZUZpYmVyRnJvbUZyYWdtZW50KG5ld0NoaWxkLCByZXR1cm5GaWJlci5tb2RlLCBsYW5lcywgbnVsbCk7XG5cbiAgICAgICAgX2NyZWF0ZWQzLnJldHVybiA9IHJldHVybkZpYmVyO1xuICAgICAgICByZXR1cm4gX2NyZWF0ZWQzO1xuICAgICAgfVxuXG4gICAgICB0aHJvd09uSW52YWxpZE9iamVjdFR5cGUocmV0dXJuRmliZXIsIG5ld0NoaWxkKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHdhcm5PbkZ1bmN0aW9uVHlwZShyZXR1cm5GaWJlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVTbG90KHJldHVybkZpYmVyLCBvbGRGaWJlciwgbmV3Q2hpbGQsIGxhbmVzKSB7XG4gICAgLy8gVXBkYXRlIHRoZSBmaWJlciBpZiB0aGUga2V5cyBtYXRjaCwgb3RoZXJ3aXNlIHJldHVybiBudWxsLlxuICAgIHZhciBrZXkgPSBvbGRGaWJlciAhPT0gbnVsbCA/IG9sZEZpYmVyLmtleSA6IG51bGw7XG5cbiAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnc3RyaW5nJyAmJiBuZXdDaGlsZCAhPT0gJycgfHwgdHlwZW9mIG5ld0NoaWxkID09PSAnbnVtYmVyJykge1xuICAgICAgLy8gVGV4dCBub2RlcyBkb24ndCBoYXZlIGtleXMuIElmIHRoZSBwcmV2aW91cyBub2RlIGlzIGltcGxpY2l0bHkga2V5ZWRcbiAgICAgIC8vIHdlIGNhbiBjb250aW51ZSB0byByZXBsYWNlIGl0IHdpdGhvdXQgYWJvcnRpbmcgZXZlbiBpZiBpdCBpcyBub3QgYSB0ZXh0XG4gICAgICAvLyBub2RlLlxuICAgICAgaWYgKGtleSAhPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHVwZGF0ZVRleHROb2RlKHJldHVybkZpYmVyLCBvbGRGaWJlciwgJycgKyBuZXdDaGlsZCwgbGFuZXMpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdvYmplY3QnICYmIG5ld0NoaWxkICE9PSBudWxsKSB7XG4gICAgICBzd2l0Y2ggKG5ld0NoaWxkLiQkdHlwZW9mKSB7XG4gICAgICAgIGNhc2UgUkVBQ1RfRUxFTUVOVF9UWVBFOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlmIChuZXdDaGlsZC5rZXkgPT09IGtleSkge1xuICAgICAgICAgICAgICByZXR1cm4gdXBkYXRlRWxlbWVudChyZXR1cm5GaWJlciwgb2xkRmliZXIsIG5ld0NoaWxkLCBsYW5lcyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZiAobmV3Q2hpbGQua2V5ID09PSBrZXkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZVBvcnRhbChyZXR1cm5GaWJlciwgb2xkRmliZXIsIG5ld0NoaWxkLCBsYW5lcyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBSRUFDVF9MQVpZX1RZUEU6XG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIHBheWxvYWQgPSBuZXdDaGlsZC5fcGF5bG9hZDtcbiAgICAgICAgICAgIHZhciBpbml0ID0gbmV3Q2hpbGQuX2luaXQ7XG4gICAgICAgICAgICByZXR1cm4gdXBkYXRlU2xvdChyZXR1cm5GaWJlciwgb2xkRmliZXIsIGluaXQocGF5bG9hZCksIGxhbmVzKTtcbiAgICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0FycmF5KG5ld0NoaWxkKSB8fCBnZXRJdGVyYXRvckZuKG5ld0NoaWxkKSkge1xuICAgICAgICBpZiAoa2V5ICE9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdXBkYXRlRnJhZ21lbnQocmV0dXJuRmliZXIsIG9sZEZpYmVyLCBuZXdDaGlsZCwgbGFuZXMsIG51bGwpO1xuICAgICAgfVxuXG4gICAgICB0aHJvd09uSW52YWxpZE9iamVjdFR5cGUocmV0dXJuRmliZXIsIG5ld0NoaWxkKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHdhcm5PbkZ1bmN0aW9uVHlwZShyZXR1cm5GaWJlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVGcm9tTWFwKGV4aXN0aW5nQ2hpbGRyZW4sIHJldHVybkZpYmVyLCBuZXdJZHgsIG5ld0NoaWxkLCBsYW5lcykge1xuICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdzdHJpbmcnICYmIG5ld0NoaWxkICE9PSAnJyB8fCB0eXBlb2YgbmV3Q2hpbGQgPT09ICdudW1iZXInKSB7XG4gICAgICAvLyBUZXh0IG5vZGVzIGRvbid0IGhhdmUga2V5cywgc28gd2UgbmVpdGhlciBoYXZlIHRvIGNoZWNrIHRoZSBvbGQgbm9yXG4gICAgICAvLyBuZXcgbm9kZSBmb3IgdGhlIGtleS4gSWYgYm90aCBhcmUgdGV4dCBub2RlcywgdGhleSBtYXRjaC5cbiAgICAgIHZhciBtYXRjaGVkRmliZXIgPSBleGlzdGluZ0NoaWxkcmVuLmdldChuZXdJZHgpIHx8IG51bGw7XG4gICAgICByZXR1cm4gdXBkYXRlVGV4dE5vZGUocmV0dXJuRmliZXIsIG1hdGNoZWRGaWJlciwgJycgKyBuZXdDaGlsZCwgbGFuZXMpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdvYmplY3QnICYmIG5ld0NoaWxkICE9PSBudWxsKSB7XG4gICAgICBzd2l0Y2ggKG5ld0NoaWxkLiQkdHlwZW9mKSB7XG4gICAgICAgIGNhc2UgUkVBQ1RfRUxFTUVOVF9UWVBFOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBfbWF0Y2hlZEZpYmVyID0gZXhpc3RpbmdDaGlsZHJlbi5nZXQobmV3Q2hpbGQua2V5ID09PSBudWxsID8gbmV3SWR4IDogbmV3Q2hpbGQua2V5KSB8fCBudWxsO1xuXG4gICAgICAgICAgICByZXR1cm4gdXBkYXRlRWxlbWVudChyZXR1cm5GaWJlciwgX21hdGNoZWRGaWJlciwgbmV3Q2hpbGQsIGxhbmVzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgX21hdGNoZWRGaWJlcjIgPSBleGlzdGluZ0NoaWxkcmVuLmdldChuZXdDaGlsZC5rZXkgPT09IG51bGwgPyBuZXdJZHggOiBuZXdDaGlsZC5rZXkpIHx8IG51bGw7XG5cbiAgICAgICAgICAgIHJldHVybiB1cGRhdGVQb3J0YWwocmV0dXJuRmliZXIsIF9tYXRjaGVkRmliZXIyLCBuZXdDaGlsZCwgbGFuZXMpO1xuICAgICAgICAgIH1cblxuICAgICAgICBjYXNlIFJFQUNUX0xBWllfVFlQRTpcbiAgICAgICAgICB2YXIgcGF5bG9hZCA9IG5ld0NoaWxkLl9wYXlsb2FkO1xuICAgICAgICAgIHZhciBpbml0ID0gbmV3Q2hpbGQuX2luaXQ7XG4gICAgICAgICAgcmV0dXJuIHVwZGF0ZUZyb21NYXAoZXhpc3RpbmdDaGlsZHJlbiwgcmV0dXJuRmliZXIsIG5ld0lkeCwgaW5pdChwYXlsb2FkKSwgbGFuZXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJheShuZXdDaGlsZCkgfHwgZ2V0SXRlcmF0b3JGbihuZXdDaGlsZCkpIHtcbiAgICAgICAgdmFyIF9tYXRjaGVkRmliZXIzID0gZXhpc3RpbmdDaGlsZHJlbi5nZXQobmV3SWR4KSB8fCBudWxsO1xuXG4gICAgICAgIHJldHVybiB1cGRhdGVGcmFnbWVudChyZXR1cm5GaWJlciwgX21hdGNoZWRGaWJlcjMsIG5ld0NoaWxkLCBsYW5lcywgbnVsbCk7XG4gICAgICB9XG5cbiAgICAgIHRocm93T25JbnZhbGlkT2JqZWN0VHlwZShyZXR1cm5GaWJlciwgbmV3Q2hpbGQpO1xuICAgIH1cblxuICAgIHtcbiAgICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgd2Fybk9uRnVuY3Rpb25UeXBlKHJldHVybkZpYmVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICAvKipcbiAgICogV2FybnMgaWYgdGhlcmUgaXMgYSBkdXBsaWNhdGUgb3IgbWlzc2luZyBrZXlcbiAgICovXG5cblxuICBmdW5jdGlvbiB3YXJuT25JbnZhbGlkS2V5KGNoaWxkLCBrbm93bktleXMsIHJldHVybkZpYmVyKSB7XG4gICAge1xuICAgICAgaWYgKHR5cGVvZiBjaGlsZCAhPT0gJ29iamVjdCcgfHwgY2hpbGQgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGtub3duS2V5cztcbiAgICAgIH1cblxuICAgICAgc3dpdGNoIChjaGlsZC4kJHR5cGVvZikge1xuICAgICAgICBjYXNlIFJFQUNUX0VMRU1FTlRfVFlQRTpcbiAgICAgICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgICAgICB3YXJuRm9yTWlzc2luZ0tleShjaGlsZCwgcmV0dXJuRmliZXIpO1xuICAgICAgICAgIHZhciBrZXkgPSBjaGlsZC5rZXk7XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChrbm93bktleXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGtub3duS2V5cyA9IG5ldyBTZXQoKTtcbiAgICAgICAgICAgIGtub3duS2V5cy5hZGQoa2V5KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICgha25vd25LZXlzLmhhcyhrZXkpKSB7XG4gICAgICAgICAgICBrbm93bktleXMuYWRkKGtleSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlcnJvcignRW5jb3VudGVyZWQgdHdvIGNoaWxkcmVuIHdpdGggdGhlIHNhbWUga2V5LCBgJXNgLiAnICsgJ0tleXMgc2hvdWxkIGJlIHVuaXF1ZSBzbyB0aGF0IGNvbXBvbmVudHMgbWFpbnRhaW4gdGhlaXIgaWRlbnRpdHkgJyArICdhY3Jvc3MgdXBkYXRlcy4gTm9uLXVuaXF1ZSBrZXlzIG1heSBjYXVzZSBjaGlsZHJlbiB0byBiZSAnICsgJ2R1cGxpY2F0ZWQgYW5kL29yIG9taXR0ZWQg4oCUIHRoZSBiZWhhdmlvciBpcyB1bnN1cHBvcnRlZCBhbmQgJyArICdjb3VsZCBjaGFuZ2UgaW4gYSBmdXR1cmUgdmVyc2lvbi4nLCBrZXkpO1xuXG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBSRUFDVF9MQVpZX1RZUEU6XG4gICAgICAgICAgdmFyIHBheWxvYWQgPSBjaGlsZC5fcGF5bG9hZDtcbiAgICAgICAgICB2YXIgaW5pdCA9IGNoaWxkLl9pbml0O1xuICAgICAgICAgIHdhcm5PbkludmFsaWRLZXkoaW5pdChwYXlsb2FkKSwga25vd25LZXlzLCByZXR1cm5GaWJlcik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGtub3duS2V5cztcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlY29uY2lsZUNoaWxkcmVuQXJyYXkocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkLCBuZXdDaGlsZHJlbiwgbGFuZXMpIHtcbiAgICAvLyBUaGlzIGFsZ29yaXRobSBjYW4ndCBvcHRpbWl6ZSBieSBzZWFyY2hpbmcgZnJvbSBib3RoIGVuZHMgc2luY2Ugd2VcbiAgICAvLyBkb24ndCBoYXZlIGJhY2twb2ludGVycyBvbiBmaWJlcnMuIEknbSB0cnlpbmcgdG8gc2VlIGhvdyBmYXIgd2UgY2FuIGdldFxuICAgIC8vIHdpdGggdGhhdCBtb2RlbC4gSWYgaXQgZW5kcyB1cCBub3QgYmVpbmcgd29ydGggdGhlIHRyYWRlb2Zmcywgd2UgY2FuXG4gICAgLy8gYWRkIGl0IGxhdGVyLlxuICAgIC8vIEV2ZW4gd2l0aCBhIHR3byBlbmRlZCBvcHRpbWl6YXRpb24sIHdlJ2Qgd2FudCB0byBvcHRpbWl6ZSBmb3IgdGhlIGNhc2VcbiAgICAvLyB3aGVyZSB0aGVyZSBhcmUgZmV3IGNoYW5nZXMgYW5kIGJydXRlIGZvcmNlIHRoZSBjb21wYXJpc29uIGluc3RlYWQgb2ZcbiAgICAvLyBnb2luZyBmb3IgdGhlIE1hcC4gSXQnZCBsaWtlIHRvIGV4cGxvcmUgaGl0dGluZyB0aGF0IHBhdGggZmlyc3QgaW5cbiAgICAvLyBmb3J3YXJkLW9ubHkgbW9kZSBhbmQgb25seSBnbyBmb3IgdGhlIE1hcCBvbmNlIHdlIG5vdGljZSB0aGF0IHdlIG5lZWRcbiAgICAvLyBsb3RzIG9mIGxvb2sgYWhlYWQuIFRoaXMgZG9lc24ndCBoYW5kbGUgcmV2ZXJzYWwgYXMgd2VsbCBhcyB0d28gZW5kZWRcbiAgICAvLyBzZWFyY2ggYnV0IHRoYXQncyB1bnVzdWFsLiBCZXNpZGVzLCBmb3IgdGhlIHR3byBlbmRlZCBvcHRpbWl6YXRpb24gdG9cbiAgICAvLyB3b3JrIG9uIEl0ZXJhYmxlcywgd2UnZCBuZWVkIHRvIGNvcHkgdGhlIHdob2xlIHNldC5cbiAgICAvLyBJbiB0aGlzIGZpcnN0IGl0ZXJhdGlvbiwgd2UnbGwganVzdCBsaXZlIHdpdGggaGl0dGluZyB0aGUgYmFkIGNhc2VcbiAgICAvLyAoYWRkaW5nIGV2ZXJ5dGhpbmcgdG8gYSBNYXApIGluIGZvciBldmVyeSBpbnNlcnQvbW92ZS5cbiAgICAvLyBJZiB5b3UgY2hhbmdlIHRoaXMgY29kZSwgYWxzbyB1cGRhdGUgcmVjb25jaWxlQ2hpbGRyZW5JdGVyYXRvcigpIHdoaWNoXG4gICAgLy8gdXNlcyB0aGUgc2FtZSBhbGdvcml0aG0uXG4gICAge1xuICAgICAgLy8gRmlyc3QsIHZhbGlkYXRlIGtleXMuXG4gICAgICB2YXIga25vd25LZXlzID0gbnVsbDtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuZXdDaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgY2hpbGQgPSBuZXdDaGlsZHJlbltpXTtcbiAgICAgICAga25vd25LZXlzID0gd2Fybk9uSW52YWxpZEtleShjaGlsZCwga25vd25LZXlzLCByZXR1cm5GaWJlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHJlc3VsdGluZ0ZpcnN0Q2hpbGQgPSBudWxsO1xuICAgIHZhciBwcmV2aW91c05ld0ZpYmVyID0gbnVsbDtcbiAgICB2YXIgb2xkRmliZXIgPSBjdXJyZW50Rmlyc3RDaGlsZDtcbiAgICB2YXIgbGFzdFBsYWNlZEluZGV4ID0gMDtcbiAgICB2YXIgbmV3SWR4ID0gMDtcbiAgICB2YXIgbmV4dE9sZEZpYmVyID0gbnVsbDtcblxuICAgIGZvciAoOyBvbGRGaWJlciAhPT0gbnVsbCAmJiBuZXdJZHggPCBuZXdDaGlsZHJlbi5sZW5ndGg7IG5ld0lkeCsrKSB7XG4gICAgICBpZiAob2xkRmliZXIuaW5kZXggPiBuZXdJZHgpIHtcbiAgICAgICAgbmV4dE9sZEZpYmVyID0gb2xkRmliZXI7XG4gICAgICAgIG9sZEZpYmVyID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHRPbGRGaWJlciA9IG9sZEZpYmVyLnNpYmxpbmc7XG4gICAgICB9XG5cbiAgICAgIHZhciBuZXdGaWJlciA9IHVwZGF0ZVNsb3QocmV0dXJuRmliZXIsIG9sZEZpYmVyLCBuZXdDaGlsZHJlbltuZXdJZHhdLCBsYW5lcyk7XG5cbiAgICAgIGlmIChuZXdGaWJlciA9PT0gbnVsbCkge1xuICAgICAgICAvLyBUT0RPOiBUaGlzIGJyZWFrcyBvbiBlbXB0eSBzbG90cyBsaWtlIG51bGwgY2hpbGRyZW4uIFRoYXQnc1xuICAgICAgICAvLyB1bmZvcnR1bmF0ZSBiZWNhdXNlIGl0IHRyaWdnZXJzIHRoZSBzbG93IHBhdGggYWxsIHRoZSB0aW1lLiBXZSBuZWVkXG4gICAgICAgIC8vIGEgYmV0dGVyIHdheSB0byBjb21tdW5pY2F0ZSB3aGV0aGVyIHRoaXMgd2FzIGEgbWlzcyBvciBudWxsLFxuICAgICAgICAvLyBib29sZWFuLCB1bmRlZmluZWQsIGV0Yy5cbiAgICAgICAgaWYgKG9sZEZpYmVyID09PSBudWxsKSB7XG4gICAgICAgICAgb2xkRmliZXIgPSBuZXh0T2xkRmliZXI7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgaWYgKHNob3VsZFRyYWNrU2lkZUVmZmVjdHMpIHtcbiAgICAgICAgaWYgKG9sZEZpYmVyICYmIG5ld0ZpYmVyLmFsdGVybmF0ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIC8vIFdlIG1hdGNoZWQgdGhlIHNsb3QsIGJ1dCB3ZSBkaWRuJ3QgcmV1c2UgdGhlIGV4aXN0aW5nIGZpYmVyLCBzbyB3ZVxuICAgICAgICAgIC8vIG5lZWQgdG8gZGVsZXRlIHRoZSBleGlzdGluZyBjaGlsZC5cbiAgICAgICAgICBkZWxldGVDaGlsZChyZXR1cm5GaWJlciwgb2xkRmliZXIpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxhc3RQbGFjZWRJbmRleCA9IHBsYWNlQ2hpbGQobmV3RmliZXIsIGxhc3RQbGFjZWRJbmRleCwgbmV3SWR4KTtcblxuICAgICAgaWYgKHByZXZpb3VzTmV3RmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgLy8gVE9ETzogTW92ZSBvdXQgb2YgdGhlIGxvb3AuIFRoaXMgb25seSBoYXBwZW5zIGZvciB0aGUgZmlyc3QgcnVuLlxuICAgICAgICByZXN1bHRpbmdGaXJzdENoaWxkID0gbmV3RmliZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBUT0RPOiBEZWZlciBzaWJsaW5ncyBpZiB3ZSdyZSBub3QgYXQgdGhlIHJpZ2h0IGluZGV4IGZvciB0aGlzIHNsb3QuXG4gICAgICAgIC8vIEkuZS4gaWYgd2UgaGFkIG51bGwgdmFsdWVzIGJlZm9yZSwgdGhlbiB3ZSB3YW50IHRvIGRlZmVyIHRoaXNcbiAgICAgICAgLy8gZm9yIGVhY2ggbnVsbCB2YWx1ZS4gSG93ZXZlciwgd2UgYWxzbyBkb24ndCB3YW50IHRvIGNhbGwgdXBkYXRlU2xvdFxuICAgICAgICAvLyB3aXRoIHRoZSBwcmV2aW91cyBvbmUuXG4gICAgICAgIHByZXZpb3VzTmV3RmliZXIuc2libGluZyA9IG5ld0ZpYmVyO1xuICAgICAgfVxuXG4gICAgICBwcmV2aW91c05ld0ZpYmVyID0gbmV3RmliZXI7XG4gICAgICBvbGRGaWJlciA9IG5leHRPbGRGaWJlcjtcbiAgICB9XG5cbiAgICBpZiAobmV3SWR4ID09PSBuZXdDaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIC8vIFdlJ3ZlIHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgbmV3IGNoaWxkcmVuLiBXZSBjYW4gZGVsZXRlIHRoZSByZXN0LlxuICAgICAgZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIG9sZEZpYmVyKTtcblxuICAgICAgaWYgKGdldElzSHlkcmF0aW5nKCkpIHtcbiAgICAgICAgdmFyIG51bWJlck9mRm9ya3MgPSBuZXdJZHg7XG4gICAgICAgIHB1c2hUcmVlRm9yayhyZXR1cm5GaWJlciwgbnVtYmVyT2ZGb3Jrcyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHRpbmdGaXJzdENoaWxkO1xuICAgIH1cblxuICAgIGlmIChvbGRGaWJlciA9PT0gbnVsbCkge1xuICAgICAgLy8gSWYgd2UgZG9uJ3QgaGF2ZSBhbnkgbW9yZSBleGlzdGluZyBjaGlsZHJlbiB3ZSBjYW4gY2hvb3NlIGEgZmFzdCBwYXRoXG4gICAgICAvLyBzaW5jZSB0aGUgcmVzdCB3aWxsIGFsbCBiZSBpbnNlcnRpb25zLlxuICAgICAgZm9yICg7IG5ld0lkeCA8IG5ld0NoaWxkcmVuLmxlbmd0aDsgbmV3SWR4KyspIHtcbiAgICAgICAgdmFyIF9uZXdGaWJlciA9IGNyZWF0ZUNoaWxkKHJldHVybkZpYmVyLCBuZXdDaGlsZHJlbltuZXdJZHhdLCBsYW5lcyk7XG5cbiAgICAgICAgaWYgKF9uZXdGaWJlciA9PT0gbnVsbCkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGFzdFBsYWNlZEluZGV4ID0gcGxhY2VDaGlsZChfbmV3RmliZXIsIGxhc3RQbGFjZWRJbmRleCwgbmV3SWR4KTtcblxuICAgICAgICBpZiAocHJldmlvdXNOZXdGaWJlciA9PT0gbnVsbCkge1xuICAgICAgICAgIC8vIFRPRE86IE1vdmUgb3V0IG9mIHRoZSBsb29wLiBUaGlzIG9ubHkgaGFwcGVucyBmb3IgdGhlIGZpcnN0IHJ1bi5cbiAgICAgICAgICByZXN1bHRpbmdGaXJzdENoaWxkID0gX25ld0ZpYmVyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByZXZpb3VzTmV3RmliZXIuc2libGluZyA9IF9uZXdGaWJlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByZXZpb3VzTmV3RmliZXIgPSBfbmV3RmliZXI7XG4gICAgICB9XG5cbiAgICAgIGlmIChnZXRJc0h5ZHJhdGluZygpKSB7XG4gICAgICAgIHZhciBfbnVtYmVyT2ZGb3JrcyA9IG5ld0lkeDtcbiAgICAgICAgcHVzaFRyZWVGb3JrKHJldHVybkZpYmVyLCBfbnVtYmVyT2ZGb3Jrcyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHRpbmdGaXJzdENoaWxkO1xuICAgIH0gLy8gQWRkIGFsbCBjaGlsZHJlbiB0byBhIGtleSBtYXAgZm9yIHF1aWNrIGxvb2t1cHMuXG5cblxuICAgIHZhciBleGlzdGluZ0NoaWxkcmVuID0gbWFwUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIG9sZEZpYmVyKTsgLy8gS2VlcCBzY2FubmluZyBhbmQgdXNlIHRoZSBtYXAgdG8gcmVzdG9yZSBkZWxldGVkIGl0ZW1zIGFzIG1vdmVzLlxuXG4gICAgZm9yICg7IG5ld0lkeCA8IG5ld0NoaWxkcmVuLmxlbmd0aDsgbmV3SWR4KyspIHtcbiAgICAgIHZhciBfbmV3RmliZXIyID0gdXBkYXRlRnJvbU1hcChleGlzdGluZ0NoaWxkcmVuLCByZXR1cm5GaWJlciwgbmV3SWR4LCBuZXdDaGlsZHJlbltuZXdJZHhdLCBsYW5lcyk7XG5cbiAgICAgIGlmIChfbmV3RmliZXIyICE9PSBudWxsKSB7XG4gICAgICAgIGlmIChzaG91bGRUcmFja1NpZGVFZmZlY3RzKSB7XG4gICAgICAgICAgaWYgKF9uZXdGaWJlcjIuYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBUaGUgbmV3IGZpYmVyIGlzIGEgd29yayBpbiBwcm9ncmVzcywgYnV0IGlmIHRoZXJlIGV4aXN0cyBhXG4gICAgICAgICAgICAvLyBjdXJyZW50LCB0aGF0IG1lYW5zIHRoYXQgd2UgcmV1c2VkIHRoZSBmaWJlci4gV2UgbmVlZCB0byBkZWxldGVcbiAgICAgICAgICAgIC8vIGl0IGZyb20gdGhlIGNoaWxkIGxpc3Qgc28gdGhhdCB3ZSBkb24ndCBhZGQgaXQgdG8gdGhlIGRlbGV0aW9uXG4gICAgICAgICAgICAvLyBsaXN0LlxuICAgICAgICAgICAgZXhpc3RpbmdDaGlsZHJlbi5kZWxldGUoX25ld0ZpYmVyMi5rZXkgPT09IG51bGwgPyBuZXdJZHggOiBfbmV3RmliZXIyLmtleSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGFzdFBsYWNlZEluZGV4ID0gcGxhY2VDaGlsZChfbmV3RmliZXIyLCBsYXN0UGxhY2VkSW5kZXgsIG5ld0lkeCk7XG5cbiAgICAgICAgaWYgKHByZXZpb3VzTmV3RmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgICByZXN1bHRpbmdGaXJzdENoaWxkID0gX25ld0ZpYmVyMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcmV2aW91c05ld0ZpYmVyLnNpYmxpbmcgPSBfbmV3RmliZXIyO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJldmlvdXNOZXdGaWJlciA9IF9uZXdGaWJlcjI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNob3VsZFRyYWNrU2lkZUVmZmVjdHMpIHtcbiAgICAgIC8vIEFueSBleGlzdGluZyBjaGlsZHJlbiB0aGF0IHdlcmVuJ3QgY29uc3VtZWQgYWJvdmUgd2VyZSBkZWxldGVkLiBXZSBuZWVkXG4gICAgICAvLyB0byBhZGQgdGhlbSB0byB0aGUgZGVsZXRpb24gbGlzdC5cbiAgICAgIGV4aXN0aW5nQ2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgcmV0dXJuIGRlbGV0ZUNoaWxkKHJldHVybkZpYmVyLCBjaGlsZCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoZ2V0SXNIeWRyYXRpbmcoKSkge1xuICAgICAgdmFyIF9udW1iZXJPZkZvcmtzMiA9IG5ld0lkeDtcbiAgICAgIHB1c2hUcmVlRm9yayhyZXR1cm5GaWJlciwgX251bWJlck9mRm9ya3MyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0aW5nRmlyc3RDaGlsZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlY29uY2lsZUNoaWxkcmVuSXRlcmF0b3IocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkLCBuZXdDaGlsZHJlbkl0ZXJhYmxlLCBsYW5lcykge1xuICAgIC8vIFRoaXMgaXMgdGhlIHNhbWUgaW1wbGVtZW50YXRpb24gYXMgcmVjb25jaWxlQ2hpbGRyZW5BcnJheSgpLFxuICAgIC8vIGJ1dCB1c2luZyB0aGUgaXRlcmF0b3IgaW5zdGVhZC5cbiAgICB2YXIgaXRlcmF0b3JGbiA9IGdldEl0ZXJhdG9yRm4obmV3Q2hpbGRyZW5JdGVyYWJsZSk7XG5cbiAgICBpZiAodHlwZW9mIGl0ZXJhdG9yRm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQW4gb2JqZWN0IGlzIG5vdCBhbiBpdGVyYWJsZS4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnIGluICcgKyAnUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cblxuICAgIHtcbiAgICAgIC8vIFdlIGRvbid0IHN1cHBvcnQgcmVuZGVyaW5nIEdlbmVyYXRvcnMgYmVjYXVzZSBpdCdzIGEgbXV0YXRpb24uXG4gICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xMjk5NVxuICAgICAgaWYgKHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgLy8gJEZsb3dGaXhNZSBGbG93IGRvZXNuJ3Qga25vdyBhYm91dCB0b1N0cmluZ1RhZ1xuICAgICAgbmV3Q2hpbGRyZW5JdGVyYWJsZVtTeW1ib2wudG9TdHJpbmdUYWddID09PSAnR2VuZXJhdG9yJykge1xuICAgICAgICBpZiAoIWRpZFdhcm5BYm91dEdlbmVyYXRvcnMpIHtcbiAgICAgICAgICBlcnJvcignVXNpbmcgR2VuZXJhdG9ycyBhcyBjaGlsZHJlbiBpcyB1bnN1cHBvcnRlZCBhbmQgd2lsbCBsaWtlbHkgeWllbGQgJyArICd1bmV4cGVjdGVkIHJlc3VsdHMgYmVjYXVzZSBlbnVtZXJhdGluZyBhIGdlbmVyYXRvciBtdXRhdGVzIGl0LiAnICsgJ1lvdSBtYXkgY29udmVydCBpdCB0byBhbiBhcnJheSB3aXRoIGBBcnJheS5mcm9tKClgIG9yIHRoZSAnICsgJ2BbLi4uc3ByZWFkXWAgb3BlcmF0b3IgYmVmb3JlIHJlbmRlcmluZy4gS2VlcCBpbiBtaW5kICcgKyAneW91IG1pZ2h0IG5lZWQgdG8gcG9seWZpbGwgdGhlc2UgZmVhdHVyZXMgZm9yIG9sZGVyIGJyb3dzZXJzLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgZGlkV2FybkFib3V0R2VuZXJhdG9ycyA9IHRydWU7XG4gICAgICB9IC8vIFdhcm4gYWJvdXQgdXNpbmcgTWFwcyBhcyBjaGlsZHJlblxuXG5cbiAgICAgIGlmIChuZXdDaGlsZHJlbkl0ZXJhYmxlLmVudHJpZXMgPT09IGl0ZXJhdG9yRm4pIHtcbiAgICAgICAgaWYgKCFkaWRXYXJuQWJvdXRNYXBzKSB7XG4gICAgICAgICAgZXJyb3IoJ1VzaW5nIE1hcHMgYXMgY2hpbGRyZW4gaXMgbm90IHN1cHBvcnRlZC4gJyArICdVc2UgYW4gYXJyYXkgb2Yga2V5ZWQgUmVhY3RFbGVtZW50cyBpbnN0ZWFkLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgZGlkV2FybkFib3V0TWFwcyA9IHRydWU7XG4gICAgICB9IC8vIEZpcnN0LCB2YWxpZGF0ZSBrZXlzLlxuICAgICAgLy8gV2UnbGwgZ2V0IGEgZGlmZmVyZW50IGl0ZXJhdG9yIGxhdGVyIGZvciB0aGUgbWFpbiBwYXNzLlxuXG5cbiAgICAgIHZhciBfbmV3Q2hpbGRyZW4gPSBpdGVyYXRvckZuLmNhbGwobmV3Q2hpbGRyZW5JdGVyYWJsZSk7XG5cbiAgICAgIGlmIChfbmV3Q2hpbGRyZW4pIHtcbiAgICAgICAgdmFyIGtub3duS2V5cyA9IG51bGw7XG5cbiAgICAgICAgdmFyIF9zdGVwID0gX25ld0NoaWxkcmVuLm5leHQoKTtcblxuICAgICAgICBmb3IgKDsgIV9zdGVwLmRvbmU7IF9zdGVwID0gX25ld0NoaWxkcmVuLm5leHQoKSkge1xuICAgICAgICAgIHZhciBjaGlsZCA9IF9zdGVwLnZhbHVlO1xuICAgICAgICAgIGtub3duS2V5cyA9IHdhcm5PbkludmFsaWRLZXkoY2hpbGQsIGtub3duS2V5cywgcmV0dXJuRmliZXIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIG5ld0NoaWxkcmVuID0gaXRlcmF0b3JGbi5jYWxsKG5ld0NoaWxkcmVuSXRlcmFibGUpO1xuXG4gICAgaWYgKG5ld0NoaWxkcmVuID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQW4gaXRlcmFibGUgb2JqZWN0IHByb3ZpZGVkIG5vIGl0ZXJhdG9yLicpO1xuICAgIH1cblxuICAgIHZhciByZXN1bHRpbmdGaXJzdENoaWxkID0gbnVsbDtcbiAgICB2YXIgcHJldmlvdXNOZXdGaWJlciA9IG51bGw7XG4gICAgdmFyIG9sZEZpYmVyID0gY3VycmVudEZpcnN0Q2hpbGQ7XG4gICAgdmFyIGxhc3RQbGFjZWRJbmRleCA9IDA7XG4gICAgdmFyIG5ld0lkeCA9IDA7XG4gICAgdmFyIG5leHRPbGRGaWJlciA9IG51bGw7XG4gICAgdmFyIHN0ZXAgPSBuZXdDaGlsZHJlbi5uZXh0KCk7XG5cbiAgICBmb3IgKDsgb2xkRmliZXIgIT09IG51bGwgJiYgIXN0ZXAuZG9uZTsgbmV3SWR4KyssIHN0ZXAgPSBuZXdDaGlsZHJlbi5uZXh0KCkpIHtcbiAgICAgIGlmIChvbGRGaWJlci5pbmRleCA+IG5ld0lkeCkge1xuICAgICAgICBuZXh0T2xkRmliZXIgPSBvbGRGaWJlcjtcbiAgICAgICAgb2xkRmliZXIgPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV4dE9sZEZpYmVyID0gb2xkRmliZXIuc2libGluZztcbiAgICAgIH1cblxuICAgICAgdmFyIG5ld0ZpYmVyID0gdXBkYXRlU2xvdChyZXR1cm5GaWJlciwgb2xkRmliZXIsIHN0ZXAudmFsdWUsIGxhbmVzKTtcblxuICAgICAgaWYgKG5ld0ZpYmVyID09PSBudWxsKSB7XG4gICAgICAgIC8vIFRPRE86IFRoaXMgYnJlYWtzIG9uIGVtcHR5IHNsb3RzIGxpa2UgbnVsbCBjaGlsZHJlbi4gVGhhdCdzXG4gICAgICAgIC8vIHVuZm9ydHVuYXRlIGJlY2F1c2UgaXQgdHJpZ2dlcnMgdGhlIHNsb3cgcGF0aCBhbGwgdGhlIHRpbWUuIFdlIG5lZWRcbiAgICAgICAgLy8gYSBiZXR0ZXIgd2F5IHRvIGNvbW11bmljYXRlIHdoZXRoZXIgdGhpcyB3YXMgYSBtaXNzIG9yIG51bGwsXG4gICAgICAgIC8vIGJvb2xlYW4sIHVuZGVmaW5lZCwgZXRjLlxuICAgICAgICBpZiAob2xkRmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgICBvbGRGaWJlciA9IG5leHRPbGRGaWJlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2hvdWxkVHJhY2tTaWRlRWZmZWN0cykge1xuICAgICAgICBpZiAob2xkRmliZXIgJiYgbmV3RmliZXIuYWx0ZXJuYXRlID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gV2UgbWF0Y2hlZCB0aGUgc2xvdCwgYnV0IHdlIGRpZG4ndCByZXVzZSB0aGUgZXhpc3RpbmcgZmliZXIsIHNvIHdlXG4gICAgICAgICAgLy8gbmVlZCB0byBkZWxldGUgdGhlIGV4aXN0aW5nIGNoaWxkLlxuICAgICAgICAgIGRlbGV0ZUNoaWxkKHJldHVybkZpYmVyLCBvbGRGaWJlcik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbGFzdFBsYWNlZEluZGV4ID0gcGxhY2VDaGlsZChuZXdGaWJlciwgbGFzdFBsYWNlZEluZGV4LCBuZXdJZHgpO1xuXG4gICAgICBpZiAocHJldmlvdXNOZXdGaWJlciA9PT0gbnVsbCkge1xuICAgICAgICAvLyBUT0RPOiBNb3ZlIG91dCBvZiB0aGUgbG9vcC4gVGhpcyBvbmx5IGhhcHBlbnMgZm9yIHRoZSBmaXJzdCBydW4uXG4gICAgICAgIHJlc3VsdGluZ0ZpcnN0Q2hpbGQgPSBuZXdGaWJlcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRPRE86IERlZmVyIHNpYmxpbmdzIGlmIHdlJ3JlIG5vdCBhdCB0aGUgcmlnaHQgaW5kZXggZm9yIHRoaXMgc2xvdC5cbiAgICAgICAgLy8gSS5lLiBpZiB3ZSBoYWQgbnVsbCB2YWx1ZXMgYmVmb3JlLCB0aGVuIHdlIHdhbnQgdG8gZGVmZXIgdGhpc1xuICAgICAgICAvLyBmb3IgZWFjaCBudWxsIHZhbHVlLiBIb3dldmVyLCB3ZSBhbHNvIGRvbid0IHdhbnQgdG8gY2FsbCB1cGRhdGVTbG90XG4gICAgICAgIC8vIHdpdGggdGhlIHByZXZpb3VzIG9uZS5cbiAgICAgICAgcHJldmlvdXNOZXdGaWJlci5zaWJsaW5nID0gbmV3RmliZXI7XG4gICAgICB9XG5cbiAgICAgIHByZXZpb3VzTmV3RmliZXIgPSBuZXdGaWJlcjtcbiAgICAgIG9sZEZpYmVyID0gbmV4dE9sZEZpYmVyO1xuICAgIH1cblxuICAgIGlmIChzdGVwLmRvbmUpIHtcbiAgICAgIC8vIFdlJ3ZlIHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgbmV3IGNoaWxkcmVuLiBXZSBjYW4gZGVsZXRlIHRoZSByZXN0LlxuICAgICAgZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIG9sZEZpYmVyKTtcblxuICAgICAgaWYgKGdldElzSHlkcmF0aW5nKCkpIHtcbiAgICAgICAgdmFyIG51bWJlck9mRm9ya3MgPSBuZXdJZHg7XG4gICAgICAgIHB1c2hUcmVlRm9yayhyZXR1cm5GaWJlciwgbnVtYmVyT2ZGb3Jrcyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHRpbmdGaXJzdENoaWxkO1xuICAgIH1cblxuICAgIGlmIChvbGRGaWJlciA9PT0gbnVsbCkge1xuICAgICAgLy8gSWYgd2UgZG9uJ3QgaGF2ZSBhbnkgbW9yZSBleGlzdGluZyBjaGlsZHJlbiB3ZSBjYW4gY2hvb3NlIGEgZmFzdCBwYXRoXG4gICAgICAvLyBzaW5jZSB0aGUgcmVzdCB3aWxsIGFsbCBiZSBpbnNlcnRpb25zLlxuICAgICAgZm9yICg7ICFzdGVwLmRvbmU7IG5ld0lkeCsrLCBzdGVwID0gbmV3Q2hpbGRyZW4ubmV4dCgpKSB7XG4gICAgICAgIHZhciBfbmV3RmliZXIzID0gY3JlYXRlQ2hpbGQocmV0dXJuRmliZXIsIHN0ZXAudmFsdWUsIGxhbmVzKTtcblxuICAgICAgICBpZiAoX25ld0ZpYmVyMyA9PT0gbnVsbCkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGFzdFBsYWNlZEluZGV4ID0gcGxhY2VDaGlsZChfbmV3RmliZXIzLCBsYXN0UGxhY2VkSW5kZXgsIG5ld0lkeCk7XG5cbiAgICAgICAgaWYgKHByZXZpb3VzTmV3RmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBUT0RPOiBNb3ZlIG91dCBvZiB0aGUgbG9vcC4gVGhpcyBvbmx5IGhhcHBlbnMgZm9yIHRoZSBmaXJzdCBydW4uXG4gICAgICAgICAgcmVzdWx0aW5nRmlyc3RDaGlsZCA9IF9uZXdGaWJlcjM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJldmlvdXNOZXdGaWJlci5zaWJsaW5nID0gX25ld0ZpYmVyMztcbiAgICAgICAgfVxuXG4gICAgICAgIHByZXZpb3VzTmV3RmliZXIgPSBfbmV3RmliZXIzO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2V0SXNIeWRyYXRpbmcoKSkge1xuICAgICAgICB2YXIgX251bWJlck9mRm9ya3MzID0gbmV3SWR4O1xuICAgICAgICBwdXNoVHJlZUZvcmsocmV0dXJuRmliZXIsIF9udW1iZXJPZkZvcmtzMyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHRpbmdGaXJzdENoaWxkO1xuICAgIH0gLy8gQWRkIGFsbCBjaGlsZHJlbiB0byBhIGtleSBtYXAgZm9yIHF1aWNrIGxvb2t1cHMuXG5cblxuICAgIHZhciBleGlzdGluZ0NoaWxkcmVuID0gbWFwUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIG9sZEZpYmVyKTsgLy8gS2VlcCBzY2FubmluZyBhbmQgdXNlIHRoZSBtYXAgdG8gcmVzdG9yZSBkZWxldGVkIGl0ZW1zIGFzIG1vdmVzLlxuXG4gICAgZm9yICg7ICFzdGVwLmRvbmU7IG5ld0lkeCsrLCBzdGVwID0gbmV3Q2hpbGRyZW4ubmV4dCgpKSB7XG4gICAgICB2YXIgX25ld0ZpYmVyNCA9IHVwZGF0ZUZyb21NYXAoZXhpc3RpbmdDaGlsZHJlbiwgcmV0dXJuRmliZXIsIG5ld0lkeCwgc3RlcC52YWx1ZSwgbGFuZXMpO1xuXG4gICAgICBpZiAoX25ld0ZpYmVyNCAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoc2hvdWxkVHJhY2tTaWRlRWZmZWN0cykge1xuICAgICAgICAgIGlmIChfbmV3RmliZXI0LmFsdGVybmF0ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gVGhlIG5ldyBmaWJlciBpcyBhIHdvcmsgaW4gcHJvZ3Jlc3MsIGJ1dCBpZiB0aGVyZSBleGlzdHMgYVxuICAgICAgICAgICAgLy8gY3VycmVudCwgdGhhdCBtZWFucyB0aGF0IHdlIHJldXNlZCB0aGUgZmliZXIuIFdlIG5lZWQgdG8gZGVsZXRlXG4gICAgICAgICAgICAvLyBpdCBmcm9tIHRoZSBjaGlsZCBsaXN0IHNvIHRoYXQgd2UgZG9uJ3QgYWRkIGl0IHRvIHRoZSBkZWxldGlvblxuICAgICAgICAgICAgLy8gbGlzdC5cbiAgICAgICAgICAgIGV4aXN0aW5nQ2hpbGRyZW4uZGVsZXRlKF9uZXdGaWJlcjQua2V5ID09PSBudWxsID8gbmV3SWR4IDogX25ld0ZpYmVyNC5rZXkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxhc3RQbGFjZWRJbmRleCA9IHBsYWNlQ2hpbGQoX25ld0ZpYmVyNCwgbGFzdFBsYWNlZEluZGV4LCBuZXdJZHgpO1xuXG4gICAgICAgIGlmIChwcmV2aW91c05ld0ZpYmVyID09PSBudWxsKSB7XG4gICAgICAgICAgcmVzdWx0aW5nRmlyc3RDaGlsZCA9IF9uZXdGaWJlcjQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJldmlvdXNOZXdGaWJlci5zaWJsaW5nID0gX25ld0ZpYmVyNDtcbiAgICAgICAgfVxuXG4gICAgICAgIHByZXZpb3VzTmV3RmliZXIgPSBfbmV3RmliZXI0O1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzaG91bGRUcmFja1NpZGVFZmZlY3RzKSB7XG4gICAgICAvLyBBbnkgZXhpc3RpbmcgY2hpbGRyZW4gdGhhdCB3ZXJlbid0IGNvbnN1bWVkIGFib3ZlIHdlcmUgZGVsZXRlZC4gV2UgbmVlZFxuICAgICAgLy8gdG8gYWRkIHRoZW0gdG8gdGhlIGRlbGV0aW9uIGxpc3QuXG4gICAgICBleGlzdGluZ0NoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgIHJldHVybiBkZWxldGVDaGlsZChyZXR1cm5GaWJlciwgY2hpbGQpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGdldElzSHlkcmF0aW5nKCkpIHtcbiAgICAgIHZhciBfbnVtYmVyT2ZGb3JrczQgPSBuZXdJZHg7XG4gICAgICBwdXNoVHJlZUZvcmsocmV0dXJuRmliZXIsIF9udW1iZXJPZkZvcmtzNCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdGluZ0ZpcnN0Q2hpbGQ7XG4gIH1cblxuICBmdW5jdGlvbiByZWNvbmNpbGVTaW5nbGVUZXh0Tm9kZShyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQsIHRleHRDb250ZW50LCBsYW5lcykge1xuICAgIC8vIFRoZXJlJ3Mgbm8gbmVlZCB0byBjaGVjayBmb3Iga2V5cyBvbiB0ZXh0IG5vZGVzIHNpbmNlIHdlIGRvbid0IGhhdmUgYVxuICAgIC8vIHdheSB0byBkZWZpbmUgdGhlbS5cbiAgICBpZiAoY3VycmVudEZpcnN0Q2hpbGQgIT09IG51bGwgJiYgY3VycmVudEZpcnN0Q2hpbGQudGFnID09PSBIb3N0VGV4dCkge1xuICAgICAgLy8gV2UgYWxyZWFkeSBoYXZlIGFuIGV4aXN0aW5nIG5vZGUgc28gbGV0J3MganVzdCB1cGRhdGUgaXQgYW5kIGRlbGV0ZVxuICAgICAgLy8gdGhlIHJlc3QuXG4gICAgICBkZWxldGVSZW1haW5pbmdDaGlsZHJlbihyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQuc2libGluZyk7XG4gICAgICB2YXIgZXhpc3RpbmcgPSB1c2VGaWJlcihjdXJyZW50Rmlyc3RDaGlsZCwgdGV4dENvbnRlbnQpO1xuICAgICAgZXhpc3RpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICByZXR1cm4gZXhpc3Rpbmc7XG4gICAgfSAvLyBUaGUgZXhpc3RpbmcgZmlyc3QgY2hpbGQgaXMgbm90IGEgdGV4dCBub2RlIHNvIHdlIG5lZWQgdG8gY3JlYXRlIG9uZVxuICAgIC8vIGFuZCBkZWxldGUgdGhlIGV4aXN0aW5nIG9uZXMuXG5cblxuICAgIGRlbGV0ZVJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCk7XG4gICAgdmFyIGNyZWF0ZWQgPSBjcmVhdGVGaWJlckZyb21UZXh0KHRleHRDb250ZW50LCByZXR1cm5GaWJlci5tb2RlLCBsYW5lcyk7XG4gICAgY3JlYXRlZC5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICByZXR1cm4gY3JlYXRlZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlY29uY2lsZVNpbmdsZUVsZW1lbnQocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkLCBlbGVtZW50LCBsYW5lcykge1xuICAgIHZhciBrZXkgPSBlbGVtZW50LmtleTtcbiAgICB2YXIgY2hpbGQgPSBjdXJyZW50Rmlyc3RDaGlsZDtcblxuICAgIHdoaWxlIChjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgLy8gVE9ETzogSWYga2V5ID09PSBudWxsIGFuZCBjaGlsZC5rZXkgPT09IG51bGwsIHRoZW4gdGhpcyBvbmx5IGFwcGxpZXMgdG9cbiAgICAgIC8vIHRoZSBmaXJzdCBpdGVtIGluIHRoZSBsaXN0LlxuICAgICAgaWYgKGNoaWxkLmtleSA9PT0ga2V5KSB7XG4gICAgICAgIHZhciBlbGVtZW50VHlwZSA9IGVsZW1lbnQudHlwZTtcblxuICAgICAgICBpZiAoZWxlbWVudFR5cGUgPT09IFJFQUNUX0ZSQUdNRU5UX1RZUEUpIHtcbiAgICAgICAgICBpZiAoY2hpbGQudGFnID09PSBGcmFnbWVudCkge1xuICAgICAgICAgICAgZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIGNoaWxkLnNpYmxpbmcpO1xuICAgICAgICAgICAgdmFyIGV4aXN0aW5nID0gdXNlRmliZXIoY2hpbGQsIGVsZW1lbnQucHJvcHMuY2hpbGRyZW4pO1xuICAgICAgICAgICAgZXhpc3RpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZXhpc3RpbmcuX2RlYnVnU291cmNlID0gZWxlbWVudC5fc291cmNlO1xuICAgICAgICAgICAgICBleGlzdGluZy5fZGVidWdPd25lciA9IGVsZW1lbnQuX293bmVyO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gZXhpc3Rpbmc7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChjaGlsZC5lbGVtZW50VHlwZSA9PT0gZWxlbWVudFR5cGUgfHwgKCAvLyBLZWVwIHRoaXMgY2hlY2sgaW5saW5lIHNvIGl0IG9ubHkgcnVucyBvbiB0aGUgZmFsc2UgcGF0aDpcbiAgICAgICAgICAgaXNDb21wYXRpYmxlRmFtaWx5Rm9ySG90UmVsb2FkaW5nKGNoaWxkLCBlbGVtZW50KSApIHx8IC8vIExhenkgdHlwZXMgc2hvdWxkIHJlY29uY2lsZSB0aGVpciByZXNvbHZlZCB0eXBlLlxuICAgICAgICAgIC8vIFdlIG5lZWQgdG8gZG8gdGhpcyBhZnRlciB0aGUgSG90IFJlbG9hZGluZyBjaGVjayBhYm92ZSxcbiAgICAgICAgICAvLyBiZWNhdXNlIGhvdCByZWxvYWRpbmcgaGFzIGRpZmZlcmVudCBzZW1hbnRpY3MgdGhhbiBwcm9kIGJlY2F1c2VcbiAgICAgICAgICAvLyBpdCBkb2Vzbid0IHJlc3VzcGVuZC4gU28gd2UgY2FuJ3QgbGV0IHRoZSBjYWxsIGJlbG93IHN1c3BlbmQuXG4gICAgICAgICAgdHlwZW9mIGVsZW1lbnRUeXBlID09PSAnb2JqZWN0JyAmJiBlbGVtZW50VHlwZSAhPT0gbnVsbCAmJiBlbGVtZW50VHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfTEFaWV9UWVBFICYmIHJlc29sdmVMYXp5KGVsZW1lbnRUeXBlKSA9PT0gY2hpbGQudHlwZSkge1xuICAgICAgICAgICAgZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIGNoaWxkLnNpYmxpbmcpO1xuXG4gICAgICAgICAgICB2YXIgX2V4aXN0aW5nID0gdXNlRmliZXIoY2hpbGQsIGVsZW1lbnQucHJvcHMpO1xuXG4gICAgICAgICAgICBfZXhpc3RpbmcucmVmID0gY29lcmNlUmVmKHJldHVybkZpYmVyLCBjaGlsZCwgZWxlbWVudCk7XG4gICAgICAgICAgICBfZXhpc3RpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgX2V4aXN0aW5nLl9kZWJ1Z1NvdXJjZSA9IGVsZW1lbnQuX3NvdXJjZTtcbiAgICAgICAgICAgICAgX2V4aXN0aW5nLl9kZWJ1Z093bmVyID0gZWxlbWVudC5fb3duZXI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBfZXhpc3Rpbmc7XG4gICAgICAgICAgfVxuICAgICAgICB9IC8vIERpZG4ndCBtYXRjaC5cblxuXG4gICAgICAgIGRlbGV0ZVJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBjaGlsZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlQ2hpbGQocmV0dXJuRmliZXIsIGNoaWxkKTtcbiAgICAgIH1cblxuICAgICAgY2hpbGQgPSBjaGlsZC5zaWJsaW5nO1xuICAgIH1cblxuICAgIGlmIChlbGVtZW50LnR5cGUgPT09IFJFQUNUX0ZSQUdNRU5UX1RZUEUpIHtcbiAgICAgIHZhciBjcmVhdGVkID0gY3JlYXRlRmliZXJGcm9tRnJhZ21lbnQoZWxlbWVudC5wcm9wcy5jaGlsZHJlbiwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMsIGVsZW1lbnQua2V5KTtcbiAgICAgIGNyZWF0ZWQucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICByZXR1cm4gY3JlYXRlZDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIF9jcmVhdGVkNCA9IGNyZWF0ZUZpYmVyRnJvbUVsZW1lbnQoZWxlbWVudCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMpO1xuXG4gICAgICBfY3JlYXRlZDQucmVmID0gY29lcmNlUmVmKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgZWxlbWVudCk7XG4gICAgICBfY3JlYXRlZDQucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICByZXR1cm4gX2NyZWF0ZWQ0O1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlY29uY2lsZVNpbmdsZVBvcnRhbChyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQsIHBvcnRhbCwgbGFuZXMpIHtcbiAgICB2YXIga2V5ID0gcG9ydGFsLmtleTtcbiAgICB2YXIgY2hpbGQgPSBjdXJyZW50Rmlyc3RDaGlsZDtcblxuICAgIHdoaWxlIChjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgLy8gVE9ETzogSWYga2V5ID09PSBudWxsIGFuZCBjaGlsZC5rZXkgPT09IG51bGwsIHRoZW4gdGhpcyBvbmx5IGFwcGxpZXMgdG9cbiAgICAgIC8vIHRoZSBmaXJzdCBpdGVtIGluIHRoZSBsaXN0LlxuICAgICAgaWYgKGNoaWxkLmtleSA9PT0ga2V5KSB7XG4gICAgICAgIGlmIChjaGlsZC50YWcgPT09IEhvc3RQb3J0YWwgJiYgY2hpbGQuc3RhdGVOb2RlLmNvbnRhaW5lckluZm8gPT09IHBvcnRhbC5jb250YWluZXJJbmZvICYmIGNoaWxkLnN0YXRlTm9kZS5pbXBsZW1lbnRhdGlvbiA9PT0gcG9ydGFsLmltcGxlbWVudGF0aW9uKSB7XG4gICAgICAgICAgZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIGNoaWxkLnNpYmxpbmcpO1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IHVzZUZpYmVyKGNoaWxkLCBwb3J0YWwuY2hpbGRyZW4gfHwgW10pO1xuICAgICAgICAgIGV4aXN0aW5nLnJldHVybiA9IHJldHVybkZpYmVyO1xuICAgICAgICAgIHJldHVybiBleGlzdGluZztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZWxldGVSZW1haW5pbmdDaGlsZHJlbihyZXR1cm5GaWJlciwgY2hpbGQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWxldGVDaGlsZChyZXR1cm5GaWJlciwgY2hpbGQpO1xuICAgICAgfVxuXG4gICAgICBjaGlsZCA9IGNoaWxkLnNpYmxpbmc7XG4gICAgfVxuXG4gICAgdmFyIGNyZWF0ZWQgPSBjcmVhdGVGaWJlckZyb21Qb3J0YWwocG9ydGFsLCByZXR1cm5GaWJlci5tb2RlLCBsYW5lcyk7XG4gICAgY3JlYXRlZC5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICByZXR1cm4gY3JlYXRlZDtcbiAgfSAvLyBUaGlzIEFQSSB3aWxsIHRhZyB0aGUgY2hpbGRyZW4gd2l0aCB0aGUgc2lkZS1lZmZlY3Qgb2YgdGhlIHJlY29uY2lsaWF0aW9uXG4gIC8vIGl0c2VsZi4gVGhleSB3aWxsIGJlIGFkZGVkIHRvIHRoZSBzaWRlLWVmZmVjdCBsaXN0IGFzIHdlIHBhc3MgdGhyb3VnaCB0aGVcbiAgLy8gY2hpbGRyZW4gYW5kIHRoZSBwYXJlbnQuXG5cblxuICBmdW5jdGlvbiByZWNvbmNpbGVDaGlsZEZpYmVycyhyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQsIG5ld0NoaWxkLCBsYW5lcykge1xuICAgIC8vIFRoaXMgZnVuY3Rpb24gaXMgbm90IHJlY3Vyc2l2ZS5cbiAgICAvLyBJZiB0aGUgdG9wIGxldmVsIGl0ZW0gaXMgYW4gYXJyYXksIHdlIHRyZWF0IGl0IGFzIGEgc2V0IG9mIGNoaWxkcmVuLFxuICAgIC8vIG5vdCBhcyBhIGZyYWdtZW50LiBOZXN0ZWQgYXJyYXlzIG9uIHRoZSBvdGhlciBoYW5kIHdpbGwgYmUgdHJlYXRlZCBhc1xuICAgIC8vIGZyYWdtZW50IG5vZGVzLiBSZWN1cnNpb24gaGFwcGVucyBhdCB0aGUgbm9ybWFsIGZsb3cuXG4gICAgLy8gSGFuZGxlIHRvcCBsZXZlbCB1bmtleWVkIGZyYWdtZW50cyBhcyBpZiB0aGV5IHdlcmUgYXJyYXlzLlxuICAgIC8vIFRoaXMgbGVhZHMgdG8gYW4gYW1iaWd1aXR5IGJldHdlZW4gPD57Wy4uLl19PC8+IGFuZCA8Pi4uLjwvPi5cbiAgICAvLyBXZSB0cmVhdCB0aGUgYW1iaWd1b3VzIGNhc2VzIGFib3ZlIHRoZSBzYW1lLlxuICAgIHZhciBpc1Vua2V5ZWRUb3BMZXZlbEZyYWdtZW50ID0gdHlwZW9mIG5ld0NoaWxkID09PSAnb2JqZWN0JyAmJiBuZXdDaGlsZCAhPT0gbnVsbCAmJiBuZXdDaGlsZC50eXBlID09PSBSRUFDVF9GUkFHTUVOVF9UWVBFICYmIG5ld0NoaWxkLmtleSA9PT0gbnVsbDtcblxuICAgIGlmIChpc1Vua2V5ZWRUb3BMZXZlbEZyYWdtZW50KSB7XG4gICAgICBuZXdDaGlsZCA9IG5ld0NoaWxkLnByb3BzLmNoaWxkcmVuO1xuICAgIH0gLy8gSGFuZGxlIG9iamVjdCB0eXBlc1xuXG5cbiAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnb2JqZWN0JyAmJiBuZXdDaGlsZCAhPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChuZXdDaGlsZC4kJHR5cGVvZikge1xuICAgICAgICBjYXNlIFJFQUNUX0VMRU1FTlRfVFlQRTpcbiAgICAgICAgICByZXR1cm4gcGxhY2VTaW5nbGVDaGlsZChyZWNvbmNpbGVTaW5nbGVFbGVtZW50KHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgbmV3Q2hpbGQsIGxhbmVzKSk7XG5cbiAgICAgICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgICAgICByZXR1cm4gcGxhY2VTaW5nbGVDaGlsZChyZWNvbmNpbGVTaW5nbGVQb3J0YWwocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkLCBuZXdDaGlsZCwgbGFuZXMpKTtcblxuICAgICAgICBjYXNlIFJFQUNUX0xBWllfVFlQRTpcbiAgICAgICAgICB2YXIgcGF5bG9hZCA9IG5ld0NoaWxkLl9wYXlsb2FkO1xuICAgICAgICAgIHZhciBpbml0ID0gbmV3Q2hpbGQuX2luaXQ7IC8vIFRPRE86IFRoaXMgZnVuY3Rpb24gaXMgc3VwcG9zZWQgdG8gYmUgbm9uLXJlY3Vyc2l2ZS5cblxuICAgICAgICAgIHJldHVybiByZWNvbmNpbGVDaGlsZEZpYmVycyhyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQsIGluaXQocGF5bG9hZCksIGxhbmVzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzQXJyYXkobmV3Q2hpbGQpKSB7XG4gICAgICAgIHJldHVybiByZWNvbmNpbGVDaGlsZHJlbkFycmF5KHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgbmV3Q2hpbGQsIGxhbmVzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdldEl0ZXJhdG9yRm4obmV3Q2hpbGQpKSB7XG4gICAgICAgIHJldHVybiByZWNvbmNpbGVDaGlsZHJlbkl0ZXJhdG9yKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgbmV3Q2hpbGQsIGxhbmVzKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3dPbkludmFsaWRPYmplY3RUeXBlKHJldHVybkZpYmVyLCBuZXdDaGlsZCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBuZXdDaGlsZCA9PT0gJ3N0cmluZycgJiYgbmV3Q2hpbGQgIT09ICcnIHx8IHR5cGVvZiBuZXdDaGlsZCA9PT0gJ251bWJlcicpIHtcbiAgICAgIHJldHVybiBwbGFjZVNpbmdsZUNoaWxkKHJlY29uY2lsZVNpbmdsZVRleHROb2RlKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgJycgKyBuZXdDaGlsZCwgbGFuZXMpKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHdhcm5PbkZ1bmN0aW9uVHlwZShyZXR1cm5GaWJlcik7XG4gICAgICB9XG4gICAgfSAvLyBSZW1haW5pbmcgY2FzZXMgYXJlIGFsbCB0cmVhdGVkIGFzIGVtcHR5LlxuXG5cbiAgICByZXR1cm4gZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkKTtcbiAgfVxuXG4gIHJldHVybiByZWNvbmNpbGVDaGlsZEZpYmVycztcbn1cblxudmFyIHJlY29uY2lsZUNoaWxkRmliZXJzID0gQ2hpbGRSZWNvbmNpbGVyKHRydWUpO1xudmFyIG1vdW50Q2hpbGRGaWJlcnMgPSBDaGlsZFJlY29uY2lsZXIoZmFsc2UpO1xuZnVuY3Rpb24gY2xvbmVDaGlsZEZpYmVycyhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcykge1xuICBpZiAoY3VycmVudCAhPT0gbnVsbCAmJiB3b3JrSW5Qcm9ncmVzcy5jaGlsZCAhPT0gY3VycmVudC5jaGlsZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignUmVzdW1pbmcgd29yayBub3QgeWV0IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgaWYgKHdvcmtJblByb2dyZXNzLmNoaWxkID09PSBudWxsKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGN1cnJlbnRDaGlsZCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICB2YXIgbmV3Q2hpbGQgPSBjcmVhdGVXb3JrSW5Qcm9ncmVzcyhjdXJyZW50Q2hpbGQsIGN1cnJlbnRDaGlsZC5wZW5kaW5nUHJvcHMpO1xuICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IG5ld0NoaWxkO1xuICBuZXdDaGlsZC5yZXR1cm4gPSB3b3JrSW5Qcm9ncmVzcztcblxuICB3aGlsZSAoY3VycmVudENoaWxkLnNpYmxpbmcgIT09IG51bGwpIHtcbiAgICBjdXJyZW50Q2hpbGQgPSBjdXJyZW50Q2hpbGQuc2libGluZztcbiAgICBuZXdDaGlsZCA9IG5ld0NoaWxkLnNpYmxpbmcgPSBjcmVhdGVXb3JrSW5Qcm9ncmVzcyhjdXJyZW50Q2hpbGQsIGN1cnJlbnRDaGlsZC5wZW5kaW5nUHJvcHMpO1xuICAgIG5ld0NoaWxkLnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICB9XG5cbiAgbmV3Q2hpbGQuc2libGluZyA9IG51bGw7XG59IC8vIFJlc2V0IGEgd29ya0luUHJvZ3Jlc3MgY2hpbGQgc2V0IHRvIHByZXBhcmUgaXQgZm9yIGEgc2Vjb25kIHBhc3MuXG5cbmZ1bmN0aW9uIHJlc2V0Q2hpbGRGaWJlcnMod29ya0luUHJvZ3Jlc3MsIGxhbmVzKSB7XG4gIHZhciBjaGlsZCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuXG4gIHdoaWxlIChjaGlsZCAhPT0gbnVsbCkge1xuICAgIHJlc2V0V29ya0luUHJvZ3Jlc3MoY2hpbGQsIGxhbmVzKTtcbiAgICBjaGlsZCA9IGNoaWxkLnNpYmxpbmc7XG4gIH1cbn1cblxudmFyIE5PX0NPTlRFWFQgPSB7fTtcbnZhciBjb250ZXh0U3RhY2tDdXJzb3IkMSA9IGNyZWF0ZUN1cnNvcihOT19DT05URVhUKTtcbnZhciBjb250ZXh0RmliZXJTdGFja0N1cnNvciA9IGNyZWF0ZUN1cnNvcihOT19DT05URVhUKTtcbnZhciByb290SW5zdGFuY2VTdGFja0N1cnNvciA9IGNyZWF0ZUN1cnNvcihOT19DT05URVhUKTtcblxuZnVuY3Rpb24gcmVxdWlyZWRDb250ZXh0KGMpIHtcbiAgaWYgKGMgPT09IE5PX0NPTlRFWFQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIGhvc3QgY29udGV4dCB0byBleGlzdC4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnICcgKyAnaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICB9XG5cbiAgcmV0dXJuIGM7XG59XG5cbmZ1bmN0aW9uIGdldFJvb3RIb3N0Q29udGFpbmVyKCkge1xuICB2YXIgcm9vdEluc3RhbmNlID0gcmVxdWlyZWRDb250ZXh0KHJvb3RJbnN0YW5jZVN0YWNrQ3Vyc29yLmN1cnJlbnQpO1xuICByZXR1cm4gcm9vdEluc3RhbmNlO1xufVxuXG5mdW5jdGlvbiBwdXNoSG9zdENvbnRhaW5lcihmaWJlciwgbmV4dFJvb3RJbnN0YW5jZSkge1xuICAvLyBQdXNoIGN1cnJlbnQgcm9vdCBpbnN0YW5jZSBvbnRvIHRoZSBzdGFjaztcbiAgLy8gVGhpcyBhbGxvd3MgdXMgdG8gcmVzZXQgcm9vdCB3aGVuIHBvcnRhbHMgYXJlIHBvcHBlZC5cbiAgcHVzaChyb290SW5zdGFuY2VTdGFja0N1cnNvciwgbmV4dFJvb3RJbnN0YW5jZSwgZmliZXIpOyAvLyBUcmFjayB0aGUgY29udGV4dCBhbmQgdGhlIEZpYmVyIHRoYXQgcHJvdmlkZWQgaXQuXG4gIC8vIFRoaXMgZW5hYmxlcyB1cyB0byBwb3Agb25seSBGaWJlcnMgdGhhdCBwcm92aWRlIHVuaXF1ZSBjb250ZXh0cy5cblxuICBwdXNoKGNvbnRleHRGaWJlclN0YWNrQ3Vyc29yLCBmaWJlciwgZmliZXIpOyAvLyBGaW5hbGx5LCB3ZSBuZWVkIHRvIHB1c2ggdGhlIGhvc3QgY29udGV4dCB0byB0aGUgc3RhY2suXG4gIC8vIEhvd2V2ZXIsIHdlIGNhbid0IGp1c3QgY2FsbCBnZXRSb290SG9zdENvbnRleHQoKSBhbmQgcHVzaCBpdCBiZWNhdXNlXG4gIC8vIHdlJ2QgaGF2ZSBhIGRpZmZlcmVudCBudW1iZXIgb2YgZW50cmllcyBvbiB0aGUgc3RhY2sgZGVwZW5kaW5nIG9uXG4gIC8vIHdoZXRoZXIgZ2V0Um9vdEhvc3RDb250ZXh0KCkgdGhyb3dzIHNvbWV3aGVyZSBpbiByZW5kZXJlciBjb2RlIG9yIG5vdC5cbiAgLy8gU28gd2UgcHVzaCBhbiBlbXB0eSB2YWx1ZSBmaXJzdC4gVGhpcyBsZXRzIHVzIHNhZmVseSB1bndpbmQgb24gZXJyb3JzLlxuXG4gIHB1c2goY29udGV4dFN0YWNrQ3Vyc29yJDEsIE5PX0NPTlRFWFQsIGZpYmVyKTtcbiAgdmFyIG5leHRSb290Q29udGV4dCA9IGdldFJvb3RIb3N0Q29udGV4dChuZXh0Um9vdEluc3RhbmNlKTsgLy8gTm93IHRoYXQgd2Uga25vdyB0aGlzIGZ1bmN0aW9uIGRvZXNuJ3QgdGhyb3csIHJlcGxhY2UgaXQuXG5cbiAgcG9wKGNvbnRleHRTdGFja0N1cnNvciQxLCBmaWJlcik7XG4gIHB1c2goY29udGV4dFN0YWNrQ3Vyc29yJDEsIG5leHRSb290Q29udGV4dCwgZmliZXIpO1xufVxuXG5mdW5jdGlvbiBwb3BIb3N0Q29udGFpbmVyKGZpYmVyKSB7XG4gIHBvcChjb250ZXh0U3RhY2tDdXJzb3IkMSwgZmliZXIpO1xuICBwb3AoY29udGV4dEZpYmVyU3RhY2tDdXJzb3IsIGZpYmVyKTtcbiAgcG9wKHJvb3RJbnN0YW5jZVN0YWNrQ3Vyc29yLCBmaWJlcik7XG59XG5cbmZ1bmN0aW9uIGdldEhvc3RDb250ZXh0KCkge1xuICB2YXIgY29udGV4dCA9IHJlcXVpcmVkQ29udGV4dChjb250ZXh0U3RhY2tDdXJzb3IkMS5jdXJyZW50KTtcbiAgcmV0dXJuIGNvbnRleHQ7XG59XG5cbmZ1bmN0aW9uIHB1c2hIb3N0Q29udGV4dChmaWJlcikge1xuICB2YXIgcm9vdEluc3RhbmNlID0gcmVxdWlyZWRDb250ZXh0KHJvb3RJbnN0YW5jZVN0YWNrQ3Vyc29yLmN1cnJlbnQpO1xuICB2YXIgY29udGV4dCA9IHJlcXVpcmVkQ29udGV4dChjb250ZXh0U3RhY2tDdXJzb3IkMS5jdXJyZW50KTtcbiAgdmFyIG5leHRDb250ZXh0ID0gZ2V0Q2hpbGRIb3N0Q29udGV4dChjb250ZXh0LCBmaWJlci50eXBlKTsgLy8gRG9uJ3QgcHVzaCB0aGlzIEZpYmVyJ3MgY29udGV4dCB1bmxlc3MgaXQncyB1bmlxdWUuXG5cbiAgaWYgKGNvbnRleHQgPT09IG5leHRDb250ZXh0KSB7XG4gICAgcmV0dXJuO1xuICB9IC8vIFRyYWNrIHRoZSBjb250ZXh0IGFuZCB0aGUgRmliZXIgdGhhdCBwcm92aWRlZCBpdC5cbiAgLy8gVGhpcyBlbmFibGVzIHVzIHRvIHBvcCBvbmx5IEZpYmVycyB0aGF0IHByb3ZpZGUgdW5pcXVlIGNvbnRleHRzLlxuXG5cbiAgcHVzaChjb250ZXh0RmliZXJTdGFja0N1cnNvciwgZmliZXIsIGZpYmVyKTtcbiAgcHVzaChjb250ZXh0U3RhY2tDdXJzb3IkMSwgbmV4dENvbnRleHQsIGZpYmVyKTtcbn1cblxuZnVuY3Rpb24gcG9wSG9zdENvbnRleHQoZmliZXIpIHtcbiAgLy8gRG8gbm90IHBvcCB1bmxlc3MgdGhpcyBGaWJlciBwcm92aWRlZCB0aGUgY3VycmVudCBjb250ZXh0LlxuICAvLyBwdXNoSG9zdENvbnRleHQoKSBvbmx5IHB1c2hlcyBGaWJlcnMgdGhhdCBwcm92aWRlIHVuaXF1ZSBjb250ZXh0cy5cbiAgaWYgKGNvbnRleHRGaWJlclN0YWNrQ3Vyc29yLmN1cnJlbnQgIT09IGZpYmVyKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcG9wKGNvbnRleHRTdGFja0N1cnNvciQxLCBmaWJlcik7XG4gIHBvcChjb250ZXh0RmliZXJTdGFja0N1cnNvciwgZmliZXIpO1xufVxuXG52YXIgRGVmYXVsdFN1c3BlbnNlQ29udGV4dCA9IDA7IC8vIFRoZSBTdXNwZW5zZSBDb250ZXh0IGlzIHNwbGl0IGludG8gdHdvIHBhcnRzLiBUaGUgbG93ZXIgYml0cyBpc1xuLy8gaW5oZXJpdGVkIGRlZXBseSBkb3duIHRoZSBzdWJ0cmVlLiBUaGUgdXBwZXIgYml0cyBvbmx5IGFmZmVjdFxuLy8gdGhpcyBpbW1lZGlhdGUgc3VzcGVuc2UgYm91bmRhcnkgYW5kIGdldHMgcmVzZXQgZWFjaCBuZXdcbi8vIGJvdW5kYXJ5IG9yIHN1c3BlbnNlIGxpc3QuXG5cbnZhciBTdWJ0cmVlU3VzcGVuc2VDb250ZXh0TWFzayA9IDE7IC8vIFN1YnRyZWUgRmxhZ3M6XG4vLyBJbnZpc2libGVQYXJlbnRTdXNwZW5zZUNvbnRleHQgaW5kaWNhdGVzIHRoYXQgb25lIG9mIG91ciBwYXJlbnQgU3VzcGVuc2Vcbi8vIGJvdW5kYXJpZXMgaXMgbm90IGN1cnJlbnRseSBzaG93aW5nIHZpc2libGUgbWFpbiBjb250ZW50LlxuLy8gRWl0aGVyIGJlY2F1c2UgaXQgaXMgYWxyZWFkeSBzaG93aW5nIGEgZmFsbGJhY2sgb3IgaXMgbm90IG1vdW50ZWQgYXQgYWxsLlxuLy8gV2UgY2FuIHVzZSB0aGlzIHRvIGRldGVybWluZSBpZiBpdCBpcyBkZXNpcmFibGUgdG8gdHJpZ2dlciBhIGZhbGxiYWNrIGF0XG4vLyB0aGUgcGFyZW50LiBJZiBub3QsIHRoZW4gd2UgbWlnaHQgbmVlZCB0byB0cmlnZ2VyIHVuZGVzaXJhYmxlIGJvdW5kYXJpZXNcbi8vIGFuZC9vciBzdXNwZW5kIHRoZSBjb21taXQgdG8gYXZvaWQgaGlkaW5nIHRoZSBwYXJlbnQgY29udGVudC5cblxudmFyIEludmlzaWJsZVBhcmVudFN1c3BlbnNlQ29udGV4dCA9IDE7IC8vIFNoYWxsb3cgRmxhZ3M6XG4vLyBGb3JjZVN1c3BlbnNlRmFsbGJhY2sgY2FuIGJlIHVzZWQgYnkgU3VzcGVuc2VMaXN0IHRvIGZvcmNlIG5ld2x5IGFkZGVkXG4vLyBpdGVtcyBpbnRvIHRoZWlyIGZhbGxiYWNrIHN0YXRlIGR1cmluZyBvbmUgb2YgdGhlIHJlbmRlciBwYXNzZXMuXG5cbnZhciBGb3JjZVN1c3BlbnNlRmFsbGJhY2sgPSAyO1xudmFyIHN1c3BlbnNlU3RhY2tDdXJzb3IgPSBjcmVhdGVDdXJzb3IoRGVmYXVsdFN1c3BlbnNlQ29udGV4dCk7XG5mdW5jdGlvbiBoYXNTdXNwZW5zZUNvbnRleHQocGFyZW50Q29udGV4dCwgZmxhZykge1xuICByZXR1cm4gKHBhcmVudENvbnRleHQgJiBmbGFnKSAhPT0gMDtcbn1cbmZ1bmN0aW9uIHNldERlZmF1bHRTaGFsbG93U3VzcGVuc2VDb250ZXh0KHBhcmVudENvbnRleHQpIHtcbiAgcmV0dXJuIHBhcmVudENvbnRleHQgJiBTdWJ0cmVlU3VzcGVuc2VDb250ZXh0TWFzaztcbn1cbmZ1bmN0aW9uIHNldFNoYWxsb3dTdXNwZW5zZUNvbnRleHQocGFyZW50Q29udGV4dCwgc2hhbGxvd0NvbnRleHQpIHtcbiAgcmV0dXJuIHBhcmVudENvbnRleHQgJiBTdWJ0cmVlU3VzcGVuc2VDb250ZXh0TWFzayB8IHNoYWxsb3dDb250ZXh0O1xufVxuZnVuY3Rpb24gYWRkU3VidHJlZVN1c3BlbnNlQ29udGV4dChwYXJlbnRDb250ZXh0LCBzdWJ0cmVlQ29udGV4dCkge1xuICByZXR1cm4gcGFyZW50Q29udGV4dCB8IHN1YnRyZWVDb250ZXh0O1xufVxuZnVuY3Rpb24gcHVzaFN1c3BlbnNlQ29udGV4dChmaWJlciwgbmV3Q29udGV4dCkge1xuICBwdXNoKHN1c3BlbnNlU3RhY2tDdXJzb3IsIG5ld0NvbnRleHQsIGZpYmVyKTtcbn1cbmZ1bmN0aW9uIHBvcFN1c3BlbnNlQ29udGV4dChmaWJlcikge1xuICBwb3Aoc3VzcGVuc2VTdGFja0N1cnNvciwgZmliZXIpO1xufVxuXG5mdW5jdGlvbiBzaG91bGRDYXB0dXJlU3VzcGVuc2Uod29ya0luUHJvZ3Jlc3MsIGhhc0ludmlzaWJsZVBhcmVudCkge1xuICAvLyBJZiBpdCB3YXMgdGhlIHByaW1hcnkgY2hpbGRyZW4gdGhhdCBqdXN0IHN1c3BlbmRlZCwgY2FwdHVyZSBhbmQgcmVuZGVyIHRoZVxuICAvLyBmYWxsYmFjay4gT3RoZXJ3aXNlLCBkb24ndCBjYXB0dXJlIGFuZCBidWJibGUgdG8gdGhlIG5leHQgYm91bmRhcnkuXG4gIHZhciBuZXh0U3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gIGlmIChuZXh0U3RhdGUgIT09IG51bGwpIHtcbiAgICBpZiAobmV4dFN0YXRlLmRlaHlkcmF0ZWQgIT09IG51bGwpIHtcbiAgICAgIC8vIEEgZGVoeWRyYXRlZCBib3VuZGFyeSBhbHdheXMgY2FwdHVyZXMuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgcHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFByb3BzOyAvLyBSZWd1bGFyIGJvdW5kYXJpZXMgYWx3YXlzIGNhcHR1cmUuXG5cbiAge1xuICAgIHJldHVybiB0cnVlO1xuICB9IC8vIElmIGl0J3MgYSBib3VuZGFyeSB3ZSBzaG91bGQgYXZvaWQsIHRoZW4gd2UgcHJlZmVyIHRvIGJ1YmJsZSB1cCB0byB0aGVcbn1cbmZ1bmN0aW9uIGZpbmRGaXJzdFN1c3BlbmRlZChyb3cpIHtcbiAgdmFyIG5vZGUgPSByb3c7XG5cbiAgd2hpbGUgKG5vZGUgIT09IG51bGwpIHtcbiAgICBpZiAobm9kZS50YWcgPT09IFN1c3BlbnNlQ29tcG9uZW50KSB7XG4gICAgICB2YXIgc3RhdGUgPSBub2RlLm1lbW9pemVkU3RhdGU7XG5cbiAgICAgIGlmIChzdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICB2YXIgZGVoeWRyYXRlZCA9IHN0YXRlLmRlaHlkcmF0ZWQ7XG5cbiAgICAgICAgaWYgKGRlaHlkcmF0ZWQgPT09IG51bGwgfHwgaXNTdXNwZW5zZUluc3RhbmNlUGVuZGluZyhkZWh5ZHJhdGVkKSB8fCBpc1N1c3BlbnNlSW5zdGFuY2VGYWxsYmFjayhkZWh5ZHJhdGVkKSkge1xuICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChub2RlLnRhZyA9PT0gU3VzcGVuc2VMaXN0Q29tcG9uZW50ICYmIC8vIHJldmVhbE9yZGVyIHVuZGVmaW5lZCBjYW4ndCBiZSB0cnVzdGVkIGJlY2F1c2UgaXQgZG9uJ3RcbiAgICAvLyBrZWVwIHRyYWNrIG9mIHdoZXRoZXIgaXQgc3VzcGVuZGVkIG9yIG5vdC5cbiAgICBub2RlLm1lbW9pemVkUHJvcHMucmV2ZWFsT3JkZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIGRpZFN1c3BlbmQgPSAobm9kZS5mbGFncyAmIERpZENhcHR1cmUpICE9PSBOb0ZsYWdzO1xuXG4gICAgICBpZiAoZGlkU3VzcGVuZCkge1xuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG5vZGUuY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIG5vZGUuY2hpbGQucmV0dXJuID0gbm9kZTtcbiAgICAgIG5vZGUgPSBub2RlLmNoaWxkO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUgPT09IHJvdykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgd2hpbGUgKG5vZGUuc2libGluZyA9PT0gbnVsbCkge1xuICAgICAgaWYgKG5vZGUucmV0dXJuID09PSBudWxsIHx8IG5vZGUucmV0dXJuID09PSByb3cpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICB9XG5cbiAgICBub2RlLnNpYmxpbmcucmV0dXJuID0gbm9kZS5yZXR1cm47XG4gICAgbm9kZSA9IG5vZGUuc2libGluZztcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG52YXIgTm9GbGFncyQxID1cbi8qICAgKi9cbjA7IC8vIFJlcHJlc2VudHMgd2hldGhlciBlZmZlY3Qgc2hvdWxkIGZpcmUuXG5cbnZhciBIYXNFZmZlY3QgPVxuLyogKi9cbjE7IC8vIFJlcHJlc2VudHMgdGhlIHBoYXNlIGluIHdoaWNoIHRoZSBlZmZlY3QgKG5vdCB0aGUgY2xlYW4tdXApIGZpcmVzLlxuXG52YXIgSW5zZXJ0aW9uID1cbi8qICAqL1xuMjtcbnZhciBMYXlvdXQgPVxuLyogICAgKi9cbjQ7XG52YXIgUGFzc2l2ZSQxID1cbi8qICAgKi9cbjg7XG5cbi8vIGFuZCBzaG91bGQgYmUgcmVzZXQgYmVmb3JlIHN0YXJ0aW5nIGEgbmV3IHJlbmRlci5cbi8vIFRoaXMgdHJhY2tzIHdoaWNoIG11dGFibGUgc291cmNlcyBuZWVkIHRvIGJlIHJlc2V0IGFmdGVyIGEgcmVuZGVyLlxuXG52YXIgd29ya0luUHJvZ3Jlc3NTb3VyY2VzID0gW107XG5mdW5jdGlvbiByZXNldFdvcmtJblByb2dyZXNzVmVyc2lvbnMoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgd29ya0luUHJvZ3Jlc3NTb3VyY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIG11dGFibGVTb3VyY2UgPSB3b3JrSW5Qcm9ncmVzc1NvdXJjZXNbaV07XG5cbiAgICB7XG4gICAgICBtdXRhYmxlU291cmNlLl93b3JrSW5Qcm9ncmVzc1ZlcnNpb25QcmltYXJ5ID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICB3b3JrSW5Qcm9ncmVzc1NvdXJjZXMubGVuZ3RoID0gMDtcbn1cbi8vIFRoaXMgZW5zdXJlcyB0aGF0IHRoZSB2ZXJzaW9uIHVzZWQgZm9yIHNlcnZlciByZW5kZXJpbmcgbWF0Y2hlcyB0aGUgb25lXG4vLyB0aGF0IGlzIGV2ZW50dWFsbHkgcmVhZCBkdXJpbmcgaHlkcmF0aW9uLlxuLy8gSWYgdGhleSBkb24ndCBtYXRjaCB0aGVyZSdzIGEgcG90ZW50aWFsIHRlYXIgYW5kIGEgZnVsbCBkZW9wdCByZW5kZXIgaXMgcmVxdWlyZWQuXG5cbmZ1bmN0aW9uIHJlZ2lzdGVyTXV0YWJsZVNvdXJjZUZvckh5ZHJhdGlvbihyb290LCBtdXRhYmxlU291cmNlKSB7XG4gIHZhciBnZXRWZXJzaW9uID0gbXV0YWJsZVNvdXJjZS5fZ2V0VmVyc2lvbjtcbiAgdmFyIHZlcnNpb24gPSBnZXRWZXJzaW9uKG11dGFibGVTb3VyY2UuX3NvdXJjZSk7IC8vIFRPRE8gQ2xlYXIgdGhpcyBkYXRhIG9uY2UgYWxsIHBlbmRpbmcgaHlkcmF0aW9uIHdvcmsgaXMgZmluaXNoZWQuXG4gIC8vIFJldGFpbmluZyBpdCBmb3JldmVyIG1heSBpbnRlcmZlcmUgd2l0aCBHQy5cblxuICBpZiAocm9vdC5tdXRhYmxlU291cmNlRWFnZXJIeWRyYXRpb25EYXRhID09IG51bGwpIHtcbiAgICByb290Lm11dGFibGVTb3VyY2VFYWdlckh5ZHJhdGlvbkRhdGEgPSBbbXV0YWJsZVNvdXJjZSwgdmVyc2lvbl07XG4gIH0gZWxzZSB7XG4gICAgcm9vdC5tdXRhYmxlU291cmNlRWFnZXJIeWRyYXRpb25EYXRhLnB1c2gobXV0YWJsZVNvdXJjZSwgdmVyc2lvbik7XG4gIH1cbn1cblxudmFyIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudERpc3BhdGNoZXIsXG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMiA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudEJhdGNoQ29uZmlnO1xudmFyIGRpZFdhcm5BYm91dE1pc21hdGNoZWRIb29rc0ZvckNvbXBvbmVudDtcbnZhciBkaWRXYXJuVW5jYWNoZWRHZXRTbmFwc2hvdDtcblxue1xuICBkaWRXYXJuQWJvdXRNaXNtYXRjaGVkSG9va3NGb3JDb21wb25lbnQgPSBuZXcgU2V0KCk7XG59XG5cbi8vIFRoZXNlIGFyZSBzZXQgcmlnaHQgYmVmb3JlIGNhbGxpbmcgdGhlIGNvbXBvbmVudC5cbnZhciByZW5kZXJMYW5lcyA9IE5vTGFuZXM7IC8vIFRoZSB3b3JrLWluLXByb2dyZXNzIGZpYmVyLiBJJ3ZlIG5hbWVkIGl0IGRpZmZlcmVudGx5IHRvIGRpc3Rpbmd1aXNoIGl0IGZyb21cbi8vIHRoZSB3b3JrLWluLXByb2dyZXNzIGhvb2suXG5cbnZhciBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxID0gbnVsbDsgLy8gSG9va3MgYXJlIHN0b3JlZCBhcyBhIGxpbmtlZCBsaXN0IG9uIHRoZSBmaWJlcidzIG1lbW9pemVkU3RhdGUgZmllbGQuIFRoZVxuLy8gY3VycmVudCBob29rIGxpc3QgaXMgdGhlIGxpc3QgdGhhdCBiZWxvbmdzIHRvIHRoZSBjdXJyZW50IGZpYmVyLiBUaGVcbi8vIHdvcmstaW4tcHJvZ3Jlc3MgaG9vayBsaXN0IGlzIGEgbmV3IGxpc3QgdGhhdCB3aWxsIGJlIGFkZGVkIHRvIHRoZVxuLy8gd29yay1pbi1wcm9ncmVzcyBmaWJlci5cblxudmFyIGN1cnJlbnRIb29rID0gbnVsbDtcbnZhciB3b3JrSW5Qcm9ncmVzc0hvb2sgPSBudWxsOyAvLyBXaGV0aGVyIGFuIHVwZGF0ZSB3YXMgc2NoZWR1bGVkIGF0IGFueSBwb2ludCBkdXJpbmcgdGhlIHJlbmRlciBwaGFzZS4gVGhpc1xuLy8gZG9lcyBub3QgZ2V0IHJlc2V0IGlmIHdlIGRvIGFub3RoZXIgcmVuZGVyIHBhc3M7IG9ubHkgd2hlbiB3ZSdyZSBjb21wbGV0ZWx5XG4vLyBmaW5pc2hlZCBldmFsdWF0aW5nIHRoaXMgY29tcG9uZW50LiBUaGlzIGlzIGFuIG9wdGltaXphdGlvbiBzbyB3ZSBrbm93XG4vLyB3aGV0aGVyIHdlIG5lZWQgdG8gY2xlYXIgcmVuZGVyIHBoYXNlIHVwZGF0ZXMgYWZ0ZXIgYSB0aHJvdy5cblxudmFyIGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGUgPSBmYWxzZTsgLy8gV2hlcmUgYW4gdXBkYXRlIHdhcyBzY2hlZHVsZWQgb25seSBkdXJpbmcgdGhlIGN1cnJlbnQgcmVuZGVyIHBhc3MuIFRoaXNcbi8vIGdldHMgcmVzZXQgYWZ0ZXIgZWFjaCBhdHRlbXB0LlxuLy8gVE9ETzogTWF5YmUgdGhlcmUncyBzb21lIHdheSB0byBjb25zb2xpZGF0ZSB0aGlzIHdpdGhcbi8vIGBkaWRTY2hlZHVsZVJlbmRlclBoYXNlVXBkYXRlYC4gT3Igd2l0aCBgbnVtYmVyT2ZSZVJlbmRlcnNgLlxuXG52YXIgZGlkU2NoZWR1bGVSZW5kZXJQaGFzZVVwZGF0ZUR1cmluZ1RoaXNQYXNzID0gZmFsc2U7IC8vIENvdW50cyB0aGUgbnVtYmVyIG9mIHVzZUlkIGhvb2tzIGluIHRoaXMgY29tcG9uZW50LlxuXG52YXIgbG9jYWxJZENvdW50ZXIgPSAwOyAvLyBVc2VkIGZvciBpZHMgdGhhdCBhcmUgZ2VuZXJhdGVkIGNvbXBsZXRlbHkgY2xpZW50LXNpZGUgKGkuZS4gbm90IGR1cmluZ1xuLy8gaHlkcmF0aW9uKS4gVGhpcyBjb3VudGVyIGlzIGdsb2JhbCwgc28gY2xpZW50IGlkcyBhcmUgbm90IHN0YWJsZSBhY3Jvc3Ncbi8vIHJlbmRlciBhdHRlbXB0cy5cblxudmFyIGdsb2JhbENsaWVudElkQ291bnRlciA9IDA7XG52YXIgUkVfUkVOREVSX0xJTUlUID0gMjU7IC8vIEluIERFViwgdGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgY3VycmVudGx5IGV4ZWN1dGluZyBwcmltaXRpdmUgaG9va1xuXG52YXIgY3VycmVudEhvb2tOYW1lSW5EZXYgPSBudWxsOyAvLyBJbiBERVYsIHRoaXMgbGlzdCBlbnN1cmVzIHRoYXQgaG9va3MgYXJlIGNhbGxlZCBpbiB0aGUgc2FtZSBvcmRlciBiZXR3ZWVuIHJlbmRlcnMuXG4vLyBUaGUgbGlzdCBzdG9yZXMgdGhlIG9yZGVyIG9mIGhvb2tzIHVzZWQgZHVyaW5nIHRoZSBpbml0aWFsIHJlbmRlciAobW91bnQpLlxuLy8gU3Vic2VxdWVudCByZW5kZXJzICh1cGRhdGVzKSByZWZlcmVuY2UgdGhpcyBsaXN0LlxuXG52YXIgaG9va1R5cGVzRGV2ID0gbnVsbDtcbnZhciBob29rVHlwZXNVcGRhdGVJbmRleERldiA9IC0xOyAvLyBJbiBERVYsIHRoaXMgdHJhY2tzIHdoZXRoZXIgY3VycmVudGx5IHJlbmRlcmluZyBjb21wb25lbnQgbmVlZHMgdG8gaWdub3JlXG4vLyB0aGUgZGVwZW5kZW5jaWVzIGZvciBIb29rcyB0aGF0IG5lZWQgdGhlbSAoZS5nLiB1c2VFZmZlY3Qgb3IgdXNlTWVtbykuXG4vLyBXaGVuIHRydWUsIHN1Y2ggSG9va3Mgd2lsbCBhbHdheXMgYmUgXCJyZW1vdW50ZWRcIi4gT25seSB1c2VkIGR1cmluZyBob3QgcmVsb2FkLlxuXG52YXIgaWdub3JlUHJldmlvdXNEZXBlbmRlbmNpZXMgPSBmYWxzZTtcblxuZnVuY3Rpb24gbW91bnRIb29rVHlwZXNEZXYoKSB7XG4gIHtcbiAgICB2YXIgaG9va05hbWUgPSBjdXJyZW50SG9va05hbWVJbkRldjtcblxuICAgIGlmIChob29rVHlwZXNEZXYgPT09IG51bGwpIHtcbiAgICAgIGhvb2tUeXBlc0RldiA9IFtob29rTmFtZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGhvb2tUeXBlc0Rldi5wdXNoKGhvb2tOYW1lKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlSG9va1R5cGVzRGV2KCkge1xuICB7XG4gICAgdmFyIGhvb2tOYW1lID0gY3VycmVudEhvb2tOYW1lSW5EZXY7XG5cbiAgICBpZiAoaG9va1R5cGVzRGV2ICE9PSBudWxsKSB7XG4gICAgICBob29rVHlwZXNVcGRhdGVJbmRleERldisrO1xuXG4gICAgICBpZiAoaG9va1R5cGVzRGV2W2hvb2tUeXBlc1VwZGF0ZUluZGV4RGV2XSAhPT0gaG9va05hbWUpIHtcbiAgICAgICAgd2Fybk9uSG9va01pc21hdGNoSW5EZXYoaG9va05hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjaGVja0RlcHNBcmVBcnJheURldihkZXBzKSB7XG4gIHtcbiAgICBpZiAoZGVwcyAhPT0gdW5kZWZpbmVkICYmIGRlcHMgIT09IG51bGwgJiYgIWlzQXJyYXkoZGVwcykpIHtcbiAgICAgIC8vIFZlcmlmeSBkZXBzLCBidXQgb25seSBvbiBtb3VudCB0byBhdm9pZCBleHRyYSBjaGVja3MuXG4gICAgICAvLyBJdCdzIHVubGlrZWx5IHRoZWlyIHR5cGUgd291bGQgY2hhbmdlIGFzIHVzdWFsbHkgeW91IGRlZmluZSB0aGVtIGlubGluZS5cbiAgICAgIGVycm9yKCclcyByZWNlaXZlZCBhIGZpbmFsIGFyZ3VtZW50IHRoYXQgaXMgbm90IGFuIGFycmF5IChpbnN0ZWFkLCByZWNlaXZlZCBgJXNgKS4gV2hlbiAnICsgJ3NwZWNpZmllZCwgdGhlIGZpbmFsIGFyZ3VtZW50IG11c3QgYmUgYW4gYXJyYXkuJywgY3VycmVudEhvb2tOYW1lSW5EZXYsIHR5cGVvZiBkZXBzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gd2Fybk9uSG9va01pc21hdGNoSW5EZXYoY3VycmVudEhvb2tOYW1lKSB7XG4gIHtcbiAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMSk7XG5cbiAgICBpZiAoIWRpZFdhcm5BYm91dE1pc21hdGNoZWRIb29rc0ZvckNvbXBvbmVudC5oYXMoY29tcG9uZW50TmFtZSkpIHtcbiAgICAgIGRpZFdhcm5BYm91dE1pc21hdGNoZWRIb29rc0ZvckNvbXBvbmVudC5hZGQoY29tcG9uZW50TmFtZSk7XG5cbiAgICAgIGlmIChob29rVHlwZXNEZXYgIT09IG51bGwpIHtcbiAgICAgICAgdmFyIHRhYmxlID0gJyc7XG4gICAgICAgIHZhciBzZWNvbmRDb2x1bW5TdGFydCA9IDMwO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDw9IGhvb2tUeXBlc1VwZGF0ZUluZGV4RGV2OyBpKyspIHtcbiAgICAgICAgICB2YXIgb2xkSG9va05hbWUgPSBob29rVHlwZXNEZXZbaV07XG4gICAgICAgICAgdmFyIG5ld0hvb2tOYW1lID0gaSA9PT0gaG9va1R5cGVzVXBkYXRlSW5kZXhEZXYgPyBjdXJyZW50SG9va05hbWUgOiBvbGRIb29rTmFtZTtcbiAgICAgICAgICB2YXIgcm93ID0gaSArIDEgKyBcIi4gXCIgKyBvbGRIb29rTmFtZTsgLy8gRXh0cmEgc3BhY2Ugc28gc2Vjb25kIGNvbHVtbiBsaW5lcyB1cFxuICAgICAgICAgIC8vIGxvbCBAIElFIG5vdCBzdXBwb3J0aW5nIFN0cmluZyNyZXBlYXRcblxuICAgICAgICAgIHdoaWxlIChyb3cubGVuZ3RoIDwgc2Vjb25kQ29sdW1uU3RhcnQpIHtcbiAgICAgICAgICAgIHJvdyArPSAnICc7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcm93ICs9IG5ld0hvb2tOYW1lICsgJ1xcbic7XG4gICAgICAgICAgdGFibGUgKz0gcm93O1xuICAgICAgICB9XG5cbiAgICAgICAgZXJyb3IoJ1JlYWN0IGhhcyBkZXRlY3RlZCBhIGNoYW5nZSBpbiB0aGUgb3JkZXIgb2YgSG9va3MgY2FsbGVkIGJ5ICVzLiAnICsgJ1RoaXMgd2lsbCBsZWFkIHRvIGJ1Z3MgYW5kIGVycm9ycyBpZiBub3QgZml4ZWQuICcgKyAnRm9yIG1vcmUgaW5mb3JtYXRpb24sIHJlYWQgdGhlIFJ1bGVzIG9mIEhvb2tzOiBodHRwczovL3JlYWN0anMub3JnL2xpbmsvcnVsZXMtb2YtaG9va3NcXG5cXG4nICsgJyAgIFByZXZpb3VzIHJlbmRlciAgICAgICAgICAgIE5leHQgcmVuZGVyXFxuJyArICcgICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cXG4nICsgJyVzJyArICcgICBeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cXG4nLCBjb21wb25lbnROYW1lLCB0YWJsZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHRocm93SW52YWxpZEhvb2tFcnJvcigpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhvb2sgY2FsbC4gSG9va3MgY2FuIG9ubHkgYmUgY2FsbGVkIGluc2lkZSBvZiB0aGUgYm9keSBvZiBhIGZ1bmN0aW9uIGNvbXBvbmVudC4gVGhpcyBjb3VsZCBoYXBwZW4gZm9yJyArICcgb25lIG9mIHRoZSBmb2xsb3dpbmcgcmVhc29uczpcXG4nICsgJzEuIFlvdSBtaWdodCBoYXZlIG1pc21hdGNoaW5nIHZlcnNpb25zIG9mIFJlYWN0IGFuZCB0aGUgcmVuZGVyZXIgKHN1Y2ggYXMgUmVhY3QgRE9NKVxcbicgKyAnMi4gWW91IG1pZ2h0IGJlIGJyZWFraW5nIHRoZSBSdWxlcyBvZiBIb29rc1xcbicgKyAnMy4gWW91IG1pZ2h0IGhhdmUgbW9yZSB0aGFuIG9uZSBjb3B5IG9mIFJlYWN0IGluIHRoZSBzYW1lIGFwcFxcbicgKyAnU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9pbnZhbGlkLWhvb2stY2FsbCBmb3IgdGlwcyBhYm91dCBob3cgdG8gZGVidWcgYW5kIGZpeCB0aGlzIHByb2JsZW0uJyk7XG59XG5cbmZ1bmN0aW9uIGFyZUhvb2tJbnB1dHNFcXVhbChuZXh0RGVwcywgcHJldkRlcHMpIHtcbiAge1xuICAgIGlmIChpZ25vcmVQcmV2aW91c0RlcGVuZGVuY2llcykge1xuICAgICAgLy8gT25seSB0cnVlIHdoZW4gdGhpcyBjb21wb25lbnQgaXMgYmVpbmcgaG90IHJlbG9hZGVkLlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGlmIChwcmV2RGVwcyA9PT0gbnVsbCkge1xuICAgIHtcbiAgICAgIGVycm9yKCclcyByZWNlaXZlZCBhIGZpbmFsIGFyZ3VtZW50IGR1cmluZyB0aGlzIHJlbmRlciwgYnV0IG5vdCBkdXJpbmcgJyArICd0aGUgcHJldmlvdXMgcmVuZGVyLiBFdmVuIHRob3VnaCB0aGUgZmluYWwgYXJndW1lbnQgaXMgb3B0aW9uYWwsICcgKyAnaXRzIHR5cGUgY2Fubm90IGNoYW5nZSBiZXR3ZWVuIHJlbmRlcnMuJywgY3VycmVudEhvb2tOYW1lSW5EZXYpO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHtcbiAgICAvLyBEb24ndCBib3RoZXIgY29tcGFyaW5nIGxlbmd0aHMgaW4gcHJvZCBiZWNhdXNlIHRoZXNlIGFycmF5cyBzaG91bGQgYmVcbiAgICAvLyBwYXNzZWQgaW5saW5lLlxuICAgIGlmIChuZXh0RGVwcy5sZW5ndGggIT09IHByZXZEZXBzLmxlbmd0aCkge1xuICAgICAgZXJyb3IoJ1RoZSBmaW5hbCBhcmd1bWVudCBwYXNzZWQgdG8gJXMgY2hhbmdlZCBzaXplIGJldHdlZW4gcmVuZGVycy4gVGhlICcgKyAnb3JkZXIgYW5kIHNpemUgb2YgdGhpcyBhcnJheSBtdXN0IHJlbWFpbiBjb25zdGFudC5cXG5cXG4nICsgJ1ByZXZpb3VzOiAlc1xcbicgKyAnSW5jb21pbmc6ICVzJywgY3VycmVudEhvb2tOYW1lSW5EZXYsIFwiW1wiICsgcHJldkRlcHMuam9pbignLCAnKSArIFwiXVwiLCBcIltcIiArIG5leHREZXBzLmpvaW4oJywgJykgKyBcIl1cIik7XG4gICAgfVxuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcmV2RGVwcy5sZW5ndGggJiYgaSA8IG5leHREZXBzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKG9iamVjdElzKG5leHREZXBzW2ldLCBwcmV2RGVwc1tpXSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZW5kZXJXaXRoSG9va3MoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcHJvcHMsIHNlY29uZEFyZywgbmV4dFJlbmRlckxhbmVzKSB7XG4gIHJlbmRlckxhbmVzID0gbmV4dFJlbmRlckxhbmVzO1xuICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxID0gd29ya0luUHJvZ3Jlc3M7XG5cbiAge1xuICAgIGhvb2tUeXBlc0RldiA9IGN1cnJlbnQgIT09IG51bGwgPyBjdXJyZW50Ll9kZWJ1Z0hvb2tUeXBlcyA6IG51bGw7XG4gICAgaG9va1R5cGVzVXBkYXRlSW5kZXhEZXYgPSAtMTsgLy8gVXNlZCBmb3IgaG90IHJlbG9hZGluZzpcblxuICAgIGlnbm9yZVByZXZpb3VzRGVwZW5kZW5jaWVzID0gY3VycmVudCAhPT0gbnVsbCAmJiBjdXJyZW50LnR5cGUgIT09IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gIH1cblxuICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gbnVsbDtcbiAgd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWUgPSBudWxsO1xuICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IE5vTGFuZXM7IC8vIFRoZSBmb2xsb3dpbmcgc2hvdWxkIGhhdmUgYWxyZWFkeSBiZWVuIHJlc2V0XG4gIC8vIGN1cnJlbnRIb29rID0gbnVsbDtcbiAgLy8gd29ya0luUHJvZ3Jlc3NIb29rID0gbnVsbDtcbiAgLy8gZGlkU2NoZWR1bGVSZW5kZXJQaGFzZVVwZGF0ZSA9IGZhbHNlO1xuICAvLyBsb2NhbElkQ291bnRlciA9IDA7XG4gIC8vIFRPRE8gV2FybiBpZiBubyBob29rcyBhcmUgdXNlZCBhdCBhbGwgZHVyaW5nIG1vdW50LCB0aGVuIHNvbWUgYXJlIHVzZWQgZHVyaW5nIHVwZGF0ZS5cbiAgLy8gQ3VycmVudGx5IHdlIHdpbGwgaWRlbnRpZnkgdGhlIHVwZGF0ZSByZW5kZXIgYXMgYSBtb3VudCBiZWNhdXNlIG1lbW9pemVkU3RhdGUgPT09IG51bGwuXG4gIC8vIFRoaXMgaXMgdHJpY2t5IGJlY2F1c2UgaXQncyB2YWxpZCBmb3IgY2VydGFpbiB0eXBlcyBvZiBjb21wb25lbnRzIChlLmcuIFJlYWN0LmxhenkpXG4gIC8vIFVzaW5nIG1lbW9pemVkU3RhdGUgdG8gZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIG1vdW50L3VwZGF0ZSBvbmx5IHdvcmtzIGlmIGF0IGxlYXN0IG9uZSBzdGF0ZWZ1bCBob29rIGlzIHVzZWQuXG4gIC8vIE5vbi1zdGF0ZWZ1bCBob29rcyAoZS5nLiBjb250ZXh0KSBkb24ndCBnZXQgYWRkZWQgdG8gbWVtb2l6ZWRTdGF0ZSxcbiAgLy8gc28gbWVtb2l6ZWRTdGF0ZSB3b3VsZCBiZSBudWxsIGR1cmluZyB1cGRhdGVzIGFuZCBtb3VudHMuXG5cbiAge1xuICAgIGlmIChjdXJyZW50ICE9PSBudWxsICYmIGN1cnJlbnQubWVtb2l6ZWRTdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBIb29rc0Rpc3BhdGNoZXJPblVwZGF0ZUluREVWO1xuICAgIH0gZWxzZSBpZiAoaG9va1R5cGVzRGV2ICE9PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIGRpc3BhdGNoZXIgaGFuZGxlcyBhbiBlZGdlIGNhc2Ugd2hlcmUgYSBjb21wb25lbnQgaXMgdXBkYXRpbmcsXG4gICAgICAvLyBidXQgbm8gc3RhdGVmdWwgaG9va3MgaGF2ZSBiZWVuIHVzZWQuXG4gICAgICAvLyBXZSB3YW50IHRvIG1hdGNoIHRoZSBwcm9kdWN0aW9uIGNvZGUgYmVoYXZpb3IgKHdoaWNoIHdpbGwgdXNlIEhvb2tzRGlzcGF0Y2hlck9uTW91bnQpLFxuICAgICAgLy8gYnV0IHdpdGggdGhlIGV4dHJhIERFViB2YWxpZGF0aW9uIHRvIGVuc3VyZSBob29rcyBvcmRlcmluZyBoYXNuJ3QgY2hhbmdlZC5cbiAgICAgIC8vIFRoaXMgZGlzcGF0Y2hlciBkb2VzIHRoYXQuXG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEhvb2tzRGlzcGF0Y2hlck9uTW91bnRXaXRoSG9va1R5cGVzSW5ERVY7XG4gICAgfSBlbHNlIHtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWO1xuICAgIH1cbiAgfVxuXG4gIHZhciBjaGlsZHJlbiA9IENvbXBvbmVudChwcm9wcywgc2Vjb25kQXJnKTsgLy8gQ2hlY2sgaWYgdGhlcmUgd2FzIGEgcmVuZGVyIHBoYXNlIHVwZGF0ZVxuXG4gIGlmIChkaWRTY2hlZHVsZVJlbmRlclBoYXNlVXBkYXRlRHVyaW5nVGhpc1Bhc3MpIHtcbiAgICAvLyBLZWVwIHJlbmRlcmluZyBpbiBhIGxvb3AgZm9yIGFzIGxvbmcgYXMgcmVuZGVyIHBoYXNlIHVwZGF0ZXMgY29udGludWUgdG9cbiAgICAvLyBiZSBzY2hlZHVsZWQuIFVzZSBhIGNvdW50ZXIgdG8gcHJldmVudCBpbmZpbml0ZSBsb29wcy5cbiAgICB2YXIgbnVtYmVyT2ZSZVJlbmRlcnMgPSAwO1xuXG4gICAgZG8ge1xuICAgICAgZGlkU2NoZWR1bGVSZW5kZXJQaGFzZVVwZGF0ZUR1cmluZ1RoaXNQYXNzID0gZmFsc2U7XG4gICAgICBsb2NhbElkQ291bnRlciA9IDA7XG5cbiAgICAgIGlmIChudW1iZXJPZlJlUmVuZGVycyA+PSBSRV9SRU5ERVJfTElNSVQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUb28gbWFueSByZS1yZW5kZXJzLiBSZWFjdCBsaW1pdHMgdGhlIG51bWJlciBvZiByZW5kZXJzIHRvIHByZXZlbnQgJyArICdhbiBpbmZpbml0ZSBsb29wLicpO1xuICAgICAgfVxuXG4gICAgICBudW1iZXJPZlJlUmVuZGVycyArPSAxO1xuXG4gICAgICB7XG4gICAgICAgIC8vIEV2ZW4gd2hlbiBob3QgcmVsb2FkaW5nLCBhbGxvdyBkZXBlbmRlbmNpZXMgdG8gc3RhYmlsaXplXG4gICAgICAgIC8vIGFmdGVyIGZpcnN0IHJlbmRlciB0byBwcmV2ZW50IGluZmluaXRlIHJlbmRlciBwaGFzZSB1cGRhdGVzLlxuICAgICAgICBpZ25vcmVQcmV2aW91c0RlcGVuZGVuY2llcyA9IGZhbHNlO1xuICAgICAgfSAvLyBTdGFydCBvdmVyIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgbGlzdFxuXG5cbiAgICAgIGN1cnJlbnRIb29rID0gbnVsbDtcbiAgICAgIHdvcmtJblByb2dyZXNzSG9vayA9IG51bGw7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZSA9IG51bGw7XG5cbiAgICAgIHtcbiAgICAgICAgLy8gQWxzbyB2YWxpZGF0ZSBob29rIG9yZGVyIGZvciBjYXNjYWRpbmcgdXBkYXRlcy5cbiAgICAgICAgaG9va1R5cGVzVXBkYXRlSW5kZXhEZXYgPSAtMTtcbiAgICAgIH1cblxuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSAgSG9va3NEaXNwYXRjaGVyT25SZXJlbmRlckluREVWIDtcbiAgICAgIGNoaWxkcmVuID0gQ29tcG9uZW50KHByb3BzLCBzZWNvbmRBcmcpO1xuICAgIH0gd2hpbGUgKGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGVEdXJpbmdUaGlzUGFzcyk7XG4gIH0gLy8gV2UgY2FuIGFzc3VtZSB0aGUgcHJldmlvdXMgZGlzcGF0Y2hlciBpcyBhbHdheXMgdGhpcyBvbmUsIHNpbmNlIHdlIHNldCBpdFxuICAvLyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZW5kZXIgcGhhc2UgYW5kIHRoZXJlJ3Mgbm8gcmUtZW50cmFuY2UuXG5cblxuICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IENvbnRleHRPbmx5RGlzcGF0Y2hlcjtcblxuICB7XG4gICAgd29ya0luUHJvZ3Jlc3MuX2RlYnVnSG9va1R5cGVzID0gaG9va1R5cGVzRGV2O1xuICB9IC8vIFRoaXMgY2hlY2sgdXNlcyBjdXJyZW50SG9vayBzbyB0aGF0IGl0IHdvcmtzIHRoZSBzYW1lIGluIERFViBhbmQgcHJvZCBidW5kbGVzLlxuICAvLyBob29rVHlwZXNEZXYgY291bGQgY2F0Y2ggbW9yZSBjYXNlcyAoZS5nLiBjb250ZXh0KSBidXQgb25seSBpbiBERVYgYnVuZGxlcy5cblxuXG4gIHZhciBkaWRSZW5kZXJUb29GZXdIb29rcyA9IGN1cnJlbnRIb29rICE9PSBudWxsICYmIGN1cnJlbnRIb29rLm5leHQgIT09IG51bGw7XG4gIHJlbmRlckxhbmVzID0gTm9MYW5lcztcbiAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMSA9IG51bGw7XG4gIGN1cnJlbnRIb29rID0gbnVsbDtcbiAgd29ya0luUHJvZ3Jlc3NIb29rID0gbnVsbDtcblxuICB7XG4gICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSBudWxsO1xuICAgIGhvb2tUeXBlc0RldiA9IG51bGw7XG4gICAgaG9va1R5cGVzVXBkYXRlSW5kZXhEZXYgPSAtMTsgLy8gQ29uZmlybSB0aGF0IGEgc3RhdGljIGZsYWcgd2FzIG5vdCBhZGRlZCBvciByZW1vdmVkIHNpbmNlIHRoZSBsYXN0XG4gICAgLy8gcmVuZGVyLiBJZiB0aGlzIGZpcmVzLCBpdCBzdWdnZXN0cyB0aGF0IHdlIGluY29ycmVjdGx5IHJlc2V0IHRoZSBzdGF0aWNcbiAgICAvLyBmbGFncyBpbiBzb21lIG90aGVyIHBhcnQgb2YgdGhlIGNvZGViYXNlLiBUaGlzIGhhcyBoYXBwZW5lZCBiZWZvcmUsIGZvclxuICAgIC8vIGV4YW1wbGUsIGluIHRoZSBTdXNwZW5zZUxpc3QgaW1wbGVtZW50YXRpb24uXG5cbiAgICBpZiAoY3VycmVudCAhPT0gbnVsbCAmJiAoY3VycmVudC5mbGFncyAmIFN0YXRpY01hc2spICE9PSAod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBTdGF0aWNNYXNrKSAmJiAvLyBEaXNhYmxlIHRoaXMgd2FybmluZyBpbiBsZWdhY3kgbW9kZSwgYmVjYXVzZSBsZWdhY3kgU3VzcGVuc2UgaXMgd2VpcmRcbiAgICAvLyBhbmQgY3JlYXRlcyBmYWxzZSBwb3NpdGl2ZXMuIFRvIG1ha2UgdGhpcyB3b3JrIGluIGxlZ2FjeSBtb2RlLCB3ZSdkXG4gICAgLy8gbmVlZCB0byBtYXJrIGZpYmVycyB0aGF0IGNvbW1pdCBpbiBhbiBpbmNvbXBsZXRlIHN0YXRlLCBzb21laG93LiBGb3JcbiAgICAvLyBub3cgSSdsbCBkaXNhYmxlIHRoZSB3YXJuaW5nIHRoYXQgbW9zdCBvZiB0aGUgYnVncyB0aGF0IHdvdWxkIHRyaWdnZXJcbiAgICAvLyBpdCBhcmUgZWl0aGVyIGV4Y2x1c2l2ZSB0byBjb25jdXJyZW50IG1vZGUgb3IgZXhpc3QgaW4gYm90aC5cbiAgICAoY3VycmVudC5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgIGVycm9yKCdJbnRlcm5hbCBSZWFjdCBlcnJvcjogRXhwZWN0ZWQgc3RhdGljIGZsYWcgd2FzIG1pc3NpbmcuIFBsZWFzZSAnICsgJ25vdGlmeSB0aGUgUmVhY3QgdGVhbS4nKTtcbiAgICB9XG4gIH1cblxuICBkaWRTY2hlZHVsZVJlbmRlclBoYXNlVXBkYXRlID0gZmFsc2U7IC8vIFRoaXMgaXMgcmVzZXQgYnkgY2hlY2tEaWRSZW5kZXJJZEhvb2tcbiAgLy8gbG9jYWxJZENvdW50ZXIgPSAwO1xuXG4gIGlmIChkaWRSZW5kZXJUb29GZXdIb29rcykge1xuICAgIHRocm93IG5ldyBFcnJvcignUmVuZGVyZWQgZmV3ZXIgaG9va3MgdGhhbiBleHBlY3RlZC4gVGhpcyBtYXkgYmUgY2F1c2VkIGJ5IGFuIGFjY2lkZW50YWwgJyArICdlYXJseSByZXR1cm4gc3RhdGVtZW50LicpO1xuICB9XG5cbiAgcmV0dXJuIGNoaWxkcmVuO1xufVxuZnVuY3Rpb24gY2hlY2tEaWRSZW5kZXJJZEhvb2soKSB7XG4gIC8vIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCBpbW1lZGlhdGVseSBhZnRlciBldmVyeSByZW5kZXJXaXRoSG9va3MgY2FsbC5cbiAgLy8gQ29uY2VwdHVhbGx5LCBpdCdzIHBhcnQgb2YgdGhlIHJldHVybiB2YWx1ZSBvZiByZW5kZXJXaXRoSG9va3M7IGl0J3Mgb25seSBhXG4gIC8vIHNlcGFyYXRlIGZ1bmN0aW9uIHRvIGF2b2lkIHVzaW5nIGFuIGFycmF5IHR1cGxlLlxuICB2YXIgZGlkUmVuZGVySWRIb29rID0gbG9jYWxJZENvdW50ZXIgIT09IDA7XG4gIGxvY2FsSWRDb3VudGVyID0gMDtcbiAgcmV0dXJuIGRpZFJlbmRlcklkSG9vaztcbn1cbmZ1bmN0aW9uIGJhaWxvdXRIb29rcyhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbGFuZXMpIHtcbiAgd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWUgPSBjdXJyZW50LnVwZGF0ZVF1ZXVlOyAvLyBUT0RPOiBEb24ndCBuZWVkIHRvIHJlc2V0IHRoZSBmbGFncyBoZXJlLCBiZWNhdXNlIHRoZXkncmUgcmVzZXQgaW4gdGhlXG4gIC8vIGNvbXBsZXRlIHBoYXNlIChidWJibGVQcm9wZXJ0aWVzKS5cblxuICBpZiAoICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgU3RyaWN0RWZmZWN0c01vZGUpICE9PSBOb01vZGUpIHtcbiAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyAmPSB+KE1vdW50UGFzc2l2ZURldiB8IE1vdW50TGF5b3V0RGV2IHwgUGFzc2l2ZSB8IFVwZGF0ZSk7XG4gIH0gZWxzZSB7XG4gICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgJj0gfihQYXNzaXZlIHwgVXBkYXRlKTtcbiAgfVxuXG4gIGN1cnJlbnQubGFuZXMgPSByZW1vdmVMYW5lcyhjdXJyZW50LmxhbmVzLCBsYW5lcyk7XG59XG5mdW5jdGlvbiByZXNldEhvb2tzQWZ0ZXJUaHJvdygpIHtcbiAgLy8gV2UgY2FuIGFzc3VtZSB0aGUgcHJldmlvdXMgZGlzcGF0Y2hlciBpcyBhbHdheXMgdGhpcyBvbmUsIHNpbmNlIHdlIHNldCBpdFxuICAvLyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZW5kZXIgcGhhc2UgYW5kIHRoZXJlJ3Mgbm8gcmUtZW50cmFuY2UuXG4gIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gQ29udGV4dE9ubHlEaXNwYXRjaGVyO1xuXG4gIGlmIChkaWRTY2hlZHVsZVJlbmRlclBoYXNlVXBkYXRlKSB7XG4gICAgLy8gVGhlcmUgd2VyZSByZW5kZXIgcGhhc2UgdXBkYXRlcy4gVGhlc2UgYXJlIG9ubHkgdmFsaWQgZm9yIHRoaXMgcmVuZGVyXG4gICAgLy8gcGhhc2UsIHdoaWNoIHdlIGFyZSBub3cgYWJvcnRpbmcuIFJlbW92ZSB0aGUgdXBkYXRlcyBmcm9tIHRoZSBxdWV1ZXMgc29cbiAgICAvLyB0aGV5IGRvIG5vdCBwZXJzaXN0IHRvIHRoZSBuZXh0IHJlbmRlci4gRG8gbm90IHJlbW92ZSB1cGRhdGVzIGZyb20gaG9va3NcbiAgICAvLyB0aGF0IHdlcmVuJ3QgcHJvY2Vzc2VkLlxuICAgIC8vXG4gICAgLy8gT25seSByZXNldCB0aGUgdXBkYXRlcyBmcm9tIHRoZSBxdWV1ZSBpZiBpdCBoYXMgYSBjbG9uZS4gSWYgaXQgZG9lc1xuICAgIC8vIG5vdCBoYXZlIGEgY2xvbmUsIHRoYXQgbWVhbnMgaXQgd2Fzbid0IHByb2Nlc3NlZCwgYW5kIHRoZSB1cGRhdGVzIHdlcmVcbiAgICAvLyBzY2hlZHVsZWQgYmVmb3JlIHdlIGVudGVyZWQgdGhlIHJlbmRlciBwaGFzZS5cbiAgICB2YXIgaG9vayA9IGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEubWVtb2l6ZWRTdGF0ZTtcblxuICAgIHdoaWxlIChob29rICE9PSBudWxsKSB7XG4gICAgICB2YXIgcXVldWUgPSBob29rLnF1ZXVlO1xuXG4gICAgICBpZiAocXVldWUgIT09IG51bGwpIHtcbiAgICAgICAgcXVldWUucGVuZGluZyA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGhvb2sgPSBob29rLm5leHQ7XG4gICAgfVxuXG4gICAgZGlkU2NoZWR1bGVSZW5kZXJQaGFzZVVwZGF0ZSA9IGZhbHNlO1xuICB9XG5cbiAgcmVuZGVyTGFuZXMgPSBOb0xhbmVzO1xuICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxID0gbnVsbDtcbiAgY3VycmVudEhvb2sgPSBudWxsO1xuICB3b3JrSW5Qcm9ncmVzc0hvb2sgPSBudWxsO1xuXG4gIHtcbiAgICBob29rVHlwZXNEZXYgPSBudWxsO1xuICAgIGhvb2tUeXBlc1VwZGF0ZUluZGV4RGV2ID0gLTE7XG4gICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSBudWxsO1xuICAgIGlzVXBkYXRpbmdPcGFxdWVWYWx1ZUluUmVuZGVyUGhhc2UgPSBmYWxzZTtcbiAgfVxuXG4gIGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGVEdXJpbmdUaGlzUGFzcyA9IGZhbHNlO1xuICBsb2NhbElkQ291bnRlciA9IDA7XG59XG5cbmZ1bmN0aW9uIG1vdW50V29ya0luUHJvZ3Jlc3NIb29rKCkge1xuICB2YXIgaG9vayA9IHtcbiAgICBtZW1vaXplZFN0YXRlOiBudWxsLFxuICAgIGJhc2VTdGF0ZTogbnVsbCxcbiAgICBiYXNlUXVldWU6IG51bGwsXG4gICAgcXVldWU6IG51bGwsXG4gICAgbmV4dDogbnVsbFxuICB9O1xuXG4gIGlmICh3b3JrSW5Qcm9ncmVzc0hvb2sgPT09IG51bGwpIHtcbiAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCBob29rIGluIHRoZSBsaXN0XG4gICAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5tZW1vaXplZFN0YXRlID0gd29ya0luUHJvZ3Jlc3NIb29rID0gaG9vaztcbiAgfSBlbHNlIHtcbiAgICAvLyBBcHBlbmQgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdFxuICAgIHdvcmtJblByb2dyZXNzSG9vayA9IHdvcmtJblByb2dyZXNzSG9vay5uZXh0ID0gaG9vaztcbiAgfVxuXG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzc0hvb2s7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpIHtcbiAgLy8gVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGJvdGggZm9yIHVwZGF0ZXMgYW5kIGZvciByZS1yZW5kZXJzIHRyaWdnZXJlZCBieSBhXG4gIC8vIHJlbmRlciBwaGFzZSB1cGRhdGUuIEl0IGFzc3VtZXMgdGhlcmUgaXMgZWl0aGVyIGEgY3VycmVudCBob29rIHdlIGNhblxuICAvLyBjbG9uZSwgb3IgYSB3b3JrLWluLXByb2dyZXNzIGhvb2sgZnJvbSBhIHByZXZpb3VzIHJlbmRlciBwYXNzIHRoYXQgd2UgY2FuXG4gIC8vIHVzZSBhcyBhIGJhc2UuIFdoZW4gd2UgcmVhY2ggdGhlIGVuZCBvZiB0aGUgYmFzZSBsaXN0LCB3ZSBtdXN0IHN3aXRjaCB0b1xuICAvLyB0aGUgZGlzcGF0Y2hlciB1c2VkIGZvciBtb3VudHMuXG4gIHZhciBuZXh0Q3VycmVudEhvb2s7XG5cbiAgaWYgKGN1cnJlbnRIb29rID09PSBudWxsKSB7XG4gICAgdmFyIGN1cnJlbnQgPSBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLmFsdGVybmF0ZTtcblxuICAgIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgICBuZXh0Q3VycmVudEhvb2sgPSBjdXJyZW50Lm1lbW9pemVkU3RhdGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5leHRDdXJyZW50SG9vayA9IG51bGw7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIG5leHRDdXJyZW50SG9vayA9IGN1cnJlbnRIb29rLm5leHQ7XG4gIH1cblxuICB2YXIgbmV4dFdvcmtJblByb2dyZXNzSG9vaztcblxuICBpZiAod29ya0luUHJvZ3Jlc3NIb29rID09PSBudWxsKSB7XG4gICAgbmV4dFdvcmtJblByb2dyZXNzSG9vayA9IGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEubWVtb2l6ZWRTdGF0ZTtcbiAgfSBlbHNlIHtcbiAgICBuZXh0V29ya0luUHJvZ3Jlc3NIb29rID0gd29ya0luUHJvZ3Jlc3NIb29rLm5leHQ7XG4gIH1cblxuICBpZiAobmV4dFdvcmtJblByb2dyZXNzSG9vayAhPT0gbnVsbCkge1xuICAgIC8vIFRoZXJlJ3MgYWxyZWFkeSBhIHdvcmstaW4tcHJvZ3Jlc3MuIFJldXNlIGl0LlxuICAgIHdvcmtJblByb2dyZXNzSG9vayA9IG5leHRXb3JrSW5Qcm9ncmVzc0hvb2s7XG4gICAgbmV4dFdvcmtJblByb2dyZXNzSG9vayA9IHdvcmtJblByb2dyZXNzSG9vay5uZXh0O1xuICAgIGN1cnJlbnRIb29rID0gbmV4dEN1cnJlbnRIb29rO1xuICB9IGVsc2Uge1xuICAgIC8vIENsb25lIGZyb20gdGhlIGN1cnJlbnQgaG9vay5cbiAgICBpZiAobmV4dEN1cnJlbnRIb29rID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlbmRlcmVkIG1vcmUgaG9va3MgdGhhbiBkdXJpbmcgdGhlIHByZXZpb3VzIHJlbmRlci4nKTtcbiAgICB9XG5cbiAgICBjdXJyZW50SG9vayA9IG5leHRDdXJyZW50SG9vaztcbiAgICB2YXIgbmV3SG9vayA9IHtcbiAgICAgIG1lbW9pemVkU3RhdGU6IGN1cnJlbnRIb29rLm1lbW9pemVkU3RhdGUsXG4gICAgICBiYXNlU3RhdGU6IGN1cnJlbnRIb29rLmJhc2VTdGF0ZSxcbiAgICAgIGJhc2VRdWV1ZTogY3VycmVudEhvb2suYmFzZVF1ZXVlLFxuICAgICAgcXVldWU6IGN1cnJlbnRIb29rLnF1ZXVlLFxuICAgICAgbmV4dDogbnVsbFxuICAgIH07XG5cbiAgICBpZiAod29ya0luUHJvZ3Jlc3NIb29rID09PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCBob29rIGluIHRoZSBsaXN0LlxuICAgICAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5tZW1vaXplZFN0YXRlID0gd29ya0luUHJvZ3Jlc3NIb29rID0gbmV3SG9vaztcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXBwZW5kIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3QuXG4gICAgICB3b3JrSW5Qcm9ncmVzc0hvb2sgPSB3b3JrSW5Qcm9ncmVzc0hvb2submV4dCA9IG5ld0hvb2s7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzSG9vaztcbn1cblxuZnVuY3Rpb24gY3JlYXRlRnVuY3Rpb25Db21wb25lbnRVcGRhdGVRdWV1ZSgpIHtcbiAgcmV0dXJuIHtcbiAgICBsYXN0RWZmZWN0OiBudWxsLFxuICAgIHN0b3JlczogbnVsbFxuICB9O1xufVxuXG5mdW5jdGlvbiBiYXNpY1N0YXRlUmVkdWNlcihzdGF0ZSwgYWN0aW9uKSB7XG4gIC8vICRGbG93Rml4TWU6IEZsb3cgZG9lc24ndCBsaWtlIG1peGVkIHR5cGVzXG4gIHJldHVybiB0eXBlb2YgYWN0aW9uID09PSAnZnVuY3Rpb24nID8gYWN0aW9uKHN0YXRlKSA6IGFjdGlvbjtcbn1cblxuZnVuY3Rpb24gbW91bnRSZWR1Y2VyKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgdmFyIGhvb2sgPSBtb3VudFdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgaW5pdGlhbFN0YXRlO1xuXG4gIGlmIChpbml0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBpbml0aWFsU3RhdGUgPSBpbml0KGluaXRpYWxBcmcpO1xuICB9IGVsc2Uge1xuICAgIGluaXRpYWxTdGF0ZSA9IGluaXRpYWxBcmc7XG4gIH1cblxuICBob29rLm1lbW9pemVkU3RhdGUgPSBob29rLmJhc2VTdGF0ZSA9IGluaXRpYWxTdGF0ZTtcbiAgdmFyIHF1ZXVlID0ge1xuICAgIHBlbmRpbmc6IG51bGwsXG4gICAgaW50ZXJsZWF2ZWQ6IG51bGwsXG4gICAgbGFuZXM6IE5vTGFuZXMsXG4gICAgZGlzcGF0Y2g6IG51bGwsXG4gICAgbGFzdFJlbmRlcmVkUmVkdWNlcjogcmVkdWNlcixcbiAgICBsYXN0UmVuZGVyZWRTdGF0ZTogaW5pdGlhbFN0YXRlXG4gIH07XG4gIGhvb2sucXVldWUgPSBxdWV1ZTtcbiAgdmFyIGRpc3BhdGNoID0gcXVldWUuZGlzcGF0Y2ggPSBkaXNwYXRjaFJlZHVjZXJBY3Rpb24uYmluZChudWxsLCBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLCBxdWV1ZSk7XG4gIHJldHVybiBbaG9vay5tZW1vaXplZFN0YXRlLCBkaXNwYXRjaF07XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCkge1xuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgcXVldWUgPSBob29rLnF1ZXVlO1xuXG4gIGlmIChxdWV1ZSA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hvdWxkIGhhdmUgYSBxdWV1ZS4gVGhpcyBpcyBsaWtlbHkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICB9XG5cbiAgcXVldWUubGFzdFJlbmRlcmVkUmVkdWNlciA9IHJlZHVjZXI7XG4gIHZhciBjdXJyZW50ID0gY3VycmVudEhvb2s7IC8vIFRoZSBsYXN0IHJlYmFzZSB1cGRhdGUgdGhhdCBpcyBOT1QgcGFydCBvZiB0aGUgYmFzZSBzdGF0ZS5cblxuICB2YXIgYmFzZVF1ZXVlID0gY3VycmVudC5iYXNlUXVldWU7IC8vIFRoZSBsYXN0IHBlbmRpbmcgdXBkYXRlIHRoYXQgaGFzbid0IGJlZW4gcHJvY2Vzc2VkIHlldC5cblxuICB2YXIgcGVuZGluZ1F1ZXVlID0gcXVldWUucGVuZGluZztcblxuICBpZiAocGVuZGluZ1F1ZXVlICE9PSBudWxsKSB7XG4gICAgLy8gV2UgaGF2ZSBuZXcgdXBkYXRlcyB0aGF0IGhhdmVuJ3QgYmVlbiBwcm9jZXNzZWQgeWV0LlxuICAgIC8vIFdlJ2xsIGFkZCB0aGVtIHRvIHRoZSBiYXNlIHF1ZXVlLlxuICAgIGlmIChiYXNlUXVldWUgIT09IG51bGwpIHtcbiAgICAgIC8vIE1lcmdlIHRoZSBwZW5kaW5nIHF1ZXVlIGFuZCB0aGUgYmFzZSBxdWV1ZS5cbiAgICAgIHZhciBiYXNlRmlyc3QgPSBiYXNlUXVldWUubmV4dDtcbiAgICAgIHZhciBwZW5kaW5nRmlyc3QgPSBwZW5kaW5nUXVldWUubmV4dDtcbiAgICAgIGJhc2VRdWV1ZS5uZXh0ID0gcGVuZGluZ0ZpcnN0O1xuICAgICAgcGVuZGluZ1F1ZXVlLm5leHQgPSBiYXNlRmlyc3Q7XG4gICAgfVxuXG4gICAge1xuICAgICAgaWYgKGN1cnJlbnQuYmFzZVF1ZXVlICE9PSBiYXNlUXVldWUpIHtcbiAgICAgICAgLy8gSW50ZXJuYWwgaW52YXJpYW50IHRoYXQgc2hvdWxkIG5ldmVyIGhhcHBlbiwgYnV0IGZlYXNpYmx5IGNvdWxkIGluXG4gICAgICAgIC8vIHRoZSBmdXR1cmUgaWYgd2UgaW1wbGVtZW50IHJlc3VtaW5nLCBvciBzb21lIGZvcm0gb2YgdGhhdC5cbiAgICAgICAgZXJyb3IoJ0ludGVybmFsIGVycm9yOiBFeHBlY3RlZCB3b3JrLWluLXByb2dyZXNzIHF1ZXVlIHRvIGJlIGEgY2xvbmUuICcgKyAnVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjdXJyZW50LmJhc2VRdWV1ZSA9IGJhc2VRdWV1ZSA9IHBlbmRpbmdRdWV1ZTtcbiAgICBxdWV1ZS5wZW5kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChiYXNlUXVldWUgIT09IG51bGwpIHtcbiAgICAvLyBXZSBoYXZlIGEgcXVldWUgdG8gcHJvY2Vzcy5cbiAgICB2YXIgZmlyc3QgPSBiYXNlUXVldWUubmV4dDtcbiAgICB2YXIgbmV3U3RhdGUgPSBjdXJyZW50LmJhc2VTdGF0ZTtcbiAgICB2YXIgbmV3QmFzZVN0YXRlID0gbnVsbDtcbiAgICB2YXIgbmV3QmFzZVF1ZXVlRmlyc3QgPSBudWxsO1xuICAgIHZhciBuZXdCYXNlUXVldWVMYXN0ID0gbnVsbDtcbiAgICB2YXIgdXBkYXRlID0gZmlyc3Q7XG5cbiAgICBkbyB7XG4gICAgICB2YXIgdXBkYXRlTGFuZSA9IHVwZGF0ZS5sYW5lO1xuXG4gICAgICBpZiAoIWlzU3Vic2V0T2ZMYW5lcyhyZW5kZXJMYW5lcywgdXBkYXRlTGFuZSkpIHtcbiAgICAgICAgLy8gUHJpb3JpdHkgaXMgaW5zdWZmaWNpZW50LiBTa2lwIHRoaXMgdXBkYXRlLiBJZiB0aGlzIGlzIHRoZSBmaXJzdFxuICAgICAgICAvLyBza2lwcGVkIHVwZGF0ZSwgdGhlIHByZXZpb3VzIHVwZGF0ZS9zdGF0ZSBpcyB0aGUgbmV3IGJhc2VcbiAgICAgICAgLy8gdXBkYXRlL3N0YXRlLlxuICAgICAgICB2YXIgY2xvbmUgPSB7XG4gICAgICAgICAgbGFuZTogdXBkYXRlTGFuZSxcbiAgICAgICAgICBhY3Rpb246IHVwZGF0ZS5hY3Rpb24sXG4gICAgICAgICAgaGFzRWFnZXJTdGF0ZTogdXBkYXRlLmhhc0VhZ2VyU3RhdGUsXG4gICAgICAgICAgZWFnZXJTdGF0ZTogdXBkYXRlLmVhZ2VyU3RhdGUsXG4gICAgICAgICAgbmV4dDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChuZXdCYXNlUXVldWVMYXN0ID09PSBudWxsKSB7XG4gICAgICAgICAgbmV3QmFzZVF1ZXVlRmlyc3QgPSBuZXdCYXNlUXVldWVMYXN0ID0gY2xvbmU7XG4gICAgICAgICAgbmV3QmFzZVN0YXRlID0gbmV3U3RhdGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmV3QmFzZVF1ZXVlTGFzdCA9IG5ld0Jhc2VRdWV1ZUxhc3QubmV4dCA9IGNsb25lO1xuICAgICAgICB9IC8vIFVwZGF0ZSB0aGUgcmVtYWluaW5nIHByaW9yaXR5IGluIHRoZSBxdWV1ZS5cbiAgICAgICAgLy8gVE9ETzogRG9uJ3QgbmVlZCB0byBhY2N1bXVsYXRlIHRoaXMuIEluc3RlYWQsIHdlIGNhbiByZW1vdmVcbiAgICAgICAgLy8gcmVuZGVyTGFuZXMgZnJvbSB0aGUgb3JpZ2luYWwgbGFuZXMuXG5cblxuICAgICAgICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLmxhbmVzID0gbWVyZ2VMYW5lcyhjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLmxhbmVzLCB1cGRhdGVMYW5lKTtcbiAgICAgICAgbWFya1NraXBwZWRVcGRhdGVMYW5lcyh1cGRhdGVMYW5lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRoaXMgdXBkYXRlIGRvZXMgaGF2ZSBzdWZmaWNpZW50IHByaW9yaXR5LlxuICAgICAgICBpZiAobmV3QmFzZVF1ZXVlTGFzdCAhPT0gbnVsbCkge1xuICAgICAgICAgIHZhciBfY2xvbmUgPSB7XG4gICAgICAgICAgICAvLyBUaGlzIHVwZGF0ZSBpcyBnb2luZyB0byBiZSBjb21taXR0ZWQgc28gd2UgbmV2ZXIgd2FudCB1bmNvbW1pdFxuICAgICAgICAgICAgLy8gaXQuIFVzaW5nIE5vTGFuZSB3b3JrcyBiZWNhdXNlIDAgaXMgYSBzdWJzZXQgb2YgYWxsIGJpdG1hc2tzLCBzb1xuICAgICAgICAgICAgLy8gdGhpcyB3aWxsIG5ldmVyIGJlIHNraXBwZWQgYnkgdGhlIGNoZWNrIGFib3ZlLlxuICAgICAgICAgICAgbGFuZTogTm9MYW5lLFxuICAgICAgICAgICAgYWN0aW9uOiB1cGRhdGUuYWN0aW9uLFxuICAgICAgICAgICAgaGFzRWFnZXJTdGF0ZTogdXBkYXRlLmhhc0VhZ2VyU3RhdGUsXG4gICAgICAgICAgICBlYWdlclN0YXRlOiB1cGRhdGUuZWFnZXJTdGF0ZSxcbiAgICAgICAgICAgIG5leHQ6IG51bGxcbiAgICAgICAgICB9O1xuICAgICAgICAgIG5ld0Jhc2VRdWV1ZUxhc3QgPSBuZXdCYXNlUXVldWVMYXN0Lm5leHQgPSBfY2xvbmU7XG4gICAgICAgIH0gLy8gUHJvY2VzcyB0aGlzIHVwZGF0ZS5cblxuXG4gICAgICAgIGlmICh1cGRhdGUuaGFzRWFnZXJTdGF0ZSkge1xuICAgICAgICAgIC8vIElmIHRoaXMgdXBkYXRlIGlzIGEgc3RhdGUgdXBkYXRlIChub3QgYSByZWR1Y2VyKSBhbmQgd2FzIHByb2Nlc3NlZCBlYWdlcmx5LFxuICAgICAgICAgIC8vIHdlIGNhbiB1c2UgdGhlIGVhZ2VybHkgY29tcHV0ZWQgc3RhdGVcbiAgICAgICAgICBuZXdTdGF0ZSA9IHVwZGF0ZS5lYWdlclN0YXRlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBhY3Rpb24gPSB1cGRhdGUuYWN0aW9uO1xuICAgICAgICAgIG5ld1N0YXRlID0gcmVkdWNlcihuZXdTdGF0ZSwgYWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB1cGRhdGUgPSB1cGRhdGUubmV4dDtcbiAgICB9IHdoaWxlICh1cGRhdGUgIT09IG51bGwgJiYgdXBkYXRlICE9PSBmaXJzdCk7XG5cbiAgICBpZiAobmV3QmFzZVF1ZXVlTGFzdCA9PT0gbnVsbCkge1xuICAgICAgbmV3QmFzZVN0YXRlID0gbmV3U3RhdGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld0Jhc2VRdWV1ZUxhc3QubmV4dCA9IG5ld0Jhc2VRdWV1ZUZpcnN0O1xuICAgIH0gLy8gTWFyayB0aGF0IHRoZSBmaWJlciBwZXJmb3JtZWQgd29yaywgYnV0IG9ubHkgaWYgdGhlIG5ldyBzdGF0ZSBpc1xuICAgIC8vIGRpZmZlcmVudCBmcm9tIHRoZSBjdXJyZW50IHN0YXRlLlxuXG5cbiAgICBpZiAoIW9iamVjdElzKG5ld1N0YXRlLCBob29rLm1lbW9pemVkU3RhdGUpKSB7XG4gICAgICBtYXJrV29ya0luUHJvZ3Jlc3NSZWNlaXZlZFVwZGF0ZSgpO1xuICAgIH1cblxuICAgIGhvb2subWVtb2l6ZWRTdGF0ZSA9IG5ld1N0YXRlO1xuICAgIGhvb2suYmFzZVN0YXRlID0gbmV3QmFzZVN0YXRlO1xuICAgIGhvb2suYmFzZVF1ZXVlID0gbmV3QmFzZVF1ZXVlTGFzdDtcbiAgICBxdWV1ZS5sYXN0UmVuZGVyZWRTdGF0ZSA9IG5ld1N0YXRlO1xuICB9IC8vIEludGVybGVhdmVkIHVwZGF0ZXMgYXJlIHN0b3JlZCBvbiBhIHNlcGFyYXRlIHF1ZXVlLiBXZSBhcmVuJ3QgZ29pbmcgdG9cbiAgLy8gcHJvY2VzcyB0aGVtIGR1cmluZyB0aGlzIHJlbmRlciwgYnV0IHdlIGRvIG5lZWQgdG8gdHJhY2sgd2hpY2ggbGFuZXNcbiAgLy8gYXJlIHJlbWFpbmluZy5cblxuXG4gIHZhciBsYXN0SW50ZXJsZWF2ZWQgPSBxdWV1ZS5pbnRlcmxlYXZlZDtcblxuICBpZiAobGFzdEludGVybGVhdmVkICE9PSBudWxsKSB7XG4gICAgdmFyIGludGVybGVhdmVkID0gbGFzdEludGVybGVhdmVkO1xuXG4gICAgZG8ge1xuICAgICAgdmFyIGludGVybGVhdmVkTGFuZSA9IGludGVybGVhdmVkLmxhbmU7XG4gICAgICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLmxhbmVzID0gbWVyZ2VMYW5lcyhjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLmxhbmVzLCBpbnRlcmxlYXZlZExhbmUpO1xuICAgICAgbWFya1NraXBwZWRVcGRhdGVMYW5lcyhpbnRlcmxlYXZlZExhbmUpO1xuICAgICAgaW50ZXJsZWF2ZWQgPSBpbnRlcmxlYXZlZC5uZXh0O1xuICAgIH0gd2hpbGUgKGludGVybGVhdmVkICE9PSBsYXN0SW50ZXJsZWF2ZWQpO1xuICB9IGVsc2UgaWYgKGJhc2VRdWV1ZSA9PT0gbnVsbCkge1xuICAgIC8vIGBxdWV1ZS5sYW5lc2AgaXMgdXNlZCBmb3IgZW50YW5nbGluZyB0cmFuc2l0aW9ucy4gV2UgY2FuIHNldCBpdCBiYWNrIHRvXG4gICAgLy8gemVybyBvbmNlIHRoZSBxdWV1ZSBpcyBlbXB0eS5cbiAgICBxdWV1ZS5sYW5lcyA9IE5vTGFuZXM7XG4gIH1cblxuICB2YXIgZGlzcGF0Y2ggPSBxdWV1ZS5kaXNwYXRjaDtcbiAgcmV0dXJuIFtob29rLm1lbW9pemVkU3RhdGUsIGRpc3BhdGNoXTtcbn1cblxuZnVuY3Rpb24gcmVyZW5kZXJSZWR1Y2VyKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIHF1ZXVlID0gaG9vay5xdWV1ZTtcblxuICBpZiAocXVldWUgPT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Nob3VsZCBoYXZlIGEgcXVldWUuIFRoaXMgaXMgbGlrZWx5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgfVxuXG4gIHF1ZXVlLmxhc3RSZW5kZXJlZFJlZHVjZXIgPSByZWR1Y2VyOyAvLyBUaGlzIGlzIGEgcmUtcmVuZGVyLiBBcHBseSB0aGUgbmV3IHJlbmRlciBwaGFzZSB1cGRhdGVzIHRvIHRoZSBwcmV2aW91c1xuICAvLyB3b3JrLWluLXByb2dyZXNzIGhvb2suXG5cbiAgdmFyIGRpc3BhdGNoID0gcXVldWUuZGlzcGF0Y2g7XG4gIHZhciBsYXN0UmVuZGVyUGhhc2VVcGRhdGUgPSBxdWV1ZS5wZW5kaW5nO1xuICB2YXIgbmV3U3RhdGUgPSBob29rLm1lbW9pemVkU3RhdGU7XG5cbiAgaWYgKGxhc3RSZW5kZXJQaGFzZVVwZGF0ZSAhPT0gbnVsbCkge1xuICAgIC8vIFRoZSBxdWV1ZSBkb2Vzbid0IHBlcnNpc3QgcGFzdCB0aGlzIHJlbmRlciBwYXNzLlxuICAgIHF1ZXVlLnBlbmRpbmcgPSBudWxsO1xuICAgIHZhciBmaXJzdFJlbmRlclBoYXNlVXBkYXRlID0gbGFzdFJlbmRlclBoYXNlVXBkYXRlLm5leHQ7XG4gICAgdmFyIHVwZGF0ZSA9IGZpcnN0UmVuZGVyUGhhc2VVcGRhdGU7XG5cbiAgICBkbyB7XG4gICAgICAvLyBQcm9jZXNzIHRoaXMgcmVuZGVyIHBoYXNlIHVwZGF0ZS4gV2UgZG9uJ3QgaGF2ZSB0byBjaGVjayB0aGVcbiAgICAgIC8vIHByaW9yaXR5IGJlY2F1c2UgaXQgd2lsbCBhbHdheXMgYmUgdGhlIHNhbWUgYXMgdGhlIGN1cnJlbnRcbiAgICAgIC8vIHJlbmRlcidzLlxuICAgICAgdmFyIGFjdGlvbiA9IHVwZGF0ZS5hY3Rpb247XG4gICAgICBuZXdTdGF0ZSA9IHJlZHVjZXIobmV3U3RhdGUsIGFjdGlvbik7XG4gICAgICB1cGRhdGUgPSB1cGRhdGUubmV4dDtcbiAgICB9IHdoaWxlICh1cGRhdGUgIT09IGZpcnN0UmVuZGVyUGhhc2VVcGRhdGUpOyAvLyBNYXJrIHRoYXQgdGhlIGZpYmVyIHBlcmZvcm1lZCB3b3JrLCBidXQgb25seSBpZiB0aGUgbmV3IHN0YXRlIGlzXG4gICAgLy8gZGlmZmVyZW50IGZyb20gdGhlIGN1cnJlbnQgc3RhdGUuXG5cblxuICAgIGlmICghb2JqZWN0SXMobmV3U3RhdGUsIGhvb2subWVtb2l6ZWRTdGF0ZSkpIHtcbiAgICAgIG1hcmtXb3JrSW5Qcm9ncmVzc1JlY2VpdmVkVXBkYXRlKCk7XG4gICAgfVxuXG4gICAgaG9vay5tZW1vaXplZFN0YXRlID0gbmV3U3RhdGU7IC8vIERvbid0IHBlcnNpc3QgdGhlIHN0YXRlIGFjY3VtdWxhdGVkIGZyb20gdGhlIHJlbmRlciBwaGFzZSB1cGRhdGVzIHRvXG4gICAgLy8gdGhlIGJhc2Ugc3RhdGUgdW5sZXNzIHRoZSBxdWV1ZSBpcyBlbXB0eS5cbiAgICAvLyBUT0RPOiBOb3Qgc3VyZSBpZiB0aGlzIGlzIHRoZSBkZXNpcmVkIHNlbWFudGljcywgYnV0IGl0J3Mgd2hhdCB3ZVxuICAgIC8vIGRvIGZvciBnRFNGUC4gSSBjYW4ndCByZW1lbWJlciB3aHkuXG5cbiAgICBpZiAoaG9vay5iYXNlUXVldWUgPT09IG51bGwpIHtcbiAgICAgIGhvb2suYmFzZVN0YXRlID0gbmV3U3RhdGU7XG4gICAgfVxuXG4gICAgcXVldWUubGFzdFJlbmRlcmVkU3RhdGUgPSBuZXdTdGF0ZTtcbiAgfVxuXG4gIHJldHVybiBbbmV3U3RhdGUsIGRpc3BhdGNoXTtcbn1cblxuZnVuY3Rpb24gbW91bnRNdXRhYmxlU291cmNlKHNvdXJjZSwgZ2V0U25hcHNob3QsIHN1YnNjcmliZSkge1xuICB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG5mdW5jdGlvbiB1cGRhdGVNdXRhYmxlU291cmNlKHNvdXJjZSwgZ2V0U25hcHNob3QsIHN1YnNjcmliZSkge1xuICB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG5mdW5jdGlvbiBtb3VudFN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KSB7XG4gIHZhciBmaWJlciA9IGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDE7XG4gIHZhciBob29rID0gbW91bnRXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIG5leHRTbmFwc2hvdDtcbiAgdmFyIGlzSHlkcmF0aW5nID0gZ2V0SXNIeWRyYXRpbmcoKTtcblxuICBpZiAoaXNIeWRyYXRpbmcpIHtcbiAgICBpZiAoZ2V0U2VydmVyU25hcHNob3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGdldFNlcnZlclNuYXBzaG90LCB3aGljaCBpcyByZXF1aXJlZCBmb3IgJyArICdzZXJ2ZXItcmVuZGVyZWQgY29udGVudC4gV2lsbCByZXZlcnQgdG8gY2xpZW50IHJlbmRlcmluZy4nKTtcbiAgICB9XG5cbiAgICBuZXh0U25hcHNob3QgPSBnZXRTZXJ2ZXJTbmFwc2hvdCgpO1xuXG4gICAge1xuICAgICAgaWYgKCFkaWRXYXJuVW5jYWNoZWRHZXRTbmFwc2hvdCkge1xuICAgICAgICBpZiAobmV4dFNuYXBzaG90ICE9PSBnZXRTZXJ2ZXJTbmFwc2hvdCgpKSB7XG4gICAgICAgICAgZXJyb3IoJ1RoZSByZXN1bHQgb2YgZ2V0U2VydmVyU25hcHNob3Qgc2hvdWxkIGJlIGNhY2hlZCB0byBhdm9pZCBhbiBpbmZpbml0ZSBsb29wJyk7XG5cbiAgICAgICAgICBkaWRXYXJuVW5jYWNoZWRHZXRTbmFwc2hvdCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgbmV4dFNuYXBzaG90ID0gZ2V0U25hcHNob3QoKTtcblxuICAgIHtcbiAgICAgIGlmICghZGlkV2FyblVuY2FjaGVkR2V0U25hcHNob3QpIHtcbiAgICAgICAgdmFyIGNhY2hlZFNuYXBzaG90ID0gZ2V0U25hcHNob3QoKTtcblxuICAgICAgICBpZiAoIW9iamVjdElzKG5leHRTbmFwc2hvdCwgY2FjaGVkU25hcHNob3QpKSB7XG4gICAgICAgICAgZXJyb3IoJ1RoZSByZXN1bHQgb2YgZ2V0U25hcHNob3Qgc2hvdWxkIGJlIGNhY2hlZCB0byBhdm9pZCBhbiBpbmZpbml0ZSBsb29wJyk7XG5cbiAgICAgICAgICBkaWRXYXJuVW5jYWNoZWRHZXRTbmFwc2hvdCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IC8vIFVubGVzcyB3ZSdyZSByZW5kZXJpbmcgYSBibG9ja2luZyBsYW5lLCBzY2hlZHVsZSBhIGNvbnNpc3RlbmN5IGNoZWNrLlxuICAgIC8vIFJpZ2h0IGJlZm9yZSBjb21taXR0aW5nLCB3ZSB3aWxsIHdhbGsgdGhlIHRyZWUgYW5kIGNoZWNrIGlmIGFueSBvZiB0aGVcbiAgICAvLyBzdG9yZXMgd2VyZSBtdXRhdGVkLlxuICAgIC8vXG4gICAgLy8gV2Ugd29uJ3QgZG8gdGhpcyBpZiB3ZSdyZSBoeWRyYXRpbmcgc2VydmVyLXJlbmRlcmVkIGNvbnRlbnQsIGJlY2F1c2UgaWZcbiAgICAvLyB0aGUgY29udGVudCBpcyBzdGFsZSwgaXQncyBhbHJlYWR5IHZpc2libGUgYW55d2F5LiBJbnN0ZWFkIHdlJ2xsIHBhdGNoXG4gICAgLy8gaXQgdXAgaW4gYSBwYXNzaXZlIGVmZmVjdC5cblxuXG4gICAgdmFyIHJvb3QgPSBnZXRXb3JrSW5Qcm9ncmVzc1Jvb3QoKTtcblxuICAgIGlmIChyb290ID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIGEgd29yay1pbi1wcm9ncmVzcyByb290LiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG5cbiAgICBpZiAoIWluY2x1ZGVzQmxvY2tpbmdMYW5lKHJvb3QsIHJlbmRlckxhbmVzKSkge1xuICAgICAgcHVzaFN0b3JlQ29uc2lzdGVuY3lDaGVjayhmaWJlciwgZ2V0U25hcHNob3QsIG5leHRTbmFwc2hvdCk7XG4gICAgfVxuICB9IC8vIFJlYWQgdGhlIGN1cnJlbnQgc25hcHNob3QgZnJvbSB0aGUgc3RvcmUgb24gZXZlcnkgcmVuZGVyLiBUaGlzIGJyZWFrcyB0aGVcbiAgLy8gbm9ybWFsIHJ1bGVzIG9mIFJlYWN0LCBhbmQgb25seSB3b3JrcyBiZWNhdXNlIHN0b3JlIHVwZGF0ZXMgYXJlXG4gIC8vIGFsd2F5cyBzeW5jaHJvbm91cy5cblxuXG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IG5leHRTbmFwc2hvdDtcbiAgdmFyIGluc3QgPSB7XG4gICAgdmFsdWU6IG5leHRTbmFwc2hvdCxcbiAgICBnZXRTbmFwc2hvdDogZ2V0U25hcHNob3RcbiAgfTtcbiAgaG9vay5xdWV1ZSA9IGluc3Q7IC8vIFNjaGVkdWxlIGFuIGVmZmVjdCB0byBzdWJzY3JpYmUgdG8gdGhlIHN0b3JlLlxuXG4gIG1vdW50RWZmZWN0KHN1YnNjcmliZVRvU3RvcmUuYmluZChudWxsLCBmaWJlciwgaW5zdCwgc3Vic2NyaWJlKSwgW3N1YnNjcmliZV0pOyAvLyBTY2hlZHVsZSBhbiBlZmZlY3QgdG8gdXBkYXRlIHRoZSBtdXRhYmxlIGluc3RhbmNlIGZpZWxkcy4gV2Ugd2lsbCB1cGRhdGVcbiAgLy8gdGhpcyB3aGVuZXZlciBzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBvciB2YWx1ZSBjaGFuZ2VzLiBCZWNhdXNlIHRoZXJlJ3Mgbm9cbiAgLy8gY2xlYW4tdXAgZnVuY3Rpb24sIGFuZCB3ZSB0cmFjayB0aGUgZGVwcyBjb3JyZWN0bHksIHdlIGNhbiBjYWxsIHB1c2hFZmZlY3RcbiAgLy8gZGlyZWN0bHksIHdpdGhvdXQgc3RvcmluZyBhbnkgYWRkaXRpb25hbCBzdGF0ZS4gRm9yIHRoZSBzYW1lIHJlYXNvbiwgd2VcbiAgLy8gZG9uJ3QgbmVlZCB0byBzZXQgYSBzdGF0aWMgZmxhZywgZWl0aGVyLlxuICAvLyBUT0RPOiBXZSBjYW4gbW92ZSB0aGlzIHRvIHRoZSBwYXNzaXZlIHBoYXNlIG9uY2Ugd2UgYWRkIGEgcHJlLWNvbW1pdFxuICAvLyBjb25zaXN0ZW5jeSBjaGVjay4gU2VlIHRoZSBuZXh0IGNvbW1lbnQuXG5cbiAgZmliZXIuZmxhZ3MgfD0gUGFzc2l2ZTtcbiAgcHVzaEVmZmVjdChIYXNFZmZlY3QgfCBQYXNzaXZlJDEsIHVwZGF0ZVN0b3JlSW5zdGFuY2UuYmluZChudWxsLCBmaWJlciwgaW5zdCwgbmV4dFNuYXBzaG90LCBnZXRTbmFwc2hvdCksIHVuZGVmaW5lZCwgbnVsbCk7XG4gIHJldHVybiBuZXh0U25hcHNob3Q7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KSB7XG4gIHZhciBmaWJlciA9IGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDE7XG4gIHZhciBob29rID0gdXBkYXRlV29ya0luUHJvZ3Jlc3NIb29rKCk7IC8vIFJlYWQgdGhlIGN1cnJlbnQgc25hcHNob3QgZnJvbSB0aGUgc3RvcmUgb24gZXZlcnkgcmVuZGVyLiBUaGlzIGJyZWFrcyB0aGVcbiAgLy8gbm9ybWFsIHJ1bGVzIG9mIFJlYWN0LCBhbmQgb25seSB3b3JrcyBiZWNhdXNlIHN0b3JlIHVwZGF0ZXMgYXJlXG4gIC8vIGFsd2F5cyBzeW5jaHJvbm91cy5cblxuICB2YXIgbmV4dFNuYXBzaG90ID0gZ2V0U25hcHNob3QoKTtcblxuICB7XG4gICAgaWYgKCFkaWRXYXJuVW5jYWNoZWRHZXRTbmFwc2hvdCkge1xuICAgICAgdmFyIGNhY2hlZFNuYXBzaG90ID0gZ2V0U25hcHNob3QoKTtcblxuICAgICAgaWYgKCFvYmplY3RJcyhuZXh0U25hcHNob3QsIGNhY2hlZFNuYXBzaG90KSkge1xuICAgICAgICBlcnJvcignVGhlIHJlc3VsdCBvZiBnZXRTbmFwc2hvdCBzaG91bGQgYmUgY2FjaGVkIHRvIGF2b2lkIGFuIGluZmluaXRlIGxvb3AnKTtcblxuICAgICAgICBkaWRXYXJuVW5jYWNoZWRHZXRTbmFwc2hvdCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHByZXZTbmFwc2hvdCA9IGhvb2subWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIHNuYXBzaG90Q2hhbmdlZCA9ICFvYmplY3RJcyhwcmV2U25hcHNob3QsIG5leHRTbmFwc2hvdCk7XG5cbiAgaWYgKHNuYXBzaG90Q2hhbmdlZCkge1xuICAgIGhvb2subWVtb2l6ZWRTdGF0ZSA9IG5leHRTbmFwc2hvdDtcbiAgICBtYXJrV29ya0luUHJvZ3Jlc3NSZWNlaXZlZFVwZGF0ZSgpO1xuICB9XG5cbiAgdmFyIGluc3QgPSBob29rLnF1ZXVlO1xuICB1cGRhdGVFZmZlY3Qoc3Vic2NyaWJlVG9TdG9yZS5iaW5kKG51bGwsIGZpYmVyLCBpbnN0LCBzdWJzY3JpYmUpLCBbc3Vic2NyaWJlXSk7IC8vIFdoZW5ldmVyIGdldFNuYXBzaG90IG9yIHN1YnNjcmliZSBjaGFuZ2VzLCB3ZSBuZWVkIHRvIGNoZWNrIGluIHRoZVxuICAvLyBjb21taXQgcGhhc2UgaWYgdGhlcmUgd2FzIGFuIGludGVybGVhdmVkIG11dGF0aW9uLiBJbiBjb25jdXJyZW50IG1vZGVcbiAgLy8gdGhpcyBjYW4gaGFwcGVuIGFsbCB0aGUgdGltZSwgYnV0IGV2ZW4gaW4gc3luY2hyb25vdXMgbW9kZSwgYW4gZWFybGllclxuICAvLyBlZmZlY3QgbWF5IGhhdmUgbXV0YXRlZCB0aGUgc3RvcmUuXG5cbiAgaWYgKGluc3QuZ2V0U25hcHNob3QgIT09IGdldFNuYXBzaG90IHx8IHNuYXBzaG90Q2hhbmdlZCB8fCAvLyBDaGVjayBpZiB0aGUgc3VzYmNyaWJlIGZ1bmN0aW9uIGNoYW5nZWQuIFdlIGNhbiBzYXZlIHNvbWUgbWVtb3J5IGJ5XG4gIC8vIGNoZWNraW5nIHdoZXRoZXIgd2Ugc2NoZWR1bGVkIGEgc3Vic2NyaXB0aW9uIGVmZmVjdCBhYm92ZS5cbiAgd29ya0luUHJvZ3Jlc3NIb29rICE9PSBudWxsICYmIHdvcmtJblByb2dyZXNzSG9vay5tZW1vaXplZFN0YXRlLnRhZyAmIEhhc0VmZmVjdCkge1xuICAgIGZpYmVyLmZsYWdzIHw9IFBhc3NpdmU7XG4gICAgcHVzaEVmZmVjdChIYXNFZmZlY3QgfCBQYXNzaXZlJDEsIHVwZGF0ZVN0b3JlSW5zdGFuY2UuYmluZChudWxsLCBmaWJlciwgaW5zdCwgbmV4dFNuYXBzaG90LCBnZXRTbmFwc2hvdCksIHVuZGVmaW5lZCwgbnVsbCk7IC8vIFVubGVzcyB3ZSdyZSByZW5kZXJpbmcgYSBibG9ja2luZyBsYW5lLCBzY2hlZHVsZSBhIGNvbnNpc3RlbmN5IGNoZWNrLlxuICAgIC8vIFJpZ2h0IGJlZm9yZSBjb21taXR0aW5nLCB3ZSB3aWxsIHdhbGsgdGhlIHRyZWUgYW5kIGNoZWNrIGlmIGFueSBvZiB0aGVcbiAgICAvLyBzdG9yZXMgd2VyZSBtdXRhdGVkLlxuXG4gICAgdmFyIHJvb3QgPSBnZXRXb3JrSW5Qcm9ncmVzc1Jvb3QoKTtcblxuICAgIGlmIChyb290ID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIGEgd29yay1pbi1wcm9ncmVzcyByb290LiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG5cbiAgICBpZiAoIWluY2x1ZGVzQmxvY2tpbmdMYW5lKHJvb3QsIHJlbmRlckxhbmVzKSkge1xuICAgICAgcHVzaFN0b3JlQ29uc2lzdGVuY3lDaGVjayhmaWJlciwgZ2V0U25hcHNob3QsIG5leHRTbmFwc2hvdCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5leHRTbmFwc2hvdDtcbn1cblxuZnVuY3Rpb24gcHVzaFN0b3JlQ29uc2lzdGVuY3lDaGVjayhmaWJlciwgZ2V0U25hcHNob3QsIHJlbmRlcmVkU25hcHNob3QpIHtcbiAgZmliZXIuZmxhZ3MgfD0gU3RvcmVDb25zaXN0ZW5jeTtcbiAgdmFyIGNoZWNrID0ge1xuICAgIGdldFNuYXBzaG90OiBnZXRTbmFwc2hvdCxcbiAgICB2YWx1ZTogcmVuZGVyZWRTbmFwc2hvdFxuICB9O1xuICB2YXIgY29tcG9uZW50VXBkYXRlUXVldWUgPSBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLnVwZGF0ZVF1ZXVlO1xuXG4gIGlmIChjb21wb25lbnRVcGRhdGVRdWV1ZSA9PT0gbnVsbCkge1xuICAgIGNvbXBvbmVudFVwZGF0ZVF1ZXVlID0gY3JlYXRlRnVuY3Rpb25Db21wb25lbnRVcGRhdGVRdWV1ZSgpO1xuICAgIGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEudXBkYXRlUXVldWUgPSBjb21wb25lbnRVcGRhdGVRdWV1ZTtcbiAgICBjb21wb25lbnRVcGRhdGVRdWV1ZS5zdG9yZXMgPSBbY2hlY2tdO1xuICB9IGVsc2Uge1xuICAgIHZhciBzdG9yZXMgPSBjb21wb25lbnRVcGRhdGVRdWV1ZS5zdG9yZXM7XG5cbiAgICBpZiAoc3RvcmVzID09PSBudWxsKSB7XG4gICAgICBjb21wb25lbnRVcGRhdGVRdWV1ZS5zdG9yZXMgPSBbY2hlY2tdO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdG9yZXMucHVzaChjaGVjayk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN0b3JlSW5zdGFuY2UoZmliZXIsIGluc3QsIG5leHRTbmFwc2hvdCwgZ2V0U25hcHNob3QpIHtcbiAgLy8gVGhlc2UgYXJlIHVwZGF0ZWQgaW4gdGhlIHBhc3NpdmUgcGhhc2VcbiAgaW5zdC52YWx1ZSA9IG5leHRTbmFwc2hvdDtcbiAgaW5zdC5nZXRTbmFwc2hvdCA9IGdldFNuYXBzaG90OyAvLyBTb21ldGhpbmcgbWF5IGhhdmUgYmVlbiBtdXRhdGVkIGluIGJldHdlZW4gcmVuZGVyIGFuZCBjb21taXQuIFRoaXMgY291bGRcbiAgLy8gaGF2ZSBiZWVuIGluIGFuIGV2ZW50IHRoYXQgZmlyZWQgYmVmb3JlIHRoZSBwYXNzaXZlIGVmZmVjdHMsIG9yIGl0IGNvdWxkXG4gIC8vIGhhdmUgYmVlbiBpbiBhIGxheW91dCBlZmZlY3QuIEluIHRoYXQgY2FzZSwgd2Ugd291bGQgaGF2ZSB1c2VkIHRoZSBvbGRcbiAgLy8gc25hcHNobyBhbmQgZ2V0U25hcHNob3QgdmFsdWVzIHRvIGJhaWwgb3V0LiBXZSBuZWVkIHRvIGNoZWNrIG9uZSBtb3JlIHRpbWUuXG5cbiAgaWYgKGNoZWNrSWZTbmFwc2hvdENoYW5nZWQoaW5zdCkpIHtcbiAgICAvLyBGb3JjZSBhIHJlLXJlbmRlci5cbiAgICBmb3JjZVN0b3JlUmVyZW5kZXIoZmliZXIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN1YnNjcmliZVRvU3RvcmUoZmliZXIsIGluc3QsIHN1YnNjcmliZSkge1xuICB2YXIgaGFuZGxlU3RvcmVDaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy8gVGhlIHN0b3JlIGNoYW5nZWQuIENoZWNrIGlmIHRoZSBzbmFwc2hvdCBjaGFuZ2VkIHNpbmNlIHRoZSBsYXN0IHRpbWUgd2VcbiAgICAvLyByZWFkIGZyb20gdGhlIHN0b3JlLlxuICAgIGlmIChjaGVja0lmU25hcHNob3RDaGFuZ2VkKGluc3QpKSB7XG4gICAgICAvLyBGb3JjZSBhIHJlLXJlbmRlci5cbiAgICAgIGZvcmNlU3RvcmVSZXJlbmRlcihmaWJlcik7XG4gICAgfVxuICB9OyAvLyBTdWJzY3JpYmUgdG8gdGhlIHN0b3JlIGFuZCByZXR1cm4gYSBjbGVhbi11cCBmdW5jdGlvbi5cblxuXG4gIHJldHVybiBzdWJzY3JpYmUoaGFuZGxlU3RvcmVDaGFuZ2UpO1xufVxuXG5mdW5jdGlvbiBjaGVja0lmU25hcHNob3RDaGFuZ2VkKGluc3QpIHtcbiAgdmFyIGxhdGVzdEdldFNuYXBzaG90ID0gaW5zdC5nZXRTbmFwc2hvdDtcbiAgdmFyIHByZXZWYWx1ZSA9IGluc3QudmFsdWU7XG5cbiAgdHJ5IHtcbiAgICB2YXIgbmV4dFZhbHVlID0gbGF0ZXN0R2V0U25hcHNob3QoKTtcbiAgICByZXR1cm4gIW9iamVjdElzKHByZXZWYWx1ZSwgbmV4dFZhbHVlKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmb3JjZVN0b3JlUmVyZW5kZXIoZmliZXIpIHtcbiAgdmFyIHJvb3QgPSBlbnF1ZXVlQ29uY3VycmVudFJlbmRlckZvckxhbmUoZmliZXIsIFN5bmNMYW5lKTtcblxuICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtb3VudFN0YXRlKGluaXRpYWxTdGF0ZSkge1xuICB2YXIgaG9vayA9IG1vdW50V29ya0luUHJvZ3Jlc3NIb29rKCk7XG5cbiAgaWYgKHR5cGVvZiBpbml0aWFsU3RhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyAkRmxvd0ZpeE1lOiBGbG93IGRvZXNuJ3QgbGlrZSBtaXhlZCB0eXBlc1xuICAgIGluaXRpYWxTdGF0ZSA9IGluaXRpYWxTdGF0ZSgpO1xuICB9XG5cbiAgaG9vay5tZW1vaXplZFN0YXRlID0gaG9vay5iYXNlU3RhdGUgPSBpbml0aWFsU3RhdGU7XG4gIHZhciBxdWV1ZSA9IHtcbiAgICBwZW5kaW5nOiBudWxsLFxuICAgIGludGVybGVhdmVkOiBudWxsLFxuICAgIGxhbmVzOiBOb0xhbmVzLFxuICAgIGRpc3BhdGNoOiBudWxsLFxuICAgIGxhc3RSZW5kZXJlZFJlZHVjZXI6IGJhc2ljU3RhdGVSZWR1Y2VyLFxuICAgIGxhc3RSZW5kZXJlZFN0YXRlOiBpbml0aWFsU3RhdGVcbiAgfTtcbiAgaG9vay5xdWV1ZSA9IHF1ZXVlO1xuICB2YXIgZGlzcGF0Y2ggPSBxdWV1ZS5kaXNwYXRjaCA9IGRpc3BhdGNoU2V0U3RhdGUuYmluZChudWxsLCBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLCBxdWV1ZSk7XG4gIHJldHVybiBbaG9vay5tZW1vaXplZFN0YXRlLCBkaXNwYXRjaF07XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN0YXRlKGluaXRpYWxTdGF0ZSkge1xuICByZXR1cm4gdXBkYXRlUmVkdWNlcihiYXNpY1N0YXRlUmVkdWNlcik7XG59XG5cbmZ1bmN0aW9uIHJlcmVuZGVyU3RhdGUoaW5pdGlhbFN0YXRlKSB7XG4gIHJldHVybiByZXJlbmRlclJlZHVjZXIoYmFzaWNTdGF0ZVJlZHVjZXIpO1xufVxuXG5mdW5jdGlvbiBwdXNoRWZmZWN0KHRhZywgY3JlYXRlLCBkZXN0cm95LCBkZXBzKSB7XG4gIHZhciBlZmZlY3QgPSB7XG4gICAgdGFnOiB0YWcsXG4gICAgY3JlYXRlOiBjcmVhdGUsXG4gICAgZGVzdHJveTogZGVzdHJveSxcbiAgICBkZXBzOiBkZXBzLFxuICAgIC8vIENpcmN1bGFyXG4gICAgbmV4dDogbnVsbFxuICB9O1xuICB2YXIgY29tcG9uZW50VXBkYXRlUXVldWUgPSBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLnVwZGF0ZVF1ZXVlO1xuXG4gIGlmIChjb21wb25lbnRVcGRhdGVRdWV1ZSA9PT0gbnVsbCkge1xuICAgIGNvbXBvbmVudFVwZGF0ZVF1ZXVlID0gY3JlYXRlRnVuY3Rpb25Db21wb25lbnRVcGRhdGVRdWV1ZSgpO1xuICAgIGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEudXBkYXRlUXVldWUgPSBjb21wb25lbnRVcGRhdGVRdWV1ZTtcbiAgICBjb21wb25lbnRVcGRhdGVRdWV1ZS5sYXN0RWZmZWN0ID0gZWZmZWN0Lm5leHQgPSBlZmZlY3Q7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxhc3RFZmZlY3QgPSBjb21wb25lbnRVcGRhdGVRdWV1ZS5sYXN0RWZmZWN0O1xuXG4gICAgaWYgKGxhc3RFZmZlY3QgPT09IG51bGwpIHtcbiAgICAgIGNvbXBvbmVudFVwZGF0ZVF1ZXVlLmxhc3RFZmZlY3QgPSBlZmZlY3QubmV4dCA9IGVmZmVjdDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGZpcnN0RWZmZWN0ID0gbGFzdEVmZmVjdC5uZXh0O1xuICAgICAgbGFzdEVmZmVjdC5uZXh0ID0gZWZmZWN0O1xuICAgICAgZWZmZWN0Lm5leHQgPSBmaXJzdEVmZmVjdDtcbiAgICAgIGNvbXBvbmVudFVwZGF0ZVF1ZXVlLmxhc3RFZmZlY3QgPSBlZmZlY3Q7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVmZmVjdDtcbn1cblxuZnVuY3Rpb24gbW91bnRSZWYoaW5pdGlhbFZhbHVlKSB7XG4gIHZhciBob29rID0gbW91bnRXb3JrSW5Qcm9ncmVzc0hvb2soKTtcblxuICB7XG4gICAgdmFyIF9yZWYyID0ge1xuICAgICAgY3VycmVudDogaW5pdGlhbFZhbHVlXG4gICAgfTtcbiAgICBob29rLm1lbW9pemVkU3RhdGUgPSBfcmVmMjtcbiAgICByZXR1cm4gX3JlZjI7XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlUmVmKGluaXRpYWxWYWx1ZSkge1xuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpO1xuICByZXR1cm4gaG9vay5tZW1vaXplZFN0YXRlO1xufVxuXG5mdW5jdGlvbiBtb3VudEVmZmVjdEltcGwoZmliZXJGbGFncywgaG9va0ZsYWdzLCBjcmVhdGUsIGRlcHMpIHtcbiAgdmFyIGhvb2sgPSBtb3VudFdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgbmV4dERlcHMgPSBkZXBzID09PSB1bmRlZmluZWQgPyBudWxsIDogZGVwcztcbiAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5mbGFncyB8PSBmaWJlckZsYWdzO1xuICBob29rLm1lbW9pemVkU3RhdGUgPSBwdXNoRWZmZWN0KEhhc0VmZmVjdCB8IGhvb2tGbGFncywgY3JlYXRlLCB1bmRlZmluZWQsIG5leHREZXBzKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlRWZmZWN0SW1wbChmaWJlckZsYWdzLCBob29rRmxhZ3MsIGNyZWF0ZSwgZGVwcykge1xuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgbmV4dERlcHMgPSBkZXBzID09PSB1bmRlZmluZWQgPyBudWxsIDogZGVwcztcbiAgdmFyIGRlc3Ryb3kgPSB1bmRlZmluZWQ7XG5cbiAgaWYgKGN1cnJlbnRIb29rICE9PSBudWxsKSB7XG4gICAgdmFyIHByZXZFZmZlY3QgPSBjdXJyZW50SG9vay5tZW1vaXplZFN0YXRlO1xuICAgIGRlc3Ryb3kgPSBwcmV2RWZmZWN0LmRlc3Ryb3k7XG5cbiAgICBpZiAobmV4dERlcHMgIT09IG51bGwpIHtcbiAgICAgIHZhciBwcmV2RGVwcyA9IHByZXZFZmZlY3QuZGVwcztcblxuICAgICAgaWYgKGFyZUhvb2tJbnB1dHNFcXVhbChuZXh0RGVwcywgcHJldkRlcHMpKSB7XG4gICAgICAgIGhvb2subWVtb2l6ZWRTdGF0ZSA9IHB1c2hFZmZlY3QoaG9va0ZsYWdzLCBjcmVhdGUsIGRlc3Ryb3ksIG5leHREZXBzKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEuZmxhZ3MgfD0gZmliZXJGbGFncztcbiAgaG9vay5tZW1vaXplZFN0YXRlID0gcHVzaEVmZmVjdChIYXNFZmZlY3QgfCBob29rRmxhZ3MsIGNyZWF0ZSwgZGVzdHJveSwgbmV4dERlcHMpO1xufVxuXG5mdW5jdGlvbiBtb3VudEVmZmVjdChjcmVhdGUsIGRlcHMpIHtcbiAgaWYgKCAoY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5tb2RlICYgU3RyaWN0RWZmZWN0c01vZGUpICE9PSBOb01vZGUpIHtcbiAgICByZXR1cm4gbW91bnRFZmZlY3RJbXBsKE1vdW50UGFzc2l2ZURldiB8IFBhc3NpdmUgfCBQYXNzaXZlU3RhdGljLCBQYXNzaXZlJDEsIGNyZWF0ZSwgZGVwcyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG1vdW50RWZmZWN0SW1wbChQYXNzaXZlIHwgUGFzc2l2ZVN0YXRpYywgUGFzc2l2ZSQxLCBjcmVhdGUsIGRlcHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUVmZmVjdChjcmVhdGUsIGRlcHMpIHtcbiAgcmV0dXJuIHVwZGF0ZUVmZmVjdEltcGwoUGFzc2l2ZSwgUGFzc2l2ZSQxLCBjcmVhdGUsIGRlcHMpO1xufVxuXG5mdW5jdGlvbiBtb3VudEluc2VydGlvbkVmZmVjdChjcmVhdGUsIGRlcHMpIHtcbiAgcmV0dXJuIG1vdW50RWZmZWN0SW1wbChVcGRhdGUsIEluc2VydGlvbiwgY3JlYXRlLCBkZXBzKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlSW5zZXJ0aW9uRWZmZWN0KGNyZWF0ZSwgZGVwcykge1xuICByZXR1cm4gdXBkYXRlRWZmZWN0SW1wbChVcGRhdGUsIEluc2VydGlvbiwgY3JlYXRlLCBkZXBzKTtcbn1cblxuZnVuY3Rpb24gbW91bnRMYXlvdXRFZmZlY3QoY3JlYXRlLCBkZXBzKSB7XG4gIHZhciBmaWJlckZsYWdzID0gVXBkYXRlO1xuXG4gIHtcbiAgICBmaWJlckZsYWdzIHw9IExheW91dFN0YXRpYztcbiAgfVxuXG4gIGlmICggKGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEubW9kZSAmIFN0cmljdEVmZmVjdHNNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgZmliZXJGbGFncyB8PSBNb3VudExheW91dERldjtcbiAgfVxuXG4gIHJldHVybiBtb3VudEVmZmVjdEltcGwoZmliZXJGbGFncywgTGF5b3V0LCBjcmVhdGUsIGRlcHMpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVMYXlvdXRFZmZlY3QoY3JlYXRlLCBkZXBzKSB7XG4gIHJldHVybiB1cGRhdGVFZmZlY3RJbXBsKFVwZGF0ZSwgTGF5b3V0LCBjcmVhdGUsIGRlcHMpO1xufVxuXG5mdW5jdGlvbiBpbXBlcmF0aXZlSGFuZGxlRWZmZWN0KGNyZWF0ZSwgcmVmKSB7XG4gIGlmICh0eXBlb2YgcmVmID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdmFyIHJlZkNhbGxiYWNrID0gcmVmO1xuXG4gICAgdmFyIF9pbnN0ID0gY3JlYXRlKCk7XG5cbiAgICByZWZDYWxsYmFjayhfaW5zdCk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlZkNhbGxiYWNrKG51bGwpO1xuICAgIH07XG4gIH0gZWxzZSBpZiAocmVmICE9PSBudWxsICYmIHJlZiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIHJlZk9iamVjdCA9IHJlZjtcblxuICAgIHtcbiAgICAgIGlmICghcmVmT2JqZWN0Lmhhc093blByb3BlcnR5KCdjdXJyZW50JykpIHtcbiAgICAgICAgZXJyb3IoJ0V4cGVjdGVkIHVzZUltcGVyYXRpdmVIYW5kbGUoKSBmaXJzdCBhcmd1bWVudCB0byBlaXRoZXIgYmUgYSAnICsgJ3JlZiBjYWxsYmFjayBvciBSZWFjdC5jcmVhdGVSZWYoKSBvYmplY3QuIEluc3RlYWQgcmVjZWl2ZWQ6ICVzLicsICdhbiBvYmplY3Qgd2l0aCBrZXlzIHsnICsgT2JqZWN0LmtleXMocmVmT2JqZWN0KS5qb2luKCcsICcpICsgJ30nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgX2luc3QyID0gY3JlYXRlKCk7XG5cbiAgICByZWZPYmplY3QuY3VycmVudCA9IF9pbnN0MjtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgcmVmT2JqZWN0LmN1cnJlbnQgPSBudWxsO1xuICAgIH07XG4gIH1cbn1cblxuZnVuY3Rpb24gbW91bnRJbXBlcmF0aXZlSGFuZGxlKHJlZiwgY3JlYXRlLCBkZXBzKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIGNyZWF0ZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIHVzZUltcGVyYXRpdmVIYW5kbGUoKSBzZWNvbmQgYXJndW1lbnQgdG8gYmUgYSBmdW5jdGlvbiAnICsgJ3RoYXQgY3JlYXRlcyBhIGhhbmRsZS4gSW5zdGVhZCByZWNlaXZlZDogJXMuJywgY3JlYXRlICE9PSBudWxsID8gdHlwZW9mIGNyZWF0ZSA6ICdudWxsJyk7XG4gICAgfVxuICB9IC8vIFRPRE86IElmIGRlcHMgYXJlIHByb3ZpZGVkLCBzaG91bGQgd2Ugc2tpcCBjb21wYXJpbmcgdGhlIHJlZiBpdHNlbGY/XG5cblxuICB2YXIgZWZmZWN0RGVwcyA9IGRlcHMgIT09IG51bGwgJiYgZGVwcyAhPT0gdW5kZWZpbmVkID8gZGVwcy5jb25jYXQoW3JlZl0pIDogbnVsbDtcbiAgdmFyIGZpYmVyRmxhZ3MgPSBVcGRhdGU7XG5cbiAge1xuICAgIGZpYmVyRmxhZ3MgfD0gTGF5b3V0U3RhdGljO1xuICB9XG5cbiAgaWYgKCAoY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5tb2RlICYgU3RyaWN0RWZmZWN0c01vZGUpICE9PSBOb01vZGUpIHtcbiAgICBmaWJlckZsYWdzIHw9IE1vdW50TGF5b3V0RGV2O1xuICB9XG5cbiAgcmV0dXJuIG1vdW50RWZmZWN0SW1wbChmaWJlckZsYWdzLCBMYXlvdXQsIGltcGVyYXRpdmVIYW5kbGVFZmZlY3QuYmluZChudWxsLCBjcmVhdGUsIHJlZiksIGVmZmVjdERlcHMpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVJbXBlcmF0aXZlSGFuZGxlKHJlZiwgY3JlYXRlLCBkZXBzKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIGNyZWF0ZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIHVzZUltcGVyYXRpdmVIYW5kbGUoKSBzZWNvbmQgYXJndW1lbnQgdG8gYmUgYSBmdW5jdGlvbiAnICsgJ3RoYXQgY3JlYXRlcyBhIGhhbmRsZS4gSW5zdGVhZCByZWNlaXZlZDogJXMuJywgY3JlYXRlICE9PSBudWxsID8gdHlwZW9mIGNyZWF0ZSA6ICdudWxsJyk7XG4gICAgfVxuICB9IC8vIFRPRE86IElmIGRlcHMgYXJlIHByb3ZpZGVkLCBzaG91bGQgd2Ugc2tpcCBjb21wYXJpbmcgdGhlIHJlZiBpdHNlbGY/XG5cblxuICB2YXIgZWZmZWN0RGVwcyA9IGRlcHMgIT09IG51bGwgJiYgZGVwcyAhPT0gdW5kZWZpbmVkID8gZGVwcy5jb25jYXQoW3JlZl0pIDogbnVsbDtcbiAgcmV0dXJuIHVwZGF0ZUVmZmVjdEltcGwoVXBkYXRlLCBMYXlvdXQsIGltcGVyYXRpdmVIYW5kbGVFZmZlY3QuYmluZChudWxsLCBjcmVhdGUsIHJlZiksIGVmZmVjdERlcHMpO1xufVxuXG5mdW5jdGlvbiBtb3VudERlYnVnVmFsdWUodmFsdWUsIGZvcm1hdHRlckZuKSB7Ly8gVGhpcyBob29rIGlzIG5vcm1hbGx5IGEgbm8tb3AuXG4gIC8vIFRoZSByZWFjdC1kZWJ1Zy1ob29rcyBwYWNrYWdlIGluamVjdHMgaXRzIG93biBpbXBsZW1lbnRhdGlvblxuICAvLyBzbyB0aGF0IGUuZy4gRGV2VG9vbHMgY2FuIGRpc3BsYXkgY3VzdG9tIGhvb2sgdmFsdWVzLlxufVxuXG52YXIgdXBkYXRlRGVidWdWYWx1ZSA9IG1vdW50RGVidWdWYWx1ZTtcblxuZnVuY3Rpb24gbW91bnRDYWxsYmFjayhjYWxsYmFjaywgZGVwcykge1xuICB2YXIgaG9vayA9IG1vdW50V29ya0luUHJvZ3Jlc3NIb29rKCk7XG4gIHZhciBuZXh0RGVwcyA9IGRlcHMgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBkZXBzO1xuICBob29rLm1lbW9pemVkU3RhdGUgPSBbY2FsbGJhY2ssIG5leHREZXBzXTtcbiAgcmV0dXJuIGNhbGxiYWNrO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVDYWxsYmFjayhjYWxsYmFjaywgZGVwcykge1xuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgbmV4dERlcHMgPSBkZXBzID09PSB1bmRlZmluZWQgPyBudWxsIDogZGVwcztcbiAgdmFyIHByZXZTdGF0ZSA9IGhvb2subWVtb2l6ZWRTdGF0ZTtcblxuICBpZiAocHJldlN0YXRlICE9PSBudWxsKSB7XG4gICAgaWYgKG5leHREZXBzICE9PSBudWxsKSB7XG4gICAgICB2YXIgcHJldkRlcHMgPSBwcmV2U3RhdGVbMV07XG5cbiAgICAgIGlmIChhcmVIb29rSW5wdXRzRXF1YWwobmV4dERlcHMsIHByZXZEZXBzKSkge1xuICAgICAgICByZXR1cm4gcHJldlN0YXRlWzBdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IFtjYWxsYmFjaywgbmV4dERlcHNdO1xuICByZXR1cm4gY2FsbGJhY2s7XG59XG5cbmZ1bmN0aW9uIG1vdW50TWVtbyhuZXh0Q3JlYXRlLCBkZXBzKSB7XG4gIHZhciBob29rID0gbW91bnRXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIG5leHREZXBzID0gZGVwcyA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGRlcHM7XG4gIHZhciBuZXh0VmFsdWUgPSBuZXh0Q3JlYXRlKCk7XG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IFtuZXh0VmFsdWUsIG5leHREZXBzXTtcbiAgcmV0dXJuIG5leHRWYWx1ZTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlTWVtbyhuZXh0Q3JlYXRlLCBkZXBzKSB7XG4gIHZhciBob29rID0gdXBkYXRlV29ya0luUHJvZ3Jlc3NIb29rKCk7XG4gIHZhciBuZXh0RGVwcyA9IGRlcHMgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBkZXBzO1xuICB2YXIgcHJldlN0YXRlID0gaG9vay5tZW1vaXplZFN0YXRlO1xuXG4gIGlmIChwcmV2U3RhdGUgIT09IG51bGwpIHtcbiAgICAvLyBBc3N1bWUgdGhlc2UgYXJlIGRlZmluZWQuIElmIHRoZXkncmUgbm90LCBhcmVIb29rSW5wdXRzRXF1YWwgd2lsbCB3YXJuLlxuICAgIGlmIChuZXh0RGVwcyAhPT0gbnVsbCkge1xuICAgICAgdmFyIHByZXZEZXBzID0gcHJldlN0YXRlWzFdO1xuXG4gICAgICBpZiAoYXJlSG9va0lucHV0c0VxdWFsKG5leHREZXBzLCBwcmV2RGVwcykpIHtcbiAgICAgICAgcmV0dXJuIHByZXZTdGF0ZVswXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgbmV4dFZhbHVlID0gbmV4dENyZWF0ZSgpO1xuICBob29rLm1lbW9pemVkU3RhdGUgPSBbbmV4dFZhbHVlLCBuZXh0RGVwc107XG4gIHJldHVybiBuZXh0VmFsdWU7XG59XG5cbmZ1bmN0aW9uIG1vdW50RGVmZXJyZWRWYWx1ZSh2YWx1ZSkge1xuICB2YXIgaG9vayA9IG1vdW50V29ya0luUHJvZ3Jlc3NIb29rKCk7XG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IHZhbHVlO1xuICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZURlZmVycmVkVmFsdWUodmFsdWUpIHtcbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIHJlc29sdmVkQ3VycmVudEhvb2sgPSBjdXJyZW50SG9vaztcbiAgdmFyIHByZXZWYWx1ZSA9IHJlc29sdmVkQ3VycmVudEhvb2subWVtb2l6ZWRTdGF0ZTtcbiAgcmV0dXJuIHVwZGF0ZURlZmVycmVkVmFsdWVJbXBsKGhvb2ssIHByZXZWYWx1ZSwgdmFsdWUpO1xufVxuXG5mdW5jdGlvbiByZXJlbmRlckRlZmVycmVkVmFsdWUodmFsdWUpIHtcbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcblxuICBpZiAoY3VycmVudEhvb2sgPT09IG51bGwpIHtcbiAgICAvLyBUaGlzIGlzIGEgcmVyZW5kZXIgZHVyaW5nIGEgbW91bnQuXG4gICAgaG9vay5tZW1vaXplZFN0YXRlID0gdmFsdWU7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgaXMgYSByZXJlbmRlciBkdXJpbmcgYW4gdXBkYXRlLlxuICAgIHZhciBwcmV2VmFsdWUgPSBjdXJyZW50SG9vay5tZW1vaXplZFN0YXRlO1xuICAgIHJldHVybiB1cGRhdGVEZWZlcnJlZFZhbHVlSW1wbChob29rLCBwcmV2VmFsdWUsIHZhbHVlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB1cGRhdGVEZWZlcnJlZFZhbHVlSW1wbChob29rLCBwcmV2VmFsdWUsIHZhbHVlKSB7XG4gIHZhciBzaG91bGREZWZlclZhbHVlID0gIWluY2x1ZGVzT25seU5vblVyZ2VudExhbmVzKHJlbmRlckxhbmVzKTtcblxuICBpZiAoc2hvdWxkRGVmZXJWYWx1ZSkge1xuICAgIC8vIFRoaXMgaXMgYW4gdXJnZW50IHVwZGF0ZS4gSWYgdGhlIHZhbHVlIGhhcyBjaGFuZ2VkLCBrZWVwIHVzaW5nIHRoZVxuICAgIC8vIHByZXZpb3VzIHZhbHVlIGFuZCBzcGF3biBhIGRlZmVycmVkIHJlbmRlciB0byB1cGRhdGUgaXQgbGF0ZXIuXG4gICAgaWYgKCFvYmplY3RJcyh2YWx1ZSwgcHJldlZhbHVlKSkge1xuICAgICAgLy8gU2NoZWR1bGUgYSBkZWZlcnJlZCByZW5kZXJcbiAgICAgIHZhciBkZWZlcnJlZExhbmUgPSBjbGFpbU5leHRUcmFuc2l0aW9uTGFuZSgpO1xuICAgICAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5sYW5lcyA9IG1lcmdlTGFuZXMoY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5sYW5lcywgZGVmZXJyZWRMYW5lKTtcbiAgICAgIG1hcmtTa2lwcGVkVXBkYXRlTGFuZXMoZGVmZXJyZWRMYW5lKTsgLy8gU2V0IHRoaXMgdG8gdHJ1ZSB0byBpbmRpY2F0ZSB0aGF0IHRoZSByZW5kZXJlZCB2YWx1ZSBpcyBpbmNvbnNpc3RlbnRcbiAgICAgIC8vIGZyb20gdGhlIGxhdGVzdCB2YWx1ZS4gVGhlIG5hbWUgXCJiYXNlU3RhdGVcIiBkb2Vzbid0IHJlYWxseSBtYXRjaCBob3cgd2VcbiAgICAgIC8vIHVzZSBpdCBiZWNhdXNlIHdlJ3JlIHJldXNpbmcgYSBzdGF0ZSBob29rIGZpZWxkIGluc3RlYWQgb2YgY3JlYXRpbmcgYVxuICAgICAgLy8gbmV3IG9uZS5cblxuICAgICAgaG9vay5iYXNlU3RhdGUgPSB0cnVlO1xuICAgIH0gLy8gUmV1c2UgdGhlIHByZXZpb3VzIHZhbHVlXG5cblxuICAgIHJldHVybiBwcmV2VmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhpcyBpcyBub3QgYW4gdXJnZW50IHVwZGF0ZSwgc28gd2UgY2FuIHVzZSB0aGUgbGF0ZXN0IHZhbHVlIHJlZ2FyZGxlc3NcbiAgICAvLyBvZiB3aGF0IGl0IGlzLiBObyBuZWVkIHRvIGRlZmVyIGl0LlxuICAgIC8vIEhvd2V2ZXIsIGlmIHdlJ3JlIGN1cnJlbnRseSBpbnNpZGUgYSBzcGF3bmVkIHJlbmRlciwgdGhlbiB3ZSBuZWVkIHRvIG1hcmtcbiAgICAvLyB0aGlzIGFzIGFuIHVwZGF0ZSB0byBwcmV2ZW50IHRoZSBmaWJlciBmcm9tIGJhaWxpbmcgb3V0LlxuICAgIC8vXG4gICAgLy8gYGJhc2VTdGF0ZWAgaXMgdHJ1ZSB3aGVuIHRoZSBjdXJyZW50IHZhbHVlIGlzIGRpZmZlcmVudCBmcm9tIHRoZSByZW5kZXJlZFxuICAgIC8vIHZhbHVlLiBUaGUgbmFtZSBkb2Vzbid0IHJlYWxseSBtYXRjaCBob3cgd2UgdXNlIGl0IGJlY2F1c2Ugd2UncmUgcmV1c2luZ1xuICAgIC8vIGEgc3RhdGUgaG9vayBmaWVsZCBpbnN0ZWFkIG9mIGNyZWF0aW5nIGEgbmV3IG9uZS5cbiAgICBpZiAoaG9vay5iYXNlU3RhdGUpIHtcbiAgICAgIC8vIEZsaXAgdGhpcyBiYWNrIHRvIGZhbHNlLlxuICAgICAgaG9vay5iYXNlU3RhdGUgPSBmYWxzZTtcbiAgICAgIG1hcmtXb3JrSW5Qcm9ncmVzc1JlY2VpdmVkVXBkYXRlKCk7XG4gICAgfVxuXG4gICAgaG9vay5tZW1vaXplZFN0YXRlID0gdmFsdWU7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN0YXJ0VHJhbnNpdGlvbihzZXRQZW5kaW5nLCBjYWxsYmFjaywgb3B0aW9ucykge1xuICB2YXIgcHJldmlvdXNQcmlvcml0eSA9IGdldEN1cnJlbnRVcGRhdGVQcmlvcml0eSgpO1xuICBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoaGlnaGVyRXZlbnRQcmlvcml0eShwcmV2aW91c1ByaW9yaXR5LCBDb250aW51b3VzRXZlbnRQcmlvcml0eSkpO1xuICBzZXRQZW5kaW5nKHRydWUpO1xuICB2YXIgcHJldlRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQyLnRyYW5zaXRpb247XG4gIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDIudHJhbnNpdGlvbiA9IHt9O1xuICB2YXIgY3VycmVudFRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQyLnRyYW5zaXRpb247XG5cbiAge1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDIudHJhbnNpdGlvbi5fdXBkYXRlZEZpYmVycyA9IG5ldyBTZXQoKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgc2V0UGVuZGluZyhmYWxzZSk7XG4gICAgY2FsbGJhY2soKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkocHJldmlvdXNQcmlvcml0eSk7XG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMi50cmFuc2l0aW9uID0gcHJldlRyYW5zaXRpb247XG5cbiAgICB7XG4gICAgICBpZiAocHJldlRyYW5zaXRpb24gPT09IG51bGwgJiYgY3VycmVudFRyYW5zaXRpb24uX3VwZGF0ZWRGaWJlcnMpIHtcbiAgICAgICAgdmFyIHVwZGF0ZWRGaWJlcnNDb3VudCA9IGN1cnJlbnRUcmFuc2l0aW9uLl91cGRhdGVkRmliZXJzLnNpemU7XG5cbiAgICAgICAgaWYgKHVwZGF0ZWRGaWJlcnNDb3VudCA+IDEwKSB7XG4gICAgICAgICAgd2FybignRGV0ZWN0ZWQgYSBsYXJnZSBudW1iZXIgb2YgdXBkYXRlcyBpbnNpZGUgc3RhcnRUcmFuc2l0aW9uLiAnICsgJ0lmIHRoaXMgaXMgZHVlIHRvIGEgc3Vic2NyaXB0aW9uIHBsZWFzZSByZS13cml0ZSBpdCB0byB1c2UgUmVhY3QgcHJvdmlkZWQgaG9va3MuICcgKyAnT3RoZXJ3aXNlIGNvbmN1cnJlbnQgbW9kZSBndWFyYW50ZWVzIGFyZSBvZmYgdGhlIHRhYmxlLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgY3VycmVudFRyYW5zaXRpb24uX3VwZGF0ZWRGaWJlcnMuY2xlYXIoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gbW91bnRUcmFuc2l0aW9uKCkge1xuICB2YXIgX21vdW50U3RhdGUgPSBtb3VudFN0YXRlKGZhbHNlKSxcbiAgICAgIGlzUGVuZGluZyA9IF9tb3VudFN0YXRlWzBdLFxuICAgICAgc2V0UGVuZGluZyA9IF9tb3VudFN0YXRlWzFdOyAvLyBUaGUgYHN0YXJ0YCBtZXRob2QgbmV2ZXIgY2hhbmdlcy5cblxuXG4gIHZhciBzdGFydCA9IHN0YXJ0VHJhbnNpdGlvbi5iaW5kKG51bGwsIHNldFBlbmRpbmcpO1xuICB2YXIgaG9vayA9IG1vdW50V29ya0luUHJvZ3Jlc3NIb29rKCk7XG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IHN0YXJ0O1xuICByZXR1cm4gW2lzUGVuZGluZywgc3RhcnRdO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVUcmFuc2l0aW9uKCkge1xuICB2YXIgX3VwZGF0ZVN0YXRlID0gdXBkYXRlU3RhdGUoKSxcbiAgICAgIGlzUGVuZGluZyA9IF91cGRhdGVTdGF0ZVswXTtcblxuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgc3RhcnQgPSBob29rLm1lbW9pemVkU3RhdGU7XG4gIHJldHVybiBbaXNQZW5kaW5nLCBzdGFydF07XG59XG5cbmZ1bmN0aW9uIHJlcmVuZGVyVHJhbnNpdGlvbigpIHtcbiAgdmFyIF9yZXJlbmRlclN0YXRlID0gcmVyZW5kZXJTdGF0ZSgpLFxuICAgICAgaXNQZW5kaW5nID0gX3JlcmVuZGVyU3RhdGVbMF07XG5cbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIHN0YXJ0ID0gaG9vay5tZW1vaXplZFN0YXRlO1xuICByZXR1cm4gW2lzUGVuZGluZywgc3RhcnRdO1xufVxuXG52YXIgaXNVcGRhdGluZ09wYXF1ZVZhbHVlSW5SZW5kZXJQaGFzZSA9IGZhbHNlO1xuZnVuY3Rpb24gZ2V0SXNVcGRhdGluZ09wYXF1ZVZhbHVlSW5SZW5kZXJQaGFzZUluREVWKCkge1xuICB7XG4gICAgcmV0dXJuIGlzVXBkYXRpbmdPcGFxdWVWYWx1ZUluUmVuZGVyUGhhc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gbW91bnRJZCgpIHtcbiAgdmFyIGhvb2sgPSBtb3VudFdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgcm9vdCA9IGdldFdvcmtJblByb2dyZXNzUm9vdCgpOyAvLyBUT0RPOiBJbiBGaXp6LCBpZCBnZW5lcmF0aW9uIGlzIHNwZWNpZmljIHRvIGVhY2ggc2VydmVyIGNvbmZpZy4gTWF5YmUgd2VcbiAgLy8gc2hvdWxkIGRvIHRoaXMgaW4gRmliZXIsIHRvbz8gRGVmZXJyaW5nIHRoaXMgZGVjaXNpb24gZm9yIG5vdyBiZWNhdXNlXG4gIC8vIHRoZXJlJ3Mgbm8gb3RoZXIgcGxhY2UgdG8gc3RvcmUgdGhlIHByZWZpeCBleGNlcHQgZm9yIGFuIGludGVybmFsIGZpZWxkIG9uXG4gIC8vIHRoZSBwdWJsaWMgY3JlYXRlUm9vdCBvYmplY3QsIHdoaWNoIHRoZSBmaWJlciB0cmVlIGRvZXMgbm90IGN1cnJlbnRseSBoYXZlXG4gIC8vIGEgcmVmZXJlbmNlIHRvLlxuXG4gIHZhciBpZGVudGlmaWVyUHJlZml4ID0gcm9vdC5pZGVudGlmaWVyUHJlZml4O1xuICB2YXIgaWQ7XG5cbiAgaWYgKGdldElzSHlkcmF0aW5nKCkpIHtcbiAgICB2YXIgdHJlZUlkID0gZ2V0VHJlZUlkKCk7IC8vIFVzZSBhIGNhcHRpYWwgUiBwcmVmaXggZm9yIHNlcnZlci1nZW5lcmF0ZWQgaWRzLlxuXG4gICAgaWQgPSAnOicgKyBpZGVudGlmaWVyUHJlZml4ICsgJ1InICsgdHJlZUlkOyAvLyBVbmxlc3MgdGhpcyBpcyB0aGUgZmlyc3QgaWQgYXQgdGhpcyBsZXZlbCwgYXBwZW5kIGEgbnVtYmVyIGF0IHRoZSBlbmRcbiAgICAvLyB0aGF0IHJlcHJlc2VudHMgdGhlIHBvc2l0aW9uIG9mIHRoaXMgdXNlSWQgaG9vayBhbW9uZyBhbGwgdGhlIHVzZUlkXG4gICAgLy8gaG9va3MgZm9yIHRoaXMgZmliZXIuXG5cbiAgICB2YXIgbG9jYWxJZCA9IGxvY2FsSWRDb3VudGVyKys7XG5cbiAgICBpZiAobG9jYWxJZCA+IDApIHtcbiAgICAgIGlkICs9ICdIJyArIGxvY2FsSWQudG9TdHJpbmcoMzIpO1xuICAgIH1cblxuICAgIGlkICs9ICc6JztcbiAgfSBlbHNlIHtcbiAgICAvLyBVc2UgYSBsb3dlcmNhc2UgciBwcmVmaXggZm9yIGNsaWVudC1nZW5lcmF0ZWQgaWRzLlxuICAgIHZhciBnbG9iYWxDbGllbnRJZCA9IGdsb2JhbENsaWVudElkQ291bnRlcisrO1xuICAgIGlkID0gJzonICsgaWRlbnRpZmllclByZWZpeCArICdyJyArIGdsb2JhbENsaWVudElkLnRvU3RyaW5nKDMyKSArICc6JztcbiAgfVxuXG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IGlkO1xuICByZXR1cm4gaWQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUlkKCkge1xuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgaWQgPSBob29rLm1lbW9pemVkU3RhdGU7XG4gIHJldHVybiBpZDtcbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hSZWR1Y2VyQWN0aW9uKGZpYmVyLCBxdWV1ZSwgYWN0aW9uKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIGFyZ3VtZW50c1szXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoXCJTdGF0ZSB1cGRhdGVzIGZyb20gdGhlIHVzZVN0YXRlKCkgYW5kIHVzZVJlZHVjZXIoKSBIb29rcyBkb24ndCBzdXBwb3J0IHRoZSBcIiArICdzZWNvbmQgY2FsbGJhY2sgYXJndW1lbnQuIFRvIGV4ZWN1dGUgYSBzaWRlIGVmZmVjdCBhZnRlciAnICsgJ3JlbmRlcmluZywgZGVjbGFyZSBpdCBpbiB0aGUgY29tcG9uZW50IGJvZHkgd2l0aCB1c2VFZmZlY3QoKS4nKTtcbiAgICB9XG4gIH1cblxuICB2YXIgbGFuZSA9IHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKTtcbiAgdmFyIHVwZGF0ZSA9IHtcbiAgICBsYW5lOiBsYW5lLFxuICAgIGFjdGlvbjogYWN0aW9uLFxuICAgIGhhc0VhZ2VyU3RhdGU6IGZhbHNlLFxuICAgIGVhZ2VyU3RhdGU6IG51bGwsXG4gICAgbmV4dDogbnVsbFxuICB9O1xuXG4gIGlmIChpc1JlbmRlclBoYXNlVXBkYXRlKGZpYmVyKSkge1xuICAgIGVucXVldWVSZW5kZXJQaGFzZVVwZGF0ZShxdWV1ZSwgdXBkYXRlKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgcm9vdCA9IGVucXVldWVDb25jdXJyZW50SG9va1VwZGF0ZShmaWJlciwgcXVldWUsIHVwZGF0ZSwgbGFuZSk7XG5cbiAgICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgICAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgbGFuZSwgZXZlbnRUaW1lKTtcbiAgICAgIGVudGFuZ2xlVHJhbnNpdGlvblVwZGF0ZShyb290LCBxdWV1ZSwgbGFuZSk7XG4gICAgfVxuICB9XG5cbiAgbWFya1VwZGF0ZUluRGV2VG9vbHMoZmliZXIsIGxhbmUpO1xufVxuXG5mdW5jdGlvbiBkaXNwYXRjaFNldFN0YXRlKGZpYmVyLCBxdWV1ZSwgYWN0aW9uKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIGFyZ3VtZW50c1szXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoXCJTdGF0ZSB1cGRhdGVzIGZyb20gdGhlIHVzZVN0YXRlKCkgYW5kIHVzZVJlZHVjZXIoKSBIb29rcyBkb24ndCBzdXBwb3J0IHRoZSBcIiArICdzZWNvbmQgY2FsbGJhY2sgYXJndW1lbnQuIFRvIGV4ZWN1dGUgYSBzaWRlIGVmZmVjdCBhZnRlciAnICsgJ3JlbmRlcmluZywgZGVjbGFyZSBpdCBpbiB0aGUgY29tcG9uZW50IGJvZHkgd2l0aCB1c2VFZmZlY3QoKS4nKTtcbiAgICB9XG4gIH1cblxuICB2YXIgbGFuZSA9IHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKTtcbiAgdmFyIHVwZGF0ZSA9IHtcbiAgICBsYW5lOiBsYW5lLFxuICAgIGFjdGlvbjogYWN0aW9uLFxuICAgIGhhc0VhZ2VyU3RhdGU6IGZhbHNlLFxuICAgIGVhZ2VyU3RhdGU6IG51bGwsXG4gICAgbmV4dDogbnVsbFxuICB9O1xuXG4gIGlmIChpc1JlbmRlclBoYXNlVXBkYXRlKGZpYmVyKSkge1xuICAgIGVucXVldWVSZW5kZXJQaGFzZVVwZGF0ZShxdWV1ZSwgdXBkYXRlKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKGZpYmVyLmxhbmVzID09PSBOb0xhbmVzICYmIChhbHRlcm5hdGUgPT09IG51bGwgfHwgYWx0ZXJuYXRlLmxhbmVzID09PSBOb0xhbmVzKSkge1xuICAgICAgLy8gVGhlIHF1ZXVlIGlzIGN1cnJlbnRseSBlbXB0eSwgd2hpY2ggbWVhbnMgd2UgY2FuIGVhZ2VybHkgY29tcHV0ZSB0aGVcbiAgICAgIC8vIG5leHQgc3RhdGUgYmVmb3JlIGVudGVyaW5nIHRoZSByZW5kZXIgcGhhc2UuIElmIHRoZSBuZXcgc3RhdGUgaXMgdGhlXG4gICAgICAvLyBzYW1lIGFzIHRoZSBjdXJyZW50IHN0YXRlLCB3ZSBtYXkgYmUgYWJsZSB0byBiYWlsIG91dCBlbnRpcmVseS5cbiAgICAgIHZhciBsYXN0UmVuZGVyZWRSZWR1Y2VyID0gcXVldWUubGFzdFJlbmRlcmVkUmVkdWNlcjtcblxuICAgICAgaWYgKGxhc3RSZW5kZXJlZFJlZHVjZXIgIT09IG51bGwpIHtcbiAgICAgICAgdmFyIHByZXZEaXNwYXRjaGVyO1xuXG4gICAgICAgIHtcbiAgICAgICAgICBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIHZhciBjdXJyZW50U3RhdGUgPSBxdWV1ZS5sYXN0UmVuZGVyZWRTdGF0ZTtcbiAgICAgICAgICB2YXIgZWFnZXJTdGF0ZSA9IGxhc3RSZW5kZXJlZFJlZHVjZXIoY3VycmVudFN0YXRlLCBhY3Rpb24pOyAvLyBTdGFzaCB0aGUgZWFnZXJseSBjb21wdXRlZCBzdGF0ZSwgYW5kIHRoZSByZWR1Y2VyIHVzZWQgdG8gY29tcHV0ZVxuICAgICAgICAgIC8vIGl0LCBvbiB0aGUgdXBkYXRlIG9iamVjdC4gSWYgdGhlIHJlZHVjZXIgaGFzbid0IGNoYW5nZWQgYnkgdGhlXG4gICAgICAgICAgLy8gdGltZSB3ZSBlbnRlciB0aGUgcmVuZGVyIHBoYXNlLCB0aGVuIHRoZSBlYWdlciBzdGF0ZSBjYW4gYmUgdXNlZFxuICAgICAgICAgIC8vIHdpdGhvdXQgY2FsbGluZyB0aGUgcmVkdWNlciBhZ2Fpbi5cblxuICAgICAgICAgIHVwZGF0ZS5oYXNFYWdlclN0YXRlID0gdHJ1ZTtcbiAgICAgICAgICB1cGRhdGUuZWFnZXJTdGF0ZSA9IGVhZ2VyU3RhdGU7XG5cbiAgICAgICAgICBpZiAob2JqZWN0SXMoZWFnZXJTdGF0ZSwgY3VycmVudFN0YXRlKSkge1xuICAgICAgICAgICAgLy8gRmFzdCBwYXRoLiBXZSBjYW4gYmFpbCBvdXQgd2l0aG91dCBzY2hlZHVsaW5nIFJlYWN0IHRvIHJlLXJlbmRlci5cbiAgICAgICAgICAgIC8vIEl0J3Mgc3RpbGwgcG9zc2libGUgdGhhdCB3ZSdsbCBuZWVkIHRvIHJlYmFzZSB0aGlzIHVwZGF0ZSBsYXRlcixcbiAgICAgICAgICAgIC8vIGlmIHRoZSBjb21wb25lbnQgcmUtcmVuZGVycyBmb3IgYSBkaWZmZXJlbnQgcmVhc29uIGFuZCBieSB0aGF0XG4gICAgICAgICAgICAvLyB0aW1lIHRoZSByZWR1Y2VyIGhhcyBjaGFuZ2VkLlxuICAgICAgICAgICAgLy8gVE9ETzogRG8gd2Ugc3RpbGwgbmVlZCB0byBlbnRhbmdsZSB0cmFuc2l0aW9ucyBpbiB0aGlzIGNhc2U/XG4gICAgICAgICAgICBlbnF1ZXVlQ29uY3VycmVudEhvb2tVcGRhdGVBbmRFYWdlcmx5QmFpbG91dChmaWJlciwgcXVldWUsIHVwZGF0ZSwgbGFuZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikgey8vIFN1cHByZXNzIHRoZSBlcnJvci4gSXQgd2lsbCB0aHJvdyBhZ2FpbiBpbiB0aGUgcmVuZGVyIHBoYXNlLlxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHJvb3QgPSBlbnF1ZXVlQ29uY3VycmVudEhvb2tVcGRhdGUoZmliZXIsIHF1ZXVlLCB1cGRhdGUsIGxhbmUpO1xuXG4gICAgaWYgKHJvb3QgIT09IG51bGwpIHtcbiAgICAgIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gICAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIGxhbmUsIGV2ZW50VGltZSk7XG4gICAgICBlbnRhbmdsZVRyYW5zaXRpb25VcGRhdGUocm9vdCwgcXVldWUsIGxhbmUpO1xuICAgIH1cbiAgfVxuXG4gIG1hcmtVcGRhdGVJbkRldlRvb2xzKGZpYmVyLCBsYW5lKTtcbn1cblxuZnVuY3Rpb24gaXNSZW5kZXJQaGFzZVVwZGF0ZShmaWJlcikge1xuICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuICByZXR1cm4gZmliZXIgPT09IGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEgfHwgYWx0ZXJuYXRlICE9PSBudWxsICYmIGFsdGVybmF0ZSA9PT0gY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMTtcbn1cblxuZnVuY3Rpb24gZW5xdWV1ZVJlbmRlclBoYXNlVXBkYXRlKHF1ZXVlLCB1cGRhdGUpIHtcbiAgLy8gVGhpcyBpcyBhIHJlbmRlciBwaGFzZSB1cGRhdGUuIFN0YXNoIGl0IGluIGEgbGF6aWx5LWNyZWF0ZWQgbWFwIG9mXG4gIC8vIHF1ZXVlIC0+IGxpbmtlZCBsaXN0IG9mIHVwZGF0ZXMuIEFmdGVyIHRoaXMgcmVuZGVyIHBhc3MsIHdlJ2xsIHJlc3RhcnRcbiAgLy8gYW5kIGFwcGx5IHRoZSBzdGFzaGVkIHVwZGF0ZXMgb24gdG9wIG9mIHRoZSB3b3JrLWluLXByb2dyZXNzIGhvb2suXG4gIGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGVEdXJpbmdUaGlzUGFzcyA9IGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGUgPSB0cnVlO1xuICB2YXIgcGVuZGluZyA9IHF1ZXVlLnBlbmRpbmc7XG5cbiAgaWYgKHBlbmRpbmcgPT09IG51bGwpIHtcbiAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCB1cGRhdGUuIENyZWF0ZSBhIGNpcmN1bGFyIGxpc3QuXG4gICAgdXBkYXRlLm5leHQgPSB1cGRhdGU7XG4gIH0gZWxzZSB7XG4gICAgdXBkYXRlLm5leHQgPSBwZW5kaW5nLm5leHQ7XG4gICAgcGVuZGluZy5uZXh0ID0gdXBkYXRlO1xuICB9XG5cbiAgcXVldWUucGVuZGluZyA9IHVwZGF0ZTtcbn0gLy8gVE9ETzogTW92ZSB0byBSZWFjdEZpYmVyQ29uY3VycmVudFVwZGF0ZXM/XG5cblxuZnVuY3Rpb24gZW50YW5nbGVUcmFuc2l0aW9uVXBkYXRlKHJvb3QsIHF1ZXVlLCBsYW5lKSB7XG4gIGlmIChpc1RyYW5zaXRpb25MYW5lKGxhbmUpKSB7XG4gICAgdmFyIHF1ZXVlTGFuZXMgPSBxdWV1ZS5sYW5lczsgLy8gSWYgYW55IGVudGFuZ2xlZCBsYW5lcyBhcmUgbm8gbG9uZ2VyIHBlbmRpbmcgb24gdGhlIHJvb3QsIHRoZW4gdGhleVxuICAgIC8vIG11c3QgaGF2ZSBmaW5pc2hlZC4gV2UgY2FuIHJlbW92ZSB0aGVtIGZyb20gdGhlIHNoYXJlZCBxdWV1ZSwgd2hpY2hcbiAgICAvLyByZXByZXNlbnRzIGEgc3VwZXJzZXQgb2YgdGhlIGFjdHVhbGx5IHBlbmRpbmcgbGFuZXMuIEluIHNvbWUgY2FzZXMgd2VcbiAgICAvLyBtYXkgZW50YW5nbGUgbW9yZSB0aGFuIHdlIG5lZWQgdG8sIGJ1dCB0aGF0J3MgT0suIEluIGZhY3QgaXQncyB3b3JzZSBpZlxuICAgIC8vIHdlICpkb24ndCogZW50YW5nbGUgd2hlbiB3ZSBzaG91bGQuXG5cbiAgICBxdWV1ZUxhbmVzID0gaW50ZXJzZWN0TGFuZXMocXVldWVMYW5lcywgcm9vdC5wZW5kaW5nTGFuZXMpOyAvLyBFbnRhbmdsZSB0aGUgbmV3IHRyYW5zaXRpb24gbGFuZSB3aXRoIHRoZSBvdGhlciB0cmFuc2l0aW9uIGxhbmVzLlxuXG4gICAgdmFyIG5ld1F1ZXVlTGFuZXMgPSBtZXJnZUxhbmVzKHF1ZXVlTGFuZXMsIGxhbmUpO1xuICAgIHF1ZXVlLmxhbmVzID0gbmV3UXVldWVMYW5lczsgLy8gRXZlbiBpZiBxdWV1ZS5sYW5lcyBhbHJlYWR5IGluY2x1ZGUgbGFuZSwgd2UgZG9uJ3Qga25vdyBmb3IgY2VydGFpbiBpZlxuICAgIC8vIHRoZSBsYW5lIGZpbmlzaGVkIHNpbmNlIHRoZSBsYXN0IHRpbWUgd2UgZW50YW5nbGVkIGl0LiBTbyB3ZSBuZWVkIHRvXG4gICAgLy8gZW50YW5nbGUgaXQgYWdhaW4sIGp1c3QgdG8gYmUgc3VyZS5cblxuICAgIG1hcmtSb290RW50YW5nbGVkKHJvb3QsIG5ld1F1ZXVlTGFuZXMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1hcmtVcGRhdGVJbkRldlRvb2xzKGZpYmVyLCBsYW5lLCBhY3Rpb24pIHtcblxuICB7XG4gICAgbWFya1N0YXRlVXBkYXRlU2NoZWR1bGVkKGZpYmVyLCBsYW5lKTtcbiAgfVxufVxuXG52YXIgQ29udGV4dE9ubHlEaXNwYXRjaGVyID0ge1xuICByZWFkQ29udGV4dDogcmVhZENvbnRleHQsXG4gIHVzZUNhbGxiYWNrOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZUNvbnRleHQ6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlRWZmZWN0OiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZUltcGVyYXRpdmVIYW5kbGU6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlSW5zZXJ0aW9uRWZmZWN0OiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZUxheW91dEVmZmVjdDogdGhyb3dJbnZhbGlkSG9va0Vycm9yLFxuICB1c2VNZW1vOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZVJlZHVjZXI6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlUmVmOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZVN0YXRlOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZURlYnVnVmFsdWU6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlRGVmZXJyZWRWYWx1ZTogdGhyb3dJbnZhbGlkSG9va0Vycm9yLFxuICB1c2VUcmFuc2l0aW9uOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZU11dGFibGVTb3VyY2U6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlU3luY0V4dGVybmFsU3RvcmU6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlSWQ6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiBlbmFibGVOZXdSZWNvbmNpbGVyXG59O1xuXG52YXIgSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWID0gbnVsbDtcbnZhciBIb29rc0Rpc3BhdGNoZXJPbk1vdW50V2l0aEhvb2tUeXBlc0luREVWID0gbnVsbDtcbnZhciBIb29rc0Rpc3BhdGNoZXJPblVwZGF0ZUluREVWID0gbnVsbDtcbnZhciBIb29rc0Rpc3BhdGNoZXJPblJlcmVuZGVySW5ERVYgPSBudWxsO1xudmFyIEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPbk1vdW50SW5ERVYgPSBudWxsO1xudmFyIEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPblVwZGF0ZUluREVWID0gbnVsbDtcbnZhciBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25SZXJlbmRlckluREVWID0gbnVsbDtcblxue1xuICB2YXIgd2FybkludmFsaWRDb250ZXh0QWNjZXNzID0gZnVuY3Rpb24gKCkge1xuICAgIGVycm9yKCdDb250ZXh0IGNhbiBvbmx5IGJlIHJlYWQgd2hpbGUgUmVhY3QgaXMgcmVuZGVyaW5nLiAnICsgJ0luIGNsYXNzZXMsIHlvdSBjYW4gcmVhZCBpdCBpbiB0aGUgcmVuZGVyIG1ldGhvZCBvciBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMuICcgKyAnSW4gZnVuY3Rpb24gY29tcG9uZW50cywgeW91IGNhbiByZWFkIGl0IGRpcmVjdGx5IGluIHRoZSBmdW5jdGlvbiBib2R5LCBidXQgbm90ICcgKyAnaW5zaWRlIEhvb2tzIGxpa2UgdXNlUmVkdWNlcigpIG9yIHVzZU1lbW8oKS4nKTtcbiAgfTtcblxuICB2YXIgd2FybkludmFsaWRIb29rQWNjZXNzID0gZnVuY3Rpb24gKCkge1xuICAgIGVycm9yKCdEbyBub3QgY2FsbCBIb29rcyBpbnNpZGUgdXNlRWZmZWN0KC4uLiksIHVzZU1lbW8oLi4uKSwgb3Igb3RoZXIgYnVpbHQtaW4gSG9va3MuICcgKyAnWW91IGNhbiBvbmx5IGNhbGwgSG9va3MgYXQgdGhlIHRvcCBsZXZlbCBvZiB5b3VyIFJlYWN0IGZ1bmN0aW9uLiAnICsgJ0ZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvcnVsZXMtb2YtaG9va3MnKTtcbiAgfTtcblxuICBIb29rc0Rpc3BhdGNoZXJPbk1vdW50SW5ERVYgPSB7XG4gICAgcmVhZENvbnRleHQ6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVhZENvbnRleHQoY29udGV4dCk7XG4gICAgfSxcbiAgICB1c2VDYWxsYmFjazogZnVuY3Rpb24gKGNhbGxiYWNrLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VDYWxsYmFjayc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgY2hlY2tEZXBzQXJlQXJyYXlEZXYoZGVwcyk7XG4gICAgICByZXR1cm4gbW91bnRDYWxsYmFjayhjYWxsYmFjaywgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ29udGV4dCc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VFZmZlY3QnO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIGNoZWNrRGVwc0FyZUFycmF5RGV2KGRlcHMpO1xuICAgICAgcmV0dXJuIG1vdW50RWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbXBlcmF0aXZlSGFuZGxlOiBmdW5jdGlvbiAocmVmLCBjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUltcGVyYXRpdmVIYW5kbGUnO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIGNoZWNrRGVwc0FyZUFycmF5RGV2KGRlcHMpO1xuICAgICAgcmV0dXJuIG1vdW50SW1wZXJhdGl2ZUhhbmRsZShyZWYsIGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbnNlcnRpb25FZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUluc2VydGlvbkVmZmVjdCc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgY2hlY2tEZXBzQXJlQXJyYXlEZXYoZGVwcyk7XG4gICAgICByZXR1cm4gbW91bnRJbnNlcnRpb25FZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUxheW91dEVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTGF5b3V0RWZmZWN0JztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICBjaGVja0RlcHNBcmVBcnJheURldihkZXBzKTtcbiAgICAgIHJldHVybiBtb3VudExheW91dEVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlTWVtbzogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTWVtbyc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgY2hlY2tEZXBzQXJlQXJyYXlEZXYoZGVwcyk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uTW91bnRJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG1vdW50TWVtbyhjcmVhdGUsIGRlcHMpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZVJlZHVjZXI6IGZ1bmN0aW9uIChyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWR1Y2VyJztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uTW91bnRJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG1vdW50UmVkdWNlcihyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VSZWY6IGZ1bmN0aW9uIChpbml0aWFsVmFsdWUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVJlZic7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50UmVmKGluaXRpYWxWYWx1ZSk7XG4gICAgfSxcbiAgICB1c2VTdGF0ZTogZnVuY3Rpb24gKGluaXRpYWxTdGF0ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3RhdGUnO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbW91bnRTdGF0ZShpbml0aWFsU3RhdGUpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZURlYnVnVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSwgZm9ybWF0dGVyRm4pIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlYnVnVmFsdWUnO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudERlYnVnVmFsdWUoKTtcbiAgICB9LFxuICAgIHVzZURlZmVycmVkVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRGVmZXJyZWRWYWx1ZSc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50RGVmZXJyZWRWYWx1ZSh2YWx1ZSk7XG4gICAgfSxcbiAgICB1c2VUcmFuc2l0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VUcmFuc2l0aW9uJztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRUcmFuc2l0aW9uKCk7XG4gICAgfSxcbiAgICB1c2VNdXRhYmxlU291cmNlOiBmdW5jdGlvbiAoc291cmNlLCBnZXRTbmFwc2hvdCwgc3Vic2NyaWJlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNdXRhYmxlU291cmNlJztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRNdXRhYmxlU291cmNlKCk7XG4gICAgfSxcbiAgICB1c2VTeW5jRXh0ZXJuYWxTdG9yZTogZnVuY3Rpb24gKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VTeW5jRXh0ZXJuYWxTdG9yZSc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50U3luY0V4dGVybmFsU3RvcmUoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpO1xuICAgIH0sXG4gICAgdXNlSWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUlkJztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRJZCgpO1xuICAgIH0sXG4gICAgdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiBlbmFibGVOZXdSZWNvbmNpbGVyXG4gIH07XG5cbiAgSG9va3NEaXNwYXRjaGVyT25Nb3VudFdpdGhIb29rVHlwZXNJbkRFViA9IHtcbiAgICByZWFkQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIHJldHVybiByZWFkQ29udGV4dChjb250ZXh0KTtcbiAgICB9LFxuICAgIHVzZUNhbGxiYWNrOiBmdW5jdGlvbiAoY2FsbGJhY2ssIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUNhbGxiYWNrJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50Q2FsbGJhY2soY2FsbGJhY2ssIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUNvbnRleHQnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gcmVhZENvbnRleHQoY29udGV4dCk7XG4gICAgfSxcbiAgICB1c2VFZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUVmZmVjdCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudEVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW1wZXJhdGl2ZUhhbmRsZTogZnVuY3Rpb24gKHJlZiwgY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbXBlcmF0aXZlSGFuZGxlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50SW1wZXJhdGl2ZUhhbmRsZShyZWYsIGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbnNlcnRpb25FZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUluc2VydGlvbkVmZmVjdCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudEluc2VydGlvbkVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlTGF5b3V0RWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VMYXlvdXRFZmZlY3QnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRMYXlvdXRFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZU1lbW86IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZU1lbW8nO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uTW91bnRJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG1vdW50TWVtbyhjcmVhdGUsIGRlcHMpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZVJlZHVjZXI6IGZ1bmN0aW9uIChyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWR1Y2VyJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPbk1vdW50SW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBtb3VudFJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVmOiBmdW5jdGlvbiAoaW5pdGlhbFZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWYnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRSZWYoaW5pdGlhbFZhbHVlKTtcbiAgICB9LFxuICAgIHVzZVN0YXRlOiBmdW5jdGlvbiAoaW5pdGlhbFN0YXRlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VTdGF0ZSc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbW91bnRTdGF0ZShpbml0aWFsU3RhdGUpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZURlYnVnVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSwgZm9ybWF0dGVyRm4pIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlYnVnVmFsdWUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnREZWJ1Z1ZhbHVlKCk7XG4gICAgfSxcbiAgICB1c2VEZWZlcnJlZFZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlZmVycmVkVmFsdWUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnREZWZlcnJlZFZhbHVlKHZhbHVlKTtcbiAgICB9LFxuICAgIHVzZVRyYW5zaXRpb246IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVRyYW5zaXRpb24nO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRUcmFuc2l0aW9uKCk7XG4gICAgfSxcbiAgICB1c2VNdXRhYmxlU291cmNlOiBmdW5jdGlvbiAoc291cmNlLCBnZXRTbmFwc2hvdCwgc3Vic2NyaWJlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNdXRhYmxlU291cmNlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50TXV0YWJsZVNvdXJjZSgpO1xuICAgIH0sXG4gICAgdXNlU3luY0V4dGVybmFsU3RvcmU6IGZ1bmN0aW9uIChzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBnZXRTZXJ2ZXJTbmFwc2hvdCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3luY0V4dGVybmFsU3RvcmUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRTeW5jRXh0ZXJuYWxTdG9yZShzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBnZXRTZXJ2ZXJTbmFwc2hvdCk7XG4gICAgfSxcbiAgICB1c2VJZDogZnVuY3Rpb24gKCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSWQnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRJZCgpO1xuICAgIH0sXG4gICAgdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiBlbmFibGVOZXdSZWNvbmNpbGVyXG4gIH07XG5cbiAgSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFViA9IHtcbiAgICByZWFkQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIHJldHVybiByZWFkQ29udGV4dChjb250ZXh0KTtcbiAgICB9LFxuICAgIHVzZUNhbGxiYWNrOiBmdW5jdGlvbiAoY2FsbGJhY2ssIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUNhbGxiYWNrJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUNhbGxiYWNrKGNhbGxiYWNrLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUNvbnRleHQ6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VDb250ZXh0JztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VFZmZlY3QnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbXBlcmF0aXZlSGFuZGxlOiBmdW5jdGlvbiAocmVmLCBjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUltcGVyYXRpdmVIYW5kbGUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlSW1wZXJhdGl2ZUhhbmRsZShyZWYsIGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbnNlcnRpb25FZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUluc2VydGlvbkVmZmVjdCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJbnNlcnRpb25FZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUxheW91dEVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTGF5b3V0RWZmZWN0JztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUxheW91dEVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlTWVtbzogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTWVtbyc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZU1lbW8oY3JlYXRlLCBkZXBzKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VSZWR1Y2VyOiBmdW5jdGlvbiAocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlUmVkdWNlcic7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZVJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVmOiBmdW5jdGlvbiAoaW5pdGlhbFZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWYnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlUmVmKCk7XG4gICAgfSxcbiAgICB1c2VTdGF0ZTogZnVuY3Rpb24gKGluaXRpYWxTdGF0ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3RhdGUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB1cGRhdGVTdGF0ZShpbml0aWFsU3RhdGUpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZURlYnVnVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSwgZm9ybWF0dGVyRm4pIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlYnVnVmFsdWUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlRGVidWdWYWx1ZSgpO1xuICAgIH0sXG4gICAgdXNlRGVmZXJyZWRWYWx1ZTogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VEZWZlcnJlZFZhbHVlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZURlZmVycmVkVmFsdWUodmFsdWUpO1xuICAgIH0sXG4gICAgdXNlVHJhbnNpdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlVHJhbnNpdGlvbic7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVUcmFuc2l0aW9uKCk7XG4gICAgfSxcbiAgICB1c2VNdXRhYmxlU291cmNlOiBmdW5jdGlvbiAoc291cmNlLCBnZXRTbmFwc2hvdCwgc3Vic2NyaWJlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNdXRhYmxlU291cmNlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZU11dGFibGVTb3VyY2UoKTtcbiAgICB9LFxuICAgIHVzZVN5bmNFeHRlcm5hbFN0b3JlOiBmdW5jdGlvbiAoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN5bmNFeHRlcm5hbFN0b3JlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZVN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QpO1xuICAgIH0sXG4gICAgdXNlSWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUlkJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUlkKCk7XG4gICAgfSxcbiAgICB1bnN0YWJsZV9pc05ld1JlY29uY2lsZXI6IGVuYWJsZU5ld1JlY29uY2lsZXJcbiAgfTtcblxuICBIb29rc0Rpc3BhdGNoZXJPblJlcmVuZGVySW5ERVYgPSB7XG4gICAgcmVhZENvbnRleHQ6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVhZENvbnRleHQoY29udGV4dCk7XG4gICAgfSxcbiAgICB1c2VDYWxsYmFjazogZnVuY3Rpb24gKGNhbGxiYWNrLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VDYWxsYmFjayc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVDYWxsYmFjayhjYWxsYmFjaywgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ29udGV4dCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiByZWFkQ29udGV4dChjb250ZXh0KTtcbiAgICB9LFxuICAgIHVzZUVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRWZmZWN0JztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW1wZXJhdGl2ZUhhbmRsZTogZnVuY3Rpb24gKHJlZiwgY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbXBlcmF0aXZlSGFuZGxlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUltcGVyYXRpdmVIYW5kbGUocmVmLCBjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW5zZXJ0aW9uRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbnNlcnRpb25FZmZlY3QnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlSW5zZXJ0aW9uRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VMYXlvdXRFZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUxheW91dEVmZmVjdCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVMYXlvdXRFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZU1lbW86IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZU1lbW8nO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uUmVyZW5kZXJJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZU1lbW8oY3JlYXRlLCBkZXBzKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VSZWR1Y2VyOiBmdW5jdGlvbiAocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlUmVkdWNlcic7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25SZXJlbmRlckluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gcmVyZW5kZXJSZWR1Y2VyKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZVJlZjogZnVuY3Rpb24gKGluaXRpYWxWYWx1ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlUmVmJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZVJlZigpO1xuICAgIH0sXG4gICAgdXNlU3RhdGU6IGZ1bmN0aW9uIChpbml0aWFsU3RhdGUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN0YXRlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPblJlcmVuZGVySW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiByZXJlbmRlclN0YXRlKGluaXRpYWxTdGF0ZSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlRGVidWdWYWx1ZTogZnVuY3Rpb24gKHZhbHVlLCBmb3JtYXR0ZXJGbikge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRGVidWdWYWx1ZSc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVEZWJ1Z1ZhbHVlKCk7XG4gICAgfSxcbiAgICB1c2VEZWZlcnJlZFZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlZmVycmVkVmFsdWUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gcmVyZW5kZXJEZWZlcnJlZFZhbHVlKHZhbHVlKTtcbiAgICB9LFxuICAgIHVzZVRyYW5zaXRpb246IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVRyYW5zaXRpb24nO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gcmVyZW5kZXJUcmFuc2l0aW9uKCk7XG4gICAgfSxcbiAgICB1c2VNdXRhYmxlU291cmNlOiBmdW5jdGlvbiAoc291cmNlLCBnZXRTbmFwc2hvdCwgc3Vic2NyaWJlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNdXRhYmxlU291cmNlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZU11dGFibGVTb3VyY2UoKTtcbiAgICB9LFxuICAgIHVzZVN5bmNFeHRlcm5hbFN0b3JlOiBmdW5jdGlvbiAoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN5bmNFeHRlcm5hbFN0b3JlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZVN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QpO1xuICAgIH0sXG4gICAgdXNlSWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUlkJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUlkKCk7XG4gICAgfSxcbiAgICB1bnN0YWJsZV9pc05ld1JlY29uY2lsZXI6IGVuYWJsZU5ld1JlY29uY2lsZXJcbiAgfTtcblxuICBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWID0ge1xuICAgIHJlYWRDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgd2FybkludmFsaWRDb250ZXh0QWNjZXNzKCk7XG4gICAgICByZXR1cm4gcmVhZENvbnRleHQoY29udGV4dCk7XG4gICAgfSxcbiAgICB1c2VDYWxsYmFjazogZnVuY3Rpb24gKGNhbGxiYWNrLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VDYWxsYmFjayc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRDYWxsYmFjayhjYWxsYmFjaywgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ29udGV4dCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gcmVhZENvbnRleHQoY29udGV4dCk7XG4gICAgfSxcbiAgICB1c2VFZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUVmZmVjdCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUltcGVyYXRpdmVIYW5kbGU6IGZ1bmN0aW9uIChyZWYsIGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSW1wZXJhdGl2ZUhhbmRsZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRJbXBlcmF0aXZlSGFuZGxlKHJlZiwgY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUluc2VydGlvbkVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSW5zZXJ0aW9uRWZmZWN0JztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudEluc2VydGlvbkVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlTGF5b3V0RWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VMYXlvdXRFZmZlY3QnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50TGF5b3V0RWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VNZW1vOiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNZW1vJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbW91bnRNZW1vKGNyZWF0ZSwgZGVwcyk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVkdWNlcjogZnVuY3Rpb24gKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVJlZHVjZXInO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPbk1vdW50SW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBtb3VudFJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVmOiBmdW5jdGlvbiAoaW5pdGlhbFZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWYnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50UmVmKGluaXRpYWxWYWx1ZSk7XG4gICAgfSxcbiAgICB1c2VTdGF0ZTogZnVuY3Rpb24gKGluaXRpYWxTdGF0ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3RhdGUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPbk1vdW50SW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBtb3VudFN0YXRlKGluaXRpYWxTdGF0ZSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlRGVidWdWYWx1ZTogZnVuY3Rpb24gKHZhbHVlLCBmb3JtYXR0ZXJGbikge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRGVidWdWYWx1ZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnREZWJ1Z1ZhbHVlKCk7XG4gICAgfSxcbiAgICB1c2VEZWZlcnJlZFZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlZmVycmVkVmFsdWUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50RGVmZXJyZWRWYWx1ZSh2YWx1ZSk7XG4gICAgfSxcbiAgICB1c2VUcmFuc2l0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VUcmFuc2l0aW9uJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudFRyYW5zaXRpb24oKTtcbiAgICB9LFxuICAgIHVzZU11dGFibGVTb3VyY2U6IGZ1bmN0aW9uIChzb3VyY2UsIGdldFNuYXBzaG90LCBzdWJzY3JpYmUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZU11dGFibGVTb3VyY2UnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50TXV0YWJsZVNvdXJjZSgpO1xuICAgIH0sXG4gICAgdXNlU3luY0V4dGVybmFsU3RvcmU6IGZ1bmN0aW9uIChzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBnZXRTZXJ2ZXJTbmFwc2hvdCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3luY0V4dGVybmFsU3RvcmUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50U3luY0V4dGVybmFsU3RvcmUoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpO1xuICAgIH0sXG4gICAgdXNlSWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUlkJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudElkKCk7XG4gICAgfSxcbiAgICB1bnN0YWJsZV9pc05ld1JlY29uY2lsZXI6IGVuYWJsZU5ld1JlY29uY2lsZXJcbiAgfTtcblxuICBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFViA9IHtcbiAgICByZWFkQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIHdhcm5JbnZhbGlkQ29udGV4dEFjY2VzcygpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlQ2FsbGJhY2s6IGZ1bmN0aW9uIChjYWxsYmFjaywgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ2FsbGJhY2snO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVDYWxsYmFjayhjYWxsYmFjaywgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ29udGV4dCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VFZmZlY3QnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUltcGVyYXRpdmVIYW5kbGU6IGZ1bmN0aW9uIChyZWYsIGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSW1wZXJhdGl2ZUhhbmRsZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUltcGVyYXRpdmVIYW5kbGUocmVmLCBjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW5zZXJ0aW9uRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbnNlcnRpb25FZmZlY3QnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJbnNlcnRpb25FZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUxheW91dEVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTGF5b3V0RWZmZWN0JztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlTGF5b3V0RWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VNZW1vOiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNZW1vJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB1cGRhdGVNZW1vKGNyZWF0ZSwgZGVwcyk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVkdWNlcjogZnVuY3Rpb24gKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVJlZHVjZXInO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZVJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVmOiBmdW5jdGlvbiAoaW5pdGlhbFZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWYnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVSZWYoKTtcbiAgICB9LFxuICAgIHVzZVN0YXRlOiBmdW5jdGlvbiAoaW5pdGlhbFN0YXRlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VTdGF0ZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPblVwZGF0ZUluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gdXBkYXRlU3RhdGUoaW5pdGlhbFN0YXRlKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VEZWJ1Z1ZhbHVlOiBmdW5jdGlvbiAodmFsdWUsIGZvcm1hdHRlckZuKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VEZWJ1Z1ZhbHVlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlRGVidWdWYWx1ZSgpO1xuICAgIH0sXG4gICAgdXNlRGVmZXJyZWRWYWx1ZTogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VEZWZlcnJlZFZhbHVlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlRGVmZXJyZWRWYWx1ZSh2YWx1ZSk7XG4gICAgfSxcbiAgICB1c2VUcmFuc2l0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VUcmFuc2l0aW9uJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlVHJhbnNpdGlvbigpO1xuICAgIH0sXG4gICAgdXNlTXV0YWJsZVNvdXJjZTogZnVuY3Rpb24gKHNvdXJjZSwgZ2V0U25hcHNob3QsIHN1YnNjcmliZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTXV0YWJsZVNvdXJjZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZU11dGFibGVTb3VyY2UoKTtcbiAgICB9LFxuICAgIHVzZVN5bmNFeHRlcm5hbFN0b3JlOiBmdW5jdGlvbiAoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN5bmNFeHRlcm5hbFN0b3JlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlU3luY0V4dGVybmFsU3RvcmUoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCk7XG4gICAgfSxcbiAgICB1c2VJZDogZnVuY3Rpb24gKCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSWQnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJZCgpO1xuICAgIH0sXG4gICAgdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiBlbmFibGVOZXdSZWNvbmNpbGVyXG4gIH07XG5cbiAgSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uUmVyZW5kZXJJbkRFViA9IHtcbiAgICByZWFkQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIHdhcm5JbnZhbGlkQ29udGV4dEFjY2VzcygpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlQ2FsbGJhY2s6IGZ1bmN0aW9uIChjYWxsYmFjaywgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ2FsbGJhY2snO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVDYWxsYmFjayhjYWxsYmFjaywgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ29udGV4dCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VFZmZlY3QnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUltcGVyYXRpdmVIYW5kbGU6IGZ1bmN0aW9uIChyZWYsIGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSW1wZXJhdGl2ZUhhbmRsZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUltcGVyYXRpdmVIYW5kbGUocmVmLCBjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW5zZXJ0aW9uRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbnNlcnRpb25FZmZlY3QnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJbnNlcnRpb25FZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUxheW91dEVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTGF5b3V0RWZmZWN0JztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlTGF5b3V0RWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VNZW1vOiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNZW1vJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB1cGRhdGVNZW1vKGNyZWF0ZSwgZGVwcyk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVkdWNlcjogZnVuY3Rpb24gKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVJlZHVjZXInO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHJlcmVuZGVyUmVkdWNlcihyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VSZWY6IGZ1bmN0aW9uIChpbml0aWFsVmFsdWUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVJlZic7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZVJlZigpO1xuICAgIH0sXG4gICAgdXNlU3RhdGU6IGZ1bmN0aW9uIChpbml0aWFsU3RhdGUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN0YXRlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiByZXJlbmRlclN0YXRlKGluaXRpYWxTdGF0ZSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlRGVidWdWYWx1ZTogZnVuY3Rpb24gKHZhbHVlLCBmb3JtYXR0ZXJGbikge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRGVidWdWYWx1ZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZURlYnVnVmFsdWUoKTtcbiAgICB9LFxuICAgIHVzZURlZmVycmVkVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRGVmZXJyZWRWYWx1ZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlcmVuZGVyRGVmZXJyZWRWYWx1ZSh2YWx1ZSk7XG4gICAgfSxcbiAgICB1c2VUcmFuc2l0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VUcmFuc2l0aW9uJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gcmVyZW5kZXJUcmFuc2l0aW9uKCk7XG4gICAgfSxcbiAgICB1c2VNdXRhYmxlU291cmNlOiBmdW5jdGlvbiAoc291cmNlLCBnZXRTbmFwc2hvdCwgc3Vic2NyaWJlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNdXRhYmxlU291cmNlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlTXV0YWJsZVNvdXJjZSgpO1xuICAgIH0sXG4gICAgdXNlU3luY0V4dGVybmFsU3RvcmU6IGZ1bmN0aW9uIChzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBnZXRTZXJ2ZXJTbmFwc2hvdCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3luY0V4dGVybmFsU3RvcmUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVTeW5jRXh0ZXJuYWxTdG9yZShzdWJzY3JpYmUsIGdldFNuYXBzaG90KTtcbiAgICB9LFxuICAgIHVzZUlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJZCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUlkKCk7XG4gICAgfSxcbiAgICB1bnN0YWJsZV9pc05ld1JlY29uY2lsZXI6IGVuYWJsZU5ld1JlY29uY2lsZXJcbiAgfTtcbn1cblxudmFyIG5vdyQxID0gU2NoZWR1bGVyLnVuc3RhYmxlX25vdztcbnZhciBjb21taXRUaW1lID0gMDtcbnZhciBsYXlvdXRFZmZlY3RTdGFydFRpbWUgPSAtMTtcbnZhciBwcm9maWxlclN0YXJ0VGltZSA9IC0xO1xudmFyIHBhc3NpdmVFZmZlY3RTdGFydFRpbWUgPSAtMTtcbi8qKlxuICogVHJhY2tzIHdoZXRoZXIgdGhlIGN1cnJlbnQgdXBkYXRlIHdhcyBhIG5lc3RlZC9jYXNjYWRpbmcgdXBkYXRlIChzY2hlZHVsZWQgZnJvbSBhIGxheW91dCBlZmZlY3QpLlxuICpcbiAqIFRoZSBvdmVyYWxsIHNlcXVlbmNlIGlzOlxuICogICAxLiByZW5kZXJcbiAqICAgMi4gY29tbWl0IChhbmQgY2FsbCBgb25SZW5kZXJgLCBgb25Db21taXRgKVxuICogICAzLiBjaGVjayBmb3IgbmVzdGVkIHVwZGF0ZXNcbiAqICAgNC4gZmx1c2ggcGFzc2l2ZSBlZmZlY3RzIChhbmQgY2FsbCBgb25Qb3N0Q29tbWl0YClcbiAqXG4gKiBOZXN0ZWQgdXBkYXRlcyBhcmUgaWRlbnRpZmllZCBpbiBzdGVwIDMgYWJvdmUsXG4gKiBidXQgc3RlcCA0IHN0aWxsIGFwcGxpZXMgdG8gdGhlIHdvcmsgdGhhdCB3YXMganVzdCBjb21taXR0ZWQuXG4gKiBXZSB1c2UgdHdvIGZsYWdzIHRvIHRyYWNrIG5lc3RlZCB1cGRhdGVzIHRoZW46XG4gKiBvbmUgdHJhY2tzIHdoZXRoZXIgdGhlIHVwY29taW5nIHVwZGF0ZSBpcyBhIG5lc3RlZCB1cGRhdGUsXG4gKiBhbmQgdGhlIG90aGVyIHRyYWNrcyB3aGV0aGVyIHRoZSBjdXJyZW50IHVwZGF0ZSB3YXMgYSBuZXN0ZWQgdXBkYXRlLlxuICogVGhlIGZpcnN0IHZhbHVlIGdldHMgc3luY2VkIHRvIHRoZSBzZWNvbmQgYXQgdGhlIHN0YXJ0IG9mIHRoZSByZW5kZXIgcGhhc2UuXG4gKi9cblxudmFyIGN1cnJlbnRVcGRhdGVJc05lc3RlZCA9IGZhbHNlO1xudmFyIG5lc3RlZFVwZGF0ZVNjaGVkdWxlZCA9IGZhbHNlO1xuXG5mdW5jdGlvbiBpc0N1cnJlbnRVcGRhdGVOZXN0ZWQoKSB7XG4gIHJldHVybiBjdXJyZW50VXBkYXRlSXNOZXN0ZWQ7XG59XG5cbmZ1bmN0aW9uIG1hcmtOZXN0ZWRVcGRhdGVTY2hlZHVsZWQoKSB7XG4gIHtcbiAgICBuZXN0ZWRVcGRhdGVTY2hlZHVsZWQgPSB0cnVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc2V0TmVzdGVkVXBkYXRlRmxhZygpIHtcbiAge1xuICAgIGN1cnJlbnRVcGRhdGVJc05lc3RlZCA9IGZhbHNlO1xuICAgIG5lc3RlZFVwZGF0ZVNjaGVkdWxlZCA9IGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN5bmNOZXN0ZWRVcGRhdGVGbGFnKCkge1xuICB7XG4gICAgY3VycmVudFVwZGF0ZUlzTmVzdGVkID0gbmVzdGVkVXBkYXRlU2NoZWR1bGVkO1xuICAgIG5lc3RlZFVwZGF0ZVNjaGVkdWxlZCA9IGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldENvbW1pdFRpbWUoKSB7XG4gIHJldHVybiBjb21taXRUaW1lO1xufVxuXG5mdW5jdGlvbiByZWNvcmRDb21taXRUaW1lKCkge1xuXG4gIGNvbW1pdFRpbWUgPSBub3ckMSgpO1xufVxuXG5mdW5jdGlvbiBzdGFydFByb2ZpbGVyVGltZXIoZmliZXIpIHtcblxuICBwcm9maWxlclN0YXJ0VGltZSA9IG5vdyQxKCk7XG5cbiAgaWYgKGZpYmVyLmFjdHVhbFN0YXJ0VGltZSA8IDApIHtcbiAgICBmaWJlci5hY3R1YWxTdGFydFRpbWUgPSBub3ckMSgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN0b3BQcm9maWxlclRpbWVySWZSdW5uaW5nKGZpYmVyKSB7XG5cbiAgcHJvZmlsZXJTdGFydFRpbWUgPSAtMTtcbn1cblxuZnVuY3Rpb24gc3RvcFByb2ZpbGVyVGltZXJJZlJ1bm5pbmdBbmRSZWNvcmREZWx0YShmaWJlciwgb3ZlcnJpZGVCYXNlVGltZSkge1xuXG4gIGlmIChwcm9maWxlclN0YXJ0VGltZSA+PSAwKSB7XG4gICAgdmFyIGVsYXBzZWRUaW1lID0gbm93JDEoKSAtIHByb2ZpbGVyU3RhcnRUaW1lO1xuICAgIGZpYmVyLmFjdHVhbER1cmF0aW9uICs9IGVsYXBzZWRUaW1lO1xuXG4gICAgaWYgKG92ZXJyaWRlQmFzZVRpbWUpIHtcbiAgICAgIGZpYmVyLnNlbGZCYXNlRHVyYXRpb24gPSBlbGFwc2VkVGltZTtcbiAgICB9XG5cbiAgICBwcm9maWxlclN0YXJ0VGltZSA9IC0xO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlY29yZExheW91dEVmZmVjdER1cmF0aW9uKGZpYmVyKSB7XG5cbiAgaWYgKGxheW91dEVmZmVjdFN0YXJ0VGltZSA+PSAwKSB7XG4gICAgdmFyIGVsYXBzZWRUaW1lID0gbm93JDEoKSAtIGxheW91dEVmZmVjdFN0YXJ0VGltZTtcbiAgICBsYXlvdXRFZmZlY3RTdGFydFRpbWUgPSAtMTsgLy8gU3RvcmUgZHVyYXRpb24gb24gdGhlIG5leHQgbmVhcmVzdCBQcm9maWxlciBhbmNlc3RvclxuICAgIC8vIE9yIHRoZSByb290IChmb3IgdGhlIERldlRvb2xzIFByb2ZpbGVyIHRvIHJlYWQpXG5cbiAgICB2YXIgcGFyZW50RmliZXIgPSBmaWJlci5yZXR1cm47XG5cbiAgICB3aGlsZSAocGFyZW50RmliZXIgIT09IG51bGwpIHtcbiAgICAgIHN3aXRjaCAocGFyZW50RmliZXIudGFnKSB7XG4gICAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgICAgdmFyIHJvb3QgPSBwYXJlbnRGaWJlci5zdGF0ZU5vZGU7XG4gICAgICAgICAgcm9vdC5lZmZlY3REdXJhdGlvbiArPSBlbGFwc2VkVGltZTtcbiAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY2FzZSBQcm9maWxlcjpcbiAgICAgICAgICB2YXIgcGFyZW50U3RhdGVOb2RlID0gcGFyZW50RmliZXIuc3RhdGVOb2RlO1xuICAgICAgICAgIHBhcmVudFN0YXRlTm9kZS5lZmZlY3REdXJhdGlvbiArPSBlbGFwc2VkVGltZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHBhcmVudEZpYmVyID0gcGFyZW50RmliZXIucmV0dXJuO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZWNvcmRQYXNzaXZlRWZmZWN0RHVyYXRpb24oZmliZXIpIHtcblxuICBpZiAocGFzc2l2ZUVmZmVjdFN0YXJ0VGltZSA+PSAwKSB7XG4gICAgdmFyIGVsYXBzZWRUaW1lID0gbm93JDEoKSAtIHBhc3NpdmVFZmZlY3RTdGFydFRpbWU7XG4gICAgcGFzc2l2ZUVmZmVjdFN0YXJ0VGltZSA9IC0xOyAvLyBTdG9yZSBkdXJhdGlvbiBvbiB0aGUgbmV4dCBuZWFyZXN0IFByb2ZpbGVyIGFuY2VzdG9yXG4gICAgLy8gT3IgdGhlIHJvb3QgKGZvciB0aGUgRGV2VG9vbHMgUHJvZmlsZXIgdG8gcmVhZClcblxuICAgIHZhciBwYXJlbnRGaWJlciA9IGZpYmVyLnJldHVybjtcblxuICAgIHdoaWxlIChwYXJlbnRGaWJlciAhPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChwYXJlbnRGaWJlci50YWcpIHtcbiAgICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAgICB2YXIgcm9vdCA9IHBhcmVudEZpYmVyLnN0YXRlTm9kZTtcblxuICAgICAgICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgICByb290LnBhc3NpdmVFZmZlY3REdXJhdGlvbiArPSBlbGFwc2VkVGltZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY2FzZSBQcm9maWxlcjpcbiAgICAgICAgICB2YXIgcGFyZW50U3RhdGVOb2RlID0gcGFyZW50RmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgaWYgKHBhcmVudFN0YXRlTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gRGV0YWNoZWQgZmliZXJzIGhhdmUgdGhlaXIgc3RhdGUgbm9kZSBjbGVhcmVkIG91dC5cbiAgICAgICAgICAgIC8vIEluIHRoaXMgY2FzZSwgdGhlIHJldHVybiBwb2ludGVyIGlzIGFsc28gY2xlYXJlZCBvdXQsXG4gICAgICAgICAgICAvLyBzbyB3ZSB3b24ndCBiZSBhYmxlIHRvIHJlcG9ydCB0aGUgdGltZSBzcGVudCBpbiB0aGlzIFByb2ZpbGVyJ3Mgc3VidHJlZS5cbiAgICAgICAgICAgIHBhcmVudFN0YXRlTm9kZS5wYXNzaXZlRWZmZWN0RHVyYXRpb24gKz0gZWxhcHNlZFRpbWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBwYXJlbnRGaWJlciA9IHBhcmVudEZpYmVyLnJldHVybjtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gc3RhcnRMYXlvdXRFZmZlY3RUaW1lcigpIHtcblxuICBsYXlvdXRFZmZlY3RTdGFydFRpbWUgPSBub3ckMSgpO1xufVxuXG5mdW5jdGlvbiBzdGFydFBhc3NpdmVFZmZlY3RUaW1lcigpIHtcblxuICBwYXNzaXZlRWZmZWN0U3RhcnRUaW1lID0gbm93JDEoKTtcbn1cblxuZnVuY3Rpb24gdHJhbnNmZXJBY3R1YWxEdXJhdGlvbihmaWJlcikge1xuICAvLyBUcmFuc2ZlciB0aW1lIHNwZW50IHJlbmRlcmluZyB0aGVzZSBjaGlsZHJlbiBzbyB3ZSBkb24ndCBsb3NlIGl0XG4gIC8vIGFmdGVyIHdlIHJlcmVuZGVyLiBUaGlzIGlzIHVzZWQgYXMgYSBoZWxwZXIgaW4gc3BlY2lhbCBjYXNlc1xuICAvLyB3aGVyZSB3ZSBzaG91bGQgY291bnQgdGhlIHdvcmsgb2YgbXVsdGlwbGUgcGFzc2VzLlxuICB2YXIgY2hpbGQgPSBmaWJlci5jaGlsZDtcblxuICB3aGlsZSAoY2hpbGQpIHtcbiAgICBmaWJlci5hY3R1YWxEdXJhdGlvbiArPSBjaGlsZC5hY3R1YWxEdXJhdGlvbjtcbiAgICBjaGlsZCA9IGNoaWxkLnNpYmxpbmc7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2FwdHVyZWRWYWx1ZUF0RmliZXIodmFsdWUsIHNvdXJjZSkge1xuICAvLyBJZiB0aGUgdmFsdWUgaXMgYW4gZXJyb3IsIGNhbGwgdGhpcyBmdW5jdGlvbiBpbW1lZGlhdGVseSBhZnRlciBpdCBpcyB0aHJvd25cbiAgLy8gc28gdGhlIHN0YWNrIGlzIGFjY3VyYXRlLlxuICByZXR1cm4ge1xuICAgIHZhbHVlOiB2YWx1ZSxcbiAgICBzb3VyY2U6IHNvdXJjZSxcbiAgICBzdGFjazogZ2V0U3RhY2tCeUZpYmVySW5EZXZBbmRQcm9kKHNvdXJjZSksXG4gICAgZGlnZXN0OiBudWxsXG4gIH07XG59XG5mdW5jdGlvbiBjcmVhdGVDYXB0dXJlZFZhbHVlKHZhbHVlLCBkaWdlc3QsIHN0YWNrKSB7XG4gIHJldHVybiB7XG4gICAgdmFsdWU6IHZhbHVlLFxuICAgIHNvdXJjZTogbnVsbCxcbiAgICBzdGFjazogc3RhY2sgIT0gbnVsbCA/IHN0YWNrIDogbnVsbCxcbiAgICBkaWdlc3Q6IGRpZ2VzdCAhPSBudWxsID8gZGlnZXN0IDogbnVsbFxuICB9O1xufVxuXG4vLyBUaGlzIG1vZHVsZSBpcyBmb3JrZWQgaW4gZGlmZmVyZW50IGVudmlyb25tZW50cy5cbi8vIEJ5IGRlZmF1bHQsIHJldHVybiBgdHJ1ZWAgdG8gbG9nIGVycm9ycyB0byB0aGUgY29uc29sZS5cbi8vIEZvcmtzIGNhbiByZXR1cm4gYGZhbHNlYCBpZiB0aGlzIGlzbid0IGRlc2lyYWJsZS5cbmZ1bmN0aW9uIHNob3dFcnJvckRpYWxvZyhib3VuZGFyeSwgZXJyb3JJbmZvKSB7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBsb2dDYXB0dXJlZEVycm9yKGJvdW5kYXJ5LCBlcnJvckluZm8pIHtcbiAgdHJ5IHtcbiAgICB2YXIgbG9nRXJyb3IgPSBzaG93RXJyb3JEaWFsb2coYm91bmRhcnksIGVycm9ySW5mbyk7IC8vIEFsbG93IGluamVjdGVkIHNob3dFcnJvckRpYWxvZygpIHRvIHByZXZlbnQgZGVmYXVsdCBjb25zb2xlLmVycm9yIGxvZ2dpbmcuXG4gICAgLy8gVGhpcyBlbmFibGVzIHJlbmRlcmVycyBsaWtlIFJlYWN0TmF0aXZlIHRvIGJldHRlciBtYW5hZ2UgcmVkYm94IGJlaGF2aW9yLlxuXG4gICAgaWYgKGxvZ0Vycm9yID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBlcnJvciA9IGVycm9ySW5mby52YWx1ZTtcblxuICAgIGlmICh0cnVlKSB7XG4gICAgICB2YXIgc291cmNlID0gZXJyb3JJbmZvLnNvdXJjZTtcbiAgICAgIHZhciBzdGFjayA9IGVycm9ySW5mby5zdGFjaztcbiAgICAgIHZhciBjb21wb25lbnRTdGFjayA9IHN0YWNrICE9PSBudWxsID8gc3RhY2sgOiAnJzsgLy8gQnJvd3NlcnMgc3VwcG9ydCBzaWxlbmNpbmcgdW5jYXVnaHQgZXJyb3JzIGJ5IGNhbGxpbmdcbiAgICAgIC8vIGBwcmV2ZW50RGVmYXVsdCgpYCBpbiB3aW5kb3cgYGVycm9yYCBoYW5kbGVyLlxuICAgICAgLy8gV2UgcmVjb3JkIHRoaXMgaW5mb3JtYXRpb24gYXMgYW4gZXhwYW5kbyBvbiB0aGUgZXJyb3IuXG5cbiAgICAgIGlmIChlcnJvciAhPSBudWxsICYmIGVycm9yLl9zdXBwcmVzc0xvZ2dpbmcpIHtcbiAgICAgICAgaWYgKGJvdW5kYXJ5LnRhZyA9PT0gQ2xhc3NDb21wb25lbnQpIHtcbiAgICAgICAgICAvLyBUaGUgZXJyb3IgaXMgcmVjb3ZlcmFibGUgYW5kIHdhcyBzaWxlbmNlZC5cbiAgICAgICAgICAvLyBJZ25vcmUgaXQgYW5kIGRvbid0IHByaW50IHRoZSBzdGFjayBhZGRlbmR1bS5cbiAgICAgICAgICAvLyBUaGlzIGlzIGhhbmR5IGZvciB0ZXN0aW5nIGVycm9yIGJvdW5kYXJpZXMgd2l0aG91dCBub2lzZS5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gLy8gVGhlIGVycm9yIGlzIGZhdGFsLiBTaW5jZSB0aGUgc2lsZW5jaW5nIG1pZ2h0IGhhdmVcbiAgICAgICAgLy8gYmVlbiBhY2NpZGVudGFsLCB3ZSdsbCBzdXJmYWNlIGl0IGFueXdheS5cbiAgICAgICAgLy8gSG93ZXZlciwgdGhlIGJyb3dzZXIgd291bGQgaGF2ZSBzaWxlbmNlZCB0aGUgb3JpZ2luYWwgZXJyb3JcbiAgICAgICAgLy8gc28gd2UnbGwgcHJpbnQgaXQgZmlyc3QsIGFuZCB0aGVuIHByaW50IHRoZSBzdGFjayBhZGRlbmR1bS5cblxuXG4gICAgICAgIGNvbnNvbGVbJ2Vycm9yJ10oZXJyb3IpOyAvLyBEb24ndCB0cmFuc2Zvcm0gdG8gb3VyIHdyYXBwZXJcbiAgICAgICAgLy8gRm9yIGEgbW9yZSBkZXRhaWxlZCBkZXNjcmlwdGlvbiBvZiB0aGlzIGJsb2NrLCBzZWU6XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzEzMzg0XG4gICAgICB9XG5cbiAgICAgIHZhciBjb21wb25lbnROYW1lID0gc291cmNlID8gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihzb3VyY2UpIDogbnVsbDtcbiAgICAgIHZhciBjb21wb25lbnROYW1lTWVzc2FnZSA9IGNvbXBvbmVudE5hbWUgPyBcIlRoZSBhYm92ZSBlcnJvciBvY2N1cnJlZCBpbiB0aGUgPFwiICsgY29tcG9uZW50TmFtZSArIFwiPiBjb21wb25lbnQ6XCIgOiAnVGhlIGFib3ZlIGVycm9yIG9jY3VycmVkIGluIG9uZSBvZiB5b3VyIFJlYWN0IGNvbXBvbmVudHM6JztcbiAgICAgIHZhciBlcnJvckJvdW5kYXJ5TWVzc2FnZTtcblxuICAgICAgaWYgKGJvdW5kYXJ5LnRhZyA9PT0gSG9zdFJvb3QpIHtcbiAgICAgICAgZXJyb3JCb3VuZGFyeU1lc3NhZ2UgPSAnQ29uc2lkZXIgYWRkaW5nIGFuIGVycm9yIGJvdW5kYXJ5IHRvIHlvdXIgdHJlZSB0byBjdXN0b21pemUgZXJyb3IgaGFuZGxpbmcgYmVoYXZpb3IuXFxuJyArICdWaXNpdCBodHRwczovL3JlYWN0anMub3JnL2xpbmsvZXJyb3ItYm91bmRhcmllcyB0byBsZWFybiBtb3JlIGFib3V0IGVycm9yIGJvdW5kYXJpZXMuJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBlcnJvckJvdW5kYXJ5TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoYm91bmRhcnkpIHx8ICdBbm9ueW1vdXMnO1xuICAgICAgICBlcnJvckJvdW5kYXJ5TWVzc2FnZSA9IFwiUmVhY3Qgd2lsbCB0cnkgdG8gcmVjcmVhdGUgdGhpcyBjb21wb25lbnQgdHJlZSBmcm9tIHNjcmF0Y2ggXCIgKyAoXCJ1c2luZyB0aGUgZXJyb3IgYm91bmRhcnkgeW91IHByb3ZpZGVkLCBcIiArIGVycm9yQm91bmRhcnlOYW1lICsgXCIuXCIpO1xuICAgICAgfVxuXG4gICAgICB2YXIgY29tYmluZWRNZXNzYWdlID0gY29tcG9uZW50TmFtZU1lc3NhZ2UgKyBcIlxcblwiICsgY29tcG9uZW50U3RhY2sgKyBcIlxcblxcblwiICsgKFwiXCIgKyBlcnJvckJvdW5kYXJ5TWVzc2FnZSk7IC8vIEluIGRldmVsb3BtZW50LCB3ZSBwcm92aWRlIG91ciBvd24gbWVzc2FnZSB3aXRoIGp1c3QgdGhlIGNvbXBvbmVudCBzdGFjay5cbiAgICAgIC8vIFdlIGRvbid0IGluY2x1ZGUgdGhlIG9yaWdpbmFsIGVycm9yIG1lc3NhZ2UgYW5kIEpTIHN0YWNrIGJlY2F1c2UgdGhlIGJyb3dzZXJcbiAgICAgIC8vIGhhcyBhbHJlYWR5IHByaW50ZWQgaXQuIEV2ZW4gaWYgdGhlIGFwcGxpY2F0aW9uIHN3YWxsb3dzIHRoZSBlcnJvciwgaXQgaXMgc3RpbGxcbiAgICAgIC8vIGRpc3BsYXllZCBieSB0aGUgYnJvd3NlciB0aGFua3MgdG8gdGhlIERFVi1vbmx5IGZha2UgZXZlbnQgdHJpY2sgaW4gUmVhY3RFcnJvclV0aWxzLlxuXG4gICAgICBjb25zb2xlWydlcnJvciddKGNvbWJpbmVkTWVzc2FnZSk7IC8vIERvbid0IHRyYW5zZm9ybSB0byBvdXIgd3JhcHBlclxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJbiBwcm9kdWN0aW9uLCB3ZSBwcmludCB0aGUgZXJyb3IgZGlyZWN0bHkuXG4gICAgICAvLyBUaGlzIHdpbGwgaW5jbHVkZSB0aGUgbWVzc2FnZSwgdGhlIEpTIHN0YWNrLCBhbmQgYW55dGhpbmcgdGhlIGJyb3dzZXIgd2FudHMgdG8gc2hvdy5cbiAgICAgIC8vIFdlIHBhc3MgdGhlIGVycm9yIG9iamVjdCBpbnN0ZWFkIG9mIGN1c3RvbSBtZXNzYWdlIHNvIHRoYXQgdGhlIGJyb3dzZXIgZGlzcGxheXMgdGhlIGVycm9yIG5hdGl2ZWx5LlxuICAgICAgY29uc29sZVsnZXJyb3InXShlcnJvcik7IC8vIERvbid0IHRyYW5zZm9ybSB0byBvdXIgd3JhcHBlclxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIFRoaXMgbWV0aG9kIG11c3Qgbm90IHRocm93LCBvciBSZWFjdCBpbnRlcm5hbCBzdGF0ZSB3aWxsIGdldCBtZXNzZWQgdXAuXG4gICAgLy8gSWYgY29uc29sZS5lcnJvciBpcyBvdmVycmlkZGVuLCBvciBsb2dDYXB0dXJlZEVycm9yKCkgc2hvd3MgYSBkaWFsb2cgdGhhdCB0aHJvd3MsXG4gICAgLy8gd2Ugd2FudCB0byByZXBvcnQgdGhpcyBlcnJvciBvdXRzaWRlIG9mIHRoZSBub3JtYWwgc3RhY2sgYXMgYSBsYXN0IHJlc29ydC5cbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzEzMTg4XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBlO1xuICAgIH0pO1xuICB9XG59XG5cbnZhciBQb3NzaWJseVdlYWtNYXAkMSA9IHR5cGVvZiBXZWFrTWFwID09PSAnZnVuY3Rpb24nID8gV2Vha01hcCA6IE1hcDtcblxuZnVuY3Rpb24gY3JlYXRlUm9vdEVycm9yVXBkYXRlKGZpYmVyLCBlcnJvckluZm8sIGxhbmUpIHtcbiAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVVwZGF0ZShOb1RpbWVzdGFtcCwgbGFuZSk7IC8vIFVubW91bnQgdGhlIHJvb3QgYnkgcmVuZGVyaW5nIG51bGwuXG5cbiAgdXBkYXRlLnRhZyA9IENhcHR1cmVVcGRhdGU7IC8vIENhdXRpb246IFJlYWN0IERldlRvb2xzIGN1cnJlbnRseSBkZXBlbmRzIG9uIHRoaXMgcHJvcGVydHlcbiAgLy8gYmVpbmcgY2FsbGVkIFwiZWxlbWVudFwiLlxuXG4gIHVwZGF0ZS5wYXlsb2FkID0ge1xuICAgIGVsZW1lbnQ6IG51bGxcbiAgfTtcbiAgdmFyIGVycm9yID0gZXJyb3JJbmZvLnZhbHVlO1xuXG4gIHVwZGF0ZS5jYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICBvblVuY2F1Z2h0RXJyb3IoZXJyb3IpO1xuICAgIGxvZ0NhcHR1cmVkRXJyb3IoZmliZXIsIGVycm9ySW5mbyk7XG4gIH07XG5cbiAgcmV0dXJuIHVwZGF0ZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2xhc3NFcnJvclVwZGF0ZShmaWJlciwgZXJyb3JJbmZvLCBsYW5lKSB7XG4gIHZhciB1cGRhdGUgPSBjcmVhdGVVcGRhdGUoTm9UaW1lc3RhbXAsIGxhbmUpO1xuICB1cGRhdGUudGFnID0gQ2FwdHVyZVVwZGF0ZTtcbiAgdmFyIGdldERlcml2ZWRTdGF0ZUZyb21FcnJvciA9IGZpYmVyLnR5cGUuZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yO1xuXG4gIGlmICh0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdmFyIGVycm9yJDEgPSBlcnJvckluZm8udmFsdWU7XG5cbiAgICB1cGRhdGUucGF5bG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBnZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IoZXJyb3IkMSk7XG4gICAgfTtcblxuICAgIHVwZGF0ZS5jYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHtcbiAgICAgICAgbWFya0ZhaWxlZEVycm9yQm91bmRhcnlGb3JIb3RSZWxvYWRpbmcoZmliZXIpO1xuICAgICAgfVxuXG4gICAgICBsb2dDYXB0dXJlZEVycm9yKGZpYmVyLCBlcnJvckluZm8pO1xuICAgIH07XG4gIH1cblxuICB2YXIgaW5zdCA9IGZpYmVyLnN0YXRlTm9kZTtcblxuICBpZiAoaW5zdCAhPT0gbnVsbCAmJiB0eXBlb2YgaW5zdC5jb21wb25lbnREaWRDYXRjaCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHVwZGF0ZS5jYWxsYmFjayA9IGZ1bmN0aW9uIGNhbGxiYWNrKCkge1xuICAgICAge1xuICAgICAgICBtYXJrRmFpbGVkRXJyb3JCb3VuZGFyeUZvckhvdFJlbG9hZGluZyhmaWJlcik7XG4gICAgICB9XG5cbiAgICAgIGxvZ0NhcHR1cmVkRXJyb3IoZmliZXIsIGVycm9ySW5mbyk7XG5cbiAgICAgIGlmICh0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIFRvIHByZXNlcnZlIHRoZSBwcmVleGlzdGluZyByZXRyeSBiZWhhdmlvciBvZiBlcnJvciBib3VuZGFyaWVzLFxuICAgICAgICAvLyB3ZSBrZWVwIHRyYWNrIG9mIHdoaWNoIG9uZXMgYWxyZWFkeSBmYWlsZWQgZHVyaW5nIHRoaXMgYmF0Y2guXG4gICAgICAgIC8vIFRoaXMgZ2V0cyByZXNldCBiZWZvcmUgd2UgeWllbGQgYmFjayB0byB0aGUgYnJvd3Nlci5cbiAgICAgICAgLy8gVE9ETzogV2FybiBpbiBzdHJpY3QgbW9kZSBpZiBnZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IgaXNcbiAgICAgICAgLy8gbm90IGRlZmluZWQuXG4gICAgICAgIG1hcmtMZWdhY3lFcnJvckJvdW5kYXJ5QXNGYWlsZWQodGhpcyk7XG4gICAgICB9XG5cbiAgICAgIHZhciBlcnJvciQxID0gZXJyb3JJbmZvLnZhbHVlO1xuICAgICAgdmFyIHN0YWNrID0gZXJyb3JJbmZvLnN0YWNrO1xuICAgICAgdGhpcy5jb21wb25lbnREaWRDYXRjaChlcnJvciQxLCB7XG4gICAgICAgIGNvbXBvbmVudFN0YWNrOiBzdGFjayAhPT0gbnVsbCA/IHN0YWNrIDogJydcbiAgICAgIH0pO1xuXG4gICAgICB7XG4gICAgICAgIGlmICh0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgLy8gSWYgY29tcG9uZW50RGlkQ2F0Y2ggaXMgdGhlIG9ubHkgZXJyb3IgYm91bmRhcnkgbWV0aG9kIGRlZmluZWQsXG4gICAgICAgICAgLy8gdGhlbiBpdCBuZWVkcyB0byBjYWxsIHNldFN0YXRlIHRvIHJlY292ZXIgZnJvbSBlcnJvcnMuXG4gICAgICAgICAgLy8gSWYgbm8gc3RhdGUgdXBkYXRlIGlzIHNjaGVkdWxlZCB0aGVuIHRoZSBib3VuZGFyeSB3aWxsIHN3YWxsb3cgdGhlIGVycm9yLlxuICAgICAgICAgIGlmICghaW5jbHVkZXNTb21lTGFuZShmaWJlci5sYW5lcywgU3luY0xhbmUpKSB7XG4gICAgICAgICAgICBlcnJvcignJXM6IEVycm9yIGJvdW5kYXJpZXMgc2hvdWxkIGltcGxlbWVudCBnZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IoKS4gJyArICdJbiB0aGF0IG1ldGhvZCwgcmV0dXJuIGEgc3RhdGUgdXBkYXRlIHRvIGRpc3BsYXkgYW4gZXJyb3IgbWVzc2FnZSBvciBmYWxsYmFjayBVSS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpYmVyKSB8fCAnVW5rbm93bicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICByZXR1cm4gdXBkYXRlO1xufVxuXG5mdW5jdGlvbiBhdHRhY2hQaW5nTGlzdGVuZXIocm9vdCwgd2FrZWFibGUsIGxhbmVzKSB7XG4gIC8vIEF0dGFjaCBhIHBpbmcgbGlzdGVuZXJcbiAgLy9cbiAgLy8gVGhlIGRhdGEgbWlnaHQgcmVzb2x2ZSBiZWZvcmUgd2UgaGF2ZSBhIGNoYW5jZSB0byBjb21taXQgdGhlIGZhbGxiYWNrLiBPcixcbiAgLy8gaW4gdGhlIGNhc2Ugb2YgYSByZWZyZXNoLCB3ZSdsbCBuZXZlciBjb21taXQgYSBmYWxsYmFjay4gU28gd2UgbmVlZCB0b1xuICAvLyBhdHRhY2ggYSBsaXN0ZW5lciBub3cuIFdoZW4gaXQgcmVzb2x2ZXMgKFwicGluZ3NcIiksIHdlIGNhbiBkZWNpZGUgd2hldGhlciB0b1xuICAvLyB0cnkgcmVuZGVyaW5nIHRoZSB0cmVlIGFnYWluLlxuICAvL1xuICAvLyBPbmx5IGF0dGFjaCBhIGxpc3RlbmVyIGlmIG9uZSBkb2VzIG5vdCBhbHJlYWR5IGV4aXN0IGZvciB0aGUgbGFuZXNcbiAgLy8gd2UncmUgY3VycmVudGx5IHJlbmRlcmluZyAod2hpY2ggYWN0cyBsaWtlIGEgXCJ0aHJlYWQgSURcIiBoZXJlKS5cbiAgLy9cbiAgLy8gV2Ugb25seSBuZWVkIHRvIGRvIHRoaXMgaW4gY29uY3VycmVudCBtb2RlLiBMZWdhY3kgU3VzcGVuc2UgYWx3YXlzXG4gIC8vIGNvbW1pdHMgZmFsbGJhY2tzIHN5bmNocm9ub3VzbHksIHNvIHRoZXJlIGFyZSBubyBwaW5ncy5cbiAgdmFyIHBpbmdDYWNoZSA9IHJvb3QucGluZ0NhY2hlO1xuICB2YXIgdGhyZWFkSURzO1xuXG4gIGlmIChwaW5nQ2FjaGUgPT09IG51bGwpIHtcbiAgICBwaW5nQ2FjaGUgPSByb290LnBpbmdDYWNoZSA9IG5ldyBQb3NzaWJseVdlYWtNYXAkMSgpO1xuICAgIHRocmVhZElEcyA9IG5ldyBTZXQoKTtcbiAgICBwaW5nQ2FjaGUuc2V0KHdha2VhYmxlLCB0aHJlYWRJRHMpO1xuICB9IGVsc2Uge1xuICAgIHRocmVhZElEcyA9IHBpbmdDYWNoZS5nZXQod2FrZWFibGUpO1xuXG4gICAgaWYgKHRocmVhZElEcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJlYWRJRHMgPSBuZXcgU2V0KCk7XG4gICAgICBwaW5nQ2FjaGUuc2V0KHdha2VhYmxlLCB0aHJlYWRJRHMpO1xuICAgIH1cbiAgfVxuXG4gIGlmICghdGhyZWFkSURzLmhhcyhsYW5lcykpIHtcbiAgICAvLyBNZW1vaXplIHVzaW5nIHRoZSB0aHJlYWQgSUQgdG8gcHJldmVudCByZWR1bmRhbnQgbGlzdGVuZXJzLlxuICAgIHRocmVhZElEcy5hZGQobGFuZXMpO1xuICAgIHZhciBwaW5nID0gcGluZ1N1c3BlbmRlZFJvb3QuYmluZChudWxsLCByb290LCB3YWtlYWJsZSwgbGFuZXMpO1xuXG4gICAge1xuICAgICAgaWYgKGlzRGV2VG9vbHNQcmVzZW50KSB7XG4gICAgICAgIC8vIElmIHdlIGhhdmUgcGVuZGluZyB3b3JrIHN0aWxsLCByZXN0b3JlIHRoZSBvcmlnaW5hbCB1cGRhdGVyc1xuICAgICAgICByZXN0b3JlUGVuZGluZ1VwZGF0ZXJzKHJvb3QsIGxhbmVzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB3YWtlYWJsZS50aGVuKHBpbmcsIHBpbmcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGF0dGFjaFJldHJ5TGlzdGVuZXIoc3VzcGVuc2VCb3VuZGFyeSwgcm9vdCwgd2FrZWFibGUsIGxhbmVzKSB7XG4gIC8vIFJldHJ5IGxpc3RlbmVyXG4gIC8vXG4gIC8vIElmIHRoZSBmYWxsYmFjayBkb2VzIGNvbW1pdCwgd2UgbmVlZCB0byBhdHRhY2ggYSBkaWZmZXJlbnQgdHlwZSBvZlxuICAvLyBsaXN0ZW5lci4gVGhpcyBvbmUgc2NoZWR1bGVzIGFuIHVwZGF0ZSBvbiB0aGUgU3VzcGVuc2UgYm91bmRhcnkgdG8gdHVyblxuICAvLyB0aGUgZmFsbGJhY2sgc3RhdGUgb2ZmLlxuICAvL1xuICAvLyBTdGFzaCB0aGUgd2FrZWFibGUgb24gdGhlIGJvdW5kYXJ5IGZpYmVyIHNvIHdlIGNhbiBhY2Nlc3MgaXQgaW4gdGhlXG4gIC8vIGNvbW1pdCBwaGFzZS5cbiAgLy9cbiAgLy8gV2hlbiB0aGUgd2FrZWFibGUgcmVzb2x2ZXMsIHdlJ2xsIGF0dGVtcHQgdG8gcmVuZGVyIHRoZSBib3VuZGFyeVxuICAvLyBhZ2FpbiAoXCJyZXRyeVwiKS5cbiAgdmFyIHdha2VhYmxlcyA9IHN1c3BlbnNlQm91bmRhcnkudXBkYXRlUXVldWU7XG5cbiAgaWYgKHdha2VhYmxlcyA9PT0gbnVsbCkge1xuICAgIHZhciB1cGRhdGVRdWV1ZSA9IG5ldyBTZXQoKTtcbiAgICB1cGRhdGVRdWV1ZS5hZGQod2FrZWFibGUpO1xuICAgIHN1c3BlbnNlQm91bmRhcnkudXBkYXRlUXVldWUgPSB1cGRhdGVRdWV1ZTtcbiAgfSBlbHNlIHtcbiAgICB3YWtlYWJsZXMuYWRkKHdha2VhYmxlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXNldFN1c3BlbmRlZENvbXBvbmVudChzb3VyY2VGaWJlciwgcm9vdFJlbmRlckxhbmVzKSB7XG4gIC8vIEEgbGVnYWN5IG1vZGUgU3VzcGVuc2UgcXVpcmssIG9ubHkgcmVsZXZhbnQgdG8gaG9vayBjb21wb25lbnRzLlxuXG5cbiAgdmFyIHRhZyA9IHNvdXJjZUZpYmVyLnRhZztcblxuICBpZiAoKHNvdXJjZUZpYmVyLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgPT09IE5vTW9kZSAmJiAodGFnID09PSBGdW5jdGlvbkNvbXBvbmVudCB8fCB0YWcgPT09IEZvcndhcmRSZWYgfHwgdGFnID09PSBTaW1wbGVNZW1vQ29tcG9uZW50KSkge1xuICAgIHZhciBjdXJyZW50U291cmNlID0gc291cmNlRmliZXIuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKGN1cnJlbnRTb3VyY2UpIHtcbiAgICAgIHNvdXJjZUZpYmVyLnVwZGF0ZVF1ZXVlID0gY3VycmVudFNvdXJjZS51cGRhdGVRdWV1ZTtcbiAgICAgIHNvdXJjZUZpYmVyLm1lbW9pemVkU3RhdGUgPSBjdXJyZW50U291cmNlLm1lbW9pemVkU3RhdGU7XG4gICAgICBzb3VyY2VGaWJlci5sYW5lcyA9IGN1cnJlbnRTb3VyY2UubGFuZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNvdXJjZUZpYmVyLnVwZGF0ZVF1ZXVlID0gbnVsbDtcbiAgICAgIHNvdXJjZUZpYmVyLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBnZXROZWFyZXN0U3VzcGVuc2VCb3VuZGFyeVRvQ2FwdHVyZShyZXR1cm5GaWJlcikge1xuICB2YXIgbm9kZSA9IHJldHVybkZpYmVyO1xuXG4gIGRvIHtcbiAgICBpZiAobm9kZS50YWcgPT09IFN1c3BlbnNlQ29tcG9uZW50ICYmIHNob3VsZENhcHR1cmVTdXNwZW5zZShub2RlKSkge1xuICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfSAvLyBUaGlzIGJvdW5kYXJ5IGFscmVhZHkgY2FwdHVyZWQgZHVyaW5nIHRoaXMgcmVuZGVyLiBDb250aW51ZSB0byB0aGUgbmV4dFxuICAgIC8vIGJvdW5kYXJ5LlxuXG5cbiAgICBub2RlID0gbm9kZS5yZXR1cm47XG4gIH0gd2hpbGUgKG5vZGUgIT09IG51bGwpO1xuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBtYXJrU3VzcGVuc2VCb3VuZGFyeVNob3VsZENhcHR1cmUoc3VzcGVuc2VCb3VuZGFyeSwgcmV0dXJuRmliZXIsIHNvdXJjZUZpYmVyLCByb290LCByb290UmVuZGVyTGFuZXMpIHtcbiAgLy8gVGhpcyBtYXJrcyBhIFN1c3BlbnNlIGJvdW5kYXJ5IHNvIHRoYXQgd2hlbiB3ZSdyZSB1bndpbmRpbmcgdGhlIHN0YWNrLFxuICAvLyBpdCBjYXB0dXJlcyB0aGUgc3VzcGVuZGVkIFwiZXhjZXB0aW9uXCIgYW5kIGRvZXMgYSBzZWNvbmQgKGZhbGxiYWNrKSBwYXNzLlxuICBpZiAoKHN1c3BlbnNlQm91bmRhcnkubW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlKSB7XG4gICAgLy8gTGVnYWN5IE1vZGUgU3VzcGVuc2VcbiAgICAvL1xuICAgIC8vIElmIHRoZSBib3VuZGFyeSBpcyBpbiBsZWdhY3kgbW9kZSwgd2Ugc2hvdWxkICpub3QqXG4gICAgLy8gc3VzcGVuZCB0aGUgY29tbWl0LiBQcmV0ZW5kIGFzIGlmIHRoZSBzdXNwZW5kZWQgY29tcG9uZW50IHJlbmRlcmVkXG4gICAgLy8gbnVsbCBhbmQga2VlcCByZW5kZXJpbmcuIFdoZW4gdGhlIFN1c3BlbnNlIGJvdW5kYXJ5IGNvbXBsZXRlcyxcbiAgICAvLyB3ZSdsbCBkbyBhIHNlY29uZCBwYXNzIHRvIHJlbmRlciB0aGUgZmFsbGJhY2suXG4gICAgaWYgKHN1c3BlbnNlQm91bmRhcnkgPT09IHJldHVybkZpYmVyKSB7XG4gICAgICAvLyBTcGVjaWFsIGNhc2Ugd2hlcmUgd2Ugc3VzcGVuZGVkIHdoaWxlIHJlY29uY2lsaW5nIHRoZSBjaGlsZHJlbiBvZlxuICAgICAgLy8gYSBTdXNwZW5zZSBib3VuZGFyeSdzIGlubmVyIE9mZnNjcmVlbiB3cmFwcGVyIGZpYmVyLiBUaGlzIGhhcHBlbnNcbiAgICAgIC8vIHdoZW4gYSBSZWFjdC5sYXp5IGNvbXBvbmVudCBpcyBhIGRpcmVjdCBjaGlsZCBvZiBhXG4gICAgICAvLyBTdXNwZW5zZSBib3VuZGFyeS5cbiAgICAgIC8vXG4gICAgICAvLyBTdXNwZW5zZSBib3VuZGFyaWVzIGFyZSBpbXBsZW1lbnRlZCBhcyBtdWx0aXBsZSBmaWJlcnMsIGJ1dCB0aGV5XG4gICAgICAvLyBhcmUgYSBzaW5nbGUgY29uY2VwdHVhbCB1bml0LiBUaGUgbGVnYWN5IG1vZGUgYmVoYXZpb3Igd2hlcmUgd2VcbiAgICAgIC8vIHByZXRlbmQgdGhlIHN1c3BlbmRlZCBmaWJlciBjb21taXR0ZWQgYXMgYG51bGxgIHdvbid0IHdvcmssXG4gICAgICAvLyBiZWNhdXNlIGluIHRoaXMgY2FzZSB0aGUgXCJzdXNwZW5kZWRcIiBmaWJlciBpcyB0aGUgaW5uZXJcbiAgICAgIC8vIE9mZnNjcmVlbiB3cmFwcGVyLlxuICAgICAgLy9cbiAgICAgIC8vIEJlY2F1c2UgdGhlIGNvbnRlbnRzIG9mIHRoZSBib3VuZGFyeSBoYXZlbid0IHN0YXJ0ZWQgcmVuZGVyaW5nXG4gICAgICAvLyB5ZXQgKGkuZS4gbm90aGluZyBpbiB0aGUgdHJlZSBoYXMgcGFydGlhbGx5IHJlbmRlcmVkKSB3ZSBjYW5cbiAgICAgIC8vIHN3aXRjaCB0byB0aGUgcmVndWxhciwgY29uY3VycmVudCBtb2RlIGJlaGF2aW9yOiBtYXJrIHRoZVxuICAgICAgLy8gYm91bmRhcnkgd2l0aCBTaG91bGRDYXB0dXJlIGFuZCBlbnRlciB0aGUgdW53aW5kIHBoYXNlLlxuICAgICAgc3VzcGVuc2VCb3VuZGFyeS5mbGFncyB8PSBTaG91bGRDYXB0dXJlO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdXNwZW5zZUJvdW5kYXJ5LmZsYWdzIHw9IERpZENhcHR1cmU7XG4gICAgICBzb3VyY2VGaWJlci5mbGFncyB8PSBGb3JjZVVwZGF0ZUZvckxlZ2FjeVN1c3BlbnNlOyAvLyBXZSdyZSBnb2luZyB0byBjb21taXQgdGhpcyBmaWJlciBldmVuIHRob3VnaCBpdCBkaWRuJ3QgY29tcGxldGUuXG4gICAgICAvLyBCdXQgd2Ugc2hvdWxkbid0IGNhbGwgYW55IGxpZmVjeWNsZSBtZXRob2RzIG9yIGNhbGxiYWNrcy4gUmVtb3ZlXG4gICAgICAvLyBhbGwgbGlmZWN5Y2xlIGVmZmVjdCB0YWdzLlxuXG4gICAgICBzb3VyY2VGaWJlci5mbGFncyAmPSB+KExpZmVjeWNsZUVmZmVjdE1hc2sgfCBJbmNvbXBsZXRlKTtcblxuICAgICAgaWYgKHNvdXJjZUZpYmVyLnRhZyA9PT0gQ2xhc3NDb21wb25lbnQpIHtcbiAgICAgICAgdmFyIGN1cnJlbnRTb3VyY2VGaWJlciA9IHNvdXJjZUZpYmVyLmFsdGVybmF0ZTtcblxuICAgICAgICBpZiAoY3VycmVudFNvdXJjZUZpYmVyID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gVGhpcyBpcyBhIG5ldyBtb3VudC4gQ2hhbmdlIHRoZSB0YWcgc28gaXQncyBub3QgbWlzdGFrZW4gZm9yIGFcbiAgICAgICAgICAvLyBjb21wbGV0ZWQgY2xhc3MgY29tcG9uZW50LiBGb3IgZXhhbXBsZSwgd2Ugc2hvdWxkIG5vdCBjYWxsXG4gICAgICAgICAgLy8gY29tcG9uZW50V2lsbFVubW91bnQgaWYgaXQgaXMgZGVsZXRlZC5cbiAgICAgICAgICBzb3VyY2VGaWJlci50YWcgPSBJbmNvbXBsZXRlQ2xhc3NDb21wb25lbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gV2hlbiB3ZSB0cnkgcmVuZGVyaW5nIGFnYWluLCB3ZSBzaG91bGQgbm90IHJldXNlIHRoZSBjdXJyZW50IGZpYmVyLFxuICAgICAgICAgIC8vIHNpbmNlIGl0J3Mga25vd24gdG8gYmUgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLiBVc2UgYSBmb3JjZSB1cGRhdGUgdG9cbiAgICAgICAgICAvLyBwcmV2ZW50IGEgYmFpbCBvdXQuXG4gICAgICAgICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVVwZGF0ZShOb1RpbWVzdGFtcCwgU3luY0xhbmUpO1xuICAgICAgICAgIHVwZGF0ZS50YWcgPSBGb3JjZVVwZGF0ZTtcbiAgICAgICAgICBlbnF1ZXVlVXBkYXRlKHNvdXJjZUZpYmVyLCB1cGRhdGUsIFN5bmNMYW5lKTtcbiAgICAgICAgfVxuICAgICAgfSAvLyBUaGUgc291cmNlIGZpYmVyIGRpZCBub3QgY29tcGxldGUuIE1hcmsgaXQgd2l0aCBTeW5jIHByaW9yaXR5IHRvXG4gICAgICAvLyBpbmRpY2F0ZSB0aGF0IGl0IHN0aWxsIGhhcyBwZW5kaW5nIHdvcmsuXG5cblxuICAgICAgc291cmNlRmliZXIubGFuZXMgPSBtZXJnZUxhbmVzKHNvdXJjZUZpYmVyLmxhbmVzLCBTeW5jTGFuZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN1c3BlbnNlQm91bmRhcnk7XG4gIH0gLy8gQ29uZmlybWVkIHRoYXQgdGhlIGJvdW5kYXJ5IGlzIGluIGEgY29uY3VycmVudCBtb2RlIHRyZWUuIENvbnRpbnVlXG4gIC8vIHdpdGggdGhlIG5vcm1hbCBzdXNwZW5kIHBhdGguXG4gIC8vXG4gIC8vIEFmdGVyIHRoaXMgd2UnbGwgdXNlIGEgc2V0IG9mIGhldXJpc3RpY3MgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpc1xuICAvLyByZW5kZXIgcGFzcyB3aWxsIHJ1biB0byBjb21wbGV0aW9uIG9yIHJlc3RhcnQgb3IgXCJzdXNwZW5kXCIgdGhlIGNvbW1pdC5cbiAgLy8gVGhlIGFjdHVhbCBsb2dpYyBmb3IgdGhpcyBpcyBzcHJlYWQgb3V0IGluIGRpZmZlcmVudCBwbGFjZXMuXG4gIC8vXG4gIC8vIFRoaXMgZmlyc3QgcHJpbmNpcGxlIGlzIHRoYXQgaWYgd2UncmUgZ29pbmcgdG8gc3VzcGVuZCB3aGVuIHdlIGNvbXBsZXRlXG4gIC8vIGEgcm9vdCwgdGhlbiB3ZSBzaG91bGQgYWxzbyByZXN0YXJ0IGlmIHdlIGdldCBhbiB1cGRhdGUgb3IgcGluZyB0aGF0XG4gIC8vIG1pZ2h0IHVuc3VzcGVuZCBpdCwgYW5kIHZpY2UgdmVyc2EuIFRoZSBvbmx5IHJlYXNvbiB0byBzdXNwZW5kIGlzXG4gIC8vIGJlY2F1c2UgeW91IHRoaW5rIHlvdSBtaWdodCB3YW50IHRvIHJlc3RhcnQgYmVmb3JlIGNvbW1pdHRpbmcuIEhvd2V2ZXIsXG4gIC8vIGl0IGRvZXNuJ3QgbWFrZSBzZW5zZSB0byByZXN0YXJ0IG9ubHkgd2hpbGUgaW4gdGhlIHBlcmlvZCB3ZSdyZSBzdXNwZW5kZWQuXG4gIC8vXG4gIC8vIFJlc3RhcnRpbmcgdG9vIGFnZ3Jlc3NpdmVseSBpcyBhbHNvIG5vdCBnb29kIGJlY2F1c2UgaXQgc3RhcnZlcyBvdXQgYW55XG4gIC8vIGludGVybWVkaWF0ZSBsb2FkaW5nIHN0YXRlLiBTbyB3ZSB1c2UgaGV1cmlzdGljcyB0byBkZXRlcm1pbmUgd2hlbi5cbiAgLy8gU3VzcGVuc2UgSGV1cmlzdGljc1xuICAvL1xuICAvLyBJZiBub3RoaW5nIHRocmV3IGEgUHJvbWlzZSBvciBhbGwgdGhlIHNhbWUgZmFsbGJhY2tzIGFyZSBhbHJlYWR5IHNob3dpbmcsXG4gIC8vIHRoZW4gZG9uJ3Qgc3VzcGVuZC9yZXN0YXJ0LlxuICAvL1xuICAvLyBJZiB0aGlzIGlzIGFuIGluaXRpYWwgcmVuZGVyIG9mIGEgbmV3IHRyZWUgb2YgU3VzcGVuc2UgYm91bmRhcmllcyBhbmRcbiAgLy8gdGhvc2UgdHJpZ2dlciBhIGZhbGxiYWNrLCB0aGVuIGRvbid0IHN1c3BlbmQvcmVzdGFydC4gV2Ugd2FudCB0byBlbnN1cmVcbiAgLy8gdGhhdCB3ZSBjYW4gc2hvdyB0aGUgaW5pdGlhbCBsb2FkaW5nIHN0YXRlIGFzIHF1aWNrbHkgYXMgcG9zc2libGUuXG4gIC8vXG4gIC8vIElmIHdlIGhpdCBhIFwiRGVsYXllZFwiIGNhc2UsIHN1Y2ggYXMgd2hlbiB3ZSdkIHN3aXRjaCBmcm9tIGNvbnRlbnQgYmFjayBpbnRvXG4gIC8vIGEgZmFsbGJhY2ssIHRoZW4gd2Ugc2hvdWxkIGFsd2F5cyBzdXNwZW5kL3Jlc3RhcnQuIFRyYW5zaXRpb25zIGFwcGx5XG4gIC8vIHRvIHRoaXMgY2FzZS4gSWYgbm9uZSBpcyBkZWZpbmVkLCBKTkQgaXMgdXNlZCBpbnN0ZWFkLlxuICAvL1xuICAvLyBJZiB3ZSdyZSBhbHJlYWR5IHNob3dpbmcgYSBmYWxsYmFjayBhbmQgaXQgZ2V0cyBcInJldHJpZWRcIiwgYWxsb3dpbmcgdXMgdG8gc2hvd1xuICAvLyBhbm90aGVyIGxldmVsLCBidXQgdGhlcmUncyBzdGlsbCBhbiBpbm5lciBib3VuZGFyeSB0aGF0IHdvdWxkIHNob3cgYSBmYWxsYmFjayxcbiAgLy8gdGhlbiB3ZSBzdXNwZW5kL3Jlc3RhcnQgZm9yIDUwMG1zIHNpbmNlIHRoZSBsYXN0IHRpbWUgd2Ugc2hvd2VkIGEgZmFsbGJhY2tcbiAgLy8gYW55d2hlcmUgaW4gdGhlIHRyZWUuIFRoaXMgZWZmZWN0aXZlbHkgdGhyb3R0bGVzIHByb2dyZXNzaXZlIGxvYWRpbmcgaW50byBhXG4gIC8vIGNvbnNpc3RlbnQgdHJhaW4gb2YgY29tbWl0cy4gVGhpcyBhbHNvIGdpdmVzIHVzIGFuIG9wcG9ydHVuaXR5IHRvIHJlc3RhcnQgdG9cbiAgLy8gZ2V0IHRvIHRoZSBjb21wbGV0ZWQgc3RhdGUgc2xpZ2h0bHkgZWFybGllci5cbiAgLy9cbiAgLy8gSWYgdGhlcmUncyBhbWJpZ3VpdHkgZHVlIHRvIGJhdGNoaW5nIGl0J3MgcmVzb2x2ZWQgaW4gcHJlZmVyZW5jZSBvZjpcbiAgLy8gMSkgXCJkZWxheWVkXCIsIDIpIFwiaW5pdGlhbCByZW5kZXJcIiwgMykgXCJyZXRyeVwiLlxuICAvL1xuICAvLyBXZSB3YW50IHRvIGVuc3VyZSB0aGF0IGEgXCJidXN5XCIgc3RhdGUgZG9lc24ndCBnZXQgZm9yY2UgY29tbWl0dGVkLiBXZSB3YW50IHRvXG4gIC8vIGVuc3VyZSB0aGF0IG5ldyBpbml0aWFsIGxvYWRpbmcgc3RhdGVzIGNhbiBjb21taXQgYXMgc29vbiBhcyBwb3NzaWJsZS5cblxuXG4gIHN1c3BlbnNlQm91bmRhcnkuZmxhZ3MgfD0gU2hvdWxkQ2FwdHVyZTsgLy8gVE9ETzogSSB0aGluayB3ZSBjYW4gcmVtb3ZlIHRoaXMsIHNpbmNlIHdlIG5vdyB1c2UgYERpZENhcHR1cmVgIGluXG4gIC8vIHRoZSBiZWdpbiBwaGFzZSB0byBwcmV2ZW50IGFuIGVhcmx5IGJhaWxvdXQuXG5cbiAgc3VzcGVuc2VCb3VuZGFyeS5sYW5lcyA9IHJvb3RSZW5kZXJMYW5lcztcbiAgcmV0dXJuIHN1c3BlbnNlQm91bmRhcnk7XG59XG5cbmZ1bmN0aW9uIHRocm93RXhjZXB0aW9uKHJvb3QsIHJldHVybkZpYmVyLCBzb3VyY2VGaWJlciwgdmFsdWUsIHJvb3RSZW5kZXJMYW5lcykge1xuICAvLyBUaGUgc291cmNlIGZpYmVyIGRpZCBub3QgY29tcGxldGUuXG4gIHNvdXJjZUZpYmVyLmZsYWdzIHw9IEluY29tcGxldGU7XG5cbiAge1xuICAgIGlmIChpc0RldlRvb2xzUHJlc2VudCkge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBwZW5kaW5nIHdvcmsgc3RpbGwsIHJlc3RvcmUgdGhlIG9yaWdpbmFsIHVwZGF0ZXJzXG4gICAgICByZXN0b3JlUGVuZGluZ1VwZGF0ZXJzKHJvb3QsIHJvb3RSZW5kZXJMYW5lcyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHZhbHVlLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBUaGlzIGlzIGEgd2FrZWFibGUuIFRoZSBjb21wb25lbnQgc3VzcGVuZGVkLlxuICAgIHZhciB3YWtlYWJsZSA9IHZhbHVlO1xuICAgIHJlc2V0U3VzcGVuZGVkQ29tcG9uZW50KHNvdXJjZUZpYmVyKTtcblxuICAgIHtcbiAgICAgIGlmIChnZXRJc0h5ZHJhdGluZygpICYmIHNvdXJjZUZpYmVyLm1vZGUgJiBDb25jdXJyZW50TW9kZSkge1xuICAgICAgICBtYXJrRGlkVGhyb3dXaGlsZUh5ZHJhdGluZ0RFVigpO1xuICAgICAgfVxuICAgIH1cblxuXG4gICAgdmFyIHN1c3BlbnNlQm91bmRhcnkgPSBnZXROZWFyZXN0U3VzcGVuc2VCb3VuZGFyeVRvQ2FwdHVyZShyZXR1cm5GaWJlcik7XG5cbiAgICBpZiAoc3VzcGVuc2VCb3VuZGFyeSAhPT0gbnVsbCkge1xuICAgICAgc3VzcGVuc2VCb3VuZGFyeS5mbGFncyAmPSB+Rm9yY2VDbGllbnRSZW5kZXI7XG4gICAgICBtYXJrU3VzcGVuc2VCb3VuZGFyeVNob3VsZENhcHR1cmUoc3VzcGVuc2VCb3VuZGFyeSwgcmV0dXJuRmliZXIsIHNvdXJjZUZpYmVyLCByb290LCByb290UmVuZGVyTGFuZXMpOyAvLyBXZSBvbmx5IGF0dGFjaCBwaW5nIGxpc3RlbmVycyBpbiBjb25jdXJyZW50IG1vZGUuIExlZ2FjeSBTdXNwZW5zZSBhbHdheXNcbiAgICAgIC8vIGNvbW1pdHMgZmFsbGJhY2tzIHN5bmNocm9ub3VzbHksIHNvIHRoZXJlIGFyZSBubyBwaW5ncy5cblxuICAgICAgaWYgKHN1c3BlbnNlQm91bmRhcnkubW9kZSAmIENvbmN1cnJlbnRNb2RlKSB7XG4gICAgICAgIGF0dGFjaFBpbmdMaXN0ZW5lcihyb290LCB3YWtlYWJsZSwgcm9vdFJlbmRlckxhbmVzKTtcbiAgICAgIH1cblxuICAgICAgYXR0YWNoUmV0cnlMaXN0ZW5lcihzdXNwZW5zZUJvdW5kYXJ5LCByb290LCB3YWtlYWJsZSk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vIGJvdW5kYXJ5IHdhcyBmb3VuZC4gVW5sZXNzIHRoaXMgaXMgYSBzeW5jIHVwZGF0ZSwgdGhpcyBpcyBPSy5cbiAgICAgIC8vIFdlIGNhbiBzdXNwZW5kIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEgdG8gYXJyaXZlLlxuICAgICAgaWYgKCFpbmNsdWRlc1N5bmNMYW5lKHJvb3RSZW5kZXJMYW5lcykpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBub3QgYSBzeW5jIHVwZGF0ZS4gU3VzcGVuZC4gU2luY2Ugd2UncmUgbm90IGFjdGl2YXRpbmcgYVxuICAgICAgICAvLyBTdXNwZW5zZSBib3VuZGFyeSwgdGhpcyB3aWxsIHVud2luZCBhbGwgdGhlIHdheSB0byB0aGUgcm9vdCB3aXRob3V0XG4gICAgICAgIC8vIHBlcmZvcm1pbmcgYSBzZWNvbmQgcGFzcyB0byByZW5kZXIgYSBmYWxsYmFjay4gKFRoaXMgaXMgYXJndWFibHkgaG93XG4gICAgICAgIC8vIHJlZnJlc2ggdHJhbnNpdGlvbnMgc2hvdWxkIHdvcmssIHRvbywgc2luY2Ugd2UncmUgbm90IGdvaW5nIHRvIGNvbW1pdFxuICAgICAgICAvLyB0aGUgZmFsbGJhY2tzIGFueXdheS4pXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFRoaXMgY2FzZSBhbHNvIGFwcGxpZXMgdG8gaW5pdGlhbCBoeWRyYXRpb24uXG4gICAgICAgIGF0dGFjaFBpbmdMaXN0ZW5lcihyb290LCB3YWtlYWJsZSwgcm9vdFJlbmRlckxhbmVzKTtcbiAgICAgICAgcmVuZGVyRGlkU3VzcGVuZERlbGF5SWZQb3NzaWJsZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IC8vIFRoaXMgaXMgYSBzeW5jL2Rpc2NyZXRlIHVwZGF0ZS4gV2UgdHJlYXQgdGhpcyBjYXNlIGxpa2UgYW4gZXJyb3JcbiAgICAgIC8vIGJlY2F1c2UgZGlzY3JldGUgcmVuZGVycyBhcmUgZXhwZWN0ZWQgdG8gcHJvZHVjZSBhIGNvbXBsZXRlIHRyZWVcbiAgICAgIC8vIHN5bmNocm9ub3VzbHkgdG8gbWFpbnRhaW4gY29uc2lzdGVuY3kgd2l0aCBleHRlcm5hbCBzdGF0ZS5cblxuXG4gICAgICB2YXIgdW5jYXVnaHRTdXNwZW5zZUVycm9yID0gbmV3IEVycm9yKCdBIGNvbXBvbmVudCBzdXNwZW5kZWQgd2hpbGUgcmVzcG9uZGluZyB0byBzeW5jaHJvbm91cyBpbnB1dC4gVGhpcyAnICsgJ3dpbGwgY2F1c2UgdGhlIFVJIHRvIGJlIHJlcGxhY2VkIHdpdGggYSBsb2FkaW5nIGluZGljYXRvci4gVG8gJyArICdmaXgsIHVwZGF0ZXMgdGhhdCBzdXNwZW5kIHNob3VsZCBiZSB3cmFwcGVkICcgKyAnd2l0aCBzdGFydFRyYW5zaXRpb24uJyk7IC8vIElmIHdlJ3JlIG91dHNpZGUgYSB0cmFuc2l0aW9uLCBmYWxsIHRocm91Z2ggdG8gdGhlIHJlZ3VsYXIgZXJyb3IgcGF0aC5cbiAgICAgIC8vIFRoZSBlcnJvciB3aWxsIGJlIGNhdWdodCBieSB0aGUgbmVhcmVzdCBzdXNwZW5zZSBib3VuZGFyeS5cblxuICAgICAgdmFsdWUgPSB1bmNhdWdodFN1c3BlbnNlRXJyb3I7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgaXMgYSByZWd1bGFyIGVycm9yLCBub3QgYSBTdXNwZW5zZSB3YWtlYWJsZS5cbiAgICBpZiAoZ2V0SXNIeWRyYXRpbmcoKSAmJiBzb3VyY2VGaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpIHtcbiAgICAgIG1hcmtEaWRUaHJvd1doaWxlSHlkcmF0aW5nREVWKCk7XG5cbiAgICAgIHZhciBfc3VzcGVuc2VCb3VuZGFyeSA9IGdldE5lYXJlc3RTdXNwZW5zZUJvdW5kYXJ5VG9DYXB0dXJlKHJldHVybkZpYmVyKTsgLy8gSWYgdGhlIGVycm9yIHdhcyB0aHJvd24gZHVyaW5nIGh5ZHJhdGlvbiwgd2UgbWF5IGJlIGFibGUgdG8gcmVjb3ZlciBieVxuICAgICAgLy8gZGlzY2FyZGluZyB0aGUgZGVoeWRyYXRlZCBjb250ZW50IGFuZCBzd2l0Y2hpbmcgdG8gYSBjbGllbnQgcmVuZGVyLlxuICAgICAgLy8gSW5zdGVhZCBvZiBzdXJmYWNpbmcgdGhlIGVycm9yLCBmaW5kIHRoZSBuZWFyZXN0IFN1c3BlbnNlIGJvdW5kYXJ5XG4gICAgICAvLyBhbmQgcmVuZGVyIGl0IGFnYWluIHdpdGhvdXQgaHlkcmF0aW9uLlxuXG5cbiAgICAgIGlmIChfc3VzcGVuc2VCb3VuZGFyeSAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoKF9zdXNwZW5zZUJvdW5kYXJ5LmZsYWdzICYgU2hvdWxkQ2FwdHVyZSkgPT09IE5vRmxhZ3MpIHtcbiAgICAgICAgICAvLyBTZXQgYSBmbGFnIHRvIGluZGljYXRlIHRoYXQgd2Ugc2hvdWxkIHRyeSByZW5kZXJpbmcgdGhlIG5vcm1hbFxuICAgICAgICAgIC8vIGNoaWxkcmVuIGFnYWluLCBub3QgdGhlIGZhbGxiYWNrLlxuICAgICAgICAgIF9zdXNwZW5zZUJvdW5kYXJ5LmZsYWdzIHw9IEZvcmNlQ2xpZW50UmVuZGVyO1xuICAgICAgICB9XG5cbiAgICAgICAgbWFya1N1c3BlbnNlQm91bmRhcnlTaG91bGRDYXB0dXJlKF9zdXNwZW5zZUJvdW5kYXJ5LCByZXR1cm5GaWJlciwgc291cmNlRmliZXIsIHJvb3QsIHJvb3RSZW5kZXJMYW5lcyk7IC8vIEV2ZW4gdGhvdWdoIHRoZSB1c2VyIG1heSBub3QgYmUgYWZmZWN0ZWQgYnkgdGhpcyBlcnJvciwgd2Ugc2hvdWxkXG4gICAgICAgIC8vIHN0aWxsIGxvZyBpdCBzbyBpdCBjYW4gYmUgZml4ZWQuXG5cbiAgICAgICAgcXVldWVIeWRyYXRpb25FcnJvcihjcmVhdGVDYXB0dXJlZFZhbHVlQXRGaWJlcih2YWx1ZSwgc291cmNlRmliZXIpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhbHVlID0gY3JlYXRlQ2FwdHVyZWRWYWx1ZUF0RmliZXIodmFsdWUsIHNvdXJjZUZpYmVyKTtcbiAgcmVuZGVyRGlkRXJyb3IodmFsdWUpOyAvLyBXZSBkaWRuJ3QgZmluZCBhIGJvdW5kYXJ5IHRoYXQgY291bGQgaGFuZGxlIHRoaXMgdHlwZSBvZiBleGNlcHRpb24uIFN0YXJ0XG4gIC8vIG92ZXIgYW5kIHRyYXZlcnNlIHBhcmVudCBwYXRoIGFnYWluLCB0aGlzIHRpbWUgdHJlYXRpbmcgdGhlIGV4Y2VwdGlvblxuICAvLyBhcyBhbiBlcnJvci5cblxuICB2YXIgd29ya0luUHJvZ3Jlc3MgPSByZXR1cm5GaWJlcjtcblxuICBkbyB7XG4gICAgc3dpdGNoICh3b3JrSW5Qcm9ncmVzcy50YWcpIHtcbiAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgX2Vycm9ySW5mbyA9IHZhbHVlO1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFNob3VsZENhcHR1cmU7XG4gICAgICAgICAgdmFyIGxhbmUgPSBwaWNrQXJiaXRyYXJ5TGFuZShyb290UmVuZGVyTGFuZXMpO1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gbWVyZ2VMYW5lcyh3b3JrSW5Qcm9ncmVzcy5sYW5lcywgbGFuZSk7XG4gICAgICAgICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVJvb3RFcnJvclVwZGF0ZSh3b3JrSW5Qcm9ncmVzcywgX2Vycm9ySW5mbywgbGFuZSk7XG4gICAgICAgICAgZW5xdWV1ZUNhcHR1cmVkVXBkYXRlKHdvcmtJblByb2dyZXNzLCB1cGRhdGUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICAvLyBDYXB0dXJlIGFuZCByZXRyeVxuICAgICAgICB2YXIgZXJyb3JJbmZvID0gdmFsdWU7XG4gICAgICAgIHZhciBjdG9yID0gd29ya0luUHJvZ3Jlc3MudHlwZTtcbiAgICAgICAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuXG4gICAgICAgIGlmICgod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBEaWRDYXB0dXJlKSA9PT0gTm9GbGFncyAmJiAodHlwZW9mIGN0b3IuZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yID09PSAnZnVuY3Rpb24nIHx8IGluc3RhbmNlICE9PSBudWxsICYmIHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRDYXRjaCA9PT0gJ2Z1bmN0aW9uJyAmJiAhaXNBbHJlYWR5RmFpbGVkTGVnYWN5RXJyb3JCb3VuZGFyeShpbnN0YW5jZSkpKSB7XG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gU2hvdWxkQ2FwdHVyZTtcblxuICAgICAgICAgIHZhciBfbGFuZSA9IHBpY2tBcmJpdHJhcnlMYW5lKHJvb3RSZW5kZXJMYW5lcyk7XG5cbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IG1lcmdlTGFuZXMod29ya0luUHJvZ3Jlc3MubGFuZXMsIF9sYW5lKTsgLy8gU2NoZWR1bGUgdGhlIGVycm9yIGJvdW5kYXJ5IHRvIHJlLXJlbmRlciB1c2luZyB1cGRhdGVkIHN0YXRlXG5cbiAgICAgICAgICB2YXIgX3VwZGF0ZSA9IGNyZWF0ZUNsYXNzRXJyb3JVcGRhdGUod29ya0luUHJvZ3Jlc3MsIGVycm9ySW5mbywgX2xhbmUpO1xuXG4gICAgICAgICAgZW5xdWV1ZUNhcHR1cmVkVXBkYXRlKHdvcmtJblByb2dyZXNzLCBfdXBkYXRlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICB3b3JrSW5Qcm9ncmVzcyA9IHdvcmtJblByb2dyZXNzLnJldHVybjtcbiAgfSB3aGlsZSAod29ya0luUHJvZ3Jlc3MgIT09IG51bGwpO1xufVxuXG5mdW5jdGlvbiBnZXRTdXNwZW5kZWRDYWNoZSgpIHtcbiAge1xuICAgIHJldHVybiBudWxsO1xuICB9IC8vIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW4gYSBTdXNwZW5zZSBib3VuZGFyeSBzdXNwZW5kcy4gSXQgcmV0dXJucyB0aGVcbn1cblxudmFyIFJlYWN0Q3VycmVudE93bmVyJDEgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRPd25lcjtcbnZhciBkaWRSZWNlaXZlVXBkYXRlID0gZmFsc2U7XG52YXIgZGlkV2FybkFib3V0QmFkQ2xhc3M7XG52YXIgZGlkV2FybkFib3V0TW9kdWxlUGF0dGVybkNvbXBvbmVudDtcbnZhciBkaWRXYXJuQWJvdXRDb250ZXh0VHlwZU9uRnVuY3Rpb25Db21wb25lbnQ7XG52YXIgZGlkV2FybkFib3V0R2V0RGVyaXZlZFN0YXRlT25GdW5jdGlvbkNvbXBvbmVudDtcbnZhciBkaWRXYXJuQWJvdXRGdW5jdGlvblJlZnM7XG52YXIgZGlkV2FybkFib3V0UmVhc3NpZ25pbmdQcm9wcztcbnZhciBkaWRXYXJuQWJvdXRSZXZlYWxPcmRlcjtcbnZhciBkaWRXYXJuQWJvdXRUYWlsT3B0aW9ucztcblxue1xuICBkaWRXYXJuQWJvdXRCYWRDbGFzcyA9IHt9O1xuICBkaWRXYXJuQWJvdXRNb2R1bGVQYXR0ZXJuQ29tcG9uZW50ID0ge307XG4gIGRpZFdhcm5BYm91dENvbnRleHRUeXBlT25GdW5jdGlvbkNvbXBvbmVudCA9IHt9O1xuICBkaWRXYXJuQWJvdXRHZXREZXJpdmVkU3RhdGVPbkZ1bmN0aW9uQ29tcG9uZW50ID0ge307XG4gIGRpZFdhcm5BYm91dEZ1bmN0aW9uUmVmcyA9IHt9O1xuICBkaWRXYXJuQWJvdXRSZWFzc2lnbmluZ1Byb3BzID0gZmFsc2U7XG4gIGRpZFdhcm5BYm91dFJldmVhbE9yZGVyID0ge307XG4gIGRpZFdhcm5BYm91dFRhaWxPcHRpb25zID0ge307XG59XG5cbmZ1bmN0aW9uIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKSB7XG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgLy8gSWYgdGhpcyBpcyBhIGZyZXNoIG5ldyBjb21wb25lbnQgdGhhdCBoYXNuJ3QgYmVlbiByZW5kZXJlZCB5ZXQsIHdlXG4gICAgLy8gd29uJ3QgdXBkYXRlIGl0cyBjaGlsZCBzZXQgYnkgYXBwbHlpbmcgbWluaW1hbCBzaWRlLWVmZmVjdHMuIEluc3RlYWQsXG4gICAgLy8gd2Ugd2lsbCBhZGQgdGhlbSBhbGwgdG8gdGhlIGNoaWxkIGJlZm9yZSBpdCBnZXRzIHJlbmRlcmVkLiBUaGF0IG1lYW5zXG4gICAgLy8gd2UgY2FuIG9wdGltaXplIHRoaXMgcmVjb25jaWxpYXRpb24gcGFzcyBieSBub3QgdHJhY2tpbmcgc2lkZS1lZmZlY3RzLlxuICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gbW91bnRDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgbnVsbCwgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gSWYgdGhlIGN1cnJlbnQgY2hpbGQgaXMgdGhlIHNhbWUgYXMgdGhlIHdvcmsgaW4gcHJvZ3Jlc3MsIGl0IG1lYW5zIHRoYXRcbiAgICAvLyB3ZSBoYXZlbid0IHlldCBzdGFydGVkIGFueSB3b3JrIG9uIHRoZXNlIGNoaWxkcmVuLiBUaGVyZWZvcmUsIHdlIHVzZVxuICAgIC8vIHRoZSBjbG9uZSBhbGdvcml0aG0gdG8gY3JlYXRlIGEgY29weSBvZiBhbGwgdGhlIGN1cnJlbnQgY2hpbGRyZW4uXG4gICAgLy8gSWYgd2UgaGFkIGFueSBwcm9ncmVzc2VkIHdvcmsgYWxyZWFkeSwgdGhhdCBpcyBpbnZhbGlkIGF0IHRoaXMgcG9pbnQgc29cbiAgICAvLyBsZXQncyB0aHJvdyBpdCBvdXQuXG4gICAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSByZWNvbmNpbGVDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgY3VycmVudC5jaGlsZCwgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZm9yY2VVbm1vdW50Q3VycmVudEFuZFJlY29uY2lsZShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcykge1xuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGZvcmsgb2YgcmVjb25jaWxlQ2hpbGRyZW4uIEl0J3MgdXNlZCBpbiBjYXNlcyB3aGVyZSB3ZVxuICAvLyB3YW50IHRvIHJlY29uY2lsZSB3aXRob3V0IG1hdGNoaW5nIGFnYWluc3QgdGhlIGV4aXN0aW5nIHNldC4gVGhpcyBoYXMgdGhlXG4gIC8vIGVmZmVjdCBvZiBhbGwgY3VycmVudCBjaGlsZHJlbiBiZWluZyB1bm1vdW50ZWQ7IGV2ZW4gaWYgdGhlIHR5cGUgYW5kIGtleVxuICAvLyBhcmUgdGhlIHNhbWUsIHRoZSBvbGQgY2hpbGQgaXMgdW5tb3VudGVkIGFuZCBhIG5ldyBjaGlsZCBpcyBjcmVhdGVkLlxuICAvL1xuICAvLyBUbyBkbyB0aGlzLCB3ZSdyZSBnb2luZyB0byBnbyB0aHJvdWdoIHRoZSByZWNvbmNpbGUgYWxnb3JpdGhtIHR3aWNlLiBJblxuICAvLyB0aGUgZmlyc3QgcGFzcywgd2Ugc2NoZWR1bGUgYSBkZWxldGlvbiBmb3IgYWxsIHRoZSBjdXJyZW50IGNoaWxkcmVuIGJ5XG4gIC8vIHBhc3NpbmcgbnVsbC5cbiAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSByZWNvbmNpbGVDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgY3VycmVudC5jaGlsZCwgbnVsbCwgcmVuZGVyTGFuZXMpOyAvLyBJbiB0aGUgc2Vjb25kIHBhc3MsIHdlIG1vdW50IHRoZSBuZXcgY2hpbGRyZW4uIFRoZSB0cmljayBoZXJlIGlzIHRoYXQgd2VcbiAgLy8gcGFzcyBudWxsIGluIHBsYWNlIG9mIHdoZXJlIHdlIHVzdWFsbHkgcGFzcyB0aGUgY3VycmVudCBjaGlsZCBzZXQuIFRoaXMgaGFzXG4gIC8vIHRoZSBlZmZlY3Qgb2YgcmVtb3VudGluZyBhbGwgY2hpbGRyZW4gcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZWlyXG4gIC8vIGlkZW50aXRpZXMgbWF0Y2guXG5cbiAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSByZWNvbmNpbGVDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgbnVsbCwgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUZvcndhcmRSZWYoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCByZW5kZXJMYW5lcykge1xuICAvLyBUT0RPOiBjdXJyZW50IGNhbiBiZSBub24tbnVsbCBoZXJlIGV2ZW4gaWYgdGhlIGNvbXBvbmVudFxuICAvLyBoYXNuJ3QgeWV0IG1vdW50ZWQuIFRoaXMgaGFwcGVucyBhZnRlciB0aGUgZmlyc3QgcmVuZGVyIHN1c3BlbmRzLlxuICAvLyBXZSdsbCBuZWVkIHRvIGZpZ3VyZSBvdXQgaWYgdGhpcyBpcyBmaW5lIG9yIGNhbiBjYXVzZSBpc3N1ZXMuXG4gIHtcbiAgICBpZiAod29ya0luUHJvZ3Jlc3MudHlwZSAhPT0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGUpIHtcbiAgICAgIC8vIExhenkgY29tcG9uZW50IHByb3BzIGNhbid0IGJlIHZhbGlkYXRlZCBpbiBjcmVhdGVFbGVtZW50XG4gICAgICAvLyBiZWNhdXNlIHRoZXkncmUgb25seSBndWFyYW50ZWVkIHRvIGJlIHJlc29sdmVkIGhlcmUuXG4gICAgICB2YXIgaW5uZXJQcm9wVHlwZXMgPSBDb21wb25lbnQucHJvcFR5cGVzO1xuXG4gICAgICBpZiAoaW5uZXJQcm9wVHlwZXMpIHtcbiAgICAgICAgY2hlY2tQcm9wVHlwZXMoaW5uZXJQcm9wVHlwZXMsIG5leHRQcm9wcywgLy8gUmVzb2x2ZWQgcHJvcHNcbiAgICAgICAgJ3Byb3AnLCBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoQ29tcG9uZW50KSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHJlbmRlciA9IENvbXBvbmVudC5yZW5kZXI7XG4gIHZhciByZWYgPSB3b3JrSW5Qcm9ncmVzcy5yZWY7IC8vIFRoZSByZXN0IGlzIGEgZm9yayBvZiB1cGRhdGVGdW5jdGlvbkNvbXBvbmVudFxuXG4gIHZhciBuZXh0Q2hpbGRyZW47XG4gIHZhciBoYXNJZDtcbiAgcHJlcGFyZVRvUmVhZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcblxuICB7XG4gICAgbWFya0NvbXBvbmVudFJlbmRlclN0YXJ0ZWQod29ya0luUHJvZ3Jlc3MpO1xuICB9XG5cbiAge1xuICAgIFJlYWN0Q3VycmVudE93bmVyJDEuY3VycmVudCA9IHdvcmtJblByb2dyZXNzO1xuICAgIHNldElzUmVuZGVyaW5nKHRydWUpO1xuICAgIG5leHRDaGlsZHJlbiA9IHJlbmRlcldpdGhIb29rcyhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyLCBuZXh0UHJvcHMsIHJlZiwgcmVuZGVyTGFuZXMpO1xuICAgIGhhc0lkID0gY2hlY2tEaWRSZW5kZXJJZEhvb2soKTtcblxuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBuZXh0Q2hpbGRyZW4gPSByZW5kZXJXaXRoSG9va3MoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlciwgbmV4dFByb3BzLCByZWYsIHJlbmRlckxhbmVzKTtcbiAgICAgICAgaGFzSWQgPSBjaGVja0RpZFJlbmRlcklkSG9vaygpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMoZmFsc2UpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHNldElzUmVuZGVyaW5nKGZhbHNlKTtcbiAgfVxuXG4gIHtcbiAgICBtYXJrQ29tcG9uZW50UmVuZGVyU3RvcHBlZCgpO1xuICB9XG5cbiAgaWYgKGN1cnJlbnQgIT09IG51bGwgJiYgIWRpZFJlY2VpdmVVcGRhdGUpIHtcbiAgICBiYWlsb3V0SG9va3MoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICB9XG5cbiAgaWYgKGdldElzSHlkcmF0aW5nKCkgJiYgaGFzSWQpIHtcbiAgICBwdXNoTWF0ZXJpYWxpemVkVHJlZUlkKHdvcmtJblByb2dyZXNzKTtcbiAgfSAvLyBSZWFjdCBEZXZUb29scyByZWFkcyB0aGlzIGZsYWcuXG5cblxuICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBQZXJmb3JtZWRXb3JrO1xuICByZWNvbmNpbGVDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxuZnVuY3Rpb24gdXBkYXRlTWVtb0NvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBuZXh0UHJvcHMsIHJlbmRlckxhbmVzKSB7XG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgdmFyIHR5cGUgPSBDb21wb25lbnQudHlwZTtcblxuICAgIGlmIChpc1NpbXBsZUZ1bmN0aW9uQ29tcG9uZW50KHR5cGUpICYmIENvbXBvbmVudC5jb21wYXJlID09PSBudWxsICYmIC8vIFNpbXBsZU1lbW9Db21wb25lbnQgY29kZXBhdGggZG9lc24ndCByZXNvbHZlIG91dGVyIHByb3BzIGVpdGhlci5cbiAgICBDb21wb25lbnQuZGVmYXVsdFByb3BzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhciByZXNvbHZlZFR5cGUgPSB0eXBlO1xuXG4gICAgICB7XG4gICAgICAgIHJlc29sdmVkVHlwZSA9IHJlc29sdmVGdW5jdGlvbkZvckhvdFJlbG9hZGluZyh0eXBlKTtcbiAgICAgIH0gLy8gSWYgdGhpcyBpcyBhIHBsYWluIGZ1bmN0aW9uIGNvbXBvbmVudCB3aXRob3V0IGRlZmF1bHQgcHJvcHMsXG4gICAgICAvLyBhbmQgd2l0aCBvbmx5IHRoZSBkZWZhdWx0IHNoYWxsb3cgY29tcGFyaXNvbiwgd2UgdXBncmFkZSBpdFxuICAgICAgLy8gdG8gYSBTaW1wbGVNZW1vQ29tcG9uZW50IHRvIGFsbG93IGZhc3QgcGF0aCB1cGRhdGVzLlxuXG5cbiAgICAgIHdvcmtJblByb2dyZXNzLnRhZyA9IFNpbXBsZU1lbW9Db21wb25lbnQ7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy50eXBlID0gcmVzb2x2ZWRUeXBlO1xuXG4gICAgICB7XG4gICAgICAgIHZhbGlkYXRlRnVuY3Rpb25Db21wb25lbnRJbkRldih3b3JrSW5Qcm9ncmVzcywgdHlwZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB1cGRhdGVTaW1wbGVNZW1vQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZXNvbHZlZFR5cGUsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpO1xuICAgIH1cblxuICAgIHtcbiAgICAgIHZhciBpbm5lclByb3BUeXBlcyA9IHR5cGUucHJvcFR5cGVzO1xuXG4gICAgICBpZiAoaW5uZXJQcm9wVHlwZXMpIHtcbiAgICAgICAgLy8gSW5uZXIgbWVtbyBjb21wb25lbnQgcHJvcHMgYXJlbid0IGN1cnJlbnRseSB2YWxpZGF0ZWQgaW4gY3JlYXRlRWxlbWVudC5cbiAgICAgICAgLy8gV2UgY291bGQgbW92ZSBpdCB0aGVyZSwgYnV0IHdlJ2Qgc3RpbGwgbmVlZCB0aGlzIGZvciBsYXp5IGNvZGUgcGF0aC5cbiAgICAgICAgY2hlY2tQcm9wVHlwZXMoaW5uZXJQcm9wVHlwZXMsIG5leHRQcm9wcywgLy8gUmVzb2x2ZWQgcHJvcHNcbiAgICAgICAgJ3Byb3AnLCBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBjaGlsZCA9IGNyZWF0ZUZpYmVyRnJvbVR5cGVBbmRQcm9wcyhDb21wb25lbnQudHlwZSwgbnVsbCwgbmV4dFByb3BzLCB3b3JrSW5Qcm9ncmVzcywgd29ya0luUHJvZ3Jlc3MubW9kZSwgcmVuZGVyTGFuZXMpO1xuICAgIGNoaWxkLnJlZiA9IHdvcmtJblByb2dyZXNzLnJlZjtcbiAgICBjaGlsZC5yZXR1cm4gPSB3b3JrSW5Qcm9ncmVzcztcbiAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IGNoaWxkO1xuICAgIHJldHVybiBjaGlsZDtcbiAgfVxuXG4gIHtcbiAgICB2YXIgX3R5cGUgPSBDb21wb25lbnQudHlwZTtcbiAgICB2YXIgX2lubmVyUHJvcFR5cGVzID0gX3R5cGUucHJvcFR5cGVzO1xuXG4gICAgaWYgKF9pbm5lclByb3BUeXBlcykge1xuICAgICAgLy8gSW5uZXIgbWVtbyBjb21wb25lbnQgcHJvcHMgYXJlbid0IGN1cnJlbnRseSB2YWxpZGF0ZWQgaW4gY3JlYXRlRWxlbWVudC5cbiAgICAgIC8vIFdlIGNvdWxkIG1vdmUgaXQgdGhlcmUsIGJ1dCB3ZSdkIHN0aWxsIG5lZWQgdGhpcyBmb3IgbGF6eSBjb2RlIHBhdGguXG4gICAgICBjaGVja1Byb3BUeXBlcyhfaW5uZXJQcm9wVHlwZXMsIG5leHRQcm9wcywgLy8gUmVzb2x2ZWQgcHJvcHNcbiAgICAgICdwcm9wJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKF90eXBlKSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGN1cnJlbnRDaGlsZCA9IGN1cnJlbnQuY2hpbGQ7IC8vIFRoaXMgaXMgYWx3YXlzIGV4YWN0bHkgb25lIGNoaWxkXG5cbiAgdmFyIGhhc1NjaGVkdWxlZFVwZGF0ZU9yQ29udGV4dCA9IGNoZWNrU2NoZWR1bGVkVXBkYXRlT3JDb250ZXh0KGN1cnJlbnQsIHJlbmRlckxhbmVzKTtcblxuICBpZiAoIWhhc1NjaGVkdWxlZFVwZGF0ZU9yQ29udGV4dCkge1xuICAgIC8vIFRoaXMgd2lsbCBiZSB0aGUgcHJvcHMgd2l0aCByZXNvbHZlZCBkZWZhdWx0UHJvcHMsXG4gICAgLy8gdW5saWtlIGN1cnJlbnQubWVtb2l6ZWRQcm9wcyB3aGljaCB3aWxsIGJlIHRoZSB1bnJlc29sdmVkIG9uZXMuXG4gICAgdmFyIHByZXZQcm9wcyA9IGN1cnJlbnRDaGlsZC5tZW1vaXplZFByb3BzOyAvLyBEZWZhdWx0IHRvIHNoYWxsb3cgY29tcGFyaXNvblxuXG4gICAgdmFyIGNvbXBhcmUgPSBDb21wb25lbnQuY29tcGFyZTtcbiAgICBjb21wYXJlID0gY29tcGFyZSAhPT0gbnVsbCA/IGNvbXBhcmUgOiBzaGFsbG93RXF1YWw7XG5cbiAgICBpZiAoY29tcGFyZShwcmV2UHJvcHMsIG5leHRQcm9wcykgJiYgY3VycmVudC5yZWYgPT09IHdvcmtJblByb2dyZXNzLnJlZikge1xuICAgICAgcmV0dXJuIGJhaWxvdXRPbkFscmVhZHlGaW5pc2hlZFdvcmsoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgICB9XG4gIH0gLy8gUmVhY3QgRGV2VG9vbHMgcmVhZHMgdGhpcyBmbGFnLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUGVyZm9ybWVkV29yaztcbiAgdmFyIG5ld0NoaWxkID0gY3JlYXRlV29ya0luUHJvZ3Jlc3MoY3VycmVudENoaWxkLCBuZXh0UHJvcHMpO1xuICBuZXdDaGlsZC5yZWYgPSB3b3JrSW5Qcm9ncmVzcy5yZWY7XG4gIG5ld0NoaWxkLnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IG5ld0NoaWxkO1xuICByZXR1cm4gbmV3Q2hpbGQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVNpbXBsZU1lbW9Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCByZW5kZXJMYW5lcykge1xuICAvLyBUT0RPOiBjdXJyZW50IGNhbiBiZSBub24tbnVsbCBoZXJlIGV2ZW4gaWYgdGhlIGNvbXBvbmVudFxuICAvLyBoYXNuJ3QgeWV0IG1vdW50ZWQuIFRoaXMgaGFwcGVucyB3aGVuIHRoZSBpbm5lciByZW5kZXIgc3VzcGVuZHMuXG4gIC8vIFdlJ2xsIG5lZWQgdG8gZmlndXJlIG91dCBpZiB0aGlzIGlzIGZpbmUgb3IgY2FuIGNhdXNlIGlzc3Vlcy5cbiAge1xuICAgIGlmICh3b3JrSW5Qcm9ncmVzcy50eXBlICE9PSB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZSkge1xuICAgICAgLy8gTGF6eSBjb21wb25lbnQgcHJvcHMgY2FuJ3QgYmUgdmFsaWRhdGVkIGluIGNyZWF0ZUVsZW1lbnRcbiAgICAgIC8vIGJlY2F1c2UgdGhleSdyZSBvbmx5IGd1YXJhbnRlZWQgdG8gYmUgcmVzb2x2ZWQgaGVyZS5cbiAgICAgIHZhciBvdXRlck1lbW9UeXBlID0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGU7XG5cbiAgICAgIGlmIChvdXRlck1lbW9UeXBlLiQkdHlwZW9mID09PSBSRUFDVF9MQVpZX1RZUEUpIHtcbiAgICAgICAgLy8gV2Ugd2FybiB3aGVuIHlvdSBkZWZpbmUgcHJvcFR5cGVzIG9uIGxhenkoKVxuICAgICAgICAvLyBzbyBsZXQncyBqdXN0IHNraXAgb3ZlciBpdCB0byBmaW5kIG1lbW8oKSBvdXRlciB3cmFwcGVyLlxuICAgICAgICAvLyBJbm5lciBwcm9wcyBmb3IgbWVtbyBhcmUgdmFsaWRhdGVkIGxhdGVyLlxuICAgICAgICB2YXIgbGF6eUNvbXBvbmVudCA9IG91dGVyTWVtb1R5cGU7XG4gICAgICAgIHZhciBwYXlsb2FkID0gbGF6eUNvbXBvbmVudC5fcGF5bG9hZDtcbiAgICAgICAgdmFyIGluaXQgPSBsYXp5Q29tcG9uZW50Ll9pbml0O1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgb3V0ZXJNZW1vVHlwZSA9IGluaXQocGF5bG9hZCk7XG4gICAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgICBvdXRlck1lbW9UeXBlID0gbnVsbDtcbiAgICAgICAgfSAvLyBJbm5lciBwcm9wVHlwZXMgd2lsbCBiZSB2YWxpZGF0ZWQgaW4gdGhlIGZ1bmN0aW9uIGNvbXBvbmVudCBwYXRoLlxuXG5cbiAgICAgICAgdmFyIG91dGVyUHJvcFR5cGVzID0gb3V0ZXJNZW1vVHlwZSAmJiBvdXRlck1lbW9UeXBlLnByb3BUeXBlcztcblxuICAgICAgICBpZiAob3V0ZXJQcm9wVHlwZXMpIHtcbiAgICAgICAgICBjaGVja1Byb3BUeXBlcyhvdXRlclByb3BUeXBlcywgbmV4dFByb3BzLCAvLyBSZXNvbHZlZCAoU2ltcGxlTWVtb0NvbXBvbmVudCBoYXMgbm8gZGVmYXVsdFByb3BzKVxuICAgICAgICAgICdwcm9wJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKG91dGVyTWVtb1R5cGUpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgdmFyIHByZXZQcm9wcyA9IGN1cnJlbnQubWVtb2l6ZWRQcm9wcztcblxuICAgIGlmIChzaGFsbG93RXF1YWwocHJldlByb3BzLCBuZXh0UHJvcHMpICYmIGN1cnJlbnQucmVmID09PSB3b3JrSW5Qcm9ncmVzcy5yZWYgJiYgKCAvLyBQcmV2ZW50IGJhaWxvdXQgaWYgdGhlIGltcGxlbWVudGF0aW9uIGNoYW5nZWQgZHVlIHRvIGhvdCByZWxvYWQuXG4gICAgIHdvcmtJblByb2dyZXNzLnR5cGUgPT09IGN1cnJlbnQudHlwZSApKSB7XG4gICAgICBkaWRSZWNlaXZlVXBkYXRlID0gZmFsc2U7IC8vIFRoZSBwcm9wcyBhcmUgc2hhbGxvd2x5IGVxdWFsLiBSZXVzZSB0aGUgcHJldmlvdXMgcHJvcHMgb2JqZWN0LCBsaWtlIHdlXG4gICAgICAvLyB3b3VsZCBkdXJpbmcgYSBub3JtYWwgZmliZXIgYmFpbG91dC5cbiAgICAgIC8vXG4gICAgICAvLyBXZSBkb24ndCBoYXZlIHN0cm9uZyBndWFyYW50ZWVzIHRoYXQgdGhlIHByb3BzIG9iamVjdCBpcyByZWZlcmVudGlhbGx5XG4gICAgICAvLyBlcXVhbCBkdXJpbmcgdXBkYXRlcyB3aGVyZSB3ZSBjYW4ndCBiYWlsIG91dCBhbnl3YXkg4oCUIGxpa2UgaWYgdGhlIHByb3BzXG4gICAgICAvLyBhcmUgc2hhbGxvd2x5IGVxdWFsLCBidXQgdGhlcmUncyBhIGxvY2FsIHN0YXRlIG9yIGNvbnRleHQgdXBkYXRlIGluIHRoZVxuICAgICAgLy8gc2FtZSBiYXRjaC5cbiAgICAgIC8vXG4gICAgICAvLyBIb3dldmVyLCBhcyBhIHByaW5jaXBsZSwgd2Ugc2hvdWxkIGFpbSB0byBtYWtlIHRoZSBiZWhhdmlvciBjb25zaXN0ZW50XG4gICAgICAvLyBhY3Jvc3MgZGlmZmVyZW50IHdheXMgb2YgbWVtb2l6aW5nIGEgY29tcG9uZW50LiBGb3IgZXhhbXBsZSwgUmVhY3QubWVtb1xuICAgICAgLy8gaGFzIGEgZGlmZmVyZW50IGludGVybmFsIEZpYmVyIGxheW91dCBpZiB5b3UgcGFzcyBhIG5vcm1hbCBmdW5jdGlvblxuICAgICAgLy8gY29tcG9uZW50IChTaW1wbGVNZW1vQ29tcG9uZW50KSB2ZXJzdXMgaWYgeW91IHBhc3MgYSBkaWZmZXJlbnQgdHlwZVxuICAgICAgLy8gbGlrZSBmb3J3YXJkUmVmIChNZW1vQ29tcG9uZW50KS4gQnV0IHRoaXMgaXMgYW4gaW1wbGVtZW50YXRpb24gZGV0YWlsLlxuICAgICAgLy8gV3JhcHBpbmcgYSBjb21wb25lbnQgaW4gZm9yd2FyZFJlZiAob3IgUmVhY3QubGF6eSwgZXRjKSBzaG91bGRuJ3RcbiAgICAgIC8vIGFmZmVjdCB3aGV0aGVyIHRoZSBwcm9wcyBvYmplY3QgaXMgcmV1c2VkIGR1cmluZyBhIGJhaWxvdXQuXG5cbiAgICAgIHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcyA9IG5leHRQcm9wcyA9IHByZXZQcm9wcztcblxuICAgICAgaWYgKCFjaGVja1NjaGVkdWxlZFVwZGF0ZU9yQ29udGV4dChjdXJyZW50LCByZW5kZXJMYW5lcykpIHtcbiAgICAgICAgLy8gVGhlIHBlbmRpbmcgbGFuZXMgd2VyZSBjbGVhcmVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgYmVnaW5Xb3JrLiBXZSdyZVxuICAgICAgICAvLyBhYm91dCB0byBiYWlsIG91dCwgYnV0IHRoZXJlIG1pZ2h0IGJlIG90aGVyIGxhbmVzIHRoYXQgd2VyZW4ndFxuICAgICAgICAvLyBpbmNsdWRlZCBpbiB0aGUgY3VycmVudCByZW5kZXIuIFVzdWFsbHksIHRoZSBwcmlvcml0eSBsZXZlbCBvZiB0aGVcbiAgICAgICAgLy8gcmVtYWluaW5nIHVwZGF0ZXMgaXMgYWNjdW11bGF0ZWQgZHVyaW5nIHRoZSBldmFsdWF0aW9uIG9mIHRoZVxuICAgICAgICAvLyBjb21wb25lbnQgKGkuZS4gd2hlbiBwcm9jZXNzaW5nIHRoZSB1cGRhdGUgcXVldWUpLiBCdXQgc2luY2Ugc2luY2VcbiAgICAgICAgLy8gd2UncmUgYmFpbGluZyBvdXQgZWFybHkgKndpdGhvdXQqIGV2YWx1YXRpbmcgdGhlIGNvbXBvbmVudCwgd2UgbmVlZFxuICAgICAgICAvLyB0byBhY2NvdW50IGZvciBpdCBoZXJlLCB0b28uIFJlc2V0IHRvIHRoZSB2YWx1ZSBvZiB0aGUgY3VycmVudCBmaWJlci5cbiAgICAgICAgLy8gTk9URTogVGhpcyBvbmx5IGFwcGxpZXMgdG8gU2ltcGxlTWVtb0NvbXBvbmVudCwgbm90IE1lbW9Db21wb25lbnQsXG4gICAgICAgIC8vIGJlY2F1c2UgYSBNZW1vQ29tcG9uZW50IGZpYmVyIGRvZXMgbm90IGhhdmUgaG9va3Mgb3IgYW4gdXBkYXRlIHF1ZXVlO1xuICAgICAgICAvLyByYXRoZXIsIGl0IHdyYXBzIGFyb3VuZCBhbiBpbm5lciBjb21wb25lbnQsIHdoaWNoIG1heSBvciBtYXkgbm90XG4gICAgICAgIC8vIGNvbnRhaW5zIGhvb2tzLlxuICAgICAgICAvLyBUT0RPOiBNb3ZlIHRoZSByZXNldCBhdCBpbiBiZWdpbldvcmsgb3V0IG9mIHRoZSBjb21tb24gcGF0aCBzbyB0aGF0XG4gICAgICAgIC8vIHRoaXMgaXMgbm8gbG9uZ2VyIG5lY2Vzc2FyeS5cbiAgICAgICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBjdXJyZW50LmxhbmVzO1xuICAgICAgICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgICAgfSBlbHNlIGlmICgoY3VycmVudC5mbGFncyAmIEZvcmNlVXBkYXRlRm9yTGVnYWN5U3VzcGVuc2UpICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgIC8vIFRoaXMgaXMgYSBzcGVjaWFsIGNhc2UgdGhhdCBvbmx5IGV4aXN0cyBmb3IgbGVnYWN5IG1vZGUuXG4gICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvcHVsbC8xOTIxNi5cbiAgICAgICAgZGlkUmVjZWl2ZVVwZGF0ZSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVwZGF0ZUZ1bmN0aW9uQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVPZmZzY3JlZW5Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBuZXh0UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciBuZXh0Q2hpbGRyZW4gPSBuZXh0UHJvcHMuY2hpbGRyZW47XG4gIHZhciBwcmV2U3RhdGUgPSBjdXJyZW50ICE9PSBudWxsID8gY3VycmVudC5tZW1vaXplZFN0YXRlIDogbnVsbDtcblxuICBpZiAobmV4dFByb3BzLm1vZGUgPT09ICdoaWRkZW4nIHx8IGVuYWJsZUxlZ2FjeUhpZGRlbiApIHtcbiAgICAvLyBSZW5kZXJpbmcgYSBoaWRkZW4gdHJlZS5cbiAgICBpZiAoKHdvcmtJblByb2dyZXNzLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgPT09IE5vTW9kZSkge1xuICAgICAgLy8gSW4gbGVnYWN5IHN5bmMgbW9kZSwgZG9uJ3QgZGVmZXIgdGhlIHN1YnRyZWUuIFJlbmRlciBpdCBub3cuXG4gICAgICAvLyBUT0RPOiBDb25zaWRlciBob3cgT2Zmc2NyZWVuIHNob3VsZCB3b3JrIHdpdGggdHJhbnNpdGlvbnMgaW4gdGhlIGZ1dHVyZVxuICAgICAgdmFyIG5leHRTdGF0ZSA9IHtcbiAgICAgICAgYmFzZUxhbmVzOiBOb0xhbmVzLFxuICAgICAgICBjYWNoZVBvb2w6IG51bGwsXG4gICAgICAgIHRyYW5zaXRpb25zOiBudWxsXG4gICAgICB9O1xuICAgICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG5leHRTdGF0ZTtcblxuICAgICAgcHVzaFJlbmRlckxhbmVzKHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgfSBlbHNlIGlmICghaW5jbHVkZXNTb21lTGFuZShyZW5kZXJMYW5lcywgT2Zmc2NyZWVuTGFuZSkpIHtcbiAgICAgIHZhciBzcGF3bmVkQ2FjaGVQb29sID0gbnVsbDsgLy8gV2UncmUgaGlkZGVuLCBhbmQgd2UncmUgbm90IHJlbmRlcmluZyBhdCBPZmZzY3JlZW4uIFdlIHdpbGwgYmFpbCBvdXRcbiAgICAgIC8vIGFuZCByZXN1bWUgdGhpcyB0cmVlIGxhdGVyLlxuXG4gICAgICB2YXIgbmV4dEJhc2VMYW5lcztcblxuICAgICAgaWYgKHByZXZTdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICB2YXIgcHJldkJhc2VMYW5lcyA9IHByZXZTdGF0ZS5iYXNlTGFuZXM7XG4gICAgICAgIG5leHRCYXNlTGFuZXMgPSBtZXJnZUxhbmVzKHByZXZCYXNlTGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHRCYXNlTGFuZXMgPSByZW5kZXJMYW5lcztcbiAgICAgIH0gLy8gU2NoZWR1bGUgdGhpcyBmaWJlciB0byByZS1yZW5kZXIgYXQgb2Zmc2NyZWVuIHByaW9yaXR5LiBUaGVuIGJhaWxvdXQuXG5cblxuICAgICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZExhbmVzID0gbGFuZVRvTGFuZXMoT2Zmc2NyZWVuTGFuZSk7XG4gICAgICB2YXIgX25leHRTdGF0ZSA9IHtcbiAgICAgICAgYmFzZUxhbmVzOiBuZXh0QmFzZUxhbmVzLFxuICAgICAgICBjYWNoZVBvb2w6IHNwYXduZWRDYWNoZVBvb2wsXG4gICAgICAgIHRyYW5zaXRpb25zOiBudWxsXG4gICAgICB9O1xuICAgICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IF9uZXh0U3RhdGU7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZSA9IG51bGw7XG4gICAgICAvLyB0byBhdm9pZCBhIHB1c2gvcG9wIG1pc2FsaWdubWVudC5cblxuXG4gICAgICBwdXNoUmVuZGVyTGFuZXMod29ya0luUHJvZ3Jlc3MsIG5leHRCYXNlTGFuZXMpO1xuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhpcyBpcyB0aGUgc2Vjb25kIHJlbmRlci4gVGhlIHN1cnJvdW5kaW5nIHZpc2libGUgY29udGVudCBoYXMgYWxyZWFkeVxuICAgICAgLy8gY29tbWl0dGVkLiBOb3cgd2UgcmVzdW1lIHJlbmRlcmluZyB0aGUgaGlkZGVuIHRyZWUuXG4gICAgICAvLyBSZW5kZXJpbmcgYXQgb2Zmc2NyZWVuLCBzbyB3ZSBjYW4gY2xlYXIgdGhlIGJhc2UgbGFuZXMuXG4gICAgICB2YXIgX25leHRTdGF0ZTIgPSB7XG4gICAgICAgIGJhc2VMYW5lczogTm9MYW5lcyxcbiAgICAgICAgY2FjaGVQb29sOiBudWxsLFxuICAgICAgICB0cmFuc2l0aW9uczogbnVsbFxuICAgICAgfTtcbiAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBfbmV4dFN0YXRlMjsgLy8gUHVzaCB0aGUgbGFuZXMgdGhhdCB3ZXJlIHNraXBwZWQgd2hlbiB3ZSBiYWlsZWQgb3V0LlxuXG4gICAgICB2YXIgc3VidHJlZVJlbmRlckxhbmVzID0gcHJldlN0YXRlICE9PSBudWxsID8gcHJldlN0YXRlLmJhc2VMYW5lcyA6IHJlbmRlckxhbmVzO1xuXG4gICAgICBwdXNoUmVuZGVyTGFuZXMod29ya0luUHJvZ3Jlc3MsIHN1YnRyZWVSZW5kZXJMYW5lcyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFJlbmRlcmluZyBhIHZpc2libGUgdHJlZS5cbiAgICB2YXIgX3N1YnRyZWVSZW5kZXJMYW5lcztcblxuICAgIGlmIChwcmV2U3RhdGUgIT09IG51bGwpIHtcbiAgICAgIC8vIFdlJ3JlIGdvaW5nIGZyb20gaGlkZGVuIC0+IHZpc2libGUuXG4gICAgICBfc3VidHJlZVJlbmRlckxhbmVzID0gbWVyZ2VMYW5lcyhwcmV2U3RhdGUuYmFzZUxhbmVzLCByZW5kZXJMYW5lcyk7XG5cbiAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBXZSB3ZXJlbid0IHByZXZpb3VzbHkgaGlkZGVuLCBhbmQgd2Ugc3RpbGwgYXJlbid0LCBzbyB0aGVyZSdzIG5vdGhpbmdcbiAgICAgIC8vIHNwZWNpYWwgdG8gZG8uIE5lZWQgdG8gcHVzaCB0byB0aGUgc3RhY2sgcmVnYXJkbGVzcywgdGhvdWdoLCB0byBhdm9pZFxuICAgICAgLy8gYSBwdXNoL3BvcCBtaXNhbGlnbm1lbnQuXG4gICAgICBfc3VidHJlZVJlbmRlckxhbmVzID0gcmVuZGVyTGFuZXM7XG4gICAgfVxuXG4gICAgcHVzaFJlbmRlckxhbmVzKHdvcmtJblByb2dyZXNzLCBfc3VidHJlZVJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufSAvLyBOb3RlOiBUaGVzZSBoYXBwZW4gdG8gaGF2ZSBpZGVudGljYWwgYmVnaW4gcGhhc2VzLCBmb3Igbm93LiBXZSBzaG91bGRuJ3QgaG9sZFxuXG5mdW5jdGlvbiB1cGRhdGVGcmFnbWVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIG5leHRDaGlsZHJlbiA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcztcbiAgcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMpO1xuICByZXR1cm4gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZU1vZGUoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBuZXh0Q2hpbGRyZW4gPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHMuY2hpbGRyZW47XG4gIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVQcm9maWxlcihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAge1xuICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFVwZGF0ZTtcblxuICAgIHtcbiAgICAgIC8vIFJlc2V0IGVmZmVjdCBkdXJhdGlvbnMgZm9yIHRoZSBuZXh0IGV2ZW50dWFsIGVmZmVjdCBwaGFzZS5cbiAgICAgIC8vIFRoZXNlIGFyZSByZXNldCBkdXJpbmcgcmVuZGVyIHRvIGFsbG93IHRoZSBEZXZUb29scyBjb21taXQgaG9vayBhIGNoYW5jZSB0byByZWFkIHRoZW0sXG4gICAgICB2YXIgc3RhdGVOb2RlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICAgICAgc3RhdGVOb2RlLmVmZmVjdER1cmF0aW9uID0gMDtcbiAgICAgIHN0YXRlTm9kZS5wYXNzaXZlRWZmZWN0RHVyYXRpb24gPSAwO1xuICAgIH1cbiAgfVxuXG4gIHZhciBuZXh0UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciBuZXh0Q2hpbGRyZW4gPSBuZXh0UHJvcHMuY2hpbGRyZW47XG4gIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiBtYXJrUmVmKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKSB7XG4gIHZhciByZWYgPSB3b3JrSW5Qcm9ncmVzcy5yZWY7XG5cbiAgaWYgKGN1cnJlbnQgPT09IG51bGwgJiYgcmVmICE9PSBudWxsIHx8IGN1cnJlbnQgIT09IG51bGwgJiYgY3VycmVudC5yZWYgIT09IHJlZikge1xuICAgIC8vIFNjaGVkdWxlIGEgUmVmIGVmZmVjdFxuICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFJlZjtcblxuICAgIHtcbiAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFJlZlN0YXRpYztcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlRnVuY3Rpb25Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCByZW5kZXJMYW5lcykge1xuICB7XG4gICAgaWYgKHdvcmtJblByb2dyZXNzLnR5cGUgIT09IHdvcmtJblByb2dyZXNzLmVsZW1lbnRUeXBlKSB7XG4gICAgICAvLyBMYXp5IGNvbXBvbmVudCBwcm9wcyBjYW4ndCBiZSB2YWxpZGF0ZWQgaW4gY3JlYXRlRWxlbWVudFxuICAgICAgLy8gYmVjYXVzZSB0aGV5J3JlIG9ubHkgZ3VhcmFudGVlZCB0byBiZSByZXNvbHZlZCBoZXJlLlxuICAgICAgdmFyIGlubmVyUHJvcFR5cGVzID0gQ29tcG9uZW50LnByb3BUeXBlcztcblxuICAgICAgaWYgKGlubmVyUHJvcFR5cGVzKSB7XG4gICAgICAgIGNoZWNrUHJvcFR5cGVzKGlubmVyUHJvcFR5cGVzLCBuZXh0UHJvcHMsIC8vIFJlc29sdmVkIHByb3BzXG4gICAgICAgICdwcm9wJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKENvbXBvbmVudCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciBjb250ZXh0O1xuXG4gIHtcbiAgICB2YXIgdW5tYXNrZWRDb250ZXh0ID0gZ2V0VW5tYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHRydWUpO1xuICAgIGNvbnRleHQgPSBnZXRNYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCB1bm1hc2tlZENvbnRleHQpO1xuICB9XG5cbiAgdmFyIG5leHRDaGlsZHJlbjtcbiAgdmFyIGhhc0lkO1xuICBwcmVwYXJlVG9SZWFkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuXG4gIHtcbiAgICBtYXJrQ29tcG9uZW50UmVuZGVyU3RhcnRlZCh3b3JrSW5Qcm9ncmVzcyk7XG4gIH1cblxuICB7XG4gICAgUmVhY3RDdXJyZW50T3duZXIkMS5jdXJyZW50ID0gd29ya0luUHJvZ3Jlc3M7XG4gICAgc2V0SXNSZW5kZXJpbmcodHJ1ZSk7XG4gICAgbmV4dENoaWxkcmVuID0gcmVuZGVyV2l0aEhvb2tzKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgY29udGV4dCwgcmVuZGVyTGFuZXMpO1xuICAgIGhhc0lkID0gY2hlY2tEaWRSZW5kZXJJZEhvb2soKTtcblxuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBuZXh0Q2hpbGRyZW4gPSByZW5kZXJXaXRoSG9va3MoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCBjb250ZXh0LCByZW5kZXJMYW5lcyk7XG4gICAgICAgIGhhc0lkID0gY2hlY2tEaWRSZW5kZXJJZEhvb2soKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRJc1JlbmRlcmluZyhmYWxzZSk7XG4gIH1cblxuICB7XG4gICAgbWFya0NvbXBvbmVudFJlbmRlclN0b3BwZWQoKTtcbiAgfVxuXG4gIGlmIChjdXJyZW50ICE9PSBudWxsICYmICFkaWRSZWNlaXZlVXBkYXRlKSB7XG4gICAgYmFpbG91dEhvb2tzKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgcmV0dXJuIGJhaWxvdXRPbkFscmVhZHlGaW5pc2hlZFdvcmsoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIGlmIChnZXRJc0h5ZHJhdGluZygpICYmIGhhc0lkKSB7XG4gICAgcHVzaE1hdGVyaWFsaXplZFRyZWVJZCh3b3JrSW5Qcm9ncmVzcyk7XG4gIH0gLy8gUmVhY3QgRGV2VG9vbHMgcmVhZHMgdGhpcyBmbGFnLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUGVyZm9ybWVkV29yaztcbiAgcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMpO1xuICByZXR1cm4gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUNsYXNzQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpIHtcbiAge1xuICAgIC8vIFRoaXMgaXMgdXNlZCBieSBEZXZUb29scyB0byBmb3JjZSBhIGJvdW5kYXJ5IHRvIGVycm9yLlxuICAgIHN3aXRjaCAoc2hvdWxkRXJyb3Iod29ya0luUHJvZ3Jlc3MpKSB7XG4gICAgICBjYXNlIGZhbHNlOlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIF9pbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcbiAgICAgICAgICB2YXIgY3RvciA9IHdvcmtJblByb2dyZXNzLnR5cGU7IC8vIFRPRE8gVGhpcyB3YXkgb2YgcmVzZXR0aW5nIHRoZSBlcnJvciBib3VuZGFyeSBzdGF0ZSBpcyBhIGhhY2suXG4gICAgICAgICAgLy8gSXMgdGhlcmUgYSBiZXR0ZXIgd2F5IHRvIGRvIHRoaXM/XG5cbiAgICAgICAgICB2YXIgdGVtcEluc3RhbmNlID0gbmV3IGN0b3Iod29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRQcm9wcywgX2luc3RhbmNlLmNvbnRleHQpO1xuICAgICAgICAgIHZhciBzdGF0ZSA9IHRlbXBJbnN0YW5jZS5zdGF0ZTtcblxuICAgICAgICAgIF9pbnN0YW5jZS51cGRhdGVyLmVucXVldWVTZXRTdGF0ZShfaW5zdGFuY2UsIHN0YXRlLCBudWxsKTtcblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgdHJ1ZTpcbiAgICAgICAge1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IERpZENhcHR1cmU7XG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gU2hvdWxkQ2FwdHVyZTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3Byb2QtZXJyb3ItY29kZXNcblxuICAgICAgICAgIHZhciBlcnJvciQxID0gbmV3IEVycm9yKCdTaW11bGF0ZWQgZXJyb3IgY29taW5nIGZyb20gRGV2VG9vbHMnKTtcbiAgICAgICAgICB2YXIgbGFuZSA9IHBpY2tBcmJpdHJhcnlMYW5lKHJlbmRlckxhbmVzKTtcbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IG1lcmdlTGFuZXMod29ya0luUHJvZ3Jlc3MubGFuZXMsIGxhbmUpOyAvLyBTY2hlZHVsZSB0aGUgZXJyb3IgYm91bmRhcnkgdG8gcmUtcmVuZGVyIHVzaW5nIHVwZGF0ZWQgc3RhdGVcblxuICAgICAgICAgIHZhciB1cGRhdGUgPSBjcmVhdGVDbGFzc0Vycm9yVXBkYXRlKHdvcmtJblByb2dyZXNzLCBjcmVhdGVDYXB0dXJlZFZhbHVlQXRGaWJlcihlcnJvciQxLCB3b3JrSW5Qcm9ncmVzcyksIGxhbmUpO1xuICAgICAgICAgIGVucXVldWVDYXB0dXJlZFVwZGF0ZSh3b3JrSW5Qcm9ncmVzcywgdXBkYXRlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICh3b3JrSW5Qcm9ncmVzcy50eXBlICE9PSB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZSkge1xuICAgICAgLy8gTGF6eSBjb21wb25lbnQgcHJvcHMgY2FuJ3QgYmUgdmFsaWRhdGVkIGluIGNyZWF0ZUVsZW1lbnRcbiAgICAgIC8vIGJlY2F1c2UgdGhleSdyZSBvbmx5IGd1YXJhbnRlZWQgdG8gYmUgcmVzb2x2ZWQgaGVyZS5cbiAgICAgIHZhciBpbm5lclByb3BUeXBlcyA9IENvbXBvbmVudC5wcm9wVHlwZXM7XG5cbiAgICAgIGlmIChpbm5lclByb3BUeXBlcykge1xuICAgICAgICBjaGVja1Byb3BUeXBlcyhpbm5lclByb3BUeXBlcywgbmV4dFByb3BzLCAvLyBSZXNvbHZlZCBwcm9wc1xuICAgICAgICAncHJvcCcsIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShDb21wb25lbnQpKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gLy8gUHVzaCBjb250ZXh0IHByb3ZpZGVycyBlYXJseSB0byBwcmV2ZW50IGNvbnRleHQgc3RhY2sgbWlzbWF0Y2hlcy5cbiAgLy8gRHVyaW5nIG1vdW50aW5nIHdlIGRvbid0IGtub3cgdGhlIGNoaWxkIGNvbnRleHQgeWV0IGFzIHRoZSBpbnN0YW5jZSBkb2Vzbid0IGV4aXN0LlxuICAvLyBXZSB3aWxsIGludmFsaWRhdGUgdGhlIGNoaWxkIGNvbnRleHQgaW4gZmluaXNoQ2xhc3NDb21wb25lbnQoKSByaWdodCBhZnRlciByZW5kZXJpbmcuXG5cblxuICB2YXIgaGFzQ29udGV4dDtcblxuICBpZiAoaXNDb250ZXh0UHJvdmlkZXIoQ29tcG9uZW50KSkge1xuICAgIGhhc0NvbnRleHQgPSB0cnVlO1xuICAgIHB1c2hDb250ZXh0UHJvdmlkZXIod29ya0luUHJvZ3Jlc3MpO1xuICB9IGVsc2Uge1xuICAgIGhhc0NvbnRleHQgPSBmYWxzZTtcbiAgfVxuXG4gIHByZXBhcmVUb1JlYWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcbiAgdmFyIHNob3VsZFVwZGF0ZTtcblxuICBpZiAoaW5zdGFuY2UgPT09IG51bGwpIHtcbiAgICByZXNldFN1c3BlbmRlZEN1cnJlbnRPbk1vdW50SW5MZWdhY3lNb2RlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKTsgLy8gSW4gdGhlIGluaXRpYWwgcGFzcyB3ZSBtaWdodCBuZWVkIHRvIGNvbnN0cnVjdCB0aGUgaW5zdGFuY2UuXG5cbiAgICBjb25zdHJ1Y3RDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcyk7XG4gICAgbW91bnRDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpO1xuICAgIHNob3VsZFVwZGF0ZSA9IHRydWU7XG4gIH0gZWxzZSBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgIC8vIEluIGEgcmVzdW1lLCB3ZSdsbCBhbHJlYWR5IGhhdmUgYW4gaW5zdGFuY2Ugd2UgY2FuIHJldXNlLlxuICAgIHNob3VsZFVwZGF0ZSA9IHJlc3VtZU1vdW50Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBuZXh0UHJvcHMsIHJlbmRlckxhbmVzKTtcbiAgfSBlbHNlIHtcbiAgICBzaG91bGRVcGRhdGUgPSB1cGRhdGVDbGFzc0luc3RhbmNlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpO1xuICB9XG5cbiAgdmFyIG5leHRVbml0T2ZXb3JrID0gZmluaXNoQ2xhc3NDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgc2hvdWxkVXBkYXRlLCBoYXNDb250ZXh0LCByZW5kZXJMYW5lcyk7XG5cbiAge1xuICAgIHZhciBpbnN0ID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuXG4gICAgaWYgKHNob3VsZFVwZGF0ZSAmJiBpbnN0LnByb3BzICE9PSBuZXh0UHJvcHMpIHtcbiAgICAgIGlmICghZGlkV2FybkFib3V0UmVhc3NpZ25pbmdQcm9wcykge1xuICAgICAgICBlcnJvcignSXQgbG9va3MgbGlrZSAlcyBpcyByZWFzc2lnbmluZyBpdHMgb3duIGB0aGlzLnByb3BzYCB3aGlsZSByZW5kZXJpbmcuICcgKyAnVGhpcyBpcyBub3Qgc3VwcG9ydGVkIGFuZCBjYW4gbGVhZCB0byBjb25mdXNpbmcgYnVncy4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKHdvcmtJblByb2dyZXNzKSB8fCAnYSBjb21wb25lbnQnKTtcbiAgICAgIH1cblxuICAgICAgZGlkV2FybkFib3V0UmVhc3NpZ25pbmdQcm9wcyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5leHRVbml0T2ZXb3JrO1xufVxuXG5mdW5jdGlvbiBmaW5pc2hDbGFzc0NvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBzaG91bGRVcGRhdGUsIGhhc0NvbnRleHQsIHJlbmRlckxhbmVzKSB7XG4gIC8vIFJlZnMgc2hvdWxkIHVwZGF0ZSBldmVuIGlmIHNob3VsZENvbXBvbmVudFVwZGF0ZSByZXR1cm5zIGZhbHNlXG4gIG1hcmtSZWYoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuICB2YXIgZGlkQ2FwdHVyZUVycm9yID0gKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRGlkQ2FwdHVyZSkgIT09IE5vRmxhZ3M7XG5cbiAgaWYgKCFzaG91bGRVcGRhdGUgJiYgIWRpZENhcHR1cmVFcnJvcikge1xuICAgIC8vIENvbnRleHQgcHJvdmlkZXJzIHNob3VsZCBkZWZlciB0byBzQ1UgZm9yIHJlbmRlcmluZ1xuICAgIGlmIChoYXNDb250ZXh0KSB7XG4gICAgICBpbnZhbGlkYXRlQ29udGV4dFByb3ZpZGVyKHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIGZhbHNlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICB9XG5cbiAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlOyAvLyBSZXJlbmRlclxuXG4gIFJlYWN0Q3VycmVudE93bmVyJDEuY3VycmVudCA9IHdvcmtJblByb2dyZXNzO1xuICB2YXIgbmV4dENoaWxkcmVuO1xuXG4gIGlmIChkaWRDYXB0dXJlRXJyb3IgJiYgdHlwZW9mIENvbXBvbmVudC5nZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IgIT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBJZiB3ZSBjYXB0dXJlZCBhbiBlcnJvciwgYnV0IGdldERlcml2ZWRTdGF0ZUZyb21FcnJvciBpcyBub3QgZGVmaW5lZCxcbiAgICAvLyB1bm1vdW50IGFsbCB0aGUgY2hpbGRyZW4uIGNvbXBvbmVudERpZENhdGNoIHdpbGwgc2NoZWR1bGUgYW4gdXBkYXRlIHRvXG4gICAgLy8gcmUtcmVuZGVyIGEgZmFsbGJhY2suIFRoaXMgaXMgdGVtcG9yYXJ5IHVudGlsIHdlIG1pZ3JhdGUgZXZlcnlvbmUgdG9cbiAgICAvLyB0aGUgbmV3IEFQSS5cbiAgICAvLyBUT0RPOiBXYXJuIGluIGEgZnV0dXJlIHJlbGVhc2UuXG4gICAgbmV4dENoaWxkcmVuID0gbnVsbDtcblxuICAgIHtcbiAgICAgIHN0b3BQcm9maWxlclRpbWVySWZSdW5uaW5nKCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHtcbiAgICAgIG1hcmtDb21wb25lbnRSZW5kZXJTdGFydGVkKHdvcmtJblByb2dyZXNzKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBzZXRJc1JlbmRlcmluZyh0cnVlKTtcbiAgICAgIG5leHRDaGlsZHJlbiA9IGluc3RhbmNlLnJlbmRlcigpO1xuXG4gICAgICBpZiAoIHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaW5zdGFuY2UucmVuZGVyKCk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHNldElzUmVuZGVyaW5nKGZhbHNlKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBtYXJrQ29tcG9uZW50UmVuZGVyU3RvcHBlZCgpO1xuICAgIH1cbiAgfSAvLyBSZWFjdCBEZXZUb29scyByZWFkcyB0aGlzIGZsYWcuXG5cblxuICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBQZXJmb3JtZWRXb3JrO1xuXG4gIGlmIChjdXJyZW50ICE9PSBudWxsICYmIGRpZENhcHR1cmVFcnJvcikge1xuICAgIC8vIElmIHdlJ3JlIHJlY292ZXJpbmcgZnJvbSBhbiBlcnJvciwgcmVjb25jaWxlIHdpdGhvdXQgcmV1c2luZyBhbnkgb2ZcbiAgICAvLyB0aGUgZXhpc3RpbmcgY2hpbGRyZW4uIENvbmNlcHR1YWxseSwgdGhlIG5vcm1hbCBjaGlsZHJlbiBhbmQgdGhlIGNoaWxkcmVuXG4gICAgLy8gdGhhdCBhcmUgc2hvd24gb24gZXJyb3IgYXJlIHR3byBkaWZmZXJlbnQgc2V0cywgc28gd2Ugc2hvdWxkbid0IHJldXNlXG4gICAgLy8gbm9ybWFsIGNoaWxkcmVuIGV2ZW4gaWYgdGhlaXIgaWRlbnRpdGllcyBtYXRjaC5cbiAgICBmb3JjZVVubW91bnRDdXJyZW50QW5kUmVjb25jaWxlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgfSBlbHNlIHtcbiAgICByZWNvbmNpbGVDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIH0gLy8gTWVtb2l6ZSBzdGF0ZSB1c2luZyB0aGUgdmFsdWVzIHdlIGp1c3QgdXNlZCB0byByZW5kZXIuXG4gIC8vIFRPRE86IFJlc3RydWN0dXJlIHNvIHdlIG5ldmVyIHJlYWQgdmFsdWVzIGZyb20gdGhlIGluc3RhbmNlLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IGluc3RhbmNlLnN0YXRlOyAvLyBUaGUgY29udGV4dCBtaWdodCBoYXZlIGNoYW5nZWQgc28gd2UgbmVlZCB0byByZWNhbGN1bGF0ZSBpdC5cblxuICBpZiAoaGFzQ29udGV4dCkge1xuICAgIGludmFsaWRhdGVDb250ZXh0UHJvdmlkZXIod29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgdHJ1ZSk7XG4gIH1cblxuICByZXR1cm4gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG59XG5cbmZ1bmN0aW9uIHB1c2hIb3N0Um9vdENvbnRleHQod29ya0luUHJvZ3Jlc3MpIHtcbiAgdmFyIHJvb3QgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG5cbiAgaWYgKHJvb3QucGVuZGluZ0NvbnRleHQpIHtcbiAgICBwdXNoVG9wTGV2ZWxDb250ZXh0T2JqZWN0KHdvcmtJblByb2dyZXNzLCByb290LnBlbmRpbmdDb250ZXh0LCByb290LnBlbmRpbmdDb250ZXh0ICE9PSByb290LmNvbnRleHQpO1xuICB9IGVsc2UgaWYgKHJvb3QuY29udGV4dCkge1xuICAgIC8vIFNob3VsZCBhbHdheXMgYmUgc2V0XG4gICAgcHVzaFRvcExldmVsQ29udGV4dE9iamVjdCh3b3JrSW5Qcm9ncmVzcywgcm9vdC5jb250ZXh0LCBmYWxzZSk7XG4gIH1cblxuICBwdXNoSG9zdENvbnRhaW5lcih3b3JrSW5Qcm9ncmVzcywgcm9vdC5jb250YWluZXJJbmZvKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlSG9zdFJvb3QoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHB1c2hIb3N0Um9vdENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuXG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaG91bGQgaGF2ZSBhIGN1cnJlbnQgZmliZXIuIFRoaXMgaXMgYSBidWcgaW4gUmVhY3QuJyk7XG4gIH1cblxuICB2YXIgbmV4dFByb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgcHJldlN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIHByZXZDaGlsZHJlbiA9IHByZXZTdGF0ZS5lbGVtZW50O1xuICBjbG9uZVVwZGF0ZVF1ZXVlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKTtcbiAgcHJvY2Vzc1VwZGF0ZVF1ZXVlKHdvcmtJblByb2dyZXNzLCBuZXh0UHJvcHMsIG51bGwsIHJlbmRlckxhbmVzKTtcbiAgdmFyIG5leHRTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG4gIHZhciByb290ID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICAvLyBiZWluZyBjYWxsZWQgXCJlbGVtZW50XCIuXG5cblxuICB2YXIgbmV4dENoaWxkcmVuID0gbmV4dFN0YXRlLmVsZW1lbnQ7XG5cbiAgaWYgKCBwcmV2U3RhdGUuaXNEZWh5ZHJhdGVkKSB7XG4gICAgLy8gVGhpcyBpcyBhIGh5ZHJhdGlvbiByb290IHdob3NlIHNoZWxsIGhhcyBub3QgeWV0IGh5ZHJhdGVkLiBXZSBzaG91bGRcbiAgICAvLyBhdHRlbXB0IHRvIGh5ZHJhdGUuXG4gICAgLy8gRmxpcCBpc0RlaHlkcmF0ZWQgdG8gZmFsc2UgdG8gaW5kaWNhdGUgdGhhdCB3aGVuIHRoaXMgcmVuZGVyXG4gICAgLy8gZmluaXNoZXMsIHRoZSByb290IHdpbGwgbm8gbG9uZ2VyIGJlIGRlaHlkcmF0ZWQuXG4gICAgdmFyIG92ZXJyaWRlU3RhdGUgPSB7XG4gICAgICBlbGVtZW50OiBuZXh0Q2hpbGRyZW4sXG4gICAgICBpc0RlaHlkcmF0ZWQ6IGZhbHNlLFxuICAgICAgY2FjaGU6IG5leHRTdGF0ZS5jYWNoZSxcbiAgICAgIHBlbmRpbmdTdXNwZW5zZUJvdW5kYXJpZXM6IG5leHRTdGF0ZS5wZW5kaW5nU3VzcGVuc2VCb3VuZGFyaWVzLFxuICAgICAgdHJhbnNpdGlvbnM6IG5leHRTdGF0ZS50cmFuc2l0aW9uc1xuICAgIH07XG4gICAgdmFyIHVwZGF0ZVF1ZXVlID0gd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWU7IC8vIGBiYXNlU3RhdGVgIGNhbiBhbHdheXMgYmUgdGhlIGxhc3Qgc3RhdGUgYmVjYXVzZSB0aGUgcm9vdCBkb2Vzbid0XG4gICAgLy8gaGF2ZSByZWR1Y2VyIGZ1bmN0aW9ucyBzbyBpdCBkb2Vzbid0IG5lZWQgcmViYXNpbmcuXG5cbiAgICB1cGRhdGVRdWV1ZS5iYXNlU3RhdGUgPSBvdmVycmlkZVN0YXRlO1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBvdmVycmlkZVN0YXRlO1xuXG4gICAgaWYgKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRm9yY2VDbGllbnRSZW5kZXIpIHtcbiAgICAgIC8vIFNvbWV0aGluZyBlcnJvcmVkIGR1cmluZyBhIHByZXZpb3VzIGF0dGVtcHQgdG8gaHlkcmF0ZSB0aGUgc2hlbGwsIHNvIHdlXG4gICAgICAvLyBmb3JjZWQgYSBjbGllbnQgcmVuZGVyLlxuICAgICAgdmFyIHJlY292ZXJhYmxlRXJyb3IgPSBjcmVhdGVDYXB0dXJlZFZhbHVlQXRGaWJlcihuZXcgRXJyb3IoJ1RoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSBoeWRyYXRpbmcuIEJlY2F1c2UgdGhlIGVycm9yIGhhcHBlbmVkIG91dHNpZGUgJyArICdvZiBhIFN1c3BlbnNlIGJvdW5kYXJ5LCB0aGUgZW50aXJlIHJvb3Qgd2lsbCBzd2l0Y2ggdG8gJyArICdjbGllbnQgcmVuZGVyaW5nLicpLCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICByZXR1cm4gbW91bnRIb3N0Um9vdFdpdGhvdXRIeWRyYXRpbmcoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMsIHJlY292ZXJhYmxlRXJyb3IpO1xuICAgIH0gZWxzZSBpZiAobmV4dENoaWxkcmVuICE9PSBwcmV2Q2hpbGRyZW4pIHtcbiAgICAgIHZhciBfcmVjb3ZlcmFibGVFcnJvciA9IGNyZWF0ZUNhcHR1cmVkVmFsdWVBdEZpYmVyKG5ldyBFcnJvcignVGhpcyByb290IHJlY2VpdmVkIGFuIGVhcmx5IHVwZGF0ZSwgYmVmb3JlIGFueXRoaW5nIHdhcyBhYmxlICcgKyAnaHlkcmF0ZS4gU3dpdGNoZWQgdGhlIGVudGlyZSByb290IHRvIGNsaWVudCByZW5kZXJpbmcuJyksIHdvcmtJblByb2dyZXNzKTtcblxuICAgICAgcmV0dXJuIG1vdW50SG9zdFJvb3RXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzLCBfcmVjb3ZlcmFibGVFcnJvcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRoZSBvdXRlcm1vc3Qgc2hlbGwgaGFzIG5vdCBoeWRyYXRlZCB5ZXQuIFN0YXJ0IGh5ZHJhdGluZy5cbiAgICAgIGVudGVySHlkcmF0aW9uU3RhdGUod29ya0luUHJvZ3Jlc3MpO1xuXG4gICAgICB2YXIgY2hpbGQgPSBtb3VudENoaWxkRmliZXJzKHdvcmtJblByb2dyZXNzLCBudWxsLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gY2hpbGQ7XG4gICAgICB2YXIgbm9kZSA9IGNoaWxkO1xuXG4gICAgICB3aGlsZSAobm9kZSkge1xuICAgICAgICAvLyBNYXJrIGVhY2ggY2hpbGQgYXMgaHlkcmF0aW5nLiBUaGlzIGlzIGEgZmFzdCBwYXRoIHRvIGtub3cgd2hldGhlciB0aGlzXG4gICAgICAgIC8vIHRyZWUgaXMgcGFydCBvZiBhIGh5ZHJhdGluZyB0cmVlLiBUaGlzIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIGEgY2hpbGRcbiAgICAgICAgLy8gbm9kZSBoYXMgZnVsbHkgbW91bnRlZCB5ZXQsIGFuZCBmb3Igc2NoZWR1bGluZyBldmVudCByZXBsYXlpbmcuXG4gICAgICAgIC8vIENvbmNlcHR1YWxseSB0aGlzIGlzIHNpbWlsYXIgdG8gUGxhY2VtZW50IGluIHRoYXQgYSBuZXcgc3VidHJlZSBpc1xuICAgICAgICAvLyBpbnNlcnRlZCBpbnRvIHRoZSBSZWFjdCB0cmVlIGhlcmUuIEl0IGp1c3QgaGFwcGVucyB0byBub3QgbmVlZCBET01cbiAgICAgICAgLy8gbXV0YXRpb25zIGJlY2F1c2UgaXQgYWxyZWFkeSBleGlzdHMuXG4gICAgICAgIG5vZGUuZmxhZ3MgPSBub2RlLmZsYWdzICYgflBsYWNlbWVudCB8IEh5ZHJhdGluZztcbiAgICAgICAgbm9kZSA9IG5vZGUuc2libGluZztcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gUm9vdCBpcyBub3QgZGVoeWRyYXRlZC4gRWl0aGVyIHRoaXMgaXMgYSBjbGllbnQtb25seSByb290LCBvciBpdFxuICAgIC8vIGFscmVhZHkgaHlkcmF0ZWQuXG4gICAgcmVzZXRIeWRyYXRpb25TdGF0ZSgpO1xuXG4gICAgaWYgKG5leHRDaGlsZHJlbiA9PT0gcHJldkNoaWxkcmVuKSB7XG4gICAgICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgIH1cblxuICAgIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxuZnVuY3Rpb24gbW91bnRIb3N0Um9vdFdpdGhvdXRIeWRyYXRpbmcoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMsIHJlY292ZXJhYmxlRXJyb3IpIHtcbiAgLy8gUmV2ZXJ0IHRvIGNsaWVudCByZW5kZXJpbmcuXG4gIHJlc2V0SHlkcmF0aW9uU3RhdGUoKTtcbiAgcXVldWVIeWRyYXRpb25FcnJvcihyZWNvdmVyYWJsZUVycm9yKTtcbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRm9yY2VDbGllbnRSZW5kZXI7XG4gIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVIb3N0Q29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcykge1xuICBwdXNoSG9zdENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuXG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgdHJ5VG9DbGFpbU5leHRIeWRyYXRhYmxlSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MpO1xuICB9XG5cbiAgdmFyIHR5cGUgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuICB2YXIgbmV4dFByb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgcHJldlByb3BzID0gY3VycmVudCAhPT0gbnVsbCA/IGN1cnJlbnQubWVtb2l6ZWRQcm9wcyA6IG51bGw7XG4gIHZhciBuZXh0Q2hpbGRyZW4gPSBuZXh0UHJvcHMuY2hpbGRyZW47XG4gIHZhciBpc0RpcmVjdFRleHRDaGlsZCA9IHNob3VsZFNldFRleHRDb250ZW50KHR5cGUsIG5leHRQcm9wcyk7XG5cbiAgaWYgKGlzRGlyZWN0VGV4dENoaWxkKSB7XG4gICAgLy8gV2Ugc3BlY2lhbCBjYXNlIGEgZGlyZWN0IHRleHQgY2hpbGQgb2YgYSBob3N0IG5vZGUuIFRoaXMgaXMgYSBjb21tb25cbiAgICAvLyBjYXNlLiBXZSB3b24ndCBoYW5kbGUgaXQgYXMgYSByZWlmaWVkIGNoaWxkLiBXZSB3aWxsIGluc3RlYWQgaGFuZGxlXG4gICAgLy8gdGhpcyBpbiB0aGUgaG9zdCBlbnZpcm9ubWVudCB0aGF0IGFsc28gaGFzIGFjY2VzcyB0byB0aGlzIHByb3AuIFRoYXRcbiAgICAvLyBhdm9pZHMgYWxsb2NhdGluZyBhbm90aGVyIEhvc3RUZXh0IGZpYmVyIGFuZCB0cmF2ZXJzaW5nIGl0LlxuICAgIG5leHRDaGlsZHJlbiA9IG51bGw7XG4gIH0gZWxzZSBpZiAocHJldlByb3BzICE9PSBudWxsICYmIHNob3VsZFNldFRleHRDb250ZW50KHR5cGUsIHByZXZQcm9wcykpIHtcbiAgICAvLyBJZiB3ZSdyZSBzd2l0Y2hpbmcgZnJvbSBhIGRpcmVjdCB0ZXh0IGNoaWxkIHRvIGEgbm9ybWFsIGNoaWxkLCBvciB0b1xuICAgIC8vIGVtcHR5LCB3ZSBuZWVkIHRvIHNjaGVkdWxlIHRoZSB0ZXh0IGNvbnRlbnQgdG8gYmUgcmVzZXQuXG4gICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gQ29udGVudFJlc2V0O1xuICB9XG5cbiAgbWFya1JlZihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcyk7XG4gIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVIb3N0VGV4dChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcykge1xuICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgIHRyeVRvQ2xhaW1OZXh0SHlkcmF0YWJsZUluc3RhbmNlKHdvcmtJblByb2dyZXNzKTtcbiAgfSAvLyBOb3RoaW5nIHRvIGRvIGhlcmUuIFRoaXMgaXMgdGVybWluYWwuIFdlJ2xsIGRvIHRoZSBjb21wbGV0aW9uIHN0ZXBcbiAgLy8gaW1tZWRpYXRlbHkgYWZ0ZXIuXG5cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gbW91bnRMYXp5Q29tcG9uZW50KF9jdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgZWxlbWVudFR5cGUsIHJlbmRlckxhbmVzKSB7XG4gIHJlc2V0U3VzcGVuZGVkQ3VycmVudE9uTW91bnRJbkxlZ2FjeU1vZGUoX2N1cnJlbnQsIHdvcmtJblByb2dyZXNzKTtcbiAgdmFyIHByb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgbGF6eUNvbXBvbmVudCA9IGVsZW1lbnRUeXBlO1xuICB2YXIgcGF5bG9hZCA9IGxhenlDb21wb25lbnQuX3BheWxvYWQ7XG4gIHZhciBpbml0ID0gbGF6eUNvbXBvbmVudC5faW5pdDtcbiAgdmFyIENvbXBvbmVudCA9IGluaXQocGF5bG9hZCk7IC8vIFN0b3JlIHRoZSB1bndyYXBwZWQgY29tcG9uZW50IGluIHRoZSB0eXBlLlxuXG4gIHdvcmtJblByb2dyZXNzLnR5cGUgPSBDb21wb25lbnQ7XG4gIHZhciByZXNvbHZlZFRhZyA9IHdvcmtJblByb2dyZXNzLnRhZyA9IHJlc29sdmVMYXp5Q29tcG9uZW50VGFnKENvbXBvbmVudCk7XG4gIHZhciByZXNvbHZlZFByb3BzID0gcmVzb2x2ZURlZmF1bHRQcm9wcyhDb21wb25lbnQsIHByb3BzKTtcbiAgdmFyIGNoaWxkO1xuXG4gIHN3aXRjaCAocmVzb2x2ZWRUYWcpIHtcbiAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICB7XG4gICAgICAgICAgdmFsaWRhdGVGdW5jdGlvbkNvbXBvbmVudEluRGV2KHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQpO1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLnR5cGUgPSBDb21wb25lbnQgPSByZXNvbHZlRnVuY3Rpb25Gb3JIb3RSZWxvYWRpbmcoQ29tcG9uZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNoaWxkID0gdXBkYXRlRnVuY3Rpb25Db21wb25lbnQobnVsbCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcmVzb2x2ZWRQcm9wcywgcmVuZGVyTGFuZXMpO1xuICAgICAgICByZXR1cm4gY2hpbGQ7XG4gICAgICB9XG5cbiAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICB7XG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MudHlwZSA9IENvbXBvbmVudCA9IHJlc29sdmVDbGFzc0ZvckhvdFJlbG9hZGluZyhDb21wb25lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2hpbGQgPSB1cGRhdGVDbGFzc0NvbXBvbmVudChudWxsLCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCByZXNvbHZlZFByb3BzLCByZW5kZXJMYW5lcyk7XG4gICAgICAgIHJldHVybiBjaGlsZDtcbiAgICAgIH1cblxuICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIHtcbiAgICAgICAge1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLnR5cGUgPSBDb21wb25lbnQgPSByZXNvbHZlRm9yd2FyZFJlZkZvckhvdFJlbG9hZGluZyhDb21wb25lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2hpbGQgPSB1cGRhdGVGb3J3YXJkUmVmKG51bGwsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHJlc29sdmVkUHJvcHMsIHJlbmRlckxhbmVzKTtcbiAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgfVxuXG4gICAgY2FzZSBNZW1vQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICB7XG4gICAgICAgICAgaWYgKHdvcmtJblByb2dyZXNzLnR5cGUgIT09IHdvcmtJblByb2dyZXNzLmVsZW1lbnRUeXBlKSB7XG4gICAgICAgICAgICB2YXIgb3V0ZXJQcm9wVHlwZXMgPSBDb21wb25lbnQucHJvcFR5cGVzO1xuXG4gICAgICAgICAgICBpZiAob3V0ZXJQcm9wVHlwZXMpIHtcbiAgICAgICAgICAgICAgY2hlY2tQcm9wVHlwZXMob3V0ZXJQcm9wVHlwZXMsIHJlc29sdmVkUHJvcHMsIC8vIFJlc29sdmVkIGZvciBvdXRlciBvbmx5XG4gICAgICAgICAgICAgICdwcm9wJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKENvbXBvbmVudCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNoaWxkID0gdXBkYXRlTWVtb0NvbXBvbmVudChudWxsLCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCByZXNvbHZlRGVmYXVsdFByb3BzKENvbXBvbmVudC50eXBlLCByZXNvbHZlZFByb3BzKSwgLy8gVGhlIGlubmVyIHR5cGUgY2FuIGhhdmUgZGVmYXVsdHMgdG9vXG4gICAgICAgIHJlbmRlckxhbmVzKTtcbiAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgfVxuICB9XG5cbiAgdmFyIGhpbnQgPSAnJztcblxuICB7XG4gICAgaWYgKENvbXBvbmVudCAhPT0gbnVsbCAmJiB0eXBlb2YgQ29tcG9uZW50ID09PSAnb2JqZWN0JyAmJiBDb21wb25lbnQuJCR0eXBlb2YgPT09IFJFQUNUX0xBWllfVFlQRSkge1xuICAgICAgaGludCA9ICcgRGlkIHlvdSB3cmFwIGEgY29tcG9uZW50IGluIFJlYWN0LmxhenkoKSBtb3JlIHRoYW4gb25jZT8nO1xuICAgIH1cbiAgfSAvLyBUaGlzIG1lc3NhZ2UgaW50ZW50aW9uYWxseSBkb2Vzbid0IG1lbnRpb24gRm9yd2FyZFJlZiBvciBNZW1vQ29tcG9uZW50XG4gIC8vIGJlY2F1c2UgdGhlIGZhY3QgdGhhdCBpdCdzIGEgc2VwYXJhdGUgdHlwZSBvZiB3b3JrIGlzIGFuXG4gIC8vIGltcGxlbWVudGF0aW9uIGRldGFpbC5cblxuXG4gIHRocm93IG5ldyBFcnJvcihcIkVsZW1lbnQgdHlwZSBpcyBpbnZhbGlkLiBSZWNlaXZlZCBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0bzogXCIgKyBDb21wb25lbnQgKyBcIi4gXCIgKyAoXCJMYXp5IGVsZW1lbnQgdHlwZSBtdXN0IHJlc29sdmUgdG8gYSBjbGFzcyBvciBmdW5jdGlvbi5cIiArIGhpbnQpKTtcbn1cblxuZnVuY3Rpb24gbW91bnRJbmNvbXBsZXRlQ2xhc3NDb21wb25lbnQoX2N1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpIHtcbiAgcmVzZXRTdXNwZW5kZWRDdXJyZW50T25Nb3VudEluTGVnYWN5TW9kZShfY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpOyAvLyBQcm9tb3RlIHRoZSBmaWJlciB0byBhIGNsYXNzIGFuZCB0cnkgcmVuZGVyaW5nIGFnYWluLlxuXG4gIHdvcmtJblByb2dyZXNzLnRhZyA9IENsYXNzQ29tcG9uZW50OyAvLyBUaGUgcmVzdCBvZiB0aGlzIGZ1bmN0aW9uIGlzIGEgZm9yayBvZiBgdXBkYXRlQ2xhc3NDb21wb25lbnRgXG4gIC8vIFB1c2ggY29udGV4dCBwcm92aWRlcnMgZWFybHkgdG8gcHJldmVudCBjb250ZXh0IHN0YWNrIG1pc21hdGNoZXMuXG4gIC8vIER1cmluZyBtb3VudGluZyB3ZSBkb24ndCBrbm93IHRoZSBjaGlsZCBjb250ZXh0IHlldCBhcyB0aGUgaW5zdGFuY2UgZG9lc24ndCBleGlzdC5cbiAgLy8gV2Ugd2lsbCBpbnZhbGlkYXRlIHRoZSBjaGlsZCBjb250ZXh0IGluIGZpbmlzaENsYXNzQ29tcG9uZW50KCkgcmlnaHQgYWZ0ZXIgcmVuZGVyaW5nLlxuXG4gIHZhciBoYXNDb250ZXh0O1xuXG4gIGlmIChpc0NvbnRleHRQcm92aWRlcihDb21wb25lbnQpKSB7XG4gICAgaGFzQ29udGV4dCA9IHRydWU7XG4gICAgcHVzaENvbnRleHRQcm92aWRlcih3b3JrSW5Qcm9ncmVzcyk7XG4gIH0gZWxzZSB7XG4gICAgaGFzQ29udGV4dCA9IGZhbHNlO1xuICB9XG5cbiAgcHJlcGFyZVRvUmVhZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgY29uc3RydWN0Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBuZXh0UHJvcHMpO1xuICBtb3VudENsYXNzSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCByZW5kZXJMYW5lcyk7XG4gIHJldHVybiBmaW5pc2hDbGFzc0NvbXBvbmVudChudWxsLCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCB0cnVlLCBoYXNDb250ZXh0LCByZW5kZXJMYW5lcyk7XG59XG5cbmZ1bmN0aW9uIG1vdW50SW5kZXRlcm1pbmF0ZUNvbXBvbmVudChfY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcmVuZGVyTGFuZXMpIHtcbiAgcmVzZXRTdXNwZW5kZWRDdXJyZW50T25Nb3VudEluTGVnYWN5TW9kZShfY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuICB2YXIgcHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciBjb250ZXh0O1xuXG4gIHtcbiAgICB2YXIgdW5tYXNrZWRDb250ZXh0ID0gZ2V0VW5tYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIGZhbHNlKTtcbiAgICBjb250ZXh0ID0gZ2V0TWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgdW5tYXNrZWRDb250ZXh0KTtcbiAgfVxuXG4gIHByZXBhcmVUb1JlYWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gIHZhciB2YWx1ZTtcbiAgdmFyIGhhc0lkO1xuXG4gIHtcbiAgICBtYXJrQ29tcG9uZW50UmVuZGVyU3RhcnRlZCh3b3JrSW5Qcm9ncmVzcyk7XG4gIH1cblxuICB7XG4gICAgaWYgKENvbXBvbmVudC5wcm90b3R5cGUgJiYgdHlwZW9mIENvbXBvbmVudC5wcm90b3R5cGUucmVuZGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShDb21wb25lbnQpIHx8ICdVbmtub3duJztcblxuICAgICAgaWYgKCFkaWRXYXJuQWJvdXRCYWRDbGFzc1tjb21wb25lbnROYW1lXSkge1xuICAgICAgICBlcnJvcihcIlRoZSA8JXMgLz4gY29tcG9uZW50IGFwcGVhcnMgdG8gaGF2ZSBhIHJlbmRlciBtZXRob2QsIGJ1dCBkb2Vzbid0IGV4dGVuZCBSZWFjdC5Db21wb25lbnQuIFwiICsgJ1RoaXMgaXMgbGlrZWx5IHRvIGNhdXNlIGVycm9ycy4gQ2hhbmdlICVzIHRvIGV4dGVuZCBSZWFjdC5Db21wb25lbnQgaW5zdGVhZC4nLCBjb21wb25lbnROYW1lLCBjb21wb25lbnROYW1lKTtcblxuICAgICAgICBkaWRXYXJuQWJvdXRCYWRDbGFzc1tjb21wb25lbnROYW1lXSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5yZWNvcmRMZWdhY3lDb250ZXh0V2FybmluZyh3b3JrSW5Qcm9ncmVzcywgbnVsbCk7XG4gICAgfVxuXG4gICAgc2V0SXNSZW5kZXJpbmcodHJ1ZSk7XG4gICAgUmVhY3RDdXJyZW50T3duZXIkMS5jdXJyZW50ID0gd29ya0luUHJvZ3Jlc3M7XG4gICAgdmFsdWUgPSByZW5kZXJXaXRoSG9va3MobnVsbCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcHJvcHMsIGNvbnRleHQsIHJlbmRlckxhbmVzKTtcbiAgICBoYXNJZCA9IGNoZWNrRGlkUmVuZGVySWRIb29rKCk7XG4gICAgc2V0SXNSZW5kZXJpbmcoZmFsc2UpO1xuICB9XG5cbiAge1xuICAgIG1hcmtDb21wb25lbnRSZW5kZXJTdG9wcGVkKCk7XG4gIH0gLy8gUmVhY3QgRGV2VG9vbHMgcmVhZHMgdGhpcyBmbGFnLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUGVyZm9ybWVkV29yaztcblxuICB7XG4gICAgLy8gU3VwcG9ydCBmb3IgbW9kdWxlIGNvbXBvbmVudHMgaXMgZGVwcmVjYXRlZCBhbmQgaXMgcmVtb3ZlZCBiZWhpbmQgYSBmbGFnLlxuICAgIC8vIFdoZXRoZXIgb3Igbm90IGl0IHdvdWxkIGNyYXNoIGxhdGVyLCB3ZSB3YW50IHRvIHNob3cgYSBnb29kIG1lc3NhZ2UgaW4gREVWIGZpcnN0LlxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZS5yZW5kZXIgPT09ICdmdW5jdGlvbicgJiYgdmFsdWUuJCR0eXBlb2YgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIF9jb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKENvbXBvbmVudCkgfHwgJ1Vua25vd24nO1xuXG4gICAgICBpZiAoIWRpZFdhcm5BYm91dE1vZHVsZVBhdHRlcm5Db21wb25lbnRbX2NvbXBvbmVudE5hbWVdKSB7XG4gICAgICAgIGVycm9yKCdUaGUgPCVzIC8+IGNvbXBvbmVudCBhcHBlYXJzIHRvIGJlIGEgZnVuY3Rpb24gY29tcG9uZW50IHRoYXQgcmV0dXJucyBhIGNsYXNzIGluc3RhbmNlLiAnICsgJ0NoYW5nZSAlcyB0byBhIGNsYXNzIHRoYXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQgaW5zdGVhZC4gJyArIFwiSWYgeW91IGNhbid0IHVzZSBhIGNsYXNzIHRyeSBhc3NpZ25pbmcgdGhlIHByb3RvdHlwZSBvbiB0aGUgZnVuY3Rpb24gYXMgYSB3b3JrYXJvdW5kLiBcIiArIFwiYCVzLnByb3RvdHlwZSA9IFJlYWN0LkNvbXBvbmVudC5wcm90b3R5cGVgLiBEb24ndCB1c2UgYW4gYXJyb3cgZnVuY3Rpb24gc2luY2UgaXQgXCIgKyAnY2Fubm90IGJlIGNhbGxlZCB3aXRoIGBuZXdgIGJ5IFJlYWN0LicsIF9jb21wb25lbnROYW1lLCBfY29tcG9uZW50TmFtZSwgX2NvbXBvbmVudE5hbWUpO1xuXG4gICAgICAgIGRpZFdhcm5BYm91dE1vZHVsZVBhdHRlcm5Db21wb25lbnRbX2NvbXBvbmVudE5hbWVdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoIC8vIFJ1biB0aGVzZSBjaGVja3MgaW4gcHJvZHVjdGlvbiBvbmx5IGlmIHRoZSBmbGFnIGlzIG9mZi5cbiAgLy8gRXZlbnR1YWxseSB3ZSdsbCBkZWxldGUgdGhpcyBicmFuY2ggYWx0b2dldGhlci5cbiAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlLnJlbmRlciA9PT0gJ2Z1bmN0aW9uJyAmJiB2YWx1ZS4kJHR5cGVvZiA9PT0gdW5kZWZpbmVkKSB7XG4gICAge1xuICAgICAgdmFyIF9jb21wb25lbnROYW1lMiA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShDb21wb25lbnQpIHx8ICdVbmtub3duJztcblxuICAgICAgaWYgKCFkaWRXYXJuQWJvdXRNb2R1bGVQYXR0ZXJuQ29tcG9uZW50W19jb21wb25lbnROYW1lMl0pIHtcbiAgICAgICAgZXJyb3IoJ1RoZSA8JXMgLz4gY29tcG9uZW50IGFwcGVhcnMgdG8gYmUgYSBmdW5jdGlvbiBjb21wb25lbnQgdGhhdCByZXR1cm5zIGEgY2xhc3MgaW5zdGFuY2UuICcgKyAnQ2hhbmdlICVzIHRvIGEgY2xhc3MgdGhhdCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCBpbnN0ZWFkLiAnICsgXCJJZiB5b3UgY2FuJ3QgdXNlIGEgY2xhc3MgdHJ5IGFzc2lnbmluZyB0aGUgcHJvdG90eXBlIG9uIHRoZSBmdW5jdGlvbiBhcyBhIHdvcmthcm91bmQuIFwiICsgXCJgJXMucHJvdG90eXBlID0gUmVhY3QuQ29tcG9uZW50LnByb3RvdHlwZWAuIERvbid0IHVzZSBhbiBhcnJvdyBmdW5jdGlvbiBzaW5jZSBpdCBcIiArICdjYW5ub3QgYmUgY2FsbGVkIHdpdGggYG5ld2AgYnkgUmVhY3QuJywgX2NvbXBvbmVudE5hbWUyLCBfY29tcG9uZW50TmFtZTIsIF9jb21wb25lbnROYW1lMik7XG5cbiAgICAgICAgZGlkV2FybkFib3V0TW9kdWxlUGF0dGVybkNvbXBvbmVudFtfY29tcG9uZW50TmFtZTJdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IC8vIFByb2NlZWQgdW5kZXIgdGhlIGFzc3VtcHRpb24gdGhhdCB0aGlzIGlzIGEgY2xhc3MgaW5zdGFuY2VcblxuXG4gICAgd29ya0luUHJvZ3Jlc3MudGFnID0gQ2xhc3NDb21wb25lbnQ7IC8vIFRocm93IG91dCBhbnkgaG9va3MgdGhhdCB3ZXJlIHVzZWQuXG5cbiAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gbnVsbDtcbiAgICB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZSA9IG51bGw7IC8vIFB1c2ggY29udGV4dCBwcm92aWRlcnMgZWFybHkgdG8gcHJldmVudCBjb250ZXh0IHN0YWNrIG1pc21hdGNoZXMuXG4gICAgLy8gRHVyaW5nIG1vdW50aW5nIHdlIGRvbid0IGtub3cgdGhlIGNoaWxkIGNvbnRleHQgeWV0IGFzIHRoZSBpbnN0YW5jZSBkb2Vzbid0IGV4aXN0LlxuICAgIC8vIFdlIHdpbGwgaW52YWxpZGF0ZSB0aGUgY2hpbGQgY29udGV4dCBpbiBmaW5pc2hDbGFzc0NvbXBvbmVudCgpIHJpZ2h0IGFmdGVyIHJlbmRlcmluZy5cblxuICAgIHZhciBoYXNDb250ZXh0ID0gZmFsc2U7XG5cbiAgICBpZiAoaXNDb250ZXh0UHJvdmlkZXIoQ29tcG9uZW50KSkge1xuICAgICAgaGFzQ29udGV4dCA9IHRydWU7XG4gICAgICBwdXNoQ29udGV4dFByb3ZpZGVyKHdvcmtJblByb2dyZXNzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGFzQ29udGV4dCA9IGZhbHNlO1xuICAgIH1cblxuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSB2YWx1ZS5zdGF0ZSAhPT0gbnVsbCAmJiB2YWx1ZS5zdGF0ZSAhPT0gdW5kZWZpbmVkID8gdmFsdWUuc3RhdGUgOiBudWxsO1xuICAgIGluaXRpYWxpemVVcGRhdGVRdWV1ZSh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgYWRvcHRDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCB2YWx1ZSk7XG4gICAgbW91bnRDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHByb3BzLCByZW5kZXJMYW5lcyk7XG4gICAgcmV0dXJuIGZpbmlzaENsYXNzQ29tcG9uZW50KG51bGwsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHRydWUsIGhhc0NvbnRleHQsIHJlbmRlckxhbmVzKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBQcm9jZWVkIHVuZGVyIHRoZSBhc3N1bXB0aW9uIHRoYXQgdGhpcyBpcyBhIGZ1bmN0aW9uIGNvbXBvbmVudFxuICAgIHdvcmtJblByb2dyZXNzLnRhZyA9IEZ1bmN0aW9uQ29tcG9uZW50O1xuXG4gICAge1xuXG4gICAgICBpZiAoIHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdmFsdWUgPSByZW5kZXJXaXRoSG9va3MobnVsbCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcHJvcHMsIGNvbnRleHQsIHJlbmRlckxhbmVzKTtcbiAgICAgICAgICBoYXNJZCA9IGNoZWNrRGlkUmVuZGVySWRIb29rKCk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGdldElzSHlkcmF0aW5nKCkgJiYgaGFzSWQpIHtcbiAgICAgIHB1c2hNYXRlcmlhbGl6ZWRUcmVlSWQod29ya0luUHJvZ3Jlc3MpO1xuICAgIH1cblxuICAgIHJlY29uY2lsZUNoaWxkcmVuKG51bGwsIHdvcmtJblByb2dyZXNzLCB2YWx1ZSwgcmVuZGVyTGFuZXMpO1xuXG4gICAge1xuICAgICAgdmFsaWRhdGVGdW5jdGlvbkNvbXBvbmVudEluRGV2KHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgfVxufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZUZ1bmN0aW9uQ29tcG9uZW50SW5EZXYod29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCkge1xuICB7XG4gICAgaWYgKENvbXBvbmVudCkge1xuICAgICAgaWYgKENvbXBvbmVudC5jaGlsZENvbnRleHRUeXBlcykge1xuICAgICAgICBlcnJvcignJXMoLi4uKTogY2hpbGRDb250ZXh0VHlwZXMgY2Fubm90IGJlIGRlZmluZWQgb24gYSBmdW5jdGlvbiBjb21wb25lbnQuJywgQ29tcG9uZW50LmRpc3BsYXlOYW1lIHx8IENvbXBvbmVudC5uYW1lIHx8ICdDb21wb25lbnQnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAod29ya0luUHJvZ3Jlc3MucmVmICE9PSBudWxsKSB7XG4gICAgICB2YXIgaW5mbyA9ICcnO1xuICAgICAgdmFyIG93bmVyTmFtZSA9IGdldEN1cnJlbnRGaWJlck93bmVyTmFtZUluRGV2T3JOdWxsKCk7XG5cbiAgICAgIGlmIChvd25lck5hbWUpIHtcbiAgICAgICAgaW5mbyArPSAnXFxuXFxuQ2hlY2sgdGhlIHJlbmRlciBtZXRob2Qgb2YgYCcgKyBvd25lck5hbWUgKyAnYC4nO1xuICAgICAgfVxuXG4gICAgICB2YXIgd2FybmluZ0tleSA9IG93bmVyTmFtZSB8fCAnJztcbiAgICAgIHZhciBkZWJ1Z1NvdXJjZSA9IHdvcmtJblByb2dyZXNzLl9kZWJ1Z1NvdXJjZTtcblxuICAgICAgaWYgKGRlYnVnU291cmNlKSB7XG4gICAgICAgIHdhcm5pbmdLZXkgPSBkZWJ1Z1NvdXJjZS5maWxlTmFtZSArICc6JyArIGRlYnVnU291cmNlLmxpbmVOdW1iZXI7XG4gICAgICB9XG5cbiAgICAgIGlmICghZGlkV2FybkFib3V0RnVuY3Rpb25SZWZzW3dhcm5pbmdLZXldKSB7XG4gICAgICAgIGRpZFdhcm5BYm91dEZ1bmN0aW9uUmVmc1t3YXJuaW5nS2V5XSA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJ0Z1bmN0aW9uIGNvbXBvbmVudHMgY2Fubm90IGJlIGdpdmVuIHJlZnMuICcgKyAnQXR0ZW1wdHMgdG8gYWNjZXNzIHRoaXMgcmVmIHdpbGwgZmFpbC4gJyArICdEaWQgeW91IG1lYW4gdG8gdXNlIFJlYWN0LmZvcndhcmRSZWYoKT8lcycsIGluZm8pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgQ29tcG9uZW50LmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIF9jb21wb25lbnROYW1lMyA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShDb21wb25lbnQpIHx8ICdVbmtub3duJztcblxuICAgICAgaWYgKCFkaWRXYXJuQWJvdXRHZXREZXJpdmVkU3RhdGVPbkZ1bmN0aW9uQ29tcG9uZW50W19jb21wb25lbnROYW1lM10pIHtcbiAgICAgICAgZXJyb3IoJyVzOiBGdW5jdGlvbiBjb21wb25lbnRzIGRvIG5vdCBzdXBwb3J0IGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcy4nLCBfY29tcG9uZW50TmFtZTMpO1xuXG4gICAgICAgIGRpZFdhcm5BYm91dEdldERlcml2ZWRTdGF0ZU9uRnVuY3Rpb25Db21wb25lbnRbX2NvbXBvbmVudE5hbWUzXSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBDb21wb25lbnQuY29udGV4dFR5cGUgPT09ICdvYmplY3QnICYmIENvbXBvbmVudC5jb250ZXh0VHlwZSAhPT0gbnVsbCkge1xuICAgICAgdmFyIF9jb21wb25lbnROYW1lNCA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShDb21wb25lbnQpIHx8ICdVbmtub3duJztcblxuICAgICAgaWYgKCFkaWRXYXJuQWJvdXRDb250ZXh0VHlwZU9uRnVuY3Rpb25Db21wb25lbnRbX2NvbXBvbmVudE5hbWU0XSkge1xuICAgICAgICBlcnJvcignJXM6IEZ1bmN0aW9uIGNvbXBvbmVudHMgZG8gbm90IHN1cHBvcnQgY29udGV4dFR5cGUuJywgX2NvbXBvbmVudE5hbWU0KTtcblxuICAgICAgICBkaWRXYXJuQWJvdXRDb250ZXh0VHlwZU9uRnVuY3Rpb25Db21wb25lbnRbX2NvbXBvbmVudE5hbWU0XSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBTVVNQRU5ERURfTUFSS0VSID0ge1xuICBkZWh5ZHJhdGVkOiBudWxsLFxuICB0cmVlQ29udGV4dDogbnVsbCxcbiAgcmV0cnlMYW5lOiBOb0xhbmVcbn07XG5cbmZ1bmN0aW9uIG1vdW50U3VzcGVuc2VPZmZzY3JlZW5TdGF0ZShyZW5kZXJMYW5lcykge1xuICByZXR1cm4ge1xuICAgIGJhc2VMYW5lczogcmVuZGVyTGFuZXMsXG4gICAgY2FjaGVQb29sOiBnZXRTdXNwZW5kZWRDYWNoZSgpLFxuICAgIHRyYW5zaXRpb25zOiBudWxsXG4gIH07XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN1c3BlbnNlT2Zmc2NyZWVuU3RhdGUocHJldk9mZnNjcmVlblN0YXRlLCByZW5kZXJMYW5lcykge1xuICB2YXIgY2FjaGVQb29sID0gbnVsbDtcblxuICByZXR1cm4ge1xuICAgIGJhc2VMYW5lczogbWVyZ2VMYW5lcyhwcmV2T2Zmc2NyZWVuU3RhdGUuYmFzZUxhbmVzLCByZW5kZXJMYW5lcyksXG4gICAgY2FjaGVQb29sOiBjYWNoZVBvb2wsXG4gICAgdHJhbnNpdGlvbnM6IHByZXZPZmZzY3JlZW5TdGF0ZS50cmFuc2l0aW9uc1xuICB9O1xufSAvLyBUT0RPOiBQcm9iYWJseSBzaG91bGQgaW5saW5lIHRoaXMgYmFja1xuXG5cbmZ1bmN0aW9uIHNob3VsZFJlbWFpbk9uRmFsbGJhY2soc3VzcGVuc2VDb250ZXh0LCBjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAgLy8gSWYgd2UncmUgYWxyZWFkeSBzaG93aW5nIGEgZmFsbGJhY2ssIHRoZXJlIGFyZSBjYXNlcyB3aGVyZSB3ZSBuZWVkIHRvXG4gIC8vIHJlbWFpbiBvbiB0aGF0IGZhbGxiYWNrIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgY29udGVudCBoYXMgcmVzb2x2ZWQuXG4gIC8vIEZvciBleGFtcGxlLCBTdXNwZW5zZUxpc3QgY29vcmRpbmF0ZXMgd2hlbiBuZXN0ZWQgY29udGVudCBhcHBlYXJzLlxuICBpZiAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgIHZhciBzdXNwZW5zZVN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuXG4gICAgaWYgKHN1c3BlbnNlU3RhdGUgPT09IG51bGwpIHtcbiAgICAgIC8vIEN1cnJlbnRseSBzaG93aW5nIGNvbnRlbnQuIERvbid0IGhpZGUgaXQsIGV2ZW4gaWYgRm9yY2VTdXNwZW5zZUZhbGxiYWNrXG4gICAgICAvLyBpcyB0cnVlLiBNb3JlIHByZWNpc2UgbmFtZSBtaWdodCBiZSBcIkZvcmNlUmVtYWluU3VzcGVuc2VGYWxsYmFja1wiLlxuICAgICAgLy8gTm90ZTogVGhpcyBpcyBhIGZhY3RvcmluZyBzbWVsbC4gQ2FuJ3QgcmVtYWluIG9uIGEgZmFsbGJhY2sgaWYgdGhlcmUnc1xuICAgICAgLy8gbm8gZmFsbGJhY2sgdG8gcmVtYWluIG9uLlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSAvLyBOb3QgY3VycmVudGx5IHNob3dpbmcgY29udGVudC4gQ29uc3VsdCB0aGUgU3VzcGVuc2UgY29udGV4dC5cblxuXG4gIHJldHVybiBoYXNTdXNwZW5zZUNvbnRleHQoc3VzcGVuc2VDb250ZXh0LCBGb3JjZVN1c3BlbnNlRmFsbGJhY2spO1xufVxuXG5mdW5jdGlvbiBnZXRSZW1haW5pbmdXb3JrSW5QcmltYXJ5VHJlZShjdXJyZW50LCByZW5kZXJMYW5lcykge1xuICAvLyBUT0RPOiBTaG91bGQgbm90IHJlbW92ZSByZW5kZXIgbGFuZXMgdGhhdCB3ZXJlIHBpbmdlZCBkdXJpbmcgdGhpcyByZW5kZXJcbiAgcmV0dXJuIHJlbW92ZUxhbmVzKGN1cnJlbnQuY2hpbGRMYW5lcywgcmVuZGVyTGFuZXMpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVTdXNwZW5zZUNvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIG5leHRQcm9wcyA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wczsgLy8gVGhpcyBpcyB1c2VkIGJ5IERldlRvb2xzIHRvIGZvcmNlIGEgYm91bmRhcnkgdG8gc3VzcGVuZC5cblxuICB7XG4gICAgaWYgKHNob3VsZFN1c3BlbmQod29ya0luUHJvZ3Jlc3MpKSB7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBEaWRDYXB0dXJlO1xuICAgIH1cbiAgfVxuXG4gIHZhciBzdXNwZW5zZUNvbnRleHQgPSBzdXNwZW5zZVN0YWNrQ3Vyc29yLmN1cnJlbnQ7XG4gIHZhciBzaG93RmFsbGJhY2sgPSBmYWxzZTtcbiAgdmFyIGRpZFN1c3BlbmQgPSAod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBEaWRDYXB0dXJlKSAhPT0gTm9GbGFncztcblxuICBpZiAoZGlkU3VzcGVuZCB8fCBzaG91bGRSZW1haW5PbkZhbGxiYWNrKHN1c3BlbnNlQ29udGV4dCwgY3VycmVudCkpIHtcbiAgICAvLyBTb21ldGhpbmcgaW4gdGhpcyBib3VuZGFyeSdzIHN1YnRyZWUgYWxyZWFkeSBzdXNwZW5kZWQuIFN3aXRjaCB0b1xuICAgIC8vIHJlbmRlcmluZyB0aGUgZmFsbGJhY2sgY2hpbGRyZW4uXG4gICAgc2hvd0ZhbGxiYWNrID0gdHJ1ZTtcbiAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyAmPSB+RGlkQ2FwdHVyZTtcbiAgfSBlbHNlIHtcbiAgICAvLyBBdHRlbXB0aW5nIHRoZSBtYWluIGNvbnRlbnRcbiAgICBpZiAoY3VycmVudCA9PT0gbnVsbCB8fCBjdXJyZW50Lm1lbW9pemVkU3RhdGUgIT09IG51bGwpIHtcbiAgICAgIC8vIFRoaXMgaXMgYSBuZXcgbW91bnQgb3IgdGhpcyBib3VuZGFyeSBpcyBhbHJlYWR5IHNob3dpbmcgYSBmYWxsYmFjayBzdGF0ZS5cbiAgICAgIC8vIE1hcmsgdGhpcyBzdWJ0cmVlIGNvbnRleHQgYXMgaGF2aW5nIGF0IGxlYXN0IG9uZSBpbnZpc2libGUgcGFyZW50IHRoYXQgY291bGRcbiAgICAgIC8vIGhhbmRsZSB0aGUgZmFsbGJhY2sgc3RhdGUuXG4gICAgICAvLyBBdm9pZGVkIGJvdW5kYXJpZXMgYXJlIG5vdCBjb25zaWRlcmVkIHNpbmNlIHRoZXkgY2Fubm90IGhhbmRsZSBwcmVmZXJyZWQgZmFsbGJhY2sgc3RhdGVzLlxuICAgICAge1xuICAgICAgICBzdXNwZW5zZUNvbnRleHQgPSBhZGRTdWJ0cmVlU3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlQ29udGV4dCwgSW52aXNpYmxlUGFyZW50U3VzcGVuc2VDb250ZXh0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzdXNwZW5zZUNvbnRleHQgPSBzZXREZWZhdWx0U2hhbGxvd1N1c3BlbnNlQ29udGV4dChzdXNwZW5zZUNvbnRleHQpO1xuICBwdXNoU3VzcGVuc2VDb250ZXh0KHdvcmtJblByb2dyZXNzLCBzdXNwZW5zZUNvbnRleHQpOyAvLyBPSywgdGhlIG5leHQgcGFydCBpcyBjb25mdXNpbmcuIFdlJ3JlIGFib3V0IHRvIHJlY29uY2lsZSB0aGUgU3VzcGVuc2VcbiAgLy8gYm91bmRhcnkncyBjaGlsZHJlbi4gVGhpcyBpbnZvbHZlcyBzb21lIGN1c3RvbSByZWNvbmNpbGlhdGlvbiBsb2dpYy4gVHdvXG4gIC8vIG1haW4gcmVhc29ucyB0aGlzIGlzIHNvIGNvbXBsaWNhdGVkLlxuICAvL1xuICAvLyBGaXJzdCwgTGVnYWN5IE1vZGUgaGFzIGRpZmZlcmVudCBzZW1hbnRpY3MgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LiBUaGVcbiAgLy8gcHJpbWFyeSB0cmVlIHdpbGwgY29tbWl0IGluIGFuIGluY29uc2lzdGVudCBzdGF0ZSwgc28gd2hlbiB3ZSBkbyB0aGVcbiAgLy8gc2Vjb25kIHBhc3MgdG8gcmVuZGVyIHRoZSBmYWxsYmFjaywgd2UgZG8gc29tZSBleGNlZWRpbmdseSwgdWgsIGNsZXZlclxuICAvLyBoYWNrcyB0byBtYWtlIHRoYXQgbm90IHRvdGFsbHkgYnJlYWsuIExpa2UgdHJhbnNmZXJyaW5nIGVmZmVjdHMgYW5kXG4gIC8vIGRlbGV0aW9ucyBmcm9tIGhpZGRlbiB0cmVlLiBJbiBDb25jdXJyZW50IE1vZGUsIGl0J3MgbXVjaCBzaW1wbGVyLFxuICAvLyBiZWNhdXNlIHdlIGJhaWxvdXQgb24gdGhlIHByaW1hcnkgdHJlZSBjb21wbGV0ZWx5IGFuZCBsZWF2ZSBpdCBpbiBpdHMgb2xkXG4gIC8vIHN0YXRlLCBubyBlZmZlY3RzLiBTYW1lIGFzIHdoYXQgd2UgZG8gZm9yIE9mZnNjcmVlbiAoZXhjZXB0IHRoYXRcbiAgLy8gT2Zmc2NyZWVuIGRvZXNuJ3QgaGF2ZSB0aGUgZmlyc3QgcmVuZGVyIHBhc3MpLlxuICAvL1xuICAvLyBTZWNvbmQgaXMgaHlkcmF0aW9uLiBEdXJpbmcgaHlkcmF0aW9uLCB0aGUgU3VzcGVuc2UgZmliZXIgaGFzIGEgc2xpZ2h0bHlcbiAgLy8gZGlmZmVyZW50IGxheW91dCwgd2hlcmUgdGhlIGNoaWxkIHBvaW50cyB0byBhIGRlaHlkcmF0ZWQgZnJhZ21lbnQsIHdoaWNoXG4gIC8vIGNvbnRhaW5zIHRoZSBET00gcmVuZGVyZWQgYnkgdGhlIHNlcnZlci5cbiAgLy9cbiAgLy8gVGhpcmQsIGV2ZW4gaWYgeW91IHNldCBhbGwgdGhhdCBhc2lkZSwgU3VzcGVuc2UgaXMgbGlrZSBlcnJvciBib3VuZGFyaWVzIGluXG4gIC8vIHRoYXQgd2UgZmlyc3Qgd2UgdHJ5IHRvIHJlbmRlciBvbmUgdHJlZSwgYW5kIGlmIHRoYXQgZmFpbHMsIHdlIHJlbmRlciBhZ2FpblxuICAvLyBhbmQgc3dpdGNoIHRvIGEgZGlmZmVyZW50IHRyZWUuIExpa2UgYSB0cnkvY2F0Y2ggYmxvY2suIFNvIHdlIGhhdmUgdG8gdHJhY2tcbiAgLy8gd2hpY2ggYnJhbmNoIHdlJ3JlIGN1cnJlbnRseSByZW5kZXJpbmcuIElkZWFsbHkgd2Ugd291bGQgbW9kZWwgdGhpcyB1c2luZ1xuICAvLyBhIHN0YWNrLlxuXG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgLy8gSW5pdGlhbCBtb3VudFxuICAgIC8vIFNwZWNpYWwgcGF0aCBmb3IgaHlkcmF0aW9uXG4gICAgLy8gSWYgd2UncmUgY3VycmVudGx5IGh5ZHJhdGluZywgdHJ5IHRvIGh5ZHJhdGUgdGhpcyBib3VuZGFyeS5cbiAgICB0cnlUb0NsYWltTmV4dEh5ZHJhdGFibGVJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcyk7IC8vIFRoaXMgY291bGQndmUgYmVlbiBhIGRlaHlkcmF0ZWQgc3VzcGVuc2UgY29tcG9uZW50LlxuXG4gICAgdmFyIHN1c3BlbnNlU3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gICAgaWYgKHN1c3BlbnNlU3RhdGUgIT09IG51bGwpIHtcbiAgICAgIHZhciBkZWh5ZHJhdGVkID0gc3VzcGVuc2VTdGF0ZS5kZWh5ZHJhdGVkO1xuXG4gICAgICBpZiAoZGVoeWRyYXRlZCAhPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbW91bnREZWh5ZHJhdGVkU3VzcGVuc2VDb21wb25lbnQod29ya0luUHJvZ3Jlc3MsIGRlaHlkcmF0ZWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBuZXh0UHJpbWFyeUNoaWxkcmVuID0gbmV4dFByb3BzLmNoaWxkcmVuO1xuICAgIHZhciBuZXh0RmFsbGJhY2tDaGlsZHJlbiA9IG5leHRQcm9wcy5mYWxsYmFjaztcblxuICAgIGlmIChzaG93RmFsbGJhY2spIHtcbiAgICAgIHZhciBmYWxsYmFja0ZyYWdtZW50ID0gbW91bnRTdXNwZW5zZUZhbGxiYWNrQ2hpbGRyZW4od29ya0luUHJvZ3Jlc3MsIG5leHRQcmltYXJ5Q2hpbGRyZW4sIG5leHRGYWxsYmFja0NoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gICAgICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgICAgIHByaW1hcnlDaGlsZEZyYWdtZW50Lm1lbW9pemVkU3RhdGUgPSBtb3VudFN1c3BlbnNlT2Zmc2NyZWVuU3RhdGUocmVuZGVyTGFuZXMpO1xuICAgICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IFNVU1BFTkRFRF9NQVJLRVI7XG5cbiAgICAgIHJldHVybiBmYWxsYmFja0ZyYWdtZW50O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbW91bnRTdXNwZW5zZVByaW1hcnlDaGlsZHJlbih3b3JrSW5Qcm9ncmVzcywgbmV4dFByaW1hcnlDaGlsZHJlbik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgaXMgYW4gdXBkYXRlLlxuICAgIC8vIFNwZWNpYWwgcGF0aCBmb3IgaHlkcmF0aW9uXG4gICAgdmFyIHByZXZTdGF0ZSA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcblxuICAgIGlmIChwcmV2U3RhdGUgIT09IG51bGwpIHtcbiAgICAgIHZhciBfZGVoeWRyYXRlZCA9IHByZXZTdGF0ZS5kZWh5ZHJhdGVkO1xuXG4gICAgICBpZiAoX2RlaHlkcmF0ZWQgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZURlaHlkcmF0ZWRTdXNwZW5zZUNvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgZGlkU3VzcGVuZCwgbmV4dFByb3BzLCBfZGVoeWRyYXRlZCwgcHJldlN0YXRlLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNob3dGYWxsYmFjaykge1xuICAgICAgdmFyIF9uZXh0RmFsbGJhY2tDaGlsZHJlbiA9IG5leHRQcm9wcy5mYWxsYmFjaztcbiAgICAgIHZhciBfbmV4dFByaW1hcnlDaGlsZHJlbiA9IG5leHRQcm9wcy5jaGlsZHJlbjtcbiAgICAgIHZhciBmYWxsYmFja0NoaWxkRnJhZ21lbnQgPSB1cGRhdGVTdXNwZW5zZUZhbGxiYWNrQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIF9uZXh0UHJpbWFyeUNoaWxkcmVuLCBfbmV4dEZhbGxiYWNrQ2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgICAgIHZhciBfcHJpbWFyeUNoaWxkRnJhZ21lbnQyID0gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG4gICAgICB2YXIgcHJldk9mZnNjcmVlblN0YXRlID0gY3VycmVudC5jaGlsZC5tZW1vaXplZFN0YXRlO1xuICAgICAgX3ByaW1hcnlDaGlsZEZyYWdtZW50Mi5tZW1vaXplZFN0YXRlID0gcHJldk9mZnNjcmVlblN0YXRlID09PSBudWxsID8gbW91bnRTdXNwZW5zZU9mZnNjcmVlblN0YXRlKHJlbmRlckxhbmVzKSA6IHVwZGF0ZVN1c3BlbnNlT2Zmc2NyZWVuU3RhdGUocHJldk9mZnNjcmVlblN0YXRlLCByZW5kZXJMYW5lcyk7XG5cbiAgICAgIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDIuY2hpbGRMYW5lcyA9IGdldFJlbWFpbmluZ1dvcmtJblByaW1hcnlUcmVlKGN1cnJlbnQsIHJlbmRlckxhbmVzKTtcbiAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBTVVNQRU5ERURfTUFSS0VSO1xuICAgICAgcmV0dXJuIGZhbGxiYWNrQ2hpbGRGcmFnbWVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIF9uZXh0UHJpbWFyeUNoaWxkcmVuMiA9IG5leHRQcm9wcy5jaGlsZHJlbjtcblxuICAgICAgdmFyIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDMgPSB1cGRhdGVTdXNwZW5zZVByaW1hcnlDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgX25leHRQcmltYXJ5Q2hpbGRyZW4yLCByZW5kZXJMYW5lcyk7XG5cbiAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgICAgcmV0dXJuIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDM7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1vdW50U3VzcGVuc2VQcmltYXJ5Q2hpbGRyZW4od29ya0luUHJvZ3Jlc3MsIHByaW1hcnlDaGlsZHJlbiwgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIG1vZGUgPSB3b3JrSW5Qcm9ncmVzcy5tb2RlO1xuICB2YXIgcHJpbWFyeUNoaWxkUHJvcHMgPSB7XG4gICAgbW9kZTogJ3Zpc2libGUnLFxuICAgIGNoaWxkcmVuOiBwcmltYXJ5Q2hpbGRyZW5cbiAgfTtcbiAgdmFyIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gbW91bnRXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKHByaW1hcnlDaGlsZFByb3BzLCBtb2RlKTtcbiAgcHJpbWFyeUNoaWxkRnJhZ21lbnQucmV0dXJuID0gd29ya0luUHJvZ3Jlc3M7XG4gIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG4gIHJldHVybiBwcmltYXJ5Q2hpbGRGcmFnbWVudDtcbn1cblxuZnVuY3Rpb24gbW91bnRTdXNwZW5zZUZhbGxiYWNrQ2hpbGRyZW4od29ya0luUHJvZ3Jlc3MsIHByaW1hcnlDaGlsZHJlbiwgZmFsbGJhY2tDaGlsZHJlbiwgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIG1vZGUgPSB3b3JrSW5Qcm9ncmVzcy5tb2RlO1xuICB2YXIgcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICB2YXIgcHJpbWFyeUNoaWxkUHJvcHMgPSB7XG4gICAgbW9kZTogJ2hpZGRlbicsXG4gICAgY2hpbGRyZW46IHByaW1hcnlDaGlsZHJlblxuICB9O1xuICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG4gIHZhciBmYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG5cbiAgaWYgKChtb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUgJiYgcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudCAhPT0gbnVsbCkge1xuICAgIC8vIEluIGxlZ2FjeSBtb2RlLCB3ZSBjb21taXQgdGhlIHByaW1hcnkgdHJlZSBhcyBpZiBpdCBzdWNjZXNzZnVsbHlcbiAgICAvLyBjb21wbGV0ZWQsIGV2ZW4gdGhvdWdoIGl0J3MgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLlxuICAgIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudDtcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5jaGlsZExhbmVzID0gTm9MYW5lcztcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5wZW5kaW5nUHJvcHMgPSBwcmltYXJ5Q2hpbGRQcm9wcztcblxuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAvLyBSZXNldCB0aGUgZHVyYXRpb25zIGZyb20gdGhlIGZpcnN0IHBhc3Mgc28gdGhleSBhcmVuJ3QgaW5jbHVkZWQgaW4gdGhlXG4gICAgICAvLyBmaW5hbCBhbW91bnRzLiBUaGlzIHNlZW1zIGNvdW50ZXJpbnR1aXRpdmUsIHNpbmNlIHdlJ3JlIGludGVudGlvbmFsbHlcbiAgICAgIC8vIG5vdCBtZWFzdXJpbmcgcGFydCBvZiB0aGUgcmVuZGVyIHBoYXNlLCBidXQgdGhpcyBtYWtlcyBpdCBtYXRjaCB3aGF0IHdlXG4gICAgICAvLyBkbyBpbiBDb25jdXJyZW50IE1vZGUuXG4gICAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5hY3R1YWxEdXJhdGlvbiA9IDA7XG4gICAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5hY3R1YWxTdGFydFRpbWUgPSAtMTtcbiAgICAgIHByaW1hcnlDaGlsZEZyYWdtZW50LnNlbGZCYXNlRHVyYXRpb24gPSAwO1xuICAgICAgcHJpbWFyeUNoaWxkRnJhZ21lbnQudHJlZUJhc2VEdXJhdGlvbiA9IDA7XG4gICAgfVxuXG4gICAgZmFsbGJhY2tDaGlsZEZyYWdtZW50ID0gY3JlYXRlRmliZXJGcm9tRnJhZ21lbnQoZmFsbGJhY2tDaGlsZHJlbiwgbW9kZSwgcmVuZGVyTGFuZXMsIG51bGwpO1xuICB9IGVsc2Uge1xuICAgIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gbW91bnRXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKHByaW1hcnlDaGlsZFByb3BzLCBtb2RlKTtcbiAgICBmYWxsYmFja0NoaWxkRnJhZ21lbnQgPSBjcmVhdGVGaWJlckZyb21GcmFnbWVudChmYWxsYmFja0NoaWxkcmVuLCBtb2RlLCByZW5kZXJMYW5lcywgbnVsbCk7XG4gIH1cblxuICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5yZXR1cm4gPSB3b3JrSW5Qcm9ncmVzcztcbiAgZmFsbGJhY2tDaGlsZEZyYWdtZW50LnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5zaWJsaW5nID0gZmFsbGJhY2tDaGlsZEZyYWdtZW50O1xuICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IHByaW1hcnlDaGlsZEZyYWdtZW50O1xuICByZXR1cm4gZmFsbGJhY2tDaGlsZEZyYWdtZW50O1xufVxuXG5mdW5jdGlvbiBtb3VudFdvcmtJblByb2dyZXNzT2Zmc2NyZWVuRmliZXIob2Zmc2NyZWVuUHJvcHMsIG1vZGUsIHJlbmRlckxhbmVzKSB7XG4gIC8vIFRoZSBwcm9wcyBhcmd1bWVudCB0byBgY3JlYXRlRmliZXJGcm9tT2Zmc2NyZWVuYCBpcyBgYW55YCB0eXBlZCwgc28gd2UgdXNlXG4gIC8vIHRoaXMgd3JhcHBlciBmdW5jdGlvbiB0byBjb25zdHJhaW4gaXQuXG4gIHJldHVybiBjcmVhdGVGaWJlckZyb21PZmZzY3JlZW4ob2Zmc2NyZWVuUHJvcHMsIG1vZGUsIE5vTGFuZXMsIG51bGwpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKGN1cnJlbnQsIG9mZnNjcmVlblByb3BzKSB7XG4gIC8vIFRoZSBwcm9wcyBhcmd1bWVudCB0byBgY3JlYXRlV29ya0luUHJvZ3Jlc3NgIGlzIGBhbnlgIHR5cGVkLCBzbyB3ZSB1c2UgdGhpc1xuICAvLyB3cmFwcGVyIGZ1bmN0aW9uIHRvIGNvbnN0cmFpbiBpdC5cbiAgcmV0dXJuIGNyZWF0ZVdvcmtJblByb2dyZXNzKGN1cnJlbnQsIG9mZnNjcmVlblByb3BzKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlU3VzcGVuc2VQcmltYXJ5Q2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHByaW1hcnlDaGlsZHJlbiwgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIGN1cnJlbnRQcmltYXJ5Q2hpbGRGcmFnbWVudCA9IGN1cnJlbnQuY2hpbGQ7XG4gIHZhciBjdXJyZW50RmFsbGJhY2tDaGlsZEZyYWdtZW50ID0gY3VycmVudFByaW1hcnlDaGlsZEZyYWdtZW50LnNpYmxpbmc7XG4gIHZhciBwcmltYXJ5Q2hpbGRGcmFnbWVudCA9IHVwZGF0ZVdvcmtJblByb2dyZXNzT2Zmc2NyZWVuRmliZXIoY3VycmVudFByaW1hcnlDaGlsZEZyYWdtZW50LCB7XG4gICAgbW9kZTogJ3Zpc2libGUnLFxuICAgIGNoaWxkcmVuOiBwcmltYXJ5Q2hpbGRyZW5cbiAgfSk7XG5cbiAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUpIHtcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5sYW5lcyA9IHJlbmRlckxhbmVzO1xuICB9XG5cbiAgcHJpbWFyeUNoaWxkRnJhZ21lbnQucmV0dXJuID0gd29ya0luUHJvZ3Jlc3M7XG4gIHByaW1hcnlDaGlsZEZyYWdtZW50LnNpYmxpbmcgPSBudWxsO1xuXG4gIGlmIChjdXJyZW50RmFsbGJhY2tDaGlsZEZyYWdtZW50ICE9PSBudWxsKSB7XG4gICAgLy8gRGVsZXRlIHRoZSBmYWxsYmFjayBjaGlsZCBmcmFnbWVudFxuICAgIHZhciBkZWxldGlvbnMgPSB3b3JrSW5Qcm9ncmVzcy5kZWxldGlvbnM7XG5cbiAgICBpZiAoZGVsZXRpb25zID09PSBudWxsKSB7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5kZWxldGlvbnMgPSBbY3VycmVudEZhbGxiYWNrQ2hpbGRGcmFnbWVudF07XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBDaGlsZERlbGV0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGlvbnMucHVzaChjdXJyZW50RmFsbGJhY2tDaGlsZEZyYWdtZW50KTtcbiAgICB9XG4gIH1cblxuICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IHByaW1hcnlDaGlsZEZyYWdtZW50O1xuICByZXR1cm4gcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN1c3BlbnNlRmFsbGJhY2tDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcHJpbWFyeUNoaWxkcmVuLCBmYWxsYmFja0NoaWxkcmVuLCByZW5kZXJMYW5lcykge1xuICB2YXIgbW9kZSA9IHdvcmtJblByb2dyZXNzLm1vZGU7XG4gIHZhciBjdXJyZW50UHJpbWFyeUNoaWxkRnJhZ21lbnQgPSBjdXJyZW50LmNoaWxkO1xuICB2YXIgY3VycmVudEZhbGxiYWNrQ2hpbGRGcmFnbWVudCA9IGN1cnJlbnRQcmltYXJ5Q2hpbGRGcmFnbWVudC5zaWJsaW5nO1xuICB2YXIgcHJpbWFyeUNoaWxkUHJvcHMgPSB7XG4gICAgbW9kZTogJ2hpZGRlbicsXG4gICAgY2hpbGRyZW46IHByaW1hcnlDaGlsZHJlblxuICB9O1xuICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG5cbiAgaWYgKCAvLyBJbiBsZWdhY3kgbW9kZSwgd2UgY29tbWl0IHRoZSBwcmltYXJ5IHRyZWUgYXMgaWYgaXQgc3VjY2Vzc2Z1bGx5XG4gIC8vIGNvbXBsZXRlZCwgZXZlbiB0aG91Z2ggaXQncyBpbiBhbiBpbmNvbnNpc3RlbnQgc3RhdGUuXG4gIChtb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUgJiYgLy8gTWFrZSBzdXJlIHdlJ3JlIG9uIHRoZSBzZWNvbmQgcGFzcywgaS5lLiB0aGUgcHJpbWFyeSBjaGlsZCBmcmFnbWVudCB3YXNcbiAgLy8gYWxyZWFkeSBjbG9uZWQuIEluIGxlZ2FjeSBtb2RlLCB0aGUgb25seSBjYXNlIHdoZXJlIHRoaXMgaXNuJ3QgdHJ1ZSBpc1xuICAvLyB3aGVuIERldlRvb2xzIGZvcmNlcyB1cyB0byBkaXNwbGF5IGEgZmFsbGJhY2s7IHdlIHNraXAgdGhlIGZpcnN0IHJlbmRlclxuICAvLyBwYXNzIGVudGlyZWx5IGFuZCBnbyBzdHJhaWdodCB0byByZW5kZXJpbmcgdGhlIGZhbGxiYWNrLiAoSW4gQ29uY3VycmVudFxuICAvLyBNb2RlLCBTdXNwZW5zZUxpc3QgY2FuIGFsc28gdHJpZ2dlciB0aGlzIHNjZW5hcmlvLCBidXQgdGhpcyBpcyBhIGxlZ2FjeS1cbiAgLy8gb25seSBjb2RlcGF0aC4pXG4gIHdvcmtJblByb2dyZXNzLmNoaWxkICE9PSBjdXJyZW50UHJpbWFyeUNoaWxkRnJhZ21lbnQpIHtcbiAgICB2YXIgcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudDtcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5jaGlsZExhbmVzID0gTm9MYW5lcztcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5wZW5kaW5nUHJvcHMgPSBwcmltYXJ5Q2hpbGRQcm9wcztcblxuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAvLyBSZXNldCB0aGUgZHVyYXRpb25zIGZyb20gdGhlIGZpcnN0IHBhc3Mgc28gdGhleSBhcmVuJ3QgaW5jbHVkZWQgaW4gdGhlXG4gICAgICAvLyBmaW5hbCBhbW91bnRzLiBUaGlzIHNlZW1zIGNvdW50ZXJpbnR1aXRpdmUsIHNpbmNlIHdlJ3JlIGludGVudGlvbmFsbHlcbiAgICAgIC8vIG5vdCBtZWFzdXJpbmcgcGFydCBvZiB0aGUgcmVuZGVyIHBoYXNlLCBidXQgdGhpcyBtYWtlcyBpdCBtYXRjaCB3aGF0IHdlXG4gICAgICAvLyBkbyBpbiBDb25jdXJyZW50IE1vZGUuXG4gICAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5hY3R1YWxEdXJhdGlvbiA9IDA7XG4gICAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5hY3R1YWxTdGFydFRpbWUgPSAtMTtcbiAgICAgIHByaW1hcnlDaGlsZEZyYWdtZW50LnNlbGZCYXNlRHVyYXRpb24gPSBjdXJyZW50UHJpbWFyeUNoaWxkRnJhZ21lbnQuc2VsZkJhc2VEdXJhdGlvbjtcbiAgICAgIHByaW1hcnlDaGlsZEZyYWdtZW50LnRyZWVCYXNlRHVyYXRpb24gPSBjdXJyZW50UHJpbWFyeUNoaWxkRnJhZ21lbnQudHJlZUJhc2VEdXJhdGlvbjtcbiAgICB9IC8vIFRoZSBmYWxsYmFjayBmaWJlciB3YXMgYWRkZWQgYXMgYSBkZWxldGlvbiBkdXJpbmcgdGhlIGZpcnN0IHBhc3MuXG4gICAgLy8gSG93ZXZlciwgc2luY2Ugd2UncmUgZ29pbmcgdG8gcmVtYWluIG9uIHRoZSBmYWxsYmFjaywgd2Ugbm8gbG9uZ2VyIHdhbnRcbiAgICAvLyB0byBkZWxldGUgaXQuXG5cblxuICAgIHdvcmtJblByb2dyZXNzLmRlbGV0aW9ucyA9IG51bGw7XG4gIH0gZWxzZSB7XG4gICAgcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKGN1cnJlbnRQcmltYXJ5Q2hpbGRGcmFnbWVudCwgcHJpbWFyeUNoaWxkUHJvcHMpOyAvLyBTaW5jZSB3ZSdyZSByZXVzaW5nIGEgY3VycmVudCB0cmVlLCB3ZSBuZWVkIHRvIHJldXNlIHRoZSBmbGFncywgdG9vLlxuICAgIC8vIChXZSBkb24ndCBkbyB0aGlzIGluIGxlZ2FjeSBtb2RlLCBiZWNhdXNlIGluIGxlZ2FjeSBtb2RlIHdlIGRvbid0IHJlLXVzZVxuICAgIC8vIHRoZSBjdXJyZW50IHRyZWU7IHNlZSBwcmV2aW91cyBicmFuY2guKVxuXG4gICAgcHJpbWFyeUNoaWxkRnJhZ21lbnQuc3VidHJlZUZsYWdzID0gY3VycmVudFByaW1hcnlDaGlsZEZyYWdtZW50LnN1YnRyZWVGbGFncyAmIFN0YXRpY01hc2s7XG4gIH1cblxuICB2YXIgZmFsbGJhY2tDaGlsZEZyYWdtZW50O1xuXG4gIGlmIChjdXJyZW50RmFsbGJhY2tDaGlsZEZyYWdtZW50ICE9PSBudWxsKSB7XG4gICAgZmFsbGJhY2tDaGlsZEZyYWdtZW50ID0gY3JlYXRlV29ya0luUHJvZ3Jlc3MoY3VycmVudEZhbGxiYWNrQ2hpbGRGcmFnbWVudCwgZmFsbGJhY2tDaGlsZHJlbik7XG4gIH0gZWxzZSB7XG4gICAgZmFsbGJhY2tDaGlsZEZyYWdtZW50ID0gY3JlYXRlRmliZXJGcm9tRnJhZ21lbnQoZmFsbGJhY2tDaGlsZHJlbiwgbW9kZSwgcmVuZGVyTGFuZXMsIG51bGwpOyAvLyBOZWVkcyBhIHBsYWNlbWVudCBlZmZlY3QgYmVjYXVzZSB0aGUgcGFyZW50ICh0aGUgU3VzcGVuc2UgYm91bmRhcnkpIGFscmVhZHlcbiAgICAvLyBtb3VudGVkIGJ1dCB0aGlzIGlzIGEgbmV3IGZpYmVyLlxuXG4gICAgZmFsbGJhY2tDaGlsZEZyYWdtZW50LmZsYWdzIHw9IFBsYWNlbWVudDtcbiAgfVxuXG4gIGZhbGxiYWNrQ2hpbGRGcmFnbWVudC5yZXR1cm4gPSB3b3JrSW5Qcm9ncmVzcztcbiAgcHJpbWFyeUNoaWxkRnJhZ21lbnQucmV0dXJuID0gd29ya0luUHJvZ3Jlc3M7XG4gIHByaW1hcnlDaGlsZEZyYWdtZW50LnNpYmxpbmcgPSBmYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG4gIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG4gIHJldHVybiBmYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG59XG5cbmZ1bmN0aW9uIHJldHJ5U3VzcGVuc2VDb21wb25lbnRXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcywgcmVjb3ZlcmFibGVFcnJvcikge1xuICAvLyBGYWxsaW5nIGJhY2sgdG8gY2xpZW50IHJlbmRlcmluZy4gQmVjYXVzZSB0aGlzIGhhcyBwZXJmb3JtYW5jZVxuICAvLyBpbXBsaWNhdGlvbnMsIGl0J3MgY29uc2lkZXJlZCBhIHJlY292ZXJhYmxlIGVycm9yLCBldmVuIHRob3VnaCB0aGUgdXNlclxuICAvLyBsaWtlbHkgd29uJ3Qgb2JzZXJ2ZSBhbnl0aGluZyB3cm9uZyB3aXRoIHRoZSBVSS5cbiAgLy9cbiAgLy8gVGhlIGVycm9yIGlzIHBhc3NlZCBpbiBhcyBhbiBhcmd1bWVudCB0byBlbmZvcmNlIHRoYXQgZXZlcnkgY2FsbGVyIHByb3ZpZGVcbiAgLy8gYSBjdXN0b20gbWVzc2FnZSwgb3IgZXhwbGljaXRseSBvcHQgb3V0IChjdXJyZW50bHkgdGhlIG9ubHkgcGF0aCB0aGF0IG9wdHNcbiAgLy8gb3V0IGlzIGxlZ2FjeSBtb2RlOyBldmVyeSBjb25jdXJyZW50IHBhdGggcHJvdmlkZXMgYW4gZXJyb3IpLlxuICBpZiAocmVjb3ZlcmFibGVFcnJvciAhPT0gbnVsbCkge1xuICAgIHF1ZXVlSHlkcmF0aW9uRXJyb3IocmVjb3ZlcmFibGVFcnJvcik7XG4gIH0gLy8gVGhpcyB3aWxsIGFkZCB0aGUgb2xkIGZpYmVyIHRvIHRoZSBkZWxldGlvbiBsaXN0XG5cblxuICByZWNvbmNpbGVDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgY3VycmVudC5jaGlsZCwgbnVsbCwgcmVuZGVyTGFuZXMpOyAvLyBXZSdyZSBub3cgbm90IHN1c3BlbmRlZCBub3IgZGVoeWRyYXRlZC5cblxuICB2YXIgbmV4dFByb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgcHJpbWFyeUNoaWxkcmVuID0gbmV4dFByb3BzLmNoaWxkcmVuO1xuICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSBtb3VudFN1c3BlbnNlUHJpbWFyeUNoaWxkcmVuKHdvcmtJblByb2dyZXNzLCBwcmltYXJ5Q2hpbGRyZW4pOyAvLyBOZWVkcyBhIHBsYWNlbWVudCBlZmZlY3QgYmVjYXVzZSB0aGUgcGFyZW50ICh0aGUgU3VzcGVuc2UgYm91bmRhcnkpIGFscmVhZHlcbiAgLy8gbW91bnRlZCBidXQgdGhpcyBpcyBhIG5ldyBmaWJlci5cblxuICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5mbGFncyB8PSBQbGFjZW1lbnQ7XG4gIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICByZXR1cm4gcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG59XG5cbmZ1bmN0aW9uIG1vdW50U3VzcGVuc2VGYWxsYmFja0FmdGVyUmV0cnlXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBwcmltYXJ5Q2hpbGRyZW4sIGZhbGxiYWNrQ2hpbGRyZW4sIHJlbmRlckxhbmVzKSB7XG4gIHZhciBmaWJlck1vZGUgPSB3b3JrSW5Qcm9ncmVzcy5tb2RlO1xuICB2YXIgcHJpbWFyeUNoaWxkUHJvcHMgPSB7XG4gICAgbW9kZTogJ3Zpc2libGUnLFxuICAgIGNoaWxkcmVuOiBwcmltYXJ5Q2hpbGRyZW5cbiAgfTtcbiAgdmFyIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gbW91bnRXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKHByaW1hcnlDaGlsZFByb3BzLCBmaWJlck1vZGUpO1xuICB2YXIgZmFsbGJhY2tDaGlsZEZyYWdtZW50ID0gY3JlYXRlRmliZXJGcm9tRnJhZ21lbnQoZmFsbGJhY2tDaGlsZHJlbiwgZmliZXJNb2RlLCByZW5kZXJMYW5lcywgbnVsbCk7IC8vIE5lZWRzIGEgcGxhY2VtZW50IGVmZmVjdCBiZWNhdXNlIHRoZSBwYXJlbnQgKHRoZSBTdXNwZW5zZVxuICAvLyBib3VuZGFyeSkgYWxyZWFkeSBtb3VudGVkIGJ1dCB0aGlzIGlzIGEgbmV3IGZpYmVyLlxuXG4gIGZhbGxiYWNrQ2hpbGRGcmFnbWVudC5mbGFncyB8PSBQbGFjZW1lbnQ7XG4gIHByaW1hcnlDaGlsZEZyYWdtZW50LnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICBmYWxsYmFja0NoaWxkRnJhZ21lbnQucmV0dXJuID0gd29ya0luUHJvZ3Jlc3M7XG4gIHByaW1hcnlDaGlsZEZyYWdtZW50LnNpYmxpbmcgPSBmYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG4gIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG5cbiAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAvLyBXZSB3aWxsIGhhdmUgZHJvcHBlZCB0aGUgZWZmZWN0IGxpc3Qgd2hpY2ggY29udGFpbnMgdGhlXG4gICAgLy8gZGVsZXRpb24uIFdlIG5lZWQgdG8gcmVjb25jaWxlIHRvIGRlbGV0ZSB0aGUgY3VycmVudCBjaGlsZC5cbiAgICByZWNvbmNpbGVDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgY3VycmVudC5jaGlsZCwgbnVsbCwgcmVuZGVyTGFuZXMpO1xuICB9XG5cbiAgcmV0dXJuIGZhbGxiYWNrQ2hpbGRGcmFnbWVudDtcbn1cblxuZnVuY3Rpb24gbW91bnREZWh5ZHJhdGVkU3VzcGVuc2VDb21wb25lbnQod29ya0luUHJvZ3Jlc3MsIHN1c3BlbnNlSW5zdGFuY2UsIHJlbmRlckxhbmVzKSB7XG4gIC8vIER1cmluZyB0aGUgZmlyc3QgcGFzcywgd2UnbGwgYmFpbCBvdXQgYW5kIG5vdCBkcmlsbCBpbnRvIHRoZSBjaGlsZHJlbi5cbiAgLy8gSW5zdGVhZCwgd2UnbGwgbGVhdmUgdGhlIGNvbnRlbnQgaW4gcGxhY2UgYW5kIHRyeSB0byBoeWRyYXRlIGl0IGxhdGVyLlxuICBpZiAoKHdvcmtJblByb2dyZXNzLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgPT09IE5vTW9kZSkge1xuICAgIHtcbiAgICAgIGVycm9yKCdDYW5ub3QgaHlkcmF0ZSBTdXNwZW5zZSBpbiBsZWdhY3kgbW9kZS4gU3dpdGNoIGZyb20gJyArICdSZWFjdERPTS5oeWRyYXRlKGVsZW1lbnQsIGNvbnRhaW5lcikgdG8gJyArICdSZWFjdERPTUNsaWVudC5oeWRyYXRlUm9vdChjb250YWluZXIsIDxBcHAgLz4pJyArICcucmVuZGVyKGVsZW1lbnQpIG9yIHJlbW92ZSB0aGUgU3VzcGVuc2UgY29tcG9uZW50cyBmcm9tICcgKyAndGhlIHNlcnZlciByZW5kZXJlZCBjb21wb25lbnRzLicpO1xuICAgIH1cblxuICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gbGFuZVRvTGFuZXMoU3luY0xhbmUpO1xuICB9IGVsc2UgaWYgKGlzU3VzcGVuc2VJbnN0YW5jZUZhbGxiYWNrKHN1c3BlbnNlSW5zdGFuY2UpKSB7XG4gICAgLy8gVGhpcyBpcyBhIGNsaWVudC1vbmx5IGJvdW5kYXJ5LiBTaW5jZSB3ZSB3b24ndCBnZXQgYW55IGNvbnRlbnQgZnJvbSB0aGUgc2VydmVyXG4gICAgLy8gZm9yIHRoaXMsIHdlIG5lZWQgdG8gc2NoZWR1bGUgdGhhdCBhdCBhIGhpZ2hlciBwcmlvcml0eSBiYXNlZCBvbiB3aGVuIGl0IHdvdWxkXG4gICAgLy8gaGF2ZSB0aW1lZCBvdXQuIEluIHRoZW9yeSB3ZSBjb3VsZCByZW5kZXIgaXQgaW4gdGhpcyBwYXNzIGJ1dCBpdCB3b3VsZCBoYXZlIHRoZVxuICAgIC8vIHdyb25nIHByaW9yaXR5IGFzc29jaWF0ZWQgd2l0aCBpdCBhbmQgd2lsbCBwcmV2ZW50IGh5ZHJhdGlvbiBvZiBwYXJlbnQgcGF0aC5cbiAgICAvLyBJbnN0ZWFkLCB3ZSdsbCBsZWF2ZSB3b3JrIGxlZnQgb24gaXQgdG8gcmVuZGVyIGl0IGluIGEgc2VwYXJhdGUgY29tbWl0LlxuICAgIC8vIFRPRE8gVGhpcyB0aW1lIHNob3VsZCBiZSB0aGUgdGltZSBhdCB3aGljaCB0aGUgc2VydmVyIHJlbmRlcmVkIHJlc3BvbnNlIHRoYXQgaXNcbiAgICAvLyBhIHBhcmVudCB0byB0aGlzIGJvdW5kYXJ5IHdhcyBkaXNwbGF5ZWQuIEhvd2V2ZXIsIHNpbmNlIHdlIGN1cnJlbnRseSBkb24ndCBoYXZlXG4gICAgLy8gYSBwcm90b2NvbCB0byB0cmFuc2ZlciB0aGF0IHRpbWUsIHdlJ2xsIGp1c3QgZXN0aW1hdGUgaXQgYnkgdXNpbmcgdGhlIGN1cnJlbnRcbiAgICAvLyB0aW1lLiBUaGlzIHdpbGwgbWVhbiB0aGF0IFN1c3BlbnNlIHRpbWVvdXRzIGFyZSBzbGlnaHRseSBzaGlmdGVkIHRvIGxhdGVyIHRoYW5cbiAgICAvLyB0aGV5IHNob3VsZCBiZS5cbiAgICAvLyBTY2hlZHVsZSBhIG5vcm1hbCBwcmkgdXBkYXRlIHRvIHJlbmRlciB0aGlzIGNvbnRlbnQuXG4gICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBsYW5lVG9MYW5lcyhEZWZhdWx0SHlkcmF0aW9uTGFuZSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gV2UnbGwgY29udGludWUgaHlkcmF0aW5nIHRoZSByZXN0IGF0IG9mZnNjcmVlbiBwcmlvcml0eSBzaW5jZSB3ZSdsbCBhbHJlYWR5XG4gICAgLy8gYmUgc2hvd2luZyB0aGUgcmlnaHQgY29udGVudCBjb21pbmcgZnJvbSB0aGUgc2VydmVyLCBpdCBpcyBubyBydXNoLlxuICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gbGFuZVRvTGFuZXMoT2Zmc2NyZWVuTGFuZSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gdXBkYXRlRGVoeWRyYXRlZFN1c3BlbnNlQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBkaWRTdXNwZW5kLCBuZXh0UHJvcHMsIHN1c3BlbnNlSW5zdGFuY2UsIHN1c3BlbnNlU3RhdGUsIHJlbmRlckxhbmVzKSB7XG4gIGlmICghZGlkU3VzcGVuZCkge1xuICAgIC8vIFRoaXMgaXMgdGhlIGZpcnN0IHJlbmRlciBwYXNzLiBBdHRlbXB0IHRvIGh5ZHJhdGUuXG4gICAgLy8gV2Ugc2hvdWxkIG5ldmVyIGJlIGh5ZHJhdGluZyBhdCB0aGlzIHBvaW50IGJlY2F1c2UgaXQgaXMgdGhlIGZpcnN0IHBhc3MsXG4gICAgLy8gYnV0IGFmdGVyIHdlJ3ZlIGFscmVhZHkgY29tbWl0dGVkIG9uY2UuXG4gICAgd2FybklmSHlkcmF0aW5nKCk7XG5cbiAgICBpZiAoKHdvcmtJblByb2dyZXNzLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgPT09IE5vTW9kZSkge1xuICAgICAgcmV0dXJuIHJldHJ5U3VzcGVuc2VDb21wb25lbnRXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcywgLy8gVE9ETzogV2hlbiB3ZSBkZWxldGUgbGVnYWN5IG1vZGUsIHdlIHNob3VsZCBtYWtlIHRoaXMgZXJyb3IgYXJndW1lbnRcbiAgICAgIC8vIHJlcXVpcmVkIOKAlCBldmVyeSBjb25jdXJyZW50IG1vZGUgcGF0aCB0aGF0IGNhdXNlcyBoeWRyYXRpb24gdG9cbiAgICAgIC8vIGRlLW9wdCB0byBjbGllbnQgcmVuZGVyaW5nIHNob3VsZCBoYXZlIGFuIGVycm9yIG1lc3NhZ2UuXG4gICAgICBudWxsKTtcbiAgICB9XG5cbiAgICBpZiAoaXNTdXNwZW5zZUluc3RhbmNlRmFsbGJhY2soc3VzcGVuc2VJbnN0YW5jZSkpIHtcbiAgICAgIC8vIFRoaXMgYm91bmRhcnkgaXMgaW4gYSBwZXJtYW5lbnQgZmFsbGJhY2sgc3RhdGUuIEluIHRoaXMgY2FzZSwgd2UnbGwgbmV2ZXJcbiAgICAgIC8vIGdldCBhbiB1cGRhdGUgYW5kIHdlJ2xsIG5ldmVyIGJlIGFibGUgdG8gaHlkcmF0ZSB0aGUgZmluYWwgY29udGVudC4gTGV0J3MganVzdCB0cnkgdGhlXG4gICAgICAvLyBjbGllbnQgc2lkZSByZW5kZXIgaW5zdGVhZC5cbiAgICAgIHZhciBkaWdlc3QsIG1lc3NhZ2UsIHN0YWNrO1xuXG4gICAgICB7XG4gICAgICAgIHZhciBfZ2V0U3VzcGVuc2VJbnN0YW5jZUYgPSBnZXRTdXNwZW5zZUluc3RhbmNlRmFsbGJhY2tFcnJvckRldGFpbHMoc3VzcGVuc2VJbnN0YW5jZSk7XG5cbiAgICAgICAgZGlnZXN0ID0gX2dldFN1c3BlbnNlSW5zdGFuY2VGLmRpZ2VzdDtcbiAgICAgICAgbWVzc2FnZSA9IF9nZXRTdXNwZW5zZUluc3RhbmNlRi5tZXNzYWdlO1xuICAgICAgICBzdGFjayA9IF9nZXRTdXNwZW5zZUluc3RhbmNlRi5zdGFjaztcbiAgICAgIH1cblxuICAgICAgdmFyIGVycm9yO1xuXG4gICAgICBpZiAobWVzc2FnZSkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2Rlc1xuICAgICAgICBlcnJvciA9IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yID0gbmV3IEVycm9yKCdUaGUgc2VydmVyIGNvdWxkIG5vdCBmaW5pc2ggdGhpcyBTdXNwZW5zZSBib3VuZGFyeSwgbGlrZWx5ICcgKyAnZHVlIHRvIGFuIGVycm9yIGR1cmluZyBzZXJ2ZXIgcmVuZGVyaW5nLiBTd2l0Y2hlZCB0byAnICsgJ2NsaWVudCByZW5kZXJpbmcuJyk7XG4gICAgICB9XG5cbiAgICAgIHZhciBjYXB0dXJlZFZhbHVlID0gY3JlYXRlQ2FwdHVyZWRWYWx1ZShlcnJvciwgZGlnZXN0LCBzdGFjayk7XG4gICAgICByZXR1cm4gcmV0cnlTdXNwZW5zZUNvbXBvbmVudFdpdGhvdXRIeWRyYXRpbmcoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzLCBjYXB0dXJlZFZhbHVlKTtcbiAgICB9XG4gICAgLy8gYW55IGNvbnRleHQgaGFzIGNoYW5nZWQsIHdlIG5lZWQgdG8gdHJlYXQgaXMgYXMgaWYgdGhlIGlucHV0IG1pZ2h0IGhhdmUgY2hhbmdlZC5cblxuXG4gICAgdmFyIGhhc0NvbnRleHRDaGFuZ2VkID0gaW5jbHVkZXNTb21lTGFuZShyZW5kZXJMYW5lcywgY3VycmVudC5jaGlsZExhbmVzKTtcblxuICAgIGlmIChkaWRSZWNlaXZlVXBkYXRlIHx8IGhhc0NvbnRleHRDaGFuZ2VkKSB7XG4gICAgICAvLyBUaGlzIGJvdW5kYXJ5IGhhcyBjaGFuZ2VkIHNpbmNlIHRoZSBmaXJzdCByZW5kZXIuIFRoaXMgbWVhbnMgdGhhdCB3ZSBhcmUgbm93IHVuYWJsZSB0b1xuICAgICAgLy8gaHlkcmF0ZSBpdC4gV2UgbWlnaHQgc3RpbGwgYmUgYWJsZSB0byBoeWRyYXRlIGl0IHVzaW5nIGEgaGlnaGVyIHByaW9yaXR5IGxhbmUuXG4gICAgICB2YXIgcm9vdCA9IGdldFdvcmtJblByb2dyZXNzUm9vdCgpO1xuXG4gICAgICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgICAgICB2YXIgYXR0ZW1wdEh5ZHJhdGlvbkF0TGFuZSA9IGdldEJ1bXBlZExhbmVGb3JIeWRyYXRpb24ocm9vdCwgcmVuZGVyTGFuZXMpO1xuXG4gICAgICAgIGlmIChhdHRlbXB0SHlkcmF0aW9uQXRMYW5lICE9PSBOb0xhbmUgJiYgYXR0ZW1wdEh5ZHJhdGlvbkF0TGFuZSAhPT0gc3VzcGVuc2VTdGF0ZS5yZXRyeUxhbmUpIHtcbiAgICAgICAgICAvLyBJbnRlbnRpb25hbGx5IG11dGF0aW5nIHNpbmNlIHRoaXMgcmVuZGVyIHdpbGwgZ2V0IGludGVycnVwdGVkLiBUaGlzXG4gICAgICAgICAgLy8gaXMgb25lIG9mIHRoZSB2ZXJ5IHJhcmUgdGltZXMgd2hlcmUgd2UgbXV0YXRlIHRoZSBjdXJyZW50IHRyZWVcbiAgICAgICAgICAvLyBkdXJpbmcgdGhlIHJlbmRlciBwaGFzZS5cbiAgICAgICAgICBzdXNwZW5zZVN0YXRlLnJldHJ5TGFuZSA9IGF0dGVtcHRIeWRyYXRpb25BdExhbmU7IC8vIFRPRE86IElkZWFsbHkgdGhpcyB3b3VsZCBpbmhlcml0IHRoZSBldmVudCB0aW1lIG9mIHRoZSBjdXJyZW50IHJlbmRlclxuXG4gICAgICAgICAgdmFyIGV2ZW50VGltZSA9IE5vVGltZXN0YW1wO1xuICAgICAgICAgIGVucXVldWVDb25jdXJyZW50UmVuZGVyRm9yTGFuZShjdXJyZW50LCBhdHRlbXB0SHlkcmF0aW9uQXRMYW5lKTtcbiAgICAgICAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgY3VycmVudCwgYXR0ZW1wdEh5ZHJhdGlvbkF0TGFuZSwgZXZlbnRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgfSAvLyBJZiB3ZSBoYXZlIHNjaGVkdWxlZCBoaWdoZXIgcHJpIHdvcmsgYWJvdmUsIHRoaXMgd2lsbCBwcm9iYWJseSBqdXN0IGFib3J0IHRoZSByZW5kZXJcbiAgICAgIC8vIHNpbmNlIHdlIG5vdyBoYXZlIGhpZ2hlciBwcmlvcml0eSB3b3JrLCBidXQgaW4gY2FzZSBpdCBkb2Vzbid0LCB3ZSBuZWVkIHRvIHByZXBhcmUgdG9cbiAgICAgIC8vIHJlbmRlciBzb21ldGhpbmcsIGlmIHdlIHRpbWUgb3V0LiBFdmVuIGlmIHRoYXQgcmVxdWlyZXMgdXMgdG8gZGVsZXRlIGV2ZXJ5dGhpbmcgYW5kXG4gICAgICAvLyBza2lwIGh5ZHJhdGlvbi5cbiAgICAgIC8vIERlbGF5IGhhdmluZyB0byBkbyB0aGlzIGFzIGxvbmcgYXMgdGhlIHN1c3BlbnNlIHRpbWVvdXQgYWxsb3dzIHVzLlxuXG5cbiAgICAgIHJlbmRlckRpZFN1c3BlbmREZWxheUlmUG9zc2libGUoKTtcblxuICAgICAgdmFyIF9jYXB0dXJlZFZhbHVlID0gY3JlYXRlQ2FwdHVyZWRWYWx1ZShuZXcgRXJyb3IoJ1RoaXMgU3VzcGVuc2UgYm91bmRhcnkgcmVjZWl2ZWQgYW4gdXBkYXRlIGJlZm9yZSBpdCBmaW5pc2hlZCAnICsgJ2h5ZHJhdGluZy4gVGhpcyBjYXVzZWQgdGhlIGJvdW5kYXJ5IHRvIHN3aXRjaCB0byBjbGllbnQgcmVuZGVyaW5nLiAnICsgJ1RoZSB1c3VhbCB3YXkgdG8gZml4IHRoaXMgaXMgdG8gd3JhcCB0aGUgb3JpZ2luYWwgdXBkYXRlICcgKyAnaW4gc3RhcnRUcmFuc2l0aW9uLicpKTtcblxuICAgICAgcmV0dXJuIHJldHJ5U3VzcGVuc2VDb21wb25lbnRXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcywgX2NhcHR1cmVkVmFsdWUpO1xuICAgIH0gZWxzZSBpZiAoaXNTdXNwZW5zZUluc3RhbmNlUGVuZGluZyhzdXNwZW5zZUluc3RhbmNlKSkge1xuICAgICAgLy8gVGhpcyBjb21wb25lbnQgaXMgc3RpbGwgcGVuZGluZyBtb3JlIGRhdGEgZnJvbSB0aGUgc2VydmVyLCBzbyB3ZSBjYW4ndCBoeWRyYXRlIGl0c1xuICAgICAgLy8gY29udGVudC4gV2UgdHJlYXQgaXQgYXMgaWYgdGhpcyBjb21wb25lbnQgc3VzcGVuZGVkIGl0c2VsZi4gSXQgbWlnaHQgc2VlbSBhcyBpZlxuICAgICAgLy8gd2UgY291bGQganVzdCB0cnkgdG8gcmVuZGVyIGl0IGNsaWVudC1zaWRlIGluc3RlYWQuIEhvd2V2ZXIsIHRoaXMgd2lsbCBwZXJmb3JtIGFcbiAgICAgIC8vIGxvdCBvZiB1bm5lY2Vzc2FyeSB3b3JrIGFuZCBpcyB1bmxpa2VseSB0byBjb21wbGV0ZSBzaW5jZSBpdCBvZnRlbiB3aWxsIHN1c3BlbmRcbiAgICAgIC8vIG9uIG1pc3NpbmcgZGF0YSBhbnl3YXkuIEFkZGl0aW9uYWxseSwgdGhlIHNlcnZlciBtaWdodCBiZSBhYmxlIHRvIHJlbmRlciBtb3JlXG4gICAgICAvLyB0aGFuIHdlIGNhbiBvbiB0aGUgY2xpZW50IHlldC4gSW4gdGhhdCBjYXNlIHdlJ2QgZW5kIHVwIHdpdGggbW9yZSBmYWxsYmFjayBzdGF0ZXNcbiAgICAgIC8vIG9uIHRoZSBjbGllbnQgdGhhbiBpZiB3ZSBqdXN0IGxlYXZlIGl0IGFsb25lLiBJZiB0aGUgc2VydmVyIHRpbWVzIG91dCBvciBlcnJvcnNcbiAgICAgIC8vIHRoZXNlIHNob3VsZCB1cGRhdGUgdGhpcyBib3VuZGFyeSB0byB0aGUgcGVybWFuZW50IEZhbGxiYWNrIHN0YXRlIGluc3RlYWQuXG4gICAgICAvLyBNYXJrIGl0IGFzIGhhdmluZyBjYXB0dXJlZCAoaS5lLiBzdXNwZW5kZWQpLlxuICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTsgLy8gTGVhdmUgdGhlIGNoaWxkIGluIHBsYWNlLiBJLmUuIHRoZSBkZWh5ZHJhdGVkIGZyYWdtZW50LlxuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IGN1cnJlbnQuY2hpbGQ7IC8vIFJlZ2lzdGVyIGEgY2FsbGJhY2sgdG8gcmV0cnkgdGhpcyBib3VuZGFyeSBvbmNlIHRoZSBzZXJ2ZXIgaGFzIHNlbnQgdGhlIHJlc3VsdC5cblxuICAgICAgdmFyIHJldHJ5ID0gcmV0cnlEZWh5ZHJhdGVkU3VzcGVuc2VCb3VuZGFyeS5iaW5kKG51bGwsIGN1cnJlbnQpO1xuICAgICAgcmVnaXN0ZXJTdXNwZW5zZUluc3RhbmNlUmV0cnkoc3VzcGVuc2VJbnN0YW5jZSwgcmV0cnkpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRoaXMgaXMgdGhlIGZpcnN0IGF0dGVtcHQuXG4gICAgICByZWVudGVySHlkcmF0aW9uU3RhdGVGcm9tRGVoeWRyYXRlZFN1c3BlbnNlSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIHN1c3BlbnNlSW5zdGFuY2UsIHN1c3BlbnNlU3RhdGUudHJlZUNvbnRleHQpO1xuICAgICAgdmFyIHByaW1hcnlDaGlsZHJlbiA9IG5leHRQcm9wcy5jaGlsZHJlbjtcbiAgICAgIHZhciBwcmltYXJ5Q2hpbGRGcmFnbWVudCA9IG1vdW50U3VzcGVuc2VQcmltYXJ5Q2hpbGRyZW4od29ya0luUHJvZ3Jlc3MsIHByaW1hcnlDaGlsZHJlbik7IC8vIE1hcmsgdGhlIGNoaWxkcmVuIGFzIGh5ZHJhdGluZy4gVGhpcyBpcyBhIGZhc3QgcGF0aCB0byBrbm93IHdoZXRoZXIgdGhpc1xuICAgICAgLy8gdHJlZSBpcyBwYXJ0IG9mIGEgaHlkcmF0aW5nIHRyZWUuIFRoaXMgaXMgdXNlZCB0byBkZXRlcm1pbmUgaWYgYSBjaGlsZFxuICAgICAgLy8gbm9kZSBoYXMgZnVsbHkgbW91bnRlZCB5ZXQsIGFuZCBmb3Igc2NoZWR1bGluZyBldmVudCByZXBsYXlpbmcuXG4gICAgICAvLyBDb25jZXB0dWFsbHkgdGhpcyBpcyBzaW1pbGFyIHRvIFBsYWNlbWVudCBpbiB0aGF0IGEgbmV3IHN1YnRyZWUgaXNcbiAgICAgIC8vIGluc2VydGVkIGludG8gdGhlIFJlYWN0IHRyZWUgaGVyZS4gSXQganVzdCBoYXBwZW5zIHRvIG5vdCBuZWVkIERPTVxuICAgICAgLy8gbXV0YXRpb25zIGJlY2F1c2UgaXQgYWxyZWFkeSBleGlzdHMuXG5cbiAgICAgIHByaW1hcnlDaGlsZEZyYWdtZW50LmZsYWdzIHw9IEh5ZHJhdGluZztcbiAgICAgIHJldHVybiBwcmltYXJ5Q2hpbGRGcmFnbWVudDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhpcyBpcyB0aGUgc2Vjb25kIHJlbmRlciBwYXNzLiBXZSBhbHJlYWR5IGF0dGVtcHRlZCB0byBoeWRyYXRlZCwgYnV0XG4gICAgLy8gc29tZXRoaW5nIGVpdGhlciBzdXNwZW5kZWQgb3IgZXJyb3JlZC5cbiAgICBpZiAod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBGb3JjZUNsaWVudFJlbmRlcikge1xuICAgICAgLy8gU29tZXRoaW5nIGVycm9yZWQgZHVyaW5nIGh5ZHJhdGlvbi4gVHJ5IGFnYWluIHdpdGhvdXQgaHlkcmF0aW5nLlxuICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgJj0gfkZvcmNlQ2xpZW50UmVuZGVyO1xuXG4gICAgICB2YXIgX2NhcHR1cmVkVmFsdWUyID0gY3JlYXRlQ2FwdHVyZWRWYWx1ZShuZXcgRXJyb3IoJ1RoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSBoeWRyYXRpbmcgdGhpcyBTdXNwZW5zZSBib3VuZGFyeS4gJyArICdTd2l0Y2hlZCB0byBjbGllbnQgcmVuZGVyaW5nLicpKTtcblxuICAgICAgcmV0dXJuIHJldHJ5U3VzcGVuc2VDb21wb25lbnRXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcywgX2NhcHR1cmVkVmFsdWUyKTtcbiAgICB9IGVsc2UgaWYgKHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgIT09IG51bGwpIHtcbiAgICAgIC8vIFNvbWV0aGluZyBzdXNwZW5kZWQgYW5kIHdlIHNob3VsZCBzdGlsbCBiZSBpbiBkZWh5ZHJhdGVkIG1vZGUuXG4gICAgICAvLyBMZWF2ZSB0aGUgZXhpc3RpbmcgY2hpbGQgaW4gcGxhY2UuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IGN1cnJlbnQuY2hpbGQ7IC8vIFRoZSBkZWh5ZHJhdGVkIGNvbXBsZXRpb24gcGFzcyBleHBlY3RzIHRoaXMgZmxhZyB0byBiZSB0aGVyZVxuICAgICAgLy8gYnV0IHRoZSBub3JtYWwgc3VzcGVuc2UgcGFzcyBkb2Vzbid0LlxuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBEaWRDYXB0dXJlO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFN1c3BlbmRlZCBidXQgd2Ugc2hvdWxkIG5vIGxvbmdlciBiZSBpbiBkZWh5ZHJhdGVkIG1vZGUuXG4gICAgICAvLyBUaGVyZWZvcmUgd2Ugbm93IGhhdmUgdG8gcmVuZGVyIHRoZSBmYWxsYmFjay5cbiAgICAgIHZhciBuZXh0UHJpbWFyeUNoaWxkcmVuID0gbmV4dFByb3BzLmNoaWxkcmVuO1xuICAgICAgdmFyIG5leHRGYWxsYmFja0NoaWxkcmVuID0gbmV4dFByb3BzLmZhbGxiYWNrO1xuICAgICAgdmFyIGZhbGxiYWNrQ2hpbGRGcmFnbWVudCA9IG1vdW50U3VzcGVuc2VGYWxsYmFja0FmdGVyUmV0cnlXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0UHJpbWFyeUNoaWxkcmVuLCBuZXh0RmFsbGJhY2tDaGlsZHJlbiwgcmVuZGVyTGFuZXMpO1xuICAgICAgdmFyIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDQgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgICAgIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDQubWVtb2l6ZWRTdGF0ZSA9IG1vdW50U3VzcGVuc2VPZmZzY3JlZW5TdGF0ZShyZW5kZXJMYW5lcyk7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gU1VTUEVOREVEX01BUktFUjtcbiAgICAgIHJldHVybiBmYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHNjaGVkdWxlU3VzcGVuc2VXb3JrT25GaWJlcihmaWJlciwgcmVuZGVyTGFuZXMsIHByb3BhZ2F0aW9uUm9vdCkge1xuICBmaWJlci5sYW5lcyA9IG1lcmdlTGFuZXMoZmliZXIubGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgdmFyIGFsdGVybmF0ZSA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICBpZiAoYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgYWx0ZXJuYXRlLmxhbmVzID0gbWVyZ2VMYW5lcyhhbHRlcm5hdGUubGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHNjaGVkdWxlQ29udGV4dFdvcmtPblBhcmVudFBhdGgoZmliZXIucmV0dXJuLCByZW5kZXJMYW5lcywgcHJvcGFnYXRpb25Sb290KTtcbn1cblxuZnVuY3Rpb24gcHJvcGFnYXRlU3VzcGVuc2VDb250ZXh0Q2hhbmdlKHdvcmtJblByb2dyZXNzLCBmaXJzdENoaWxkLCByZW5kZXJMYW5lcykge1xuICAvLyBNYXJrIGFueSBTdXNwZW5zZSBib3VuZGFyaWVzIHdpdGggZmFsbGJhY2tzIGFzIGhhdmluZyB3b3JrIHRvIGRvLlxuICAvLyBJZiB0aGV5IHdlcmUgcHJldmlvdXNseSBmb3JjZWQgaW50byBmYWxsYmFja3MsIHRoZXkgbWF5IG5vdyBiZSBhYmxlXG4gIC8vIHRvIHVuYmxvY2suXG4gIHZhciBub2RlID0gZmlyc3RDaGlsZDtcblxuICB3aGlsZSAobm9kZSAhPT0gbnVsbCkge1xuICAgIGlmIChub2RlLnRhZyA9PT0gU3VzcGVuc2VDb21wb25lbnQpIHtcbiAgICAgIHZhciBzdGF0ZSA9IG5vZGUubWVtb2l6ZWRTdGF0ZTtcblxuICAgICAgaWYgKHN0YXRlICE9PSBudWxsKSB7XG4gICAgICAgIHNjaGVkdWxlU3VzcGVuc2VXb3JrT25GaWJlcihub2RlLCByZW5kZXJMYW5lcywgd29ya0luUHJvZ3Jlc3MpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobm9kZS50YWcgPT09IFN1c3BlbnNlTGlzdENvbXBvbmVudCkge1xuICAgICAgLy8gSWYgdGhlIHRhaWwgaXMgaGlkZGVuIHRoZXJlIG1pZ2h0IG5vdCBiZSBhbiBTdXNwZW5zZSBib3VuZGFyaWVzXG4gICAgICAvLyB0byBzY2hlZHVsZSB3b3JrIG9uLiBJbiB0aGlzIGNhc2Ugd2UgaGF2ZSB0byBzY2hlZHVsZSBpdCBvbiB0aGVcbiAgICAgIC8vIGxpc3QgaXRzZWxmLlxuICAgICAgLy8gV2UgZG9uJ3QgaGF2ZSB0byB0cmF2ZXJzZSB0byB0aGUgY2hpbGRyZW4gb2YgdGhlIGxpc3Qgc2luY2VcbiAgICAgIC8vIHRoZSBsaXN0IHdpbGwgcHJvcGFnYXRlIHRoZSBjaGFuZ2Ugd2hlbiBpdCByZXJlbmRlcnMuXG4gICAgICBzY2hlZHVsZVN1c3BlbnNlV29ya09uRmliZXIobm9kZSwgcmVuZGVyTGFuZXMsIHdvcmtJblByb2dyZXNzKTtcbiAgICB9IGVsc2UgaWYgKG5vZGUuY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIG5vZGUuY2hpbGQucmV0dXJuID0gbm9kZTtcbiAgICAgIG5vZGUgPSBub2RlLmNoaWxkO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUgPT09IHdvcmtJblByb2dyZXNzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2hpbGUgKG5vZGUuc2libGluZyA9PT0gbnVsbCkge1xuICAgICAgaWYgKG5vZGUucmV0dXJuID09PSBudWxsIHx8IG5vZGUucmV0dXJuID09PSB3b3JrSW5Qcm9ncmVzcykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICB9XG5cbiAgICBub2RlLnNpYmxpbmcucmV0dXJuID0gbm9kZS5yZXR1cm47XG4gICAgbm9kZSA9IG5vZGUuc2libGluZztcbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5kTGFzdENvbnRlbnRSb3coZmlyc3RDaGlsZCkge1xuICAvLyBUaGlzIGlzIGdvaW5nIHRvIGZpbmQgdGhlIGxhc3Qgcm93IGFtb25nIHRoZXNlIGNoaWxkcmVuIHRoYXQgaXMgYWxyZWFkeVxuICAvLyBzaG93aW5nIGNvbnRlbnQgb24gdGhlIHNjcmVlbiwgYXMgb3Bwb3NlZCB0byBiZWluZyBpbiBmYWxsYmFjayBzdGF0ZSBvclxuICAvLyBuZXcuIElmIGEgcm93IGhhcyBtdWx0aXBsZSBTdXNwZW5zZSBib3VuZGFyaWVzLCBhbnkgb2YgdGhlbSBiZWluZyBpbiB0aGVcbiAgLy8gZmFsbGJhY2sgc3RhdGUsIGNvdW50cyBhcyB0aGUgd2hvbGUgcm93IGJlaW5nIGluIGEgZmFsbGJhY2sgc3RhdGUuXG4gIC8vIE5vdGUgdGhhdCB0aGUgXCJyb3dzXCIgd2lsbCBiZSB3b3JrSW5Qcm9ncmVzcywgYnV0IGFueSBuZXN0ZWQgY2hpbGRyZW5cbiAgLy8gd2lsbCBzdGlsbCBiZSBjdXJyZW50IHNpbmNlIHdlIGhhdmVuJ3QgcmVuZGVyZWQgdGhlbSB5ZXQuIFRoZSBtb3VudGVkXG4gIC8vIG9yZGVyIG1heSBub3QgYmUgdGhlIHNhbWUgYXMgdGhlIG5ldyBvcmRlci4gV2UgdXNlIHRoZSBuZXcgb3JkZXIuXG4gIHZhciByb3cgPSBmaXJzdENoaWxkO1xuICB2YXIgbGFzdENvbnRlbnRSb3cgPSBudWxsO1xuXG4gIHdoaWxlIChyb3cgIT09IG51bGwpIHtcbiAgICB2YXIgY3VycmVudFJvdyA9IHJvdy5hbHRlcm5hdGU7IC8vIE5ldyByb3dzIGNhbid0IGJlIGNvbnRlbnQgcm93cy5cblxuICAgIGlmIChjdXJyZW50Um93ICE9PSBudWxsICYmIGZpbmRGaXJzdFN1c3BlbmRlZChjdXJyZW50Um93KSA9PT0gbnVsbCkge1xuICAgICAgbGFzdENvbnRlbnRSb3cgPSByb3c7XG4gICAgfVxuXG4gICAgcm93ID0gcm93LnNpYmxpbmc7XG4gIH1cblxuICByZXR1cm4gbGFzdENvbnRlbnRSb3c7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUmV2ZWFsT3JkZXIocmV2ZWFsT3JkZXIpIHtcbiAge1xuICAgIGlmIChyZXZlYWxPcmRlciAhPT0gdW5kZWZpbmVkICYmIHJldmVhbE9yZGVyICE9PSAnZm9yd2FyZHMnICYmIHJldmVhbE9yZGVyICE9PSAnYmFja3dhcmRzJyAmJiByZXZlYWxPcmRlciAhPT0gJ3RvZ2V0aGVyJyAmJiAhZGlkV2FybkFib3V0UmV2ZWFsT3JkZXJbcmV2ZWFsT3JkZXJdKSB7XG4gICAgICBkaWRXYXJuQWJvdXRSZXZlYWxPcmRlcltyZXZlYWxPcmRlcl0gPSB0cnVlO1xuXG4gICAgICBpZiAodHlwZW9mIHJldmVhbE9yZGVyID09PSAnc3RyaW5nJykge1xuICAgICAgICBzd2l0Y2ggKHJldmVhbE9yZGVyLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICBjYXNlICd0b2dldGhlcic6XG4gICAgICAgICAgY2FzZSAnZm9yd2FyZHMnOlxuICAgICAgICAgIGNhc2UgJ2JhY2t3YXJkcyc6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yKCdcIiVzXCIgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIHJldmVhbE9yZGVyIG9uIDxTdXNwZW5zZUxpc3QgLz4uICcgKyAnVXNlIGxvd2VyY2FzZSBcIiVzXCIgaW5zdGVhZC4nLCByZXZlYWxPcmRlciwgcmV2ZWFsT3JkZXIudG9Mb3dlckNhc2UoKSk7XG5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICBjYXNlICdmb3J3YXJkJzpcbiAgICAgICAgICBjYXNlICdiYWNrd2FyZCc6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yKCdcIiVzXCIgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIHJldmVhbE9yZGVyIG9uIDxTdXNwZW5zZUxpc3QgLz4uICcgKyAnUmVhY3QgdXNlcyB0aGUgLXMgc3VmZml4IGluIHRoZSBzcGVsbGluZy4gVXNlIFwiJXNzXCIgaW5zdGVhZC4nLCByZXZlYWxPcmRlciwgcmV2ZWFsT3JkZXIudG9Mb3dlckNhc2UoKSk7XG5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgZXJyb3IoJ1wiJXNcIiBpcyBub3QgYSBzdXBwb3J0ZWQgcmV2ZWFsT3JkZXIgb24gPFN1c3BlbnNlTGlzdCAvPi4gJyArICdEaWQgeW91IG1lYW4gXCJ0b2dldGhlclwiLCBcImZvcndhcmRzXCIgb3IgXCJiYWNrd2FyZHNcIj8nLCByZXZlYWxPcmRlcik7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlcnJvcignJXMgaXMgbm90IGEgc3VwcG9ydGVkIHZhbHVlIGZvciByZXZlYWxPcmRlciBvbiA8U3VzcGVuc2VMaXN0IC8+LiAnICsgJ0RpZCB5b3UgbWVhbiBcInRvZ2V0aGVyXCIsIFwiZm9yd2FyZHNcIiBvciBcImJhY2t3YXJkc1wiPycsIHJldmVhbE9yZGVyKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVUYWlsT3B0aW9ucyh0YWlsTW9kZSwgcmV2ZWFsT3JkZXIpIHtcbiAge1xuICAgIGlmICh0YWlsTW9kZSAhPT0gdW5kZWZpbmVkICYmICFkaWRXYXJuQWJvdXRUYWlsT3B0aW9uc1t0YWlsTW9kZV0pIHtcbiAgICAgIGlmICh0YWlsTW9kZSAhPT0gJ2NvbGxhcHNlZCcgJiYgdGFpbE1vZGUgIT09ICdoaWRkZW4nKSB7XG4gICAgICAgIGRpZFdhcm5BYm91dFRhaWxPcHRpb25zW3RhaWxNb2RlXSA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJ1wiJXNcIiBpcyBub3QgYSBzdXBwb3J0ZWQgdmFsdWUgZm9yIHRhaWwgb24gPFN1c3BlbnNlTGlzdCAvPi4gJyArICdEaWQgeW91IG1lYW4gXCJjb2xsYXBzZWRcIiBvciBcImhpZGRlblwiPycsIHRhaWxNb2RlKTtcbiAgICAgIH0gZWxzZSBpZiAocmV2ZWFsT3JkZXIgIT09ICdmb3J3YXJkcycgJiYgcmV2ZWFsT3JkZXIgIT09ICdiYWNrd2FyZHMnKSB7XG4gICAgICAgIGRpZFdhcm5BYm91dFRhaWxPcHRpb25zW3RhaWxNb2RlXSA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJzxTdXNwZW5zZUxpc3QgdGFpbD1cIiVzXCIgLz4gaXMgb25seSB2YWxpZCBpZiByZXZlYWxPcmRlciBpcyAnICsgJ1wiZm9yd2FyZHNcIiBvciBcImJhY2t3YXJkc1wiLiAnICsgJ0RpZCB5b3UgbWVhbiB0byBzcGVjaWZ5IHJldmVhbE9yZGVyPVwiZm9yd2FyZHNcIj8nLCB0YWlsTW9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlU3VzcGVuc2VMaXN0TmVzdGVkQ2hpbGQoY2hpbGRTbG90LCBpbmRleCkge1xuICB7XG4gICAgdmFyIGlzQW5BcnJheSA9IGlzQXJyYXkoY2hpbGRTbG90KTtcbiAgICB2YXIgaXNJdGVyYWJsZSA9ICFpc0FuQXJyYXkgJiYgdHlwZW9mIGdldEl0ZXJhdG9yRm4oY2hpbGRTbG90KSA9PT0gJ2Z1bmN0aW9uJztcblxuICAgIGlmIChpc0FuQXJyYXkgfHwgaXNJdGVyYWJsZSkge1xuICAgICAgdmFyIHR5cGUgPSBpc0FuQXJyYXkgPyAnYXJyYXknIDogJ2l0ZXJhYmxlJztcblxuICAgICAgZXJyb3IoJ0EgbmVzdGVkICVzIHdhcyBwYXNzZWQgdG8gcm93ICMlcyBpbiA8U3VzcGVuc2VMaXN0IC8+LiBXcmFwIGl0IGluICcgKyAnYW4gYWRkaXRpb25hbCBTdXNwZW5zZUxpc3QgdG8gY29uZmlndXJlIGl0cyByZXZlYWxPcmRlcjogJyArICc8U3VzcGVuc2VMaXN0IHJldmVhbE9yZGVyPS4uLj4gLi4uICcgKyAnPFN1c3BlbnNlTGlzdCByZXZlYWxPcmRlcj0uLi4+eyVzfTwvU3VzcGVuc2VMaXN0PiAuLi4gJyArICc8L1N1c3BlbnNlTGlzdD4nLCB0eXBlLCBpbmRleCwgdHlwZSk7XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVTdXNwZW5zZUxpc3RDaGlsZHJlbihjaGlsZHJlbiwgcmV2ZWFsT3JkZXIpIHtcbiAge1xuICAgIGlmICgocmV2ZWFsT3JkZXIgPT09ICdmb3J3YXJkcycgfHwgcmV2ZWFsT3JkZXIgPT09ICdiYWNrd2FyZHMnKSAmJiBjaGlsZHJlbiAhPT0gdW5kZWZpbmVkICYmIGNoaWxkcmVuICE9PSBudWxsICYmIGNoaWxkcmVuICE9PSBmYWxzZSkge1xuICAgICAgaWYgKGlzQXJyYXkoY2hpbGRyZW4pKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAoIXZhbGlkYXRlU3VzcGVuc2VMaXN0TmVzdGVkQ2hpbGQoY2hpbGRyZW5baV0sIGkpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgaXRlcmF0b3JGbiA9IGdldEl0ZXJhdG9yRm4oY2hpbGRyZW4pO1xuXG4gICAgICAgIGlmICh0eXBlb2YgaXRlcmF0b3JGbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHZhciBjaGlsZHJlbkl0ZXJhdG9yID0gaXRlcmF0b3JGbi5jYWxsKGNoaWxkcmVuKTtcblxuICAgICAgICAgIGlmIChjaGlsZHJlbkl0ZXJhdG9yKSB7XG4gICAgICAgICAgICB2YXIgc3RlcCA9IGNoaWxkcmVuSXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgICAgdmFyIF9pID0gMDtcblxuICAgICAgICAgICAgZm9yICg7ICFzdGVwLmRvbmU7IHN0ZXAgPSBjaGlsZHJlbkl0ZXJhdG9yLm5leHQoKSkge1xuICAgICAgICAgICAgICBpZiAoIXZhbGlkYXRlU3VzcGVuc2VMaXN0TmVzdGVkQ2hpbGQoc3RlcC52YWx1ZSwgX2kpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgX2krKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXJyb3IoJ0Egc2luZ2xlIHJvdyB3YXMgcGFzc2VkIHRvIGEgPFN1c3BlbnNlTGlzdCByZXZlYWxPcmRlcj1cIiVzXCIgLz4uICcgKyAnVGhpcyBpcyBub3QgdXNlZnVsIHNpbmNlIGl0IG5lZWRzIG11bHRpcGxlIHJvd3MuICcgKyAnRGlkIHlvdSBtZWFuIHRvIHBhc3MgbXVsdGlwbGUgY2hpbGRyZW4gb3IgYW4gYXJyYXk/JywgcmV2ZWFsT3JkZXIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGluaXRTdXNwZW5zZUxpc3RSZW5kZXJTdGF0ZSh3b3JrSW5Qcm9ncmVzcywgaXNCYWNrd2FyZHMsIHRhaWwsIGxhc3RDb250ZW50Um93LCB0YWlsTW9kZSkge1xuICB2YXIgcmVuZGVyU3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gIGlmIChyZW5kZXJTdGF0ZSA9PT0gbnVsbCkge1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSB7XG4gICAgICBpc0JhY2t3YXJkczogaXNCYWNrd2FyZHMsXG4gICAgICByZW5kZXJpbmc6IG51bGwsXG4gICAgICByZW5kZXJpbmdTdGFydFRpbWU6IDAsXG4gICAgICBsYXN0OiBsYXN0Q29udGVudFJvdyxcbiAgICAgIHRhaWw6IHRhaWwsXG4gICAgICB0YWlsTW9kZTogdGFpbE1vZGVcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIC8vIFdlIGNhbiByZXVzZSB0aGUgZXhpc3Rpbmcgb2JqZWN0IGZyb20gcHJldmlvdXMgcmVuZGVycy5cbiAgICByZW5kZXJTdGF0ZS5pc0JhY2t3YXJkcyA9IGlzQmFja3dhcmRzO1xuICAgIHJlbmRlclN0YXRlLnJlbmRlcmluZyA9IG51bGw7XG4gICAgcmVuZGVyU3RhdGUucmVuZGVyaW5nU3RhcnRUaW1lID0gMDtcbiAgICByZW5kZXJTdGF0ZS5sYXN0ID0gbGFzdENvbnRlbnRSb3c7XG4gICAgcmVuZGVyU3RhdGUudGFpbCA9IHRhaWw7XG4gICAgcmVuZGVyU3RhdGUudGFpbE1vZGUgPSB0YWlsTW9kZTtcbiAgfVxufSAvLyBUaGlzIGNhbiBlbmQgdXAgcmVuZGVyaW5nIHRoaXMgY29tcG9uZW50IG11bHRpcGxlIHBhc3Nlcy5cbi8vIFRoZSBmaXJzdCBwYXNzIHNwbGl0cyB0aGUgY2hpbGRyZW4gZmliZXJzIGludG8gdHdvIHNldHMuIEEgaGVhZCBhbmQgdGFpbC5cbi8vIFdlIGZpcnN0IHJlbmRlciB0aGUgaGVhZC4gSWYgYW55dGhpbmcgaXMgaW4gZmFsbGJhY2sgc3RhdGUsIHdlIGRvIGFub3RoZXJcbi8vIHBhc3MgdGhyb3VnaCBiZWdpbldvcmsgdG8gcmVyZW5kZXIgYWxsIGNoaWxkcmVuIChpbmNsdWRpbmcgdGhlIHRhaWwpIHdpdGhcbi8vIHRoZSBmb3JjZSBzdXNwZW5kIGNvbnRleHQuIElmIHRoZSBmaXJzdCByZW5kZXIgZGlkbid0IGhhdmUgYW55dGhpbmcgaW5cbi8vIGluIGZhbGxiYWNrIHN0YXRlLiBUaGVuIHdlIHJlbmRlciBlYWNoIHJvdyBpbiB0aGUgdGFpbCBvbmUtYnktb25lLlxuLy8gVGhhdCBoYXBwZW5zIGluIHRoZSBjb21wbGV0ZVdvcmsgcGhhc2Ugd2l0aG91dCBnb2luZyBiYWNrIHRvIGJlZ2luV29yay5cblxuXG5mdW5jdGlvbiB1cGRhdGVTdXNwZW5zZUxpc3RDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBuZXh0UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciByZXZlYWxPcmRlciA9IG5leHRQcm9wcy5yZXZlYWxPcmRlcjtcbiAgdmFyIHRhaWxNb2RlID0gbmV4dFByb3BzLnRhaWw7XG4gIHZhciBuZXdDaGlsZHJlbiA9IG5leHRQcm9wcy5jaGlsZHJlbjtcbiAgdmFsaWRhdGVSZXZlYWxPcmRlcihyZXZlYWxPcmRlcik7XG4gIHZhbGlkYXRlVGFpbE9wdGlvbnModGFpbE1vZGUsIHJldmVhbE9yZGVyKTtcbiAgdmFsaWRhdGVTdXNwZW5zZUxpc3RDaGlsZHJlbihuZXdDaGlsZHJlbiwgcmV2ZWFsT3JkZXIpO1xuICByZWNvbmNpbGVDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV3Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgdmFyIHN1c3BlbnNlQ29udGV4dCA9IHN1c3BlbnNlU3RhY2tDdXJzb3IuY3VycmVudDtcbiAgdmFyIHNob3VsZEZvcmNlRmFsbGJhY2sgPSBoYXNTdXNwZW5zZUNvbnRleHQoc3VzcGVuc2VDb250ZXh0LCBGb3JjZVN1c3BlbnNlRmFsbGJhY2spO1xuXG4gIGlmIChzaG91bGRGb3JjZUZhbGxiYWNrKSB7XG4gICAgc3VzcGVuc2VDb250ZXh0ID0gc2V0U2hhbGxvd1N1c3BlbnNlQ29udGV4dChzdXNwZW5zZUNvbnRleHQsIEZvcmNlU3VzcGVuc2VGYWxsYmFjayk7XG4gICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgZGlkU3VzcGVuZEJlZm9yZSA9IGN1cnJlbnQgIT09IG51bGwgJiYgKGN1cnJlbnQuZmxhZ3MgJiBEaWRDYXB0dXJlKSAhPT0gTm9GbGFncztcblxuICAgIGlmIChkaWRTdXNwZW5kQmVmb3JlKSB7XG4gICAgICAvLyBJZiB3ZSBwcmV2aW91c2x5IGZvcmNlZCBhIGZhbGxiYWNrLCB3ZSBuZWVkIHRvIHNjaGVkdWxlIHdvcmtcbiAgICAgIC8vIG9uIGFueSBuZXN0ZWQgYm91bmRhcmllcyB0byBsZXQgdGhlbSBrbm93IHRvIHRyeSB0byByZW5kZXJcbiAgICAgIC8vIGFnYWluLiBUaGlzIGlzIHRoZSBzYW1lIGFzIGNvbnRleHQgdXBkYXRpbmcuXG4gICAgICBwcm9wYWdhdGVTdXNwZW5zZUNvbnRleHRDaGFuZ2Uod29ya0luUHJvZ3Jlc3MsIHdvcmtJblByb2dyZXNzLmNoaWxkLCByZW5kZXJMYW5lcyk7XG4gICAgfVxuXG4gICAgc3VzcGVuc2VDb250ZXh0ID0gc2V0RGVmYXVsdFNoYWxsb3dTdXNwZW5zZUNvbnRleHQoc3VzcGVuc2VDb250ZXh0KTtcbiAgfVxuXG4gIHB1c2hTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MsIHN1c3BlbnNlQ29udGV4dCk7XG5cbiAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUpIHtcbiAgICAvLyBJbiBsZWdhY3kgbW9kZSwgU3VzcGVuc2VMaXN0IGRvZXNuJ3Qgd29yayBzbyB3ZSBqdXN0XG4gICAgLy8gdXNlIG1ha2UgaXQgYSBub29wIGJ5IHRyZWF0aW5nIGl0IGFzIHRoZSBkZWZhdWx0IHJldmVhbE9yZGVyLlxuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICB9IGVsc2Uge1xuICAgIHN3aXRjaCAocmV2ZWFsT3JkZXIpIHtcbiAgICAgIGNhc2UgJ2ZvcndhcmRzJzpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBsYXN0Q29udGVudFJvdyA9IGZpbmRMYXN0Q29udGVudFJvdyh3b3JrSW5Qcm9ncmVzcy5jaGlsZCk7XG4gICAgICAgICAgdmFyIHRhaWw7XG5cbiAgICAgICAgICBpZiAobGFzdENvbnRlbnRSb3cgPT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFRoZSB3aG9sZSBsaXN0IGlzIHBhcnQgb2YgdGhlIHRhaWwuXG4gICAgICAgICAgICAvLyBUT0RPOiBXZSBjb3VsZCBmYXN0IHBhdGggYnkganVzdCByZW5kZXJpbmcgdGhlIHRhaWwgbm93LlxuICAgICAgICAgICAgdGFpbCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSBudWxsO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBEaXNjb25uZWN0IHRoZSB0YWlsIHJvd3MgYWZ0ZXIgdGhlIGNvbnRlbnQgcm93LlxuICAgICAgICAgICAgLy8gV2UncmUgZ29pbmcgdG8gcmVuZGVyIHRoZW0gc2VwYXJhdGVseSBsYXRlci5cbiAgICAgICAgICAgIHRhaWwgPSBsYXN0Q29udGVudFJvdy5zaWJsaW5nO1xuICAgICAgICAgICAgbGFzdENvbnRlbnRSb3cuc2libGluZyA9IG51bGw7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaW5pdFN1c3BlbnNlTGlzdFJlbmRlclN0YXRlKHdvcmtJblByb2dyZXNzLCBmYWxzZSwgLy8gaXNCYWNrd2FyZHNcbiAgICAgICAgICB0YWlsLCBsYXN0Q29udGVudFJvdywgdGFpbE1vZGUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgJ2JhY2t3YXJkcyc6XG4gICAgICAgIHtcbiAgICAgICAgICAvLyBXZSdyZSBnb2luZyB0byBmaW5kIHRoZSBmaXJzdCByb3cgdGhhdCBoYXMgZXhpc3RpbmcgY29udGVudC5cbiAgICAgICAgICAvLyBBdCB0aGUgc2FtZSB0aW1lIHdlJ3JlIGdvaW5nIHRvIHJldmVyc2UgdGhlIGxpc3Qgb2YgZXZlcnl0aGluZ1xuICAgICAgICAgIC8vIHdlIHBhc3MgaW4gdGhlIG1lYW50aW1lLiBUaGF0J3MgZ29pbmcgdG8gYmUgb3VyIHRhaWwgaW4gcmV2ZXJzZVxuICAgICAgICAgIC8vIG9yZGVyLlxuICAgICAgICAgIHZhciBfdGFpbCA9IG51bGw7XG4gICAgICAgICAgdmFyIHJvdyA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gbnVsbDtcblxuICAgICAgICAgIHdoaWxlIChyb3cgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBjdXJyZW50Um93ID0gcm93LmFsdGVybmF0ZTsgLy8gTmV3IHJvd3MgY2FuJ3QgYmUgY29udGVudCByb3dzLlxuXG4gICAgICAgICAgICBpZiAoY3VycmVudFJvdyAhPT0gbnVsbCAmJiBmaW5kRmlyc3RTdXNwZW5kZWQoY3VycmVudFJvdykgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgYmVnaW5uaW5nIG9mIHRoZSBtYWluIGNvbnRlbnQuXG4gICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcm93O1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIG5leHRSb3cgPSByb3cuc2libGluZztcbiAgICAgICAgICAgIHJvdy5zaWJsaW5nID0gX3RhaWw7XG4gICAgICAgICAgICBfdGFpbCA9IHJvdztcbiAgICAgICAgICAgIHJvdyA9IG5leHRSb3c7XG4gICAgICAgICAgfSAvLyBUT0RPOiBJZiB3b3JrSW5Qcm9ncmVzcy5jaGlsZCBpcyBudWxsLCB3ZSBjYW4gY29udGludWUgb24gdGhlIHRhaWwgaW1tZWRpYXRlbHkuXG5cblxuICAgICAgICAgIGluaXRTdXNwZW5zZUxpc3RSZW5kZXJTdGF0ZSh3b3JrSW5Qcm9ncmVzcywgdHJ1ZSwgLy8gaXNCYWNrd2FyZHNcbiAgICAgICAgICBfdGFpbCwgbnVsbCwgLy8gbGFzdFxuICAgICAgICAgIHRhaWxNb2RlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlICd0b2dldGhlcic6XG4gICAgICAgIHtcbiAgICAgICAgICBpbml0U3VzcGVuc2VMaXN0UmVuZGVyU3RhdGUod29ya0luUHJvZ3Jlc3MsIGZhbHNlLCAvLyBpc0JhY2t3YXJkc1xuICAgICAgICAgIG51bGwsIC8vIHRhaWxcbiAgICAgICAgICBudWxsLCAvLyBsYXN0XG4gICAgICAgICAgdW5kZWZpbmVkKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB7XG4gICAgICAgICAgLy8gVGhlIGRlZmF1bHQgcmV2ZWFsIG9yZGVyIGlzIHRoZSBzYW1lIGFzIG5vdCBoYXZpbmdcbiAgICAgICAgICAvLyBhIGJvdW5kYXJ5LlxuICAgICAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVQb3J0YWxDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHB1c2hIb3N0Q29udGFpbmVyKHdvcmtJblByb2dyZXNzLCB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUuY29udGFpbmVySW5mbyk7XG4gIHZhciBuZXh0Q2hpbGRyZW4gPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG5cbiAgaWYgKGN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAvLyBQb3J0YWxzIGFyZSBzcGVjaWFsIGJlY2F1c2Ugd2UgZG9uJ3QgYXBwZW5kIHRoZSBjaGlsZHJlbiBkdXJpbmcgbW91bnRcbiAgICAvLyBidXQgYXQgY29tbWl0LiBUaGVyZWZvcmUgd2UgbmVlZCB0byB0cmFjayBpbnNlcnRpb25zIHdoaWNoIHRoZSBub3JtYWxcbiAgICAvLyBmbG93IGRvZXNuJ3QgZG8gZHVyaW5nIG1vdW50LiBUaGlzIGRvZXNuJ3QgaGFwcGVuIGF0IHRoZSByb290IGJlY2F1c2VcbiAgICAvLyB0aGUgcm9vdCBhbHdheXMgc3RhcnRzIHdpdGggYSBcImN1cnJlbnRcIiB3aXRoIGEgbnVsbCBjaGlsZC5cbiAgICAvLyBUT0RPOiBDb25zaWRlciB1bmlmeWluZyB0aGlzIHdpdGggaG93IHRoZSByb290IHdvcmtzLlxuICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcmVjb25jaWxlQ2hpbGRGaWJlcnMod29ya0luUHJvZ3Jlc3MsIG51bGwsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMpO1xuICB9IGVsc2Uge1xuICAgIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxudmFyIGhhc1dhcm5lZEFib3V0VXNpbmdOb1ZhbHVlUHJvcE9uQ29udGV4dFByb3ZpZGVyID0gZmFsc2U7XG5cbmZ1bmN0aW9uIHVwZGF0ZUNvbnRleHRQcm92aWRlcihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIHByb3ZpZGVyVHlwZSA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gIHZhciBjb250ZXh0ID0gcHJvdmlkZXJUeXBlLl9jb250ZXh0O1xuICB2YXIgbmV3UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciBvbGRQcm9wcyA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkUHJvcHM7XG4gIHZhciBuZXdWYWx1ZSA9IG5ld1Byb3BzLnZhbHVlO1xuXG4gIHtcbiAgICBpZiAoISgndmFsdWUnIGluIG5ld1Byb3BzKSkge1xuICAgICAgaWYgKCFoYXNXYXJuZWRBYm91dFVzaW5nTm9WYWx1ZVByb3BPbkNvbnRleHRQcm92aWRlcikge1xuICAgICAgICBoYXNXYXJuZWRBYm91dFVzaW5nTm9WYWx1ZVByb3BPbkNvbnRleHRQcm92aWRlciA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJ1RoZSBgdmFsdWVgIHByb3AgaXMgcmVxdWlyZWQgZm9yIHRoZSBgPENvbnRleHQuUHJvdmlkZXI+YC4gRGlkIHlvdSBtaXNzcGVsbCBpdCBvciBmb3JnZXQgdG8gcGFzcyBpdD8nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcHJvdmlkZXJQcm9wVHlwZXMgPSB3b3JrSW5Qcm9ncmVzcy50eXBlLnByb3BUeXBlcztcblxuICAgIGlmIChwcm92aWRlclByb3BUeXBlcykge1xuICAgICAgY2hlY2tQcm9wVHlwZXMocHJvdmlkZXJQcm9wVHlwZXMsIG5ld1Byb3BzLCAncHJvcCcsICdDb250ZXh0LlByb3ZpZGVyJyk7XG4gICAgfVxuICB9XG5cbiAgcHVzaFByb3ZpZGVyKHdvcmtJblByb2dyZXNzLCBjb250ZXh0LCBuZXdWYWx1ZSk7XG5cbiAge1xuICAgIGlmIChvbGRQcm9wcyAhPT0gbnVsbCkge1xuICAgICAgdmFyIG9sZFZhbHVlID0gb2xkUHJvcHMudmFsdWU7XG5cbiAgICAgIGlmIChvYmplY3RJcyhvbGRWYWx1ZSwgbmV3VmFsdWUpKSB7XG4gICAgICAgIC8vIE5vIGNoYW5nZS4gQmFpbG91dCBlYXJseSBpZiBjaGlsZHJlbiBhcmUgdGhlIHNhbWUuXG4gICAgICAgIGlmIChvbGRQcm9wcy5jaGlsZHJlbiA9PT0gbmV3UHJvcHMuY2hpbGRyZW4gJiYgIWhhc0NvbnRleHRDaGFuZ2VkKCkpIHtcbiAgICAgICAgICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBUaGUgY29udGV4dCB2YWx1ZSBjaGFuZ2VkLiBTZWFyY2ggZm9yIG1hdGNoaW5nIGNvbnN1bWVycyBhbmQgc2NoZWR1bGVcbiAgICAgICAgLy8gdGhlbSB0byB1cGRhdGUuXG4gICAgICAgIHByb3BhZ2F0ZUNvbnRleHRDaGFuZ2Uod29ya0luUHJvZ3Jlc3MsIGNvbnRleHQsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgbmV3Q2hpbGRyZW4gPSBuZXdQcm9wcy5jaGlsZHJlbjtcbiAgcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5ld0NoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxudmFyIGhhc1dhcm5lZEFib3V0VXNpbmdDb250ZXh0QXNDb25zdW1lciA9IGZhbHNlO1xuXG5mdW5jdGlvbiB1cGRhdGVDb250ZXh0Q29uc3VtZXIoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBjb250ZXh0ID0gd29ya0luUHJvZ3Jlc3MudHlwZTsgLy8gVGhlIGxvZ2ljIGJlbG93IGZvciBDb250ZXh0IGRpZmZlcnMgZGVwZW5kaW5nIG9uIFBST0Qgb3IgREVWIG1vZGUuIEluXG4gIC8vIERFViBtb2RlLCB3ZSBjcmVhdGUgYSBzZXBhcmF0ZSBvYmplY3QgZm9yIENvbnRleHQuQ29uc3VtZXIgdGhhdCBhY3RzXG4gIC8vIGxpa2UgYSBwcm94eSB0byBDb250ZXh0LiBUaGlzIHByb3h5IG9iamVjdCBhZGRzIHVubmVjZXNzYXJ5IGNvZGUgaW4gUFJPRFxuICAvLyBzbyB3ZSB1c2UgdGhlIG9sZCBiZWhhdmlvdXIgKENvbnRleHQuQ29uc3VtZXIgcmVmZXJlbmNlcyBDb250ZXh0KSB0b1xuICAvLyByZWR1Y2Ugc2l6ZSBhbmQgb3ZlcmhlYWQuIFRoZSBzZXBhcmF0ZSBvYmplY3QgcmVmZXJlbmNlcyBjb250ZXh0IHZpYVxuICAvLyBhIHByb3BlcnR5IGNhbGxlZCBcIl9jb250ZXh0XCIsIHdoaWNoIGFsc28gZ2l2ZXMgdXMgdGhlIGFiaWxpdHkgdG8gY2hlY2tcbiAgLy8gaW4gREVWIG1vZGUgaWYgdGhpcyBwcm9wZXJ0eSBleGlzdHMgb3Igbm90IGFuZCB3YXJuIGlmIGl0IGRvZXMgbm90LlxuXG4gIHtcbiAgICBpZiAoY29udGV4dC5fY29udGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBUaGlzIG1heSBiZSBiZWNhdXNlIGl0J3MgYSBDb250ZXh0IChyYXRoZXIgdGhhbiBhIENvbnN1bWVyKS5cbiAgICAgIC8vIE9yIGl0IG1heSBiZSBiZWNhdXNlIGl0J3Mgb2xkZXIgUmVhY3Qgd2hlcmUgdGhleSdyZSB0aGUgc2FtZSB0aGluZy5cbiAgICAgIC8vIFdlIG9ubHkgd2FudCB0byB3YXJuIGlmIHdlJ3JlIHN1cmUgaXQncyBhIG5ldyBSZWFjdC5cbiAgICAgIGlmIChjb250ZXh0ICE9PSBjb250ZXh0LkNvbnN1bWVyKSB7XG4gICAgICAgIGlmICghaGFzV2FybmVkQWJvdXRVc2luZ0NvbnRleHRBc0NvbnN1bWVyKSB7XG4gICAgICAgICAgaGFzV2FybmVkQWJvdXRVc2luZ0NvbnRleHRBc0NvbnN1bWVyID0gdHJ1ZTtcblxuICAgICAgICAgIGVycm9yKCdSZW5kZXJpbmcgPENvbnRleHQ+IGRpcmVjdGx5IGlzIG5vdCBzdXBwb3J0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiAnICsgJ2EgZnV0dXJlIG1ham9yIHJlbGVhc2UuIERpZCB5b3UgbWVhbiB0byByZW5kZXIgPENvbnRleHQuQ29uc3VtZXI+IGluc3RlYWQ/Jyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29udGV4dCA9IGNvbnRleHQuX2NvbnRleHQ7XG4gICAgfVxuICB9XG5cbiAgdmFyIG5ld1Byb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgcmVuZGVyID0gbmV3UHJvcHMuY2hpbGRyZW47XG5cbiAge1xuICAgIGlmICh0eXBlb2YgcmVuZGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcignQSBjb250ZXh0IGNvbnN1bWVyIHdhcyByZW5kZXJlZCB3aXRoIG11bHRpcGxlIGNoaWxkcmVuLCBvciBhIGNoaWxkICcgKyBcInRoYXQgaXNuJ3QgYSBmdW5jdGlvbi4gQSBjb250ZXh0IGNvbnN1bWVyIGV4cGVjdHMgYSBzaW5nbGUgY2hpbGQgXCIgKyAndGhhdCBpcyBhIGZ1bmN0aW9uLiBJZiB5b3UgZGlkIHBhc3MgYSBmdW5jdGlvbiwgbWFrZSBzdXJlIHRoZXJlICcgKyAnaXMgbm8gdHJhaWxpbmcgb3IgbGVhZGluZyB3aGl0ZXNwYWNlIGFyb3VuZCBpdC4nKTtcbiAgICB9XG4gIH1cblxuICBwcmVwYXJlVG9SZWFkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICB2YXIgbmV3VmFsdWUgPSByZWFkQ29udGV4dChjb250ZXh0KTtcblxuICB7XG4gICAgbWFya0NvbXBvbmVudFJlbmRlclN0YXJ0ZWQod29ya0luUHJvZ3Jlc3MpO1xuICB9XG5cbiAgdmFyIG5ld0NoaWxkcmVuO1xuXG4gIHtcbiAgICBSZWFjdEN1cnJlbnRPd25lciQxLmN1cnJlbnQgPSB3b3JrSW5Qcm9ncmVzcztcbiAgICBzZXRJc1JlbmRlcmluZyh0cnVlKTtcbiAgICBuZXdDaGlsZHJlbiA9IHJlbmRlcihuZXdWYWx1ZSk7XG4gICAgc2V0SXNSZW5kZXJpbmcoZmFsc2UpO1xuICB9XG5cbiAge1xuICAgIG1hcmtDb21wb25lbnRSZW5kZXJTdG9wcGVkKCk7XG4gIH0gLy8gUmVhY3QgRGV2VG9vbHMgcmVhZHMgdGhpcyBmbGFnLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUGVyZm9ybWVkV29yaztcbiAgcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5ld0NoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxuZnVuY3Rpb24gbWFya1dvcmtJblByb2dyZXNzUmVjZWl2ZWRVcGRhdGUoKSB7XG4gIGRpZFJlY2VpdmVVcGRhdGUgPSB0cnVlO1xufVxuXG5mdW5jdGlvbiByZXNldFN1c3BlbmRlZEN1cnJlbnRPbk1vdW50SW5MZWdhY3lNb2RlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKSB7XG4gIGlmICgod29ya0luUHJvZ3Jlc3MubW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlKSB7XG4gICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgIC8vIEEgbGF6eSBjb21wb25lbnQgb25seSBtb3VudHMgaWYgaXQgc3VzcGVuZGVkIGluc2lkZSBhIG5vbi1cbiAgICAgIC8vIGNvbmN1cnJlbnQgdHJlZSwgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLiBXZSB3YW50IHRvIHRyZWF0IGl0IGxpa2VcbiAgICAgIC8vIGEgbmV3IG1vdW50LCBldmVuIHRob3VnaCBhbiBlbXB0eSB2ZXJzaW9uIG9mIGl0IGFscmVhZHkgY29tbWl0dGVkLlxuICAgICAgLy8gRGlzY29ubmVjdCB0aGUgYWx0ZXJuYXRlIHBvaW50ZXJzLlxuICAgICAgY3VycmVudC5hbHRlcm5hdGUgPSBudWxsO1xuICAgICAgd29ya0luUHJvZ3Jlc3MuYWx0ZXJuYXRlID0gbnVsbDsgLy8gU2luY2UgdGhpcyBpcyBjb25jZXB0dWFsbHkgYSBuZXcgZmliZXIsIHNjaGVkdWxlIGEgUGxhY2VtZW50IGVmZmVjdFxuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBQbGFjZW1lbnQ7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGJhaWxvdXRPbkFscmVhZHlGaW5pc2hlZFdvcmsoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgLy8gUmV1c2UgcHJldmlvdXMgZGVwZW5kZW5jaWVzXG4gICAgd29ya0luUHJvZ3Jlc3MuZGVwZW5kZW5jaWVzID0gY3VycmVudC5kZXBlbmRlbmNpZXM7XG4gIH1cblxuICB7XG4gICAgLy8gRG9uJ3QgdXBkYXRlIFwiYmFzZVwiIHJlbmRlciB0aW1lcyBmb3IgYmFpbG91dHMuXG4gICAgc3RvcFByb2ZpbGVyVGltZXJJZlJ1bm5pbmcoKTtcbiAgfVxuXG4gIG1hcmtTa2lwcGVkVXBkYXRlTGFuZXMod29ya0luUHJvZ3Jlc3MubGFuZXMpOyAvLyBDaGVjayBpZiB0aGUgY2hpbGRyZW4gaGF2ZSBhbnkgcGVuZGluZyB3b3JrLlxuXG4gIGlmICghaW5jbHVkZXNTb21lTGFuZShyZW5kZXJMYW5lcywgd29ya0luUHJvZ3Jlc3MuY2hpbGRMYW5lcykpIHtcbiAgICAvLyBUaGUgY2hpbGRyZW4gZG9uJ3QgaGF2ZSBhbnkgd29yayBlaXRoZXIuIFdlIGNhbiBza2lwIHRoZW0uXG4gICAgLy8gVE9ETzogT25jZSB3ZSBhZGQgYmFjayByZXN1bWluZywgd2Ugc2hvdWxkIGNoZWNrIGlmIHRoZSBjaGlsZHJlbiBhcmVcbiAgICAvLyBhIHdvcmstaW4tcHJvZ3Jlc3Mgc2V0LiBJZiBzbywgd2UgbmVlZCB0byB0cmFuc2ZlciB0aGVpciBlZmZlY3RzLlxuICAgIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfSAvLyBUaGlzIGZpYmVyIGRvZXNuJ3QgaGF2ZSB3b3JrLCBidXQgaXRzIHN1YnRyZWUgZG9lcy4gQ2xvbmUgdGhlIGNoaWxkXG4gIC8vIGZpYmVycyBhbmQgY29udGludWUuXG5cblxuICBjbG9uZUNoaWxkRmliZXJzKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiByZW1vdW50RmliZXIoY3VycmVudCwgb2xkV29ya0luUHJvZ3Jlc3MsIG5ld1dvcmtJblByb2dyZXNzKSB7XG4gIHtcbiAgICB2YXIgcmV0dXJuRmliZXIgPSBvbGRXb3JrSW5Qcm9ncmVzcy5yZXR1cm47XG5cbiAgICBpZiAocmV0dXJuRmliZXIgPT09IG51bGwpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9wcm9kLWVycm9yLWNvZGVzXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBzd2FwIHRoZSByb290IGZpYmVyLicpO1xuICAgIH0gLy8gRGlzY29ubmVjdCBmcm9tIHRoZSBvbGQgY3VycmVudC5cbiAgICAvLyBJdCB3aWxsIGdldCBkZWxldGVkLlxuXG5cbiAgICBjdXJyZW50LmFsdGVybmF0ZSA9IG51bGw7XG4gICAgb2xkV29ya0luUHJvZ3Jlc3MuYWx0ZXJuYXRlID0gbnVsbDsgLy8gQ29ubmVjdCB0byB0aGUgbmV3IHRyZWUuXG5cbiAgICBuZXdXb3JrSW5Qcm9ncmVzcy5pbmRleCA9IG9sZFdvcmtJblByb2dyZXNzLmluZGV4O1xuICAgIG5ld1dvcmtJblByb2dyZXNzLnNpYmxpbmcgPSBvbGRXb3JrSW5Qcm9ncmVzcy5zaWJsaW5nO1xuICAgIG5ld1dvcmtJblByb2dyZXNzLnJldHVybiA9IG9sZFdvcmtJblByb2dyZXNzLnJldHVybjtcbiAgICBuZXdXb3JrSW5Qcm9ncmVzcy5yZWYgPSBvbGRXb3JrSW5Qcm9ncmVzcy5yZWY7IC8vIFJlcGxhY2UgdGhlIGNoaWxkL3NpYmxpbmcgcG9pbnRlcnMgYWJvdmUgaXQuXG5cbiAgICBpZiAob2xkV29ya0luUHJvZ3Jlc3MgPT09IHJldHVybkZpYmVyLmNoaWxkKSB7XG4gICAgICByZXR1cm5GaWJlci5jaGlsZCA9IG5ld1dvcmtJblByb2dyZXNzO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgcHJldlNpYmxpbmcgPSByZXR1cm5GaWJlci5jaGlsZDtcblxuICAgICAgaWYgKHByZXZTaWJsaW5nID09PSBudWxsKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9wcm9kLWVycm9yLWNvZGVzXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgcGFyZW50IHRvIGhhdmUgYSBjaGlsZC4nKTtcbiAgICAgIH1cblxuICAgICAgd2hpbGUgKHByZXZTaWJsaW5nLnNpYmxpbmcgIT09IG9sZFdvcmtJblByb2dyZXNzKSB7XG4gICAgICAgIHByZXZTaWJsaW5nID0gcHJldlNpYmxpbmcuc2libGluZztcblxuICAgICAgICBpZiAocHJldlNpYmxpbmcgPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2Rlc1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgdG8gZmluZCB0aGUgcHJldmlvdXMgc2libGluZy4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBwcmV2U2libGluZy5zaWJsaW5nID0gbmV3V29ya0luUHJvZ3Jlc3M7XG4gICAgfSAvLyBEZWxldGUgdGhlIG9sZCBmaWJlciBhbmQgcGxhY2UgdGhlIG5ldyBvbmUuXG4gICAgLy8gU2luY2UgdGhlIG9sZCBmaWJlciBpcyBkaXNjb25uZWN0ZWQsIHdlIGhhdmUgdG8gc2NoZWR1bGUgaXQgbWFudWFsbHkuXG5cblxuICAgIHZhciBkZWxldGlvbnMgPSByZXR1cm5GaWJlci5kZWxldGlvbnM7XG5cbiAgICBpZiAoZGVsZXRpb25zID09PSBudWxsKSB7XG4gICAgICByZXR1cm5GaWJlci5kZWxldGlvbnMgPSBbY3VycmVudF07XG4gICAgICByZXR1cm5GaWJlci5mbGFncyB8PSBDaGlsZERlbGV0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGlvbnMucHVzaChjdXJyZW50KTtcbiAgICB9XG5cbiAgICBuZXdXb3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBQbGFjZW1lbnQ7IC8vIFJlc3RhcnQgd29yayBmcm9tIHRoZSBuZXcgZmliZXIuXG5cbiAgICByZXR1cm4gbmV3V29ya0luUHJvZ3Jlc3M7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tTY2hlZHVsZWRVcGRhdGVPckNvbnRleHQoY3VycmVudCwgcmVuZGVyTGFuZXMpIHtcbiAgLy8gQmVmb3JlIHBlcmZvcm1pbmcgYW4gZWFybHkgYmFpbG91dCwgd2UgbXVzdCBjaGVjayBpZiB0aGVyZSBhcmUgcGVuZGluZ1xuICAvLyB1cGRhdGVzIG9yIGNvbnRleHQuXG4gIHZhciB1cGRhdGVMYW5lcyA9IGN1cnJlbnQubGFuZXM7XG5cbiAgaWYgKGluY2x1ZGVzU29tZUxhbmUodXBkYXRlTGFuZXMsIHJlbmRlckxhbmVzKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IC8vIE5vIHBlbmRpbmcgdXBkYXRlLCBidXQgYmVjYXVzZSBjb250ZXh0IGlzIHByb3BhZ2F0ZWQgbGF6aWx5LCB3ZSBuZWVkXG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBhdHRlbXB0RWFybHlCYWlsb3V0SWZOb1NjaGVkdWxlZFVwZGF0ZShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAgLy8gVGhpcyBmaWJlciBkb2VzIG5vdCBoYXZlIGFueSBwZW5kaW5nIHdvcmsuIEJhaWxvdXQgd2l0aG91dCBlbnRlcmluZ1xuICAvLyB0aGUgYmVnaW4gcGhhc2UuIFRoZXJlJ3Mgc3RpbGwgc29tZSBib29ra2VlcGluZyB3ZSB0aGF0IG5lZWRzIHRvIGJlIGRvbmVcbiAgLy8gaW4gdGhpcyBvcHRpbWl6ZWQgcGF0aCwgbW9zdGx5IHB1c2hpbmcgc3R1ZmYgb250byB0aGUgc3RhY2suXG4gIHN3aXRjaCAod29ya0luUHJvZ3Jlc3MudGFnKSB7XG4gICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgIHB1c2hIb3N0Um9vdENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgdmFyIHJvb3QgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG5cbiAgICAgIHJlc2V0SHlkcmF0aW9uU3RhdGUoKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAgcHVzaEhvc3RDb250ZXh0KHdvcmtJblByb2dyZXNzKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIENvbXBvbmVudCA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG5cbiAgICAgICAgaWYgKGlzQ29udGV4dFByb3ZpZGVyKENvbXBvbmVudCkpIHtcbiAgICAgICAgICBwdXNoQ29udGV4dFByb3ZpZGVyKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0UG9ydGFsOlxuICAgICAgcHVzaEhvc3RDb250YWluZXIod29ya0luUHJvZ3Jlc3MsIHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZS5jb250YWluZXJJbmZvKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBDb250ZXh0UHJvdmlkZXI6XG4gICAgICB7XG4gICAgICAgIHZhciBuZXdWYWx1ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkUHJvcHMudmFsdWU7XG4gICAgICAgIHZhciBjb250ZXh0ID0gd29ya0luUHJvZ3Jlc3MudHlwZS5fY29udGV4dDtcbiAgICAgICAgcHVzaFByb3ZpZGVyKHdvcmtJblByb2dyZXNzLCBjb250ZXh0LCBuZXdWYWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBQcm9maWxlcjpcbiAgICAgIHtcbiAgICAgICAgLy8gUHJvZmlsZXIgc2hvdWxkIG9ubHkgY2FsbCBvblJlbmRlciB3aGVuIG9uZSBvZiBpdHMgZGVzY2VuZGFudHMgYWN0dWFsbHkgcmVuZGVyZWQuXG4gICAgICAgIHZhciBoYXNDaGlsZFdvcmsgPSBpbmNsdWRlc1NvbWVMYW5lKHJlbmRlckxhbmVzLCB3b3JrSW5Qcm9ncmVzcy5jaGlsZExhbmVzKTtcblxuICAgICAgICBpZiAoaGFzQ2hpbGRXb3JrKSB7XG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gVXBkYXRlO1xuICAgICAgICB9XG5cbiAgICAgICAge1xuICAgICAgICAgIC8vIFJlc2V0IGVmZmVjdCBkdXJhdGlvbnMgZm9yIHRoZSBuZXh0IGV2ZW50dWFsIGVmZmVjdCBwaGFzZS5cbiAgICAgICAgICAvLyBUaGVzZSBhcmUgcmVzZXQgZHVyaW5nIHJlbmRlciB0byBhbGxvdyB0aGUgRGV2VG9vbHMgY29tbWl0IGhvb2sgYSBjaGFuY2UgdG8gcmVhZCB0aGVtLFxuICAgICAgICAgIHZhciBzdGF0ZU5vZGUgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG4gICAgICAgICAgc3RhdGVOb2RlLmVmZmVjdER1cmF0aW9uID0gMDtcbiAgICAgICAgICBzdGF0ZU5vZGUucGFzc2l2ZUVmZmVjdER1cmF0aW9uID0gMDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBicmVhaztcblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBzdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG5cbiAgICAgICAgaWYgKHN0YXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgaWYgKHN0YXRlLmRlaHlkcmF0ZWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHB1c2hTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MsIHNldERlZmF1bHRTaGFsbG93U3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlU3RhY2tDdXJzb3IuY3VycmVudCkpOyAvLyBXZSBrbm93IHRoYXQgdGhpcyBjb21wb25lbnQgd2lsbCBzdXNwZW5kIGFnYWluIGJlY2F1c2UgaWYgaXQgaGFzXG4gICAgICAgICAgICAvLyBiZWVuIHVuc3VzcGVuZGVkIGl0IGhhcyBjb21taXR0ZWQgYXMgYSByZXNvbHZlZCBTdXNwZW5zZSBjb21wb25lbnQuXG4gICAgICAgICAgICAvLyBJZiBpdCBuZWVkcyB0byBiZSByZXRyaWVkLCBpdCBzaG91bGQgaGF2ZSB3b3JrIHNjaGVkdWxlZCBvbiBpdC5cblxuICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTsgLy8gV2Ugc2hvdWxkIG5ldmVyIHJlbmRlciB0aGUgY2hpbGRyZW4gb2YgYSBkZWh5ZHJhdGVkIGJvdW5kYXJ5IHVudGlsIHdlXG4gICAgICAgICAgICAvLyB1cGdyYWRlIGl0LiBXZSByZXR1cm4gbnVsbCBpbnN0ZWFkIG9mIGJhaWxvdXRPbkFscmVhZHlGaW5pc2hlZFdvcmsuXG5cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH0gLy8gSWYgdGhpcyBib3VuZGFyeSBpcyBjdXJyZW50bHkgdGltZWQgb3V0LCB3ZSBuZWVkIHRvIGRlY2lkZVxuICAgICAgICAgIC8vIHdoZXRoZXIgdG8gcmV0cnkgdGhlIHByaW1hcnkgY2hpbGRyZW4sIG9yIHRvIHNraXAgb3ZlciBpdCBhbmRcbiAgICAgICAgICAvLyBnbyBzdHJhaWdodCB0byB0aGUgZmFsbGJhY2suIENoZWNrIHRoZSBwcmlvcml0eSBvZiB0aGUgcHJpbWFyeVxuICAgICAgICAgIC8vIGNoaWxkIGZyYWdtZW50LlxuXG5cbiAgICAgICAgICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgICAgICAgICB2YXIgcHJpbWFyeUNoaWxkTGFuZXMgPSBwcmltYXJ5Q2hpbGRGcmFnbWVudC5jaGlsZExhbmVzO1xuXG4gICAgICAgICAgaWYgKGluY2x1ZGVzU29tZUxhbmUocmVuZGVyTGFuZXMsIHByaW1hcnlDaGlsZExhbmVzKSkge1xuICAgICAgICAgICAgLy8gVGhlIHByaW1hcnkgY2hpbGRyZW4gaGF2ZSBwZW5kaW5nIHdvcmsuIFVzZSB0aGUgbm9ybWFsIHBhdGhcbiAgICAgICAgICAgIC8vIHRvIGF0dGVtcHQgdG8gcmVuZGVyIHRoZSBwcmltYXJ5IGNoaWxkcmVuIGFnYWluLlxuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZVN1c3BlbnNlQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRoZSBwcmltYXJ5IGNoaWxkIGZyYWdtZW50IGRvZXMgbm90IGhhdmUgcGVuZGluZyB3b3JrIG1hcmtlZFxuICAgICAgICAgICAgLy8gb24gaXRcbiAgICAgICAgICAgIHB1c2hTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MsIHNldERlZmF1bHRTaGFsbG93U3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlU3RhY2tDdXJzb3IuY3VycmVudCkpOyAvLyBUaGUgcHJpbWFyeSBjaGlsZHJlbiBkbyBub3QgaGF2ZSBwZW5kaW5nIHdvcmsgd2l0aCBzdWZmaWNpZW50XG4gICAgICAgICAgICAvLyBwcmlvcml0eS4gQmFpbG91dC5cblxuICAgICAgICAgICAgdmFyIGNoaWxkID0gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuXG4gICAgICAgICAgICBpZiAoY2hpbGQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgLy8gVGhlIGZhbGxiYWNrIGNoaWxkcmVuIGhhdmUgcGVuZGluZyB3b3JrLiBTa2lwIG92ZXIgdGhlXG4gICAgICAgICAgICAgIC8vIHByaW1hcnkgY2hpbGRyZW4gYW5kIHdvcmsgb24gdGhlIGZhbGxiYWNrLlxuICAgICAgICAgICAgICByZXR1cm4gY2hpbGQuc2libGluZztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIE5vdGU6IFdlIGNhbiByZXR1cm4gYG51bGxgIGhlcmUgYmVjYXVzZSB3ZSBhbHJlYWR5IGNoZWNrZWRcbiAgICAgICAgICAgICAgLy8gd2hldGhlciB0aGVyZSB3ZXJlIG5lc3RlZCBjb250ZXh0IGNvbnN1bWVycywgdmlhIHRoZSBjYWxsIHRvXG4gICAgICAgICAgICAgIC8vIGBiYWlsb3V0T25BbHJlYWR5RmluaXNoZWRXb3JrYCBhYm92ZS5cbiAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHB1c2hTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MsIHNldERlZmF1bHRTaGFsbG93U3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlU3RhY2tDdXJzb3IuY3VycmVudCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIGRpZFN1c3BlbmRCZWZvcmUgPSAoY3VycmVudC5mbGFncyAmIERpZENhcHR1cmUpICE9PSBOb0ZsYWdzO1xuXG4gICAgICAgIHZhciBfaGFzQ2hpbGRXb3JrID0gaW5jbHVkZXNTb21lTGFuZShyZW5kZXJMYW5lcywgd29ya0luUHJvZ3Jlc3MuY2hpbGRMYW5lcyk7XG5cbiAgICAgICAgaWYgKGRpZFN1c3BlbmRCZWZvcmUpIHtcbiAgICAgICAgICBpZiAoX2hhc0NoaWxkV29yaykge1xuICAgICAgICAgICAgLy8gSWYgc29tZXRoaW5nIHdhcyBpbiBmYWxsYmFjayBzdGF0ZSBsYXN0IHRpbWUsIGFuZCB3ZSBoYXZlIGFsbCB0aGVcbiAgICAgICAgICAgIC8vIHNhbWUgY2hpbGRyZW4gdGhlbiB3ZSdyZSBzdGlsbCBpbiBwcm9ncmVzc2l2ZSBsb2FkaW5nIHN0YXRlLlxuICAgICAgICAgICAgLy8gU29tZXRoaW5nIG1pZ2h0IGdldCB1bmJsb2NrZWQgYnkgc3RhdGUgdXBkYXRlcyBvciByZXRyaWVzIGluIHRoZVxuICAgICAgICAgICAgLy8gdHJlZSB3aGljaCB3aWxsIGFmZmVjdCB0aGUgdGFpbC4gU28gd2UgbmVlZCB0byB1c2UgdGhlIG5vcm1hbFxuICAgICAgICAgICAgLy8gcGF0aCB0byBjb21wdXRlIHRoZSBjb3JyZWN0IHRhaWwuXG4gICAgICAgICAgICByZXR1cm4gdXBkYXRlU3VzcGVuc2VMaXN0Q29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgICAgICAgfSAvLyBJZiBub25lIG9mIHRoZSBjaGlsZHJlbiBoYWQgYW55IHdvcmssIHRoYXQgbWVhbnMgdGhhdCBub25lIG9mXG4gICAgICAgICAgLy8gdGhlbSBnb3QgcmV0cmllZCBzbyB0aGV5J2xsIHN0aWxsIGJlIGJsb2NrZWQgaW4gdGhlIHNhbWUgd2F5XG4gICAgICAgICAgLy8gYXMgYmVmb3JlLiBXZSBjYW4gZmFzdCBiYWlsIG91dC5cblxuXG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTtcbiAgICAgICAgfSAvLyBJZiBub3RoaW5nIHN1c3BlbmRlZCBiZWZvcmUgYW5kIHdlJ3JlIHJlbmRlcmluZyB0aGUgc2FtZSBjaGlsZHJlbixcbiAgICAgICAgLy8gdGhlbiB0aGUgdGFpbCBkb2Vzbid0IG1hdHRlci4gQW55dGhpbmcgbmV3IHRoYXQgc3VzcGVuZHMgd2lsbCB3b3JrXG4gICAgICAgIC8vIGluIHRoZSBcInRvZ2V0aGVyXCIgbW9kZSwgc28gd2UgY2FuIGNvbnRpbnVlIGZyb20gdGhlIHN0YXRlIHdlIGhhZC5cblxuXG4gICAgICAgIHZhciByZW5kZXJTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG5cbiAgICAgICAgaWYgKHJlbmRlclN0YXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgLy8gUmVzZXQgdG8gdGhlIFwidG9nZXRoZXJcIiBtb2RlIGluIGNhc2Ugd2UndmUgc3RhcnRlZCBhIGRpZmZlcmVudFxuICAgICAgICAgIC8vIHVwZGF0ZSBpbiB0aGUgcGFzdCBidXQgZGlkbid0IGNvbXBsZXRlIGl0LlxuICAgICAgICAgIHJlbmRlclN0YXRlLnJlbmRlcmluZyA9IG51bGw7XG4gICAgICAgICAgcmVuZGVyU3RhdGUudGFpbCA9IG51bGw7XG4gICAgICAgICAgcmVuZGVyU3RhdGUubGFzdEVmZmVjdCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBwdXNoU3VzcGVuc2VDb250ZXh0KHdvcmtJblByb2dyZXNzLCBzdXNwZW5zZVN0YWNrQ3Vyc29yLmN1cnJlbnQpO1xuXG4gICAgICAgIGlmIChfaGFzQ2hpbGRXb3JrKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gSWYgbm9uZSBvZiB0aGUgY2hpbGRyZW4gaGFkIGFueSB3b3JrLCB0aGF0IG1lYW5zIHRoYXQgbm9uZSBvZlxuICAgICAgICAgIC8vIHRoZW0gZ290IHJldHJpZWQgc28gdGhleSdsbCBzdGlsbCBiZSBibG9ja2VkIGluIHRoZSBzYW1lIHdheVxuICAgICAgICAgIC8vIGFzIGJlZm9yZS4gV2UgY2FuIGZhc3QgYmFpbCBvdXQuXG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgIGNhc2UgT2Zmc2NyZWVuQ29tcG9uZW50OlxuICAgIGNhc2UgTGVnYWN5SGlkZGVuQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICAvLyBOZWVkIHRvIGNoZWNrIGlmIHRoZSB0cmVlIHN0aWxsIG5lZWRzIHRvIGJlIGRlZmVycmVkLiBUaGlzIGlzXG4gICAgICAgIC8vIGFsbW9zdCBpZGVudGljYWwgdG8gdGhlIGxvZ2ljIHVzZWQgaW4gdGhlIG5vcm1hbCB1cGRhdGUgcGF0aCxcbiAgICAgICAgLy8gc28gd2UnbGwganVzdCBlbnRlciB0aGF0LiBUaGUgb25seSBkaWZmZXJlbmNlIGlzIHdlJ2xsIGJhaWwgb3V0XG4gICAgICAgIC8vIGF0IHRoZSBuZXh0IGxldmVsIGluc3RlYWQgb2YgdGhpcyBvbmUsIGJlY2F1c2UgdGhlIGNoaWxkIHByb3BzXG4gICAgICAgIC8vIGhhdmUgbm90IGNoYW5nZWQuIFdoaWNoIGlzIGZpbmUuXG4gICAgICAgIC8vIFRPRE86IFByb2JhYmx5IHNob3VsZCByZWZhY3RvciBgYmVnaW5Xb3JrYCB0byBzcGxpdCB0aGUgYmFpbG91dFxuICAgICAgICAvLyBwYXRoIGZyb20gdGhlIG5vcm1hbCBwYXRoLiBJJ20gdGVtcHRlZCB0byBkbyBhIGxhYmVsZWQgYnJlYWsgaGVyZVxuICAgICAgICAvLyBidXQgSSB3b24ndCA6KVxuICAgICAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IE5vTGFuZXM7XG4gICAgICAgIHJldHVybiB1cGRhdGVPZmZzY3JlZW5Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cbiAgfVxuXG4gIHJldHVybiBiYWlsb3V0T25BbHJlYWR5RmluaXNoZWRXb3JrKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG59XG5cbmZ1bmN0aW9uIGJlZ2luV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAge1xuICAgIGlmICh3b3JrSW5Qcm9ncmVzcy5fZGVidWdOZWVkc1JlbW91bnQgJiYgY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgLy8gVGhpcyB3aWxsIHJlc3RhcnQgdGhlIGJlZ2luIHBoYXNlIHdpdGggYSBuZXcgZmliZXIuXG4gICAgICByZXR1cm4gcmVtb3VudEZpYmVyKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBjcmVhdGVGaWJlckZyb21UeXBlQW5kUHJvcHMod29ya0luUHJvZ3Jlc3MudHlwZSwgd29ya0luUHJvZ3Jlc3Mua2V5LCB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHMsIHdvcmtJblByb2dyZXNzLl9kZWJ1Z093bmVyIHx8IG51bGwsIHdvcmtJblByb2dyZXNzLm1vZGUsIHdvcmtJblByb2dyZXNzLmxhbmVzKSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICB2YXIgb2xkUHJvcHMgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7XG4gICAgdmFyIG5ld1Byb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuXG4gICAgaWYgKG9sZFByb3BzICE9PSBuZXdQcm9wcyB8fCBoYXNDb250ZXh0Q2hhbmdlZCgpIHx8ICggLy8gRm9yY2UgYSByZS1yZW5kZXIgaWYgdGhlIGltcGxlbWVudGF0aW9uIGNoYW5nZWQgZHVlIHRvIGhvdCByZWxvYWQ6XG4gICAgIHdvcmtJblByb2dyZXNzLnR5cGUgIT09IGN1cnJlbnQudHlwZSApKSB7XG4gICAgICAvLyBJZiBwcm9wcyBvciBjb250ZXh0IGNoYW5nZWQsIG1hcmsgdGhlIGZpYmVyIGFzIGhhdmluZyBwZXJmb3JtZWQgd29yay5cbiAgICAgIC8vIFRoaXMgbWF5IGJlIHVuc2V0IGlmIHRoZSBwcm9wcyBhcmUgZGV0ZXJtaW5lZCB0byBiZSBlcXVhbCBsYXRlciAobWVtbykuXG4gICAgICBkaWRSZWNlaXZlVXBkYXRlID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTmVpdGhlciBwcm9wcyBub3IgbGVnYWN5IGNvbnRleHQgY2hhbmdlcy4gQ2hlY2sgaWYgdGhlcmUncyBhIHBlbmRpbmdcbiAgICAgIC8vIHVwZGF0ZSBvciBjb250ZXh0IGNoYW5nZS5cbiAgICAgIHZhciBoYXNTY2hlZHVsZWRVcGRhdGVPckNvbnRleHQgPSBjaGVja1NjaGVkdWxlZFVwZGF0ZU9yQ29udGV4dChjdXJyZW50LCByZW5kZXJMYW5lcyk7XG5cbiAgICAgIGlmICghaGFzU2NoZWR1bGVkVXBkYXRlT3JDb250ZXh0ICYmIC8vIElmIHRoaXMgaXMgdGhlIHNlY29uZCBwYXNzIG9mIGFuIGVycm9yIG9yIHN1c3BlbnNlIGJvdW5kYXJ5LCB0aGVyZVxuICAgICAgLy8gbWF5IG5vdCBiZSB3b3JrIHNjaGVkdWxlZCBvbiBgY3VycmVudGAsIHNvIHdlIGNoZWNrIGZvciB0aGlzIGZsYWcuXG4gICAgICAod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBEaWRDYXB0dXJlKSA9PT0gTm9GbGFncykge1xuICAgICAgICAvLyBObyBwZW5kaW5nIHVwZGF0ZXMgb3IgY29udGV4dC4gQmFpbCBvdXQgbm93LlxuICAgICAgICBkaWRSZWNlaXZlVXBkYXRlID0gZmFsc2U7XG4gICAgICAgIHJldHVybiBhdHRlbXB0RWFybHlCYWlsb3V0SWZOb1NjaGVkdWxlZFVwZGF0ZShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoKGN1cnJlbnQuZmxhZ3MgJiBGb3JjZVVwZGF0ZUZvckxlZ2FjeVN1c3BlbnNlKSAhPT0gTm9GbGFncykge1xuICAgICAgICAvLyBUaGlzIGlzIGEgc3BlY2lhbCBjYXNlIHRoYXQgb25seSBleGlzdHMgZm9yIGxlZ2FjeSBtb2RlLlxuICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L3B1bGwvMTkyMTYuXG4gICAgICAgIGRpZFJlY2VpdmVVcGRhdGUgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQW4gdXBkYXRlIHdhcyBzY2hlZHVsZWQgb24gdGhpcyBmaWJlciwgYnV0IHRoZXJlIGFyZSBubyBuZXcgcHJvcHNcbiAgICAgICAgLy8gbm9yIGxlZ2FjeSBjb250ZXh0LiBTZXQgdGhpcyB0byBmYWxzZS4gSWYgYW4gdXBkYXRlIHF1ZXVlIG9yIGNvbnRleHRcbiAgICAgICAgLy8gY29uc3VtZXIgcHJvZHVjZXMgYSBjaGFuZ2VkIHZhbHVlLCBpdCB3aWxsIHNldCB0aGlzIHRvIHRydWUuIE90aGVyd2lzZSxcbiAgICAgICAgLy8gdGhlIGNvbXBvbmVudCB3aWxsIGFzc3VtZSB0aGUgY2hpbGRyZW4gaGF2ZSBub3QgY2hhbmdlZCBhbmQgYmFpbCBvdXQuXG4gICAgICAgIGRpZFJlY2VpdmVVcGRhdGUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZGlkUmVjZWl2ZVVwZGF0ZSA9IGZhbHNlO1xuXG4gICAgaWYgKGdldElzSHlkcmF0aW5nKCkgJiYgaXNGb3JrZWRDaGlsZCh3b3JrSW5Qcm9ncmVzcykpIHtcbiAgICAgIC8vIENoZWNrIGlmIHRoaXMgY2hpbGQgYmVsb25ncyB0byBhIGxpc3Qgb2YgbXVsaXBsZSBjaGlsZHJlbiBpblxuICAgICAgLy8gaXRzIHBhcmVudC5cbiAgICAgIC8vXG4gICAgICAvLyBJbiBhIHRydWUgbXVsdGktdGhyZWFkZWQgaW1wbGVtZW50YXRpb24sIHdlIHdvdWxkIHJlbmRlciBjaGlsZHJlbiBvblxuICAgICAgLy8gcGFyYWxsZWwgdGhyZWFkcy4gVGhpcyB3b3VsZCByZXByZXNlbnQgdGhlIGJlZ2lubmluZyBvZiBhIG5ldyByZW5kZXJcbiAgICAgIC8vIHRocmVhZCBmb3IgdGhpcyBzdWJ0cmVlLlxuICAgICAgLy9cbiAgICAgIC8vIFdlIG9ubHkgdXNlIHRoaXMgZm9yIGlkIGdlbmVyYXRpb24gZHVyaW5nIGh5ZHJhdGlvbiwgd2hpY2ggaXMgd2h5IHRoZVxuICAgICAgLy8gbG9naWMgaXMgbG9jYXRlZCBpbiB0aGlzIHNwZWNpYWwgYnJhbmNoLlxuICAgICAgdmFyIHNsb3RJbmRleCA9IHdvcmtJblByb2dyZXNzLmluZGV4O1xuICAgICAgdmFyIG51bWJlck9mRm9ya3MgPSBnZXRGb3Jrc0F0TGV2ZWwoKTtcbiAgICAgIHB1c2hUcmVlSWQod29ya0luUHJvZ3Jlc3MsIG51bWJlck9mRm9ya3MsIHNsb3RJbmRleCk7XG4gICAgfVxuICB9IC8vIEJlZm9yZSBlbnRlcmluZyB0aGUgYmVnaW4gcGhhc2UsIGNsZWFyIHBlbmRpbmcgdXBkYXRlIHByaW9yaXR5LlxuICAvLyBUT0RPOiBUaGlzIGFzc3VtZXMgdGhhdCB3ZSdyZSBhYm91dCB0byBldmFsdWF0ZSB0aGUgY29tcG9uZW50IGFuZCBwcm9jZXNzXG4gIC8vIHRoZSB1cGRhdGUgcXVldWUuIEhvd2V2ZXIsIHRoZXJlJ3MgYW4gZXhjZXB0aW9uOiBTaW1wbGVNZW1vQ29tcG9uZW50XG4gIC8vIHNvbWV0aW1lcyBiYWlscyBvdXQgbGF0ZXIgaW4gdGhlIGJlZ2luIHBoYXNlLiBUaGlzIGluZGljYXRlcyB0aGF0IHdlIHNob3VsZFxuICAvLyBtb3ZlIHRoaXMgYXNzaWdubWVudCBvdXQgb2YgdGhlIGNvbW1vbiBwYXRoIGFuZCBpbnRvIGVhY2ggYnJhbmNoLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBOb0xhbmVzO1xuXG4gIHN3aXRjaCAod29ya0luUHJvZ3Jlc3MudGFnKSB7XG4gICAgY2FzZSBJbmRldGVybWluYXRlQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICByZXR1cm4gbW91bnRJbmRldGVybWluYXRlQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCB3b3JrSW5Qcm9ncmVzcy50eXBlLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG5cbiAgICBjYXNlIExhenlDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBlbGVtZW50VHlwZSA9IHdvcmtJblByb2dyZXNzLmVsZW1lbnRUeXBlO1xuICAgICAgICByZXR1cm4gbW91bnRMYXp5Q29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBlbGVtZW50VHlwZSwgcmVuZGVyTGFuZXMpO1xuICAgICAgfVxuXG4gICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIENvbXBvbmVudCA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gICAgICAgIHZhciB1bnJlc29sdmVkUHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gICAgICAgIHZhciByZXNvbHZlZFByb3BzID0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGUgPT09IENvbXBvbmVudCA/IHVucmVzb2x2ZWRQcm9wcyA6IHJlc29sdmVEZWZhdWx0UHJvcHMoQ29tcG9uZW50LCB1bnJlc29sdmVkUHJvcHMpO1xuICAgICAgICByZXR1cm4gdXBkYXRlRnVuY3Rpb25Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcmVzb2x2ZWRQcm9wcywgcmVuZGVyTGFuZXMpO1xuICAgICAgfVxuXG4gICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIF9Db21wb25lbnQgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuICAgICAgICB2YXIgX3VucmVzb2x2ZWRQcm9wcyA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcztcblxuICAgICAgICB2YXIgX3Jlc29sdmVkUHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZSA9PT0gX0NvbXBvbmVudCA/IF91bnJlc29sdmVkUHJvcHMgOiByZXNvbHZlRGVmYXVsdFByb3BzKF9Db21wb25lbnQsIF91bnJlc29sdmVkUHJvcHMpO1xuXG4gICAgICAgIHJldHVybiB1cGRhdGVDbGFzc0NvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgX0NvbXBvbmVudCwgX3Jlc29sdmVkUHJvcHMsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICByZXR1cm4gdXBkYXRlSG9zdFJvb3QoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcblxuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHJldHVybiB1cGRhdGVIb3N0Q29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG5cbiAgICBjYXNlIEhvc3RUZXh0OlxuICAgICAgcmV0dXJuIHVwZGF0ZUhvc3RUZXh0KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKTtcblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICByZXR1cm4gdXBkYXRlU3VzcGVuc2VDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcblxuICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgIHJldHVybiB1cGRhdGVQb3J0YWxDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcblxuICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIHtcbiAgICAgICAgdmFyIHR5cGUgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuICAgICAgICB2YXIgX3VucmVzb2x2ZWRQcm9wczIgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG5cbiAgICAgICAgdmFyIF9yZXNvbHZlZFByb3BzMiA9IHdvcmtJblByb2dyZXNzLmVsZW1lbnRUeXBlID09PSB0eXBlID8gX3VucmVzb2x2ZWRQcm9wczIgOiByZXNvbHZlRGVmYXVsdFByb3BzKHR5cGUsIF91bnJlc29sdmVkUHJvcHMyKTtcblxuICAgICAgICByZXR1cm4gdXBkYXRlRm9yd2FyZFJlZihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgdHlwZSwgX3Jlc29sdmVkUHJvcHMyLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG5cbiAgICBjYXNlIEZyYWdtZW50OlxuICAgICAgcmV0dXJuIHVwZGF0ZUZyYWdtZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG5cbiAgICBjYXNlIE1vZGU6XG4gICAgICByZXR1cm4gdXBkYXRlTW9kZShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuXG4gICAgY2FzZSBQcm9maWxlcjpcbiAgICAgIHJldHVybiB1cGRhdGVQcm9maWxlcihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuXG4gICAgY2FzZSBDb250ZXh0UHJvdmlkZXI6XG4gICAgICByZXR1cm4gdXBkYXRlQ29udGV4dFByb3ZpZGVyKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG5cbiAgICBjYXNlIENvbnRleHRDb25zdW1lcjpcbiAgICAgIHJldHVybiB1cGRhdGVDb250ZXh0Q29uc3VtZXIoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcblxuICAgIGNhc2UgTWVtb0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIF90eXBlMiA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gICAgICAgIHZhciBfdW5yZXNvbHZlZFByb3BzMyA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wczsgLy8gUmVzb2x2ZSBvdXRlciBwcm9wcyBmaXJzdCwgdGhlbiByZXNvbHZlIGlubmVyIHByb3BzLlxuXG4gICAgICAgIHZhciBfcmVzb2x2ZWRQcm9wczMgPSByZXNvbHZlRGVmYXVsdFByb3BzKF90eXBlMiwgX3VucmVzb2x2ZWRQcm9wczMpO1xuXG4gICAgICAgIHtcbiAgICAgICAgICBpZiAod29ya0luUHJvZ3Jlc3MudHlwZSAhPT0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGUpIHtcbiAgICAgICAgICAgIHZhciBvdXRlclByb3BUeXBlcyA9IF90eXBlMi5wcm9wVHlwZXM7XG5cbiAgICAgICAgICAgIGlmIChvdXRlclByb3BUeXBlcykge1xuICAgICAgICAgICAgICBjaGVja1Byb3BUeXBlcyhvdXRlclByb3BUeXBlcywgX3Jlc29sdmVkUHJvcHMzLCAvLyBSZXNvbHZlZCBmb3Igb3V0ZXIgb25seVxuICAgICAgICAgICAgICAncHJvcCcsIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShfdHlwZTIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBfcmVzb2x2ZWRQcm9wczMgPSByZXNvbHZlRGVmYXVsdFByb3BzKF90eXBlMi50eXBlLCBfcmVzb2x2ZWRQcm9wczMpO1xuICAgICAgICByZXR1cm4gdXBkYXRlTWVtb0NvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgX3R5cGUyLCBfcmVzb2x2ZWRQcm9wczMsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cblxuICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZVNpbXBsZU1lbW9Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHdvcmtJblByb2dyZXNzLnR5cGUsIHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcywgcmVuZGVyTGFuZXMpO1xuICAgICAgfVxuXG4gICAgY2FzZSBJbmNvbXBsZXRlQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBfQ29tcG9uZW50MiA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gICAgICAgIHZhciBfdW5yZXNvbHZlZFByb3BzNCA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcztcblxuICAgICAgICB2YXIgX3Jlc29sdmVkUHJvcHM0ID0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGUgPT09IF9Db21wb25lbnQyID8gX3VucmVzb2x2ZWRQcm9wczQgOiByZXNvbHZlRGVmYXVsdFByb3BzKF9Db21wb25lbnQyLCBfdW5yZXNvbHZlZFByb3BzNCk7XG5cbiAgICAgICAgcmV0dXJuIG1vdW50SW5jb21wbGV0ZUNsYXNzQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBfQ29tcG9uZW50MiwgX3Jlc29sdmVkUHJvcHM0LCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZVN1c3BlbnNlTGlzdENvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgICAgfVxuXG4gICAgY2FzZSBTY29wZUNvbXBvbmVudDpcbiAgICAgIHtcblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgT2Zmc2NyZWVuQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICByZXR1cm4gdXBkYXRlT2Zmc2NyZWVuQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIHVuaXQgb2Ygd29yayB0YWcgKFwiICsgd29ya0luUHJvZ3Jlc3MudGFnICsgXCIpLiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gXCIgKyAnUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xufVxuXG5mdW5jdGlvbiBtYXJrVXBkYXRlKHdvcmtJblByb2dyZXNzKSB7XG4gIC8vIFRhZyB0aGUgZmliZXIgd2l0aCBhbiB1cGRhdGUgZWZmZWN0LiBUaGlzIHR1cm5zIGEgUGxhY2VtZW50IGludG9cbiAgLy8gYSBQbGFjZW1lbnRBbmRVcGRhdGUuXG4gIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFVwZGF0ZTtcbn1cblxuZnVuY3Rpb24gbWFya1JlZiQxKHdvcmtJblByb2dyZXNzKSB7XG4gIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFJlZjtcblxuICB7XG4gICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUmVmU3RhdGljO1xuICB9XG59XG5cbnZhciBhcHBlbmRBbGxDaGlsZHJlbjtcbnZhciB1cGRhdGVIb3N0Q29udGFpbmVyO1xudmFyIHVwZGF0ZUhvc3RDb21wb25lbnQkMTtcbnZhciB1cGRhdGVIb3N0VGV4dCQxO1xuXG57XG4gIC8vIE11dGF0aW9uIG1vZGVcbiAgYXBwZW5kQWxsQ2hpbGRyZW4gPSBmdW5jdGlvbiAocGFyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmVlZHNWaXNpYmlsaXR5VG9nZ2xlLCBpc0hpZGRlbikge1xuICAgIC8vIFdlIG9ubHkgaGF2ZSB0aGUgdG9wIEZpYmVyIHRoYXQgd2FzIGNyZWF0ZWQgYnV0IHdlIG5lZWQgcmVjdXJzZSBkb3duIGl0c1xuICAgIC8vIGNoaWxkcmVuIHRvIGZpbmQgYWxsIHRoZSB0ZXJtaW5hbCBub2Rlcy5cbiAgICB2YXIgbm9kZSA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuXG4gICAgd2hpbGUgKG5vZGUgIT09IG51bGwpIHtcbiAgICAgIGlmIChub2RlLnRhZyA9PT0gSG9zdENvbXBvbmVudCB8fCBub2RlLnRhZyA9PT0gSG9zdFRleHQpIHtcbiAgICAgICAgYXBwZW5kSW5pdGlhbENoaWxkKHBhcmVudCwgbm9kZS5zdGF0ZU5vZGUpO1xuICAgICAgfSBlbHNlIGlmIChub2RlLnRhZyA9PT0gSG9zdFBvcnRhbCkgOyBlbHNlIGlmIChub2RlLmNoaWxkICE9PSBudWxsKSB7XG4gICAgICAgIG5vZGUuY2hpbGQucmV0dXJuID0gbm9kZTtcbiAgICAgICAgbm9kZSA9IG5vZGUuY2hpbGQ7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAobm9kZSA9PT0gd29ya0luUHJvZ3Jlc3MpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB3aGlsZSAobm9kZS5zaWJsaW5nID09PSBudWxsKSB7XG4gICAgICAgIGlmIChub2RlLnJldHVybiA9PT0gbnVsbCB8fCBub2RlLnJldHVybiA9PT0gd29ya0luUHJvZ3Jlc3MpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBub2RlID0gbm9kZS5yZXR1cm47XG4gICAgICB9XG5cbiAgICAgIG5vZGUuc2libGluZy5yZXR1cm4gPSBub2RlLnJldHVybjtcbiAgICAgIG5vZGUgPSBub2RlLnNpYmxpbmc7XG4gICAgfVxuICB9O1xuXG4gIHVwZGF0ZUhvc3RDb250YWluZXIgPSBmdW5jdGlvbiAoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpIHsvLyBOb29wXG4gIH07XG5cbiAgdXBkYXRlSG9zdENvbXBvbmVudCQxID0gZnVuY3Rpb24gKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCB0eXBlLCBuZXdQcm9wcywgcm9vdENvbnRhaW5lckluc3RhbmNlKSB7XG4gICAgLy8gSWYgd2UgaGF2ZSBhbiBhbHRlcm5hdGUsIHRoYXQgbWVhbnMgdGhpcyBpcyBhbiB1cGRhdGUgYW5kIHdlIG5lZWQgdG9cbiAgICAvLyBzY2hlZHVsZSBhIHNpZGUtZWZmZWN0IHRvIGRvIHRoZSB1cGRhdGVzLlxuICAgIHZhciBvbGRQcm9wcyA9IGN1cnJlbnQubWVtb2l6ZWRQcm9wcztcblxuICAgIGlmIChvbGRQcm9wcyA9PT0gbmV3UHJvcHMpIHtcbiAgICAgIC8vIEluIG11dGF0aW9uIG1vZGUsIHRoaXMgaXMgc3VmZmljaWVudCBmb3IgYSBiYWlsb3V0IGJlY2F1c2VcbiAgICAgIC8vIHdlIHdvbid0IHRvdWNoIHRoaXMgbm9kZSBldmVuIGlmIGNoaWxkcmVuIGNoYW5nZWQuXG4gICAgICByZXR1cm47XG4gICAgfSAvLyBJZiB3ZSBnZXQgdXBkYXRlZCBiZWNhdXNlIG9uZSBvZiBvdXIgY2hpbGRyZW4gdXBkYXRlZCwgd2UgZG9uJ3RcbiAgICAvLyBoYXZlIG5ld1Byb3BzIHNvIHdlJ2xsIGhhdmUgdG8gcmV1c2UgdGhlbS5cbiAgICAvLyBUT0RPOiBTcGxpdCB0aGUgdXBkYXRlIEFQSSBhcyBzZXBhcmF0ZSBmb3IgdGhlIHByb3BzIHZzLiBjaGlsZHJlbi5cbiAgICAvLyBFdmVuIGJldHRlciB3b3VsZCBiZSBpZiBjaGlsZHJlbiB3ZXJlbid0IHNwZWNpYWwgY2FzZWQgYXQgYWxsIHRoby5cblxuXG4gICAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICAgIHZhciBjdXJyZW50SG9zdENvbnRleHQgPSBnZXRIb3N0Q29udGV4dCgpOyAvLyBUT0RPOiBFeHBlcmllbmNpbmcgYW4gZXJyb3Igd2hlcmUgb2xkUHJvcHMgaXMgbnVsbC4gU3VnZ2VzdHMgYSBob3N0XG4gICAgLy8gY29tcG9uZW50IGlzIGhpdHRpbmcgdGhlIHJlc3VtZSBwYXRoLiBGaWd1cmUgb3V0IHdoeS4gUG9zc2libHlcbiAgICAvLyByZWxhdGVkIHRvIGBoaWRkZW5gLlxuXG4gICAgdmFyIHVwZGF0ZVBheWxvYWQgPSBwcmVwYXJlVXBkYXRlKGluc3RhbmNlLCB0eXBlLCBvbGRQcm9wcywgbmV3UHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgY3VycmVudEhvc3RDb250ZXh0KTsgLy8gVE9ETzogVHlwZSB0aGlzIHNwZWNpZmljIHRvIHRoaXMgdHlwZSBvZiBjb21wb25lbnQuXG5cbiAgICB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZSA9IHVwZGF0ZVBheWxvYWQ7IC8vIElmIHRoZSB1cGRhdGUgcGF5bG9hZCBpbmRpY2F0ZXMgdGhhdCB0aGVyZSBpcyBhIGNoYW5nZSBvciBpZiB0aGVyZVxuICAgIC8vIGlzIGEgbmV3IHJlZiB3ZSBtYXJrIHRoaXMgYXMgYW4gdXBkYXRlLiBBbGwgdGhlIHdvcmsgaXMgZG9uZSBpbiBjb21taXRXb3JrLlxuXG4gICAgaWYgKHVwZGF0ZVBheWxvYWQpIHtcbiAgICAgIG1hcmtVcGRhdGUod29ya0luUHJvZ3Jlc3MpO1xuICAgIH1cbiAgfTtcblxuICB1cGRhdGVIb3N0VGV4dCQxID0gZnVuY3Rpb24gKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBvbGRUZXh0LCBuZXdUZXh0KSB7XG4gICAgLy8gSWYgdGhlIHRleHQgZGlmZmVycywgbWFyayBpdCBhcyBhbiB1cGRhdGUuIEFsbCB0aGUgd29yayBpbiBkb25lIGluIGNvbW1pdFdvcmsuXG4gICAgaWYgKG9sZFRleHQgIT09IG5ld1RleHQpIHtcbiAgICAgIG1hcmtVcGRhdGUod29ya0luUHJvZ3Jlc3MpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gY3V0T2ZmVGFpbElmTmVlZGVkKHJlbmRlclN0YXRlLCBoYXNSZW5kZXJlZEFUYWlsRmFsbGJhY2spIHtcbiAgaWYgKGdldElzSHlkcmF0aW5nKCkpIHtcbiAgICAvLyBJZiB3ZSdyZSBoeWRyYXRpbmcsIHdlIHNob3VsZCBjb25zdW1lIGFzIG1hbnkgaXRlbXMgYXMgd2UgY2FuXG4gICAgLy8gc28gd2UgZG9uJ3QgbGVhdmUgYW55IGJlaGluZC5cbiAgICByZXR1cm47XG4gIH1cblxuICBzd2l0Y2ggKHJlbmRlclN0YXRlLnRhaWxNb2RlKSB7XG4gICAgY2FzZSAnaGlkZGVuJzpcbiAgICAgIHtcbiAgICAgICAgLy8gQW55IGluc2VydGlvbnMgYXQgdGhlIGVuZCBvZiB0aGUgdGFpbCBsaXN0IGFmdGVyIHRoaXMgcG9pbnRcbiAgICAgICAgLy8gc2hvdWxkIGJlIGludmlzaWJsZS4gSWYgdGhlcmUgYXJlIGFscmVhZHkgbW91bnRlZCBib3VuZGFyaWVzXG4gICAgICAgIC8vIGFueXRoaW5nIGJlZm9yZSB0aGVtIGFyZSBub3QgY29uc2lkZXJlZCBmb3IgY29sbGFwc2luZy5cbiAgICAgICAgLy8gVGhlcmVmb3JlIHdlIG5lZWQgdG8gZ28gdGhyb3VnaCB0aGUgd2hvbGUgdGFpbCB0byBmaW5kIGlmXG4gICAgICAgIC8vIHRoZXJlIGFyZSBhbnkuXG4gICAgICAgIHZhciB0YWlsTm9kZSA9IHJlbmRlclN0YXRlLnRhaWw7XG4gICAgICAgIHZhciBsYXN0VGFpbE5vZGUgPSBudWxsO1xuXG4gICAgICAgIHdoaWxlICh0YWlsTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmICh0YWlsTm9kZS5hbHRlcm5hdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGxhc3RUYWlsTm9kZSA9IHRhaWxOb2RlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRhaWxOb2RlID0gdGFpbE5vZGUuc2libGluZztcbiAgICAgICAgfSAvLyBOZXh0IHdlJ3JlIHNpbXBseSBnb2luZyB0byBkZWxldGUgYWxsIGluc2VydGlvbnMgYWZ0ZXIgdGhlXG4gICAgICAgIC8vIGxhc3QgcmVuZGVyZWQgaXRlbS5cblxuXG4gICAgICAgIGlmIChsYXN0VGFpbE5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBBbGwgcmVtYWluaW5nIGl0ZW1zIGluIHRoZSB0YWlsIGFyZSBpbnNlcnRpb25zLlxuICAgICAgICAgIHJlbmRlclN0YXRlLnRhaWwgPSBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIERldGFjaCB0aGUgaW5zZXJ0aW9uIGFmdGVyIHRoZSBsYXN0IG5vZGUgdGhhdCB3YXMgYWxyZWFkeVxuICAgICAgICAgIC8vIGluc2VydGVkLlxuICAgICAgICAgIGxhc3RUYWlsTm9kZS5zaWJsaW5nID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSAnY29sbGFwc2VkJzpcbiAgICAgIHtcbiAgICAgICAgLy8gQW55IGluc2VydGlvbnMgYXQgdGhlIGVuZCBvZiB0aGUgdGFpbCBsaXN0IGFmdGVyIHRoaXMgcG9pbnRcbiAgICAgICAgLy8gc2hvdWxkIGJlIGludmlzaWJsZS4gSWYgdGhlcmUgYXJlIGFscmVhZHkgbW91bnRlZCBib3VuZGFyaWVzXG4gICAgICAgIC8vIGFueXRoaW5nIGJlZm9yZSB0aGVtIGFyZSBub3QgY29uc2lkZXJlZCBmb3IgY29sbGFwc2luZy5cbiAgICAgICAgLy8gVGhlcmVmb3JlIHdlIG5lZWQgdG8gZ28gdGhyb3VnaCB0aGUgd2hvbGUgdGFpbCB0byBmaW5kIGlmXG4gICAgICAgIC8vIHRoZXJlIGFyZSBhbnkuXG4gICAgICAgIHZhciBfdGFpbE5vZGUgPSByZW5kZXJTdGF0ZS50YWlsO1xuICAgICAgICB2YXIgX2xhc3RUYWlsTm9kZSA9IG51bGw7XG5cbiAgICAgICAgd2hpbGUgKF90YWlsTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmIChfdGFpbE5vZGUuYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBfbGFzdFRhaWxOb2RlID0gX3RhaWxOb2RlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIF90YWlsTm9kZSA9IF90YWlsTm9kZS5zaWJsaW5nO1xuICAgICAgICB9IC8vIE5leHQgd2UncmUgc2ltcGx5IGdvaW5nIHRvIGRlbGV0ZSBhbGwgaW5zZXJ0aW9ucyBhZnRlciB0aGVcbiAgICAgICAgLy8gbGFzdCByZW5kZXJlZCBpdGVtLlxuXG5cbiAgICAgICAgaWYgKF9sYXN0VGFpbE5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBBbGwgcmVtYWluaW5nIGl0ZW1zIGluIHRoZSB0YWlsIGFyZSBpbnNlcnRpb25zLlxuICAgICAgICAgIGlmICghaGFzUmVuZGVyZWRBVGFpbEZhbGxiYWNrICYmIHJlbmRlclN0YXRlLnRhaWwgIT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFdlIHN1c3BlbmRlZCBkdXJpbmcgdGhlIGhlYWQuIFdlIHdhbnQgdG8gc2hvdyBhdCBsZWFzdCBvbmVcbiAgICAgICAgICAgIC8vIHJvdyBhdCB0aGUgdGFpbC4gU28gd2UnbGwga2VlcCBvbiBhbmQgY3V0IG9mZiB0aGUgcmVzdC5cbiAgICAgICAgICAgIHJlbmRlclN0YXRlLnRhaWwuc2libGluZyA9IG51bGw7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlbmRlclN0YXRlLnRhaWwgPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBEZXRhY2ggdGhlIGluc2VydGlvbiBhZnRlciB0aGUgbGFzdCBub2RlIHRoYXQgd2FzIGFscmVhZHlcbiAgICAgICAgICAvLyBpbnNlcnRlZC5cbiAgICAgICAgICBfbGFzdFRhaWxOb2RlLnNpYmxpbmcgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYnViYmxlUHJvcGVydGllcyhjb21wbGV0ZWRXb3JrKSB7XG4gIHZhciBkaWRCYWlsb3V0ID0gY29tcGxldGVkV29yay5hbHRlcm5hdGUgIT09IG51bGwgJiYgY29tcGxldGVkV29yay5hbHRlcm5hdGUuY2hpbGQgPT09IGNvbXBsZXRlZFdvcmsuY2hpbGQ7XG4gIHZhciBuZXdDaGlsZExhbmVzID0gTm9MYW5lcztcbiAgdmFyIHN1YnRyZWVGbGFncyA9IE5vRmxhZ3M7XG5cbiAgaWYgKCFkaWRCYWlsb3V0KSB7XG4gICAgLy8gQnViYmxlIHVwIHRoZSBlYXJsaWVzdCBleHBpcmF0aW9uIHRpbWUuXG4gICAgaWYgKCAoY29tcGxldGVkV29yay5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgIC8vIEluIHByb2ZpbGluZyBtb2RlLCByZXNldENoaWxkRXhwaXJhdGlvblRpbWUgaXMgYWxzbyB1c2VkIHRvIHJlc2V0XG4gICAgICAvLyBwcm9maWxlciBkdXJhdGlvbnMuXG4gICAgICB2YXIgYWN0dWFsRHVyYXRpb24gPSBjb21wbGV0ZWRXb3JrLmFjdHVhbER1cmF0aW9uO1xuICAgICAgdmFyIHRyZWVCYXNlRHVyYXRpb24gPSBjb21wbGV0ZWRXb3JrLnNlbGZCYXNlRHVyYXRpb247XG4gICAgICB2YXIgY2hpbGQgPSBjb21wbGV0ZWRXb3JrLmNoaWxkO1xuXG4gICAgICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICAgICAgbmV3Q2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMobmV3Q2hpbGRMYW5lcywgbWVyZ2VMYW5lcyhjaGlsZC5sYW5lcywgY2hpbGQuY2hpbGRMYW5lcykpO1xuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gY2hpbGQuc3VidHJlZUZsYWdzO1xuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gY2hpbGQuZmxhZ3M7IC8vIFdoZW4gYSBmaWJlciBpcyBjbG9uZWQsIGl0cyBhY3R1YWxEdXJhdGlvbiBpcyByZXNldCB0byAwLiBUaGlzIHZhbHVlIHdpbGxcbiAgICAgICAgLy8gb25seSBiZSB1cGRhdGVkIGlmIHdvcmsgaXMgZG9uZSBvbiB0aGUgZmliZXIgKGkuZS4gaXQgZG9lc24ndCBiYWlsb3V0KS5cbiAgICAgICAgLy8gV2hlbiB3b3JrIGlzIGRvbmUsIGl0IHNob3VsZCBidWJibGUgdG8gdGhlIHBhcmVudCdzIGFjdHVhbER1cmF0aW9uLiBJZlxuICAgICAgICAvLyB0aGUgZmliZXIgaGFzIG5vdCBiZWVuIGNsb25lZCB0aG91Z2gsIChtZWFuaW5nIG5vIHdvcmsgd2FzIGRvbmUpLCB0aGVuXG4gICAgICAgIC8vIHRoaXMgdmFsdWUgd2lsbCByZWZsZWN0IHRoZSBhbW91bnQgb2YgdGltZSBzcGVudCB3b3JraW5nIG9uIGEgcHJldmlvdXNcbiAgICAgICAgLy8gcmVuZGVyLiBJbiB0aGF0IGNhc2UgaXQgc2hvdWxkIG5vdCBidWJibGUuIFdlIGRldGVybWluZSB3aGV0aGVyIGl0IHdhc1xuICAgICAgICAvLyBjbG9uZWQgYnkgY29tcGFyaW5nIHRoZSBjaGlsZCBwb2ludGVyLlxuXG4gICAgICAgIGFjdHVhbER1cmF0aW9uICs9IGNoaWxkLmFjdHVhbER1cmF0aW9uO1xuICAgICAgICB0cmVlQmFzZUR1cmF0aW9uICs9IGNoaWxkLnRyZWVCYXNlRHVyYXRpb247XG4gICAgICAgIGNoaWxkID0gY2hpbGQuc2libGluZztcbiAgICAgIH1cblxuICAgICAgY29tcGxldGVkV29yay5hY3R1YWxEdXJhdGlvbiA9IGFjdHVhbER1cmF0aW9uO1xuICAgICAgY29tcGxldGVkV29yay50cmVlQmFzZUR1cmF0aW9uID0gdHJlZUJhc2VEdXJhdGlvbjtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIF9jaGlsZCA9IGNvbXBsZXRlZFdvcmsuY2hpbGQ7XG5cbiAgICAgIHdoaWxlIChfY2hpbGQgIT09IG51bGwpIHtcbiAgICAgICAgbmV3Q2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMobmV3Q2hpbGRMYW5lcywgbWVyZ2VMYW5lcyhfY2hpbGQubGFuZXMsIF9jaGlsZC5jaGlsZExhbmVzKSk7XG4gICAgICAgIHN1YnRyZWVGbGFncyB8PSBfY2hpbGQuc3VidHJlZUZsYWdzO1xuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gX2NoaWxkLmZsYWdzOyAvLyBVcGRhdGUgdGhlIHJldHVybiBwb2ludGVyIHNvIHRoZSB0cmVlIGlzIGNvbnNpc3RlbnQuIFRoaXMgaXMgYSBjb2RlXG4gICAgICAgIC8vIHNtZWxsIGJlY2F1c2UgaXQgYXNzdW1lcyB0aGUgY29tbWl0IHBoYXNlIGlzIG5ldmVyIGNvbmN1cnJlbnQgd2l0aFxuICAgICAgICAvLyB0aGUgcmVuZGVyIHBoYXNlLiBXaWxsIGFkZHJlc3MgZHVyaW5nIHJlZmFjdG9yIHRvIGFsdGVybmF0ZSBtb2RlbC5cblxuICAgICAgICBfY2hpbGQucmV0dXJuID0gY29tcGxldGVkV29yaztcbiAgICAgICAgX2NoaWxkID0gX2NoaWxkLnNpYmxpbmc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29tcGxldGVkV29yay5zdWJ0cmVlRmxhZ3MgfD0gc3VidHJlZUZsYWdzO1xuICB9IGVsc2Uge1xuICAgIC8vIEJ1YmJsZSB1cCB0aGUgZWFybGllc3QgZXhwaXJhdGlvbiB0aW1lLlxuICAgIGlmICggKGNvbXBsZXRlZFdvcmsubW9kZSAmIFByb2ZpbGVNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICAvLyBJbiBwcm9maWxpbmcgbW9kZSwgcmVzZXRDaGlsZEV4cGlyYXRpb25UaW1lIGlzIGFsc28gdXNlZCB0byByZXNldFxuICAgICAgLy8gcHJvZmlsZXIgZHVyYXRpb25zLlxuICAgICAgdmFyIF90cmVlQmFzZUR1cmF0aW9uID0gY29tcGxldGVkV29yay5zZWxmQmFzZUR1cmF0aW9uO1xuICAgICAgdmFyIF9jaGlsZDIgPSBjb21wbGV0ZWRXb3JrLmNoaWxkO1xuXG4gICAgICB3aGlsZSAoX2NoaWxkMiAhPT0gbnVsbCkge1xuICAgICAgICBuZXdDaGlsZExhbmVzID0gbWVyZ2VMYW5lcyhuZXdDaGlsZExhbmVzLCBtZXJnZUxhbmVzKF9jaGlsZDIubGFuZXMsIF9jaGlsZDIuY2hpbGRMYW5lcykpOyAvLyBcIlN0YXRpY1wiIGZsYWdzIHNoYXJlIHRoZSBsaWZldGltZSBvZiB0aGUgZmliZXIvaG9vayB0aGV5IGJlbG9uZyB0byxcbiAgICAgICAgLy8gc28gd2Ugc2hvdWxkIGJ1YmJsZSB0aG9zZSB1cCBldmVuIGR1cmluZyBhIGJhaWxvdXQuIEFsbCB0aGUgb3RoZXJcbiAgICAgICAgLy8gZmxhZ3MgaGF2ZSBhIGxpZmV0aW1lIG9ubHkgb2YgYSBzaW5nbGUgcmVuZGVyICsgY29tbWl0LCBzbyB3ZSBzaG91bGRcbiAgICAgICAgLy8gaWdub3JlIHRoZW0uXG5cbiAgICAgICAgc3VidHJlZUZsYWdzIHw9IF9jaGlsZDIuc3VidHJlZUZsYWdzICYgU3RhdGljTWFzaztcbiAgICAgICAgc3VidHJlZUZsYWdzIHw9IF9jaGlsZDIuZmxhZ3MgJiBTdGF0aWNNYXNrO1xuICAgICAgICBfdHJlZUJhc2VEdXJhdGlvbiArPSBfY2hpbGQyLnRyZWVCYXNlRHVyYXRpb247XG4gICAgICAgIF9jaGlsZDIgPSBfY2hpbGQyLnNpYmxpbmc7XG4gICAgICB9XG5cbiAgICAgIGNvbXBsZXRlZFdvcmsudHJlZUJhc2VEdXJhdGlvbiA9IF90cmVlQmFzZUR1cmF0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgX2NoaWxkMyA9IGNvbXBsZXRlZFdvcmsuY2hpbGQ7XG5cbiAgICAgIHdoaWxlIChfY2hpbGQzICE9PSBudWxsKSB7XG4gICAgICAgIG5ld0NoaWxkTGFuZXMgPSBtZXJnZUxhbmVzKG5ld0NoaWxkTGFuZXMsIG1lcmdlTGFuZXMoX2NoaWxkMy5sYW5lcywgX2NoaWxkMy5jaGlsZExhbmVzKSk7IC8vIFwiU3RhdGljXCIgZmxhZ3Mgc2hhcmUgdGhlIGxpZmV0aW1lIG9mIHRoZSBmaWJlci9ob29rIHRoZXkgYmVsb25nIHRvLFxuICAgICAgICAvLyBzbyB3ZSBzaG91bGQgYnViYmxlIHRob3NlIHVwIGV2ZW4gZHVyaW5nIGEgYmFpbG91dC4gQWxsIHRoZSBvdGhlclxuICAgICAgICAvLyBmbGFncyBoYXZlIGEgbGlmZXRpbWUgb25seSBvZiBhIHNpbmdsZSByZW5kZXIgKyBjb21taXQsIHNvIHdlIHNob3VsZFxuICAgICAgICAvLyBpZ25vcmUgdGhlbS5cblxuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gX2NoaWxkMy5zdWJ0cmVlRmxhZ3MgJiBTdGF0aWNNYXNrO1xuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gX2NoaWxkMy5mbGFncyAmIFN0YXRpY01hc2s7IC8vIFVwZGF0ZSB0aGUgcmV0dXJuIHBvaW50ZXIgc28gdGhlIHRyZWUgaXMgY29uc2lzdGVudC4gVGhpcyBpcyBhIGNvZGVcbiAgICAgICAgLy8gc21lbGwgYmVjYXVzZSBpdCBhc3N1bWVzIHRoZSBjb21taXQgcGhhc2UgaXMgbmV2ZXIgY29uY3VycmVudCB3aXRoXG4gICAgICAgIC8vIHRoZSByZW5kZXIgcGhhc2UuIFdpbGwgYWRkcmVzcyBkdXJpbmcgcmVmYWN0b3IgdG8gYWx0ZXJuYXRlIG1vZGVsLlxuXG4gICAgICAgIF9jaGlsZDMucmV0dXJuID0gY29tcGxldGVkV29yaztcbiAgICAgICAgX2NoaWxkMyA9IF9jaGlsZDMuc2libGluZztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb21wbGV0ZWRXb3JrLnN1YnRyZWVGbGFncyB8PSBzdWJ0cmVlRmxhZ3M7XG4gIH1cblxuICBjb21wbGV0ZWRXb3JrLmNoaWxkTGFuZXMgPSBuZXdDaGlsZExhbmVzO1xuICByZXR1cm4gZGlkQmFpbG91dDtcbn1cblxuZnVuY3Rpb24gY29tcGxldGVEZWh5ZHJhdGVkU3VzcGVuc2VCb3VuZGFyeShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dFN0YXRlKSB7XG4gIGlmIChoYXNVbmh5ZHJhdGVkVGFpbE5vZGVzKCkgJiYgKHdvcmtJblByb2dyZXNzLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZSAmJiAod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBEaWRDYXB0dXJlKSA9PT0gTm9GbGFncykge1xuICAgIHdhcm5JZlVuaHlkcmF0ZWRUYWlsTm9kZXMod29ya0luUHJvZ3Jlc3MpO1xuICAgIHJlc2V0SHlkcmF0aW9uU3RhdGUoKTtcbiAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBGb3JjZUNsaWVudFJlbmRlciB8IEluY29tcGxldGUgfCBTaG91bGRDYXB0dXJlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciB3YXNIeWRyYXRlZCA9IHBvcEh5ZHJhdGlvblN0YXRlKHdvcmtJblByb2dyZXNzKTtcblxuICBpZiAobmV4dFN0YXRlICE9PSBudWxsICYmIG5leHRTdGF0ZS5kZWh5ZHJhdGVkICE9PSBudWxsKSB7XG4gICAgLy8gV2UgbWlnaHQgYmUgaW5zaWRlIGEgaHlkcmF0aW9uIHN0YXRlIHRoZSBmaXJzdCB0aW1lIHdlJ3JlIHBpY2tpbmcgdXAgdGhpc1xuICAgIC8vIFN1c3BlbnNlIGJvdW5kYXJ5LCBhbmQgYWxzbyBhZnRlciB3ZSd2ZSByZWVudGVyZWQgaXQgZm9yIGZ1cnRoZXIgaHlkcmF0aW9uLlxuICAgIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgICBpZiAoIXdhc0h5ZHJhdGVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQSBkZWh5ZHJhdGVkIHN1c3BlbnNlIGNvbXBvbmVudCB3YXMgY29tcGxldGVkIHdpdGhvdXQgYSBoeWRyYXRlZCBub2RlLiAnICsgJ1RoaXMgaXMgcHJvYmFibHkgYSBidWcgaW4gUmVhY3QuJyk7XG4gICAgICB9XG5cbiAgICAgIHByZXBhcmVUb0h5ZHJhdGVIb3N0U3VzcGVuc2VJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcblxuICAgICAge1xuICAgICAgICBpZiAoKHdvcmtJblByb2dyZXNzLm1vZGUgJiBQcm9maWxlTW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgICAgIHZhciBpc1RpbWVkT3V0U3VzcGVuc2UgPSBuZXh0U3RhdGUgIT09IG51bGw7XG5cbiAgICAgICAgICBpZiAoaXNUaW1lZE91dFN1c3BlbnNlKSB7XG4gICAgICAgICAgICAvLyBEb24ndCBjb3VudCB0aW1lIHNwZW50IGluIGEgdGltZWQgb3V0IFN1c3BlbnNlIHN1YnRyZWUgYXMgcGFydCBvZiB0aGUgYmFzZSBkdXJhdGlvbi5cbiAgICAgICAgICAgIHZhciBwcmltYXJ5Q2hpbGRGcmFnbWVudCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuXG4gICAgICAgICAgICBpZiAocHJpbWFyeUNoaWxkRnJhZ21lbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgLy8gJEZsb3dGaXhNZSBGbG93IGRvZXNuJ3Qgc3VwcG9ydCB0eXBlIGNhc3RpbmcgaW4gY29tYmluYXRpb24gd2l0aCB0aGUgLT0gb3BlcmF0b3JcbiAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MudHJlZUJhc2VEdXJhdGlvbiAtPSBwcmltYXJ5Q2hpbGRGcmFnbWVudC50cmVlQmFzZUR1cmF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFdlIG1pZ2h0IGhhdmUgcmVlbnRlcmVkIHRoaXMgYm91bmRhcnkgdG8gaHlkcmF0ZSBpdC4gSWYgc28sIHdlIG5lZWQgdG8gcmVzZXQgdGhlIGh5ZHJhdGlvblxuICAgICAgLy8gc3RhdGUgc2luY2Ugd2UncmUgbm93IGV4aXRpbmcgb3V0IG9mIGl0LiBwb3BIeWRyYXRpb25TdGF0ZSBkb2Vzbid0IGRvIHRoYXQgZm9yIHVzLlxuICAgICAgcmVzZXRIeWRyYXRpb25TdGF0ZSgpO1xuXG4gICAgICBpZiAoKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRGlkQ2FwdHVyZSkgPT09IE5vRmxhZ3MpIHtcbiAgICAgICAgLy8gVGhpcyBib3VuZGFyeSBkaWQgbm90IHN1c3BlbmQgc28gaXQncyBub3cgaHlkcmF0ZWQgYW5kIHVuc3VzcGVuZGVkLlxuICAgICAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gbnVsbDtcbiAgICAgIH0gLy8gSWYgbm90aGluZyBzdXNwZW5kZWQsIHdlIG5lZWQgdG8gc2NoZWR1bGUgYW4gZWZmZWN0IHRvIG1hcmsgdGhpcyBib3VuZGFyeVxuICAgICAgLy8gYXMgaGF2aW5nIGh5ZHJhdGVkIHNvIGV2ZW50cyBrbm93IHRoYXQgdGhleSdyZSBmcmVlIHRvIGJlIGludm9rZWQuXG4gICAgICAvLyBJdCdzIGFsc28gYSBzaWduYWwgdG8gcmVwbGF5IGV2ZW50cyBhbmQgdGhlIHN1c3BlbnNlIGNhbGxiYWNrLlxuICAgICAgLy8gSWYgc29tZXRoaW5nIHN1c3BlbmRlZCwgc2NoZWR1bGUgYW4gZWZmZWN0IHRvIGF0dGFjaCByZXRyeSBsaXN0ZW5lcnMuXG4gICAgICAvLyBTbyB3ZSBtaWdodCBhcyB3ZWxsIGFsd2F5cyBtYXJrIHRoaXMuXG5cblxuICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gVXBkYXRlO1xuICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgIHtcbiAgICAgICAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgICB2YXIgX2lzVGltZWRPdXRTdXNwZW5zZSA9IG5leHRTdGF0ZSAhPT0gbnVsbDtcblxuICAgICAgICAgIGlmIChfaXNUaW1lZE91dFN1c3BlbnNlKSB7XG4gICAgICAgICAgICAvLyBEb24ndCBjb3VudCB0aW1lIHNwZW50IGluIGEgdGltZWQgb3V0IFN1c3BlbnNlIHN1YnRyZWUgYXMgcGFydCBvZiB0aGUgYmFzZSBkdXJhdGlvbi5cbiAgICAgICAgICAgIHZhciBfcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcblxuICAgICAgICAgICAgaWYgKF9wcmltYXJ5Q2hpbGRGcmFnbWVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lIEZsb3cgZG9lc24ndCBzdXBwb3J0IHR5cGUgY2FzdGluZyBpbiBjb21iaW5hdGlvbiB3aXRoIHRoZSAtPSBvcGVyYXRvclxuICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy50cmVlQmFzZUR1cmF0aW9uIC09IF9wcmltYXJ5Q2hpbGRGcmFnbWVudC50cmVlQmFzZUR1cmF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgdGhpcyB0cmVlLiBJZiB0aGlzIHdhcyBhIGZvcmNlZCBjbGllbnQgcmVuZGVyLFxuICAgIC8vIHRoZXJlIG1heSBoYXZlIGJlZW4gcmVjb3ZlcmFibGUgZXJyb3JzIGR1cmluZyBmaXJzdCBoeWRyYXRpb25cbiAgICAvLyBhdHRlbXB0LiBJZiBzbywgYWRkIHRoZW0gdG8gYSBxdWV1ZSBzbyB3ZSBjYW4gbG9nIHRoZW0gaW4gdGhlXG4gICAgLy8gY29tbWl0IHBoYXNlLlxuICAgIHVwZ3JhZGVIeWRyYXRpb25FcnJvcnNUb1JlY292ZXJhYmxlKCk7IC8vIEZhbGwgdGhyb3VnaCB0byBub3JtYWwgU3VzcGVuc2UgcGF0aFxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tcGxldGVXb3JrKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcykge1xuICB2YXIgbmV3UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7IC8vIE5vdGU6IFRoaXMgaW50ZW50aW9uYWxseSBkb2Vzbid0IGNoZWNrIGlmIHdlJ3JlIGh5ZHJhdGluZyBiZWNhdXNlIGNvbXBhcmluZ1xuICAvLyB0byB0aGUgY3VycmVudCB0cmVlIHByb3ZpZGVyIGZpYmVyIGlzIGp1c3QgYXMgZmFzdCBhbmQgbGVzcyBlcnJvci1wcm9uZS5cbiAgLy8gSWRlYWxseSB3ZSB3b3VsZCBoYXZlIGEgc3BlY2lhbCB2ZXJzaW9uIG9mIHRoZSB3b3JrIGxvb3Agb25seVxuICAvLyBmb3IgaHlkcmF0aW9uLlxuXG4gIHBvcFRyZWVDb250ZXh0KHdvcmtJblByb2dyZXNzKTtcblxuICBzd2l0Y2ggKHdvcmtJblByb2dyZXNzLnRhZykge1xuICAgIGNhc2UgSW5kZXRlcm1pbmF0ZUNvbXBvbmVudDpcbiAgICBjYXNlIExhenlDb21wb25lbnQ6XG4gICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgIGNhc2UgRnJhZ21lbnQ6XG4gICAgY2FzZSBNb2RlOlxuICAgIGNhc2UgUHJvZmlsZXI6XG4gICAgY2FzZSBDb250ZXh0Q29uc3VtZXI6XG4gICAgY2FzZSBNZW1vQ29tcG9uZW50OlxuICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICByZXR1cm4gbnVsbDtcblxuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBDb21wb25lbnQgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuXG4gICAgICAgIGlmIChpc0NvbnRleHRQcm92aWRlcihDb21wb25lbnQpKSB7XG4gICAgICAgICAgcG9wQ29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIH1cblxuICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RSb290OlxuICAgICAge1xuICAgICAgICB2YXIgZmliZXJSb290ID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICAgICAgICBwb3BIb3N0Q29udGFpbmVyKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcG9wVG9wTGV2ZWxDb250ZXh0T2JqZWN0KHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcmVzZXRXb3JrSW5Qcm9ncmVzc1ZlcnNpb25zKCk7XG5cbiAgICAgICAgaWYgKGZpYmVyUm9vdC5wZW5kaW5nQ29udGV4dCkge1xuICAgICAgICAgIGZpYmVyUm9vdC5jb250ZXh0ID0gZmliZXJSb290LnBlbmRpbmdDb250ZXh0O1xuICAgICAgICAgIGZpYmVyUm9vdC5wZW5kaW5nQ29udGV4dCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY3VycmVudCA9PT0gbnVsbCB8fCBjdXJyZW50LmNoaWxkID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gSWYgd2UgaHlkcmF0ZWQsIHBvcCBzbyB0aGF0IHdlIGNhbiBkZWxldGUgYW55IHJlbWFpbmluZyBjaGlsZHJlblxuICAgICAgICAgIC8vIHRoYXQgd2VyZW4ndCBoeWRyYXRlZC5cbiAgICAgICAgICB2YXIgd2FzSHlkcmF0ZWQgPSBwb3BIeWRyYXRpb25TdGF0ZSh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgICAgICBpZiAod2FzSHlkcmF0ZWQpIHtcbiAgICAgICAgICAgIC8vIElmIHdlIGh5ZHJhdGVkLCB0aGVuIHdlJ2xsIG5lZWQgdG8gc2NoZWR1bGUgYW4gdXBkYXRlIGZvclxuICAgICAgICAgICAgLy8gdGhlIGNvbW1pdCBzaWRlLWVmZmVjdHMgb24gdGhlIHJvb3QuXG4gICAgICAgICAgICBtYXJrVXBkYXRlKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdmFyIHByZXZTdGF0ZSA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcblxuICAgICAgICAgICAgICBpZiAoIC8vIENoZWNrIGlmIHRoaXMgaXMgYSBjbGllbnQgcm9vdFxuICAgICAgICAgICAgICAhcHJldlN0YXRlLmlzRGVoeWRyYXRlZCB8fCAvLyBDaGVjayBpZiB3ZSByZXZlcnRlZCB0byBjbGllbnQgcmVuZGVyaW5nIChlLmcuIGR1ZSB0byBhbiBlcnJvcilcbiAgICAgICAgICAgICAgKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRm9yY2VDbGllbnRSZW5kZXIpICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgICAgICAgICAgLy8gU2NoZWR1bGUgYW4gZWZmZWN0IHRvIGNsZWFyIHRoaXMgY29udGFpbmVyIGF0IHRoZSBzdGFydCBvZiB0aGVcbiAgICAgICAgICAgICAgICAvLyBuZXh0IGNvbW1pdC4gVGhpcyBoYW5kbGVzIHRoZSBjYXNlIG9mIFJlYWN0IHJlbmRlcmluZyBpbnRvIGFcbiAgICAgICAgICAgICAgICAvLyBjb250YWluZXIgd2l0aCBwcmV2aW91cyBjaGlsZHJlbi4gSXQncyBhbHNvIHNhZmUgdG8gZG8gZm9yXG4gICAgICAgICAgICAgICAgLy8gdXBkYXRlcyB0b28sIGJlY2F1c2UgY3VycmVudC5jaGlsZCB3b3VsZCBvbmx5IGJlIG51bGwgaWYgdGhlXG4gICAgICAgICAgICAgICAgLy8gcHJldmlvdXMgcmVuZGVyIHdhcyBudWxsIChzbyB0aGUgY29udGFpbmVyIHdvdWxkIGFscmVhZHlcbiAgICAgICAgICAgICAgICAvLyBiZSBlbXB0eSkuXG4gICAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gU25hcHNob3Q7IC8vIElmIHRoaXMgd2FzIGEgZm9yY2VkIGNsaWVudCByZW5kZXIsIHRoZXJlIG1heSBoYXZlIGJlZW5cbiAgICAgICAgICAgICAgICAvLyByZWNvdmVyYWJsZSBlcnJvcnMgZHVyaW5nIGZpcnN0IGh5ZHJhdGlvbiBhdHRlbXB0LiBJZiBzbywgYWRkXG4gICAgICAgICAgICAgICAgLy8gdGhlbSB0byBhIHF1ZXVlIHNvIHdlIGNhbiBsb2cgdGhlbSBpbiB0aGUgY29tbWl0IHBoYXNlLlxuXG4gICAgICAgICAgICAgICAgdXBncmFkZUh5ZHJhdGlvbkVycm9yc1RvUmVjb3ZlcmFibGUoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHVwZGF0ZUhvc3RDb250YWluZXIoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcG9wSG9zdENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICB2YXIgcm9vdENvbnRhaW5lckluc3RhbmNlID0gZ2V0Um9vdEhvc3RDb250YWluZXIoKTtcbiAgICAgICAgdmFyIHR5cGUgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuXG4gICAgICAgIGlmIChjdXJyZW50ICE9PSBudWxsICYmIHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZSAhPSBudWxsKSB7XG4gICAgICAgICAgdXBkYXRlSG9zdENvbXBvbmVudCQxKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCB0eXBlLCBuZXdQcm9wcywgcm9vdENvbnRhaW5lckluc3RhbmNlKTtcblxuICAgICAgICAgIGlmIChjdXJyZW50LnJlZiAhPT0gd29ya0luUHJvZ3Jlc3MucmVmKSB7XG4gICAgICAgICAgICBtYXJrUmVmJDEod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoIW5ld1Byb3BzKSB7XG4gICAgICAgICAgICBpZiAod29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignV2UgbXVzdCBoYXZlIG5ldyBwcm9wcyBmb3IgbmV3IG1vdW50cy4gVGhpcyBlcnJvciBpcyBsaWtlbHkgJyArICdjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgICAgICAgICAgfSAvLyBUaGlzIGNhbiBoYXBwZW4gd2hlbiB3ZSBhYm9ydCB3b3JrLlxuXG5cbiAgICAgICAgICAgIGJ1YmJsZVByb3BlcnRpZXMod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIGN1cnJlbnRIb3N0Q29udGV4dCA9IGdldEhvc3RDb250ZXh0KCk7IC8vIFRPRE86IE1vdmUgY3JlYXRlSW5zdGFuY2UgdG8gYmVnaW5Xb3JrIGFuZCBrZWVwIGl0IG9uIGEgY29udGV4dFxuICAgICAgICAgIC8vIFwic3RhY2tcIiBhcyB0aGUgcGFyZW50LiBUaGVuIGFwcGVuZCBjaGlsZHJlbiBhcyB3ZSBnbyBpbiBiZWdpbldvcmtcbiAgICAgICAgICAvLyBvciBjb21wbGV0ZVdvcmsgZGVwZW5kaW5nIG9uIHdoZXRoZXIgd2Ugd2FudCB0byBhZGQgdGhlbSB0b3AtPmRvd24gb3JcbiAgICAgICAgICAvLyBib3R0b20tPnVwLiBUb3AtPmRvd24gaXMgZmFzdGVyIGluIElFMTEuXG5cbiAgICAgICAgICB2YXIgX3dhc0h5ZHJhdGVkID0gcG9wSHlkcmF0aW9uU3RhdGUod29ya0luUHJvZ3Jlc3MpO1xuXG4gICAgICAgICAgaWYgKF93YXNIeWRyYXRlZCkge1xuICAgICAgICAgICAgLy8gVE9ETzogTW92ZSB0aGlzIGFuZCBjcmVhdGVJbnN0YW5jZSBzdGVwIGludG8gdGhlIGJlZ2luUGhhc2VcbiAgICAgICAgICAgIC8vIHRvIGNvbnNvbGlkYXRlLlxuICAgICAgICAgICAgaWYgKHByZXBhcmVUb0h5ZHJhdGVIb3N0SW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgY3VycmVudEhvc3RDb250ZXh0KSkge1xuICAgICAgICAgICAgICAvLyBJZiBjaGFuZ2VzIHRvIHRoZSBoeWRyYXRlZCBub2RlIG5lZWQgdG8gYmUgYXBwbGllZCBhdCB0aGVcbiAgICAgICAgICAgICAgLy8gY29tbWl0LXBoYXNlIHdlIG1hcmsgdGhpcyBhcyBzdWNoLlxuICAgICAgICAgICAgICBtYXJrVXBkYXRlKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gY3JlYXRlSW5zdGFuY2UodHlwZSwgbmV3UHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgY3VycmVudEhvc3RDb250ZXh0LCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgICAgICBhcHBlbmRBbGxDaGlsZHJlbihpbnN0YW5jZSwgd29ya0luUHJvZ3Jlc3MsIGZhbHNlLCBmYWxzZSk7XG4gICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUgPSBpbnN0YW5jZTsgLy8gQ2VydGFpbiByZW5kZXJlcnMgcmVxdWlyZSBjb21taXQtdGltZSBlZmZlY3RzIGZvciBpbml0aWFsIG1vdW50LlxuICAgICAgICAgICAgLy8gKGVnIERPTSByZW5kZXJlciBzdXBwb3J0cyBhdXRvLWZvY3VzIGZvciBjZXJ0YWluIGVsZW1lbnRzKS5cbiAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSBzdWNoIHJlbmRlcmVycyBnZXQgc2NoZWR1bGVkIGZvciBsYXRlciB3b3JrLlxuXG4gICAgICAgICAgICBpZiAoZmluYWxpemVJbml0aWFsQ2hpbGRyZW4oaW5zdGFuY2UsIHR5cGUsIG5ld1Byb3BzLCByb290Q29udGFpbmVySW5zdGFuY2UpKSB7XG4gICAgICAgICAgICAgIG1hcmtVcGRhdGUod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh3b3JrSW5Qcm9ncmVzcy5yZWYgIT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIGEgcmVmIG9uIGEgaG9zdCBub2RlIHdlIG5lZWQgdG8gc2NoZWR1bGUgYSBjYWxsYmFja1xuICAgICAgICAgICAgbWFya1JlZiQxKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RUZXh0OlxuICAgICAge1xuICAgICAgICB2YXIgbmV3VGV4dCA9IG5ld1Byb3BzO1xuXG4gICAgICAgIGlmIChjdXJyZW50ICYmIHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZSAhPSBudWxsKSB7XG4gICAgICAgICAgdmFyIG9sZFRleHQgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7IC8vIElmIHdlIGhhdmUgYW4gYWx0ZXJuYXRlLCB0aGF0IG1lYW5zIHRoaXMgaXMgYW4gdXBkYXRlIGFuZCB3ZSBuZWVkXG4gICAgICAgICAgLy8gdG8gc2NoZWR1bGUgYSBzaWRlLWVmZmVjdCB0byBkbyB0aGUgdXBkYXRlcy5cblxuICAgICAgICAgIHVwZGF0ZUhvc3RUZXh0JDEoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG9sZFRleHQsIG5ld1RleHQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0eXBlb2YgbmV3VGV4dCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGlmICh3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZSBtdXN0IGhhdmUgbmV3IHByb3BzIGZvciBuZXcgbW91bnRzLiBUaGlzIGVycm9yIGlzIGxpa2VseSAnICsgJ2NhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgICAgICAgICB9IC8vIFRoaXMgY2FuIGhhcHBlbiB3aGVuIHdlIGFib3J0IHdvcmsuXG5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgX3Jvb3RDb250YWluZXJJbnN0YW5jZSA9IGdldFJvb3RIb3N0Q29udGFpbmVyKCk7XG5cbiAgICAgICAgICB2YXIgX2N1cnJlbnRIb3N0Q29udGV4dCA9IGdldEhvc3RDb250ZXh0KCk7XG5cbiAgICAgICAgICB2YXIgX3dhc0h5ZHJhdGVkMiA9IHBvcEh5ZHJhdGlvblN0YXRlKHdvcmtJblByb2dyZXNzKTtcblxuICAgICAgICAgIGlmIChfd2FzSHlkcmF0ZWQyKSB7XG4gICAgICAgICAgICBpZiAocHJlcGFyZVRvSHlkcmF0ZUhvc3RUZXh0SW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MpKSB7XG4gICAgICAgICAgICAgIG1hcmtVcGRhdGUod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUgPSBjcmVhdGVUZXh0SW5zdGFuY2UobmV3VGV4dCwgX3Jvb3RDb250YWluZXJJbnN0YW5jZSwgX2N1cnJlbnRIb3N0Q29udGV4dCwgd29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGJ1YmJsZVByb3BlcnRpZXMod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHBvcFN1c3BlbnNlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIHZhciBuZXh0U3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlOyAvLyBTcGVjaWFsIHBhdGggZm9yIGRlaHlkcmF0ZWQgYm91bmRhcmllcy4gV2UgbWF5IGV2ZW50dWFsbHkgbW92ZSB0aGlzXG4gICAgICAgIC8vIHRvIGl0cyBvd24gZmliZXIgdHlwZSBzbyB0aGF0IHdlIGNhbiBhZGQgb3RoZXIga2luZHMgb2YgaHlkcmF0aW9uXG4gICAgICAgIC8vIGJvdW5kYXJpZXMgdGhhdCBhcmVuJ3QgYXNzb2NpYXRlZCB3aXRoIGEgU3VzcGVuc2UgdHJlZS4gSW4gYW50aWNpcGF0aW9uXG4gICAgICAgIC8vIG9mIHN1Y2ggYSByZWZhY3RvciwgYWxsIHRoZSBoeWRyYXRpb24gbG9naWMgaXMgY29udGFpbmVkIGluXG4gICAgICAgIC8vIHRoaXMgYnJhbmNoLlxuXG4gICAgICAgIGlmIChjdXJyZW50ID09PSBudWxsIHx8IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZSAhPT0gbnVsbCAmJiBjdXJyZW50Lm1lbW9pemVkU3RhdGUuZGVoeWRyYXRlZCAhPT0gbnVsbCkge1xuICAgICAgICAgIHZhciBmYWxsdGhyb3VnaFRvTm9ybWFsU3VzcGVuc2VQYXRoID0gY29tcGxldGVEZWh5ZHJhdGVkU3VzcGVuc2VCb3VuZGFyeShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dFN0YXRlKTtcblxuICAgICAgICAgIGlmICghZmFsbHRocm91Z2hUb05vcm1hbFN1c3BlbnNlUGF0aCkge1xuICAgICAgICAgICAgaWYgKHdvcmtJblByb2dyZXNzLmZsYWdzICYgU2hvdWxkQ2FwdHVyZSkge1xuICAgICAgICAgICAgICAvLyBTcGVjaWFsIGNhc2UuIFRoZXJlIHdlcmUgcmVtYWluaW5nIHVuaHlkcmF0ZWQgbm9kZXMuIFdlIHRyZWF0XG4gICAgICAgICAgICAgIC8vIHRoaXMgYXMgYSBtaXNtYXRjaC4gUmV2ZXJ0IHRvIGNsaWVudCByZW5kZXJpbmcuXG4gICAgICAgICAgICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIERpZCBub3QgZmluaXNoIGh5ZHJhdGluZywgZWl0aGVyIGJlY2F1c2UgdGhpcyBpcyB0aGUgaW5pdGlhbFxuICAgICAgICAgICAgICAvLyByZW5kZXIgb3IgYmVjYXVzZSBzb21ldGhpbmcgc3VzcGVuZGVkLlxuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IC8vIENvbnRpbnVlIHdpdGggdGhlIG5vcm1hbCBTdXNwZW5zZSBwYXRoLlxuXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRGlkQ2FwdHVyZSkgIT09IE5vRmxhZ3MpIHtcbiAgICAgICAgICAvLyBTb21ldGhpbmcgc3VzcGVuZGVkLiBSZS1yZW5kZXIgd2l0aCB0aGUgZmFsbGJhY2sgY2hpbGRyZW4uXG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSByZW5kZXJMYW5lczsgLy8gRG8gbm90IHJlc2V0IHRoZSBlZmZlY3QgbGlzdC5cblxuICAgICAgICAgIGlmICggKHdvcmtJblByb2dyZXNzLm1vZGUgJiBQcm9maWxlTW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgICAgICAgdHJhbnNmZXJBY3R1YWxEdXJhdGlvbih3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgICAgfSAvLyBEb24ndCBidWJibGUgcHJvcGVydGllcyBpbiB0aGlzIGNhc2UuXG5cblxuICAgICAgICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBuZXh0RGlkVGltZW91dCA9IG5leHRTdGF0ZSAhPT0gbnVsbDtcbiAgICAgICAgdmFyIHByZXZEaWRUaW1lb3V0ID0gY3VycmVudCAhPT0gbnVsbCAmJiBjdXJyZW50Lm1lbW9pemVkU3RhdGUgIT09IG51bGw7XG4gICAgICAgIC8vIGEgcGFzc2l2ZSBlZmZlY3QsIHdoaWNoIGlzIHdoZW4gd2UgcHJvY2VzcyB0aGUgdHJhbnNpdGlvbnNcblxuXG4gICAgICAgIGlmIChuZXh0RGlkVGltZW91dCAhPT0gcHJldkRpZFRpbWVvdXQpIHtcbiAgICAgICAgICAvLyBhbiBlZmZlY3QgdG8gdG9nZ2xlIHRoZSBzdWJ0cmVlJ3MgdmlzaWJpbGl0eS4gV2hlbiB3ZSBzd2l0Y2ggZnJvbVxuICAgICAgICAgIC8vIGZhbGxiYWNrIC0+IHByaW1hcnksIHRoZSBpbm5lciBPZmZzY3JlZW4gZmliZXIgc2NoZWR1bGVzIHRoaXMgZWZmZWN0XG4gICAgICAgICAgLy8gYXMgcGFydCBvZiBpdHMgbm9ybWFsIGNvbXBsZXRlIHBoYXNlLiBCdXQgd2hlbiB3ZSBzd2l0Y2ggZnJvbVxuICAgICAgICAgIC8vIHByaW1hcnkgLT4gZmFsbGJhY2ssIHRoZSBpbm5lciBPZmZzY3JlZW4gZmliZXIgZG9lcyBub3QgaGF2ZSBhIGNvbXBsZXRlXG4gICAgICAgICAgLy8gcGhhc2UuIFNvIHdlIG5lZWQgdG8gc2NoZWR1bGUgaXRzIGVmZmVjdCBoZXJlLlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gV2UgYWxzbyB1c2UgdGhpcyBmbGFnIHRvIGNvbm5lY3QvZGlzY29ubmVjdCB0aGUgZWZmZWN0cywgYnV0IHRoZSBzYW1lXG4gICAgICAgICAgLy8gbG9naWMgYXBwbGllczogd2hlbiByZS1jb25uZWN0aW5nLCB0aGUgT2Zmc2NyZWVuIGZpYmVyJ3MgY29tcGxldGVcbiAgICAgICAgICAvLyBwaGFzZSB3aWxsIGhhbmRsZSBzY2hlZHVsaW5nIHRoZSBlZmZlY3QuIEl0J3Mgb25seSB3aGVuIHRoZSBmYWxsYmFja1xuICAgICAgICAgIC8vIGlzIGFjdGl2ZSB0aGF0IHdlIGhhdmUgdG8gZG8gYW55dGhpbmcgc3BlY2lhbC5cblxuXG4gICAgICAgICAgaWYgKG5leHREaWRUaW1lb3V0KSB7XG4gICAgICAgICAgICB2YXIgX29mZnNjcmVlbkZpYmVyMiA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgICAgICAgICAgX29mZnNjcmVlbkZpYmVyMi5mbGFncyB8PSBWaXNpYmlsaXR5OyAvLyBUT0RPOiBUaGlzIHdpbGwgc3RpbGwgc3VzcGVuZCBhIHN5bmNocm9ub3VzIHRyZWUgaWYgYW55dGhpbmdcbiAgICAgICAgICAgIC8vIGluIHRoZSBjb25jdXJyZW50IHRyZWUgYWxyZWFkeSBzdXNwZW5kZWQgZHVyaW5nIHRoaXMgcmVuZGVyLlxuICAgICAgICAgICAgLy8gVGhpcyBpcyBhIGtub3duIGJ1Zy5cblxuICAgICAgICAgICAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgICAgICAgLy8gVE9ETzogTW92ZSB0aGlzIGJhY2sgdG8gdGhyb3dFeGNlcHRpb24gYmVjYXVzZSB0aGlzIGlzIHRvbyBsYXRlXG4gICAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgYSBsYXJnZSB0cmVlIHdoaWNoIGlzIGNvbW1vbiBmb3IgaW5pdGlhbCBsb2Fkcy4gV2VcbiAgICAgICAgICAgICAgLy8gZG9uJ3Qga25vdyBpZiB3ZSBzaG91bGQgcmVzdGFydCBhIHJlbmRlciBvciBub3QgdW50aWwgd2UgZ2V0XG4gICAgICAgICAgICAgIC8vIHRoaXMgbWFya2VyLCBhbmQgdGhpcyBpcyB0b28gbGF0ZS5cbiAgICAgICAgICAgICAgLy8gSWYgdGhpcyByZW5kZXIgYWxyZWFkeSBoYWQgYSBwaW5nIG9yIGxvd2VyIHByaSB1cGRhdGVzLFxuICAgICAgICAgICAgICAvLyBhbmQgdGhpcyBpcyB0aGUgZmlyc3QgdGltZSB3ZSBrbm93IHdlJ3JlIGdvaW5nIHRvIHN1c3BlbmQgd2VcbiAgICAgICAgICAgICAgLy8gc2hvdWxkIGJlIGFibGUgdG8gaW1tZWRpYXRlbHkgcmVzdGFydCBmcm9tIHdpdGhpbiB0aHJvd0V4Y2VwdGlvbi5cbiAgICAgICAgICAgICAgdmFyIGhhc0ludmlzaWJsZUNoaWxkQ29udGV4dCA9IGN1cnJlbnQgPT09IG51bGwgJiYgKHdvcmtJblByb2dyZXNzLm1lbW9pemVkUHJvcHMudW5zdGFibGVfYXZvaWRUaGlzRmFsbGJhY2sgIT09IHRydWUgfHwgIWVuYWJsZVN1c3BlbnNlQXZvaWRUaGlzRmFsbGJhY2spO1xuXG4gICAgICAgICAgICAgIGlmIChoYXNJbnZpc2libGVDaGlsZENvbnRleHQgfHwgaGFzU3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlU3RhY2tDdXJzb3IuY3VycmVudCwgSW52aXNpYmxlUGFyZW50U3VzcGVuc2VDb250ZXh0KSkge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgd2FzIGluIGFuIGludmlzaWJsZSB0cmVlIG9yIGEgbmV3IHJlbmRlciwgdGhlbiBzaG93aW5nXG4gICAgICAgICAgICAgICAgLy8gdGhpcyBib3VuZGFyeSBpcyBvay5cbiAgICAgICAgICAgICAgICByZW5kZXJEaWRTdXNwZW5kKCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCB3ZSdyZSBnb2luZyB0byBoYXZlIHRvIGhpZGUgY29udGVudCBzbyB3ZSBzaG91bGRcbiAgICAgICAgICAgICAgICAvLyBzdXNwZW5kIGZvciBsb25nZXIgaWYgcG9zc2libGUuXG4gICAgICAgICAgICAgICAgcmVuZGVyRGlkU3VzcGVuZERlbGF5SWZQb3NzaWJsZSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHdha2VhYmxlcyA9IHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlO1xuXG4gICAgICAgIGlmICh3YWtlYWJsZXMgIT09IG51bGwpIHtcbiAgICAgICAgICAvLyBTY2hlZHVsZSBhbiBlZmZlY3QgdG8gYXR0YWNoIGEgcmV0cnkgbGlzdGVuZXIgdG8gdGhlIHByb21pc2UuXG4gICAgICAgICAgLy8gVE9ETzogTW92ZSB0byBwYXNzaXZlIHBoYXNlXG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gVXBkYXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgICAge1xuICAgICAgICAgIGlmICgod29ya0luUHJvZ3Jlc3MubW9kZSAmIFByb2ZpbGVNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICAgICAgICBpZiAobmV4dERpZFRpbWVvdXQpIHtcbiAgICAgICAgICAgICAgLy8gRG9uJ3QgY291bnQgdGltZSBzcGVudCBpbiBhIHRpbWVkIG91dCBTdXNwZW5zZSBzdWJ0cmVlIGFzIHBhcnQgb2YgdGhlIGJhc2UgZHVyYXRpb24uXG4gICAgICAgICAgICAgIHZhciBwcmltYXJ5Q2hpbGRGcmFnbWVudCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuXG4gICAgICAgICAgICAgIGlmIChwcmltYXJ5Q2hpbGRGcmFnbWVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWUgRmxvdyBkb2Vzbid0IHN1cHBvcnQgdHlwZSBjYXN0aW5nIGluIGNvbWJpbmF0aW9uIHdpdGggdGhlIC09IG9wZXJhdG9yXG4gICAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MudHJlZUJhc2VEdXJhdGlvbiAtPSBwcmltYXJ5Q2hpbGRGcmFnbWVudC50cmVlQmFzZUR1cmF0aW9uO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RQb3J0YWw6XG4gICAgICBwb3BIb3N0Q29udGFpbmVyKHdvcmtJblByb2dyZXNzKTtcbiAgICAgIHVwZGF0ZUhvc3RDb250YWluZXIoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuXG4gICAgICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgICAgICBwcmVwYXJlUG9ydGFsTW91bnQod29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlLmNvbnRhaW5lckluZm8pO1xuICAgICAgfVxuXG4gICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY2FzZSBDb250ZXh0UHJvdmlkZXI6XG4gICAgICAvLyBQb3AgcHJvdmlkZXIgZmliZXJcbiAgICAgIHZhciBjb250ZXh0ID0gd29ya0luUHJvZ3Jlc3MudHlwZS5fY29udGV4dDtcbiAgICAgIHBvcFByb3ZpZGVyKGNvbnRleHQsIHdvcmtJblByb2dyZXNzKTtcbiAgICAgIGJ1YmJsZVByb3BlcnRpZXMod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICBjYXNlIEluY29tcGxldGVDbGFzc0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgLy8gU2FtZSBhcyBjbGFzcyBjb21wb25lbnQgY2FzZS4gSSBwdXQgaXQgZG93biBoZXJlIHNvIHRoYXQgdGhlIHRhZ3MgYXJlXG4gICAgICAgIC8vIHNlcXVlbnRpYWwgdG8gZW5zdXJlIHRoaXMgc3dpdGNoIGlzIGNvbXBpbGVkIHRvIGEganVtcCB0YWJsZS5cbiAgICAgICAgdmFyIF9Db21wb25lbnQgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuXG4gICAgICAgIGlmIChpc0NvbnRleHRQcm92aWRlcihfQ29tcG9uZW50KSkge1xuICAgICAgICAgIHBvcENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBTdXNwZW5zZUxpc3RDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHBvcFN1c3BlbnNlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIHZhciByZW5kZXJTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG5cbiAgICAgICAgaWYgKHJlbmRlclN0YXRlID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gV2UncmUgcnVubmluZyBpbiB0aGUgZGVmYXVsdCwgXCJpbmRlcGVuZGVudFwiIG1vZGUuXG4gICAgICAgICAgLy8gV2UgZG9uJ3QgZG8gYW55dGhpbmcgaW4gdGhpcyBtb2RlLlxuICAgICAgICAgIGJ1YmJsZVByb3BlcnRpZXMod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGRpZFN1c3BlbmRBbHJlYWR5ID0gKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRGlkQ2FwdHVyZSkgIT09IE5vRmxhZ3M7XG4gICAgICAgIHZhciByZW5kZXJlZFRhaWwgPSByZW5kZXJTdGF0ZS5yZW5kZXJpbmc7XG5cbiAgICAgICAgaWYgKHJlbmRlcmVkVGFpbCA9PT0gbnVsbCkge1xuICAgICAgICAgIC8vIFdlIGp1c3QgcmVuZGVyZWQgdGhlIGhlYWQuXG4gICAgICAgICAgaWYgKCFkaWRTdXNwZW5kQWxyZWFkeSkge1xuICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgcGFzcy4gV2UgbmVlZCB0byBmaWd1cmUgb3V0IGlmIGFueXRoaW5nIGlzIHN0aWxsXG4gICAgICAgICAgICAvLyBzdXNwZW5kZWQgaW4gdGhlIHJlbmRlcmVkIHNldC5cbiAgICAgICAgICAgIC8vIElmIG5ldyBjb250ZW50IHVuc3VzcGVuZGVkLCBidXQgdGhlcmUncyBzdGlsbCBzb21lIGNvbnRlbnQgdGhhdFxuICAgICAgICAgICAgLy8gZGlkbid0LiBUaGVuIHdlIG5lZWQgdG8gZG8gYSBzZWNvbmQgcGFzcyB0aGF0IGZvcmNlcyBldmVyeXRoaW5nXG4gICAgICAgICAgICAvLyB0byBrZWVwIHNob3dpbmcgdGhlaXIgZmFsbGJhY2tzLlxuICAgICAgICAgICAgLy8gV2UgbWlnaHQgYmUgc3VzcGVuZGVkIGlmIHNvbWV0aGluZyBpbiB0aGlzIHJlbmRlciBwYXNzIHN1c3BlbmRlZCwgb3JcbiAgICAgICAgICAgIC8vIHNvbWV0aGluZyBpbiB0aGUgcHJldmlvdXMgY29tbWl0dGVkIHBhc3Mgc3VzcGVuZGVkLiBPdGhlcndpc2UsXG4gICAgICAgICAgICAvLyB0aGVyZSdzIG5vIGNoYW5jZSBzbyB3ZSBjYW4gc2tpcCB0aGUgZXhwZW5zaXZlIGNhbGwgdG9cbiAgICAgICAgICAgIC8vIGZpbmRGaXJzdFN1c3BlbmRlZC5cbiAgICAgICAgICAgIHZhciBjYW5ub3RCZVN1c3BlbmRlZCA9IHJlbmRlckhhc05vdFN1c3BlbmRlZFlldCgpICYmIChjdXJyZW50ID09PSBudWxsIHx8IChjdXJyZW50LmZsYWdzICYgRGlkQ2FwdHVyZSkgPT09IE5vRmxhZ3MpO1xuXG4gICAgICAgICAgICBpZiAoIWNhbm5vdEJlU3VzcGVuZGVkKSB7XG4gICAgICAgICAgICAgIHZhciByb3cgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcblxuICAgICAgICAgICAgICB3aGlsZSAocm93ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN1c3BlbmRlZCA9IGZpbmRGaXJzdFN1c3BlbmRlZChyb3cpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHN1c3BlbmRlZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgZGlkU3VzcGVuZEFscmVhZHkgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTtcbiAgICAgICAgICAgICAgICAgIGN1dE9mZlRhaWxJZk5lZWRlZChyZW5kZXJTdGF0ZSwgZmFsc2UpOyAvLyBJZiB0aGlzIGlzIGEgbmV3bHkgc3VzcGVuZGVkIHRyZWUsIGl0IG1pZ2h0IG5vdCBnZXQgY29tbWl0dGVkIGFzXG4gICAgICAgICAgICAgICAgICAvLyBwYXJ0IG9mIHRoZSBzZWNvbmQgcGFzcy4gSW4gdGhhdCBjYXNlIG5vdGhpbmcgd2lsbCBzdWJzY3JpYmUgdG9cbiAgICAgICAgICAgICAgICAgIC8vIGl0cyB0aGVuYWJsZXMuIEluc3RlYWQsIHdlJ2xsIHRyYW5zZmVyIGl0cyB0aGVuYWJsZXMgdG8gdGhlXG4gICAgICAgICAgICAgICAgICAvLyBTdXNwZW5zZUxpc3Qgc28gdGhhdCBpdCBjYW4gcmV0cnkgaWYgdGhleSByZXNvbHZlLlxuICAgICAgICAgICAgICAgICAgLy8gVGhlcmUgbWlnaHQgYmUgbXVsdGlwbGUgb2YgdGhlc2UgaW4gdGhlIGxpc3QgYnV0IHNpbmNlIHdlJ3JlXG4gICAgICAgICAgICAgICAgICAvLyBnb2luZyB0byB3YWl0IGZvciBhbGwgb2YgdGhlbSBhbnl3YXksIGl0IGRvZXNuJ3QgcmVhbGx5IG1hdHRlclxuICAgICAgICAgICAgICAgICAgLy8gd2hpY2ggb25lcyBnZXRzIHRvIHBpbmcuIEluIHRoZW9yeSB3ZSBjb3VsZCBnZXQgY2xldmVyIGFuZCBrZWVwXG4gICAgICAgICAgICAgICAgICAvLyB0cmFjayBvZiBob3cgbWFueSBkZXBlbmRlbmNpZXMgcmVtYWluIGJ1dCBpdCBnZXRzIHRyaWNreSBiZWNhdXNlXG4gICAgICAgICAgICAgICAgICAvLyBpbiB0aGUgbWVhbnRpbWUsIHdlIGNhbiBhZGQvcmVtb3ZlL2NoYW5nZSBpdGVtcyBhbmQgZGVwZW5kZW5jaWVzLlxuICAgICAgICAgICAgICAgICAgLy8gV2UgbWlnaHQgYmFpbCBvdXQgb2YgdGhlIGxvb3AgYmVmb3JlIGZpbmRpbmcgYW55IGJ1dCB0aGF0XG4gICAgICAgICAgICAgICAgICAvLyBkb2Vzbid0IG1hdHRlciBzaW5jZSB0aGF0IG1lYW5zIHRoYXQgdGhlIG90aGVyIGJvdW5kYXJpZXMgdGhhdFxuICAgICAgICAgICAgICAgICAgLy8gd2UgZGlkIGZpbmQgYWxyZWFkeSBoYXMgdGhlaXIgbGlzdGVuZXJzIGF0dGFjaGVkLlxuXG4gICAgICAgICAgICAgICAgICB2YXIgbmV3VGhlbmFibGVzID0gc3VzcGVuZGVkLnVwZGF0ZVF1ZXVlO1xuXG4gICAgICAgICAgICAgICAgICBpZiAobmV3VGhlbmFibGVzICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gbmV3VGhlbmFibGVzO1xuICAgICAgICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBVcGRhdGU7XG4gICAgICAgICAgICAgICAgICB9IC8vIFJlcmVuZGVyIHRoZSB3aG9sZSBsaXN0LCBidXQgdGhpcyB0aW1lLCB3ZSdsbCBmb3JjZSBmYWxsYmFja3NcbiAgICAgICAgICAgICAgICAgIC8vIHRvIHN0YXkgaW4gcGxhY2UuXG4gICAgICAgICAgICAgICAgICAvLyBSZXNldCB0aGUgZWZmZWN0IGZsYWdzIGJlZm9yZSBkb2luZyB0aGUgc2Vjb25kIHBhc3Mgc2luY2UgdGhhdCdzIG5vdyBpbnZhbGlkLlxuICAgICAgICAgICAgICAgICAgLy8gUmVzZXQgdGhlIGNoaWxkIGZpYmVycyB0byB0aGVpciBvcmlnaW5hbCBzdGF0ZS5cblxuXG4gICAgICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5zdWJ0cmVlRmxhZ3MgPSBOb0ZsYWdzO1xuICAgICAgICAgICAgICAgICAgcmVzZXRDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpOyAvLyBTZXQgdXAgdGhlIFN1c3BlbnNlIENvbnRleHQgdG8gZm9yY2Ugc3VzcGVuc2UgYW5kIGltbWVkaWF0ZWx5XG4gICAgICAgICAgICAgICAgICAvLyByZXJlbmRlciB0aGUgY2hpbGRyZW4uXG5cbiAgICAgICAgICAgICAgICAgIHB1c2hTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MsIHNldFNoYWxsb3dTdXNwZW5zZUNvbnRleHQoc3VzcGVuc2VTdGFja0N1cnNvci5jdXJyZW50LCBGb3JjZVN1c3BlbnNlRmFsbGJhY2spKTsgLy8gRG9uJ3QgYnViYmxlIHByb3BlcnRpZXMgaW4gdGhpcyBjYXNlLlxuXG4gICAgICAgICAgICAgICAgICByZXR1cm4gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcm93ID0gcm93LnNpYmxpbmc7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlbmRlclN0YXRlLnRhaWwgIT09IG51bGwgJiYgbm93KCkgPiBnZXRSZW5kZXJUYXJnZXRUaW1lKCkpIHtcbiAgICAgICAgICAgICAgLy8gV2UgaGF2ZSBhbHJlYWR5IHBhc3NlZCBvdXIgQ1BVIGRlYWRsaW5lIGJ1dCB3ZSBzdGlsbCBoYXZlIHJvd3NcbiAgICAgICAgICAgICAgLy8gbGVmdCBpbiB0aGUgdGFpbC4gV2UnbGwganVzdCBnaXZlIHVwIGZ1cnRoZXIgYXR0ZW1wdHMgdG8gcmVuZGVyXG4gICAgICAgICAgICAgIC8vIHRoZSBtYWluIGNvbnRlbnQgYW5kIG9ubHkgcmVuZGVyIGZhbGxiYWNrcy5cbiAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTtcbiAgICAgICAgICAgICAgZGlkU3VzcGVuZEFscmVhZHkgPSB0cnVlO1xuICAgICAgICAgICAgICBjdXRPZmZUYWlsSWZOZWVkZWQocmVuZGVyU3RhdGUsIGZhbHNlKTsgLy8gU2luY2Ugbm90aGluZyBhY3R1YWxseSBzdXNwZW5kZWQsIHRoZXJlIHdpbGwgbm90aGluZyB0byBwaW5nIHRoaXNcbiAgICAgICAgICAgICAgLy8gdG8gZ2V0IGl0IHN0YXJ0ZWQgYmFjayB1cCB0byBhdHRlbXB0IHRoZSBuZXh0IGl0ZW0uIFdoaWxlIGluIHRlcm1zXG4gICAgICAgICAgICAgIC8vIG9mIHByaW9yaXR5IHRoaXMgd29yayBoYXMgdGhlIHNhbWUgcHJpb3JpdHkgYXMgdGhpcyBjdXJyZW50IHJlbmRlcixcbiAgICAgICAgICAgICAgLy8gaXQncyBub3QgcGFydCBvZiB0aGUgc2FtZSB0cmFuc2l0aW9uIG9uY2UgdGhlIHRyYW5zaXRpb24gaGFzXG4gICAgICAgICAgICAgIC8vIGNvbW1pdHRlZC4gSWYgaXQncyBzeW5jLCB3ZSBzdGlsbCB3YW50IHRvIHlpZWxkIHNvIHRoYXQgaXQgY2FuIGJlXG4gICAgICAgICAgICAgIC8vIHBhaW50ZWQuIENvbmNlcHR1YWxseSwgdGhpcyBpcyByZWFsbHkgdGhlIHNhbWUgYXMgcGluZ2luZy5cbiAgICAgICAgICAgICAgLy8gV2UgY2FuIHVzZSBhbnkgUmV0cnlMYW5lIGV2ZW4gaWYgaXQncyB0aGUgb25lIGN1cnJlbnRseSByZW5kZXJpbmdcbiAgICAgICAgICAgICAgLy8gc2luY2Ugd2UncmUgbGVhdmluZyBpdCBiZWhpbmQgb24gdGhpcyBub2RlLlxuXG4gICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gU29tZVJldHJ5TGFuZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3V0T2ZmVGFpbElmTmVlZGVkKHJlbmRlclN0YXRlLCBmYWxzZSk7XG4gICAgICAgICAgfSAvLyBOZXh0IHdlJ3JlIGdvaW5nIHRvIHJlbmRlciB0aGUgdGFpbC5cblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEFwcGVuZCB0aGUgcmVuZGVyZWQgcm93IHRvIHRoZSBjaGlsZCBsaXN0LlxuICAgICAgICAgIGlmICghZGlkU3VzcGVuZEFscmVhZHkpIHtcbiAgICAgICAgICAgIHZhciBfc3VzcGVuZGVkID0gZmluZEZpcnN0U3VzcGVuZGVkKHJlbmRlcmVkVGFpbCk7XG5cbiAgICAgICAgICAgIGlmIChfc3VzcGVuZGVkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IERpZENhcHR1cmU7XG4gICAgICAgICAgICAgIGRpZFN1c3BlbmRBbHJlYWR5ID0gdHJ1ZTsgLy8gRW5zdXJlIHdlIHRyYW5zZmVyIHRoZSB1cGRhdGUgcXVldWUgdG8gdGhlIHBhcmVudCBzbyB0aGF0IGl0IGRvZXNuJ3RcbiAgICAgICAgICAgICAgLy8gZ2V0IGxvc3QgaWYgdGhpcyByb3cgZW5kcyB1cCBkcm9wcGVkIGR1cmluZyBhIHNlY29uZCBwYXNzLlxuXG4gICAgICAgICAgICAgIHZhciBfbmV3VGhlbmFibGVzID0gX3N1c3BlbmRlZC51cGRhdGVRdWV1ZTtcblxuICAgICAgICAgICAgICBpZiAoX25ld1RoZW5hYmxlcyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gX25ld1RoZW5hYmxlcztcbiAgICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBVcGRhdGU7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBjdXRPZmZUYWlsSWZOZWVkZWQocmVuZGVyU3RhdGUsIHRydWUpOyAvLyBUaGlzIG1pZ2h0IGhhdmUgYmVlbiBtb2RpZmllZC5cblxuICAgICAgICAgICAgICBpZiAocmVuZGVyU3RhdGUudGFpbCA9PT0gbnVsbCAmJiByZW5kZXJTdGF0ZS50YWlsTW9kZSA9PT0gJ2hpZGRlbicgJiYgIXJlbmRlcmVkVGFpbC5hbHRlcm5hdGUgJiYgIWdldElzSHlkcmF0aW5nKCkgLy8gV2UgZG9uJ3QgY3V0IGl0IGlmIHdlJ3JlIGh5ZHJhdGluZy5cbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAvLyBXZSdyZSBkb25lLlxuICAgICAgICAgICAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCAvLyBUaGUgdGltZSBpdCB0b29rIHRvIHJlbmRlciBsYXN0IHJvdyBpcyBncmVhdGVyIHRoYW4gdGhlIHJlbWFpbmluZ1xuICAgICAgICAgICAgLy8gdGltZSB3ZSBoYXZlIHRvIHJlbmRlci4gU28gcmVuZGVyaW5nIG9uZSBtb3JlIHJvdyB3b3VsZCBsaWtlbHlcbiAgICAgICAgICAgIC8vIGV4Y2VlZCBpdC5cbiAgICAgICAgICAgIG5vdygpICogMiAtIHJlbmRlclN0YXRlLnJlbmRlcmluZ1N0YXJ0VGltZSA+IGdldFJlbmRlclRhcmdldFRpbWUoKSAmJiByZW5kZXJMYW5lcyAhPT0gT2Zmc2NyZWVuTGFuZSkge1xuICAgICAgICAgICAgICAvLyBXZSBoYXZlIG5vdyBwYXNzZWQgb3VyIENQVSBkZWFkbGluZSBhbmQgd2UnbGwganVzdCBnaXZlIHVwIGZ1cnRoZXJcbiAgICAgICAgICAgICAgLy8gYXR0ZW1wdHMgdG8gcmVuZGVyIHRoZSBtYWluIGNvbnRlbnQgYW5kIG9ubHkgcmVuZGVyIGZhbGxiYWNrcy5cbiAgICAgICAgICAgICAgLy8gVGhlIGFzc3VtcHRpb24gaXMgdGhhdCB0aGlzIGlzIHVzdWFsbHkgZmFzdGVyLlxuICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBEaWRDYXB0dXJlO1xuICAgICAgICAgICAgICBkaWRTdXNwZW5kQWxyZWFkeSA9IHRydWU7XG4gICAgICAgICAgICAgIGN1dE9mZlRhaWxJZk5lZWRlZChyZW5kZXJTdGF0ZSwgZmFsc2UpOyAvLyBTaW5jZSBub3RoaW5nIGFjdHVhbGx5IHN1c3BlbmRlZCwgdGhlcmUgd2lsbCBub3RoaW5nIHRvIHBpbmcgdGhpc1xuICAgICAgICAgICAgICAvLyB0byBnZXQgaXQgc3RhcnRlZCBiYWNrIHVwIHRvIGF0dGVtcHQgdGhlIG5leHQgaXRlbS4gV2hpbGUgaW4gdGVybXNcbiAgICAgICAgICAgICAgLy8gb2YgcHJpb3JpdHkgdGhpcyB3b3JrIGhhcyB0aGUgc2FtZSBwcmlvcml0eSBhcyB0aGlzIGN1cnJlbnQgcmVuZGVyLFxuICAgICAgICAgICAgICAvLyBpdCdzIG5vdCBwYXJ0IG9mIHRoZSBzYW1lIHRyYW5zaXRpb24gb25jZSB0aGUgdHJhbnNpdGlvbiBoYXNcbiAgICAgICAgICAgICAgLy8gY29tbWl0dGVkLiBJZiBpdCdzIHN5bmMsIHdlIHN0aWxsIHdhbnQgdG8geWllbGQgc28gdGhhdCBpdCBjYW4gYmVcbiAgICAgICAgICAgICAgLy8gcGFpbnRlZC4gQ29uY2VwdHVhbGx5LCB0aGlzIGlzIHJlYWxseSB0aGUgc2FtZSBhcyBwaW5naW5nLlxuICAgICAgICAgICAgICAvLyBXZSBjYW4gdXNlIGFueSBSZXRyeUxhbmUgZXZlbiBpZiBpdCdzIHRoZSBvbmUgY3VycmVudGx5IHJlbmRlcmluZ1xuICAgICAgICAgICAgICAvLyBzaW5jZSB3ZSdyZSBsZWF2aW5nIGl0IGJlaGluZCBvbiB0aGlzIG5vZGUuXG5cbiAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBTb21lUmV0cnlMYW5lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChyZW5kZXJTdGF0ZS5pc0JhY2t3YXJkcykge1xuICAgICAgICAgICAgLy8gVGhlIGVmZmVjdCBsaXN0IG9mIHRoZSBiYWNrd2FyZHMgdGFpbCB3aWxsIGhhdmUgYmVlbiBhZGRlZFxuICAgICAgICAgICAgLy8gdG8gdGhlIGVuZC4gVGhpcyBicmVha3MgdGhlIGd1YXJhbnRlZSB0aGF0IGxpZmUtY3ljbGVzIGZpcmUgaW5cbiAgICAgICAgICAgIC8vIHNpYmxpbmcgb3JkZXIgYnV0IHRoYXQgaXNuJ3QgYSBzdHJvbmcgZ3VhcmFudGVlIHByb21pc2VkIGJ5IFJlYWN0LlxuICAgICAgICAgICAgLy8gRXNwZWNpYWxseSBzaW5jZSB0aGVzZSBtaWdodCBhbHNvIGp1c3QgcG9wIGluIGR1cmluZyBmdXR1cmUgY29tbWl0cy5cbiAgICAgICAgICAgIC8vIEFwcGVuZCB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0LlxuICAgICAgICAgICAgcmVuZGVyZWRUYWlsLnNpYmxpbmcgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcmVuZGVyZWRUYWlsO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgcHJldmlvdXNTaWJsaW5nID0gcmVuZGVyU3RhdGUubGFzdDtcblxuICAgICAgICAgICAgaWYgKHByZXZpb3VzU2libGluZyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICBwcmV2aW91c1NpYmxpbmcuc2libGluZyA9IHJlbmRlcmVkVGFpbDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcmVuZGVyZWRUYWlsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZW5kZXJTdGF0ZS5sYXN0ID0gcmVuZGVyZWRUYWlsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyZW5kZXJTdGF0ZS50YWlsICE9PSBudWxsKSB7XG4gICAgICAgICAgLy8gV2Ugc3RpbGwgaGF2ZSB0YWlsIHJvd3MgdG8gcmVuZGVyLlxuICAgICAgICAgIC8vIFBvcCBhIHJvdy5cbiAgICAgICAgICB2YXIgbmV4dCA9IHJlbmRlclN0YXRlLnRhaWw7XG4gICAgICAgICAgcmVuZGVyU3RhdGUucmVuZGVyaW5nID0gbmV4dDtcbiAgICAgICAgICByZW5kZXJTdGF0ZS50YWlsID0gbmV4dC5zaWJsaW5nO1xuICAgICAgICAgIHJlbmRlclN0YXRlLnJlbmRlcmluZ1N0YXJ0VGltZSA9IG5vdygpO1xuICAgICAgICAgIG5leHQuc2libGluZyA9IG51bGw7IC8vIFJlc3RvcmUgdGhlIGNvbnRleHQuXG4gICAgICAgICAgLy8gVE9ETzogV2UgY2FuIHByb2JhYmx5IGp1c3QgYXZvaWQgcG9wcGluZyBpdCBpbnN0ZWFkIGFuZCBvbmx5XG4gICAgICAgICAgLy8gc2V0dGluZyBpdCB0aGUgZmlyc3QgdGltZSB3ZSBnbyBmcm9tIG5vdCBzdXNwZW5kZWQgdG8gc3VzcGVuZGVkLlxuXG4gICAgICAgICAgdmFyIHN1c3BlbnNlQ29udGV4dCA9IHN1c3BlbnNlU3RhY2tDdXJzb3IuY3VycmVudDtcblxuICAgICAgICAgIGlmIChkaWRTdXNwZW5kQWxyZWFkeSkge1xuICAgICAgICAgICAgc3VzcGVuc2VDb250ZXh0ID0gc2V0U2hhbGxvd1N1c3BlbnNlQ29udGV4dChzdXNwZW5zZUNvbnRleHQsIEZvcmNlU3VzcGVuc2VGYWxsYmFjayk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN1c3BlbnNlQ29udGV4dCA9IHNldERlZmF1bHRTaGFsbG93U3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlQ29udGV4dCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcHVzaFN1c3BlbnNlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgc3VzcGVuc2VDb250ZXh0KTsgLy8gRG8gYSBwYXNzIG92ZXIgdGhlIG5leHQgcm93LlxuICAgICAgICAgIC8vIERvbid0IGJ1YmJsZSBwcm9wZXJ0aWVzIGluIHRoaXMgY2FzZS5cblxuICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICB9XG5cbiAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBTY29wZUNvbXBvbmVudDpcbiAgICAgIHtcblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgT2Zmc2NyZWVuQ29tcG9uZW50OlxuICAgIGNhc2UgTGVnYWN5SGlkZGVuQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBwb3BSZW5kZXJMYW5lcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIHZhciBfbmV4dFN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgICAgICAgdmFyIG5leHRJc0hpZGRlbiA9IF9uZXh0U3RhdGUgIT09IG51bGw7XG5cbiAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICB2YXIgX3ByZXZTdGF0ZSA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcbiAgICAgICAgICB2YXIgcHJldklzSGlkZGVuID0gX3ByZXZTdGF0ZSAhPT0gbnVsbDtcblxuICAgICAgICAgIGlmIChwcmV2SXNIaWRkZW4gIT09IG5leHRJc0hpZGRlbiAmJiAoIC8vIExlZ2FjeUhpZGRlbiBkb2Vzbid0IGRvIGFueSBoaWRpbmcg4oCUIGl0IG9ubHkgcHJlLXJlbmRlcnMuXG4gICAgICAgICAgIWVuYWJsZUxlZ2FjeUhpZGRlbiApKSB7XG4gICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBWaXNpYmlsaXR5O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghbmV4dElzSGlkZGVuIHx8ICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUpIHtcbiAgICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBEb24ndCBidWJibGUgcHJvcGVydGllcyBmb3IgaGlkZGVuIGNoaWxkcmVuIHVubGVzcyB3ZSdyZSByZW5kZXJpbmdcbiAgICAgICAgICAvLyBhdCBvZmZzY3JlZW4gcHJpb3JpdHkuXG4gICAgICAgICAgaWYgKGluY2x1ZGVzU29tZUxhbmUoc3VidHJlZVJlbmRlckxhbmVzLCBPZmZzY3JlZW5MYW5lKSkge1xuICAgICAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlcmUgd2FzIGFuIGluc2VydGlvbiBvciB1cGRhdGUgaW4gdGhlIGhpZGRlbiBzdWJ0cmVlLlxuICAgICAgICAgICAgICAvLyBJZiBzbywgd2UgbmVlZCB0byBoaWRlIHRob3NlIG5vZGVzIGluIHRoZSBjb21taXQgcGhhc2UsIHNvXG4gICAgICAgICAgICAgIC8vIHNjaGVkdWxlIGEgdmlzaWJpbGl0eSBlZmZlY3QuXG4gICAgICAgICAgICAgIGlmICggd29ya0luUHJvZ3Jlc3Muc3VidHJlZUZsYWdzICYgKFBsYWNlbWVudCB8IFVwZGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBWaXNpYmlsaXR5O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBDYWNoZUNvbXBvbmVudDpcbiAgICAgIHtcblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgVHJhY2luZ01hcmtlckNvbXBvbmVudDpcbiAgICAgIHtcblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gdW5pdCBvZiB3b3JrIHRhZyAoXCIgKyB3b3JrSW5Qcm9ncmVzcy50YWcgKyBcIikuIFRoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBcIiArICdSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG59XG5cbmZ1bmN0aW9uIHVud2luZFdvcmsoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIC8vIE5vdGU6IFRoaXMgaW50ZW50aW9uYWxseSBkb2Vzbid0IGNoZWNrIGlmIHdlJ3JlIGh5ZHJhdGluZyBiZWNhdXNlIGNvbXBhcmluZ1xuICAvLyB0byB0aGUgY3VycmVudCB0cmVlIHByb3ZpZGVyIGZpYmVyIGlzIGp1c3QgYXMgZmFzdCBhbmQgbGVzcyBlcnJvci1wcm9uZS5cbiAgLy8gSWRlYWxseSB3ZSB3b3VsZCBoYXZlIGEgc3BlY2lhbCB2ZXJzaW9uIG9mIHRoZSB3b3JrIGxvb3Agb25seVxuICAvLyBmb3IgaHlkcmF0aW9uLlxuICBwb3BUcmVlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgc3dpdGNoICh3b3JrSW5Qcm9ncmVzcy50YWcpIHtcbiAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICB2YXIgQ29tcG9uZW50ID0gd29ya0luUHJvZ3Jlc3MudHlwZTtcblxuICAgICAgICBpZiAoaXNDb250ZXh0UHJvdmlkZXIoQ29tcG9uZW50KSkge1xuICAgICAgICAgIHBvcENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGZsYWdzID0gd29ya0luUHJvZ3Jlc3MuZmxhZ3M7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgU2hvdWxkQ2FwdHVyZSkge1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzID0gZmxhZ3MgJiB+U2hvdWxkQ2FwdHVyZSB8IERpZENhcHR1cmU7XG5cbiAgICAgICAgICBpZiAoICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgICAgIHRyYW5zZmVyQWN0dWFsRHVyYXRpb24od29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgIHtcbiAgICAgICAgdmFyIHJvb3QgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG4gICAgICAgIHBvcEhvc3RDb250YWluZXIod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICBwb3BUb3BMZXZlbENvbnRleHRPYmplY3Qod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICByZXNldFdvcmtJblByb2dyZXNzVmVyc2lvbnMoKTtcbiAgICAgICAgdmFyIF9mbGFncyA9IHdvcmtJblByb2dyZXNzLmZsYWdzO1xuXG4gICAgICAgIGlmICgoX2ZsYWdzICYgU2hvdWxkQ2FwdHVyZSkgIT09IE5vRmxhZ3MgJiYgKF9mbGFncyAmIERpZENhcHR1cmUpID09PSBOb0ZsYWdzKSB7XG4gICAgICAgICAgLy8gVGhlcmUgd2FzIGFuIGVycm9yIGR1cmluZyByZW5kZXIgdGhhdCB3YXNuJ3QgY2FwdHVyZWQgYnkgYSBzdXNwZW5zZVxuICAgICAgICAgIC8vIGJvdW5kYXJ5LiBEbyBhIHNlY29uZCBwYXNzIG9uIHRoZSByb290IHRvIHVubW91bnQgdGhlIGNoaWxkcmVuLlxuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzID0gX2ZsYWdzICYgflNob3VsZENhcHR1cmUgfCBEaWRDYXB0dXJlO1xuICAgICAgICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbiAgICAgICAgfSAvLyBXZSB1bndvdW5kIHRvIHRoZSByb290IHdpdGhvdXQgY29tcGxldGluZyBpdC4gRXhpdC5cblxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAge1xuICAgICAgICAvLyBUT0RPOiBwb3BIeWRyYXRpb25TdGF0ZVxuICAgICAgICBwb3BIb3N0Q29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBTdXNwZW5zZUNvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcG9wU3VzcGVuc2VDb250ZXh0KHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgdmFyIHN1c3BlbnNlU3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gICAgICAgIGlmIChzdXNwZW5zZVN0YXRlICE9PSBudWxsICYmIHN1c3BlbnNlU3RhdGUuZGVoeWRyYXRlZCAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmICh3b3JrSW5Qcm9ncmVzcy5hbHRlcm5hdGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhyZXcgaW4gbmV3bHkgbW91bnRlZCBkZWh5ZHJhdGVkIGNvbXBvbmVudC4gVGhpcyBpcyBsaWtlbHkgYSBidWcgaW4gJyArICdSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmVzZXRIeWRyYXRpb25TdGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIF9mbGFnczIgPSB3b3JrSW5Qcm9ncmVzcy5mbGFncztcblxuICAgICAgICBpZiAoX2ZsYWdzMiAmIFNob3VsZENhcHR1cmUpIHtcbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyA9IF9mbGFnczIgJiB+U2hvdWxkQ2FwdHVyZSB8IERpZENhcHR1cmU7IC8vIENhcHR1cmVkIGEgc3VzcGVuc2UgZWZmZWN0LiBSZS1yZW5kZXIgdGhlIGJvdW5kYXJ5LlxuXG4gICAgICAgICAgaWYgKCAod29ya0luUHJvZ3Jlc3MubW9kZSAmIFByb2ZpbGVNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICAgICAgICB0cmFuc2ZlckFjdHVhbER1cmF0aW9uKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gd29ya0luUHJvZ3Jlc3M7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgU3VzcGVuc2VMaXN0Q29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBwb3BTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MpOyAvLyBTdXNwZW5zZUxpc3QgZG9lc24ndCBhY3R1YWxseSBjYXRjaCBhbnl0aGluZy4gSXQgc2hvdWxkJ3ZlIGJlZW5cbiAgICAgICAgLy8gY2F1Z2h0IGJ5IGEgbmVzdGVkIGJvdW5kYXJ5LiBJZiBub3QsIGl0IHNob3VsZCBidWJibGUgdGhyb3VnaC5cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgIHBvcEhvc3RDb250YWluZXIod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICBjYXNlIENvbnRleHRQcm92aWRlcjpcbiAgICAgIHZhciBjb250ZXh0ID0gd29ya0luUHJvZ3Jlc3MudHlwZS5fY29udGV4dDtcbiAgICAgIHBvcFByb3ZpZGVyKGNvbnRleHQsIHdvcmtJblByb2dyZXNzKTtcbiAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgY2FzZSBMZWdhY3lIaWRkZW5Db21wb25lbnQ6XG4gICAgICBwb3BSZW5kZXJMYW5lcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICByZXR1cm4gbnVsbDtcblxuICAgIGNhc2UgQ2FjaGVDb21wb25lbnQ6XG5cbiAgICAgIHJldHVybiBudWxsO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVud2luZEludGVycnVwdGVkV29yayhjdXJyZW50LCBpbnRlcnJ1cHRlZFdvcmssIHJlbmRlckxhbmVzKSB7XG4gIC8vIE5vdGU6IFRoaXMgaW50ZW50aW9uYWxseSBkb2Vzbid0IGNoZWNrIGlmIHdlJ3JlIGh5ZHJhdGluZyBiZWNhdXNlIGNvbXBhcmluZ1xuICAvLyB0byB0aGUgY3VycmVudCB0cmVlIHByb3ZpZGVyIGZpYmVyIGlzIGp1c3QgYXMgZmFzdCBhbmQgbGVzcyBlcnJvci1wcm9uZS5cbiAgLy8gSWRlYWxseSB3ZSB3b3VsZCBoYXZlIGEgc3BlY2lhbCB2ZXJzaW9uIG9mIHRoZSB3b3JrIGxvb3Agb25seVxuICAvLyBmb3IgaHlkcmF0aW9uLlxuICBwb3BUcmVlQ29udGV4dChpbnRlcnJ1cHRlZFdvcmspO1xuXG4gIHN3aXRjaCAoaW50ZXJydXB0ZWRXb3JrLnRhZykge1xuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBjaGlsZENvbnRleHRUeXBlcyA9IGludGVycnVwdGVkV29yay50eXBlLmNoaWxkQ29udGV4dFR5cGVzO1xuXG4gICAgICAgIGlmIChjaGlsZENvbnRleHRUeXBlcyAhPT0gbnVsbCAmJiBjaGlsZENvbnRleHRUeXBlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcG9wQ29udGV4dChpbnRlcnJ1cHRlZFdvcmspO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RSb290OlxuICAgICAge1xuICAgICAgICB2YXIgcm9vdCA9IGludGVycnVwdGVkV29yay5zdGF0ZU5vZGU7XG4gICAgICAgIHBvcEhvc3RDb250YWluZXIoaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgICAgcG9wVG9wTGV2ZWxDb250ZXh0T2JqZWN0KGludGVycnVwdGVkV29yayk7XG4gICAgICAgIHJlc2V0V29ya0luUHJvZ3Jlc3NWZXJzaW9ucygpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcG9wSG9zdENvbnRleHQoaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RQb3J0YWw6XG4gICAgICBwb3BIb3N0Q29udGFpbmVyKGludGVycnVwdGVkV29yayk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICBwb3BTdXNwZW5zZUNvbnRleHQoaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBTdXNwZW5zZUxpc3RDb21wb25lbnQ6XG4gICAgICBwb3BTdXNwZW5zZUNvbnRleHQoaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBDb250ZXh0UHJvdmlkZXI6XG4gICAgICB2YXIgY29udGV4dCA9IGludGVycnVwdGVkV29yay50eXBlLl9jb250ZXh0O1xuICAgICAgcG9wUHJvdmlkZXIoY29udGV4dCwgaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgY2FzZSBMZWdhY3lIaWRkZW5Db21wb25lbnQ6XG4gICAgICBwb3BSZW5kZXJMYW5lcyhpbnRlcnJ1cHRlZFdvcmspO1xuICAgICAgYnJlYWs7XG4gIH1cbn1cblxudmFyIGRpZFdhcm5BYm91dFVuZGVmaW5lZFNuYXBzaG90QmVmb3JlVXBkYXRlID0gbnVsbDtcblxue1xuICBkaWRXYXJuQWJvdXRVbmRlZmluZWRTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9IG5ldyBTZXQoKTtcbn0gLy8gVXNlZCBkdXJpbmcgdGhlIGNvbW1pdCBwaGFzZSB0byB0cmFjayB0aGUgc3RhdGUgb2YgdGhlIE9mZnNjcmVlbiBjb21wb25lbnQgc3RhY2suXG4vLyBBbGxvd3MgdXMgdG8gYXZvaWQgdHJhdmVyc2luZyB0aGUgcmV0dXJuIHBhdGggdG8gZmluZCB0aGUgbmVhcmVzdCBPZmZzY3JlZW4gYW5jZXN0b3IuXG4vLyBPbmx5IHVzZWQgd2hlbiBlbmFibGVTdXNwZW5zZUxheW91dEVmZmVjdFNlbWFudGljcyBpcyBlbmFibGVkLlxuXG5cbnZhciBvZmZzY3JlZW5TdWJ0cmVlSXNIaWRkZW4gPSBmYWxzZTtcbnZhciBvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuID0gZmFsc2U7XG52YXIgUG9zc2libHlXZWFrU2V0ID0gdHlwZW9mIFdlYWtTZXQgPT09ICdmdW5jdGlvbicgPyBXZWFrU2V0IDogU2V0O1xudmFyIG5leHRFZmZlY3QgPSBudWxsOyAvLyBVc2VkIGZvciBQcm9maWxpbmcgYnVpbGRzIHRvIHRyYWNrIHVwZGF0ZXJzLlxuXG52YXIgaW5Qcm9ncmVzc0xhbmVzID0gbnVsbDtcbnZhciBpblByb2dyZXNzUm9vdCA9IG51bGw7XG5mdW5jdGlvbiByZXBvcnRVbmNhdWdodEVycm9ySW5ERVYoZXJyb3IpIHtcbiAgLy8gV3JhcHBpbmcgZWFjaCBzbWFsbCBwYXJ0IG9mIHRoZSBjb21taXQgcGhhc2UgaW50byBhIGd1YXJkZWRcbiAgLy8gY2FsbGJhY2sgaXMgYSBiaXQgdG9vIHNsb3cgKGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzIxNjY2KS5cbiAgLy8gQnV0IHdlIHJlbHkgb24gaXQgdG8gc3VyZmFjZSBlcnJvcnMgdG8gREVWIHRvb2xzIGxpa2Ugb3ZlcmxheXNcbiAgLy8gKGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMjE3MTIpLlxuICAvLyBBcyBhIGNvbXByb21pc2UsIHJldGhyb3cgb25seSBjYXVnaHQgZXJyb3JzIGluIGEgZ3VhcmQuXG4gIHtcbiAgICBpbnZva2VHdWFyZGVkQ2FsbGJhY2sobnVsbCwgZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSk7XG4gICAgY2xlYXJDYXVnaHRFcnJvcigpO1xuICB9XG59XG5cbnZhciBjYWxsQ29tcG9uZW50V2lsbFVubW91bnRXaXRoVGltZXIgPSBmdW5jdGlvbiAoY3VycmVudCwgaW5zdGFuY2UpIHtcbiAgaW5zdGFuY2UucHJvcHMgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7XG4gIGluc3RhbmNlLnN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuXG4gIGlmICggY3VycmVudC5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICB0cnkge1xuICAgICAgc3RhcnRMYXlvdXRFZmZlY3RUaW1lcigpO1xuICAgICAgaW5zdGFuY2UuY29tcG9uZW50V2lsbFVubW91bnQoKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgcmVjb3JkTGF5b3V0RWZmZWN0RHVyYXRpb24oY3VycmVudCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVbm1vdW50KCk7XG4gIH1cbn07IC8vIENhcHR1cmUgZXJyb3JzIHNvIHRoZXkgZG9uJ3QgaW50ZXJydXB0IG1vdW50aW5nLlxuXG5cbmZ1bmN0aW9uIHNhZmVseUNhbGxDb21taXRIb29rTGF5b3V0RWZmZWN0TGlzdE1vdW50KGN1cnJlbnQsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IpIHtcbiAgdHJ5IHtcbiAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KExheW91dCwgY3VycmVudCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZXJyb3IpO1xuICB9XG59IC8vIENhcHR1cmUgZXJyb3JzIHNvIHRoZXkgZG9uJ3QgaW50ZXJydXB0IHVubW91bnRpbmcuXG5cblxuZnVuY3Rpb24gc2FmZWx5Q2FsbENvbXBvbmVudFdpbGxVbm1vdW50KGN1cnJlbnQsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGluc3RhbmNlKSB7XG4gIHRyeSB7XG4gICAgY2FsbENvbXBvbmVudFdpbGxVbm1vdW50V2l0aFRpbWVyKGN1cnJlbnQsIGluc3RhbmNlKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvcik7XG4gIH1cbn0gLy8gQ2FwdHVyZSBlcnJvcnMgc28gdGhleSBkb24ndCBpbnRlcnJ1cHQgbW91bnRpbmcuXG5cblxuZnVuY3Rpb24gc2FmZWx5Q2FsbENvbXBvbmVudERpZE1vdW50KGN1cnJlbnQsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGluc3RhbmNlKSB7XG4gIHRyeSB7XG4gICAgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQoKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvcik7XG4gIH1cbn0gLy8gQ2FwdHVyZSBlcnJvcnMgc28gdGhleSBkb24ndCBpbnRlcnJ1cHQgbW91bnRpbmcuXG5cblxuZnVuY3Rpb24gc2FmZWx5QXR0YWNoUmVmKGN1cnJlbnQsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IpIHtcbiAgdHJ5IHtcbiAgICBjb21taXRBdHRhY2hSZWYoY3VycmVudCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZXJyb3IpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNhZmVseURldGFjaFJlZihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yKSB7XG4gIHZhciByZWYgPSBjdXJyZW50LnJlZjtcblxuICBpZiAocmVmICE9PSBudWxsKSB7XG4gICAgaWYgKHR5cGVvZiByZWYgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciByZXRWYWw7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGlmIChlbmFibGVQcm9maWxlclRpbWVyICYmIGVuYWJsZVByb2ZpbGVyQ29tbWl0SG9va3MgJiYgY3VycmVudC5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgc3RhcnRMYXlvdXRFZmZlY3RUaW1lcigpO1xuICAgICAgICAgICAgcmV0VmFsID0gcmVmKG51bGwpO1xuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICByZWNvcmRMYXlvdXRFZmZlY3REdXJhdGlvbihjdXJyZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0VmFsID0gcmVmKG51bGwpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvcik7XG4gICAgICB9XG5cbiAgICAgIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXRWYWwgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBlcnJvcignVW5leHBlY3RlZCByZXR1cm4gdmFsdWUgZnJvbSBhIGNhbGxiYWNrIHJlZiBpbiAlcy4gJyArICdBIGNhbGxiYWNrIHJlZiBzaG91bGQgbm90IHJldHVybiBhIGZ1bmN0aW9uLicsIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoY3VycmVudCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gc2FmZWx5Q2FsbERlc3Ryb3koY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVzdHJveSkge1xuICB0cnkge1xuICAgIGRlc3Ryb3koKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvcik7XG4gIH1cbn1cblxudmFyIGZvY3VzZWRJbnN0YW5jZUhhbmRsZSA9IG51bGw7XG52YXIgc2hvdWxkRmlyZUFmdGVyQWN0aXZlSW5zdGFuY2VCbHVyID0gZmFsc2U7XG5mdW5jdGlvbiBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmlyc3RDaGlsZCkge1xuICBmb2N1c2VkSW5zdGFuY2VIYW5kbGUgPSBwcmVwYXJlRm9yQ29tbWl0KHJvb3QuY29udGFpbmVySW5mbyk7XG4gIG5leHRFZmZlY3QgPSBmaXJzdENoaWxkO1xuICBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHNfYmVnaW4oKTsgLy8gV2Ugbm8gbG9uZ2VyIG5lZWQgdG8gdHJhY2sgdGhlIGFjdGl2ZSBpbnN0YW5jZSBmaWJlclxuXG4gIHZhciBzaG91bGRGaXJlID0gc2hvdWxkRmlyZUFmdGVyQWN0aXZlSW5zdGFuY2VCbHVyO1xuICBzaG91bGRGaXJlQWZ0ZXJBY3RpdmVJbnN0YW5jZUJsdXIgPSBmYWxzZTtcbiAgZm9jdXNlZEluc3RhbmNlSGFuZGxlID0gbnVsbDtcbiAgcmV0dXJuIHNob3VsZEZpcmU7XG59XG5cbmZ1bmN0aW9uIGNvbW1pdEJlZm9yZU11dGF0aW9uRWZmZWN0c19iZWdpbigpIHtcbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0OyAvLyBUaGlzIHBoYXNlIGlzIG9ubHkgdXNlZCBmb3IgYmVmb3JlQWN0aXZlSW5zdGFuY2VCbHVyLlxuXG4gICAgdmFyIGNoaWxkID0gZmliZXIuY2hpbGQ7XG5cbiAgICBpZiAoKGZpYmVyLnN1YnRyZWVGbGFncyAmIEJlZm9yZU11dGF0aW9uTWFzaykgIT09IE5vRmxhZ3MgJiYgY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGNoaWxkLnJldHVybiA9IGZpYmVyO1xuICAgICAgbmV4dEVmZmVjdCA9IGNoaWxkO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHNfY29tcGxldGUoKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0QmVmb3JlTXV0YXRpb25FZmZlY3RzX2NvbXBsZXRlKCkge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7XG4gICAgc2V0Q3VycmVudEZpYmVyKGZpYmVyKTtcblxuICAgIHRyeSB7XG4gICAgICBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHNPbkZpYmVyKGZpYmVyKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmliZXIsIGZpYmVyLnJldHVybiwgZXJyb3IpO1xuICAgIH1cblxuICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gZmliZXIucmV0dXJuO1xuICAgICAgbmV4dEVmZmVjdCA9IHNpYmxpbmc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dEVmZmVjdCA9IGZpYmVyLnJldHVybjtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHNPbkZpYmVyKGZpbmlzaGVkV29yaykge1xuICB2YXIgY3VycmVudCA9IGZpbmlzaGVkV29yay5hbHRlcm5hdGU7XG4gIHZhciBmbGFncyA9IGZpbmlzaGVkV29yay5mbGFncztcblxuICBpZiAoKGZsYWdzICYgU25hcHNob3QpICE9PSBOb0ZsYWdzKSB7XG4gICAgc2V0Q3VycmVudEZpYmVyKGZpbmlzaGVkV29yayk7XG5cbiAgICBzd2l0Y2ggKGZpbmlzaGVkV29yay50YWcpIHtcbiAgICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBwcmV2UHJvcHMgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7XG4gICAgICAgICAgICB2YXIgcHJldlN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gZmluaXNoZWRXb3JrLnN0YXRlTm9kZTsgLy8gV2UgY291bGQgdXBkYXRlIGluc3RhbmNlIHByb3BzIGFuZCBzdGF0ZSBoZXJlLFxuICAgICAgICAgICAgLy8gYnV0IGluc3RlYWQgd2UgcmVseSBvbiB0aGVtIGJlaW5nIHNldCBkdXJpbmcgbGFzdCByZW5kZXIuXG4gICAgICAgICAgICAvLyBUT0RPOiByZXZpc2l0IHRoaXMgd2hlbiB3ZSBpbXBsZW1lbnQgcmVzdW1pbmcuXG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay50eXBlID09PSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgJiYgIWRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UucHJvcHMgIT09IGZpbmlzaGVkV29yay5tZW1vaXplZFByb3BzKSB7XG4gICAgICAgICAgICAgICAgICBlcnJvcignRXhwZWN0ZWQgJXMgcHJvcHMgdG8gbWF0Y2ggbWVtb2l6ZWQgcHJvcHMgYmVmb3JlICcgKyAnZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUuICcgKyAnVGhpcyBtaWdodCBlaXRoZXIgYmUgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBSZWFjdCwgb3IgYmVjYXVzZSAnICsgJ2EgY29tcG9uZW50IHJlYXNzaWducyBpdHMgb3duIGB0aGlzLnByb3BzYC4gJyArICdQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykgfHwgJ2luc3RhbmNlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlLnN0YXRlICE9PSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRTdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgZXJyb3IoJ0V4cGVjdGVkICVzIHN0YXRlIHRvIG1hdGNoIG1lbW9pemVkIHN0YXRlIGJlZm9yZSAnICsgJ2dldFNuYXBzaG90QmVmb3JlVXBkYXRlLiAnICsgJ1RoaXMgbWlnaHQgZWl0aGVyIGJlIGJlY2F1c2Ugb2YgYSBidWcgaW4gUmVhY3QsIG9yIGJlY2F1c2UgJyArICdhIGNvbXBvbmVudCByZWFzc2lnbnMgaXRzIG93biBgdGhpcy5zdGF0ZWAuICcgKyAnUGxlYXNlIGZpbGUgYW4gaXNzdWUuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaW5pc2hlZFdvcmspIHx8ICdpbnN0YW5jZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgc25hcHNob3QgPSBpbnN0YW5jZS5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZShmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgPT09IGZpbmlzaGVkV29yay50eXBlID8gcHJldlByb3BzIDogcmVzb2x2ZURlZmF1bHRQcm9wcyhmaW5pc2hlZFdvcmsudHlwZSwgcHJldlByb3BzKSwgcHJldlN0YXRlKTtcblxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB2YXIgZGlkV2FyblNldCA9IGRpZFdhcm5BYm91dFVuZGVmaW5lZFNuYXBzaG90QmVmb3JlVXBkYXRlO1xuXG4gICAgICAgICAgICAgIGlmIChzbmFwc2hvdCA9PT0gdW5kZWZpbmVkICYmICFkaWRXYXJuU2V0LmhhcyhmaW5pc2hlZFdvcmsudHlwZSkpIHtcbiAgICAgICAgICAgICAgICBkaWRXYXJuU2V0LmFkZChmaW5pc2hlZFdvcmsudHlwZSk7XG5cbiAgICAgICAgICAgICAgICBlcnJvcignJXMuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUoKTogQSBzbmFwc2hvdCB2YWx1ZSAob3IgbnVsbCkgJyArICdtdXN0IGJlIHJldHVybmVkLiBZb3UgaGF2ZSByZXR1cm5lZCB1bmRlZmluZWQuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaW5pc2hlZFdvcmspKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpbnN0YW5jZS5fX3JlYWN0SW50ZXJuYWxTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9IHNuYXBzaG90O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgIHtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgcm9vdCA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGU7XG4gICAgICAgICAgICBjbGVhckNvbnRhaW5lcihyb290LmNvbnRhaW5lckluZm8pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIGNhc2UgSG9zdFRleHQ6XG4gICAgICBjYXNlIEhvc3RQb3J0YWw6XG4gICAgICBjYXNlIEluY29tcGxldGVDbGFzc0NvbXBvbmVudDpcbiAgICAgICAgLy8gTm90aGluZyB0byBkbyBmb3IgdGhlc2UgY29tcG9uZW50IHR5cGVzXG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHVuaXQgb2Ygd29yayB0YWcgc2hvdWxkIG5vdCBoYXZlIHNpZGUtZWZmZWN0cy4gVGhpcyBlcnJvciBpcyAnICsgJ2xpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVzZXRDdXJyZW50RmliZXIoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoZmxhZ3MsIGZpbmlzaGVkV29yaywgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcikge1xuICB2YXIgdXBkYXRlUXVldWUgPSBmaW5pc2hlZFdvcmsudXBkYXRlUXVldWU7XG4gIHZhciBsYXN0RWZmZWN0ID0gdXBkYXRlUXVldWUgIT09IG51bGwgPyB1cGRhdGVRdWV1ZS5sYXN0RWZmZWN0IDogbnVsbDtcblxuICBpZiAobGFzdEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaXJzdEVmZmVjdCA9IGxhc3RFZmZlY3QubmV4dDtcbiAgICB2YXIgZWZmZWN0ID0gZmlyc3RFZmZlY3Q7XG5cbiAgICBkbyB7XG4gICAgICBpZiAoKGVmZmVjdC50YWcgJiBmbGFncykgPT09IGZsYWdzKSB7XG4gICAgICAgIC8vIFVubW91bnRcbiAgICAgICAgdmFyIGRlc3Ryb3kgPSBlZmZlY3QuZGVzdHJveTtcbiAgICAgICAgZWZmZWN0LmRlc3Ryb3kgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKGRlc3Ryb3kgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBQYXNzaXZlJDEpICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgICAgbWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RVbm1vdW50U3RhcnRlZChmaW5pc2hlZFdvcmspO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgoZmxhZ3MgJiBMYXlvdXQpICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgICAgbWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdGFydGVkKGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKChmbGFncyAmIEluc2VydGlvbikgIT09IE5vRmxhZ3MkMSkge1xuICAgICAgICAgICAgICBzZXRJc1J1bm5pbmdJbnNlcnRpb25FZmZlY3QodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc2FmZWx5Q2FsbERlc3Ryb3koZmluaXNoZWRXb3JrLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBkZXN0cm95KTtcblxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBJbnNlcnRpb24pICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgICAgc2V0SXNSdW5uaW5nSW5zZXJ0aW9uRWZmZWN0KGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZiAoKGZsYWdzICYgUGFzc2l2ZSQxKSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICAgIG1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0VW5tb3VudFN0b3BwZWQoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGZsYWdzICYgTGF5b3V0KSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICAgIG1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RVbm1vdW50U3RvcHBlZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBlZmZlY3QgPSBlZmZlY3QubmV4dDtcbiAgICB9IHdoaWxlIChlZmZlY3QgIT09IGZpcnN0RWZmZWN0KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KGZsYWdzLCBmaW5pc2hlZFdvcmspIHtcbiAgdmFyIHVwZGF0ZVF1ZXVlID0gZmluaXNoZWRXb3JrLnVwZGF0ZVF1ZXVlO1xuICB2YXIgbGFzdEVmZmVjdCA9IHVwZGF0ZVF1ZXVlICE9PSBudWxsID8gdXBkYXRlUXVldWUubGFzdEVmZmVjdCA6IG51bGw7XG5cbiAgaWYgKGxhc3RFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmlyc3RFZmZlY3QgPSBsYXN0RWZmZWN0Lm5leHQ7XG4gICAgdmFyIGVmZmVjdCA9IGZpcnN0RWZmZWN0O1xuXG4gICAgZG8ge1xuICAgICAgaWYgKChlZmZlY3QudGFnICYgZmxhZ3MpID09PSBmbGFncykge1xuICAgICAgICB7XG4gICAgICAgICAgaWYgKChmbGFncyAmIFBhc3NpdmUkMSkgIT09IE5vRmxhZ3MkMSkge1xuICAgICAgICAgICAgbWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RNb3VudFN0YXJ0ZWQoZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKChmbGFncyAmIExheW91dCkgIT09IE5vRmxhZ3MkMSkge1xuICAgICAgICAgICAgbWFya0NvbXBvbmVudExheW91dEVmZmVjdE1vdW50U3RhcnRlZChmaW5pc2hlZFdvcmspO1xuICAgICAgICAgIH1cbiAgICAgICAgfSAvLyBNb3VudFxuXG5cbiAgICAgICAgdmFyIGNyZWF0ZSA9IGVmZmVjdC5jcmVhdGU7XG5cbiAgICAgICAge1xuICAgICAgICAgIGlmICgoZmxhZ3MgJiBJbnNlcnRpb24pICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgIHNldElzUnVubmluZ0luc2VydGlvbkVmZmVjdCh0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBlZmZlY3QuZGVzdHJveSA9IGNyZWF0ZSgpO1xuXG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoKGZsYWdzICYgSW5zZXJ0aW9uKSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICBzZXRJc1J1bm5pbmdJbnNlcnRpb25FZmZlY3QoZmFsc2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoKGZsYWdzICYgUGFzc2l2ZSQxKSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICBtYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdE1vdW50U3RvcHBlZCgpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoKGZsYWdzICYgTGF5b3V0KSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICBtYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0TW91bnRTdG9wcGVkKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAge1xuICAgICAgICAgIHZhciBkZXN0cm95ID0gZWZmZWN0LmRlc3Ryb3k7XG5cbiAgICAgICAgICBpZiAoZGVzdHJveSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBkZXN0cm95ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB2YXIgaG9va05hbWUgPSB2b2lkIDA7XG5cbiAgICAgICAgICAgIGlmICgoZWZmZWN0LnRhZyAmIExheW91dCkgIT09IE5vRmxhZ3MpIHtcbiAgICAgICAgICAgICAgaG9va05hbWUgPSAndXNlTGF5b3V0RWZmZWN0JztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGVmZmVjdC50YWcgJiBJbnNlcnRpb24pICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgICAgICAgIGhvb2tOYW1lID0gJ3VzZUluc2VydGlvbkVmZmVjdCc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBob29rTmFtZSA9ICd1c2VFZmZlY3QnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgYWRkZW5kdW0gPSB2b2lkIDA7XG5cbiAgICAgICAgICAgIGlmIChkZXN0cm95ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIGFkZGVuZHVtID0gJyBZb3UgcmV0dXJuZWQgbnVsbC4gSWYgeW91ciBlZmZlY3QgZG9lcyBub3QgcmVxdWlyZSBjbGVhbiAnICsgJ3VwLCByZXR1cm4gdW5kZWZpbmVkIChvciBub3RoaW5nKS4nO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZGVzdHJveS50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgIGFkZGVuZHVtID0gJ1xcblxcbkl0IGxvb2tzIGxpa2UgeW91IHdyb3RlICcgKyBob29rTmFtZSArICcoYXN5bmMgKCkgPT4gLi4uKSBvciByZXR1cm5lZCBhIFByb21pc2UuICcgKyAnSW5zdGVhZCwgd3JpdGUgdGhlIGFzeW5jIGZ1bmN0aW9uIGluc2lkZSB5b3VyIGVmZmVjdCAnICsgJ2FuZCBjYWxsIGl0IGltbWVkaWF0ZWx5OlxcblxcbicgKyBob29rTmFtZSArICcoKCkgPT4ge1xcbicgKyAnICBhc3luYyBmdW5jdGlvbiBmZXRjaERhdGEoKSB7XFxuJyArICcgICAgLy8gWW91IGNhbiBhd2FpdCBoZXJlXFxuJyArICcgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBNeUFQSS5nZXREYXRhKHNvbWVJZCk7XFxuJyArICcgICAgLy8gLi4uXFxuJyArICcgIH1cXG4nICsgJyAgZmV0Y2hEYXRhKCk7XFxuJyArIFwifSwgW3NvbWVJZF0pOyAvLyBPciBbXSBpZiBlZmZlY3QgZG9lc24ndCBuZWVkIHByb3BzIG9yIHN0YXRlXFxuXFxuXCIgKyAnTGVhcm4gbW9yZSBhYm91dCBkYXRhIGZldGNoaW5nIHdpdGggSG9va3M6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9ob29rcy1kYXRhLWZldGNoaW5nJztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGFkZGVuZHVtID0gJyBZb3UgcmV0dXJuZWQ6ICcgKyBkZXN0cm95O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBlcnJvcignJXMgbXVzdCBub3QgcmV0dXJuIGFueXRoaW5nIGJlc2lkZXMgYSBmdW5jdGlvbiwgJyArICd3aGljaCBpcyB1c2VkIGZvciBjbGVhbi11cC4lcycsIGhvb2tOYW1lLCBhZGRlbmR1bSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGVmZmVjdCA9IGVmZmVjdC5uZXh0O1xuICAgIH0gd2hpbGUgKGVmZmVjdCAhPT0gZmlyc3RFZmZlY3QpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVFZmZlY3REdXJhdGlvbnMoZmluaXNoZWRSb290LCBmaW5pc2hlZFdvcmspIHtcbiAge1xuICAgIC8vIE9ubHkgUHJvZmlsZXJzIHdpdGggd29yayBpbiB0aGVpciBzdWJ0cmVlIHdpbGwgaGF2ZSBhbiBVcGRhdGUgZWZmZWN0IHNjaGVkdWxlZC5cbiAgICBpZiAoKGZpbmlzaGVkV29yay5mbGFncyAmIFVwZGF0ZSkgIT09IE5vRmxhZ3MpIHtcbiAgICAgIHN3aXRjaCAoZmluaXNoZWRXb3JrLnRhZykge1xuICAgICAgICBjYXNlIFByb2ZpbGVyOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBwYXNzaXZlRWZmZWN0RHVyYXRpb24gPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlLnBhc3NpdmVFZmZlY3REdXJhdGlvbjtcbiAgICAgICAgICAgIHZhciBfZmluaXNoZWRXb3JrJG1lbW9pemUgPSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wcyxcbiAgICAgICAgICAgICAgICBpZCA9IF9maW5pc2hlZFdvcmskbWVtb2l6ZS5pZCxcbiAgICAgICAgICAgICAgICBvblBvc3RDb21taXQgPSBfZmluaXNoZWRXb3JrJG1lbW9pemUub25Qb3N0Q29tbWl0OyAvLyBUaGlzIHZhbHVlIHdpbGwgc3RpbGwgcmVmbGVjdCB0aGUgcHJldmlvdXMgY29tbWl0IHBoYXNlLlxuICAgICAgICAgICAgLy8gSXQgZG9lcyBub3QgZ2V0IHJlc2V0IHVudGlsIHRoZSBzdGFydCBvZiB0aGUgbmV4dCBjb21taXQgcGhhc2UuXG5cbiAgICAgICAgICAgIHZhciBjb21taXRUaW1lID0gZ2V0Q29tbWl0VGltZSgpO1xuICAgICAgICAgICAgdmFyIHBoYXNlID0gZmluaXNoZWRXb3JrLmFsdGVybmF0ZSA9PT0gbnVsbCA/ICdtb3VudCcgOiAndXBkYXRlJztcblxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZiAoaXNDdXJyZW50VXBkYXRlTmVzdGVkKCkpIHtcbiAgICAgICAgICAgICAgICBwaGFzZSA9ICduZXN0ZWQtdXBkYXRlJztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9uUG9zdENvbW1pdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICBvblBvc3RDb21taXQoaWQsIHBoYXNlLCBwYXNzaXZlRWZmZWN0RHVyYXRpb24sIGNvbW1pdFRpbWUpO1xuICAgICAgICAgICAgfSAvLyBCdWJibGUgdGltZXMgdG8gdGhlIG5leHQgbmVhcmVzdCBhbmNlc3RvciBQcm9maWxlci5cbiAgICAgICAgICAgIC8vIEFmdGVyIHdlIHByb2Nlc3MgdGhhdCBQcm9maWxlciwgd2UnbGwgYnViYmxlIGZ1cnRoZXIgdXAuXG5cblxuICAgICAgICAgICAgdmFyIHBhcmVudEZpYmVyID0gZmluaXNoZWRXb3JrLnJldHVybjtcblxuICAgICAgICAgICAgb3V0ZXI6IHdoaWxlIChwYXJlbnRGaWJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICBzd2l0Y2ggKHBhcmVudEZpYmVyLnRhZykge1xuICAgICAgICAgICAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgICAgICAgICAgICB2YXIgcm9vdCA9IHBhcmVudEZpYmVyLnN0YXRlTm9kZTtcbiAgICAgICAgICAgICAgICAgIHJvb3QucGFzc2l2ZUVmZmVjdER1cmF0aW9uICs9IHBhc3NpdmVFZmZlY3REdXJhdGlvbjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuXG4gICAgICAgICAgICAgICAgY2FzZSBQcm9maWxlcjpcbiAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnRTdGF0ZU5vZGUgPSBwYXJlbnRGaWJlci5zdGF0ZU5vZGU7XG4gICAgICAgICAgICAgICAgICBwYXJlbnRTdGF0ZU5vZGUucGFzc2l2ZUVmZmVjdER1cmF0aW9uICs9IHBhc3NpdmVFZmZlY3REdXJhdGlvbjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcGFyZW50RmliZXIgPSBwYXJlbnRGaWJlci5yZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0TGF5b3V0RWZmZWN0T25GaWJlcihmaW5pc2hlZFJvb3QsIGN1cnJlbnQsIGZpbmlzaGVkV29yaywgY29tbWl0dGVkTGFuZXMpIHtcbiAgaWYgKChmaW5pc2hlZFdvcmsuZmxhZ3MgJiBMYXlvdXRNYXNrKSAhPT0gTm9GbGFncykge1xuICAgIHN3aXRjaCAoZmluaXNoZWRXb3JrLnRhZykge1xuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIGlmICggIW9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4pIHtcbiAgICAgICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgbGF5b3V0IGVmZmVjdHMgaGF2ZSBhbHJlYWR5IGJlZW4gZGVzdHJveWVkIChkdXJpbmcgbXV0YXRpb24gcGhhc2UpLlxuICAgICAgICAgICAgLy8gVGhpcyBpcyBkb25lIHRvIHByZXZlbnQgc2libGluZyBjb21wb25lbnQgZWZmZWN0cyBmcm9tIGludGVyZmVyaW5nIHdpdGggZWFjaCBvdGhlcixcbiAgICAgICAgICAgIC8vIGUuZy4gYSBkZXN0cm95IGZ1bmN0aW9uIGluIG9uZSBjb21wb25lbnQgc2hvdWxkIG5ldmVyIG92ZXJyaWRlIGEgcmVmIHNldFxuICAgICAgICAgICAgLy8gYnkgYSBjcmVhdGUgZnVuY3Rpb24gaW4gYW5vdGhlciBjb21wb25lbnQgZHVyaW5nIHRoZSBzYW1lIGNvbW1pdC5cbiAgICAgICAgICAgIGlmICggZmluaXNoZWRXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHN0YXJ0TGF5b3V0RWZmZWN0VGltZXIoKTtcbiAgICAgICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KExheW91dCB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICByZWNvcmRMYXlvdXRFZmZlY3REdXJhdGlvbihmaW5pc2hlZFdvcmspO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KExheW91dCB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIGluc3RhbmNlID0gZmluaXNoZWRXb3JrLnN0YXRlTm9kZTtcblxuICAgICAgICAgIGlmIChmaW5pc2hlZFdvcmsuZmxhZ3MgJiBVcGRhdGUpIHtcbiAgICAgICAgICAgIGlmICghb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbikge1xuICAgICAgICAgICAgICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIFdlIGNvdWxkIHVwZGF0ZSBpbnN0YW5jZSBwcm9wcyBhbmQgc3RhdGUgaGVyZSxcbiAgICAgICAgICAgICAgICAvLyBidXQgaW5zdGVhZCB3ZSByZWx5IG9uIHRoZW0gYmVpbmcgc2V0IGR1cmluZyBsYXN0IHJlbmRlci5cbiAgICAgICAgICAgICAgICAvLyBUT0RPOiByZXZpc2l0IHRoaXMgd2hlbiB3ZSBpbXBsZW1lbnQgcmVzdW1pbmcuXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay50eXBlID09PSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgJiYgIWRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlLnByb3BzICE9PSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wcykge1xuICAgICAgICAgICAgICAgICAgICAgIGVycm9yKCdFeHBlY3RlZCAlcyBwcm9wcyB0byBtYXRjaCBtZW1vaXplZCBwcm9wcyBiZWZvcmUgJyArICdjb21wb25lbnREaWRNb3VudC4gJyArICdUaGlzIG1pZ2h0IGVpdGhlciBiZSBiZWNhdXNlIG9mIGEgYnVnIGluIFJlYWN0LCBvciBiZWNhdXNlICcgKyAnYSBjb21wb25lbnQgcmVhc3NpZ25zIGl0cyBvd24gYHRoaXMucHJvcHNgLiAnICsgJ1BsZWFzZSBmaWxlIGFuIGlzc3VlLicsIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmluaXNoZWRXb3JrKSB8fCAnaW5zdGFuY2UnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZS5zdGF0ZSAhPT0gZmluaXNoZWRXb3JrLm1lbW9pemVkU3RhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBlcnJvcignRXhwZWN0ZWQgJXMgc3RhdGUgdG8gbWF0Y2ggbWVtb2l6ZWQgc3RhdGUgYmVmb3JlICcgKyAnY29tcG9uZW50RGlkTW91bnQuICcgKyAnVGhpcyBtaWdodCBlaXRoZXIgYmUgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBSZWFjdCwgb3IgYmVjYXVzZSAnICsgJ2EgY29tcG9uZW50IHJlYXNzaWducyBpdHMgb3duIGB0aGlzLnN0YXRlYC4gJyArICdQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykgfHwgJ2luc3RhbmNlJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIGZpbmlzaGVkV29yay5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0TGF5b3V0RWZmZWN0VGltZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQoKTtcbiAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgIHJlY29yZExheW91dEVmZmVjdER1cmF0aW9uKGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGluc3RhbmNlLmNvbXBvbmVudERpZE1vdW50KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBwcmV2UHJvcHMgPSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgPT09IGZpbmlzaGVkV29yay50eXBlID8gY3VycmVudC5tZW1vaXplZFByb3BzIDogcmVzb2x2ZURlZmF1bHRQcm9wcyhmaW5pc2hlZFdvcmsudHlwZSwgY3VycmVudC5tZW1vaXplZFByb3BzKTtcbiAgICAgICAgICAgICAgICB2YXIgcHJldlN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlOyAvLyBXZSBjb3VsZCB1cGRhdGUgaW5zdGFuY2UgcHJvcHMgYW5kIHN0YXRlIGhlcmUsXG4gICAgICAgICAgICAgICAgLy8gYnV0IGluc3RlYWQgd2UgcmVseSBvbiB0aGVtIGJlaW5nIHNldCBkdXJpbmcgbGFzdCByZW5kZXIuXG4gICAgICAgICAgICAgICAgLy8gVE9ETzogcmV2aXNpdCB0aGlzIHdoZW4gd2UgaW1wbGVtZW50IHJlc3VtaW5nLlxuXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay50eXBlID09PSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgJiYgIWRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlLnByb3BzICE9PSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wcykge1xuICAgICAgICAgICAgICAgICAgICAgIGVycm9yKCdFeHBlY3RlZCAlcyBwcm9wcyB0byBtYXRjaCBtZW1vaXplZCBwcm9wcyBiZWZvcmUgJyArICdjb21wb25lbnREaWRVcGRhdGUuICcgKyAnVGhpcyBtaWdodCBlaXRoZXIgYmUgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBSZWFjdCwgb3IgYmVjYXVzZSAnICsgJ2EgY29tcG9uZW50IHJlYXNzaWducyBpdHMgb3duIGB0aGlzLnByb3BzYC4gJyArICdQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykgfHwgJ2luc3RhbmNlJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2Uuc3RhdGUgIT09IGZpbmlzaGVkV29yay5tZW1vaXplZFN0YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgZXJyb3IoJ0V4cGVjdGVkICVzIHN0YXRlIHRvIG1hdGNoIG1lbW9pemVkIHN0YXRlIGJlZm9yZSAnICsgJ2NvbXBvbmVudERpZFVwZGF0ZS4gJyArICdUaGlzIG1pZ2h0IGVpdGhlciBiZSBiZWNhdXNlIG9mIGEgYnVnIGluIFJlYWN0LCBvciBiZWNhdXNlICcgKyAnYSBjb21wb25lbnQgcmVhc3NpZ25zIGl0cyBvd24gYHRoaXMuc3RhdGVgLiAnICsgJ1BsZWFzZSBmaWxlIGFuIGlzc3VlLicsIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmluaXNoZWRXb3JrKSB8fCAnaW5zdGFuY2UnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICggZmluaXNoZWRXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkge1xuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRMYXlvdXRFZmZlY3RUaW1lcigpO1xuICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5jb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzLCBwcmV2U3RhdGUsIGluc3RhbmNlLl9fcmVhY3RJbnRlcm5hbFNuYXBzaG90QmVmb3JlVXBkYXRlKTtcbiAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgIHJlY29yZExheW91dEVmZmVjdER1cmF0aW9uKGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGluc3RhbmNlLmNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMsIHByZXZTdGF0ZSwgaW5zdGFuY2UuX19yZWFjdEludGVybmFsU25hcHNob3RCZWZvcmVVcGRhdGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gLy8gVE9ETzogSSB0aGluayB0aGlzIGlzIG5vdyBhbHdheXMgbm9uLW51bGwgYnkgdGhlIHRpbWUgaXQgcmVhY2hlcyB0aGVcbiAgICAgICAgICAvLyBjb21taXQgcGhhc2UuIENvbnNpZGVyIHJlbW92aW5nIHRoZSB0eXBlIGNoZWNrLlxuXG5cbiAgICAgICAgICB2YXIgdXBkYXRlUXVldWUgPSBmaW5pc2hlZFdvcmsudXBkYXRlUXVldWU7XG5cbiAgICAgICAgICBpZiAodXBkYXRlUXVldWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay50eXBlID09PSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgJiYgIWRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UucHJvcHMgIT09IGZpbmlzaGVkV29yay5tZW1vaXplZFByb3BzKSB7XG4gICAgICAgICAgICAgICAgICBlcnJvcignRXhwZWN0ZWQgJXMgcHJvcHMgdG8gbWF0Y2ggbWVtb2l6ZWQgcHJvcHMgYmVmb3JlICcgKyAncHJvY2Vzc2luZyB0aGUgdXBkYXRlIHF1ZXVlLiAnICsgJ1RoaXMgbWlnaHQgZWl0aGVyIGJlIGJlY2F1c2Ugb2YgYSBidWcgaW4gUmVhY3QsIG9yIGJlY2F1c2UgJyArICdhIGNvbXBvbmVudCByZWFzc2lnbnMgaXRzIG93biBgdGhpcy5wcm9wc2AuICcgKyAnUGxlYXNlIGZpbGUgYW4gaXNzdWUuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaW5pc2hlZFdvcmspIHx8ICdpbnN0YW5jZScpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZS5zdGF0ZSAhPT0gZmluaXNoZWRXb3JrLm1lbW9pemVkU3RhdGUpIHtcbiAgICAgICAgICAgICAgICAgIGVycm9yKCdFeHBlY3RlZCAlcyBzdGF0ZSB0byBtYXRjaCBtZW1vaXplZCBzdGF0ZSBiZWZvcmUgJyArICdwcm9jZXNzaW5nIHRoZSB1cGRhdGUgcXVldWUuICcgKyAnVGhpcyBtaWdodCBlaXRoZXIgYmUgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBSZWFjdCwgb3IgYmVjYXVzZSAnICsgJ2EgY29tcG9uZW50IHJlYXNzaWducyBpdHMgb3duIGB0aGlzLnN0YXRlYC4gJyArICdQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykgfHwgJ2luc3RhbmNlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IC8vIFdlIGNvdWxkIHVwZGF0ZSBpbnN0YW5jZSBwcm9wcyBhbmQgc3RhdGUgaGVyZSxcbiAgICAgICAgICAgIC8vIGJ1dCBpbnN0ZWFkIHdlIHJlbHkgb24gdGhlbSBiZWluZyBzZXQgZHVyaW5nIGxhc3QgcmVuZGVyLlxuICAgICAgICAgICAgLy8gVE9ETzogcmV2aXNpdCB0aGlzIHdoZW4gd2UgaW1wbGVtZW50IHJlc3VtaW5nLlxuXG5cbiAgICAgICAgICAgIGNvbW1pdFVwZGF0ZVF1ZXVlKGZpbmlzaGVkV29yaywgdXBkYXRlUXVldWUsIGluc3RhbmNlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEhvc3RSb290OlxuICAgICAgICB7XG4gICAgICAgICAgLy8gVE9ETzogSSB0aGluayB0aGlzIGlzIG5vdyBhbHdheXMgbm9uLW51bGwgYnkgdGhlIHRpbWUgaXQgcmVhY2hlcyB0aGVcbiAgICAgICAgICAvLyBjb21taXQgcGhhc2UuIENvbnNpZGVyIHJlbW92aW5nIHRoZSB0eXBlIGNoZWNrLlxuICAgICAgICAgIHZhciBfdXBkYXRlUXVldWUgPSBmaW5pc2hlZFdvcmsudXBkYXRlUXVldWU7XG5cbiAgICAgICAgICBpZiAoX3VwZGF0ZVF1ZXVlICE9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgX2luc3RhbmNlID0gbnVsbDtcblxuICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay5jaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICBzd2l0Y2ggKGZpbmlzaGVkV29yay5jaGlsZC50YWcpIHtcbiAgICAgICAgICAgICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgICAgICAgICAgICBfaW5zdGFuY2UgPSBnZXRQdWJsaWNJbnN0YW5jZShmaW5pc2hlZFdvcmsuY2hpbGQuc3RhdGVOb2RlKTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgICAgICAgICAgICAgIF9pbnN0YW5jZSA9IGZpbmlzaGVkV29yay5jaGlsZC5zdGF0ZU5vZGU7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb21taXRVcGRhdGVRdWV1ZShmaW5pc2hlZFdvcmssIF91cGRhdGVRdWV1ZSwgX2luc3RhbmNlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgX2luc3RhbmNlMiA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGU7IC8vIFJlbmRlcmVycyBtYXkgc2NoZWR1bGUgd29yayB0byBiZSBkb25lIGFmdGVyIGhvc3QgY29tcG9uZW50cyBhcmUgbW91bnRlZFxuICAgICAgICAgIC8vIChlZyBET00gcmVuZGVyZXIgbWF5IHNjaGVkdWxlIGF1dG8tZm9jdXMgZm9yIGlucHV0cyBhbmQgZm9ybSBjb250cm9scykuXG4gICAgICAgICAgLy8gVGhlc2UgZWZmZWN0cyBzaG91bGQgb25seSBiZSBjb21taXR0ZWQgd2hlbiBjb21wb25lbnRzIGFyZSBmaXJzdCBtb3VudGVkLFxuICAgICAgICAgIC8vIGFrYSB3aGVuIHRoZXJlIGlzIG5vIGN1cnJlbnQvYWx0ZXJuYXRlLlxuXG4gICAgICAgICAgaWYgKGN1cnJlbnQgPT09IG51bGwgJiYgZmluaXNoZWRXb3JrLmZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAgICB2YXIgdHlwZSA9IGZpbmlzaGVkV29yay50eXBlO1xuICAgICAgICAgICAgdmFyIHByb3BzID0gZmluaXNoZWRXb3JrLm1lbW9pemVkUHJvcHM7XG4gICAgICAgICAgICBjb21taXRNb3VudChfaW5zdGFuY2UyLCB0eXBlLCBwcm9wcyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBIb3N0VGV4dDpcbiAgICAgICAge1xuICAgICAgICAgIC8vIFdlIGhhdmUgbm8gbGlmZS1jeWNsZXMgYXNzb2NpYXRlZCB3aXRoIHRleHQuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBIb3N0UG9ydGFsOlxuICAgICAgICB7XG4gICAgICAgICAgLy8gV2UgaGF2ZSBubyBsaWZlLWN5Y2xlcyBhc3NvY2lhdGVkIHdpdGggcG9ydGFscy5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIFByb2ZpbGVyOlxuICAgICAgICB7XG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIF9maW5pc2hlZFdvcmskbWVtb2l6ZTIgPSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wcyxcbiAgICAgICAgICAgICAgICBvbkNvbW1pdCA9IF9maW5pc2hlZFdvcmskbWVtb2l6ZTIub25Db21taXQsXG4gICAgICAgICAgICAgICAgb25SZW5kZXIgPSBfZmluaXNoZWRXb3JrJG1lbW9pemUyLm9uUmVuZGVyO1xuICAgICAgICAgICAgdmFyIGVmZmVjdER1cmF0aW9uID0gZmluaXNoZWRXb3JrLnN0YXRlTm9kZS5lZmZlY3REdXJhdGlvbjtcbiAgICAgICAgICAgIHZhciBjb21taXRUaW1lID0gZ2V0Q29tbWl0VGltZSgpO1xuICAgICAgICAgICAgdmFyIHBoYXNlID0gY3VycmVudCA9PT0gbnVsbCA/ICdtb3VudCcgOiAndXBkYXRlJztcblxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZiAoaXNDdXJyZW50VXBkYXRlTmVzdGVkKCkpIHtcbiAgICAgICAgICAgICAgICBwaGFzZSA9ICduZXN0ZWQtdXBkYXRlJztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9uUmVuZGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgIG9uUmVuZGVyKGZpbmlzaGVkV29yay5tZW1vaXplZFByb3BzLmlkLCBwaGFzZSwgZmluaXNoZWRXb3JrLmFjdHVhbER1cmF0aW9uLCBmaW5pc2hlZFdvcmsudHJlZUJhc2VEdXJhdGlvbiwgZmluaXNoZWRXb3JrLmFjdHVhbFN0YXJ0VGltZSwgY29tbWl0VGltZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbkNvbW1pdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIG9uQ29tbWl0KGZpbmlzaGVkV29yay5tZW1vaXplZFByb3BzLmlkLCBwaGFzZSwgZWZmZWN0RHVyYXRpb24sIGNvbW1pdFRpbWUpO1xuICAgICAgICAgICAgICB9IC8vIFNjaGVkdWxlIGEgcGFzc2l2ZSBlZmZlY3QgZm9yIHRoaXMgUHJvZmlsZXIgdG8gY2FsbCBvblBvc3RDb21taXQgaG9va3MuXG4gICAgICAgICAgICAgIC8vIFRoaXMgZWZmZWN0IHNob3VsZCBiZSBzY2hlZHVsZWQgZXZlbiBpZiB0aGVyZSBpcyBubyBvblBvc3RDb21taXQgY2FsbGJhY2sgZm9yIHRoaXMgUHJvZmlsZXIsXG4gICAgICAgICAgICAgIC8vIGJlY2F1c2UgdGhlIGVmZmVjdCBpcyBhbHNvIHdoZXJlIHRpbWVzIGJ1YmJsZSB0byBwYXJlbnQgUHJvZmlsZXJzLlxuXG5cbiAgICAgICAgICAgICAgZW5xdWV1ZVBlbmRpbmdQYXNzaXZlUHJvZmlsZXJFZmZlY3QoZmluaXNoZWRXb3JrKTsgLy8gUHJvcGFnYXRlIGxheW91dCBlZmZlY3QgZHVyYXRpb25zIHRvIHRoZSBuZXh0IG5lYXJlc3QgUHJvZmlsZXIgYW5jZXN0b3IuXG4gICAgICAgICAgICAgIC8vIERvIG5vdCByZXNldCB0aGVzZSB2YWx1ZXMgdW50aWwgdGhlIG5leHQgcmVuZGVyIHNvIERldlRvb2xzIGhhcyBhIGNoYW5jZSB0byByZWFkIHRoZW0gZmlyc3QuXG5cbiAgICAgICAgICAgICAgdmFyIHBhcmVudEZpYmVyID0gZmluaXNoZWRXb3JrLnJldHVybjtcblxuICAgICAgICAgICAgICBvdXRlcjogd2hpbGUgKHBhcmVudEZpYmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChwYXJlbnRGaWJlci50YWcpIHtcbiAgICAgICAgICAgICAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgICAgICAgICAgICAgIHZhciByb290ID0gcGFyZW50RmliZXIuc3RhdGVOb2RlO1xuICAgICAgICAgICAgICAgICAgICByb290LmVmZmVjdER1cmF0aW9uICs9IGVmZmVjdER1cmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjtcblxuICAgICAgICAgICAgICAgICAgY2FzZSBQcm9maWxlcjpcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudFN0YXRlTm9kZSA9IHBhcmVudEZpYmVyLnN0YXRlTm9kZTtcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50U3RhdGVOb2RlLmVmZmVjdER1cmF0aW9uICs9IGVmZmVjdER1cmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBwYXJlbnRGaWJlciA9IHBhcmVudEZpYmVyLnJldHVybjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICBjb21taXRTdXNwZW5zZUh5ZHJhdGlvbkNhbGxiYWNrcyhmaW5pc2hlZFJvb3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBTdXNwZW5zZUxpc3RDb21wb25lbnQ6XG4gICAgICBjYXNlIEluY29tcGxldGVDbGFzc0NvbXBvbmVudDpcbiAgICAgIGNhc2UgU2NvcGVDb21wb25lbnQ6XG4gICAgICBjYXNlIE9mZnNjcmVlbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgTGVnYWN5SGlkZGVuQ29tcG9uZW50OlxuICAgICAgY2FzZSBUcmFjaW5nTWFya2VyQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHVuaXQgb2Ygd29yayB0YWcgc2hvdWxkIG5vdCBoYXZlIHNpZGUtZWZmZWN0cy4gVGhpcyBlcnJvciBpcyAnICsgJ2xpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmICggIW9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4pIHtcbiAgICB7XG4gICAgICBpZiAoZmluaXNoZWRXb3JrLmZsYWdzICYgUmVmKSB7XG4gICAgICAgIGNvbW1pdEF0dGFjaFJlZihmaW5pc2hlZFdvcmspO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZWFwcGVhckxheW91dEVmZmVjdHNPbkZpYmVyKG5vZGUpIHtcbiAgLy8gVHVybiBvbiBsYXlvdXQgZWZmZWN0cyBpbiBhIHRyZWUgdGhhdCBwcmV2aW91c2x5IGRpc2FwcGVhcmVkLlxuICAvLyBUT0RPIChPZmZzY3JlZW4pIENoZWNrOiBmbGFncyAmIExheW91dFN0YXRpY1xuICBzd2l0Y2ggKG5vZGUudGFnKSB7XG4gICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBpZiAoIG5vZGUubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHN0YXJ0TGF5b3V0RWZmZWN0VGltZXIoKTtcbiAgICAgICAgICAgIHNhZmVseUNhbGxDb21taXRIb29rTGF5b3V0RWZmZWN0TGlzdE1vdW50KG5vZGUsIG5vZGUucmV0dXJuKTtcbiAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgcmVjb3JkTGF5b3V0RWZmZWN0RHVyYXRpb24obm9kZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNhZmVseUNhbGxDb21taXRIb29rTGF5b3V0RWZmZWN0TGlzdE1vdW50KG5vZGUsIG5vZGUucmV0dXJuKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIGluc3RhbmNlID0gbm9kZS5zdGF0ZU5vZGU7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRNb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHNhZmVseUNhbGxDb21wb25lbnREaWRNb3VudChub2RlLCBub2RlLnJldHVybiwgaW5zdGFuY2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgc2FmZWx5QXR0YWNoUmVmKG5vZGUsIG5vZGUucmV0dXJuKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHNhZmVseUF0dGFjaFJlZihub2RlLCBub2RlLnJldHVybik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGhpZGVPclVuaGlkZUFsbENoaWxkcmVuKGZpbmlzaGVkV29yaywgaXNIaWRkZW4pIHtcbiAgLy8gT25seSBoaWRlIG9yIHVuaGlkZSB0aGUgdG9wLW1vc3QgaG9zdCBub2Rlcy5cbiAgdmFyIGhvc3RTdWJ0cmVlUm9vdCA9IG51bGw7XG5cbiAge1xuICAgIC8vIFdlIG9ubHkgaGF2ZSB0aGUgdG9wIEZpYmVyIHRoYXQgd2FzIGluc2VydGVkIGJ1dCB3ZSBuZWVkIHRvIHJlY3Vyc2UgZG93biBpdHNcbiAgICAvLyBjaGlsZHJlbiB0byBmaW5kIGFsbCB0aGUgdGVybWluYWwgbm9kZXMuXG4gICAgdmFyIG5vZGUgPSBmaW5pc2hlZFdvcms7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKG5vZGUudGFnID09PSBIb3N0Q29tcG9uZW50KSB7XG4gICAgICAgIGlmIChob3N0U3VidHJlZVJvb3QgPT09IG51bGwpIHtcbiAgICAgICAgICBob3N0U3VidHJlZVJvb3QgPSBub2RlO1xuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZhciBpbnN0YW5jZSA9IG5vZGUuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgICBpZiAoaXNIaWRkZW4pIHtcbiAgICAgICAgICAgICAgaGlkZUluc3RhbmNlKGluc3RhbmNlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHVuaGlkZUluc3RhbmNlKG5vZGUuc3RhdGVOb2RlLCBub2RlLm1lbW9pemVkUHJvcHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaW5pc2hlZFdvcmssIGZpbmlzaGVkV29yay5yZXR1cm4sIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobm9kZS50YWcgPT09IEhvc3RUZXh0KSB7XG4gICAgICAgIGlmIChob3N0U3VidHJlZVJvb3QgPT09IG51bGwpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmFyIF9pbnN0YW5jZTMgPSBub2RlLnN0YXRlTm9kZTtcblxuICAgICAgICAgICAgaWYgKGlzSGlkZGVuKSB7XG4gICAgICAgICAgICAgIGhpZGVUZXh0SW5zdGFuY2UoX2luc3RhbmNlMyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB1bmhpZGVUZXh0SW5zdGFuY2UoX2luc3RhbmNlMywgbm9kZS5tZW1vaXplZFByb3BzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmluaXNoZWRXb3JrLCBmaW5pc2hlZFdvcmsucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKChub2RlLnRhZyA9PT0gT2Zmc2NyZWVuQ29tcG9uZW50IHx8IG5vZGUudGFnID09PSBMZWdhY3lIaWRkZW5Db21wb25lbnQpICYmIG5vZGUubWVtb2l6ZWRTdGF0ZSAhPT0gbnVsbCAmJiBub2RlICE9PSBmaW5pc2hlZFdvcmspIDsgZWxzZSBpZiAobm9kZS5jaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICBub2RlLmNoaWxkLnJldHVybiA9IG5vZGU7XG4gICAgICAgIG5vZGUgPSBub2RlLmNoaWxkO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGUgPT09IGZpbmlzaGVkV29yaykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHdoaWxlIChub2RlLnNpYmxpbmcgPT09IG51bGwpIHtcbiAgICAgICAgaWYgKG5vZGUucmV0dXJuID09PSBudWxsIHx8IG5vZGUucmV0dXJuID09PSBmaW5pc2hlZFdvcmspIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaG9zdFN1YnRyZWVSb290ID09PSBub2RlKSB7XG4gICAgICAgICAgaG9zdFN1YnRyZWVSb290ID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGhvc3RTdWJ0cmVlUm9vdCA9PT0gbm9kZSkge1xuICAgICAgICBob3N0U3VidHJlZVJvb3QgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBub2RlLnNpYmxpbmcucmV0dXJuID0gbm9kZS5yZXR1cm47XG4gICAgICBub2RlID0gbm9kZS5zaWJsaW5nO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRBdHRhY2hSZWYoZmluaXNoZWRXb3JrKSB7XG4gIHZhciByZWYgPSBmaW5pc2hlZFdvcmsucmVmO1xuXG4gIGlmIChyZWYgIT09IG51bGwpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlO1xuICAgIHZhciBpbnN0YW5jZVRvVXNlO1xuXG4gICAgc3dpdGNoIChmaW5pc2hlZFdvcmsudGFnKSB7XG4gICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgIGluc3RhbmNlVG9Vc2UgPSBnZXRQdWJsaWNJbnN0YW5jZShpbnN0YW5jZSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpbnN0YW5jZVRvVXNlID0gaW5zdGFuY2U7XG4gICAgfSAvLyBNb3ZlZCBvdXRzaWRlIHRvIGVuc3VyZSBEQ0Ugd29ya3Mgd2l0aCB0aGlzIGZsYWdcblxuICAgIGlmICh0eXBlb2YgcmVmID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgcmV0VmFsO1xuXG4gICAgICBpZiAoIGZpbmlzaGVkV29yay5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBzdGFydExheW91dEVmZmVjdFRpbWVyKCk7XG4gICAgICAgICAgcmV0VmFsID0gcmVmKGluc3RhbmNlVG9Vc2UpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHJlY29yZExheW91dEVmZmVjdER1cmF0aW9uKGZpbmlzaGVkV29yayk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldFZhbCA9IHJlZihpbnN0YW5jZVRvVXNlKTtcbiAgICAgIH1cblxuICAgICAge1xuICAgICAgICBpZiAodHlwZW9mIHJldFZhbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGVycm9yKCdVbmV4cGVjdGVkIHJldHVybiB2YWx1ZSBmcm9tIGEgY2FsbGJhY2sgcmVmIGluICVzLiAnICsgJ0EgY2FsbGJhY2sgcmVmIHNob3VsZCBub3QgcmV0dXJuIGEgZnVuY3Rpb24uJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaW5pc2hlZFdvcmspKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB7XG4gICAgICAgIGlmICghcmVmLmhhc093blByb3BlcnR5KCdjdXJyZW50JykpIHtcbiAgICAgICAgICBlcnJvcignVW5leHBlY3RlZCByZWYgb2JqZWN0IHByb3ZpZGVkIGZvciAlcy4gJyArICdVc2UgZWl0aGVyIGEgcmVmLXNldHRlciBmdW5jdGlvbiBvciBSZWFjdC5jcmVhdGVSZWYoKS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJlZi5jdXJyZW50ID0gaW5zdGFuY2VUb1VzZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZGV0YWNoRmliZXJNdXRhdGlvbihmaWJlcikge1xuICAvLyBDdXQgb2ZmIHRoZSByZXR1cm4gcG9pbnRlciB0byBkaXNjb25uZWN0IGl0IGZyb20gdGhlIHRyZWUuXG4gIC8vIFRoaXMgZW5hYmxlcyB1cyB0byBkZXRlY3QgYW5kIHdhcm4gYWdhaW5zdCBzdGF0ZSB1cGRhdGVzIG9uIGFuIHVubW91bnRlZCBjb21wb25lbnQuXG4gIC8vIEl0IGFsc28gcHJldmVudHMgZXZlbnRzIGZyb20gYnViYmxpbmcgZnJvbSB3aXRoaW4gZGlzY29ubmVjdGVkIGNvbXBvbmVudHMuXG4gIC8vXG4gIC8vIElkZWFsbHksIHdlIHNob3VsZCBhbHNvIGNsZWFyIHRoZSBjaGlsZCBwb2ludGVyIG9mIHRoZSBwYXJlbnQgYWx0ZXJuYXRlIHRvIGxldCB0aGlzXG4gIC8vIGdldCBHQzplZCBidXQgd2UgZG9uJ3Qga25vdyB3aGljaCBmb3Igc3VyZSB3aGljaCBwYXJlbnQgaXMgdGhlIGN1cnJlbnRcbiAgLy8gb25lIHNvIHdlJ2xsIHNldHRsZSBmb3IgR0M6aW5nIHRoZSBzdWJ0cmVlIG9mIHRoaXMgY2hpbGQuXG4gIC8vIFRoaXMgY2hpbGQgaXRzZWxmIHdpbGwgYmUgR0M6ZWQgd2hlbiB0aGUgcGFyZW50IHVwZGF0ZXMgdGhlIG5leHQgdGltZS5cbiAgLy9cbiAgLy8gTm90ZSB0aGF0IHdlIGNhbid0IGNsZWFyIGNoaWxkIG9yIHNpYmxpbmcgcG9pbnRlcnMgeWV0LlxuICAvLyBUaGV5J3JlIG5lZWRlZCBmb3IgcGFzc2l2ZSBlZmZlY3RzIGFuZCBmb3IgZmluZERPTU5vZGUuXG4gIC8vIFdlIGRlZmVyIHRob3NlIGZpZWxkcywgYW5kIGFsbCBvdGhlciBjbGVhbnVwLCB0byB0aGUgcGFzc2l2ZSBwaGFzZSAoc2VlIGRldGFjaEZpYmVyQWZ0ZXJFZmZlY3RzKS5cbiAgLy9cbiAgLy8gRG9uJ3QgcmVzZXQgdGhlIGFsdGVybmF0ZSB5ZXQsIGVpdGhlci4gV2UgbmVlZCB0aGF0IHNvIHdlIGNhbiBkZXRhY2ggdGhlXG4gIC8vIGFsdGVybmF0ZSdzIGZpZWxkcyBpbiB0aGUgcGFzc2l2ZSBwaGFzZS4gQ2xlYXJpbmcgdGhlIHJldHVybiBwb2ludGVyIGlzXG4gIC8vIHN1ZmZpY2llbnQgZm9yIGZpbmRET01Ob2RlIHNlbWFudGljcy5cbiAgdmFyIGFsdGVybmF0ZSA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICBpZiAoYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgYWx0ZXJuYXRlLnJldHVybiA9IG51bGw7XG4gIH1cblxuICBmaWJlci5yZXR1cm4gPSBudWxsO1xufVxuXG5mdW5jdGlvbiBkZXRhY2hGaWJlckFmdGVyRWZmZWN0cyhmaWJlcikge1xuICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuXG4gIGlmIChhbHRlcm5hdGUgIT09IG51bGwpIHtcbiAgICBmaWJlci5hbHRlcm5hdGUgPSBudWxsO1xuICAgIGRldGFjaEZpYmVyQWZ0ZXJFZmZlY3RzKGFsdGVybmF0ZSk7XG4gIH0gLy8gTm90ZTogRGVmZW5zaXZlbHkgdXNpbmcgbmVnYXRpb24gaW5zdGVhZCBvZiA8IGluIGNhc2VcbiAgLy8gYGRlbGV0ZWRUcmVlQ2xlYW5VcExldmVsYCBpcyB1bmRlZmluZWQuXG5cblxuICB7XG4gICAgLy8gQ2xlYXIgY3ljbGljYWwgRmliZXIgZmllbGRzLiBUaGlzIGxldmVsIGFsb25lIGlzIGRlc2lnbmVkIHRvIHJvdWdobHlcbiAgICAvLyBhcHByb3hpbWF0ZSB0aGUgcGxhbm5lZCBGaWJlciByZWZhY3Rvci4gSW4gdGhhdCB3b3JsZCwgYHNldFN0YXRlYCB3aWxsIGJlXG4gICAgLy8gYm91bmQgdG8gYSBzcGVjaWFsIFwiaW5zdGFuY2VcIiBvYmplY3QgaW5zdGVhZCBvZiBhIEZpYmVyLiBUaGUgSW5zdGFuY2VcbiAgICAvLyBvYmplY3Qgd2lsbCBub3QgaGF2ZSBhbnkgb2YgdGhlc2UgZmllbGRzLiBJdCB3aWxsIG9ubHkgYmUgY29ubmVjdGVkIHRvXG4gICAgLy8gdGhlIGZpYmVyIHRyZWUgdmlhIGEgc2luZ2xlIGxpbmsgYXQgdGhlIHJvb3QuIFNvIGlmIHRoaXMgbGV2ZWwgYWxvbmUgaXNcbiAgICAvLyBzdWZmaWNpZW50IHRvIGZpeCBtZW1vcnkgaXNzdWVzLCB0aGF0IGJvZGVzIHdlbGwgZm9yIG91ciBwbGFucy5cbiAgICBmaWJlci5jaGlsZCA9IG51bGw7XG4gICAgZmliZXIuZGVsZXRpb25zID0gbnVsbDtcbiAgICBmaWJlci5zaWJsaW5nID0gbnVsbDsgLy8gVGhlIGBzdGF0ZU5vZGVgIGlzIGN5Y2xpY2FsIGJlY2F1c2Ugb24gaG9zdCBub2RlcyBpdCBwb2ludHMgdG8gdGhlIGhvc3RcbiAgICAvLyB0cmVlLCB3aGljaCBoYXMgaXRzIG93biBwb2ludGVycyB0byBjaGlsZHJlbiwgcGFyZW50cywgYW5kIHNpYmxpbmdzLlxuICAgIC8vIFRoZSBvdGhlciBob3N0IG5vZGVzIGFsc28gcG9pbnQgYmFjayB0byBmaWJlcnMsIHNvIHdlIHNob3VsZCBkZXRhY2ggdGhhdFxuICAgIC8vIG9uZSwgdG9vLlxuXG4gICAgaWYgKGZpYmVyLnRhZyA9PT0gSG9zdENvbXBvbmVudCkge1xuICAgICAgdmFyIGhvc3RJbnN0YW5jZSA9IGZpYmVyLnN0YXRlTm9kZTtcblxuICAgICAgaWYgKGhvc3RJbnN0YW5jZSAhPT0gbnVsbCkge1xuICAgICAgICBkZXRhY2hEZWxldGVkSW5zdGFuY2UoaG9zdEluc3RhbmNlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmaWJlci5zdGF0ZU5vZGUgPSBudWxsOyAvLyBJJ20gaW50ZW50aW9uYWxseSBub3QgY2xlYXJpbmcgdGhlIGByZXR1cm5gIGZpZWxkIGluIHRoaXMgbGV2ZWwuIFdlXG4gICAgLy8gYWxyZWFkeSBkaXNjb25uZWN0IHRoZSBgcmV0dXJuYCBwb2ludGVyIGF0IHRoZSByb290IG9mIHRoZSBkZWxldGVkXG4gICAgLy8gc3VidHJlZSAoaW4gYGRldGFjaEZpYmVyTXV0YXRpb25gKS4gQmVzaWRlcywgYHJldHVybmAgYnkgaXRzZWxmIGlzIG5vdFxuICAgIC8vIGN5Y2xpY2FsIOKAlCBpdCdzIG9ubHkgY3ljbGljYWwgd2hlbiBjb21iaW5lZCB3aXRoIGBjaGlsZGAsIGBzaWJsaW5nYCwgYW5kXG4gICAgLy8gYGFsdGVybmF0ZWAuIEJ1dCB3ZSdsbCBjbGVhciBpdCBpbiB0aGUgbmV4dCBsZXZlbCBhbnl3YXksIGp1c3QgaW4gY2FzZS5cblxuICAgIHtcbiAgICAgIGZpYmVyLl9kZWJ1Z093bmVyID0gbnVsbDtcbiAgICB9XG5cbiAgICB7XG4gICAgICAvLyBUaGVvcmV0aWNhbGx5LCBub3RoaW5nIGluIGhlcmUgc2hvdWxkIGJlIG5lY2Vzc2FyeSwgYmVjYXVzZSB3ZSBhbHJlYWR5XG4gICAgICAvLyBkaXNjb25uZWN0ZWQgdGhlIGZpYmVyIGZyb20gdGhlIHRyZWUuIFNvIGV2ZW4gaWYgc29tZXRoaW5nIGxlYWtzIHRoaXNcbiAgICAgIC8vIHBhcnRpY3VsYXIgZmliZXIsIGl0IHdvbid0IGxlYWsgYW55dGhpbmcgZWxzZVxuICAgICAgLy9cbiAgICAgIC8vIFRoZSBwdXJwb3NlIG9mIHRoaXMgYnJhbmNoIGlzIHRvIGJlIHN1cGVyIGFnZ3Jlc3NpdmUgc28gd2UgY2FuIG1lYXN1cmVcbiAgICAgIC8vIGlmIHRoZXJlJ3MgYW55IGRpZmZlcmVuY2UgaW4gbWVtb3J5IGltcGFjdC4gSWYgdGhlcmUgaXMsIHRoYXQgY291bGRcbiAgICAgIC8vIGluZGljYXRlIGEgUmVhY3QgbGVhayB3ZSBkb24ndCBrbm93IGFib3V0LlxuICAgICAgZmliZXIucmV0dXJuID0gbnVsbDtcbiAgICAgIGZpYmVyLmRlcGVuZGVuY2llcyA9IG51bGw7XG4gICAgICBmaWJlci5tZW1vaXplZFByb3BzID0gbnVsbDtcbiAgICAgIGZpYmVyLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgICAgZmliZXIucGVuZGluZ1Byb3BzID0gbnVsbDtcbiAgICAgIGZpYmVyLnN0YXRlTm9kZSA9IG51bGw7IC8vIFRPRE86IE1vdmUgdG8gYGNvbW1pdFBhc3NpdmVVbm1vdW50SW5zaWRlRGVsZXRlZFRyZWVPbkZpYmVyYCBpbnN0ZWFkLlxuXG4gICAgICBmaWJlci51cGRhdGVRdWV1ZSA9IG51bGw7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldEhvc3RQYXJlbnRGaWJlcihmaWJlcikge1xuICB2YXIgcGFyZW50ID0gZmliZXIucmV0dXJuO1xuXG4gIHdoaWxlIChwYXJlbnQgIT09IG51bGwpIHtcbiAgICBpZiAoaXNIb3N0UGFyZW50KHBhcmVudCkpIHtcbiAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgfVxuXG4gICAgcGFyZW50ID0gcGFyZW50LnJldHVybjtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgdG8gZmluZCBhIGhvc3QgcGFyZW50LiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgJyArICdpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG59XG5cbmZ1bmN0aW9uIGlzSG9zdFBhcmVudChmaWJlcikge1xuICByZXR1cm4gZmliZXIudGFnID09PSBIb3N0Q29tcG9uZW50IHx8IGZpYmVyLnRhZyA9PT0gSG9zdFJvb3QgfHwgZmliZXIudGFnID09PSBIb3N0UG9ydGFsO1xufVxuXG5mdW5jdGlvbiBnZXRIb3N0U2libGluZyhmaWJlcikge1xuICAvLyBXZSdyZSBnb2luZyB0byBzZWFyY2ggZm9yd2FyZCBpbnRvIHRoZSB0cmVlIHVudGlsIHdlIGZpbmQgYSBzaWJsaW5nIGhvc3RcbiAgLy8gbm9kZS4gVW5mb3J0dW5hdGVseSwgaWYgbXVsdGlwbGUgaW5zZXJ0aW9ucyBhcmUgZG9uZSBpbiBhIHJvdyB3ZSBoYXZlIHRvXG4gIC8vIHNlYXJjaCBwYXN0IHRoZW0uIFRoaXMgbGVhZHMgdG8gZXhwb25lbnRpYWwgc2VhcmNoIGZvciB0aGUgbmV4dCBzaWJsaW5nLlxuICAvLyBUT0RPOiBGaW5kIGEgbW9yZSBlZmZpY2llbnQgd2F5IHRvIGRvIHRoaXMuXG4gIHZhciBub2RlID0gZmliZXI7XG5cbiAgc2libGluZ3M6IHdoaWxlICh0cnVlKSB7XG4gICAgLy8gSWYgd2UgZGlkbid0IGZpbmQgYW55dGhpbmcsIGxldCdzIHRyeSB0aGUgbmV4dCBzaWJsaW5nLlxuICAgIHdoaWxlIChub2RlLnNpYmxpbmcgPT09IG51bGwpIHtcbiAgICAgIGlmIChub2RlLnJldHVybiA9PT0gbnVsbCB8fCBpc0hvc3RQYXJlbnQobm9kZS5yZXR1cm4pKSB7XG4gICAgICAgIC8vIElmIHdlIHBvcCBvdXQgb2YgdGhlIHJvb3Qgb3IgaGl0IHRoZSBwYXJlbnQgdGhlIGZpYmVyIHdlIGFyZSB0aGVcbiAgICAgICAgLy8gbGFzdCBzaWJsaW5nLlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICAgIH1cblxuICAgIG5vZGUuc2libGluZy5yZXR1cm4gPSBub2RlLnJldHVybjtcbiAgICBub2RlID0gbm9kZS5zaWJsaW5nO1xuXG4gICAgd2hpbGUgKG5vZGUudGFnICE9PSBIb3N0Q29tcG9uZW50ICYmIG5vZGUudGFnICE9PSBIb3N0VGV4dCAmJiBub2RlLnRhZyAhPT0gRGVoeWRyYXRlZEZyYWdtZW50KSB7XG4gICAgICAvLyBJZiBpdCBpcyBub3QgaG9zdCBub2RlIGFuZCwgd2UgbWlnaHQgaGF2ZSBhIGhvc3Qgbm9kZSBpbnNpZGUgaXQuXG4gICAgICAvLyBUcnkgdG8gc2VhcmNoIGRvd24gdW50aWwgd2UgZmluZCBvbmUuXG4gICAgICBpZiAobm9kZS5mbGFncyAmIFBsYWNlbWVudCkge1xuICAgICAgICAvLyBJZiB3ZSBkb24ndCBoYXZlIGEgY2hpbGQsIHRyeSB0aGUgc2libGluZ3MgaW5zdGVhZC5cbiAgICAgICAgY29udGludWUgc2libGluZ3M7XG4gICAgICB9IC8vIElmIHdlIGRvbid0IGhhdmUgYSBjaGlsZCwgdHJ5IHRoZSBzaWJsaW5ncyBpbnN0ZWFkLlxuICAgICAgLy8gV2UgYWxzbyBza2lwIHBvcnRhbHMgYmVjYXVzZSB0aGV5IGFyZSBub3QgcGFydCBvZiB0aGlzIGhvc3QgdHJlZS5cblxuXG4gICAgICBpZiAobm9kZS5jaGlsZCA9PT0gbnVsbCB8fCBub2RlLnRhZyA9PT0gSG9zdFBvcnRhbCkge1xuICAgICAgICBjb250aW51ZSBzaWJsaW5ncztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vZGUuY2hpbGQucmV0dXJuID0gbm9kZTtcbiAgICAgICAgbm9kZSA9IG5vZGUuY2hpbGQ7XG4gICAgICB9XG4gICAgfSAvLyBDaGVjayBpZiB0aGlzIGhvc3Qgbm9kZSBpcyBzdGFibGUgb3IgYWJvdXQgdG8gYmUgcGxhY2VkLlxuXG5cbiAgICBpZiAoIShub2RlLmZsYWdzICYgUGxhY2VtZW50KSkge1xuICAgICAgLy8gRm91bmQgaXQhXG4gICAgICByZXR1cm4gbm9kZS5zdGF0ZU5vZGU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBsYWNlbWVudChmaW5pc2hlZFdvcmspIHtcblxuXG4gIHZhciBwYXJlbnRGaWJlciA9IGdldEhvc3RQYXJlbnRGaWJlcihmaW5pc2hlZFdvcmspOyAvLyBOb3RlOiB0aGVzZSB0d28gdmFyaWFibGVzICptdXN0KiBhbHdheXMgYmUgdXBkYXRlZCB0b2dldGhlci5cblxuICBzd2l0Y2ggKHBhcmVudEZpYmVyLnRhZykge1xuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIHBhcmVudCA9IHBhcmVudEZpYmVyLnN0YXRlTm9kZTtcblxuICAgICAgICBpZiAocGFyZW50RmliZXIuZmxhZ3MgJiBDb250ZW50UmVzZXQpIHtcbiAgICAgICAgICAvLyBSZXNldCB0aGUgdGV4dCBjb250ZW50IG9mIHRoZSBwYXJlbnQgYmVmb3JlIGRvaW5nIGFueSBpbnNlcnRpb25zXG4gICAgICAgICAgcmVzZXRUZXh0Q29udGVudChwYXJlbnQpOyAvLyBDbGVhciBDb250ZW50UmVzZXQgZnJvbSB0aGUgZWZmZWN0IHRhZ1xuXG4gICAgICAgICAgcGFyZW50RmliZXIuZmxhZ3MgJj0gfkNvbnRlbnRSZXNldDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBiZWZvcmUgPSBnZXRIb3N0U2libGluZyhmaW5pc2hlZFdvcmspOyAvLyBXZSBvbmx5IGhhdmUgdGhlIHRvcCBGaWJlciB0aGF0IHdhcyBpbnNlcnRlZCBidXQgd2UgbmVlZCB0byByZWN1cnNlIGRvd24gaXRzXG4gICAgICAgIC8vIGNoaWxkcmVuIHRvIGZpbmQgYWxsIHRoZSB0ZXJtaW5hbCBub2Rlcy5cblxuICAgICAgICBpbnNlcnRPckFwcGVuZFBsYWNlbWVudE5vZGUoZmluaXNoZWRXb3JrLCBiZWZvcmUsIHBhcmVudCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0Um9vdDpcbiAgICBjYXNlIEhvc3RQb3J0YWw6XG4gICAgICB7XG4gICAgICAgIHZhciBfcGFyZW50ID0gcGFyZW50RmliZXIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm87XG5cbiAgICAgICAgdmFyIF9iZWZvcmUgPSBnZXRIb3N0U2libGluZyhmaW5pc2hlZFdvcmspO1xuXG4gICAgICAgIGluc2VydE9yQXBwZW5kUGxhY2VtZW50Tm9kZUludG9Db250YWluZXIoZmluaXNoZWRXb3JrLCBfYmVmb3JlLCBfcGFyZW50KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lLW5vLWZhbGx0aHJvdWdoXG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhvc3QgcGFyZW50IGZpYmVyLiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgJyArICdpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5zZXJ0T3JBcHBlbmRQbGFjZW1lbnROb2RlSW50b0NvbnRhaW5lcihub2RlLCBiZWZvcmUsIHBhcmVudCkge1xuICB2YXIgdGFnID0gbm9kZS50YWc7XG4gIHZhciBpc0hvc3QgPSB0YWcgPT09IEhvc3RDb21wb25lbnQgfHwgdGFnID09PSBIb3N0VGV4dDtcblxuICBpZiAoaXNIb3N0KSB7XG4gICAgdmFyIHN0YXRlTm9kZSA9IG5vZGUuc3RhdGVOb2RlO1xuXG4gICAgaWYgKGJlZm9yZSkge1xuICAgICAgaW5zZXJ0SW5Db250YWluZXJCZWZvcmUocGFyZW50LCBzdGF0ZU5vZGUsIGJlZm9yZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwcGVuZENoaWxkVG9Db250YWluZXIocGFyZW50LCBzdGF0ZU5vZGUpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0YWcgPT09IEhvc3RQb3J0YWwpIDsgZWxzZSB7XG4gICAgdmFyIGNoaWxkID0gbm9kZS5jaGlsZDtcblxuICAgIGlmIChjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgaW5zZXJ0T3JBcHBlbmRQbGFjZW1lbnROb2RlSW50b0NvbnRhaW5lcihjaGlsZCwgYmVmb3JlLCBwYXJlbnQpO1xuICAgICAgdmFyIHNpYmxpbmcgPSBjaGlsZC5zaWJsaW5nO1xuXG4gICAgICB3aGlsZSAoc2libGluZyAhPT0gbnVsbCkge1xuICAgICAgICBpbnNlcnRPckFwcGVuZFBsYWNlbWVudE5vZGVJbnRvQ29udGFpbmVyKHNpYmxpbmcsIGJlZm9yZSwgcGFyZW50KTtcbiAgICAgICAgc2libGluZyA9IHNpYmxpbmcuc2libGluZztcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5zZXJ0T3JBcHBlbmRQbGFjZW1lbnROb2RlKG5vZGUsIGJlZm9yZSwgcGFyZW50KSB7XG4gIHZhciB0YWcgPSBub2RlLnRhZztcbiAgdmFyIGlzSG9zdCA9IHRhZyA9PT0gSG9zdENvbXBvbmVudCB8fCB0YWcgPT09IEhvc3RUZXh0O1xuXG4gIGlmIChpc0hvc3QpIHtcbiAgICB2YXIgc3RhdGVOb2RlID0gbm9kZS5zdGF0ZU5vZGU7XG5cbiAgICBpZiAoYmVmb3JlKSB7XG4gICAgICBpbnNlcnRCZWZvcmUocGFyZW50LCBzdGF0ZU5vZGUsIGJlZm9yZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwcGVuZENoaWxkKHBhcmVudCwgc3RhdGVOb2RlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodGFnID09PSBIb3N0UG9ydGFsKSA7IGVsc2Uge1xuICAgIHZhciBjaGlsZCA9IG5vZGUuY2hpbGQ7XG5cbiAgICBpZiAoY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGluc2VydE9yQXBwZW5kUGxhY2VtZW50Tm9kZShjaGlsZCwgYmVmb3JlLCBwYXJlbnQpO1xuICAgICAgdmFyIHNpYmxpbmcgPSBjaGlsZC5zaWJsaW5nO1xuXG4gICAgICB3aGlsZSAoc2libGluZyAhPT0gbnVsbCkge1xuICAgICAgICBpbnNlcnRPckFwcGVuZFBsYWNlbWVudE5vZGUoc2libGluZywgYmVmb3JlLCBwYXJlbnQpO1xuICAgICAgICBzaWJsaW5nID0gc2libGluZy5zaWJsaW5nO1xuICAgICAgfVxuICAgIH1cbiAgfVxufSAvLyBUaGVzZSBhcmUgdHJhY2tlZCBvbiB0aGUgc3RhY2sgYXMgd2UgcmVjdXJzaXZlbHkgdHJhdmVyc2UgYVxuLy8gZGVsZXRlZCBzdWJ0cmVlLlxuLy8gVE9ETzogVXBkYXRlIHRoZXNlIGR1cmluZyB0aGUgd2hvbGUgbXV0YXRpb24gcGhhc2UsIG5vdCBqdXN0IGR1cmluZ1xuLy8gYSBkZWxldGlvbi5cblxuXG52YXIgaG9zdFBhcmVudCA9IG51bGw7XG52YXIgaG9zdFBhcmVudElzQ29udGFpbmVyID0gZmFsc2U7XG5cbmZ1bmN0aW9uIGNvbW1pdERlbGV0aW9uRWZmZWN0cyhyb290LCByZXR1cm5GaWJlciwgZGVsZXRlZEZpYmVyKSB7XG4gIHtcbiAgICAvLyBXZSBvbmx5IGhhdmUgdGhlIHRvcCBGaWJlciB0aGF0IHdhcyBkZWxldGVkIGJ1dCB3ZSBuZWVkIHRvIHJlY3Vyc2UgZG93biBpdHNcbiAgICAvLyBjaGlsZHJlbiB0byBmaW5kIGFsbCB0aGUgdGVybWluYWwgbm9kZXMuXG4gICAgLy8gUmVjdXJzaXZlbHkgZGVsZXRlIGFsbCBob3N0IG5vZGVzIGZyb20gdGhlIHBhcmVudCwgZGV0YWNoIHJlZnMsIGNsZWFuXG4gICAgLy8gdXAgbW91bnRlZCBsYXlvdXQgZWZmZWN0cywgYW5kIGNhbGwgY29tcG9uZW50V2lsbFVubW91bnQuXG4gICAgLy8gV2Ugb25seSBuZWVkIHRvIHJlbW92ZSB0aGUgdG9wbW9zdCBob3N0IGNoaWxkIGluIGVhY2ggYnJhbmNoLiBCdXQgdGhlbiB3ZVxuICAgIC8vIHN0aWxsIG5lZWQgdG8ga2VlcCB0cmF2ZXJzaW5nIHRvIHVubW91bnQgZWZmZWN0cywgcmVmcywgYW5kIGNXVS4gVE9ETzogV2VcbiAgICAvLyBjb3VsZCBzcGxpdCB0aGlzIGludG8gdHdvIHNlcGFyYXRlIHRyYXZlcnNhbHMgZnVuY3Rpb25zLCB3aGVyZSB0aGUgc2Vjb25kXG4gICAgLy8gb25lIGRvZXNuJ3QgaW5jbHVkZSBhbnkgcmVtb3ZlQ2hpbGQgbG9naWMuIFRoaXMgaXMgbWF5YmUgdGhlIHNhbWVcbiAgICAvLyBmdW5jdGlvbiBhcyBcImRpc2FwcGVhckxheW91dEVmZmVjdHNcIiAob3Igd2hhdGV2ZXIgdGhhdCB0dXJucyBpbnRvIGFmdGVyXG4gICAgLy8gdGhlIGxheW91dCBwaGFzZSBpcyByZWZhY3RvcmVkIHRvIHVzZSByZWN1cnNpb24pLlxuICAgIC8vIEJlZm9yZSBzdGFydGluZywgZmluZCB0aGUgbmVhcmVzdCBob3N0IHBhcmVudCBvbiB0aGUgc3RhY2sgc28gd2Uga25vd1xuICAgIC8vIHdoaWNoIGluc3RhbmNlL2NvbnRhaW5lciB0byByZW1vdmUgdGhlIGNoaWxkcmVuIGZyb20uXG4gICAgLy8gVE9ETzogSW5zdGVhZCBvZiBzZWFyY2hpbmcgdXAgdGhlIGZpYmVyIHJldHVybiBwYXRoIG9uIGV2ZXJ5IGRlbGV0aW9uLCB3ZVxuICAgIC8vIGNhbiB0cmFjayB0aGUgbmVhcmVzdCBob3N0IGNvbXBvbmVudCBvbiB0aGUgSlMgc3RhY2sgYXMgd2UgdHJhdmVyc2UgdGhlXG4gICAgLy8gdHJlZSBkdXJpbmcgdGhlIGNvbW1pdCBwaGFzZS4gVGhpcyB3b3VsZCBtYWtlIGluc2VydGlvbnMgZmFzdGVyLCB0b28uXG4gICAgdmFyIHBhcmVudCA9IHJldHVybkZpYmVyO1xuXG4gICAgZmluZFBhcmVudDogd2hpbGUgKHBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChwYXJlbnQudGFnKSB7XG4gICAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBob3N0UGFyZW50ID0gcGFyZW50LnN0YXRlTm9kZTtcbiAgICAgICAgICAgIGhvc3RQYXJlbnRJc0NvbnRhaW5lciA9IGZhbHNlO1xuICAgICAgICAgICAgYnJlYWsgZmluZFBhcmVudDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBob3N0UGFyZW50ID0gcGFyZW50LnN0YXRlTm9kZS5jb250YWluZXJJbmZvO1xuICAgICAgICAgICAgaG9zdFBhcmVudElzQ29udGFpbmVyID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrIGZpbmRQYXJlbnQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBob3N0UGFyZW50ID0gcGFyZW50LnN0YXRlTm9kZS5jb250YWluZXJJbmZvO1xuICAgICAgICAgICAgaG9zdFBhcmVudElzQ29udGFpbmVyID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrIGZpbmRQYXJlbnQ7XG4gICAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBwYXJlbnQgPSBwYXJlbnQucmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChob3N0UGFyZW50ID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHRvIGZpbmQgYSBob3N0IHBhcmVudC4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5ICcgKyAnYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cblxuICAgIGNvbW1pdERlbGV0aW9uRWZmZWN0c09uRmliZXIocm9vdCwgcmV0dXJuRmliZXIsIGRlbGV0ZWRGaWJlcik7XG4gICAgaG9zdFBhcmVudCA9IG51bGw7XG4gICAgaG9zdFBhcmVudElzQ29udGFpbmVyID0gZmFsc2U7XG4gIH1cblxuICBkZXRhY2hGaWJlck11dGF0aW9uKGRlbGV0ZWRGaWJlcik7XG59XG5cbmZ1bmN0aW9uIHJlY3Vyc2l2ZWx5VHJhdmVyc2VEZWxldGlvbkVmZmVjdHMoZmluaXNoZWRSb290LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBwYXJlbnQpIHtcbiAgLy8gVE9ETzogVXNlIGEgc3RhdGljIGZsYWcgdG8gc2tpcCB0cmVlcyB0aGF0IGRvbid0IGhhdmUgdW5tb3VudCBlZmZlY3RzXG4gIHZhciBjaGlsZCA9IHBhcmVudC5jaGlsZDtcblxuICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICBjb21taXREZWxldGlvbkVmZmVjdHNPbkZpYmVyKGZpbmlzaGVkUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgY2hpbGQpO1xuICAgIGNoaWxkID0gY2hpbGQuc2libGluZztcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXREZWxldGlvbkVmZmVjdHNPbkZpYmVyKGZpbmlzaGVkUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVsZXRlZEZpYmVyKSB7XG4gIG9uQ29tbWl0VW5tb3VudChkZWxldGVkRmliZXIpOyAvLyBUaGUgY2FzZXMgaW4gdGhpcyBvdXRlciBzd2l0Y2ggbW9kaWZ5IHRoZSBzdGFjayBiZWZvcmUgdGhleSB0cmF2ZXJzZVxuICAvLyBpbnRvIHRoZWlyIHN1YnRyZWUuIFRoZXJlIGFyZSBzaW1wbGVyIGNhc2VzIGluIHRoZSBpbm5lciBzd2l0Y2hcbiAgLy8gdGhhdCBkb24ndCBtb2RpZnkgdGhlIHN0YWNrLlxuXG4gIHN3aXRjaCAoZGVsZXRlZEZpYmVyLnRhZykge1xuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgaWYgKCFvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuKSB7XG4gICAgICAgICAgc2FmZWx5RGV0YWNoUmVmKGRlbGV0ZWRGaWJlciwgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcik7XG4gICAgICAgIH0gLy8gSW50ZW50aW9uYWwgZmFsbHRocm91Z2ggdG8gbmV4dCBicmFuY2hcblxuICAgICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZS1uby1mYWxsdGhyb3VnaFxuXG4gICAgY2FzZSBIb3N0VGV4dDpcbiAgICAgIHtcbiAgICAgICAgLy8gV2Ugb25seSBuZWVkIHRvIHJlbW92ZSB0aGUgbmVhcmVzdCBob3N0IGNoaWxkLiBTZXQgdGhlIGhvc3QgcGFyZW50XG4gICAgICAgIC8vIHRvIGBudWxsYCBvbiB0aGUgc3RhY2sgdG8gaW5kaWNhdGUgdGhhdCBuZXN0ZWQgY2hpbGRyZW4gZG9uJ3RcbiAgICAgICAgLy8gbmVlZCB0byBiZSByZW1vdmVkLlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHByZXZIb3N0UGFyZW50ID0gaG9zdFBhcmVudDtcbiAgICAgICAgICB2YXIgcHJldkhvc3RQYXJlbnRJc0NvbnRhaW5lciA9IGhvc3RQYXJlbnRJc0NvbnRhaW5lcjtcbiAgICAgICAgICBob3N0UGFyZW50ID0gbnVsbDtcbiAgICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlRGVsZXRpb25FZmZlY3RzKGZpbmlzaGVkUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVsZXRlZEZpYmVyKTtcbiAgICAgICAgICBob3N0UGFyZW50ID0gcHJldkhvc3RQYXJlbnQ7XG4gICAgICAgICAgaG9zdFBhcmVudElzQ29udGFpbmVyID0gcHJldkhvc3RQYXJlbnRJc0NvbnRhaW5lcjtcblxuICAgICAgICAgIGlmIChob3N0UGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBOb3cgdGhhdCBhbGwgdGhlIGNoaWxkIGVmZmVjdHMgaGF2ZSB1bm1vdW50ZWQsIHdlIGNhbiByZW1vdmUgdGhlXG4gICAgICAgICAgICAvLyBub2RlIGZyb20gdGhlIHRyZWUuXG4gICAgICAgICAgICBpZiAoaG9zdFBhcmVudElzQ29udGFpbmVyKSB7XG4gICAgICAgICAgICAgIHJlbW92ZUNoaWxkRnJvbUNvbnRhaW5lcihob3N0UGFyZW50LCBkZWxldGVkRmliZXIuc3RhdGVOb2RlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlbW92ZUNoaWxkKGhvc3RQYXJlbnQsIGRlbGV0ZWRGaWJlci5zdGF0ZU5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgRGVoeWRyYXRlZEZyYWdtZW50OlxuICAgICAge1xuICAgICAgICAvLyBEZWxldGUgdGhlIGRlaHlkcmF0ZWQgc3VzcGVuc2UgYm91bmRhcnkgYW5kIGFsbCBvZiBpdHMgY29udGVudC5cblxuXG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoaG9zdFBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKGhvc3RQYXJlbnRJc0NvbnRhaW5lcikge1xuICAgICAgICAgICAgICBjbGVhclN1c3BlbnNlQm91bmRhcnlGcm9tQ29udGFpbmVyKGhvc3RQYXJlbnQsIGRlbGV0ZWRGaWJlci5zdGF0ZU5vZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY2xlYXJTdXNwZW5zZUJvdW5kYXJ5KGhvc3RQYXJlbnQsIGRlbGV0ZWRGaWJlci5zdGF0ZU5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgIHtcbiAgICAgICAge1xuICAgICAgICAgIC8vIFdoZW4gd2UgZ28gaW50byBhIHBvcnRhbCwgaXQgYmVjb21lcyB0aGUgcGFyZW50IHRvIHJlbW92ZSBmcm9tLlxuICAgICAgICAgIHZhciBfcHJldkhvc3RQYXJlbnQgPSBob3N0UGFyZW50O1xuICAgICAgICAgIHZhciBfcHJldkhvc3RQYXJlbnRJc0NvbnRhaW5lciA9IGhvc3RQYXJlbnRJc0NvbnRhaW5lcjtcbiAgICAgICAgICBob3N0UGFyZW50ID0gZGVsZXRlZEZpYmVyLnN0YXRlTm9kZS5jb250YWluZXJJbmZvO1xuICAgICAgICAgIGhvc3RQYXJlbnRJc0NvbnRhaW5lciA9IHRydWU7XG4gICAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgICAgaG9zdFBhcmVudCA9IF9wcmV2SG9zdFBhcmVudDtcbiAgICAgICAgICBob3N0UGFyZW50SXNDb250YWluZXIgPSBfcHJldkhvc3RQYXJlbnRJc0NvbnRhaW5lcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgIGNhc2UgTWVtb0NvbXBvbmVudDpcbiAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIGlmICghb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbikge1xuICAgICAgICAgIHZhciB1cGRhdGVRdWV1ZSA9IGRlbGV0ZWRGaWJlci51cGRhdGVRdWV1ZTtcblxuICAgICAgICAgIGlmICh1cGRhdGVRdWV1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGxhc3RFZmZlY3QgPSB1cGRhdGVRdWV1ZS5sYXN0RWZmZWN0O1xuXG4gICAgICAgICAgICBpZiAobGFzdEVmZmVjdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICB2YXIgZmlyc3RFZmZlY3QgPSBsYXN0RWZmZWN0Lm5leHQ7XG4gICAgICAgICAgICAgIHZhciBlZmZlY3QgPSBmaXJzdEVmZmVjdDtcblxuICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgdmFyIF9lZmZlY3QgPSBlZmZlY3QsXG4gICAgICAgICAgICAgICAgICAgIGRlc3Ryb3kgPSBfZWZmZWN0LmRlc3Ryb3ksXG4gICAgICAgICAgICAgICAgICAgIHRhZyA9IF9lZmZlY3QudGFnO1xuXG4gICAgICAgICAgICAgICAgaWYgKGRlc3Ryb3kgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgaWYgKCh0YWcgJiBJbnNlcnRpb24pICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgICAgICAgICAgc2FmZWx5Q2FsbERlc3Ryb3koZGVsZXRlZEZpYmVyLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBkZXN0cm95KTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHRhZyAmIExheW91dCkgIT09IE5vRmxhZ3MkMSkge1xuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgbWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdGFydGVkKGRlbGV0ZWRGaWJlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoIGRlbGV0ZWRGaWJlci5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBzdGFydExheW91dEVmZmVjdFRpbWVyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgc2FmZWx5Q2FsbERlc3Ryb3koZGVsZXRlZEZpYmVyLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBkZXN0cm95KTtcbiAgICAgICAgICAgICAgICAgICAgICByZWNvcmRMYXlvdXRFZmZlY3REdXJhdGlvbihkZWxldGVkRmliZXIpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIHNhZmVseUNhbGxEZXN0cm95KGRlbGV0ZWRGaWJlciwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVzdHJveSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgbWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdG9wcGVkKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBlZmZlY3QgPSBlZmZlY3QubmV4dDtcbiAgICAgICAgICAgICAgfSB3aGlsZSAoZWZmZWN0ICE9PSBmaXJzdEVmZmVjdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIGlmICghb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbikge1xuICAgICAgICAgIHNhZmVseURldGFjaFJlZihkZWxldGVkRmliZXIsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IpO1xuICAgICAgICAgIHZhciBpbnN0YW5jZSA9IGRlbGV0ZWRGaWJlci5zdGF0ZU5vZGU7XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVbm1vdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBzYWZlbHlDYWxsQ29tcG9uZW50V2lsbFVubW91bnQoZGVsZXRlZEZpYmVyLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBpbnN0YW5jZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgU2NvcGVDb21wb25lbnQ6XG4gICAgICB7XG5cbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgT2Zmc2NyZWVuQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBpZiAoIC8vIFRPRE86IFJlbW92ZSB0aGlzIGRlYWQgZmxhZ1xuICAgICAgICAgZGVsZXRlZEZpYmVyLm1vZGUgJiBDb25jdXJyZW50TW9kZSkge1xuICAgICAgICAgIC8vIElmIHRoaXMgb2Zmc2NyZWVuIGNvbXBvbmVudCBpcyBoaWRkZW4sIHdlIGFscmVhZHkgdW5tb3VudGVkIGl0LiBCZWZvcmVcbiAgICAgICAgICAvLyBkZWxldGluZyB0aGUgY2hpbGRyZW4sIHRyYWNrIHRoYXQgaXQncyBhbHJlYWR5IHVubW91bnRlZCBzbyB0aGF0IHdlXG4gICAgICAgICAgLy8gZG9uJ3QgYXR0ZW1wdCB0byB1bm1vdW50IHRoZSBlZmZlY3RzIGFnYWluLlxuICAgICAgICAgIC8vIFRPRE86IElmIHRoZSB0cmVlIGlzIGhpZGRlbiwgaW4gbW9zdCBjYXNlcyB3ZSBzaG91bGQgYmUgYWJsZSB0byBza2lwXG4gICAgICAgICAgLy8gb3ZlciB0aGUgbmVzdGVkIGNoaWxkcmVuIGVudGlyZWx5LiBBbiBleGNlcHRpb24gaXMgd2UgaGF2ZW4ndCB5ZXQgZm91bmRcbiAgICAgICAgICAvLyB0aGUgdG9wbW9zdCBob3N0IG5vZGUgdG8gZGVsZXRlLCB3aGljaCB3ZSBhbHJlYWR5IHRyYWNrIG9uIHRoZSBzdGFjay5cbiAgICAgICAgICAvLyBCdXQgdGhlIG90aGVyIGNhc2UgaXMgcG9ydGFscywgd2hpY2ggbmVlZCB0byBiZSBkZXRhY2hlZCBubyBtYXR0ZXIgaG93XG4gICAgICAgICAgLy8gZGVlcGx5IHRoZXkgYXJlIG5lc3RlZC4gV2Ugc2hvdWxkIHVzZSBhIHN1YnRyZWUgZmxhZyB0byB0cmFjayB3aGV0aGVyIGFcbiAgICAgICAgICAvLyBzdWJ0cmVlIGluY2x1ZGVzIGEgbmVzdGVkIHBvcnRhbC5cbiAgICAgICAgICB2YXIgcHJldk9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4gPSBvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuO1xuICAgICAgICAgIG9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4gPSBwcmV2T2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiB8fCBkZWxldGVkRmliZXIubWVtb2l6ZWRTdGF0ZSAhPT0gbnVsbDtcbiAgICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlRGVsZXRpb25FZmZlY3RzKGZpbmlzaGVkUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVsZXRlZEZpYmVyKTtcbiAgICAgICAgICBvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuID0gcHJldk9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VEZWxldGlvbkVmZmVjdHMoZmluaXNoZWRSb290LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBkZWxldGVkRmliZXIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0U3VzcGVuc2VDYWxsYmFjayhmaW5pc2hlZFdvcmspIHtcbiAgLy8gVE9ETzogTW92ZSB0aGlzIHRvIHBhc3NpdmUgcGhhc2VcbiAgdmFyIG5ld1N0YXRlID0gZmluaXNoZWRXb3JrLm1lbW9pemVkU3RhdGU7XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFN1c3BlbnNlSHlkcmF0aW9uQ2FsbGJhY2tzKGZpbmlzaGVkUm9vdCwgZmluaXNoZWRXb3JrKSB7XG5cbiAgdmFyIG5ld1N0YXRlID0gZmluaXNoZWRXb3JrLm1lbW9pemVkU3RhdGU7XG5cbiAgaWYgKG5ld1N0YXRlID09PSBudWxsKSB7XG4gICAgdmFyIGN1cnJlbnQgPSBmaW5pc2hlZFdvcmsuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgIHZhciBwcmV2U3RhdGUgPSBjdXJyZW50Lm1lbW9pemVkU3RhdGU7XG5cbiAgICAgIGlmIChwcmV2U3RhdGUgIT09IG51bGwpIHtcbiAgICAgICAgdmFyIHN1c3BlbnNlSW5zdGFuY2UgPSBwcmV2U3RhdGUuZGVoeWRyYXRlZDtcblxuICAgICAgICBpZiAoc3VzcGVuc2VJbnN0YW5jZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGNvbW1pdEh5ZHJhdGVkU3VzcGVuc2VJbnN0YW5jZShzdXNwZW5zZUluc3RhbmNlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhdHRhY2hTdXNwZW5zZVJldHJ5TGlzdGVuZXJzKGZpbmlzaGVkV29yaykge1xuICAvLyBJZiB0aGlzIGJvdW5kYXJ5IGp1c3QgdGltZWQgb3V0LCB0aGVuIGl0IHdpbGwgaGF2ZSBhIHNldCBvZiB3YWtlYWJsZXMuXG4gIC8vIEZvciBlYWNoIHdha2VhYmxlLCBhdHRhY2ggYSBsaXN0ZW5lciBzbyB0aGF0IHdoZW4gaXQgcmVzb2x2ZXMsIFJlYWN0XG4gIC8vIGF0dGVtcHRzIHRvIHJlLXJlbmRlciB0aGUgYm91bmRhcnkgaW4gdGhlIHByaW1hcnkgKHByZS10aW1lb3V0KSBzdGF0ZS5cbiAgdmFyIHdha2VhYmxlcyA9IGZpbmlzaGVkV29yay51cGRhdGVRdWV1ZTtcblxuICBpZiAod2FrZWFibGVzICE9PSBudWxsKSB7XG4gICAgZmluaXNoZWRXb3JrLnVwZGF0ZVF1ZXVlID0gbnVsbDtcbiAgICB2YXIgcmV0cnlDYWNoZSA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGU7XG5cbiAgICBpZiAocmV0cnlDYWNoZSA9PT0gbnVsbCkge1xuICAgICAgcmV0cnlDYWNoZSA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGUgPSBuZXcgUG9zc2libHlXZWFrU2V0KCk7XG4gICAgfVxuXG4gICAgd2FrZWFibGVzLmZvckVhY2goZnVuY3Rpb24gKHdha2VhYmxlKSB7XG4gICAgICAvLyBNZW1vaXplIHVzaW5nIHRoZSBib3VuZGFyeSBmaWJlciB0byBwcmV2ZW50IHJlZHVuZGFudCBsaXN0ZW5lcnMuXG4gICAgICB2YXIgcmV0cnkgPSByZXNvbHZlUmV0cnlXYWtlYWJsZS5iaW5kKG51bGwsIGZpbmlzaGVkV29yaywgd2FrZWFibGUpO1xuXG4gICAgICBpZiAoIXJldHJ5Q2FjaGUuaGFzKHdha2VhYmxlKSkge1xuICAgICAgICByZXRyeUNhY2hlLmFkZCh3YWtlYWJsZSk7XG5cbiAgICAgICAge1xuICAgICAgICAgIGlmIChpc0RldlRvb2xzUHJlc2VudCkge1xuICAgICAgICAgICAgaWYgKGluUHJvZ3Jlc3NMYW5lcyAhPT0gbnVsbCAmJiBpblByb2dyZXNzUm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAvLyBJZiB3ZSBoYXZlIHBlbmRpbmcgd29yayBzdGlsbCwgYXNzb2NpYXRlIHRoZSBvcmlnaW5hbCB1cGRhdGVycyB3aXRoIGl0LlxuICAgICAgICAgICAgICByZXN0b3JlUGVuZGluZ1VwZGF0ZXJzKGluUHJvZ3Jlc3NSb290LCBpblByb2dyZXNzTGFuZXMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ0V4cGVjdGVkIGZpbmlzaGVkIHJvb3QgYW5kIGxhbmVzIHRvIGJlIHNldC4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB3YWtlYWJsZS50aGVuKHJldHJ5LCByZXRyeSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn0gLy8gVGhpcyBmdW5jdGlvbiBkZXRlY3RzIHdoZW4gYSBTdXNwZW5zZSBib3VuZGFyeSBnb2VzIGZyb20gdmlzaWJsZSB0byBoaWRkZW4uXG5mdW5jdGlvbiBjb21taXRNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrLCBjb21taXR0ZWRMYW5lcykge1xuICBpblByb2dyZXNzTGFuZXMgPSBjb21taXR0ZWRMYW5lcztcbiAgaW5Qcm9ncmVzc1Jvb3QgPSByb290O1xuICBzZXRDdXJyZW50RmliZXIoZmluaXNoZWRXb3JrKTtcbiAgY29tbWl0TXV0YXRpb25FZmZlY3RzT25GaWJlcihmaW5pc2hlZFdvcmssIHJvb3QpO1xuICBzZXRDdXJyZW50RmliZXIoZmluaXNoZWRXb3JrKTtcbiAgaW5Qcm9ncmVzc0xhbmVzID0gbnVsbDtcbiAgaW5Qcm9ncmVzc1Jvb3QgPSBudWxsO1xufVxuXG5mdW5jdGlvbiByZWN1cnNpdmVseVRyYXZlcnNlTXV0YXRpb25FZmZlY3RzKHJvb3QsIHBhcmVudEZpYmVyLCBsYW5lcykge1xuICAvLyBEZWxldGlvbnMgZWZmZWN0cyBjYW4gYmUgc2NoZWR1bGVkIG9uIGFueSBmaWJlciB0eXBlLiBUaGV5IG5lZWQgdG8gaGFwcGVuXG4gIC8vIGJlZm9yZSB0aGUgY2hpbGRyZW4gZWZmZWN0cyBoYWUgZmlyZWQuXG4gIHZhciBkZWxldGlvbnMgPSBwYXJlbnRGaWJlci5kZWxldGlvbnM7XG5cbiAgaWYgKGRlbGV0aW9ucyAhPT0gbnVsbCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGVsZXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgY2hpbGRUb0RlbGV0ZSA9IGRlbGV0aW9uc1tpXTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29tbWl0RGVsZXRpb25FZmZlY3RzKHJvb3QsIHBhcmVudEZpYmVyLCBjaGlsZFRvRGVsZXRlKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGNoaWxkVG9EZWxldGUsIHBhcmVudEZpYmVyLCBlcnJvcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHByZXZEZWJ1Z0ZpYmVyID0gZ2V0Q3VycmVudEZpYmVyKCk7XG5cbiAgaWYgKHBhcmVudEZpYmVyLnN1YnRyZWVGbGFncyAmIE11dGF0aW9uTWFzaykge1xuICAgIHZhciBjaGlsZCA9IHBhcmVudEZpYmVyLmNoaWxkO1xuXG4gICAgd2hpbGUgKGNoaWxkICE9PSBudWxsKSB7XG4gICAgICBzZXRDdXJyZW50RmliZXIoY2hpbGQpO1xuICAgICAgY29tbWl0TXV0YXRpb25FZmZlY3RzT25GaWJlcihjaGlsZCwgcm9vdCk7XG4gICAgICBjaGlsZCA9IGNoaWxkLnNpYmxpbmc7XG4gICAgfVxuICB9XG5cbiAgc2V0Q3VycmVudEZpYmVyKHByZXZEZWJ1Z0ZpYmVyKTtcbn1cblxuZnVuY3Rpb24gY29tbWl0TXV0YXRpb25FZmZlY3RzT25GaWJlcihmaW5pc2hlZFdvcmssIHJvb3QsIGxhbmVzKSB7XG4gIHZhciBjdXJyZW50ID0gZmluaXNoZWRXb3JrLmFsdGVybmF0ZTtcbiAgdmFyIGZsYWdzID0gZmluaXNoZWRXb3JrLmZsYWdzOyAvLyBUaGUgZWZmZWN0IGZsYWcgc2hvdWxkIGJlIGNoZWNrZWQgKmFmdGVyKiB3ZSByZWZpbmUgdGhlIHR5cGUgb2YgZmliZXIsXG4gIC8vIGJlY2F1c2UgdGhlIGZpYmVyIHRhZyBpcyBtb3JlIHNwZWNpZmljLiBBbiBleGNlcHRpb24gaXMgYW55IGZsYWcgcmVsYXRlZFxuICAvLyB0byByZWNvbmNpbGF0aW9uLCBiZWNhdXNlIHRob3NlIGNhbiBiZSBzZXQgb24gYWxsIGZpYmVyIHR5cGVzLlxuXG4gIHN3aXRjaCAoZmluaXNoZWRXb3JrLnRhZykge1xuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgIGNhc2UgTWVtb0NvbXBvbmVudDpcbiAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChJbnNlcnRpb24gfCBIYXNFZmZlY3QsIGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybik7XG4gICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KEluc2VydGlvbiB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmluaXNoZWRXb3JrLCBmaW5pc2hlZFdvcmsucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfSAvLyBMYXlvdXQgZWZmZWN0cyBhcmUgZGVzdHJveWVkIGR1cmluZyB0aGUgbXV0YXRpb24gcGhhc2Ugc28gdGhhdCBhbGxcbiAgICAgICAgICAvLyBkZXN0cm95IGZ1bmN0aW9ucyBmb3IgYWxsIGZpYmVycyBhcmUgY2FsbGVkIGJlZm9yZSBhbnkgY3JlYXRlIGZ1bmN0aW9ucy5cbiAgICAgICAgICAvLyBUaGlzIHByZXZlbnRzIHNpYmxpbmcgY29tcG9uZW50IGVmZmVjdHMgZnJvbSBpbnRlcmZlcmluZyB3aXRoIGVhY2ggb3RoZXIsXG4gICAgICAgICAgLy8gZS5nLiBhIGRlc3Ryb3kgZnVuY3Rpb24gaW4gb25lIGNvbXBvbmVudCBzaG91bGQgbmV2ZXIgb3ZlcnJpZGUgYSByZWYgc2V0XG4gICAgICAgICAgLy8gYnkgYSBjcmVhdGUgZnVuY3Rpb24gaW4gYW5vdGhlciBjb21wb25lbnQgZHVyaW5nIHRoZSBzYW1lIGNvbW1pdC5cblxuXG4gICAgICAgICAgaWYgKCBmaW5pc2hlZFdvcmsubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzdGFydExheW91dEVmZmVjdFRpbWVyKCk7XG4gICAgICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChMYXlvdXQgfCBIYXNFZmZlY3QsIGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybik7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaW5pc2hlZFdvcmssIGZpbmlzaGVkV29yay5yZXR1cm4sIGVycm9yKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmVjb3JkTGF5b3V0RWZmZWN0RHVyYXRpb24oZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29tbWl0SG9va0VmZmVjdExpc3RVbm1vdW50KExheW91dCB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrLCBmaW5pc2hlZFdvcmsucmV0dXJuKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgUmVmKSB7XG4gICAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHNhZmVseURldGFjaFJlZihjdXJyZW50LCBjdXJyZW50LnJldHVybik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAge1xuICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlTXV0YXRpb25FZmZlY3RzKHJvb3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgIGNvbW1pdFJlY29uY2lsaWF0aW9uRWZmZWN0cyhmaW5pc2hlZFdvcmspO1xuXG4gICAgICAgIGlmIChmbGFncyAmIFJlZikge1xuICAgICAgICAgIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBzYWZlbHlEZXRhY2hSZWYoY3VycmVudCwgY3VycmVudC5yZXR1cm4pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHtcbiAgICAgICAgICAvLyBUT0RPOiBDb250ZW50UmVzZXQgZ2V0cyBjbGVhcmVkIGJ5IHRoZSBjaGlsZHJlbiBkdXJpbmcgdGhlIGNvbW1pdFxuICAgICAgICAgIC8vIHBoYXNlLiBUaGlzIGlzIGEgcmVmYWN0b3IgaGF6YXJkIGJlY2F1c2UgaXQgbWVhbnMgd2UgbXVzdCByZWFkXG4gICAgICAgICAgLy8gZmxhZ3MgdGhlIGZsYWdzIGFmdGVyIGBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHNgIGhhcyBhbHJlYWR5IHJ1bjtcbiAgICAgICAgICAvLyB0aGUgb3JkZXIgbWF0dGVycy4gV2Ugc2hvdWxkIHJlZmFjdG9yIHNvIHRoYXQgQ29udGVudFJlc2V0IGRvZXMgbm90XG4gICAgICAgICAgLy8gcmVseSBvbiBtdXRhdGluZyB0aGUgZmxhZyBkdXJpbmcgY29tbWl0LiBMaWtlIGJ5IHNldHRpbmcgYSBmbGFnXG4gICAgICAgICAgLy8gZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UgaW5zdGVhZC5cbiAgICAgICAgICBpZiAoZmluaXNoZWRXb3JrLmZsYWdzICYgQ29udGVudFJlc2V0KSB7XG4gICAgICAgICAgICB2YXIgaW5zdGFuY2UgPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICByZXNldFRleHRDb250ZW50KGluc3RhbmNlKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChmbGFncyAmIFVwZGF0ZSkge1xuICAgICAgICAgICAgdmFyIF9pbnN0YW5jZTQgPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgICBpZiAoX2luc3RhbmNlNCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIC8vIENvbW1pdCB0aGUgd29yayBwcmVwYXJlZCBlYXJsaWVyLlxuICAgICAgICAgICAgICB2YXIgbmV3UHJvcHMgPSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wczsgLy8gRm9yIGh5ZHJhdGlvbiB3ZSByZXVzZSB0aGUgdXBkYXRlIHBhdGggYnV0IHdlIHRyZWF0IHRoZSBvbGRQcm9wc1xuICAgICAgICAgICAgICAvLyBhcyB0aGUgbmV3UHJvcHMuIFRoZSB1cGRhdGVQYXlsb2FkIHdpbGwgY29udGFpbiB0aGUgcmVhbCBjaGFuZ2UgaW5cbiAgICAgICAgICAgICAgLy8gdGhpcyBjYXNlLlxuXG4gICAgICAgICAgICAgIHZhciBvbGRQcm9wcyA9IGN1cnJlbnQgIT09IG51bGwgPyBjdXJyZW50Lm1lbW9pemVkUHJvcHMgOiBuZXdQcm9wcztcbiAgICAgICAgICAgICAgdmFyIHR5cGUgPSBmaW5pc2hlZFdvcmsudHlwZTsgLy8gVE9ETzogVHlwZSB0aGUgdXBkYXRlUXVldWUgdG8gYmUgc3BlY2lmaWMgdG8gaG9zdCBjb21wb25lbnRzLlxuXG4gICAgICAgICAgICAgIHZhciB1cGRhdGVQYXlsb2FkID0gZmluaXNoZWRXb3JrLnVwZGF0ZVF1ZXVlO1xuICAgICAgICAgICAgICBmaW5pc2hlZFdvcmsudXBkYXRlUXVldWUgPSBudWxsO1xuXG4gICAgICAgICAgICAgIGlmICh1cGRhdGVQYXlsb2FkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIGNvbW1pdFVwZGF0ZShfaW5zdGFuY2U0LCB1cGRhdGVQYXlsb2FkLCB0eXBlLCBvbGRQcm9wcywgbmV3UHJvcHMsIGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFRleHQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay5zdGF0ZU5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHNob3VsZCBoYXZlIGEgdGV4dCBub2RlIGluaXRpYWxpemVkLiBUaGlzIGVycm9yIGlzIGxpa2VseSAnICsgJ2NhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciB0ZXh0SW5zdGFuY2UgPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlO1xuICAgICAgICAgICAgdmFyIG5ld1RleHQgPSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wczsgLy8gRm9yIGh5ZHJhdGlvbiB3ZSByZXVzZSB0aGUgdXBkYXRlIHBhdGggYnV0IHdlIHRyZWF0IHRoZSBvbGRQcm9wc1xuICAgICAgICAgICAgLy8gYXMgdGhlIG5ld1Byb3BzLiBUaGUgdXBkYXRlUGF5bG9hZCB3aWxsIGNvbnRhaW4gdGhlIHJlYWwgY2hhbmdlIGluXG4gICAgICAgICAgICAvLyB0aGlzIGNhc2UuXG5cbiAgICAgICAgICAgIHZhciBvbGRUZXh0ID0gY3VycmVudCAhPT0gbnVsbCA/IGN1cnJlbnQubWVtb2l6ZWRQcm9wcyA6IG5ld1RleHQ7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGNvbW1pdFRleHRVcGRhdGUodGV4dEluc3RhbmNlLCBvbGRUZXh0LCBuZXdUZXh0KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdmFyIHByZXZSb290U3RhdGUgPSBjdXJyZW50Lm1lbW9pemVkU3RhdGU7XG5cbiAgICAgICAgICAgICAgaWYgKHByZXZSb290U3RhdGUuaXNEZWh5ZHJhdGVkKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIGNvbW1pdEh5ZHJhdGVkQ29udGFpbmVyKHJvb3QuY29udGFpbmVySW5mbyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgIHtcbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZU11dGF0aW9uRWZmZWN0cyhyb290LCBmaW5pc2hlZFdvcmspO1xuICAgICAgICBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHMoZmluaXNoZWRXb3JrKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlTXV0YXRpb25FZmZlY3RzKHJvb3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgIGNvbW1pdFJlY29uY2lsaWF0aW9uRWZmZWN0cyhmaW5pc2hlZFdvcmspO1xuICAgICAgICB2YXIgb2Zmc2NyZWVuRmliZXIgPSBmaW5pc2hlZFdvcmsuY2hpbGQ7XG5cbiAgICAgICAgaWYgKG9mZnNjcmVlbkZpYmVyLmZsYWdzICYgVmlzaWJpbGl0eSkge1xuICAgICAgICAgIHZhciBvZmZzY3JlZW5JbnN0YW5jZSA9IG9mZnNjcmVlbkZpYmVyLnN0YXRlTm9kZTtcbiAgICAgICAgICB2YXIgbmV3U3RhdGUgPSBvZmZzY3JlZW5GaWJlci5tZW1vaXplZFN0YXRlO1xuICAgICAgICAgIHZhciBpc0hpZGRlbiA9IG5ld1N0YXRlICE9PSBudWxsOyAvLyBUcmFjayB0aGUgY3VycmVudCBzdGF0ZSBvbiB0aGUgT2Zmc2NyZWVuIGluc3RhbmNlIHNvIHdlIGNhblxuICAgICAgICAgIC8vIHJlYWQgaXQgZHVyaW5nIGFuIGV2ZW50XG5cbiAgICAgICAgICBvZmZzY3JlZW5JbnN0YW5jZS5pc0hpZGRlbiA9IGlzSGlkZGVuO1xuXG4gICAgICAgICAgaWYgKGlzSGlkZGVuKSB7XG4gICAgICAgICAgICB2YXIgd2FzSGlkZGVuID0gb2Zmc2NyZWVuRmliZXIuYWx0ZXJuYXRlICE9PSBudWxsICYmIG9mZnNjcmVlbkZpYmVyLmFsdGVybmF0ZS5tZW1vaXplZFN0YXRlICE9PSBudWxsO1xuXG4gICAgICAgICAgICBpZiAoIXdhc0hpZGRlbikge1xuICAgICAgICAgICAgICAvLyBUT0RPOiBNb3ZlIHRvIHBhc3NpdmUgcGhhc2VcbiAgICAgICAgICAgICAgbWFya0NvbW1pdFRpbWVPZkZhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbW1pdFN1c3BlbnNlQ2FsbGJhY2soZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmluaXNoZWRXb3JrLCBmaW5pc2hlZFdvcmsucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYXR0YWNoU3VzcGVuc2VSZXRyeUxpc3RlbmVycyhmaW5pc2hlZFdvcmspO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBfd2FzSGlkZGVuID0gY3VycmVudCAhPT0gbnVsbCAmJiBjdXJyZW50Lm1lbW9pemVkU3RhdGUgIT09IG51bGw7XG5cbiAgICAgICAgaWYgKCAvLyBUT0RPOiBSZW1vdmUgdGhpcyBkZWFkIGZsYWdcbiAgICAgICAgIGZpbmlzaGVkV29yay5tb2RlICYgQ29uY3VycmVudE1vZGUpIHtcbiAgICAgICAgICAvLyBCZWZvcmUgY29tbWl0dGluZyB0aGUgY2hpbGRyZW4sIHRyYWNrIG9uIHRoZSBzdGFjayB3aGV0aGVyIHRoaXNcbiAgICAgICAgICAvLyBvZmZzY3JlZW4gc3VidHJlZSB3YXMgYWxyZWFkeSBoaWRkZW4sIHNvIHRoYXQgd2UgZG9uJ3QgdW5tb3VudCB0aGVcbiAgICAgICAgICAvLyBlZmZlY3RzIGFnYWluLlxuICAgICAgICAgIHZhciBwcmV2T2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IG9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW47XG4gICAgICAgICAgb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IHByZXZPZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuIHx8IF93YXNIaWRkZW47XG4gICAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZU11dGF0aW9uRWZmZWN0cyhyb290LCBmaW5pc2hlZFdvcmspO1xuICAgICAgICAgIG9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4gPSBwcmV2T2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlTXV0YXRpb25FZmZlY3RzKHJvb3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgIH1cblxuICAgICAgICBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHMoZmluaXNoZWRXb3JrKTtcblxuICAgICAgICBpZiAoZmxhZ3MgJiBWaXNpYmlsaXR5KSB7XG4gICAgICAgICAgdmFyIF9vZmZzY3JlZW5JbnN0YW5jZSA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGU7XG4gICAgICAgICAgdmFyIF9uZXdTdGF0ZSA9IGZpbmlzaGVkV29yay5tZW1vaXplZFN0YXRlO1xuXG4gICAgICAgICAgdmFyIF9pc0hpZGRlbiA9IF9uZXdTdGF0ZSAhPT0gbnVsbDtcblxuICAgICAgICAgIHZhciBvZmZzY3JlZW5Cb3VuZGFyeSA9IGZpbmlzaGVkV29yazsgLy8gVHJhY2sgdGhlIGN1cnJlbnQgc3RhdGUgb24gdGhlIE9mZnNjcmVlbiBpbnN0YW5jZSBzbyB3ZSBjYW5cbiAgICAgICAgICAvLyByZWFkIGl0IGR1cmluZyBhbiBldmVudFxuXG4gICAgICAgICAgX29mZnNjcmVlbkluc3RhbmNlLmlzSGlkZGVuID0gX2lzSGlkZGVuO1xuXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKF9pc0hpZGRlbikge1xuICAgICAgICAgICAgICBpZiAoIV93YXNIaWRkZW4pIHtcbiAgICAgICAgICAgICAgICBpZiAoKG9mZnNjcmVlbkJvdW5kYXJ5Lm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgICAgICAgICAgICAgbmV4dEVmZmVjdCA9IG9mZnNjcmVlbkJvdW5kYXJ5O1xuICAgICAgICAgICAgICAgICAgdmFyIG9mZnNjcmVlbkNoaWxkID0gb2Zmc2NyZWVuQm91bmRhcnkuY2hpbGQ7XG5cbiAgICAgICAgICAgICAgICAgIHdoaWxlIChvZmZzY3JlZW5DaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuZXh0RWZmZWN0ID0gb2Zmc2NyZWVuQ2hpbGQ7XG4gICAgICAgICAgICAgICAgICAgIGRpc2FwcGVhckxheW91dEVmZmVjdHNfYmVnaW4ob2Zmc2NyZWVuQ2hpbGQpO1xuICAgICAgICAgICAgICAgICAgICBvZmZzY3JlZW5DaGlsZCA9IG9mZnNjcmVlbkNoaWxkLnNpYmxpbmc7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAge1xuICAgICAgICAgICAgLy8gVE9ETzogVGhpcyBuZWVkcyB0byBydW4gd2hlbmV2ZXIgdGhlcmUncyBhbiBpbnNlcnRpb24gb3IgdXBkYXRlXG4gICAgICAgICAgICAvLyBpbnNpZGUgYSBoaWRkZW4gT2Zmc2NyZWVuIHRyZWUuXG4gICAgICAgICAgICBoaWRlT3JVbmhpZGVBbGxDaGlsZHJlbihvZmZzY3JlZW5Cb3VuZGFyeSwgX2lzSGlkZGVuKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZU11dGF0aW9uRWZmZWN0cyhyb290LCBmaW5pc2hlZFdvcmspO1xuICAgICAgICBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHMoZmluaXNoZWRXb3JrKTtcblxuICAgICAgICBpZiAoZmxhZ3MgJiBVcGRhdGUpIHtcbiAgICAgICAgICBhdHRhY2hTdXNwZW5zZVJldHJ5TGlzdGVuZXJzKGZpbmlzaGVkV29yayk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICBjYXNlIFNjb3BlQ29tcG9uZW50OlxuICAgICAge1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHMoZmluaXNoZWRXb3JrKSB7XG4gIC8vIFBsYWNlbWVudCBlZmZlY3RzIChpbnNlcnRpb25zLCByZW9yZGVycykgY2FuIGJlIHNjaGVkdWxlZCBvbiBhbnkgZmliZXJcbiAgLy8gdHlwZS4gVGhleSBuZWVkcyB0byBoYXBwZW4gYWZ0ZXIgdGhlIGNoaWxkcmVuIGVmZmVjdHMgaGF2ZSBmaXJlZCwgYnV0XG4gIC8vIGJlZm9yZSB0aGUgZWZmZWN0cyBvbiB0aGlzIGZpYmVyIGhhdmUgZmlyZWQuXG4gIHZhciBmbGFncyA9IGZpbmlzaGVkV29yay5mbGFncztcblxuICBpZiAoZmxhZ3MgJiBQbGFjZW1lbnQpIHtcbiAgICB0cnkge1xuICAgICAgY29tbWl0UGxhY2VtZW50KGZpbmlzaGVkV29yayk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgIH0gLy8gQ2xlYXIgdGhlIFwicGxhY2VtZW50XCIgZnJvbSBlZmZlY3QgdGFnIHNvIHRoYXQgd2Uga25vdyB0aGF0IHRoaXMgaXNcbiAgICAvLyBpbnNlcnRlZCwgYmVmb3JlIGFueSBsaWZlLWN5Y2xlcyBsaWtlIGNvbXBvbmVudERpZE1vdW50IGdldHMgY2FsbGVkLlxuICAgIC8vIFRPRE86IGZpbmRET01Ob2RlIGRvZXNuJ3QgcmVseSBvbiB0aGlzIGFueSBtb3JlIGJ1dCBpc01vdW50ZWQgZG9lc1xuICAgIC8vIGFuZCBpc01vdW50ZWQgaXMgZGVwcmVjYXRlZCBhbnl3YXkgc28gd2Ugc2hvdWxkIGJlIGFibGUgdG8ga2lsbCB0aGlzLlxuXG5cbiAgICBmaW5pc2hlZFdvcmsuZmxhZ3MgJj0gflBsYWNlbWVudDtcbiAgfVxuXG4gIGlmIChmbGFncyAmIEh5ZHJhdGluZykge1xuICAgIGZpbmlzaGVkV29yay5mbGFncyAmPSB+SHlkcmF0aW5nO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdExheW91dEVmZmVjdHMoZmluaXNoZWRXb3JrLCByb290LCBjb21taXR0ZWRMYW5lcykge1xuICBpblByb2dyZXNzTGFuZXMgPSBjb21taXR0ZWRMYW5lcztcbiAgaW5Qcm9ncmVzc1Jvb3QgPSByb290O1xuICBuZXh0RWZmZWN0ID0gZmluaXNoZWRXb3JrO1xuICBjb21taXRMYXlvdXRFZmZlY3RzX2JlZ2luKGZpbmlzaGVkV29yaywgcm9vdCwgY29tbWl0dGVkTGFuZXMpO1xuICBpblByb2dyZXNzTGFuZXMgPSBudWxsO1xuICBpblByb2dyZXNzUm9vdCA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGNvbW1pdExheW91dEVmZmVjdHNfYmVnaW4oc3VidHJlZVJvb3QsIHJvb3QsIGNvbW1pdHRlZExhbmVzKSB7XG4gIC8vIFN1c3BlbnNlIGxheW91dCBlZmZlY3RzIHNlbWFudGljcyBkb24ndCBjaGFuZ2UgZm9yIGxlZ2FjeSByb290cy5cbiAgdmFyIGlzTW9kZXJuUm9vdCA9IChzdWJ0cmVlUm9vdC5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG5cbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0O1xuICAgIHZhciBmaXJzdENoaWxkID0gZmliZXIuY2hpbGQ7XG5cbiAgICBpZiAoIGZpYmVyLnRhZyA9PT0gT2Zmc2NyZWVuQ29tcG9uZW50ICYmIGlzTW9kZXJuUm9vdCkge1xuICAgICAgLy8gS2VlcCB0cmFjayBvZiB0aGUgY3VycmVudCBPZmZzY3JlZW4gc3RhY2sncyBzdGF0ZS5cbiAgICAgIHZhciBpc0hpZGRlbiA9IGZpYmVyLm1lbW9pemVkU3RhdGUgIT09IG51bGw7XG4gICAgICB2YXIgbmV3T2Zmc2NyZWVuU3VidHJlZUlzSGlkZGVuID0gaXNIaWRkZW4gfHwgb2Zmc2NyZWVuU3VidHJlZUlzSGlkZGVuO1xuXG4gICAgICBpZiAobmV3T2Zmc2NyZWVuU3VidHJlZUlzSGlkZGVuKSB7XG4gICAgICAgIC8vIFRoZSBPZmZzY3JlZW4gdHJlZSBpcyBoaWRkZW4uIFNraXAgb3ZlciBpdHMgbGF5b3V0IGVmZmVjdHMuXG4gICAgICAgIGNvbW1pdExheW91dE1vdW50RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCwgcm9vdCwgY29tbWl0dGVkTGFuZXMpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRPRE8gKE9mZnNjcmVlbikgQWxzbyBjaGVjazogc3VidHJlZUZsYWdzICYgTGF5b3V0TWFza1xuICAgICAgICB2YXIgY3VycmVudCA9IGZpYmVyLmFsdGVybmF0ZTtcbiAgICAgICAgdmFyIHdhc0hpZGRlbiA9IGN1cnJlbnQgIT09IG51bGwgJiYgY3VycmVudC5tZW1vaXplZFN0YXRlICE9PSBudWxsO1xuICAgICAgICB2YXIgbmV3T2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IHdhc0hpZGRlbiB8fCBvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuO1xuICAgICAgICB2YXIgcHJldk9mZnNjcmVlblN1YnRyZWVJc0hpZGRlbiA9IG9mZnNjcmVlblN1YnRyZWVJc0hpZGRlbjtcbiAgICAgICAgdmFyIHByZXZPZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuID0gb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbjsgLy8gVHJhdmVyc2UgdGhlIE9mZnNjcmVlbiBzdWJ0cmVlIHdpdGggdGhlIGN1cnJlbnQgT2Zmc2NyZWVuIGFzIHRoZSByb290LlxuXG4gICAgICAgIG9mZnNjcmVlblN1YnRyZWVJc0hpZGRlbiA9IG5ld09mZnNjcmVlblN1YnRyZWVJc0hpZGRlbjtcbiAgICAgICAgb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IG5ld09mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW47XG5cbiAgICAgICAgaWYgKG9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4gJiYgIXByZXZPZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuKSB7XG4gICAgICAgICAgLy8gVGhpcyBpcyB0aGUgcm9vdCBvZiBhIHJlYXBwZWFyaW5nIGJvdW5kYXJ5LiBUdXJuIGl0cyBsYXlvdXQgZWZmZWN0c1xuICAgICAgICAgIC8vIGJhY2sgb24uXG4gICAgICAgICAgbmV4dEVmZmVjdCA9IGZpYmVyO1xuICAgICAgICAgIHJlYXBwZWFyTGF5b3V0RWZmZWN0c19iZWdpbihmaWJlcik7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY2hpbGQgPSBmaXJzdENoaWxkO1xuXG4gICAgICAgIHdoaWxlIChjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICAgIG5leHRFZmZlY3QgPSBjaGlsZDtcbiAgICAgICAgICBjb21taXRMYXlvdXRFZmZlY3RzX2JlZ2luKGNoaWxkLCAvLyBOZXcgcm9vdDsgYnViYmxlIGJhY2sgdXAgdG8gaGVyZSBhbmQgc3RvcC5cbiAgICAgICAgICByb290LCBjb21taXR0ZWRMYW5lcyk7XG4gICAgICAgICAgY2hpbGQgPSBjaGlsZC5zaWJsaW5nO1xuICAgICAgICB9IC8vIFJlc3RvcmUgT2Zmc2NyZWVuIHN0YXRlIGFuZCByZXN1bWUgaW4gb3VyLXByb2dyZXNzIHRyYXZlcnNhbC5cblxuXG4gICAgICAgIG5leHRFZmZlY3QgPSBmaWJlcjtcbiAgICAgICAgb2Zmc2NyZWVuU3VidHJlZUlzSGlkZGVuID0gcHJldk9mZnNjcmVlblN1YnRyZWVJc0hpZGRlbjtcbiAgICAgICAgb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IHByZXZPZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuO1xuICAgICAgICBjb21taXRMYXlvdXRNb3VudEVmZmVjdHNfY29tcGxldGUoc3VidHJlZVJvb3QsIHJvb3QsIGNvbW1pdHRlZExhbmVzKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKChmaWJlci5zdWJ0cmVlRmxhZ3MgJiBMYXlvdXRNYXNrKSAhPT0gTm9GbGFncyAmJiBmaXJzdENoaWxkICE9PSBudWxsKSB7XG4gICAgICBmaXJzdENoaWxkLnJldHVybiA9IGZpYmVyO1xuICAgICAgbmV4dEVmZmVjdCA9IGZpcnN0Q2hpbGQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbW1pdExheW91dE1vdW50RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCwgcm9vdCwgY29tbWl0dGVkTGFuZXMpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRMYXlvdXRNb3VudEVmZmVjdHNfY29tcGxldGUoc3VidHJlZVJvb3QsIHJvb3QsIGNvbW1pdHRlZExhbmVzKSB7XG4gIHdoaWxlIChuZXh0RWZmZWN0ICE9PSBudWxsKSB7XG4gICAgdmFyIGZpYmVyID0gbmV4dEVmZmVjdDtcblxuICAgIGlmICgoZmliZXIuZmxhZ3MgJiBMYXlvdXRNYXNrKSAhPT0gTm9GbGFncykge1xuICAgICAgdmFyIGN1cnJlbnQgPSBmaWJlci5hbHRlcm5hdGU7XG4gICAgICBzZXRDdXJyZW50RmliZXIoZmliZXIpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb21taXRMYXlvdXRFZmZlY3RPbkZpYmVyKHJvb3QsIGN1cnJlbnQsIGZpYmVyLCBjb21taXR0ZWRMYW5lcyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaWJlciwgZmliZXIucmV0dXJuLCBlcnJvcik7XG4gICAgICB9XG5cbiAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgfVxuXG4gICAgaWYgKGZpYmVyID09PSBzdWJ0cmVlUm9vdCkge1xuICAgICAgbmV4dEVmZmVjdCA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gZmliZXIucmV0dXJuO1xuICAgICAgbmV4dEVmZmVjdCA9IHNpYmxpbmc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dEVmZmVjdCA9IGZpYmVyLnJldHVybjtcbiAgfVxufVxuXG5mdW5jdGlvbiBkaXNhcHBlYXJMYXlvdXRFZmZlY3RzX2JlZ2luKHN1YnRyZWVSb290KSB7XG4gIHdoaWxlIChuZXh0RWZmZWN0ICE9PSBudWxsKSB7XG4gICAgdmFyIGZpYmVyID0gbmV4dEVmZmVjdDtcbiAgICB2YXIgZmlyc3RDaGlsZCA9IGZpYmVyLmNoaWxkOyAvLyBUT0RPIChPZmZzY3JlZW4pIENoZWNrOiBmbGFncyAmIChSZWZTdGF0aWMgfCBMYXlvdXRTdGF0aWMpXG5cbiAgICBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIGNhc2UgTWVtb0NvbXBvbmVudDpcbiAgICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIGlmICggZmliZXIubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzdGFydExheW91dEVmZmVjdFRpbWVyKCk7XG4gICAgICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChMYXlvdXQsIGZpYmVyLCBmaWJlci5yZXR1cm4pO1xuICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgcmVjb3JkTGF5b3V0RWZmZWN0RHVyYXRpb24oZmliZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoTGF5b3V0LCBmaWJlciwgZmliZXIucmV0dXJuKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgLy8gVE9ETyAoT2Zmc2NyZWVuKSBDaGVjazogZmxhZ3MgJiBSZWZTdGF0aWNcbiAgICAgICAgICBzYWZlbHlEZXRhY2hSZWYoZmliZXIsIGZpYmVyLnJldHVybik7XG4gICAgICAgICAgdmFyIGluc3RhbmNlID0gZmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsVW5tb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgc2FmZWx5Q2FsbENvbXBvbmVudFdpbGxVbm1vdW50KGZpYmVyLCBmaWJlci5yZXR1cm4sIGluc3RhbmNlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICBzYWZlbHlEZXRhY2hSZWYoZmliZXIsIGZpYmVyLnJldHVybik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIGFcbiAgICAgICAgICB2YXIgaXNIaWRkZW4gPSBmaWJlci5tZW1vaXplZFN0YXRlICE9PSBudWxsO1xuXG4gICAgICAgICAgaWYgKGlzSGlkZGVuKSB7XG4gICAgICAgICAgICAvLyBOZXN0ZWQgT2Zmc2NyZWVuIHRyZWUgaXMgYWxyZWFkeSBoaWRkZW4uIERvbid0IGRpc2FwcGVhclxuICAgICAgICAgICAgLy8gaXRzIGVmZmVjdHMuXG4gICAgICAgICAgICBkaXNhcHBlYXJMYXlvdXRFZmZlY3RzX2NvbXBsZXRlKHN1YnRyZWVSb290KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfSAvLyBUT0RPIChPZmZzY3JlZW4pIENoZWNrOiBzdWJ0cmVlRmxhZ3MgJiBMYXlvdXRTdGF0aWNcblxuXG4gICAgaWYgKGZpcnN0Q2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGZpcnN0Q2hpbGQucmV0dXJuID0gZmliZXI7XG4gICAgICBuZXh0RWZmZWN0ID0gZmlyc3RDaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgZGlzYXBwZWFyTGF5b3V0RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGRpc2FwcGVhckxheW91dEVmZmVjdHNfY29tcGxldGUoc3VidHJlZVJvb3QpIHtcbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0O1xuXG4gICAgaWYgKGZpYmVyID09PSBzdWJ0cmVlUm9vdCkge1xuICAgICAgbmV4dEVmZmVjdCA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gZmliZXIucmV0dXJuO1xuICAgICAgbmV4dEVmZmVjdCA9IHNpYmxpbmc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dEVmZmVjdCA9IGZpYmVyLnJldHVybjtcbiAgfVxufVxuXG5mdW5jdGlvbiByZWFwcGVhckxheW91dEVmZmVjdHNfYmVnaW4oc3VidHJlZVJvb3QpIHtcbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0O1xuICAgIHZhciBmaXJzdENoaWxkID0gZmliZXIuY2hpbGQ7XG5cbiAgICBpZiAoZmliZXIudGFnID09PSBPZmZzY3JlZW5Db21wb25lbnQpIHtcbiAgICAgIHZhciBpc0hpZGRlbiA9IGZpYmVyLm1lbW9pemVkU3RhdGUgIT09IG51bGw7XG5cbiAgICAgIGlmIChpc0hpZGRlbikge1xuICAgICAgICAvLyBOZXN0ZWQgT2Zmc2NyZWVuIHRyZWUgaXMgc3RpbGwgaGlkZGVuLiBEb24ndCByZS1hcHBlYXIgaXRzIGVmZmVjdHMuXG4gICAgICAgIHJlYXBwZWFyTGF5b3V0RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH0gLy8gVE9ETyAoT2Zmc2NyZWVuKSBDaGVjazogc3VidHJlZUZsYWdzICYgTGF5b3V0U3RhdGljXG5cblxuICAgIGlmIChmaXJzdENoaWxkICE9PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIG5vZGUgbWF5IGhhdmUgYmVlbiByZXVzZWQgZnJvbSBhIHByZXZpb3VzIHJlbmRlciwgc28gd2UgY2FuJ3RcbiAgICAgIC8vIGFzc3VtZSBpdHMgcmV0dXJuIHBvaW50ZXIgaXMgY29ycmVjdC5cbiAgICAgIGZpcnN0Q2hpbGQucmV0dXJuID0gZmliZXI7XG4gICAgICBuZXh0RWZmZWN0ID0gZmlyc3RDaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVhcHBlYXJMYXlvdXRFZmZlY3RzX2NvbXBsZXRlKHN1YnRyZWVSb290KTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVhcHBlYXJMYXlvdXRFZmZlY3RzX2NvbXBsZXRlKHN1YnRyZWVSb290KSB7XG4gIHdoaWxlIChuZXh0RWZmZWN0ICE9PSBudWxsKSB7XG4gICAgdmFyIGZpYmVyID0gbmV4dEVmZmVjdDsgLy8gVE9ETyAoT2Zmc2NyZWVuKSBDaGVjazogZmxhZ3MgJiBMYXlvdXRTdGF0aWNcblxuICAgIHNldEN1cnJlbnRGaWJlcihmaWJlcik7XG5cbiAgICB0cnkge1xuICAgICAgcmVhcHBlYXJMYXlvdXRFZmZlY3RzT25GaWJlcihmaWJlcik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpYmVyLCBmaWJlci5yZXR1cm4sIGVycm9yKTtcbiAgICB9XG5cbiAgICByZXNldEN1cnJlbnRGaWJlcigpO1xuXG4gICAgaWYgKGZpYmVyID09PSBzdWJ0cmVlUm9vdCkge1xuICAgICAgbmV4dEVmZmVjdCA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIC8vIFRoaXMgbm9kZSBtYXkgaGF2ZSBiZWVuIHJldXNlZCBmcm9tIGEgcHJldmlvdXMgcmVuZGVyLCBzbyB3ZSBjYW4ndFxuICAgICAgLy8gYXNzdW1lIGl0cyByZXR1cm4gcG9pbnRlciBpcyBjb3JyZWN0LlxuICAgICAgc2libGluZy5yZXR1cm4gPSBmaWJlci5yZXR1cm47XG4gICAgICBuZXh0RWZmZWN0ID0gc2libGluZztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBuZXh0RWZmZWN0ID0gZmliZXIucmV0dXJuO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVNb3VudEVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrLCBjb21taXR0ZWRMYW5lcywgY29tbWl0dGVkVHJhbnNpdGlvbnMpIHtcbiAgbmV4dEVmZmVjdCA9IGZpbmlzaGVkV29yaztcbiAgY29tbWl0UGFzc2l2ZU1vdW50RWZmZWN0c19iZWdpbihmaW5pc2hlZFdvcmssIHJvb3QsIGNvbW1pdHRlZExhbmVzLCBjb21taXR0ZWRUcmFuc2l0aW9ucyk7XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVNb3VudEVmZmVjdHNfYmVnaW4oc3VidHJlZVJvb3QsIHJvb3QsIGNvbW1pdHRlZExhbmVzLCBjb21taXR0ZWRUcmFuc2l0aW9ucykge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7XG4gICAgdmFyIGZpcnN0Q2hpbGQgPSBmaWJlci5jaGlsZDtcblxuICAgIGlmICgoZmliZXIuc3VidHJlZUZsYWdzICYgUGFzc2l2ZU1hc2spICE9PSBOb0ZsYWdzICYmIGZpcnN0Q2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGZpcnN0Q2hpbGQucmV0dXJuID0gZmliZXI7XG4gICAgICBuZXh0RWZmZWN0ID0gZmlyc3RDaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tbWl0UGFzc2l2ZU1vdW50RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCwgcm9vdCwgY29tbWl0dGVkTGFuZXMsIGNvbW1pdHRlZFRyYW5zaXRpb25zKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0UGFzc2l2ZU1vdW50RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCwgcm9vdCwgY29tbWl0dGVkTGFuZXMsIGNvbW1pdHRlZFRyYW5zaXRpb25zKSB7XG4gIHdoaWxlIChuZXh0RWZmZWN0ICE9PSBudWxsKSB7XG4gICAgdmFyIGZpYmVyID0gbmV4dEVmZmVjdDtcblxuICAgIGlmICgoZmliZXIuZmxhZ3MgJiBQYXNzaXZlKSAhPT0gTm9GbGFncykge1xuICAgICAgc2V0Q3VycmVudEZpYmVyKGZpYmVyKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29tbWl0UGFzc2l2ZU1vdW50T25GaWJlcihyb290LCBmaWJlciwgY29tbWl0dGVkTGFuZXMsIGNvbW1pdHRlZFRyYW5zaXRpb25zKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpYmVyLCBmaWJlci5yZXR1cm4sIGVycm9yKTtcbiAgICAgIH1cblxuICAgICAgcmVzZXRDdXJyZW50RmliZXIoKTtcbiAgICB9XG5cbiAgICBpZiAoZmliZXIgPT09IHN1YnRyZWVSb290KSB7XG4gICAgICBuZXh0RWZmZWN0ID0gbnVsbDtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgc2libGluZyA9IGZpYmVyLnNpYmxpbmc7XG5cbiAgICBpZiAoc2libGluZyAhPT0gbnVsbCkge1xuICAgICAgc2libGluZy5yZXR1cm4gPSBmaWJlci5yZXR1cm47XG4gICAgICBuZXh0RWZmZWN0ID0gc2libGluZztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBuZXh0RWZmZWN0ID0gZmliZXIucmV0dXJuO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVNb3VudE9uRmliZXIoZmluaXNoZWRSb290LCBmaW5pc2hlZFdvcmssIGNvbW1pdHRlZExhbmVzLCBjb21taXR0ZWRUcmFuc2l0aW9ucykge1xuICBzd2l0Y2ggKGZpbmlzaGVkV29yay50YWcpIHtcbiAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIGlmICggZmluaXNoZWRXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkge1xuICAgICAgICAgIHN0YXJ0UGFzc2l2ZUVmZmVjdFRpbWVyKCk7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29tbWl0SG9va0VmZmVjdExpc3RNb3VudChQYXNzaXZlJDEgfCBIYXNFZmZlY3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHJlY29yZFBhc3NpdmVFZmZlY3REdXJhdGlvbihmaW5pc2hlZFdvcmspO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KFBhc3NpdmUkMSB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVVbm1vdW50RWZmZWN0cyhmaXJzdENoaWxkKSB7XG4gIG5leHRFZmZlY3QgPSBmaXJzdENoaWxkO1xuICBjb21taXRQYXNzaXZlVW5tb3VudEVmZmVjdHNfYmVnaW4oKTtcbn1cblxuZnVuY3Rpb24gY29tbWl0UGFzc2l2ZVVubW91bnRFZmZlY3RzX2JlZ2luKCkge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7XG4gICAgdmFyIGNoaWxkID0gZmliZXIuY2hpbGQ7XG5cbiAgICBpZiAoKG5leHRFZmZlY3QuZmxhZ3MgJiBDaGlsZERlbGV0aW9uKSAhPT0gTm9GbGFncykge1xuICAgICAgdmFyIGRlbGV0aW9ucyA9IGZpYmVyLmRlbGV0aW9ucztcblxuICAgICAgaWYgKGRlbGV0aW9ucyAhPT0gbnVsbCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRlbGV0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBmaWJlclRvRGVsZXRlID0gZGVsZXRpb25zW2ldO1xuICAgICAgICAgIG5leHRFZmZlY3QgPSBmaWJlclRvRGVsZXRlO1xuICAgICAgICAgIGNvbW1pdFBhc3NpdmVVbm1vdW50RWZmZWN0c0luc2lkZU9mRGVsZXRlZFRyZWVfYmVnaW4oZmliZXJUb0RlbGV0ZSwgZmliZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAge1xuICAgICAgICAgIC8vIEEgZmliZXIgd2FzIGRlbGV0ZWQgZnJvbSB0aGlzIHBhcmVudCBmaWJlciwgYnV0IGl0J3Mgc3RpbGwgcGFydCBvZlxuICAgICAgICAgIC8vIHRoZSBwcmV2aW91cyAoYWx0ZXJuYXRlKSBwYXJlbnQgZmliZXIncyBsaXN0IG9mIGNoaWxkcmVuLiBCZWNhdXNlXG4gICAgICAgICAgLy8gY2hpbGRyZW4gYXJlIGEgbGlua2VkIGxpc3QsIGFuIGVhcmxpZXIgc2libGluZyB0aGF0J3Mgc3RpbGwgYWxpdmVcbiAgICAgICAgICAvLyB3aWxsIGJlIGNvbm5lY3RlZCB0byB0aGUgZGVsZXRlZCBmaWJlciB2aWEgaXRzIGBhbHRlcm5hdGVgOlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gICBsaXZlIGZpYmVyXG4gICAgICAgICAgLy8gICAtLWFsdGVybmF0ZS0tPiBwcmV2aW91cyBsaXZlIGZpYmVyXG4gICAgICAgICAgLy8gICAtLXNpYmxpbmctLT4gZGVsZXRlZCBmaWJlclxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gV2UgY2FuJ3QgZGlzY29ubmVjdCBgYWx0ZXJuYXRlYCBvbiBub2RlcyB0aGF0IGhhdmVuJ3QgYmVlbiBkZWxldGVkXG4gICAgICAgICAgLy8geWV0LCBidXQgd2UgY2FuIGRpc2Nvbm5lY3QgdGhlIGBzaWJsaW5nYCBhbmQgYGNoaWxkYCBwb2ludGVycy5cbiAgICAgICAgICB2YXIgcHJldmlvdXNGaWJlciA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICAgICAgICAgIGlmIChwcmV2aW91c0ZpYmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgZGV0YWNoZWRDaGlsZCA9IHByZXZpb3VzRmliZXIuY2hpbGQ7XG5cbiAgICAgICAgICAgIGlmIChkZXRhY2hlZENoaWxkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgIHByZXZpb3VzRmliZXIuY2hpbGQgPSBudWxsO1xuXG4gICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICB2YXIgZGV0YWNoZWRTaWJsaW5nID0gZGV0YWNoZWRDaGlsZC5zaWJsaW5nO1xuICAgICAgICAgICAgICAgIGRldGFjaGVkQ2hpbGQuc2libGluZyA9IG51bGw7XG4gICAgICAgICAgICAgICAgZGV0YWNoZWRDaGlsZCA9IGRldGFjaGVkU2libGluZztcbiAgICAgICAgICAgICAgfSB3aGlsZSAoZGV0YWNoZWRDaGlsZCAhPT0gbnVsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbmV4dEVmZmVjdCA9IGZpYmVyO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICgoZmliZXIuc3VidHJlZUZsYWdzICYgUGFzc2l2ZU1hc2spICE9PSBOb0ZsYWdzICYmIGNoaWxkICE9PSBudWxsKSB7XG4gICAgICBjaGlsZC5yZXR1cm4gPSBmaWJlcjtcbiAgICAgIG5leHRFZmZlY3QgPSBjaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tbWl0UGFzc2l2ZVVubW91bnRFZmZlY3RzX2NvbXBsZXRlKCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVVbm1vdW50RWZmZWN0c19jb21wbGV0ZSgpIHtcbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0O1xuXG4gICAgaWYgKChmaWJlci5mbGFncyAmIFBhc3NpdmUpICE9PSBOb0ZsYWdzKSB7XG4gICAgICBzZXRDdXJyZW50RmliZXIoZmliZXIpO1xuICAgICAgY29tbWl0UGFzc2l2ZVVubW91bnRPbkZpYmVyKGZpYmVyKTtcbiAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gZmliZXIucmV0dXJuO1xuICAgICAgbmV4dEVmZmVjdCA9IHNpYmxpbmc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dEVmZmVjdCA9IGZpYmVyLnJldHVybjtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRQYXNzaXZlVW5tb3VudE9uRmliZXIoZmluaXNoZWRXb3JrKSB7XG4gIHN3aXRjaCAoZmluaXNoZWRXb3JrLnRhZykge1xuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgaWYgKCBmaW5pc2hlZFdvcmsubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgc3RhcnRQYXNzaXZlRWZmZWN0VGltZXIoKTtcbiAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoUGFzc2l2ZSQxIHwgSGFzRWZmZWN0LCBmaW5pc2hlZFdvcmssIGZpbmlzaGVkV29yay5yZXR1cm4pO1xuICAgICAgICAgIHJlY29yZFBhc3NpdmVFZmZlY3REdXJhdGlvbihmaW5pc2hlZFdvcmspO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChQYXNzaXZlJDEgfCBIYXNFZmZlY3QsIGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybik7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRQYXNzaXZlVW5tb3VudEVmZmVjdHNJbnNpZGVPZkRlbGV0ZWRUcmVlX2JlZ2luKGRlbGV0ZWRTdWJ0cmVlUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcikge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7IC8vIERlbGV0aW9uIGVmZmVjdHMgZmlyZSBpbiBwYXJlbnQgLT4gY2hpbGQgb3JkZXJcbiAgICAvLyBUT0RPOiBDaGVjayBpZiBmaWJlciBoYXMgYSBQYXNzaXZlU3RhdGljIGZsYWdcblxuICAgIHNldEN1cnJlbnRGaWJlcihmaWJlcik7XG4gICAgY29tbWl0UGFzc2l2ZVVubW91bnRJbnNpZGVEZWxldGVkVHJlZU9uRmliZXIoZmliZXIsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IpO1xuICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgdmFyIGNoaWxkID0gZmliZXIuY2hpbGQ7IC8vIFRPRE86IE9ubHkgdHJhdmVyc2Ugc3VidHJlZSBpZiBpdCBoYXMgYSBQYXNzaXZlU3RhdGljIGZsYWcuIChCdXQsIGlmIHdlXG4gICAgLy8gZG8gdGhpcywgc3RpbGwgbmVlZCB0byBoYW5kbGUgYGRlbGV0ZWRUcmVlQ2xlYW5VcExldmVsYCBjb3JyZWN0bHkuKVxuXG4gICAgaWYgKGNoaWxkICE9PSBudWxsKSB7XG4gICAgICBjaGlsZC5yZXR1cm4gPSBmaWJlcjtcbiAgICAgIG5leHRFZmZlY3QgPSBjaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tbWl0UGFzc2l2ZVVubW91bnRFZmZlY3RzSW5zaWRlT2ZEZWxldGVkVHJlZV9jb21wbGV0ZShkZWxldGVkU3VidHJlZVJvb3QpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRQYXNzaXZlVW5tb3VudEVmZmVjdHNJbnNpZGVPZkRlbGV0ZWRUcmVlX2NvbXBsZXRlKGRlbGV0ZWRTdWJ0cmVlUm9vdCkge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7XG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuICAgIHZhciByZXR1cm5GaWJlciA9IGZpYmVyLnJldHVybjtcblxuICAgIHtcbiAgICAgIC8vIFJlY3Vyc2l2ZWx5IHRyYXZlcnNlIHRoZSBlbnRpcmUgZGVsZXRlZCB0cmVlIGFuZCBjbGVhbiB1cCBmaWJlciBmaWVsZHMuXG4gICAgICAvLyBUaGlzIGlzIG1vcmUgYWdncmVzc2l2ZSB0aGFuIGlkZWFsLCBhbmQgdGhlIGxvbmcgdGVybSBnb2FsIGlzIHRvIG9ubHlcbiAgICAgIC8vIGhhdmUgdG8gZGV0YWNoIHRoZSBkZWxldGVkIHRyZWUgYXQgdGhlIHJvb3QuXG4gICAgICBkZXRhY2hGaWJlckFmdGVyRWZmZWN0cyhmaWJlcik7XG5cbiAgICAgIGlmIChmaWJlciA9PT0gZGVsZXRlZFN1YnRyZWVSb290KSB7XG4gICAgICAgIG5leHRFZmZlY3QgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICBuZXh0RWZmZWN0ID0gc2libGluZztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBuZXh0RWZmZWN0ID0gcmV0dXJuRmliZXI7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0UGFzc2l2ZVVubW91bnRJbnNpZGVEZWxldGVkVHJlZU9uRmliZXIoY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcikge1xuICBzd2l0Y2ggKGN1cnJlbnQudGFnKSB7XG4gICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBpZiAoIGN1cnJlbnQubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgc3RhcnRQYXNzaXZlRWZmZWN0VGltZXIoKTtcbiAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoUGFzc2l2ZSQxLCBjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yKTtcbiAgICAgICAgICByZWNvcmRQYXNzaXZlRWZmZWN0RHVyYXRpb24oY3VycmVudCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29tbWl0SG9va0VmZmVjdExpc3RVbm1vdW50KFBhc3NpdmUkMSwgY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcik7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgfVxufSAvLyBUT0RPOiBSZXVzZSByZWFwcGVhckxheW91dEVmZmVjdHMgdHJhdmVyc2FsIGhlcmU/XG5cblxuZnVuY3Rpb24gaW52b2tlTGF5b3V0RWZmZWN0TW91bnRJbkRFVihmaWJlcikge1xuICB7XG4gICAgLy8gV2UgZG9uJ3QgbmVlZCB0byByZS1jaGVjayBTdHJpY3RFZmZlY3RzTW9kZSBoZXJlLlxuICAgIC8vIFRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWQgaWYgdGhhdCBjaGVjayBoYXMgYWxyZWFkeSBwYXNzZWQuXG4gICAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29tbWl0SG9va0VmZmVjdExpc3RNb3VudChMYXlvdXQgfCBIYXNFZmZlY3QsIGZpYmVyKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmliZXIsIGZpYmVyLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgaW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGU7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQoKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmliZXIsIGZpYmVyLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGludm9rZVBhc3NpdmVFZmZlY3RNb3VudEluREVWKGZpYmVyKSB7XG4gIHtcbiAgICAvLyBXZSBkb24ndCBuZWVkIHRvIHJlLWNoZWNrIFN0cmljdEVmZmVjdHNNb2RlIGhlcmUuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBvbmx5IGNhbGxlZCBpZiB0aGF0IGNoZWNrIGhhcyBhbHJlYWR5IHBhc3NlZC5cbiAgICBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KFBhc3NpdmUkMSB8IEhhc0VmZmVjdCwgZmliZXIpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaWJlciwgZmliZXIucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaW52b2tlTGF5b3V0RWZmZWN0VW5tb3VudEluREVWKGZpYmVyKSB7XG4gIHtcbiAgICAvLyBXZSBkb24ndCBuZWVkIHRvIHJlLWNoZWNrIFN0cmljdEVmZmVjdHNNb2RlIGhlcmUuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBvbmx5IGNhbGxlZCBpZiB0aGF0IGNoZWNrIGhhcyBhbHJlYWR5IHBhc3NlZC5cbiAgICBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoTGF5b3V0IHwgSGFzRWZmZWN0LCBmaWJlciwgZmliZXIucmV0dXJuKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmliZXIsIGZpYmVyLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgaW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGU7XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVbm1vdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBzYWZlbHlDYWxsQ29tcG9uZW50V2lsbFVubW91bnQoZmliZXIsIGZpYmVyLnJldHVybiwgaW5zdGFuY2UpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGludm9rZVBhc3NpdmVFZmZlY3RVbm1vdW50SW5ERVYoZmliZXIpIHtcbiAge1xuICAgIC8vIFdlIGRvbid0IG5lZWQgdG8gcmUtY2hlY2sgU3RyaWN0RWZmZWN0c01vZGUgaGVyZS5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIG9ubHkgY2FsbGVkIGlmIHRoYXQgY2hlY2sgaGFzIGFscmVhZHkgcGFzc2VkLlxuICAgIHN3aXRjaCAoZmliZXIudGFnKSB7XG4gICAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChQYXNzaXZlJDEgfCBIYXNFZmZlY3QsIGZpYmVyLCBmaWJlci5yZXR1cm4pO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaWJlciwgZmliZXIucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBDT01QT05FTlRfVFlQRSA9IDA7XG52YXIgSEFTX1BTRVVET19DTEFTU19UWVBFID0gMTtcbnZhciBST0xFX1RZUEUgPSAyO1xudmFyIFRFU1RfTkFNRV9UWVBFID0gMztcbnZhciBURVhUX1RZUEUgPSA0O1xuXG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wuZm9yKSB7XG4gIHZhciBzeW1ib2xGb3IgPSBTeW1ib2wuZm9yO1xuICBDT01QT05FTlRfVFlQRSA9IHN5bWJvbEZvcignc2VsZWN0b3IuY29tcG9uZW50Jyk7XG4gIEhBU19QU0VVRE9fQ0xBU1NfVFlQRSA9IHN5bWJvbEZvcignc2VsZWN0b3IuaGFzX3BzZXVkb19jbGFzcycpO1xuICBST0xFX1RZUEUgPSBzeW1ib2xGb3IoJ3NlbGVjdG9yLnJvbGUnKTtcbiAgVEVTVF9OQU1FX1RZUEUgPSBzeW1ib2xGb3IoJ3NlbGVjdG9yLnRlc3RfaWQnKTtcbiAgVEVYVF9UWVBFID0gc3ltYm9sRm9yKCdzZWxlY3Rvci50ZXh0Jyk7XG59XG52YXIgY29tbWl0SG9va3MgPSBbXTtcbmZ1bmN0aW9uIG9uQ29tbWl0Um9vdCQxKCkge1xuICB7XG4gICAgY29tbWl0SG9va3MuZm9yRWFjaChmdW5jdGlvbiAoY29tbWl0SG9vaykge1xuICAgICAgcmV0dXJuIGNvbW1pdEhvb2soKTtcbiAgICB9KTtcbiAgfVxufVxuXG52YXIgUmVhY3RDdXJyZW50QWN0UXVldWUgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRBY3RRdWV1ZTtcbmZ1bmN0aW9uIGlzTGVnYWN5QWN0RW52aXJvbm1lbnQoZmliZXIpIHtcbiAge1xuICAgIC8vIExlZ2FjeSBtb2RlLiBXZSBwcmVzZXJ2ZSB0aGUgYmVoYXZpb3Igb2YgUmVhY3QgMTcncyBhY3QuIEl0IGFzc3VtZXMgYW5cbiAgICAvLyBhY3QgZW52aXJvbm1lbnQgd2hlbmV2ZXIgYGplc3RgIGlzIGRlZmluZWQsIGJ1dCB5b3UgY2FuIHN0aWxsIHR1cm4gb2ZmXG4gICAgLy8gc3B1cmlvdXMgd2FybmluZ3MgYnkgc2V0dGluZyBJU19SRUFDVF9BQ1RfRU5WSVJPTk1FTlQgZXhwbGljaXRseVxuICAgIC8vIHRvIGZhbHNlLlxuICAgIHZhciBpc1JlYWN0QWN0RW52aXJvbm1lbnRHbG9iYWwgPSAvLyAkRmxvd0V4cGVjdGVkRXJyb3Ig4oCTIEZsb3cgZG9lc24ndCBrbm93IGFib3V0IElTX1JFQUNUX0FDVF9FTlZJUk9OTUVOVCBnbG9iYWxcbiAgICB0eXBlb2YgSVNfUkVBQ1RfQUNUX0VOVklST05NRU5UICE9PSAndW5kZWZpbmVkJyA/IElTX1JFQUNUX0FDVF9FTlZJUk9OTUVOVCA6IHVuZGVmaW5lZDsgLy8gJEZsb3dFeHBlY3RlZEVycm9yIC0gRmxvdyBkb2Vzbid0IGtub3cgYWJvdXQgamVzdFxuXG4gICAgdmFyIGplc3RJc0RlZmluZWQgPSB0eXBlb2YgamVzdCAhPT0gJ3VuZGVmaW5lZCc7XG4gICAgcmV0dXJuICBqZXN0SXNEZWZpbmVkICYmIGlzUmVhY3RBY3RFbnZpcm9ubWVudEdsb2JhbCAhPT0gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIGlzQ29uY3VycmVudEFjdEVudmlyb25tZW50KCkge1xuICB7XG4gICAgdmFyIGlzUmVhY3RBY3RFbnZpcm9ubWVudEdsb2JhbCA9IC8vICRGbG93RXhwZWN0ZWRFcnJvciDigJMgRmxvdyBkb2Vzbid0IGtub3cgYWJvdXQgSVNfUkVBQ1RfQUNUX0VOVklST05NRU5UIGdsb2JhbFxuICAgIHR5cGVvZiBJU19SRUFDVF9BQ1RfRU5WSVJPTk1FTlQgIT09ICd1bmRlZmluZWQnID8gSVNfUkVBQ1RfQUNUX0VOVklST05NRU5UIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKCFpc1JlYWN0QWN0RW52aXJvbm1lbnRHbG9iYWwgJiYgUmVhY3RDdXJyZW50QWN0UXVldWUuY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgLy8gVE9ETzogSW5jbHVkZSBsaW5rIHRvIHJlbGV2YW50IGRvY3VtZW50YXRpb24gcGFnZS5cbiAgICAgIGVycm9yKCdUaGUgY3VycmVudCB0ZXN0aW5nIGVudmlyb25tZW50IGlzIG5vdCBjb25maWd1cmVkIHRvIHN1cHBvcnQgJyArICdhY3QoLi4uKScpO1xuICAgIH1cblxuICAgIHJldHVybiBpc1JlYWN0QWN0RW52aXJvbm1lbnRHbG9iYWw7XG4gIH1cbn1cblxudmFyIGNlaWwgPSBNYXRoLmNlaWw7XG52YXIgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQyID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3RDdXJyZW50RGlzcGF0Y2hlcixcbiAgICBSZWFjdEN1cnJlbnRPd25lciQyID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3RDdXJyZW50T3duZXIsXG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMyA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLFxuICAgIFJlYWN0Q3VycmVudEFjdFF1ZXVlJDEgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRBY3RRdWV1ZTtcbnZhciBOb0NvbnRleHQgPVxuLyogICAgICAgICAgICAgKi9cbjA7XG52YXIgQmF0Y2hlZENvbnRleHQgPVxuLyogICAgICAgICAgICAgICAqL1xuMTtcbnZhciBSZW5kZXJDb250ZXh0ID1cbi8qICAgICAgICAgICAgICAgICovXG4yO1xudmFyIENvbW1pdENvbnRleHQgPVxuLyogICAgICAgICAgICAgICAgKi9cbjQ7XG52YXIgUm9vdEluUHJvZ3Jlc3MgPSAwO1xudmFyIFJvb3RGYXRhbEVycm9yZWQgPSAxO1xudmFyIFJvb3RFcnJvcmVkID0gMjtcbnZhciBSb290U3VzcGVuZGVkID0gMztcbnZhciBSb290U3VzcGVuZGVkV2l0aERlbGF5ID0gNDtcbnZhciBSb290Q29tcGxldGVkID0gNTtcbnZhciBSb290RGlkTm90Q29tcGxldGUgPSA2OyAvLyBEZXNjcmliZXMgd2hlcmUgd2UgYXJlIGluIHRoZSBSZWFjdCBleGVjdXRpb24gc3RhY2tcblxudmFyIGV4ZWN1dGlvbkNvbnRleHQgPSBOb0NvbnRleHQ7IC8vIFRoZSByb290IHdlJ3JlIHdvcmtpbmcgb25cblxudmFyIHdvcmtJblByb2dyZXNzUm9vdCA9IG51bGw7IC8vIFRoZSBmaWJlciB3ZSdyZSB3b3JraW5nIG9uXG5cbnZhciB3b3JrSW5Qcm9ncmVzcyA9IG51bGw7IC8vIFRoZSBsYW5lcyB3ZSdyZSByZW5kZXJpbmdcblxudmFyIHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzID0gTm9MYW5lczsgLy8gU3RhY2sgdGhhdCBhbGxvd3MgY29tcG9uZW50cyB0byBjaGFuZ2UgdGhlIHJlbmRlciBsYW5lcyBmb3IgaXRzIHN1YnRyZWVcbi8vIFRoaXMgaXMgYSBzdXBlcnNldCBvZiB0aGUgbGFuZXMgd2Ugc3RhcnRlZCB3b3JraW5nIG9uIGF0IHRoZSByb290LiBUaGUgb25seVxuLy8gY2FzZSB3aGVyZSBpdCdzIGRpZmZlcmVudCBmcm9tIGB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lc2AgaXMgd2hlbiB3ZVxuLy8gZW50ZXIgYSBzdWJ0cmVlIHRoYXQgaXMgaGlkZGVuIGFuZCBuZWVkcyB0byBiZSB1bmhpZGRlbjogU3VzcGVuc2UgYW5kXG4vLyBPZmZzY3JlZW4gY29tcG9uZW50LlxuLy9cbi8vIE1vc3QgdGhpbmdzIGluIHRoZSB3b3JrIGxvb3Agc2hvdWxkIGRlYWwgd2l0aCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcy5cbi8vIE1vc3QgdGhpbmdzIGluIGJlZ2luL2NvbXBsZXRlIHBoYXNlcyBzaG91bGQgZGVhbCB3aXRoIHN1YnRyZWVSZW5kZXJMYW5lcy5cblxudmFyIHN1YnRyZWVSZW5kZXJMYW5lcyA9IE5vTGFuZXM7XG52YXIgc3VidHJlZVJlbmRlckxhbmVzQ3Vyc29yID0gY3JlYXRlQ3Vyc29yKE5vTGFuZXMpOyAvLyBXaGV0aGVyIHRvIHJvb3QgY29tcGxldGVkLCBlcnJvcmVkLCBzdXNwZW5kZWQsIGV0Yy5cblxudmFyIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPSBSb290SW5Qcm9ncmVzczsgLy8gQSBmYXRhbCBlcnJvciwgaWYgb25lIGlzIHRocm93blxuXG52YXIgd29ya0luUHJvZ3Jlc3NSb290RmF0YWxFcnJvciA9IG51bGw7IC8vIFwiSW5jbHVkZWRcIiBsYW5lcyByZWZlciB0byBsYW5lcyB0aGF0IHdlcmUgd29ya2VkIG9uIGR1cmluZyB0aGlzIHJlbmRlci4gSXQnc1xuLy8gc2xpZ2h0bHkgZGlmZmVyZW50IHRoYW4gYHJlbmRlckxhbmVzYCBiZWNhdXNlIGByZW5kZXJMYW5lc2AgY2FuIGNoYW5nZSBhcyB5b3Vcbi8vIGVudGVyIGFuZCBleGl0IGFuIE9mZnNjcmVlbiB0cmVlLiBUaGlzIHZhbHVlIGlzIHRoZSBjb21iaW5hdGlvbiBvZiBhbGwgcmVuZGVyXG4vLyBsYW5lcyBmb3IgdGhlIGVudGlyZSByZW5kZXIgcGhhc2UuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RJbmNsdWRlZExhbmVzID0gTm9MYW5lczsgLy8gVGhlIHdvcmsgbGVmdCBvdmVyIGJ5IGNvbXBvbmVudHMgdGhhdCB3ZXJlIHZpc2l0ZWQgZHVyaW5nIHRoaXMgcmVuZGVyLiBPbmx5XG4vLyBpbmNsdWRlcyB1bnByb2Nlc3NlZCB1cGRhdGVzLCBub3Qgd29yayBpbiBiYWlsZWQgb3V0IGNoaWxkcmVuLlxuXG52YXIgd29ya0luUHJvZ3Jlc3NSb290U2tpcHBlZExhbmVzID0gTm9MYW5lczsgLy8gTGFuZXMgdGhhdCB3ZXJlIHVwZGF0ZWQgKGluIGFuIGludGVybGVhdmVkIGV2ZW50KSBkdXJpbmcgdGhpcyByZW5kZXIuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RJbnRlcmxlYXZlZFVwZGF0ZWRMYW5lcyA9IE5vTGFuZXM7IC8vIExhbmVzIHRoYXQgd2VyZSB1cGRhdGVkIGR1cmluZyB0aGUgcmVuZGVyIHBoYXNlICgqbm90KiBhbiBpbnRlcmxlYXZlZCBldmVudCkuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RQaW5nZWRMYW5lcyA9IE5vTGFuZXM7IC8vIEVycm9ycyB0aGF0IGFyZSB0aHJvd24gZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RDb25jdXJyZW50RXJyb3JzID0gbnVsbDsgLy8gVGhlc2UgYXJlIGVycm9ycyB0aGF0IHdlIHJlY292ZXJlZCBmcm9tIHdpdGhvdXQgc3VyZmFjaW5nIHRoZW0gdG8gdGhlIFVJLlxuLy8gV2Ugd2lsbCBsb2cgdGhlbSBvbmNlIHRoZSB0cmVlIGNvbW1pdHMuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RSZWNvdmVyYWJsZUVycm9ycyA9IG51bGw7IC8vIFRoZSBtb3N0IHJlY2VudCB0aW1lIHdlIGNvbW1pdHRlZCBhIGZhbGxiYWNrLiBUaGlzIGxldHMgdXMgZW5zdXJlIGEgdHJhaW5cbi8vIG1vZGVsIHdoZXJlIHdlIGRvbid0IGNvbW1pdCBuZXcgbG9hZGluZyBzdGF0ZXMgaW4gdG9vIHF1aWNrIHN1Y2Nlc3Npb24uXG5cbnZhciBnbG9iYWxNb3N0UmVjZW50RmFsbGJhY2tUaW1lID0gMDtcbnZhciBGQUxMQkFDS19USFJPVFRMRV9NUyA9IDUwMDsgLy8gVGhlIGFic29sdXRlIHRpbWUgZm9yIHdoZW4gd2Ugc2hvdWxkIHN0YXJ0IGdpdmluZyB1cCBvbiByZW5kZXJpbmdcbi8vIG1vcmUgYW5kIHByZWZlciBDUFUgc3VzcGVuc2UgaGV1cmlzdGljcyBpbnN0ZWFkLlxuXG52YXIgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyVGFyZ2V0VGltZSA9IEluZmluaXR5OyAvLyBIb3cgbG9uZyBhIHJlbmRlciBpcyBzdXBwb3NlZCB0byB0YWtlIGJlZm9yZSB3ZSBzdGFydCBmb2xsb3dpbmcgQ1BVXG4vLyBzdXNwZW5zZSBoZXVyaXN0aWNzIGFuZCBvcHQgb3V0IG9mIHJlbmRlcmluZyBtb3JlIGNvbnRlbnQuXG5cbnZhciBSRU5ERVJfVElNRU9VVF9NUyA9IDUwMDtcbnZhciB3b3JrSW5Qcm9ncmVzc1RyYW5zaXRpb25zID0gbnVsbDtcblxuZnVuY3Rpb24gcmVzZXRSZW5kZXJUaW1lcigpIHtcbiAgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyVGFyZ2V0VGltZSA9IG5vdygpICsgUkVOREVSX1RJTUVPVVRfTVM7XG59XG5cbmZ1bmN0aW9uIGdldFJlbmRlclRhcmdldFRpbWUoKSB7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJUYXJnZXRUaW1lO1xufVxudmFyIGhhc1VuY2F1Z2h0RXJyb3IgPSBmYWxzZTtcbnZhciBmaXJzdFVuY2F1Z2h0RXJyb3IgPSBudWxsO1xudmFyIGxlZ2FjeUVycm9yQm91bmRhcmllc1RoYXRBbHJlYWR5RmFpbGVkID0gbnVsbDsgLy8gT25seSB1c2VkIHdoZW4gZW5hYmxlUHJvZmlsZXJOZXN0ZWRVcGRhdGVTY2hlZHVsZWRIb29rIGlzIHRydWU7XG52YXIgcm9vdERvZXNIYXZlUGFzc2l2ZUVmZmVjdHMgPSBmYWxzZTtcbnZhciByb290V2l0aFBlbmRpbmdQYXNzaXZlRWZmZWN0cyA9IG51bGw7XG52YXIgcGVuZGluZ1Bhc3NpdmVFZmZlY3RzTGFuZXMgPSBOb0xhbmVzO1xudmFyIHBlbmRpbmdQYXNzaXZlUHJvZmlsZXJFZmZlY3RzID0gW107XG52YXIgcGVuZGluZ1Bhc3NpdmVUcmFuc2l0aW9ucyA9IG51bGw7IC8vIFVzZSB0aGVzZSB0byBwcmV2ZW50IGFuIGluZmluaXRlIGxvb3Agb2YgbmVzdGVkIHVwZGF0ZXNcblxudmFyIE5FU1RFRF9VUERBVEVfTElNSVQgPSA1MDtcbnZhciBuZXN0ZWRVcGRhdGVDb3VudCA9IDA7XG52YXIgcm9vdFdpdGhOZXN0ZWRVcGRhdGVzID0gbnVsbDtcbnZhciBpc0ZsdXNoaW5nUGFzc2l2ZUVmZmVjdHMgPSBmYWxzZTtcbnZhciBkaWRTY2hlZHVsZVVwZGF0ZUR1cmluZ1Bhc3NpdmVFZmZlY3RzID0gZmFsc2U7XG52YXIgTkVTVEVEX1BBU1NJVkVfVVBEQVRFX0xJTUlUID0gNTA7XG52YXIgbmVzdGVkUGFzc2l2ZVVwZGF0ZUNvdW50ID0gMDtcbnZhciByb290V2l0aFBhc3NpdmVOZXN0ZWRVcGRhdGVzID0gbnVsbDsgLy8gSWYgdHdvIHVwZGF0ZXMgYXJlIHNjaGVkdWxlZCB3aXRoaW4gdGhlIHNhbWUgZXZlbnQsIHdlIHNob3VsZCB0cmVhdCB0aGVpclxuLy8gZXZlbnQgdGltZXMgYXMgc2ltdWx0YW5lb3VzLCBldmVuIGlmIHRoZSBhY3R1YWwgY2xvY2sgdGltZSBoYXMgYWR2YW5jZWRcbi8vIGJldHdlZW4gdGhlIGZpcnN0IGFuZCBzZWNvbmQgY2FsbC5cblxudmFyIGN1cnJlbnRFdmVudFRpbWUgPSBOb1RpbWVzdGFtcDtcbnZhciBjdXJyZW50RXZlbnRUcmFuc2l0aW9uTGFuZSA9IE5vTGFuZXM7XG52YXIgaXNSdW5uaW5nSW5zZXJ0aW9uRWZmZWN0ID0gZmFsc2U7XG5mdW5jdGlvbiBnZXRXb3JrSW5Qcm9ncmVzc1Jvb3QoKSB7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzc1Jvb3Q7XG59XG5mdW5jdGlvbiByZXF1ZXN0RXZlbnRUaW1lKCkge1xuICBpZiAoKGV4ZWN1dGlvbkNvbnRleHQgJiAoUmVuZGVyQ29udGV4dCB8IENvbW1pdENvbnRleHQpKSAhPT0gTm9Db250ZXh0KSB7XG4gICAgLy8gV2UncmUgaW5zaWRlIFJlYWN0LCBzbyBpdCdzIGZpbmUgdG8gcmVhZCB0aGUgYWN0dWFsIHRpbWUuXG4gICAgcmV0dXJuIG5vdygpO1xuICB9IC8vIFdlJ3JlIG5vdCBpbnNpZGUgUmVhY3QsIHNvIHdlIG1heSBiZSBpbiB0aGUgbWlkZGxlIG9mIGEgYnJvd3NlciBldmVudC5cblxuXG4gIGlmIChjdXJyZW50RXZlbnRUaW1lICE9PSBOb1RpbWVzdGFtcCkge1xuICAgIC8vIFVzZSB0aGUgc2FtZSBzdGFydCB0aW1lIGZvciBhbGwgdXBkYXRlcyB1bnRpbCB3ZSBlbnRlciBSZWFjdCBhZ2Fpbi5cbiAgICByZXR1cm4gY3VycmVudEV2ZW50VGltZTtcbiAgfSAvLyBUaGlzIGlzIHRoZSBmaXJzdCB1cGRhdGUgc2luY2UgUmVhY3QgeWllbGRlZC4gQ29tcHV0ZSBhIG5ldyBzdGFydCB0aW1lLlxuXG5cbiAgY3VycmVudEV2ZW50VGltZSA9IG5vdygpO1xuICByZXR1cm4gY3VycmVudEV2ZW50VGltZTtcbn1cbmZ1bmN0aW9uIHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKSB7XG4gIC8vIFNwZWNpYWwgY2FzZXNcbiAgdmFyIG1vZGUgPSBmaWJlci5tb2RlO1xuXG4gIGlmICgobW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlKSB7XG4gICAgcmV0dXJuIFN5bmNMYW5lO1xuICB9IGVsc2UgaWYgKCAoZXhlY3V0aW9uQ29udGV4dCAmIFJlbmRlckNvbnRleHQpICE9PSBOb0NvbnRleHQgJiYgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMgIT09IE5vTGFuZXMpIHtcbiAgICAvLyBUaGlzIGlzIGEgcmVuZGVyIHBoYXNlIHVwZGF0ZS4gVGhlc2UgYXJlIG5vdCBvZmZpY2lhbGx5IHN1cHBvcnRlZC4gVGhlXG4gICAgLy8gb2xkIGJlaGF2aW9yIGlzIHRvIGdpdmUgdGhpcyB0aGUgc2FtZSBcInRocmVhZFwiIChsYW5lcykgYXNcbiAgICAvLyB3aGF0ZXZlciBpcyBjdXJyZW50bHkgcmVuZGVyaW5nLiBTbyBpZiB5b3UgY2FsbCBgc2V0U3RhdGVgIG9uIGEgY29tcG9uZW50XG4gICAgLy8gdGhhdCBoYXBwZW5zIGxhdGVyIGluIHRoZSBzYW1lIHJlbmRlciwgaXQgd2lsbCBmbHVzaC4gSWRlYWxseSwgd2Ugd2FudCB0b1xuICAgIC8vIHJlbW92ZSB0aGUgc3BlY2lhbCBjYXNlIGFuZCB0cmVhdCB0aGVtIGFzIGlmIHRoZXkgY2FtZSBmcm9tIGFuXG4gICAgLy8gaW50ZXJsZWF2ZWQgZXZlbnQuIFJlZ2FyZGxlc3MsIHRoaXMgcGF0dGVybiBpcyBub3Qgb2ZmaWNpYWxseSBzdXBwb3J0ZWQuXG4gICAgLy8gVGhpcyBiZWhhdmlvciBpcyBvbmx5IGEgZmFsbGJhY2suIFRoZSBmbGFnIG9ubHkgZXhpc3RzIHVudGlsIHdlIGNhbiByb2xsXG4gICAgLy8gb3V0IHRoZSBzZXRTdGF0ZSB3YXJuaW5nLCBzaW5jZSBleGlzdGluZyBjb2RlIG1pZ2h0IGFjY2lkZW50YWxseSByZWx5IG9uXG4gICAgLy8gdGhlIGN1cnJlbnQgYmVoYXZpb3IuXG4gICAgcmV0dXJuIHBpY2tBcmJpdHJhcnlMYW5lKHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHZhciBpc1RyYW5zaXRpb24gPSByZXF1ZXN0Q3VycmVudFRyYW5zaXRpb24oKSAhPT0gTm9UcmFuc2l0aW9uO1xuXG4gIGlmIChpc1RyYW5zaXRpb24pIHtcbiAgICBpZiAoIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbiAhPT0gbnVsbCkge1xuICAgICAgdmFyIHRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb247XG5cbiAgICAgIGlmICghdHJhbnNpdGlvbi5fdXBkYXRlZEZpYmVycykge1xuICAgICAgICB0cmFuc2l0aW9uLl91cGRhdGVkRmliZXJzID0gbmV3IFNldCgpO1xuICAgICAgfVxuXG4gICAgICB0cmFuc2l0aW9uLl91cGRhdGVkRmliZXJzLmFkZChmaWJlcik7XG4gICAgfSAvLyBUaGUgYWxnb3JpdGhtIGZvciBhc3NpZ25pbmcgYW4gdXBkYXRlIHRvIGEgbGFuZSBzaG91bGQgYmUgc3RhYmxlIGZvciBhbGxcbiAgICAvLyB1cGRhdGVzIGF0IHRoZSBzYW1lIHByaW9yaXR5IHdpdGhpbiB0aGUgc2FtZSBldmVudC4gVG8gZG8gdGhpcywgdGhlXG4gICAgLy8gaW5wdXRzIHRvIHRoZSBhbGdvcml0aG0gbXVzdCBiZSB0aGUgc2FtZS5cbiAgICAvL1xuICAgIC8vIFRoZSB0cmljayB3ZSB1c2UgaXMgdG8gY2FjaGUgdGhlIGZpcnN0IG9mIGVhY2ggb2YgdGhlc2UgaW5wdXRzIHdpdGhpbiBhblxuICAgIC8vIGV2ZW50LiBUaGVuIHJlc2V0IHRoZSBjYWNoZWQgdmFsdWVzIG9uY2Ugd2UgY2FuIGJlIHN1cmUgdGhlIGV2ZW50IGlzXG4gICAgLy8gb3Zlci4gT3VyIGhldXJpc3RpYyBmb3IgdGhhdCBpcyB3aGVuZXZlciB3ZSBlbnRlciBhIGNvbmN1cnJlbnQgd29yayBsb29wLlxuXG5cbiAgICBpZiAoY3VycmVudEV2ZW50VHJhbnNpdGlvbkxhbmUgPT09IE5vTGFuZSkge1xuICAgICAgLy8gQWxsIHRyYW5zaXRpb25zIHdpdGhpbiB0aGUgc2FtZSBldmVudCBhcmUgYXNzaWduZWQgdGhlIHNhbWUgbGFuZS5cbiAgICAgIGN1cnJlbnRFdmVudFRyYW5zaXRpb25MYW5lID0gY2xhaW1OZXh0VHJhbnNpdGlvbkxhbmUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY3VycmVudEV2ZW50VHJhbnNpdGlvbkxhbmU7XG4gIH0gLy8gVXBkYXRlcyBvcmlnaW5hdGluZyBpbnNpZGUgY2VydGFpbiBSZWFjdCBtZXRob2RzLCBsaWtlIGZsdXNoU3luYywgaGF2ZVxuICAvLyB0aGVpciBwcmlvcml0eSBzZXQgYnkgdHJhY2tpbmcgaXQgd2l0aCBhIGNvbnRleHQgdmFyaWFibGUuXG4gIC8vXG4gIC8vIFRoZSBvcGFxdWUgdHlwZSByZXR1cm5lZCBieSB0aGUgaG9zdCBjb25maWcgaXMgaW50ZXJuYWxseSBhIGxhbmUsIHNvIHdlIGNhblxuICAvLyB1c2UgdGhhdCBkaXJlY3RseS5cbiAgLy8gVE9ETzogTW92ZSB0aGlzIHR5cGUgY29udmVyc2lvbiB0byB0aGUgZXZlbnQgcHJpb3JpdHkgbW9kdWxlLlxuXG5cbiAgdmFyIHVwZGF0ZUxhbmUgPSBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoKTtcblxuICBpZiAodXBkYXRlTGFuZSAhPT0gTm9MYW5lKSB7XG4gICAgcmV0dXJuIHVwZGF0ZUxhbmU7XG4gIH0gLy8gVGhpcyB1cGRhdGUgb3JpZ2luYXRlZCBvdXRzaWRlIFJlYWN0LiBBc2sgdGhlIGhvc3QgZW52aXJvbm1lbnQgZm9yIGFuXG4gIC8vIGFwcHJvcHJpYXRlIHByaW9yaXR5LCBiYXNlZCBvbiB0aGUgdHlwZSBvZiBldmVudC5cbiAgLy9cbiAgLy8gVGhlIG9wYXF1ZSB0eXBlIHJldHVybmVkIGJ5IHRoZSBob3N0IGNvbmZpZyBpcyBpbnRlcm5hbGx5IGEgbGFuZSwgc28gd2UgY2FuXG4gIC8vIHVzZSB0aGF0IGRpcmVjdGx5LlxuICAvLyBUT0RPOiBNb3ZlIHRoaXMgdHlwZSBjb252ZXJzaW9uIHRvIHRoZSBldmVudCBwcmlvcml0eSBtb2R1bGUuXG5cblxuICB2YXIgZXZlbnRMYW5lID0gZ2V0Q3VycmVudEV2ZW50UHJpb3JpdHkoKTtcbiAgcmV0dXJuIGV2ZW50TGFuZTtcbn1cblxuZnVuY3Rpb24gcmVxdWVzdFJldHJ5TGFuZShmaWJlcikge1xuICAvLyBUaGlzIGlzIGEgZm9yayBvZiBgcmVxdWVzdFVwZGF0ZUxhbmVgIGRlc2lnbmVkIHNwZWNpZmljYWxseSBmb3IgU3VzcGVuc2VcbiAgLy8gXCJyZXRyaWVzXCIg4oCUIGEgc3BlY2lhbCB1cGRhdGUgdGhhdCBhdHRlbXB0cyB0byBmbGlwIGEgU3VzcGVuc2UgYm91bmRhcnlcbiAgLy8gZnJvbSBpdHMgcGxhY2Vob2xkZXIgc3RhdGUgdG8gaXRzIHByaW1hcnkvcmVzb2x2ZWQgc3RhdGUuXG4gIC8vIFNwZWNpYWwgY2FzZXNcbiAgdmFyIG1vZGUgPSBmaWJlci5tb2RlO1xuXG4gIGlmICgobW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlKSB7XG4gICAgcmV0dXJuIFN5bmNMYW5lO1xuICB9XG5cbiAgcmV0dXJuIGNsYWltTmV4dFJldHJ5TGFuZSgpO1xufVxuXG5mdW5jdGlvbiBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIGxhbmUsIGV2ZW50VGltZSkge1xuICBjaGVja0Zvck5lc3RlZFVwZGF0ZXMoKTtcblxuICB7XG4gICAgaWYgKGlzUnVubmluZ0luc2VydGlvbkVmZmVjdCkge1xuICAgICAgZXJyb3IoJ3VzZUluc2VydGlvbkVmZmVjdCBtdXN0IG5vdCBzY2hlZHVsZSB1cGRhdGVzLicpO1xuICAgIH1cbiAgfVxuXG4gIHtcbiAgICBpZiAoaXNGbHVzaGluZ1Bhc3NpdmVFZmZlY3RzKSB7XG4gICAgICBkaWRTY2hlZHVsZVVwZGF0ZUR1cmluZ1Bhc3NpdmVFZmZlY3RzID0gdHJ1ZTtcbiAgICB9XG4gIH0gLy8gTWFyayB0aGF0IHRoZSByb290IGhhcyBhIHBlbmRpbmcgdXBkYXRlLlxuXG5cbiAgbWFya1Jvb3RVcGRhdGVkKHJvb3QsIGxhbmUsIGV2ZW50VGltZSk7XG5cbiAgaWYgKChleGVjdXRpb25Db250ZXh0ICYgUmVuZGVyQ29udGV4dCkgIT09IE5vTGFuZXMgJiYgcm9vdCA9PT0gd29ya0luUHJvZ3Jlc3NSb290KSB7XG4gICAgLy8gVGhpcyB1cGRhdGUgd2FzIGRpc3BhdGNoZWQgZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UuIFRoaXMgaXMgYSBtaXN0YWtlXG4gICAgLy8gaWYgdGhlIHVwZGF0ZSBvcmlnaW5hdGVzIGZyb20gdXNlciBzcGFjZSAod2l0aCB0aGUgZXhjZXB0aW9uIG9mIGxvY2FsXG4gICAgLy8gaG9vayB1cGRhdGVzLCB3aGljaCBhcmUgaGFuZGxlZCBkaWZmZXJlbnRseSBhbmQgZG9uJ3QgcmVhY2ggdGhpc1xuICAgIC8vIGZ1bmN0aW9uKSwgYnV0IHRoZXJlIGFyZSBzb21lIGludGVybmFsIFJlYWN0IGZlYXR1cmVzIHRoYXQgdXNlIHRoaXMgYXNcbiAgICAvLyBhbiBpbXBsZW1lbnRhdGlvbiBkZXRhaWwsIGxpa2Ugc2VsZWN0aXZlIGh5ZHJhdGlvbi5cbiAgICB3YXJuQWJvdXRSZW5kZXJQaGFzZVVwZGF0ZXNJbkRFVihmaWJlcik7IC8vIFRyYWNrIGxhbmVzIHRoYXQgd2VyZSB1cGRhdGVkIGR1cmluZyB0aGUgcmVuZGVyIHBoYXNlXG4gIH0gZWxzZSB7XG4gICAgLy8gVGhpcyBpcyBhIG5vcm1hbCB1cGRhdGUsIHNjaGVkdWxlZCBmcm9tIG91dHNpZGUgdGhlIHJlbmRlciBwaGFzZS4gRm9yXG4gICAgLy8gZXhhbXBsZSwgZHVyaW5nIGFuIGlucHV0IGV2ZW50LlxuICAgIHtcbiAgICAgIGlmIChpc0RldlRvb2xzUHJlc2VudCkge1xuICAgICAgICBhZGRGaWJlclRvTGFuZXNNYXAocm9vdCwgZmliZXIsIGxhbmUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHdhcm5JZlVwZGF0ZXNOb3RXcmFwcGVkV2l0aEFjdERFVihmaWJlcik7XG5cbiAgICBpZiAocm9vdCA9PT0gd29ya0luUHJvZ3Jlc3NSb290KSB7XG4gICAgICAvLyBSZWNlaXZlZCBhbiB1cGRhdGUgdG8gYSB0cmVlIHRoYXQncyBpbiB0aGUgbWlkZGxlIG9mIHJlbmRlcmluZy4gTWFya1xuICAgICAgLy8gdGhhdCB0aGVyZSB3YXMgYW4gaW50ZXJsZWF2ZWQgdXBkYXRlIHdvcmsgb24gdGhpcyByb290LiBVbmxlc3MgdGhlXG4gICAgICAvLyBgZGVmZXJSZW5kZXJQaGFzZVVwZGF0ZVRvTmV4dEJhdGNoYCBmbGFnIGlzIG9mZiBhbmQgdGhpcyBpcyBhIHJlbmRlclxuICAgICAgLy8gcGhhc2UgdXBkYXRlLiBJbiB0aGF0IGNhc2UsIHdlIGRvbid0IHRyZWF0IHJlbmRlciBwaGFzZSB1cGRhdGVzIGFzIGlmXG4gICAgICAvLyB0aGV5IHdlcmUgaW50ZXJsZWF2ZWQsIGZvciBiYWNrd2FyZHMgY29tcGF0IHJlYXNvbnMuXG4gICAgICBpZiAoIChleGVjdXRpb25Db250ZXh0ICYgUmVuZGVyQ29udGV4dCkgPT09IE5vQ29udGV4dCkge1xuICAgICAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RJbnRlcmxlYXZlZFVwZGF0ZWRMYW5lcyA9IG1lcmdlTGFuZXMod29ya0luUHJvZ3Jlc3NSb290SW50ZXJsZWF2ZWRVcGRhdGVkTGFuZXMsIGxhbmUpO1xuICAgICAgfVxuXG4gICAgICBpZiAod29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9PT0gUm9vdFN1c3BlbmRlZFdpdGhEZWxheSkge1xuICAgICAgICAvLyBUaGUgcm9vdCBhbHJlYWR5IHN1c3BlbmRlZCB3aXRoIGEgZGVsYXksIHdoaWNoIG1lYW5zIHRoaXMgcmVuZGVyXG4gICAgICAgIC8vIGRlZmluaXRlbHkgd29uJ3QgZmluaXNoLiBTaW5jZSB3ZSBoYXZlIGEgbmV3IHVwZGF0ZSwgbGV0J3MgbWFyayBpdCBhc1xuICAgICAgICAvLyBzdXNwZW5kZWQgbm93LCByaWdodCBiZWZvcmUgbWFya2luZyB0aGUgaW5jb21pbmcgdXBkYXRlLiBUaGlzIGhhcyB0aGVcbiAgICAgICAgLy8gZWZmZWN0IG9mIGludGVycnVwdGluZyB0aGUgY3VycmVudCByZW5kZXIgYW5kIHN3aXRjaGluZyB0byB0aGUgdXBkYXRlLlxuICAgICAgICAvLyBUT0RPOiBNYWtlIHN1cmUgdGhpcyBkb2Vzbid0IG92ZXJyaWRlIHBpbmdzIHRoYXQgaGFwcGVuIHdoaWxlIHdlJ3ZlXG4gICAgICAgIC8vIGFscmVhZHkgc3RhcnRlZCByZW5kZXJpbmcuXG4gICAgICAgIG1hcmtSb290U3VzcGVuZGVkJDEocm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBldmVudFRpbWUpO1xuXG4gICAgaWYgKGxhbmUgPT09IFN5bmNMYW5lICYmIGV4ZWN1dGlvbkNvbnRleHQgPT09IE5vQ29udGV4dCAmJiAoZmliZXIubW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlICYmIC8vIFRyZWF0IGBhY3RgIGFzIGlmIGl0J3MgaW5zaWRlIGBiYXRjaGVkVXBkYXRlc2AsIGV2ZW4gaW4gbGVnYWN5IG1vZGUuXG4gICAgISggUmVhY3RDdXJyZW50QWN0UXVldWUkMS5pc0JhdGNoaW5nTGVnYWN5KSkge1xuICAgICAgLy8gRmx1c2ggdGhlIHN5bmNocm9ub3VzIHdvcmsgbm93LCB1bmxlc3Mgd2UncmUgYWxyZWFkeSB3b3JraW5nIG9yIGluc2lkZVxuICAgICAgLy8gYSBiYXRjaC4gVGhpcyBpcyBpbnRlbnRpb25hbGx5IGluc2lkZSBzY2hlZHVsZVVwZGF0ZU9uRmliZXIgaW5zdGVhZCBvZlxuICAgICAgLy8gc2NoZWR1bGVDYWxsYmFja0ZvckZpYmVyIHRvIHByZXNlcnZlIHRoZSBhYmlsaXR5IHRvIHNjaGVkdWxlIGEgY2FsbGJhY2tcbiAgICAgIC8vIHdpdGhvdXQgaW1tZWRpYXRlbHkgZmx1c2hpbmcgaXQuIFdlIG9ubHkgZG8gdGhpcyBmb3IgdXNlci1pbml0aWF0ZWRcbiAgICAgIC8vIHVwZGF0ZXMsIHRvIHByZXNlcnZlIGhpc3RvcmljYWwgYmVoYXZpb3Igb2YgbGVnYWN5IG1vZGUuXG4gICAgICByZXNldFJlbmRlclRpbWVyKCk7XG4gICAgICBmbHVzaFN5bmNDYWxsYmFja3NPbmx5SW5MZWdhY3lNb2RlKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBzY2hlZHVsZUluaXRpYWxIeWRyYXRpb25PblJvb3Qocm9vdCwgbGFuZSwgZXZlbnRUaW1lKSB7XG4gIC8vIFRoaXMgaXMgYSBzcGVjaWFsIGZvcmsgb2Ygc2NoZWR1bGVVcGRhdGVPbkZpYmVyIHRoYXQgaXMgb25seSB1c2VkIHRvXG4gIC8vIHNjaGVkdWxlIHRoZSBpbml0aWFsIGh5ZHJhdGlvbiBvZiBhIHJvb3QgdGhhdCBoYXMganVzdCBiZWVuIGNyZWF0ZWQuIE1vc3RcbiAgLy8gb2YgdGhlIHN0dWZmIGluIHNjaGVkdWxlVXBkYXRlT25GaWJlciBjYW4gYmUgc2tpcHBlZC5cbiAgLy9cbiAgLy8gVGhlIG1haW4gcmVhc29uIGZvciB0aGlzIHNlcGFyYXRlIHBhdGgsIHRob3VnaCwgaXMgdG8gZGlzdGluZ3Vpc2ggdGhlXG4gIC8vIGluaXRpYWwgY2hpbGRyZW4gZnJvbSBzdWJzZXF1ZW50IHVwZGF0ZXMuIEluIGZ1bGx5IGNsaWVudC1yZW5kZXJlZCByb290c1xuICAvLyAoY3JlYXRlUm9vdCBpbnN0ZWFkIG9mIGh5ZHJhdGVSb290KSwgYWxsIHRvcC1sZXZlbCByZW5kZXJzIGFyZSBtb2RlbGVkIGFzXG4gIC8vIHVwZGF0ZXMsIGJ1dCBoeWRyYXRpb24gcm9vdHMgYXJlIHNwZWNpYWwgYmVjYXVzZSB0aGUgaW5pdGlhbCByZW5kZXIgbXVzdFxuICAvLyBtYXRjaCB3aGF0IHdhcyByZW5kZXJlZCBvbiB0aGUgc2VydmVyLlxuICB2YXIgY3VycmVudCA9IHJvb3QuY3VycmVudDtcbiAgY3VycmVudC5sYW5lcyA9IGxhbmU7XG4gIG1hcmtSb290VXBkYXRlZChyb290LCBsYW5lLCBldmVudFRpbWUpO1xuICBlbnN1cmVSb290SXNTY2hlZHVsZWQocm9vdCwgZXZlbnRUaW1lKTtcbn1cbmZ1bmN0aW9uIGlzVW5zYWZlQ2xhc3NSZW5kZXJQaGFzZVVwZGF0ZShmaWJlcikge1xuICAvLyBDaGVjayBpZiB0aGlzIGlzIGEgcmVuZGVyIHBoYXNlIHVwZGF0ZS4gT25seSBjYWxsZWQgYnkgY2xhc3MgY29tcG9uZW50cyxcbiAgLy8gd2hpY2ggc3BlY2lhbCAoZGVwcmVjYXRlZCkgYmVoYXZpb3IgZm9yIFVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZSBwcm9wcy5cbiAgcmV0dXJuICgvLyBUT0RPOiBSZW1vdmUgb3V0ZGF0ZWQgZGVmZXJSZW5kZXJQaGFzZVVwZGF0ZVRvTmV4dEJhdGNoIGV4cGVyaW1lbnQuIFdlXG4gICAgLy8gZGVjaWRlZCBub3QgdG8gZW5hYmxlIGl0LlxuICAgICAoZXhlY3V0aW9uQ29udGV4dCAmIFJlbmRlckNvbnRleHQpICE9PSBOb0NvbnRleHRcbiAgKTtcbn0gLy8gVXNlIHRoaXMgZnVuY3Rpb24gdG8gc2NoZWR1bGUgYSB0YXNrIGZvciBhIHJvb3QuIFRoZXJlJ3Mgb25seSBvbmUgdGFzayBwZXJcbi8vIHJvb3Q7IGlmIGEgdGFzayB3YXMgYWxyZWFkeSBzY2hlZHVsZWQsIHdlJ2xsIGNoZWNrIHRvIG1ha2Ugc3VyZSB0aGUgcHJpb3JpdHlcbi8vIG9mIHRoZSBleGlzdGluZyB0YXNrIGlzIHRoZSBzYW1lIGFzIHRoZSBwcmlvcml0eSBvZiB0aGUgbmV4dCBsZXZlbCB0aGF0IHRoZVxuLy8gcm9vdCBoYXMgd29yayBvbi4gVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgb24gZXZlcnkgdXBkYXRlLCBhbmQgcmlnaHQgYmVmb3JlXG4vLyBleGl0aW5nIGEgdGFzay5cblxuZnVuY3Rpb24gZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIGN1cnJlbnRUaW1lKSB7XG4gIHZhciBleGlzdGluZ0NhbGxiYWNrTm9kZSA9IHJvb3QuY2FsbGJhY2tOb2RlOyAvLyBDaGVjayBpZiBhbnkgbGFuZXMgYXJlIGJlaW5nIHN0YXJ2ZWQgYnkgb3RoZXIgd29yay4gSWYgc28sIG1hcmsgdGhlbSBhc1xuICAvLyBleHBpcmVkIHNvIHdlIGtub3cgdG8gd29yayBvbiB0aG9zZSBuZXh0LlxuXG4gIG1hcmtTdGFydmVkTGFuZXNBc0V4cGlyZWQocm9vdCwgY3VycmVudFRpbWUpOyAvLyBEZXRlcm1pbmUgdGhlIG5leHQgbGFuZXMgdG8gd29yayBvbiwgYW5kIHRoZWlyIHByaW9yaXR5LlxuXG4gIHZhciBuZXh0TGFuZXMgPSBnZXROZXh0TGFuZXMocm9vdCwgcm9vdCA9PT0gd29ya0luUHJvZ3Jlc3NSb290ID8gd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMgOiBOb0xhbmVzKTtcblxuICBpZiAobmV4dExhbmVzID09PSBOb0xhbmVzKSB7XG4gICAgLy8gU3BlY2lhbCBjYXNlOiBUaGVyZSdzIG5vdGhpbmcgdG8gd29yayBvbi5cbiAgICBpZiAoZXhpc3RpbmdDYWxsYmFja05vZGUgIT09IG51bGwpIHtcbiAgICAgIGNhbmNlbENhbGxiYWNrJDEoZXhpc3RpbmdDYWxsYmFja05vZGUpO1xuICAgIH1cblxuICAgIHJvb3QuY2FsbGJhY2tOb2RlID0gbnVsbDtcbiAgICByb290LmNhbGxiYWNrUHJpb3JpdHkgPSBOb0xhbmU7XG4gICAgcmV0dXJuO1xuICB9IC8vIFdlIHVzZSB0aGUgaGlnaGVzdCBwcmlvcml0eSBsYW5lIHRvIHJlcHJlc2VudCB0aGUgcHJpb3JpdHkgb2YgdGhlIGNhbGxiYWNrLlxuXG5cbiAgdmFyIG5ld0NhbGxiYWNrUHJpb3JpdHkgPSBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lKG5leHRMYW5lcyk7IC8vIENoZWNrIGlmIHRoZXJlJ3MgYW4gZXhpc3RpbmcgdGFzay4gV2UgbWF5IGJlIGFibGUgdG8gcmV1c2UgaXQuXG5cbiAgdmFyIGV4aXN0aW5nQ2FsbGJhY2tQcmlvcml0eSA9IHJvb3QuY2FsbGJhY2tQcmlvcml0eTtcblxuICBpZiAoZXhpc3RpbmdDYWxsYmFja1ByaW9yaXR5ID09PSBuZXdDYWxsYmFja1ByaW9yaXR5ICYmIC8vIFNwZWNpYWwgY2FzZSByZWxhdGVkIHRvIGBhY3RgLiBJZiB0aGUgY3VycmVudGx5IHNjaGVkdWxlZCB0YXNrIGlzIGFcbiAgLy8gU2NoZWR1bGVyIHRhc2ssIHJhdGhlciB0aGFuIGFuIGBhY3RgIHRhc2ssIGNhbmNlbCBpdCBhbmQgcmUtc2NoZWR1bGVkXG4gIC8vIG9uIHRoZSBgYWN0YCBxdWV1ZS5cbiAgISggUmVhY3RDdXJyZW50QWN0UXVldWUkMS5jdXJyZW50ICE9PSBudWxsICYmIGV4aXN0aW5nQ2FsbGJhY2tOb2RlICE9PSBmYWtlQWN0Q2FsbGJhY2tOb2RlKSkge1xuICAgIHtcbiAgICAgIC8vIElmIHdlJ3JlIGdvaW5nIHRvIHJlLXVzZSBhbiBleGlzdGluZyB0YXNrLCBpdCBuZWVkcyB0byBleGlzdC5cbiAgICAgIC8vIEFzc3VtZSB0aGF0IGRpc2NyZXRlIHVwZGF0ZSBtaWNyb3Rhc2tzIGFyZSBub24tY2FuY2VsbGFibGUgYW5kIG51bGwuXG4gICAgICAvLyBUT0RPOiBUZW1wb3JhcnkgdW50aWwgd2UgY29uZmlybSB0aGlzIHdhcm5pbmcgaXMgbm90IGZpcmVkLlxuICAgICAgaWYgKGV4aXN0aW5nQ2FsbGJhY2tOb2RlID09IG51bGwgJiYgZXhpc3RpbmdDYWxsYmFja1ByaW9yaXR5ICE9PSBTeW5jTGFuZSkge1xuICAgICAgICBlcnJvcignRXhwZWN0ZWQgc2NoZWR1bGVkIGNhbGxiYWNrIHRvIGV4aXN0LiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgICAgfVxuICAgIH0gLy8gVGhlIHByaW9yaXR5IGhhc24ndCBjaGFuZ2VkLiBXZSBjYW4gcmV1c2UgdGhlIGV4aXN0aW5nIHRhc2suIEV4aXQuXG5cblxuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChleGlzdGluZ0NhbGxiYWNrTm9kZSAhPSBudWxsKSB7XG4gICAgLy8gQ2FuY2VsIHRoZSBleGlzdGluZyBjYWxsYmFjay4gV2UnbGwgc2NoZWR1bGUgYSBuZXcgb25lIGJlbG93LlxuICAgIGNhbmNlbENhbGxiYWNrJDEoZXhpc3RpbmdDYWxsYmFja05vZGUpO1xuICB9IC8vIFNjaGVkdWxlIGEgbmV3IGNhbGxiYWNrLlxuXG5cbiAgdmFyIG5ld0NhbGxiYWNrTm9kZTtcblxuICBpZiAobmV3Q2FsbGJhY2tQcmlvcml0eSA9PT0gU3luY0xhbmUpIHtcbiAgICAvLyBTcGVjaWFsIGNhc2U6IFN5bmMgUmVhY3QgY2FsbGJhY2tzIGFyZSBzY2hlZHVsZWQgb24gYSBzcGVjaWFsXG4gICAgLy8gaW50ZXJuYWwgcXVldWVcbiAgICBpZiAocm9vdC50YWcgPT09IExlZ2FjeVJvb3QpIHtcbiAgICAgIGlmICggUmVhY3RDdXJyZW50QWN0UXVldWUkMS5pc0JhdGNoaW5nTGVnYWN5ICE9PSBudWxsKSB7XG4gICAgICAgIFJlYWN0Q3VycmVudEFjdFF1ZXVlJDEuZGlkU2NoZWR1bGVMZWdhY3lVcGRhdGUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBzY2hlZHVsZUxlZ2FjeVN5bmNDYWxsYmFjayhwZXJmb3JtU3luY1dvcmtPblJvb3QuYmluZChudWxsLCByb290KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjaGVkdWxlU3luY0NhbGxiYWNrKHBlcmZvcm1TeW5jV29ya09uUm9vdC5iaW5kKG51bGwsIHJvb3QpKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICAvLyBGbHVzaCB0aGUgcXVldWUgaW4gYSBtaWNyb3Rhc2suXG4gICAgICBpZiAoIFJlYWN0Q3VycmVudEFjdFF1ZXVlJDEuY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgICAvLyBJbnNpZGUgYGFjdGAsIHVzZSBvdXIgaW50ZXJuYWwgYGFjdGAgcXVldWUgc28gdGhhdCB0aGVzZSBnZXQgZmx1c2hlZFxuICAgICAgICAvLyBhdCB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IHNjb3BlIGV2ZW4gd2hlbiB1c2luZyB0aGUgc3luYyB2ZXJzaW9uXG4gICAgICAgIC8vIG9mIGBhY3RgLlxuICAgICAgICBSZWFjdEN1cnJlbnRBY3RRdWV1ZSQxLmN1cnJlbnQucHVzaChmbHVzaFN5bmNDYWxsYmFja3MpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2NoZWR1bGVNaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgIC8vIEluIFNhZmFyaSwgYXBwZW5kaW5nIGFuIGlmcmFtZSBmb3JjZXMgbWljcm90YXNrcyB0byBydW4uXG4gICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8yMjQ1OVxuICAgICAgICAgIC8vIFdlIGRvbid0IHN1cHBvcnQgcnVubmluZyBjYWxsYmFja3MgaW4gdGhlIG1pZGRsZSBvZiByZW5kZXJcbiAgICAgICAgICAvLyBvciBjb21taXQgc28gd2UgbmVlZCB0byBjaGVjayBhZ2FpbnN0IHRoYXQuXG4gICAgICAgICAgaWYgKChleGVjdXRpb25Db250ZXh0ICYgKFJlbmRlckNvbnRleHQgfCBDb21taXRDb250ZXh0KSkgPT09IE5vQ29udGV4dCkge1xuICAgICAgICAgICAgLy8gTm90ZSB0aGF0IHRoaXMgd291bGQgc3RpbGwgcHJlbWF0dXJlbHkgZmx1c2ggdGhlIGNhbGxiYWNrc1xuICAgICAgICAgICAgLy8gaWYgdGhpcyBoYXBwZW5zIG91dHNpZGUgcmVuZGVyIG9yIGNvbW1pdCBwaGFzZSAoZS5nLiBpbiBhbiBldmVudCkuXG4gICAgICAgICAgICBmbHVzaFN5bmNDYWxsYmFja3MoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIG5ld0NhbGxiYWNrTm9kZSA9IG51bGw7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHNjaGVkdWxlclByaW9yaXR5TGV2ZWw7XG5cbiAgICBzd2l0Y2ggKGxhbmVzVG9FdmVudFByaW9yaXR5KG5leHRMYW5lcykpIHtcbiAgICAgIGNhc2UgRGlzY3JldGVFdmVudFByaW9yaXR5OlxuICAgICAgICBzY2hlZHVsZXJQcmlvcml0eUxldmVsID0gSW1tZWRpYXRlUHJpb3JpdHk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIENvbnRpbnVvdXNFdmVudFByaW9yaXR5OlxuICAgICAgICBzY2hlZHVsZXJQcmlvcml0eUxldmVsID0gVXNlckJsb2NraW5nUHJpb3JpdHk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIERlZmF1bHRFdmVudFByaW9yaXR5OlxuICAgICAgICBzY2hlZHVsZXJQcmlvcml0eUxldmVsID0gTm9ybWFsUHJpb3JpdHk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIElkbGVFdmVudFByaW9yaXR5OlxuICAgICAgICBzY2hlZHVsZXJQcmlvcml0eUxldmVsID0gSWRsZVByaW9yaXR5O1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgc2NoZWR1bGVyUHJpb3JpdHlMZXZlbCA9IE5vcm1hbFByaW9yaXR5O1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBuZXdDYWxsYmFja05vZGUgPSBzY2hlZHVsZUNhbGxiYWNrJDEoc2NoZWR1bGVyUHJpb3JpdHlMZXZlbCwgcGVyZm9ybUNvbmN1cnJlbnRXb3JrT25Sb290LmJpbmQobnVsbCwgcm9vdCkpO1xuICB9XG5cbiAgcm9vdC5jYWxsYmFja1ByaW9yaXR5ID0gbmV3Q2FsbGJhY2tQcmlvcml0eTtcbiAgcm9vdC5jYWxsYmFja05vZGUgPSBuZXdDYWxsYmFja05vZGU7XG59IC8vIFRoaXMgaXMgdGhlIGVudHJ5IHBvaW50IGZvciBldmVyeSBjb25jdXJyZW50IHRhc2ssIGkuZS4gYW55dGhpbmcgdGhhdFxuLy8gZ29lcyB0aHJvdWdoIFNjaGVkdWxlci5cblxuXG5mdW5jdGlvbiBwZXJmb3JtQ29uY3VycmVudFdvcmtPblJvb3Qocm9vdCwgZGlkVGltZW91dCkge1xuICB7XG4gICAgcmVzZXROZXN0ZWRVcGRhdGVGbGFnKCk7XG4gIH0gLy8gU2luY2Ugd2Uga25vdyB3ZSdyZSBpbiBhIFJlYWN0IGV2ZW50LCB3ZSBjYW4gY2xlYXIgdGhlIGN1cnJlbnRcbiAgLy8gZXZlbnQgdGltZS4gVGhlIG5leHQgdXBkYXRlIHdpbGwgY29tcHV0ZSBhIG5ldyBldmVudCB0aW1lLlxuXG5cbiAgY3VycmVudEV2ZW50VGltZSA9IE5vVGltZXN0YW1wO1xuICBjdXJyZW50RXZlbnRUcmFuc2l0aW9uTGFuZSA9IE5vTGFuZXM7XG5cbiAgaWYgKChleGVjdXRpb25Db250ZXh0ICYgKFJlbmRlckNvbnRleHQgfCBDb21taXRDb250ZXh0KSkgIT09IE5vQ29udGV4dCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hvdWxkIG5vdCBhbHJlYWR5IGJlIHdvcmtpbmcuJyk7XG4gIH0gLy8gRmx1c2ggYW55IHBlbmRpbmcgcGFzc2l2ZSBlZmZlY3RzIGJlZm9yZSBkZWNpZGluZyB3aGljaCBsYW5lcyB0byB3b3JrIG9uLFxuICAvLyBpbiBjYXNlIHRoZXkgc2NoZWR1bGUgYWRkaXRpb25hbCB3b3JrLlxuXG5cbiAgdmFyIG9yaWdpbmFsQ2FsbGJhY2tOb2RlID0gcm9vdC5jYWxsYmFja05vZGU7XG4gIHZhciBkaWRGbHVzaFBhc3NpdmVFZmZlY3RzID0gZmx1c2hQYXNzaXZlRWZmZWN0cygpO1xuXG4gIGlmIChkaWRGbHVzaFBhc3NpdmVFZmZlY3RzKSB7XG4gICAgLy8gU29tZXRoaW5nIGluIHRoZSBwYXNzaXZlIGVmZmVjdCBwaGFzZSBtYXkgaGF2ZSBjYW5jZWxlZCB0aGUgY3VycmVudCB0YXNrLlxuICAgIC8vIENoZWNrIGlmIHRoZSB0YXNrIG5vZGUgZm9yIHRoaXMgcm9vdCB3YXMgY2hhbmdlZC5cbiAgICBpZiAocm9vdC5jYWxsYmFja05vZGUgIT09IG9yaWdpbmFsQ2FsbGJhY2tOb2RlKSB7XG4gICAgICAvLyBUaGUgY3VycmVudCB0YXNrIHdhcyBjYW5jZWxlZC4gRXhpdC4gV2UgZG9uJ3QgbmVlZCB0byBjYWxsXG4gICAgICAvLyBgZW5zdXJlUm9vdElzU2NoZWR1bGVkYCBiZWNhdXNlIHRoZSBjaGVjayBhYm92ZSBpbXBsaWVzIGVpdGhlciB0aGF0XG4gICAgICAvLyB0aGVyZSdzIGEgbmV3IHRhc2ssIG9yIHRoYXQgdGhlcmUncyBubyByZW1haW5pbmcgd29yayBvbiB0aGlzIHJvb3QuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH0gLy8gRGV0ZXJtaW5lIHRoZSBuZXh0IGxhbmVzIHRvIHdvcmsgb24sIHVzaW5nIHRoZSBmaWVsZHMgc3RvcmVkXG4gIC8vIG9uIHRoZSByb290LlxuXG5cbiAgdmFyIGxhbmVzID0gZ2V0TmV4dExhbmVzKHJvb3QsIHJvb3QgPT09IHdvcmtJblByb2dyZXNzUm9vdCA/IHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzIDogTm9MYW5lcyk7XG5cbiAgaWYgKGxhbmVzID09PSBOb0xhbmVzKSB7XG4gICAgLy8gRGVmZW5zaXZlIGNvZGluZy4gVGhpcyBpcyBuZXZlciBleHBlY3RlZCB0byBoYXBwZW4uXG4gICAgcmV0dXJuIG51bGw7XG4gIH0gLy8gV2UgZGlzYWJsZSB0aW1lLXNsaWNpbmcgaW4gc29tZSBjYXNlczogaWYgdGhlIHdvcmsgaGFzIGJlZW4gQ1BVLWJvdW5kXG4gIC8vIGZvciB0b28gbG9uZyAoXCJleHBpcmVkXCIgd29yaywgdG8gcHJldmVudCBzdGFydmF0aW9uKSwgb3Igd2UncmUgaW5cbiAgLy8gc3luYy11cGRhdGVzLWJ5LWRlZmF1bHQgbW9kZS5cbiAgLy8gVE9ETzogV2Ugb25seSBjaGVjayBgZGlkVGltZW91dGAgZGVmZW5zaXZlbHksIHRvIGFjY291bnQgZm9yIGEgU2NoZWR1bGVyXG4gIC8vIGJ1ZyB3ZSdyZSBzdGlsbCBpbnZlc3RpZ2F0aW5nLiBPbmNlIHRoZSBidWcgaW4gU2NoZWR1bGVyIGlzIGZpeGVkLFxuICAvLyB3ZSBjYW4gcmVtb3ZlIHRoaXMsIHNpbmNlIHdlIHRyYWNrIGV4cGlyYXRpb24gb3Vyc2VsdmVzLlxuXG5cbiAgdmFyIHNob3VsZFRpbWVTbGljZSA9ICFpbmNsdWRlc0Jsb2NraW5nTGFuZShyb290LCBsYW5lcykgJiYgIWluY2x1ZGVzRXhwaXJlZExhbmUocm9vdCwgbGFuZXMpICYmICggIWRpZFRpbWVvdXQpO1xuICB2YXIgZXhpdFN0YXR1cyA9IHNob3VsZFRpbWVTbGljZSA/IHJlbmRlclJvb3RDb25jdXJyZW50KHJvb3QsIGxhbmVzKSA6IHJlbmRlclJvb3RTeW5jKHJvb3QsIGxhbmVzKTtcblxuICBpZiAoZXhpdFN0YXR1cyAhPT0gUm9vdEluUHJvZ3Jlc3MpIHtcbiAgICBpZiAoZXhpdFN0YXR1cyA9PT0gUm9vdEVycm9yZWQpIHtcbiAgICAgIC8vIElmIHNvbWV0aGluZyB0aHJldyBhbiBlcnJvciwgdHJ5IHJlbmRlcmluZyBvbmUgbW9yZSB0aW1lLiBXZSdsbFxuICAgICAgLy8gcmVuZGVyIHN5bmNocm9ub3VzbHkgdG8gYmxvY2sgY29uY3VycmVudCBkYXRhIG11dGF0aW9ucywgYW5kIHdlJ2xsXG4gICAgICAvLyBpbmNsdWRlcyBhbGwgcGVuZGluZyB1cGRhdGVzIGFyZSBpbmNsdWRlZC4gSWYgaXQgc3RpbGwgZmFpbHMgYWZ0ZXJcbiAgICAgIC8vIHRoZSBzZWNvbmQgYXR0ZW1wdCwgd2UnbGwgZ2l2ZSB1cCBhbmQgY29tbWl0IHRoZSByZXN1bHRpbmcgdHJlZS5cbiAgICAgIHZhciBlcnJvclJldHJ5TGFuZXMgPSBnZXRMYW5lc1RvUmV0cnlTeW5jaHJvbm91c2x5T25FcnJvcihyb290KTtcblxuICAgICAgaWYgKGVycm9yUmV0cnlMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgICAgICBsYW5lcyA9IGVycm9yUmV0cnlMYW5lcztcbiAgICAgICAgZXhpdFN0YXR1cyA9IHJlY292ZXJGcm9tQ29uY3VycmVudEVycm9yKHJvb3QsIGVycm9yUmV0cnlMYW5lcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGV4aXRTdGF0dXMgPT09IFJvb3RGYXRhbEVycm9yZWQpIHtcbiAgICAgIHZhciBmYXRhbEVycm9yID0gd29ya0luUHJvZ3Jlc3NSb290RmF0YWxFcnJvcjtcbiAgICAgIHByZXBhcmVGcmVzaFN0YWNrKHJvb3QsIE5vTGFuZXMpO1xuICAgICAgbWFya1Jvb3RTdXNwZW5kZWQkMShyb290LCBsYW5lcyk7XG4gICAgICBlbnN1cmVSb290SXNTY2hlZHVsZWQocm9vdCwgbm93KCkpO1xuICAgICAgdGhyb3cgZmF0YWxFcnJvcjtcbiAgICB9XG5cbiAgICBpZiAoZXhpdFN0YXR1cyA9PT0gUm9vdERpZE5vdENvbXBsZXRlKSB7XG4gICAgICAvLyBUaGUgcmVuZGVyIHVud291bmQgd2l0aG91dCBjb21wbGV0aW5nIHRoZSB0cmVlLiBUaGlzIGhhcHBlbnMgaW4gc3BlY2lhbFxuICAgICAgLy8gY2FzZXMgd2hlcmUgbmVlZCB0byBleGl0IHRoZSBjdXJyZW50IHJlbmRlciB3aXRob3V0IHByb2R1Y2luZyBhXG4gICAgICAvLyBjb25zaXN0ZW50IHRyZWUgb3IgY29tbWl0dGluZy5cbiAgICAgIC8vXG4gICAgICAvLyBUaGlzIHNob3VsZCBvbmx5IGhhcHBlbiBkdXJpbmcgYSBjb25jdXJyZW50IHJlbmRlciwgbm90IGEgZGlzY3JldGUgb3JcbiAgICAgIC8vIHN5bmNocm9ub3VzIHVwZGF0ZS4gV2Ugc2hvdWxkIGhhdmUgYWxyZWFkeSBjaGVja2VkIGZvciB0aGlzIHdoZW4gd2VcbiAgICAgIC8vIHVud291bmQgdGhlIHN0YWNrLlxuICAgICAgbWFya1Jvb3RTdXNwZW5kZWQkMShyb290LCBsYW5lcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRoZSByZW5kZXIgY29tcGxldGVkLlxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyByZW5kZXIgbWF5IGhhdmUgeWllbGRlZCB0byBhIGNvbmN1cnJlbnQgZXZlbnQsIGFuZCBpZiBzbyxcbiAgICAgIC8vIGNvbmZpcm0gdGhhdCBhbnkgbmV3bHkgcmVuZGVyZWQgc3RvcmVzIGFyZSBjb25zaXN0ZW50LlxuICAgICAgLy8gVE9ETzogSXQncyBwb3NzaWJsZSB0aGF0IGV2ZW4gYSBjb25jdXJyZW50IHJlbmRlciBtYXkgbmV2ZXIgaGF2ZSB5aWVsZGVkXG4gICAgICAvLyB0byB0aGUgbWFpbiB0aHJlYWQsIGlmIGl0IHdhcyBmYXN0IGVub3VnaCwgb3IgaWYgaXQgZXhwaXJlZC4gV2UgY291bGRcbiAgICAgIC8vIHNraXAgdGhlIGNvbnNpc3RlbmN5IGNoZWNrIGluIHRoYXQgY2FzZSwgdG9vLlxuICAgICAgdmFyIHJlbmRlcldhc0NvbmN1cnJlbnQgPSAhaW5jbHVkZXNCbG9ja2luZ0xhbmUocm9vdCwgbGFuZXMpO1xuICAgICAgdmFyIGZpbmlzaGVkV29yayA9IHJvb3QuY3VycmVudC5hbHRlcm5hdGU7XG5cbiAgICAgIGlmIChyZW5kZXJXYXNDb25jdXJyZW50ICYmICFpc1JlbmRlckNvbnNpc3RlbnRXaXRoRXh0ZXJuYWxTdG9yZXMoZmluaXNoZWRXb3JrKSkge1xuICAgICAgICAvLyBBIHN0b3JlIHdhcyBtdXRhdGVkIGluIGFuIGludGVybGVhdmVkIGV2ZW50LiBSZW5kZXIgYWdhaW4sXG4gICAgICAgIC8vIHN5bmNocm9ub3VzbHksIHRvIGJsb2NrIGZ1cnRoZXIgbXV0YXRpb25zLlxuICAgICAgICBleGl0U3RhdHVzID0gcmVuZGVyUm9vdFN5bmMocm9vdCwgbGFuZXMpOyAvLyBXZSBuZWVkIHRvIGNoZWNrIGFnYWluIGlmIHNvbWV0aGluZyB0aHJld1xuXG4gICAgICAgIGlmIChleGl0U3RhdHVzID09PSBSb290RXJyb3JlZCkge1xuICAgICAgICAgIHZhciBfZXJyb3JSZXRyeUxhbmVzID0gZ2V0TGFuZXNUb1JldHJ5U3luY2hyb25vdXNseU9uRXJyb3Iocm9vdCk7XG5cbiAgICAgICAgICBpZiAoX2Vycm9yUmV0cnlMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgICAgICAgICAgbGFuZXMgPSBfZXJyb3JSZXRyeUxhbmVzO1xuICAgICAgICAgICAgZXhpdFN0YXR1cyA9IHJlY292ZXJGcm9tQ29uY3VycmVudEVycm9yKHJvb3QsIF9lcnJvclJldHJ5TGFuZXMpOyAvLyBXZSBhc3N1bWUgdGhlIHRyZWUgaXMgbm93IGNvbnNpc3RlbnQgYmVjYXVzZSB3ZSBkaWRuJ3QgeWllbGQgdG8gYW55XG4gICAgICAgICAgICAvLyBjb25jdXJyZW50IGV2ZW50cy5cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXhpdFN0YXR1cyA9PT0gUm9vdEZhdGFsRXJyb3JlZCkge1xuICAgICAgICAgIHZhciBfZmF0YWxFcnJvciA9IHdvcmtJblByb2dyZXNzUm9vdEZhdGFsRXJyb3I7XG4gICAgICAgICAgcHJlcGFyZUZyZXNoU3RhY2socm9vdCwgTm9MYW5lcyk7XG4gICAgICAgICAgbWFya1Jvb3RTdXNwZW5kZWQkMShyb290LCBsYW5lcyk7XG4gICAgICAgICAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIG5vdygpKTtcbiAgICAgICAgICB0aHJvdyBfZmF0YWxFcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSAvLyBXZSBub3cgaGF2ZSBhIGNvbnNpc3RlbnQgdHJlZS4gVGhlIG5leHQgc3RlcCBpcyBlaXRoZXIgdG8gY29tbWl0IGl0LFxuICAgICAgLy8gb3IsIGlmIHNvbWV0aGluZyBzdXNwZW5kZWQsIHdhaXQgdG8gY29tbWl0IGl0IGFmdGVyIGEgdGltZW91dC5cblxuXG4gICAgICByb290LmZpbmlzaGVkV29yayA9IGZpbmlzaGVkV29yaztcbiAgICAgIHJvb3QuZmluaXNoZWRMYW5lcyA9IGxhbmVzO1xuICAgICAgZmluaXNoQ29uY3VycmVudFJlbmRlcihyb290LCBleGl0U3RhdHVzLCBsYW5lcyk7XG4gICAgfVxuICB9XG5cbiAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIG5vdygpKTtcblxuICBpZiAocm9vdC5jYWxsYmFja05vZGUgPT09IG9yaWdpbmFsQ2FsbGJhY2tOb2RlKSB7XG4gICAgLy8gVGhlIHRhc2sgbm9kZSBzY2hlZHVsZWQgZm9yIHRoaXMgcm9vdCBpcyB0aGUgc2FtZSBvbmUgdGhhdCdzXG4gICAgLy8gY3VycmVudGx5IGV4ZWN1dGVkLiBOZWVkIHRvIHJldHVybiBhIGNvbnRpbnVhdGlvbi5cbiAgICByZXR1cm4gcGVyZm9ybUNvbmN1cnJlbnRXb3JrT25Sb290LmJpbmQobnVsbCwgcm9vdCk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gcmVjb3ZlckZyb21Db25jdXJyZW50RXJyb3Iocm9vdCwgZXJyb3JSZXRyeUxhbmVzKSB7XG4gIC8vIElmIGFuIGVycm9yIG9jY3VycmVkIGR1cmluZyBoeWRyYXRpb24sIGRpc2NhcmQgc2VydmVyIHJlc3BvbnNlIGFuZCBmYWxsXG4gIC8vIGJhY2sgdG8gY2xpZW50IHNpZGUgcmVuZGVyLlxuICAvLyBCZWZvcmUgcmVuZGVyaW5nIGFnYWluLCBzYXZlIHRoZSBlcnJvcnMgZnJvbSB0aGUgcHJldmlvdXMgYXR0ZW1wdC5cbiAgdmFyIGVycm9yc0Zyb21GaXJzdEF0dGVtcHQgPSB3b3JrSW5Qcm9ncmVzc1Jvb3RDb25jdXJyZW50RXJyb3JzO1xuXG4gIGlmIChpc1Jvb3REZWh5ZHJhdGVkKHJvb3QpKSB7XG4gICAgLy8gVGhlIHNoZWxsIGZhaWxlZCB0byBoeWRyYXRlLiBTZXQgYSBmbGFnIHRvIGZvcmNlIGEgY2xpZW50IHJlbmRlcmluZ1xuICAgIC8vIGR1cmluZyB0aGUgbmV4dCBhdHRlbXB0LiBUbyBkbyB0aGlzLCB3ZSBjYWxsIHByZXBhcmVGcmVzaFN0YWNrIG5vd1xuICAgIC8vIHRvIGNyZWF0ZSB0aGUgcm9vdCB3b3JrLWluLXByb2dyZXNzIGZpYmVyLiBUaGlzIGlzIGEgYml0IHdlaXJkIGluIHRlcm1zXG4gICAgLy8gb2YgZmFjdG9yaW5nLCBiZWNhdXNlIGl0IHJlbGllcyBvbiByZW5kZXJSb290U3luYyBub3QgY2FsbGluZ1xuICAgIC8vIHByZXBhcmVGcmVzaFN0YWNrIGFnYWluIGluIHRoZSBjYWxsIGJlbG93LCB3aGljaCBoYXBwZW5zIGJlY2F1c2UgdGhlXG4gICAgLy8gcm9vdCBhbmQgbGFuZXMgaGF2ZW4ndCBjaGFuZ2VkLlxuICAgIC8vXG4gICAgLy8gVE9ETzogSSB0aGluayB3aGF0IHdlIHNob3VsZCBkbyBpcyBzZXQgRm9yY2VDbGllbnRSZW5kZXIgaW5zaWRlXG4gICAgLy8gdGhyb3dFeGNlcHRpb24sIGxpa2Ugd2UgZG8gZm9yIG5lc3RlZCBTdXNwZW5zZSBib3VuZGFyaWVzLiBUaGUgcmVhc29uXG4gICAgLy8gaXQncyBoZXJlIGluc3RlYWQgaXMgc28gd2UgY2FuIHN3aXRjaCB0byB0aGUgc3luY2hyb25vdXMgd29yayBsb29wLCB0b28uXG4gICAgLy8gU29tZXRoaW5nIHRvIGNvbnNpZGVyIGZvciBhIGZ1dHVyZSByZWZhY3Rvci5cbiAgICB2YXIgcm9vdFdvcmtJblByb2dyZXNzID0gcHJlcGFyZUZyZXNoU3RhY2socm9vdCwgZXJyb3JSZXRyeUxhbmVzKTtcbiAgICByb290V29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRm9yY2VDbGllbnRSZW5kZXI7XG5cbiAgICB7XG4gICAgICBlcnJvckh5ZHJhdGluZ0NvbnRhaW5lcihyb290LmNvbnRhaW5lckluZm8pO1xuICAgIH1cbiAgfVxuXG4gIHZhciBleGl0U3RhdHVzID0gcmVuZGVyUm9vdFN5bmMocm9vdCwgZXJyb3JSZXRyeUxhbmVzKTtcblxuICBpZiAoZXhpdFN0YXR1cyAhPT0gUm9vdEVycm9yZWQpIHtcbiAgICAvLyBTdWNjZXNzZnVsbHkgZmluaXNoZWQgcmVuZGVyaW5nIG9uIHJldHJ5XG4gICAgLy8gVGhlIGVycm9ycyBmcm9tIHRoZSBmYWlsZWQgZmlyc3QgYXR0ZW1wdCBoYXZlIGJlZW4gcmVjb3ZlcmVkLiBBZGRcbiAgICAvLyB0aGVtIHRvIHRoZSBjb2xsZWN0aW9uIG9mIHJlY292ZXJhYmxlIGVycm9ycy4gV2UnbGwgbG9nIHRoZW0gaW4gdGhlXG4gICAgLy8gY29tbWl0IHBoYXNlLlxuICAgIHZhciBlcnJvcnNGcm9tU2Vjb25kQXR0ZW1wdCA9IHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzO1xuICAgIHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzID0gZXJyb3JzRnJvbUZpcnN0QXR0ZW1wdDsgLy8gVGhlIGVycm9ycyBmcm9tIHRoZSBzZWNvbmQgYXR0ZW1wdCBzaG91bGQgYmUgcXVldWVkIGFmdGVyIHRoZSBlcnJvcnNcbiAgICAvLyBmcm9tIHRoZSBmaXJzdCBhdHRlbXB0LCB0byBwcmVzZXJ2ZSB0aGUgY2F1c2FsIHNlcXVlbmNlLlxuXG4gICAgaWYgKGVycm9yc0Zyb21TZWNvbmRBdHRlbXB0ICE9PSBudWxsKSB7XG4gICAgICBxdWV1ZVJlY292ZXJhYmxlRXJyb3JzKGVycm9yc0Zyb21TZWNvbmRBdHRlbXB0KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXhpdFN0YXR1cztcbn1cblxuZnVuY3Rpb24gcXVldWVSZWNvdmVyYWJsZUVycm9ycyhlcnJvcnMpIHtcbiAgaWYgKHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzID09PSBudWxsKSB7XG4gICAgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMgPSBlcnJvcnM7XG4gIH0gZWxzZSB7XG4gICAgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMucHVzaC5hcHBseSh3b3JrSW5Qcm9ncmVzc1Jvb3RSZWNvdmVyYWJsZUVycm9ycywgZXJyb3JzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5pc2hDb25jdXJyZW50UmVuZGVyKHJvb3QsIGV4aXRTdGF0dXMsIGxhbmVzKSB7XG4gIHN3aXRjaCAoZXhpdFN0YXR1cykge1xuICAgIGNhc2UgUm9vdEluUHJvZ3Jlc3M6XG4gICAgY2FzZSBSb290RmF0YWxFcnJvcmVkOlxuICAgICAge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jvb3QgZGlkIG5vdCBjb21wbGV0ZS4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4nKTtcbiAgICAgIH1cbiAgICAvLyBGbG93IGtub3dzIGFib3V0IGludmFyaWFudCwgc28gaXQgY29tcGxhaW5zIGlmIEkgYWRkIGEgYnJlYWtcbiAgICAvLyBzdGF0ZW1lbnQsIGJ1dCBlc2xpbnQgZG9lc24ndCBrbm93IGFib3V0IGludmFyaWFudCwgc28gaXQgY29tcGxhaW5zXG4gICAgLy8gaWYgSSBkby4gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWZhbGx0aHJvdWdoXG5cbiAgICBjYXNlIFJvb3RFcnJvcmVkOlxuICAgICAge1xuICAgICAgICAvLyBXZSBzaG91bGQgaGF2ZSBhbHJlYWR5IGF0dGVtcHRlZCB0byByZXRyeSB0aGlzIHRyZWUuIElmIHdlIHJlYWNoZWRcbiAgICAgICAgLy8gdGhpcyBwb2ludCwgaXQgZXJyb3JlZCBhZ2Fpbi4gQ29tbWl0IGl0LlxuICAgICAgICBjb21taXRSb290KHJvb3QsIHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzLCB3b3JrSW5Qcm9ncmVzc1RyYW5zaXRpb25zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIFJvb3RTdXNwZW5kZWQ6XG4gICAgICB7XG4gICAgICAgIG1hcmtSb290U3VzcGVuZGVkJDEocm9vdCwgbGFuZXMpOyAvLyBXZSBoYXZlIGFuIGFjY2VwdGFibGUgbG9hZGluZyBzdGF0ZS4gV2UgbmVlZCB0byBmaWd1cmUgb3V0IGlmIHdlXG4gICAgICAgIC8vIHNob3VsZCBpbW1lZGlhdGVseSBjb21taXQgaXQgb3Igd2FpdCBhIGJpdC5cblxuICAgICAgICBpZiAoaW5jbHVkZXNPbmx5UmV0cmllcyhsYW5lcykgJiYgLy8gZG8gbm90IGRlbGF5IGlmIHdlJ3JlIGluc2lkZSBhbiBhY3QoKSBzY29wZVxuICAgICAgICAhc2hvdWxkRm9yY2VGbHVzaEZhbGxiYWNrc0luREVWKCkpIHtcbiAgICAgICAgICAvLyBUaGlzIHJlbmRlciBvbmx5IGluY2x1ZGVkIHJldHJpZXMsIG5vIHVwZGF0ZXMuIFRocm90dGxlIGNvbW1pdHRpbmdcbiAgICAgICAgICAvLyByZXRyaWVzIHNvIHRoYXQgd2UgZG9uJ3Qgc2hvdyB0b28gbWFueSBsb2FkaW5nIHN0YXRlcyB0b28gcXVpY2tseS5cbiAgICAgICAgICB2YXIgbXNVbnRpbFRpbWVvdXQgPSBnbG9iYWxNb3N0UmVjZW50RmFsbGJhY2tUaW1lICsgRkFMTEJBQ0tfVEhST1RUTEVfTVMgLSBub3coKTsgLy8gRG9uJ3QgYm90aGVyIHdpdGggYSB2ZXJ5IHNob3J0IHN1c3BlbnNlIHRpbWUuXG5cbiAgICAgICAgICBpZiAobXNVbnRpbFRpbWVvdXQgPiAxMCkge1xuICAgICAgICAgICAgdmFyIG5leHRMYW5lcyA9IGdldE5leHRMYW5lcyhyb290LCBOb0xhbmVzKTtcblxuICAgICAgICAgICAgaWYgKG5leHRMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgICAgICAgICAgICAvLyBUaGVyZSdzIGFkZGl0aW9uYWwgd29yayBvbiB0aGlzIHJvb3QuXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgc3VzcGVuZGVkTGFuZXMgPSByb290LnN1c3BlbmRlZExhbmVzO1xuXG4gICAgICAgICAgICBpZiAoIWlzU3Vic2V0T2ZMYW5lcyhzdXNwZW5kZWRMYW5lcywgbGFuZXMpKSB7XG4gICAgICAgICAgICAgIC8vIFdlIHNob3VsZCBwcmVmZXIgdG8gcmVuZGVyIHRoZSBmYWxsYmFjayBvZiBhdCB0aGUgbGFzdFxuICAgICAgICAgICAgICAvLyBzdXNwZW5kZWQgbGV2ZWwuIFBpbmcgdGhlIGxhc3Qgc3VzcGVuZGVkIGxldmVsIHRvIHRyeVxuICAgICAgICAgICAgICAvLyByZW5kZXJpbmcgaXQgYWdhaW4uXG4gICAgICAgICAgICAgIC8vIEZJWE1FOiBXaGF0IGlmIHRoZSBzdXNwZW5kZWQgbGFuZXMgYXJlIElkbGU/IFNob3VsZCBub3QgcmVzdGFydC5cbiAgICAgICAgICAgICAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgICAgICAgICAgICAgbWFya1Jvb3RQaW5nZWQocm9vdCwgc3VzcGVuZGVkTGFuZXMpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH0gLy8gVGhlIHJlbmRlciBpcyBzdXNwZW5kZWQsIGl0IGhhc24ndCB0aW1lZCBvdXQsIGFuZCB0aGVyZSdzIG5vXG4gICAgICAgICAgICAvLyBsb3dlciBwcmlvcml0eSB3b3JrIHRvIGRvLiBJbnN0ZWFkIG9mIGNvbW1pdHRpbmcgdGhlIGZhbGxiYWNrXG4gICAgICAgICAgICAvLyBpbW1lZGlhdGVseSwgd2FpdCBmb3IgbW9yZSBkYXRhIHRvIGFycml2ZS5cblxuXG4gICAgICAgICAgICByb290LnRpbWVvdXRIYW5kbGUgPSBzY2hlZHVsZVRpbWVvdXQoY29tbWl0Um9vdC5iaW5kKG51bGwsIHJvb3QsIHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzLCB3b3JrSW5Qcm9ncmVzc1RyYW5zaXRpb25zKSwgbXNVbnRpbFRpbWVvdXQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9IC8vIFRoZSB3b3JrIGV4cGlyZWQuIENvbW1pdCBpbW1lZGlhdGVseS5cblxuXG4gICAgICAgIGNvbW1pdFJvb3Qocm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMsIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgUm9vdFN1c3BlbmRlZFdpdGhEZWxheTpcbiAgICAgIHtcbiAgICAgICAgbWFya1Jvb3RTdXNwZW5kZWQkMShyb290LCBsYW5lcyk7XG5cbiAgICAgICAgaWYgKGluY2x1ZGVzT25seVRyYW5zaXRpb25zKGxhbmVzKSkge1xuICAgICAgICAgIC8vIFRoaXMgaXMgYSB0cmFuc2l0aW9uLCBzbyB3ZSBzaG91bGQgZXhpdCB3aXRob3V0IGNvbW1pdHRpbmcgYVxuICAgICAgICAgIC8vIHBsYWNlaG9sZGVyIGFuZCB3aXRob3V0IHNjaGVkdWxpbmcgYSB0aW1lb3V0LiBEZWxheSBpbmRlZmluaXRlbHlcbiAgICAgICAgICAvLyB1bnRpbCB3ZSByZWNlaXZlIG1vcmUgZGF0YS5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghc2hvdWxkRm9yY2VGbHVzaEZhbGxiYWNrc0luREVWKCkpIHtcbiAgICAgICAgICAvLyBUaGlzIGlzIG5vdCBhIHRyYW5zaXRpb24sIGJ1dCB3ZSBkaWQgdHJpZ2dlciBhbiBhdm9pZGVkIHN0YXRlLlxuICAgICAgICAgIC8vIFNjaGVkdWxlIGEgcGxhY2Vob2xkZXIgdG8gZGlzcGxheSBhZnRlciBhIHNob3J0IGRlbGF5LCB1c2luZyB0aGUgSnVzdFxuICAgICAgICAgIC8vIE5vdGljZWFibGUgRGlmZmVyZW5jZS5cbiAgICAgICAgICAvLyBUT0RPOiBJcyB0aGUgSk5EIG9wdGltaXphdGlvbiB3b3J0aCB0aGUgYWRkZWQgY29tcGxleGl0eT8gSWYgdGhpcyBpc1xuICAgICAgICAgIC8vIHRoZSBvbmx5IHJlYXNvbiB3ZSB0cmFjayB0aGUgZXZlbnQgdGltZSwgdGhlbiBwcm9iYWJseSBub3QuXG4gICAgICAgICAgLy8gQ29uc2lkZXIgcmVtb3ZpbmcuXG4gICAgICAgICAgdmFyIG1vc3RSZWNlbnRFdmVudFRpbWUgPSBnZXRNb3N0UmVjZW50RXZlbnRUaW1lKHJvb3QsIGxhbmVzKTtcbiAgICAgICAgICB2YXIgZXZlbnRUaW1lTXMgPSBtb3N0UmVjZW50RXZlbnRUaW1lO1xuICAgICAgICAgIHZhciB0aW1lRWxhcHNlZE1zID0gbm93KCkgLSBldmVudFRpbWVNcztcblxuICAgICAgICAgIHZhciBfbXNVbnRpbFRpbWVvdXQgPSBqbmQodGltZUVsYXBzZWRNcykgLSB0aW1lRWxhcHNlZE1zOyAvLyBEb24ndCBib3RoZXIgd2l0aCBhIHZlcnkgc2hvcnQgc3VzcGVuc2UgdGltZS5cblxuXG4gICAgICAgICAgaWYgKF9tc1VudGlsVGltZW91dCA+IDEwKSB7XG4gICAgICAgICAgICAvLyBJbnN0ZWFkIG9mIGNvbW1pdHRpbmcgdGhlIGZhbGxiYWNrIGltbWVkaWF0ZWx5LCB3YWl0IGZvciBtb3JlIGRhdGFcbiAgICAgICAgICAgIC8vIHRvIGFycml2ZS5cbiAgICAgICAgICAgIHJvb3QudGltZW91dEhhbmRsZSA9IHNjaGVkdWxlVGltZW91dChjb21taXRSb290LmJpbmQobnVsbCwgcm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMsIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMpLCBfbXNVbnRpbFRpbWVvdXQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9IC8vIENvbW1pdCB0aGUgcGxhY2Vob2xkZXIuXG5cblxuICAgICAgICBjb21taXRSb290KHJvb3QsIHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzLCB3b3JrSW5Qcm9ncmVzc1RyYW5zaXRpb25zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIFJvb3RDb21wbGV0ZWQ6XG4gICAgICB7XG4gICAgICAgIC8vIFRoZSB3b3JrIGNvbXBsZXRlZC4gUmVhZHkgdG8gY29tbWl0LlxuICAgICAgICBjb21taXRSb290KHJvb3QsIHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzLCB3b3JrSW5Qcm9ncmVzc1RyYW5zaXRpb25zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBkZWZhdWx0OlxuICAgICAge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gcm9vdCBleGl0IHN0YXR1cy4nKTtcbiAgICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBpc1JlbmRlckNvbnNpc3RlbnRXaXRoRXh0ZXJuYWxTdG9yZXMoZmluaXNoZWRXb3JrKSB7XG4gIC8vIFNlYXJjaCB0aGUgcmVuZGVyZWQgdHJlZSBmb3IgZXh0ZXJuYWwgc3RvcmUgcmVhZHMsIGFuZCBjaGVjayB3aGV0aGVyIHRoZVxuICAvLyBzdG9yZXMgd2VyZSBtdXRhdGVkIGluIGEgY29uY3VycmVudCBldmVudC4gSW50ZW50aW9uYWxseSB1c2luZyBhbiBpdGVyYXRpdmVcbiAgLy8gbG9vcCBpbnN0ZWFkIG9mIHJlY3Vyc2lvbiBzbyB3ZSBjYW4gZXhpdCBlYXJseS5cbiAgdmFyIG5vZGUgPSBmaW5pc2hlZFdvcms7XG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAobm9kZS5mbGFncyAmIFN0b3JlQ29uc2lzdGVuY3kpIHtcbiAgICAgIHZhciB1cGRhdGVRdWV1ZSA9IG5vZGUudXBkYXRlUXVldWU7XG5cbiAgICAgIGlmICh1cGRhdGVRdWV1ZSAhPT0gbnVsbCkge1xuICAgICAgICB2YXIgY2hlY2tzID0gdXBkYXRlUXVldWUuc3RvcmVzO1xuXG4gICAgICAgIGlmIChjaGVja3MgIT09IG51bGwpIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoZWNrcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGNoZWNrID0gY2hlY2tzW2ldO1xuICAgICAgICAgICAgdmFyIGdldFNuYXBzaG90ID0gY2hlY2suZ2V0U25hcHNob3Q7XG4gICAgICAgICAgICB2YXIgcmVuZGVyZWRWYWx1ZSA9IGNoZWNrLnZhbHVlO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBpZiAoIW9iamVjdElzKGdldFNuYXBzaG90KCksIHJlbmRlcmVkVmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgLy8gRm91bmQgYW4gaW5jb25zaXN0ZW50IHN0b3JlLlxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgLy8gSWYgYGdldFNuYXBzaG90YCB0aHJvd3MsIHJldHVybiBgZmFsc2VgLiBUaGlzIHdpbGwgc2NoZWR1bGVcbiAgICAgICAgICAgICAgLy8gYSByZS1yZW5kZXIsIGFuZCB0aGUgZXJyb3Igd2lsbCBiZSByZXRocm93biBkdXJpbmcgcmVuZGVyLlxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGNoaWxkID0gbm9kZS5jaGlsZDtcblxuICAgIGlmIChub2RlLnN1YnRyZWVGbGFncyAmIFN0b3JlQ29uc2lzdGVuY3kgJiYgY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGNoaWxkLnJldHVybiA9IG5vZGU7XG4gICAgICBub2RlID0gY2hpbGQ7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAobm9kZSA9PT0gZmluaXNoZWRXb3JrKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB3aGlsZSAobm9kZS5zaWJsaW5nID09PSBudWxsKSB7XG4gICAgICBpZiAobm9kZS5yZXR1cm4gPT09IG51bGwgfHwgbm9kZS5yZXR1cm4gPT09IGZpbmlzaGVkV29yaykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICAgIH1cblxuICAgIG5vZGUuc2libGluZy5yZXR1cm4gPSBub2RlLnJldHVybjtcbiAgICBub2RlID0gbm9kZS5zaWJsaW5nO1xuICB9IC8vIEZsb3cgZG9lc24ndCBrbm93IHRoaXMgaXMgdW5yZWFjaGFibGUsIGJ1dCBlc2xpbnQgZG9lc1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5yZWFjaGFibGVcblxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBtYXJrUm9vdFN1c3BlbmRlZCQxKHJvb3QsIHN1c3BlbmRlZExhbmVzKSB7XG4gIC8vIFdoZW4gc3VzcGVuZGluZywgd2Ugc2hvdWxkIGFsd2F5cyBleGNsdWRlIGxhbmVzIHRoYXQgd2VyZSBwaW5nZWQgb3IgKG1vcmVcbiAgLy8gcmFyZWx5LCBzaW5jZSB3ZSB0cnkgdG8gYXZvaWQgaXQpIHVwZGF0ZWQgZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UuXG4gIC8vIFRPRE86IExvbCBtYXliZSB0aGVyZSdzIGEgYmV0dGVyIHdheSB0byBmYWN0b3IgdGhpcyBiZXNpZGVzIHRoaXNcbiAgLy8gb2Jub3hpb3VzbHkgbmFtZWQgZnVuY3Rpb24gOilcbiAgc3VzcGVuZGVkTGFuZXMgPSByZW1vdmVMYW5lcyhzdXNwZW5kZWRMYW5lcywgd29ya0luUHJvZ3Jlc3NSb290UGluZ2VkTGFuZXMpO1xuICBzdXNwZW5kZWRMYW5lcyA9IHJlbW92ZUxhbmVzKHN1c3BlbmRlZExhbmVzLCB3b3JrSW5Qcm9ncmVzc1Jvb3RJbnRlcmxlYXZlZFVwZGF0ZWRMYW5lcyk7XG4gIG1hcmtSb290U3VzcGVuZGVkKHJvb3QsIHN1c3BlbmRlZExhbmVzKTtcbn0gLy8gVGhpcyBpcyB0aGUgZW50cnkgcG9pbnQgZm9yIHN5bmNocm9ub3VzIHRhc2tzIHRoYXQgZG9uJ3QgZ29cbi8vIHRocm91Z2ggU2NoZWR1bGVyXG5cblxuZnVuY3Rpb24gcGVyZm9ybVN5bmNXb3JrT25Sb290KHJvb3QpIHtcbiAge1xuICAgIHN5bmNOZXN0ZWRVcGRhdGVGbGFnKCk7XG4gIH1cblxuICBpZiAoKGV4ZWN1dGlvbkNvbnRleHQgJiAoUmVuZGVyQ29udGV4dCB8IENvbW1pdENvbnRleHQpKSAhPT0gTm9Db250ZXh0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaG91bGQgbm90IGFscmVhZHkgYmUgd29ya2luZy4nKTtcbiAgfVxuXG4gIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKTtcbiAgdmFyIGxhbmVzID0gZ2V0TmV4dExhbmVzKHJvb3QsIE5vTGFuZXMpO1xuXG4gIGlmICghaW5jbHVkZXNTb21lTGFuZShsYW5lcywgU3luY0xhbmUpKSB7XG4gICAgLy8gVGhlcmUncyBubyByZW1haW5pbmcgc3luYyB3b3JrIGxlZnQuXG4gICAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIG5vdygpKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBleGl0U3RhdHVzID0gcmVuZGVyUm9vdFN5bmMocm9vdCwgbGFuZXMpO1xuXG4gIGlmIChyb290LnRhZyAhPT0gTGVnYWN5Um9vdCAmJiBleGl0U3RhdHVzID09PSBSb290RXJyb3JlZCkge1xuICAgIC8vIElmIHNvbWV0aGluZyB0aHJldyBhbiBlcnJvciwgdHJ5IHJlbmRlcmluZyBvbmUgbW9yZSB0aW1lLiBXZSdsbCByZW5kZXJcbiAgICAvLyBzeW5jaHJvbm91c2x5IHRvIGJsb2NrIGNvbmN1cnJlbnQgZGF0YSBtdXRhdGlvbnMsIGFuZCB3ZSdsbCBpbmNsdWRlc1xuICAgIC8vIGFsbCBwZW5kaW5nIHVwZGF0ZXMgYXJlIGluY2x1ZGVkLiBJZiBpdCBzdGlsbCBmYWlscyBhZnRlciB0aGUgc2Vjb25kXG4gICAgLy8gYXR0ZW1wdCwgd2UnbGwgZ2l2ZSB1cCBhbmQgY29tbWl0IHRoZSByZXN1bHRpbmcgdHJlZS5cbiAgICB2YXIgZXJyb3JSZXRyeUxhbmVzID0gZ2V0TGFuZXNUb1JldHJ5U3luY2hyb25vdXNseU9uRXJyb3Iocm9vdCk7XG5cbiAgICBpZiAoZXJyb3JSZXRyeUxhbmVzICE9PSBOb0xhbmVzKSB7XG4gICAgICBsYW5lcyA9IGVycm9yUmV0cnlMYW5lcztcbiAgICAgIGV4aXRTdGF0dXMgPSByZWNvdmVyRnJvbUNvbmN1cnJlbnRFcnJvcihyb290LCBlcnJvclJldHJ5TGFuZXMpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChleGl0U3RhdHVzID09PSBSb290RmF0YWxFcnJvcmVkKSB7XG4gICAgdmFyIGZhdGFsRXJyb3IgPSB3b3JrSW5Qcm9ncmVzc1Jvb3RGYXRhbEVycm9yO1xuICAgIHByZXBhcmVGcmVzaFN0YWNrKHJvb3QsIE5vTGFuZXMpO1xuICAgIG1hcmtSb290U3VzcGVuZGVkJDEocm9vdCwgbGFuZXMpO1xuICAgIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBub3coKSk7XG4gICAgdGhyb3cgZmF0YWxFcnJvcjtcbiAgfVxuXG4gIGlmIChleGl0U3RhdHVzID09PSBSb290RGlkTm90Q29tcGxldGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jvb3QgZGlkIG5vdCBjb21wbGV0ZS4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4nKTtcbiAgfSAvLyBXZSBub3cgaGF2ZSBhIGNvbnNpc3RlbnQgdHJlZS4gQmVjYXVzZSB0aGlzIGlzIGEgc3luYyByZW5kZXIsIHdlXG4gIC8vIHdpbGwgY29tbWl0IGl0IGV2ZW4gaWYgc29tZXRoaW5nIHN1c3BlbmRlZC5cblxuXG4gIHZhciBmaW5pc2hlZFdvcmsgPSByb290LmN1cnJlbnQuYWx0ZXJuYXRlO1xuICByb290LmZpbmlzaGVkV29yayA9IGZpbmlzaGVkV29yaztcbiAgcm9vdC5maW5pc2hlZExhbmVzID0gbGFuZXM7XG4gIGNvbW1pdFJvb3Qocm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMsIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMpOyAvLyBCZWZvcmUgZXhpdGluZywgbWFrZSBzdXJlIHRoZXJlJ3MgYSBjYWxsYmFjayBzY2hlZHVsZWQgZm9yIHRoZSBuZXh0XG4gIC8vIHBlbmRpbmcgbGV2ZWwuXG5cbiAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIG5vdygpKTtcbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGZsdXNoUm9vdChyb290LCBsYW5lcykge1xuICBpZiAobGFuZXMgIT09IE5vTGFuZXMpIHtcbiAgICBtYXJrUm9vdEVudGFuZ2xlZChyb290LCBtZXJnZUxhbmVzKGxhbmVzLCBTeW5jTGFuZSkpO1xuICAgIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBub3coKSk7XG5cbiAgICBpZiAoKGV4ZWN1dGlvbkNvbnRleHQgJiAoUmVuZGVyQ29udGV4dCB8IENvbW1pdENvbnRleHQpKSA9PT0gTm9Db250ZXh0KSB7XG4gICAgICByZXNldFJlbmRlclRpbWVyKCk7XG4gICAgICBmbHVzaFN5bmNDYWxsYmFja3MoKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGJhdGNoZWRVcGRhdGVzJDEoZm4sIGEpIHtcbiAgdmFyIHByZXZFeGVjdXRpb25Db250ZXh0ID0gZXhlY3V0aW9uQ29udGV4dDtcbiAgZXhlY3V0aW9uQ29udGV4dCB8PSBCYXRjaGVkQ29udGV4dDtcblxuICB0cnkge1xuICAgIHJldHVybiBmbihhKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBleGVjdXRpb25Db250ZXh0ID0gcHJldkV4ZWN1dGlvbkNvbnRleHQ7IC8vIElmIHRoZXJlIHdlcmUgbGVnYWN5IHN5bmMgdXBkYXRlcywgZmx1c2ggdGhlbSBhdCB0aGUgZW5kIG9mIHRoZSBvdXRlclxuICAgIC8vIG1vc3QgYmF0Y2hlZFVwZGF0ZXMtbGlrZSBtZXRob2QuXG5cbiAgICBpZiAoZXhlY3V0aW9uQ29udGV4dCA9PT0gTm9Db250ZXh0ICYmIC8vIFRyZWF0IGBhY3RgIGFzIGlmIGl0J3MgaW5zaWRlIGBiYXRjaGVkVXBkYXRlc2AsIGV2ZW4gaW4gbGVnYWN5IG1vZGUuXG4gICAgISggUmVhY3RDdXJyZW50QWN0UXVldWUkMS5pc0JhdGNoaW5nTGVnYWN5KSkge1xuICAgICAgcmVzZXRSZW5kZXJUaW1lcigpO1xuICAgICAgZmx1c2hTeW5jQ2FsbGJhY2tzT25seUluTGVnYWN5TW9kZSgpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gZGlzY3JldGVVcGRhdGVzKGZuLCBhLCBiLCBjLCBkKSB7XG4gIHZhciBwcmV2aW91c1ByaW9yaXR5ID0gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KCk7XG4gIHZhciBwcmV2VHJhbnNpdGlvbiA9IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbjtcblxuICB0cnkge1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbiA9IG51bGw7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KERpc2NyZXRlRXZlbnRQcmlvcml0eSk7XG4gICAgcmV0dXJuIGZuKGEsIGIsIGMsIGQpO1xuICB9IGZpbmFsbHkge1xuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmV2aW91c1ByaW9yaXR5KTtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb24gPSBwcmV2VHJhbnNpdGlvbjtcblxuICAgIGlmIChleGVjdXRpb25Db250ZXh0ID09PSBOb0NvbnRleHQpIHtcbiAgICAgIHJlc2V0UmVuZGVyVGltZXIoKTtcbiAgICB9XG4gIH1cbn0gLy8gT3ZlcmxvYWQgdGhlIGRlZmluaXRpb24gdG8gdGhlIHR3byB2YWxpZCBzaWduYXR1cmVzLlxuLy8gV2FybmluZywgdGhpcyBvcHRzLW91dCBvZiBjaGVja2luZyB0aGUgZnVuY3Rpb24gYm9keS5cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlZGVjbGFyZVxuZnVuY3Rpb24gZmx1c2hTeW5jKGZuKSB7XG4gIC8vIEluIGxlZ2FjeSBtb2RlLCB3ZSBmbHVzaCBwZW5kaW5nIHBhc3NpdmUgZWZmZWN0cyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZVxuICAvLyBuZXh0IGV2ZW50LCBub3QgYXQgdGhlIGVuZCBvZiB0aGUgcHJldmlvdXMgb25lLlxuICBpZiAocm9vdFdpdGhQZW5kaW5nUGFzc2l2ZUVmZmVjdHMgIT09IG51bGwgJiYgcm9vdFdpdGhQZW5kaW5nUGFzc2l2ZUVmZmVjdHMudGFnID09PSBMZWdhY3lSb290ICYmIChleGVjdXRpb25Db250ZXh0ICYgKFJlbmRlckNvbnRleHQgfCBDb21taXRDb250ZXh0KSkgPT09IE5vQ29udGV4dCkge1xuICAgIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKTtcbiAgfVxuXG4gIHZhciBwcmV2RXhlY3V0aW9uQ29udGV4dCA9IGV4ZWN1dGlvbkNvbnRleHQ7XG4gIGV4ZWN1dGlvbkNvbnRleHQgfD0gQmF0Y2hlZENvbnRleHQ7XG4gIHZhciBwcmV2VHJhbnNpdGlvbiA9IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbjtcbiAgdmFyIHByZXZpb3VzUHJpb3JpdHkgPSBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoKTtcblxuICB0cnkge1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbiA9IG51bGw7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KERpc2NyZXRlRXZlbnRQcmlvcml0eSk7XG5cbiAgICBpZiAoZm4pIHtcbiAgICAgIHJldHVybiBmbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkocHJldmlvdXNQcmlvcml0eSk7XG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uID0gcHJldlRyYW5zaXRpb247XG4gICAgZXhlY3V0aW9uQ29udGV4dCA9IHByZXZFeGVjdXRpb25Db250ZXh0OyAvLyBGbHVzaCB0aGUgaW1tZWRpYXRlIGNhbGxiYWNrcyB0aGF0IHdlcmUgc2NoZWR1bGVkIGR1cmluZyB0aGlzIGJhdGNoLlxuICAgIC8vIE5vdGUgdGhhdCB0aGlzIHdpbGwgaGFwcGVuIGV2ZW4gaWYgYmF0Y2hlZFVwZGF0ZXMgaXMgaGlnaGVyIHVwXG4gICAgLy8gdGhlIHN0YWNrLlxuXG4gICAgaWYgKChleGVjdXRpb25Db250ZXh0ICYgKFJlbmRlckNvbnRleHQgfCBDb21taXRDb250ZXh0KSkgPT09IE5vQ29udGV4dCkge1xuICAgICAgZmx1c2hTeW5jQ2FsbGJhY2tzKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBpc0FscmVhZHlSZW5kZXJpbmcoKSB7XG4gIC8vIFVzZWQgYnkgdGhlIHJlbmRlcmVyIHRvIHByaW50IGEgd2FybmluZyBpZiBjZXJ0YWluIEFQSXMgYXJlIGNhbGxlZCBmcm9tXG4gIC8vIHRoZSB3cm9uZyBjb250ZXh0LlxuICByZXR1cm4gIChleGVjdXRpb25Db250ZXh0ICYgKFJlbmRlckNvbnRleHQgfCBDb21taXRDb250ZXh0KSkgIT09IE5vQ29udGV4dDtcbn1cbmZ1bmN0aW9uIHB1c2hSZW5kZXJMYW5lcyhmaWJlciwgbGFuZXMpIHtcbiAgcHVzaChzdWJ0cmVlUmVuZGVyTGFuZXNDdXJzb3IsIHN1YnRyZWVSZW5kZXJMYW5lcywgZmliZXIpO1xuICBzdWJ0cmVlUmVuZGVyTGFuZXMgPSBtZXJnZUxhbmVzKHN1YnRyZWVSZW5kZXJMYW5lcywgbGFuZXMpO1xuICB3b3JrSW5Qcm9ncmVzc1Jvb3RJbmNsdWRlZExhbmVzID0gbWVyZ2VMYW5lcyh3b3JrSW5Qcm9ncmVzc1Jvb3RJbmNsdWRlZExhbmVzLCBsYW5lcyk7XG59XG5mdW5jdGlvbiBwb3BSZW5kZXJMYW5lcyhmaWJlcikge1xuICBzdWJ0cmVlUmVuZGVyTGFuZXMgPSBzdWJ0cmVlUmVuZGVyTGFuZXNDdXJzb3IuY3VycmVudDtcbiAgcG9wKHN1YnRyZWVSZW5kZXJMYW5lc0N1cnNvciwgZmliZXIpO1xufVxuXG5mdW5jdGlvbiBwcmVwYXJlRnJlc2hTdGFjayhyb290LCBsYW5lcykge1xuICByb290LmZpbmlzaGVkV29yayA9IG51bGw7XG4gIHJvb3QuZmluaXNoZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHZhciB0aW1lb3V0SGFuZGxlID0gcm9vdC50aW1lb3V0SGFuZGxlO1xuXG4gIGlmICh0aW1lb3V0SGFuZGxlICE9PSBub1RpbWVvdXQpIHtcbiAgICAvLyBUaGUgcm9vdCBwcmV2aW91cyBzdXNwZW5kZWQgYW5kIHNjaGVkdWxlZCBhIHRpbWVvdXQgdG8gY29tbWl0IGEgZmFsbGJhY2tcbiAgICAvLyBzdGF0ZS4gTm93IHRoYXQgd2UgaGF2ZSBhZGRpdGlvbmFsIHdvcmssIGNhbmNlbCB0aGUgdGltZW91dC5cbiAgICByb290LnRpbWVvdXRIYW5kbGUgPSBub1RpbWVvdXQ7IC8vICRGbG93Rml4TWUgQ29tcGxhaW5zIG5vVGltZW91dCBpcyBub3QgYSBUaW1lb3V0SUQsIGRlc3BpdGUgdGhlIGNoZWNrIGFib3ZlXG5cbiAgICBjYW5jZWxUaW1lb3V0KHRpbWVvdXRIYW5kbGUpO1xuICB9XG5cbiAgaWYgKHdvcmtJblByb2dyZXNzICE9PSBudWxsKSB7XG4gICAgdmFyIGludGVycnVwdGVkV29yayA9IHdvcmtJblByb2dyZXNzLnJldHVybjtcblxuICAgIHdoaWxlIChpbnRlcnJ1cHRlZFdvcmsgIT09IG51bGwpIHtcbiAgICAgIHZhciBjdXJyZW50ID0gaW50ZXJydXB0ZWRXb3JrLmFsdGVybmF0ZTtcbiAgICAgIHVud2luZEludGVycnVwdGVkV29yayhjdXJyZW50LCBpbnRlcnJ1cHRlZFdvcmspO1xuICAgICAgaW50ZXJydXB0ZWRXb3JrID0gaW50ZXJydXB0ZWRXb3JrLnJldHVybjtcbiAgICB9XG4gIH1cblxuICB3b3JrSW5Qcm9ncmVzc1Jvb3QgPSByb290O1xuICB2YXIgcm9vdFdvcmtJblByb2dyZXNzID0gY3JlYXRlV29ya0luUHJvZ3Jlc3Mocm9vdC5jdXJyZW50LCBudWxsKTtcbiAgd29ya0luUHJvZ3Jlc3MgPSByb290V29ya0luUHJvZ3Jlc3M7XG4gIHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzID0gc3VidHJlZVJlbmRlckxhbmVzID0gd29ya0luUHJvZ3Jlc3NSb290SW5jbHVkZWRMYW5lcyA9IGxhbmVzO1xuICB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID0gUm9vdEluUHJvZ3Jlc3M7XG4gIHdvcmtJblByb2dyZXNzUm9vdEZhdGFsRXJyb3IgPSBudWxsO1xuICB3b3JrSW5Qcm9ncmVzc1Jvb3RTa2lwcGVkTGFuZXMgPSBOb0xhbmVzO1xuICB3b3JrSW5Qcm9ncmVzc1Jvb3RJbnRlcmxlYXZlZFVwZGF0ZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHdvcmtJblByb2dyZXNzUm9vdFBpbmdlZExhbmVzID0gTm9MYW5lcztcbiAgd29ya0luUHJvZ3Jlc3NSb290Q29uY3VycmVudEVycm9ycyA9IG51bGw7XG4gIHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzID0gbnVsbDtcbiAgZmluaXNoUXVldWVpbmdDb25jdXJyZW50VXBkYXRlcygpO1xuXG4gIHtcbiAgICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5kaXNjYXJkUGVuZGluZ1dhcm5pbmdzKCk7XG4gIH1cblxuICByZXR1cm4gcm9vdFdvcmtJblByb2dyZXNzO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVFcnJvcihyb290LCB0aHJvd25WYWx1ZSkge1xuICBkbyB7XG4gICAgdmFyIGVycm9yZWRXb3JrID0gd29ya0luUHJvZ3Jlc3M7XG5cbiAgICB0cnkge1xuICAgICAgLy8gUmVzZXQgbW9kdWxlLWxldmVsIHN0YXRlIHRoYXQgd2FzIHNldCBkdXJpbmcgdGhlIHJlbmRlciBwaGFzZS5cbiAgICAgIHJlc2V0Q29udGV4dERlcGVuZGVuY2llcygpO1xuICAgICAgcmVzZXRIb29rc0FmdGVyVGhyb3coKTtcbiAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7IC8vIFRPRE86IEkgZm91bmQgYW5kIGFkZGVkIHRoaXMgbWlzc2luZyBsaW5lIHdoaWxlIGludmVzdGlnYXRpbmcgYVxuICAgICAgLy8gc2VwYXJhdGUgaXNzdWUuIFdyaXRlIGEgcmVncmVzc2lvbiB0ZXN0IHVzaW5nIHN0cmluZyByZWZzLlxuXG4gICAgICBSZWFjdEN1cnJlbnRPd25lciQyLmN1cnJlbnQgPSBudWxsO1xuXG4gICAgICBpZiAoZXJyb3JlZFdvcmsgPT09IG51bGwgfHwgZXJyb3JlZFdvcmsucmV0dXJuID09PSBudWxsKSB7XG4gICAgICAgIC8vIEV4cGVjdGVkIHRvIGJlIHdvcmtpbmcgb24gYSBub24tcm9vdCBmaWJlci4gVGhpcyBpcyBhIGZhdGFsIGVycm9yXG4gICAgICAgIC8vIGJlY2F1c2UgdGhlcmUncyBubyBhbmNlc3RvciB0aGF0IGNhbiBoYW5kbGUgaXQ7IHRoZSByb290IGlzXG4gICAgICAgIC8vIHN1cHBvc2VkIHRvIGNhcHR1cmUgYWxsIGVycm9ycyB0aGF0IHdlcmVuJ3QgY2F1Z2h0IGJ5IGFuIGVycm9yXG4gICAgICAgIC8vIGJvdW5kYXJ5LlxuICAgICAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID0gUm9vdEZhdGFsRXJyb3JlZDtcbiAgICAgICAgd29ya0luUHJvZ3Jlc3NSb290RmF0YWxFcnJvciA9IHRocm93blZhbHVlOyAvLyBTZXQgYHdvcmtJblByb2dyZXNzYCB0byBudWxsLiBUaGlzIHJlcHJlc2VudHMgYWR2YW5jaW5nIHRvIHRoZSBuZXh0XG4gICAgICAgIC8vIHNpYmxpbmcsIG9yIHRoZSBwYXJlbnQgaWYgdGhlcmUgYXJlIG5vIHNpYmxpbmdzLiBCdXQgc2luY2UgdGhlIHJvb3RcbiAgICAgICAgLy8gaGFzIG5vIHNpYmxpbmdzIG5vciBhIHBhcmVudCwgd2Ugc2V0IGl0IHRvIG51bGwuIFVzdWFsbHkgdGhpcyBpc1xuICAgICAgICAvLyBoYW5kbGVkIGJ5IGBjb21wbGV0ZVVuaXRPZldvcmtgIG9yIGB1bndpbmRXb3JrYCwgYnV0IHNpbmNlIHdlJ3JlXG4gICAgICAgIC8vIGludGVudGlvbmFsbHkgbm90IGNhbGxpbmcgdGhvc2UsIHdlIG5lZWQgc2V0IGl0IGhlcmUuXG4gICAgICAgIC8vIFRPRE86IENvbnNpZGVyIGNhbGxpbmcgYHVud2luZFdvcmtgIHRvIHBvcCB0aGUgY29udGV4dHMuXG5cbiAgICAgICAgd29ya0luUHJvZ3Jlc3MgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChlbmFibGVQcm9maWxlclRpbWVyICYmIGVycm9yZWRXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkge1xuICAgICAgICAvLyBSZWNvcmQgdGhlIHRpbWUgc3BlbnQgcmVuZGVyaW5nIGJlZm9yZSBhbiBlcnJvciB3YXMgdGhyb3duLiBUaGlzXG4gICAgICAgIC8vIGF2b2lkcyBpbmFjY3VyYXRlIFByb2ZpbGVyIGR1cmF0aW9ucyBpbiB0aGUgY2FzZSBvZiBhXG4gICAgICAgIC8vIHN1c3BlbmRlZCByZW5kZXIuXG4gICAgICAgIHN0b3BQcm9maWxlclRpbWVySWZSdW5uaW5nQW5kUmVjb3JkRGVsdGEoZXJyb3JlZFdvcmssIHRydWUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZW5hYmxlU2NoZWR1bGluZ1Byb2ZpbGVyKSB7XG4gICAgICAgIG1hcmtDb21wb25lbnRSZW5kZXJTdG9wcGVkKCk7XG5cbiAgICAgICAgaWYgKHRocm93blZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB0aHJvd25WYWx1ZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHRocm93blZhbHVlLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB2YXIgd2FrZWFibGUgPSB0aHJvd25WYWx1ZTtcbiAgICAgICAgICBtYXJrQ29tcG9uZW50U3VzcGVuZGVkKGVycm9yZWRXb3JrLCB3YWtlYWJsZSwgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1hcmtDb21wb25lbnRFcnJvcmVkKGVycm9yZWRXb3JrLCB0aHJvd25WYWx1ZSwgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRocm93RXhjZXB0aW9uKHJvb3QsIGVycm9yZWRXb3JrLnJldHVybiwgZXJyb3JlZFdvcmssIHRocm93blZhbHVlLCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcyk7XG4gICAgICBjb21wbGV0ZVVuaXRPZldvcmsoZXJyb3JlZFdvcmspO1xuICAgIH0gY2F0Y2ggKHlldEFub3RoZXJUaHJvd25WYWx1ZSkge1xuICAgICAgLy8gU29tZXRoaW5nIGluIHRoZSByZXR1cm4gcGF0aCBhbHNvIHRocmV3LlxuICAgICAgdGhyb3duVmFsdWUgPSB5ZXRBbm90aGVyVGhyb3duVmFsdWU7XG5cbiAgICAgIGlmICh3b3JrSW5Qcm9ncmVzcyA9PT0gZXJyb3JlZFdvcmsgJiYgZXJyb3JlZFdvcmsgIT09IG51bGwpIHtcbiAgICAgICAgLy8gSWYgdGhpcyBib3VuZGFyeSBoYXMgYWxyZWFkeSBlcnJvcmVkLCB0aGVuIHdlIGhhZCB0cm91YmxlIHByb2Nlc3NpbmdcbiAgICAgICAgLy8gdGhlIGVycm9yLiBCdWJibGUgaXQgdG8gdGhlIG5leHQgYm91bmRhcnkuXG4gICAgICAgIGVycm9yZWRXb3JrID0gZXJyb3JlZFdvcmsucmV0dXJuO1xuICAgICAgICB3b3JrSW5Qcm9ncmVzcyA9IGVycm9yZWRXb3JrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXJyb3JlZFdvcmsgPSB3b3JrSW5Qcm9ncmVzcztcbiAgICAgIH1cblxuICAgICAgY29udGludWU7XG4gICAgfSAvLyBSZXR1cm4gdG8gdGhlIG5vcm1hbCB3b3JrIGxvb3AuXG5cblxuICAgIHJldHVybjtcbiAgfSB3aGlsZSAodHJ1ZSk7XG59XG5cbmZ1bmN0aW9uIHB1c2hEaXNwYXRjaGVyKCkge1xuICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDIuY3VycmVudDtcbiAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQyLmN1cnJlbnQgPSBDb250ZXh0T25seURpc3BhdGNoZXI7XG5cbiAgaWYgKHByZXZEaXNwYXRjaGVyID09PSBudWxsKSB7XG4gICAgLy8gVGhlIFJlYWN0IGlzb21vcnBoaWMgcGFja2FnZSBkb2VzIG5vdCBpbmNsdWRlIGEgZGVmYXVsdCBkaXNwYXRjaGVyLlxuICAgIC8vIEluc3RlYWQgdGhlIGZpcnN0IHJlbmRlcmVyIHdpbGwgbGF6aWx5IGF0dGFjaCBvbmUsIGluIG9yZGVyIHRvIGdpdmVcbiAgICAvLyBuaWNlciBlcnJvciBtZXNzYWdlcy5cbiAgICByZXR1cm4gQ29udGV4dE9ubHlEaXNwYXRjaGVyO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBwcmV2RGlzcGF0Y2hlcjtcbiAgfVxufVxuXG5mdW5jdGlvbiBwb3BEaXNwYXRjaGVyKHByZXZEaXNwYXRjaGVyKSB7XG4gIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMi5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG59XG5cbmZ1bmN0aW9uIG1hcmtDb21taXRUaW1lT2ZGYWxsYmFjaygpIHtcbiAgZ2xvYmFsTW9zdFJlY2VudEZhbGxiYWNrVGltZSA9IG5vdygpO1xufVxuZnVuY3Rpb24gbWFya1NraXBwZWRVcGRhdGVMYW5lcyhsYW5lKSB7XG4gIHdvcmtJblByb2dyZXNzUm9vdFNraXBwZWRMYW5lcyA9IG1lcmdlTGFuZXMobGFuZSwgd29ya0luUHJvZ3Jlc3NSb290U2tpcHBlZExhbmVzKTtcbn1cbmZ1bmN0aW9uIHJlbmRlckRpZFN1c3BlbmQoKSB7XG4gIGlmICh3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID09PSBSb290SW5Qcm9ncmVzcykge1xuICAgIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPSBSb290U3VzcGVuZGVkO1xuICB9XG59XG5mdW5jdGlvbiByZW5kZXJEaWRTdXNwZW5kRGVsYXlJZlBvc3NpYmxlKCkge1xuICBpZiAod29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9PT0gUm9vdEluUHJvZ3Jlc3MgfHwgd29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9PT0gUm9vdFN1c3BlbmRlZCB8fCB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID09PSBSb290RXJyb3JlZCkge1xuICAgIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPSBSb290U3VzcGVuZGVkV2l0aERlbGF5O1xuICB9IC8vIENoZWNrIGlmIHRoZXJlIGFyZSB1cGRhdGVzIHRoYXQgd2Ugc2tpcHBlZCB0cmVlIHRoYXQgbWlnaHQgaGF2ZSB1bmJsb2NrZWRcbiAgLy8gdGhpcyByZW5kZXIuXG5cblxuICBpZiAod29ya0luUHJvZ3Jlc3NSb290ICE9PSBudWxsICYmIChpbmNsdWRlc05vbklkbGVXb3JrKHdvcmtJblByb2dyZXNzUm9vdFNraXBwZWRMYW5lcykgfHwgaW5jbHVkZXNOb25JZGxlV29yayh3b3JrSW5Qcm9ncmVzc1Jvb3RJbnRlcmxlYXZlZFVwZGF0ZWRMYW5lcykpKSB7XG4gICAgLy8gTWFyayB0aGUgY3VycmVudCByZW5kZXIgYXMgc3VzcGVuZGVkIHNvIHRoYXQgd2Ugc3dpdGNoIHRvIHdvcmtpbmcgb25cbiAgICAvLyB0aGUgdXBkYXRlcyB0aGF0IHdlcmUgc2tpcHBlZC4gVXN1YWxseSB3ZSBvbmx5IHN1c3BlbmQgYXQgdGhlIGVuZCBvZlxuICAgIC8vIHRoZSByZW5kZXIgcGhhc2UuXG4gICAgLy8gVE9ETzogV2Ugc2hvdWxkIHByb2JhYmx5IGFsd2F5cyBtYXJrIHRoZSByb290IGFzIHN1c3BlbmRlZCBpbW1lZGlhdGVseVxuICAgIC8vIChpbnNpZGUgdGhpcyBmdW5jdGlvbiksIHNpbmNlIGJ5IHN1c3BlbmRpbmcgYXQgdGhlIGVuZCBvZiB0aGUgcmVuZGVyXG4gICAgLy8gcGhhc2UgaW50cm9kdWNlcyBhIHBvdGVudGlhbCBtaXN0YWtlIHdoZXJlIHdlIHN1c3BlbmQgbGFuZXMgdGhhdCB3ZXJlXG4gICAgLy8gcGluZ2VkIG9yIHVwZGF0ZWQgd2hpbGUgd2Ugd2VyZSByZW5kZXJpbmcuXG4gICAgbWFya1Jvb3RTdXNwZW5kZWQkMSh3b3JrSW5Qcm9ncmVzc1Jvb3QsIHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzKTtcbiAgfVxufVxuZnVuY3Rpb24gcmVuZGVyRGlkRXJyb3IoZXJyb3IpIHtcbiAgaWYgKHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgIT09IFJvb3RTdXNwZW5kZWRXaXRoRGVsYXkpIHtcbiAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID0gUm9vdEVycm9yZWQ7XG4gIH1cblxuICBpZiAod29ya0luUHJvZ3Jlc3NSb290Q29uY3VycmVudEVycm9ycyA9PT0gbnVsbCkge1xuICAgIHdvcmtJblByb2dyZXNzUm9vdENvbmN1cnJlbnRFcnJvcnMgPSBbZXJyb3JdO1xuICB9IGVsc2Uge1xuICAgIHdvcmtJblByb2dyZXNzUm9vdENvbmN1cnJlbnRFcnJvcnMucHVzaChlcnJvcik7XG4gIH1cbn0gLy8gQ2FsbGVkIGR1cmluZyByZW5kZXIgdG8gZGV0ZXJtaW5lIGlmIGFueXRoaW5nIGhhcyBzdXNwZW5kZWQuXG4vLyBSZXR1cm5zIGZhbHNlIGlmIHdlJ3JlIG5vdCBzdXJlLlxuXG5mdW5jdGlvbiByZW5kZXJIYXNOb3RTdXNwZW5kZWRZZXQoKSB7XG4gIC8vIElmIHNvbWV0aGluZyBlcnJvcmVkIG9yIGNvbXBsZXRlZCwgd2UgY2FuJ3QgcmVhbGx5IGJlIHN1cmUsXG4gIC8vIHNvIHRob3NlIGFyZSBmYWxzZS5cbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPT09IFJvb3RJblByb2dyZXNzO1xufVxuXG5mdW5jdGlvbiByZW5kZXJSb290U3luYyhyb290LCBsYW5lcykge1xuICB2YXIgcHJldkV4ZWN1dGlvbkNvbnRleHQgPSBleGVjdXRpb25Db250ZXh0O1xuICBleGVjdXRpb25Db250ZXh0IHw9IFJlbmRlckNvbnRleHQ7XG4gIHZhciBwcmV2RGlzcGF0Y2hlciA9IHB1c2hEaXNwYXRjaGVyKCk7IC8vIElmIHRoZSByb290IG9yIGxhbmVzIGhhdmUgY2hhbmdlZCwgdGhyb3cgb3V0IHRoZSBleGlzdGluZyBzdGFja1xuICAvLyBhbmQgcHJlcGFyZSBhIGZyZXNoIG9uZS4gT3RoZXJ3aXNlIHdlJ2xsIGNvbnRpbnVlIHdoZXJlIHdlIGxlZnQgb2ZmLlxuXG4gIGlmICh3b3JrSW5Qcm9ncmVzc1Jvb3QgIT09IHJvb3QgfHwgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMgIT09IGxhbmVzKSB7XG4gICAge1xuICAgICAgaWYgKGlzRGV2VG9vbHNQcmVzZW50KSB7XG4gICAgICAgIHZhciBtZW1vaXplZFVwZGF0ZXJzID0gcm9vdC5tZW1vaXplZFVwZGF0ZXJzO1xuXG4gICAgICAgIGlmIChtZW1vaXplZFVwZGF0ZXJzLnNpemUgPiAwKSB7XG4gICAgICAgICAgcmVzdG9yZVBlbmRpbmdVcGRhdGVycyhyb290LCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcyk7XG4gICAgICAgICAgbWVtb2l6ZWRVcGRhdGVycy5jbGVhcigpO1xuICAgICAgICB9IC8vIEF0IHRoaXMgcG9pbnQsIG1vdmUgRmliZXJzIHRoYXQgc2NoZWR1bGVkIHRoZSB1cGNvbWluZyB3b3JrIGZyb20gdGhlIE1hcCB0byB0aGUgU2V0LlxuICAgICAgICAvLyBJZiB3ZSBiYWlsb3V0IG9uIHRoaXMgd29yaywgd2UnbGwgbW92ZSB0aGVtIGJhY2sgKGxpa2UgYWJvdmUpLlxuICAgICAgICAvLyBJdCdzIGltcG9ydGFudCB0byBtb3ZlIHRoZW0gbm93IGluIGNhc2UgdGhlIHdvcmsgc3Bhd25zIG1vcmUgd29yayBhdCB0aGUgc2FtZSBwcmlvcml0eSB3aXRoIGRpZmZlcmVudCB1cGRhdGVycy5cbiAgICAgICAgLy8gVGhhdCB3YXkgd2UgY2FuIGtlZXAgdGhlIGN1cnJlbnQgdXBkYXRlIGFuZCBmdXR1cmUgdXBkYXRlcyBzZXBhcmF0ZS5cblxuXG4gICAgICAgIG1vdmVQZW5kaW5nRmliZXJzVG9NZW1vaXplZChyb290LCBsYW5lcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgd29ya0luUHJvZ3Jlc3NUcmFuc2l0aW9ucyA9IGdldFRyYW5zaXRpb25zRm9yTGFuZXMoKTtcbiAgICBwcmVwYXJlRnJlc2hTdGFjayhyb290LCBsYW5lcyk7XG4gIH1cblxuICB7XG4gICAgbWFya1JlbmRlclN0YXJ0ZWQobGFuZXMpO1xuICB9XG5cbiAgZG8ge1xuICAgIHRyeSB7XG4gICAgICB3b3JrTG9vcFN5bmMoKTtcbiAgICAgIGJyZWFrO1xuICAgIH0gY2F0Y2ggKHRocm93blZhbHVlKSB7XG4gICAgICBoYW5kbGVFcnJvcihyb290LCB0aHJvd25WYWx1ZSk7XG4gICAgfVxuICB9IHdoaWxlICh0cnVlKTtcblxuICByZXNldENvbnRleHREZXBlbmRlbmNpZXMoKTtcbiAgZXhlY3V0aW9uQ29udGV4dCA9IHByZXZFeGVjdXRpb25Db250ZXh0O1xuICBwb3BEaXNwYXRjaGVyKHByZXZEaXNwYXRjaGVyKTtcblxuICBpZiAod29ya0luUHJvZ3Jlc3MgIT09IG51bGwpIHtcbiAgICAvLyBUaGlzIGlzIGEgc3luYyByZW5kZXIsIHNvIHdlIHNob3VsZCBoYXZlIGZpbmlzaGVkIHRoZSB3aG9sZSB0cmVlLlxuICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNvbW1pdCBhbiBpbmNvbXBsZXRlIHJvb3QuIFRoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhICcgKyAnYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgfVxuXG4gIHtcbiAgICBtYXJrUmVuZGVyU3RvcHBlZCgpO1xuICB9IC8vIFNldCB0aGlzIHRvIG51bGwgdG8gaW5kaWNhdGUgdGhlcmUncyBubyBpbi1wcm9ncmVzcyByZW5kZXIuXG5cblxuICB3b3JrSW5Qcm9ncmVzc1Jvb3QgPSBudWxsO1xuICB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcyA9IE5vTGFuZXM7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzO1xufSAvLyBUaGUgd29yayBsb29wIGlzIGFuIGV4dHJlbWVseSBob3QgcGF0aC4gVGVsbCBDbG9zdXJlIG5vdCB0byBpbmxpbmUgaXQuXG5cbi8qKiBAbm9pbmxpbmUgKi9cblxuXG5mdW5jdGlvbiB3b3JrTG9vcFN5bmMoKSB7XG4gIC8vIEFscmVhZHkgdGltZWQgb3V0LCBzbyBwZXJmb3JtIHdvcmsgd2l0aG91dCBjaGVja2luZyBpZiB3ZSBuZWVkIHRvIHlpZWxkLlxuICB3aGlsZSAod29ya0luUHJvZ3Jlc3MgIT09IG51bGwpIHtcbiAgICBwZXJmb3JtVW5pdE9mV29yayh3b3JrSW5Qcm9ncmVzcyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVuZGVyUm9vdENvbmN1cnJlbnQocm9vdCwgbGFuZXMpIHtcbiAgdmFyIHByZXZFeGVjdXRpb25Db250ZXh0ID0gZXhlY3V0aW9uQ29udGV4dDtcbiAgZXhlY3V0aW9uQ29udGV4dCB8PSBSZW5kZXJDb250ZXh0O1xuICB2YXIgcHJldkRpc3BhdGNoZXIgPSBwdXNoRGlzcGF0Y2hlcigpOyAvLyBJZiB0aGUgcm9vdCBvciBsYW5lcyBoYXZlIGNoYW5nZWQsIHRocm93IG91dCB0aGUgZXhpc3Rpbmcgc3RhY2tcbiAgLy8gYW5kIHByZXBhcmUgYSBmcmVzaCBvbmUuIE90aGVyd2lzZSB3ZSdsbCBjb250aW51ZSB3aGVyZSB3ZSBsZWZ0IG9mZi5cblxuICBpZiAod29ya0luUHJvZ3Jlc3NSb290ICE9PSByb290IHx8IHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzICE9PSBsYW5lcykge1xuICAgIHtcbiAgICAgIGlmIChpc0RldlRvb2xzUHJlc2VudCkge1xuICAgICAgICB2YXIgbWVtb2l6ZWRVcGRhdGVycyA9IHJvb3QubWVtb2l6ZWRVcGRhdGVycztcblxuICAgICAgICBpZiAobWVtb2l6ZWRVcGRhdGVycy5zaXplID4gMCkge1xuICAgICAgICAgIHJlc3RvcmVQZW5kaW5nVXBkYXRlcnMocm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMpO1xuICAgICAgICAgIG1lbW9pemVkVXBkYXRlcnMuY2xlYXIoKTtcbiAgICAgICAgfSAvLyBBdCB0aGlzIHBvaW50LCBtb3ZlIEZpYmVycyB0aGF0IHNjaGVkdWxlZCB0aGUgdXBjb21pbmcgd29yayBmcm9tIHRoZSBNYXAgdG8gdGhlIFNldC5cbiAgICAgICAgLy8gSWYgd2UgYmFpbG91dCBvbiB0aGlzIHdvcmssIHdlJ2xsIG1vdmUgdGhlbSBiYWNrIChsaWtlIGFib3ZlKS5cbiAgICAgICAgLy8gSXQncyBpbXBvcnRhbnQgdG8gbW92ZSB0aGVtIG5vdyBpbiBjYXNlIHRoZSB3b3JrIHNwYXducyBtb3JlIHdvcmsgYXQgdGhlIHNhbWUgcHJpb3JpdHkgd2l0aCBkaWZmZXJlbnQgdXBkYXRlcnMuXG4gICAgICAgIC8vIFRoYXQgd2F5IHdlIGNhbiBrZWVwIHRoZSBjdXJyZW50IHVwZGF0ZSBhbmQgZnV0dXJlIHVwZGF0ZXMgc2VwYXJhdGUuXG5cblxuICAgICAgICBtb3ZlUGVuZGluZ0ZpYmVyc1RvTWVtb2l6ZWQocm9vdCwgbGFuZXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMgPSBnZXRUcmFuc2l0aW9uc0ZvckxhbmVzKCk7XG4gICAgcmVzZXRSZW5kZXJUaW1lcigpO1xuICAgIHByZXBhcmVGcmVzaFN0YWNrKHJvb3QsIGxhbmVzKTtcbiAgfVxuXG4gIHtcbiAgICBtYXJrUmVuZGVyU3RhcnRlZChsYW5lcyk7XG4gIH1cblxuICBkbyB7XG4gICAgdHJ5IHtcbiAgICAgIHdvcmtMb29wQ29uY3VycmVudCgpO1xuICAgICAgYnJlYWs7XG4gICAgfSBjYXRjaCAodGhyb3duVmFsdWUpIHtcbiAgICAgIGhhbmRsZUVycm9yKHJvb3QsIHRocm93blZhbHVlKTtcbiAgICB9XG4gIH0gd2hpbGUgKHRydWUpO1xuXG4gIHJlc2V0Q29udGV4dERlcGVuZGVuY2llcygpO1xuICBwb3BEaXNwYXRjaGVyKHByZXZEaXNwYXRjaGVyKTtcbiAgZXhlY3V0aW9uQ29udGV4dCA9IHByZXZFeGVjdXRpb25Db250ZXh0O1xuXG5cbiAgaWYgKHdvcmtJblByb2dyZXNzICE9PSBudWxsKSB7XG4gICAgLy8gU3RpbGwgd29yayByZW1haW5pbmcuXG4gICAge1xuICAgICAgbWFya1JlbmRlcllpZWxkZWQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gUm9vdEluUHJvZ3Jlc3M7XG4gIH0gZWxzZSB7XG4gICAgLy8gQ29tcGxldGVkIHRoZSB0cmVlLlxuICAgIHtcbiAgICAgIG1hcmtSZW5kZXJTdG9wcGVkKCk7XG4gICAgfSAvLyBTZXQgdGhpcyB0byBudWxsIHRvIGluZGljYXRlIHRoZXJlJ3Mgbm8gaW4tcHJvZ3Jlc3MgcmVuZGVyLlxuXG5cbiAgICB3b3JrSW5Qcm9ncmVzc1Jvb3QgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzID0gTm9MYW5lczsgLy8gUmV0dXJuIHRoZSBmaW5hbCBleGl0IHN0YXR1cy5cblxuICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzO1xuICB9XG59XG4vKiogQG5vaW5saW5lICovXG5cblxuZnVuY3Rpb24gd29ya0xvb3BDb25jdXJyZW50KCkge1xuICAvLyBQZXJmb3JtIHdvcmsgdW50aWwgU2NoZWR1bGVyIGFza3MgdXMgdG8geWllbGRcbiAgd2hpbGUgKHdvcmtJblByb2dyZXNzICE9PSBudWxsICYmICFzaG91bGRZaWVsZCgpKSB7XG4gICAgcGVyZm9ybVVuaXRPZldvcmsod29ya0luUHJvZ3Jlc3MpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBlcmZvcm1Vbml0T2ZXb3JrKHVuaXRPZldvcmspIHtcbiAgLy8gVGhlIGN1cnJlbnQsIGZsdXNoZWQsIHN0YXRlIG9mIHRoaXMgZmliZXIgaXMgdGhlIGFsdGVybmF0ZS4gSWRlYWxseVxuICAvLyBub3RoaW5nIHNob3VsZCByZWx5IG9uIHRoaXMsIGJ1dCByZWx5aW5nIG9uIGl0IGhlcmUgbWVhbnMgdGhhdCB3ZSBkb24ndFxuICAvLyBuZWVkIGFuIGFkZGl0aW9uYWwgZmllbGQgb24gdGhlIHdvcmsgaW4gcHJvZ3Jlc3MuXG4gIHZhciBjdXJyZW50ID0gdW5pdE9mV29yay5hbHRlcm5hdGU7XG4gIHNldEN1cnJlbnRGaWJlcih1bml0T2ZXb3JrKTtcbiAgdmFyIG5leHQ7XG5cbiAgaWYgKCAodW5pdE9mV29yay5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICBzdGFydFByb2ZpbGVyVGltZXIodW5pdE9mV29yayk7XG4gICAgbmV4dCA9IGJlZ2luV29yayQxKGN1cnJlbnQsIHVuaXRPZldvcmssIHN1YnRyZWVSZW5kZXJMYW5lcyk7XG4gICAgc3RvcFByb2ZpbGVyVGltZXJJZlJ1bm5pbmdBbmRSZWNvcmREZWx0YSh1bml0T2ZXb3JrLCB0cnVlKTtcbiAgfSBlbHNlIHtcbiAgICBuZXh0ID0gYmVnaW5Xb3JrJDEoY3VycmVudCwgdW5pdE9mV29yaywgc3VidHJlZVJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gIHVuaXRPZldvcmsubWVtb2l6ZWRQcm9wcyA9IHVuaXRPZldvcmsucGVuZGluZ1Byb3BzO1xuXG4gIGlmIChuZXh0ID09PSBudWxsKSB7XG4gICAgLy8gSWYgdGhpcyBkb2Vzbid0IHNwYXduIG5ldyB3b3JrLCBjb21wbGV0ZSB0aGUgY3VycmVudCB3b3JrLlxuICAgIGNvbXBsZXRlVW5pdE9mV29yayh1bml0T2ZXb3JrKTtcbiAgfSBlbHNlIHtcbiAgICB3b3JrSW5Qcm9ncmVzcyA9IG5leHQ7XG4gIH1cblxuICBSZWFjdEN1cnJlbnRPd25lciQyLmN1cnJlbnQgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBjb21wbGV0ZVVuaXRPZldvcmsodW5pdE9mV29yaykge1xuICAvLyBBdHRlbXB0IHRvIGNvbXBsZXRlIHRoZSBjdXJyZW50IHVuaXQgb2Ygd29yaywgdGhlbiBtb3ZlIHRvIHRoZSBuZXh0XG4gIC8vIHNpYmxpbmcuIElmIHRoZXJlIGFyZSBubyBtb3JlIHNpYmxpbmdzLCByZXR1cm4gdG8gdGhlIHBhcmVudCBmaWJlci5cbiAgdmFyIGNvbXBsZXRlZFdvcmsgPSB1bml0T2ZXb3JrO1xuXG4gIGRvIHtcbiAgICAvLyBUaGUgY3VycmVudCwgZmx1c2hlZCwgc3RhdGUgb2YgdGhpcyBmaWJlciBpcyB0aGUgYWx0ZXJuYXRlLiBJZGVhbGx5XG4gICAgLy8gbm90aGluZyBzaG91bGQgcmVseSBvbiB0aGlzLCBidXQgcmVseWluZyBvbiBpdCBoZXJlIG1lYW5zIHRoYXQgd2UgZG9uJ3RcbiAgICAvLyBuZWVkIGFuIGFkZGl0aW9uYWwgZmllbGQgb24gdGhlIHdvcmsgaW4gcHJvZ3Jlc3MuXG4gICAgdmFyIGN1cnJlbnQgPSBjb21wbGV0ZWRXb3JrLmFsdGVybmF0ZTtcbiAgICB2YXIgcmV0dXJuRmliZXIgPSBjb21wbGV0ZWRXb3JrLnJldHVybjsgLy8gQ2hlY2sgaWYgdGhlIHdvcmsgY29tcGxldGVkIG9yIGlmIHNvbWV0aGluZyB0aHJldy5cblxuICAgIGlmICgoY29tcGxldGVkV29yay5mbGFncyAmIEluY29tcGxldGUpID09PSBOb0ZsYWdzKSB7XG4gICAgICBzZXRDdXJyZW50RmliZXIoY29tcGxldGVkV29yayk7XG4gICAgICB2YXIgbmV4dCA9IHZvaWQgMDtcblxuICAgICAgaWYgKCAoY29tcGxldGVkV29yay5tb2RlICYgUHJvZmlsZU1vZGUpID09PSBOb01vZGUpIHtcbiAgICAgICAgbmV4dCA9IGNvbXBsZXRlV29yayhjdXJyZW50LCBjb21wbGV0ZWRXb3JrLCBzdWJ0cmVlUmVuZGVyTGFuZXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhcnRQcm9maWxlclRpbWVyKGNvbXBsZXRlZFdvcmspO1xuICAgICAgICBuZXh0ID0gY29tcGxldGVXb3JrKGN1cnJlbnQsIGNvbXBsZXRlZFdvcmssIHN1YnRyZWVSZW5kZXJMYW5lcyk7IC8vIFVwZGF0ZSByZW5kZXIgZHVyYXRpb24gYXNzdW1pbmcgd2UgZGlkbid0IGVycm9yLlxuXG4gICAgICAgIHN0b3BQcm9maWxlclRpbWVySWZSdW5uaW5nQW5kUmVjb3JkRGVsdGEoY29tcGxldGVkV29yaywgZmFsc2UpO1xuICAgICAgfVxuXG4gICAgICByZXNldEN1cnJlbnRGaWJlcigpO1xuXG4gICAgICBpZiAobmV4dCAhPT0gbnVsbCkge1xuICAgICAgICAvLyBDb21wbGV0aW5nIHRoaXMgZmliZXIgc3Bhd25lZCBuZXcgd29yay4gV29yayBvbiB0aGF0IG5leHQuXG4gICAgICAgIHdvcmtJblByb2dyZXNzID0gbmV4dDtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUaGlzIGZpYmVyIGRpZCBub3QgY29tcGxldGUgYmVjYXVzZSBzb21ldGhpbmcgdGhyZXcuIFBvcCB2YWx1ZXMgb2ZmXG4gICAgICAvLyB0aGUgc3RhY2sgd2l0aG91dCBlbnRlcmluZyB0aGUgY29tcGxldGUgcGhhc2UuIElmIHRoaXMgaXMgYSBib3VuZGFyeSxcbiAgICAgIC8vIGNhcHR1cmUgdmFsdWVzIGlmIHBvc3NpYmxlLlxuICAgICAgdmFyIF9uZXh0ID0gdW53aW5kV29yayhjdXJyZW50LCBjb21wbGV0ZWRXb3JrKTsgLy8gQmVjYXVzZSB0aGlzIGZpYmVyIGRpZCBub3QgY29tcGxldGUsIGRvbid0IHJlc2V0IGl0cyBsYW5lcy5cblxuXG4gICAgICBpZiAoX25leHQgIT09IG51bGwpIHtcbiAgICAgICAgLy8gSWYgY29tcGxldGluZyB0aGlzIHdvcmsgc3Bhd25lZCBuZXcgd29yaywgZG8gdGhhdCBuZXh0LiBXZSdsbCBjb21lXG4gICAgICAgIC8vIGJhY2sgaGVyZSBhZ2Fpbi5cbiAgICAgICAgLy8gU2luY2Ugd2UncmUgcmVzdGFydGluZywgcmVtb3ZlIGFueXRoaW5nIHRoYXQgaXMgbm90IGEgaG9zdCBlZmZlY3RcbiAgICAgICAgLy8gZnJvbSB0aGUgZWZmZWN0IHRhZy5cbiAgICAgICAgX25leHQuZmxhZ3MgJj0gSG9zdEVmZmVjdE1hc2s7XG4gICAgICAgIHdvcmtJblByb2dyZXNzID0gX25leHQ7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKCAoY29tcGxldGVkV29yay5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgLy8gUmVjb3JkIHRoZSByZW5kZXIgZHVyYXRpb24gZm9yIHRoZSBmaWJlciB0aGF0IGVycm9yZWQuXG4gICAgICAgIHN0b3BQcm9maWxlclRpbWVySWZSdW5uaW5nQW5kUmVjb3JkRGVsdGEoY29tcGxldGVkV29yaywgZmFsc2UpOyAvLyBJbmNsdWRlIHRoZSB0aW1lIHNwZW50IHdvcmtpbmcgb24gZmFpbGVkIGNoaWxkcmVuIGJlZm9yZSBjb250aW51aW5nLlxuXG4gICAgICAgIHZhciBhY3R1YWxEdXJhdGlvbiA9IGNvbXBsZXRlZFdvcmsuYWN0dWFsRHVyYXRpb247XG4gICAgICAgIHZhciBjaGlsZCA9IGNvbXBsZXRlZFdvcmsuY2hpbGQ7XG5cbiAgICAgICAgd2hpbGUgKGNoaWxkICE9PSBudWxsKSB7XG4gICAgICAgICAgYWN0dWFsRHVyYXRpb24gKz0gY2hpbGQuYWN0dWFsRHVyYXRpb247XG4gICAgICAgICAgY2hpbGQgPSBjaGlsZC5zaWJsaW5nO1xuICAgICAgICB9XG5cbiAgICAgICAgY29tcGxldGVkV29yay5hY3R1YWxEdXJhdGlvbiA9IGFjdHVhbER1cmF0aW9uO1xuICAgICAgfVxuXG4gICAgICBpZiAocmV0dXJuRmliZXIgIT09IG51bGwpIHtcbiAgICAgICAgLy8gTWFyayB0aGUgcGFyZW50IGZpYmVyIGFzIGluY29tcGxldGUgYW5kIGNsZWFyIGl0cyBzdWJ0cmVlIGZsYWdzLlxuICAgICAgICByZXR1cm5GaWJlci5mbGFncyB8PSBJbmNvbXBsZXRlO1xuICAgICAgICByZXR1cm5GaWJlci5zdWJ0cmVlRmxhZ3MgPSBOb0ZsYWdzO1xuICAgICAgICByZXR1cm5GaWJlci5kZWxldGlvbnMgPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gV2UndmUgdW53b3VuZCBhbGwgdGhlIHdheSB0byB0aGUgcm9vdC5cbiAgICAgICAgd29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9IFJvb3REaWROb3RDb21wbGV0ZTtcbiAgICAgICAgd29ya0luUHJvZ3Jlc3MgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmdGaWJlciA9IGNvbXBsZXRlZFdvcmsuc2libGluZztcblxuICAgIGlmIChzaWJsaW5nRmliZXIgIT09IG51bGwpIHtcbiAgICAgIC8vIElmIHRoZXJlIGlzIG1vcmUgd29yayB0byBkbyBpbiB0aGlzIHJldHVybkZpYmVyLCBkbyB0aGF0IG5leHQuXG4gICAgICB3b3JrSW5Qcm9ncmVzcyA9IHNpYmxpbmdGaWJlcjtcbiAgICAgIHJldHVybjtcbiAgICB9IC8vIE90aGVyd2lzZSwgcmV0dXJuIHRvIHRoZSBwYXJlbnRcblxuXG4gICAgY29tcGxldGVkV29yayA9IHJldHVybkZpYmVyOyAvLyBVcGRhdGUgdGhlIG5leHQgdGhpbmcgd2UncmUgd29ya2luZyBvbiBpbiBjYXNlIHNvbWV0aGluZyB0aHJvd3MuXG5cbiAgICB3b3JrSW5Qcm9ncmVzcyA9IGNvbXBsZXRlZFdvcms7XG4gIH0gd2hpbGUgKGNvbXBsZXRlZFdvcmsgIT09IG51bGwpOyAvLyBXZSd2ZSByZWFjaGVkIHRoZSByb290LlxuXG5cbiAgaWYgKHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPT09IFJvb3RJblByb2dyZXNzKSB7XG4gICAgd29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9IFJvb3RDb21wbGV0ZWQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0Um9vdChyb290LCByZWNvdmVyYWJsZUVycm9ycywgdHJhbnNpdGlvbnMpIHtcbiAgLy8gVE9ETzogVGhpcyBubyBsb25nZXIgbWFrZXMgYW55IHNlbnNlLiBXZSBhbHJlYWR5IHdyYXAgdGhlIG11dGF0aW9uIGFuZFxuICAvLyBsYXlvdXQgcGhhc2VzLiBTaG91bGQgYmUgYWJsZSB0byByZW1vdmUuXG4gIHZhciBwcmV2aW91c1VwZGF0ZUxhbmVQcmlvcml0eSA9IGdldEN1cnJlbnRVcGRhdGVQcmlvcml0eSgpO1xuICB2YXIgcHJldlRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb247XG5cbiAgdHJ5IHtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb24gPSBudWxsO1xuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShEaXNjcmV0ZUV2ZW50UHJpb3JpdHkpO1xuICAgIGNvbW1pdFJvb3RJbXBsKHJvb3QsIHJlY292ZXJhYmxlRXJyb3JzLCB0cmFuc2l0aW9ucywgcHJldmlvdXNVcGRhdGVMYW5lUHJpb3JpdHkpO1xuICB9IGZpbmFsbHkge1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbiA9IHByZXZUcmFuc2l0aW9uO1xuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmV2aW91c1VwZGF0ZUxhbmVQcmlvcml0eSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gY29tbWl0Um9vdEltcGwocm9vdCwgcmVjb3ZlcmFibGVFcnJvcnMsIHRyYW5zaXRpb25zLCByZW5kZXJQcmlvcml0eUxldmVsKSB7XG4gIGRvIHtcbiAgICAvLyBgZmx1c2hQYXNzaXZlRWZmZWN0c2Agd2lsbCBjYWxsIGBmbHVzaFN5bmNVcGRhdGVRdWV1ZWAgYXQgdGhlIGVuZCwgd2hpY2hcbiAgICAvLyBtZWFucyBgZmx1c2hQYXNzaXZlRWZmZWN0c2Agd2lsbCBzb21ldGltZXMgcmVzdWx0IGluIGFkZGl0aW9uYWxcbiAgICAvLyBwYXNzaXZlIGVmZmVjdHMuIFNvIHdlIG5lZWQgdG8ga2VlcCBmbHVzaGluZyBpbiBhIGxvb3AgdW50aWwgdGhlcmUgYXJlXG4gICAgLy8gbm8gbW9yZSBwZW5kaW5nIGVmZmVjdHMuXG4gICAgLy8gVE9ETzogTWlnaHQgYmUgYmV0dGVyIGlmIGBmbHVzaFBhc3NpdmVFZmZlY3RzYCBkaWQgbm90IGF1dG9tYXRpY2FsbHlcbiAgICAvLyBmbHVzaCBzeW5jaHJvbm91cyB3b3JrIGF0IHRoZSBlbmQsIHRvIGF2b2lkIGZhY3RvcmluZyBoYXphcmRzIGxpa2UgdGhpcy5cbiAgICBmbHVzaFBhc3NpdmVFZmZlY3RzKCk7XG4gIH0gd2hpbGUgKHJvb3RXaXRoUGVuZGluZ1Bhc3NpdmVFZmZlY3RzICE9PSBudWxsKTtcblxuICBmbHVzaFJlbmRlclBoYXNlU3RyaWN0TW9kZVdhcm5pbmdzSW5ERVYoKTtcblxuICBpZiAoKGV4ZWN1dGlvbkNvbnRleHQgJiAoUmVuZGVyQ29udGV4dCB8IENvbW1pdENvbnRleHQpKSAhPT0gTm9Db250ZXh0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaG91bGQgbm90IGFscmVhZHkgYmUgd29ya2luZy4nKTtcbiAgfVxuXG4gIHZhciBmaW5pc2hlZFdvcmsgPSByb290LmZpbmlzaGVkV29yaztcbiAgdmFyIGxhbmVzID0gcm9vdC5maW5pc2hlZExhbmVzO1xuXG4gIHtcbiAgICBtYXJrQ29tbWl0U3RhcnRlZChsYW5lcyk7XG4gIH1cblxuICBpZiAoZmluaXNoZWRXb3JrID09PSBudWxsKSB7XG5cbiAgICB7XG4gICAgICBtYXJrQ29tbWl0U3RvcHBlZCgpO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9IGVsc2Uge1xuICAgIHtcbiAgICAgIGlmIChsYW5lcyA9PT0gTm9MYW5lcykge1xuICAgICAgICBlcnJvcigncm9vdC5maW5pc2hlZExhbmVzIHNob3VsZCBub3QgYmUgZW1wdHkgZHVyaW5nIGEgY29tbWl0LiBUaGlzIGlzIGEgJyArICdidWcgaW4gUmVhY3QuJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcm9vdC5maW5pc2hlZFdvcmsgPSBudWxsO1xuICByb290LmZpbmlzaGVkTGFuZXMgPSBOb0xhbmVzO1xuXG4gIGlmIChmaW5pc2hlZFdvcmsgPT09IHJvb3QuY3VycmVudCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNvbW1pdCB0aGUgc2FtZSB0cmVlIGFzIGJlZm9yZS4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5ICcgKyAnYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICB9IC8vIGNvbW1pdFJvb3QgbmV2ZXIgcmV0dXJucyBhIGNvbnRpbnVhdGlvbjsgaXQgYWx3YXlzIGZpbmlzaGVzIHN5bmNocm9ub3VzbHkuXG4gIC8vIFNvIHdlIGNhbiBjbGVhciB0aGVzZSBub3cgdG8gYWxsb3cgYSBuZXcgY2FsbGJhY2sgdG8gYmUgc2NoZWR1bGVkLlxuXG5cbiAgcm9vdC5jYWxsYmFja05vZGUgPSBudWxsO1xuICByb290LmNhbGxiYWNrUHJpb3JpdHkgPSBOb0xhbmU7IC8vIFVwZGF0ZSB0aGUgZmlyc3QgYW5kIGxhc3QgcGVuZGluZyB0aW1lcyBvbiB0aGlzIHJvb3QuIFRoZSBuZXcgZmlyc3RcbiAgLy8gcGVuZGluZyB0aW1lIGlzIHdoYXRldmVyIGlzIGxlZnQgb24gdGhlIHJvb3QgZmliZXIuXG5cbiAgdmFyIHJlbWFpbmluZ0xhbmVzID0gbWVyZ2VMYW5lcyhmaW5pc2hlZFdvcmsubGFuZXMsIGZpbmlzaGVkV29yay5jaGlsZExhbmVzKTtcbiAgbWFya1Jvb3RGaW5pc2hlZChyb290LCByZW1haW5pbmdMYW5lcyk7XG5cbiAgaWYgKHJvb3QgPT09IHdvcmtJblByb2dyZXNzUm9vdCkge1xuICAgIC8vIFdlIGNhbiByZXNldCB0aGVzZSBub3cgdGhhdCB0aGV5IGFyZSBmaW5pc2hlZC5cbiAgICB3b3JrSW5Qcm9ncmVzc1Jvb3QgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzID0gbnVsbDtcbiAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcyA9IE5vTGFuZXM7XG4gIH0gLy8gSWYgdGhlcmUgYXJlIHBlbmRpbmcgcGFzc2l2ZSBlZmZlY3RzLCBzY2hlZHVsZSBhIGNhbGxiYWNrIHRvIHByb2Nlc3MgdGhlbS5cbiAgLy8gRG8gdGhpcyBhcyBlYXJseSBhcyBwb3NzaWJsZSwgc28gaXQgaXMgcXVldWVkIGJlZm9yZSBhbnl0aGluZyBlbHNlIHRoYXRcbiAgLy8gbWlnaHQgZ2V0IHNjaGVkdWxlZCBpbiB0aGUgY29tbWl0IHBoYXNlLiAoU2VlICMxNjcxNC4pXG4gIC8vIFRPRE86IERlbGV0ZSBhbGwgb3RoZXIgcGxhY2VzIHRoYXQgc2NoZWR1bGUgdGhlIHBhc3NpdmUgZWZmZWN0IGNhbGxiYWNrXG4gIC8vIFRoZXkncmUgcmVkdW5kYW50LlxuXG5cbiAgaWYgKChmaW5pc2hlZFdvcmsuc3VidHJlZUZsYWdzICYgUGFzc2l2ZU1hc2spICE9PSBOb0ZsYWdzIHx8IChmaW5pc2hlZFdvcmsuZmxhZ3MgJiBQYXNzaXZlTWFzaykgIT09IE5vRmxhZ3MpIHtcbiAgICBpZiAoIXJvb3REb2VzSGF2ZVBhc3NpdmVFZmZlY3RzKSB7XG4gICAgICByb290RG9lc0hhdmVQYXNzaXZlRWZmZWN0cyA9IHRydWU7XG4gICAgICAvLyB0byBzdG9yZSBpdCBpbiBwZW5kaW5nUGFzc2l2ZVRyYW5zaXRpb25zIHVudGlsIHRoZXkgZ2V0IHByb2Nlc3NlZFxuICAgICAgLy8gV2UgbmVlZCB0byBwYXNzIHRoaXMgdGhyb3VnaCBhcyBhbiBhcmd1bWVudCB0byBjb21taXRSb290XG4gICAgICAvLyBiZWNhdXNlIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMgbWlnaHQgaGF2ZSBjaGFuZ2VkIGJldHdlZW5cbiAgICAgIC8vIHRoZSBwcmV2aW91cyByZW5kZXIgYW5kIGNvbW1pdCBpZiB3ZSB0aHJvdHRsZSB0aGUgY29tbWl0XG4gICAgICAvLyB3aXRoIHNldFRpbWVvdXRcblxuICAgICAgcGVuZGluZ1Bhc3NpdmVUcmFuc2l0aW9ucyA9IHRyYW5zaXRpb25zO1xuICAgICAgc2NoZWR1bGVDYWxsYmFjayQxKE5vcm1hbFByaW9yaXR5LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKTsgLy8gVGhpcyByZW5kZXIgdHJpZ2dlcmVkIHBhc3NpdmUgZWZmZWN0czogcmVsZWFzZSB0aGUgcm9vdCBjYWNoZSBwb29sXG4gICAgICAgIC8vICphZnRlciogcGFzc2l2ZSBlZmZlY3RzIGZpcmUgdG8gYXZvaWQgZnJlZWluZyBhIGNhY2hlIHBvb2wgdGhhdCBtYXlcbiAgICAgICAgLy8gYmUgcmVmZXJlbmNlZCBieSBhIG5vZGUgaW4gdGhlIHRyZWUgKEhvc3RSb290LCBDYWNoZSBib3VuZGFyeSBldGMpXG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9KTtcbiAgICB9XG4gIH0gLy8gQ2hlY2sgaWYgdGhlcmUgYXJlIGFueSBlZmZlY3RzIGluIHRoZSB3aG9sZSB0cmVlLlxuICAvLyBUT0RPOiBUaGlzIGlzIGxlZnQgb3ZlciBmcm9tIHRoZSBlZmZlY3QgbGlzdCBpbXBsZW1lbnRhdGlvbiwgd2hlcmUgd2UgaGFkXG4gIC8vIHRvIGNoZWNrIGZvciB0aGUgZXhpc3RlbmNlIG9mIGBmaXJzdEVmZmVjdGAgdG8gc2F0aXNmeSBGbG93LiBJIHRoaW5rIHRoZVxuICAvLyBvbmx5IG90aGVyIHJlYXNvbiB0aGlzIG9wdGltaXphdGlvbiBleGlzdHMgaXMgYmVjYXVzZSBpdCBhZmZlY3RzIHByb2ZpbGluZy5cbiAgLy8gUmVjb25zaWRlciB3aGV0aGVyIHRoaXMgaXMgbmVjZXNzYXJ5LlxuXG5cbiAgdmFyIHN1YnRyZWVIYXNFZmZlY3RzID0gKGZpbmlzaGVkV29yay5zdWJ0cmVlRmxhZ3MgJiAoQmVmb3JlTXV0YXRpb25NYXNrIHwgTXV0YXRpb25NYXNrIHwgTGF5b3V0TWFzayB8IFBhc3NpdmVNYXNrKSkgIT09IE5vRmxhZ3M7XG4gIHZhciByb290SGFzRWZmZWN0ID0gKGZpbmlzaGVkV29yay5mbGFncyAmIChCZWZvcmVNdXRhdGlvbk1hc2sgfCBNdXRhdGlvbk1hc2sgfCBMYXlvdXRNYXNrIHwgUGFzc2l2ZU1hc2spKSAhPT0gTm9GbGFncztcblxuICBpZiAoc3VidHJlZUhhc0VmZmVjdHMgfHwgcm9vdEhhc0VmZmVjdCkge1xuICAgIHZhciBwcmV2VHJhbnNpdGlvbiA9IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbjtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb24gPSBudWxsO1xuICAgIHZhciBwcmV2aW91c1ByaW9yaXR5ID0gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KCk7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KERpc2NyZXRlRXZlbnRQcmlvcml0eSk7XG4gICAgdmFyIHByZXZFeGVjdXRpb25Db250ZXh0ID0gZXhlY3V0aW9uQ29udGV4dDtcbiAgICBleGVjdXRpb25Db250ZXh0IHw9IENvbW1pdENvbnRleHQ7IC8vIFJlc2V0IHRoaXMgdG8gbnVsbCBiZWZvcmUgY2FsbGluZyBsaWZlY3ljbGVzXG5cbiAgICBSZWFjdEN1cnJlbnRPd25lciQyLmN1cnJlbnQgPSBudWxsOyAvLyBUaGUgY29tbWl0IHBoYXNlIGlzIGJyb2tlbiBpbnRvIHNldmVyYWwgc3ViLXBoYXNlcy4gV2UgZG8gYSBzZXBhcmF0ZSBwYXNzXG4gICAgLy8gb2YgdGhlIGVmZmVjdCBsaXN0IGZvciBlYWNoIHBoYXNlOiBhbGwgbXV0YXRpb24gZWZmZWN0cyBjb21lIGJlZm9yZSBhbGxcbiAgICAvLyBsYXlvdXQgZWZmZWN0cywgYW5kIHNvIG9uLlxuICAgIC8vIFRoZSBmaXJzdCBwaGFzZSBhIFwiYmVmb3JlIG11dGF0aW9uXCIgcGhhc2UuIFdlIHVzZSB0aGlzIHBoYXNlIHRvIHJlYWQgdGhlXG4gICAgLy8gc3RhdGUgb2YgdGhlIGhvc3QgdHJlZSByaWdodCBiZWZvcmUgd2UgbXV0YXRlIGl0LiBUaGlzIGlzIHdoZXJlXG4gICAgLy8gZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUgaXMgY2FsbGVkLlxuXG4gICAgdmFyIHNob3VsZEZpcmVBZnRlckFjdGl2ZUluc3RhbmNlQmx1ciA9IGNvbW1pdEJlZm9yZU11dGF0aW9uRWZmZWN0cyhyb290LCBmaW5pc2hlZFdvcmspO1xuXG4gICAge1xuICAgICAgLy8gTWFyayB0aGUgY3VycmVudCBjb21taXQgdGltZSB0byBiZSBzaGFyZWQgYnkgYWxsIFByb2ZpbGVycyBpbiB0aGlzXG4gICAgICAvLyBiYXRjaC4gVGhpcyBlbmFibGVzIHRoZW0gdG8gYmUgZ3JvdXBlZCBsYXRlci5cbiAgICAgIHJlY29yZENvbW1pdFRpbWUoKTtcbiAgICB9XG5cblxuICAgIGNvbW1pdE11dGF0aW9uRWZmZWN0cyhyb290LCBmaW5pc2hlZFdvcmssIGxhbmVzKTtcblxuICAgIHJlc2V0QWZ0ZXJDb21taXQocm9vdC5jb250YWluZXJJbmZvKTsgLy8gVGhlIHdvcmstaW4tcHJvZ3Jlc3MgdHJlZSBpcyBub3cgdGhlIGN1cnJlbnQgdHJlZS4gVGhpcyBtdXN0IGNvbWUgYWZ0ZXJcbiAgICAvLyB0aGUgbXV0YXRpb24gcGhhc2UsIHNvIHRoYXQgdGhlIHByZXZpb3VzIHRyZWUgaXMgc3RpbGwgY3VycmVudCBkdXJpbmdcbiAgICAvLyBjb21wb25lbnRXaWxsVW5tb3VudCwgYnV0IGJlZm9yZSB0aGUgbGF5b3V0IHBoYXNlLCBzbyB0aGF0IHRoZSBmaW5pc2hlZFxuICAgIC8vIHdvcmsgaXMgY3VycmVudCBkdXJpbmcgY29tcG9uZW50RGlkTW91bnQvVXBkYXRlLlxuXG4gICAgcm9vdC5jdXJyZW50ID0gZmluaXNoZWRXb3JrOyAvLyBUaGUgbmV4dCBwaGFzZSBpcyB0aGUgbGF5b3V0IHBoYXNlLCB3aGVyZSB3ZSBjYWxsIGVmZmVjdHMgdGhhdCByZWFkXG5cbiAgICB7XG4gICAgICBtYXJrTGF5b3V0RWZmZWN0c1N0YXJ0ZWQobGFuZXMpO1xuICAgIH1cblxuICAgIGNvbW1pdExheW91dEVmZmVjdHMoZmluaXNoZWRXb3JrLCByb290LCBsYW5lcyk7XG5cbiAgICB7XG4gICAgICBtYXJrTGF5b3V0RWZmZWN0c1N0b3BwZWQoKTtcbiAgICB9XG4gICAgLy8gb3Bwb3J0dW5pdHkgdG8gcGFpbnQuXG5cblxuICAgIHJlcXVlc3RQYWludCgpO1xuICAgIGV4ZWN1dGlvbkNvbnRleHQgPSBwcmV2RXhlY3V0aW9uQ29udGV4dDsgLy8gUmVzZXQgdGhlIHByaW9yaXR5IHRvIHRoZSBwcmV2aW91cyBub24tc3luYyB2YWx1ZS5cblxuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmV2aW91c1ByaW9yaXR5KTtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb24gPSBwcmV2VHJhbnNpdGlvbjtcbiAgfSBlbHNlIHtcbiAgICAvLyBObyBlZmZlY3RzLlxuICAgIHJvb3QuY3VycmVudCA9IGZpbmlzaGVkV29yazsgLy8gTWVhc3VyZSB0aGVzZSBhbnl3YXkgc28gdGhlIGZsYW1lZ3JhcGggZXhwbGljaXRseSBzaG93cyB0aGF0IHRoZXJlIHdlcmVcbiAgICAvLyBubyBlZmZlY3RzLlxuICAgIC8vIFRPRE86IE1heWJlIHRoZXJlJ3MgYSBiZXR0ZXIgd2F5IHRvIHJlcG9ydCB0aGlzLlxuXG4gICAge1xuICAgICAgcmVjb3JkQ29tbWl0VGltZSgpO1xuICAgIH1cbiAgfVxuXG4gIHZhciByb290RGlkSGF2ZVBhc3NpdmVFZmZlY3RzID0gcm9vdERvZXNIYXZlUGFzc2l2ZUVmZmVjdHM7XG5cbiAgaWYgKHJvb3REb2VzSGF2ZVBhc3NpdmVFZmZlY3RzKSB7XG4gICAgLy8gVGhpcyBjb21taXQgaGFzIHBhc3NpdmUgZWZmZWN0cy4gU3Rhc2ggYSByZWZlcmVuY2UgdG8gdGhlbS4gQnV0IGRvbid0XG4gICAgLy8gc2NoZWR1bGUgYSBjYWxsYmFjayB1bnRpbCBhZnRlciBmbHVzaGluZyBsYXlvdXQgd29yay5cbiAgICByb290RG9lc0hhdmVQYXNzaXZlRWZmZWN0cyA9IGZhbHNlO1xuICAgIHJvb3RXaXRoUGVuZGluZ1Bhc3NpdmVFZmZlY3RzID0gcm9vdDtcbiAgICBwZW5kaW5nUGFzc2l2ZUVmZmVjdHNMYW5lcyA9IGxhbmVzO1xuICB9IGVsc2Uge1xuXG4gICAge1xuICAgICAgbmVzdGVkUGFzc2l2ZVVwZGF0ZUNvdW50ID0gMDtcbiAgICAgIHJvb3RXaXRoUGFzc2l2ZU5lc3RlZFVwZGF0ZXMgPSBudWxsO1xuICAgIH1cbiAgfSAvLyBSZWFkIHRoaXMgYWdhaW4sIHNpbmNlIGFuIGVmZmVjdCBtaWdodCBoYXZlIHVwZGF0ZWQgaXRcblxuXG4gIHJlbWFpbmluZ0xhbmVzID0gcm9vdC5wZW5kaW5nTGFuZXM7IC8vIENoZWNrIGlmIHRoZXJlJ3MgcmVtYWluaW5nIHdvcmsgb24gdGhpcyByb290XG4gIC8vIFRPRE86IFRoaXMgaXMgcGFydCBvZiB0aGUgYGNvbXBvbmVudERpZENhdGNoYCBpbXBsZW1lbnRhdGlvbi4gSXRzIHB1cnBvc2VcbiAgLy8gaXMgdG8gZGV0ZWN0IHdoZXRoZXIgc29tZXRoaW5nIG1pZ2h0IGhhdmUgY2FsbGVkIHNldFN0YXRlIGluc2lkZVxuICAvLyBgY29tcG9uZW50RGlkQ2F0Y2hgLiBUaGUgbWVjaGFuaXNtIGlzIGtub3duIHRvIGJlIGZsYXdlZCBiZWNhdXNlIGBzZXRTdGF0ZWBcbiAgLy8gaW5zaWRlIGBjb21wb25lbnREaWRDYXRjaGAgaXMgaXRzZWxmIGZsYXdlZCDigJQgdGhhdCdzIHdoeSB3ZSByZWNvbW1lbmRcbiAgLy8gYGdldERlcml2ZWRTdGF0ZUZyb21FcnJvcmAgaW5zdGVhZC4gSG93ZXZlciwgaXQgY291bGQgYmUgaW1wcm92ZWQgYnlcbiAgLy8gY2hlY2tpbmcgaWYgcmVtYWluaW5nTGFuZXMgaW5jbHVkZXMgU3luYyB3b3JrLCBpbnN0ZWFkIG9mIHdoZXRoZXIgdGhlcmUnc1xuICAvLyBhbnkgd29yayByZW1haW5pbmcgYXQgYWxsICh3aGljaCB3b3VsZCBhbHNvIGluY2x1ZGUgc3R1ZmYgbGlrZSBTdXNwZW5zZVxuICAvLyByZXRyaWVzIG9yIHRyYW5zaXRpb25zKS4gSXQncyBiZWVuIGxpa2UgdGhpcyBmb3IgYSB3aGlsZSwgdGhvdWdoLCBzbyBmaXhpbmdcbiAgLy8gaXQgcHJvYmFibHkgaXNuJ3QgdGhhdCB1cmdlbnQuXG5cbiAgaWYgKHJlbWFpbmluZ0xhbmVzID09PSBOb0xhbmVzKSB7XG4gICAgLy8gSWYgdGhlcmUncyBubyByZW1haW5pbmcgd29yaywgd2UgY2FuIGNsZWFyIHRoZSBzZXQgb2YgYWxyZWFkeSBmYWlsZWRcbiAgICAvLyBlcnJvciBib3VuZGFyaWVzLlxuICAgIGxlZ2FjeUVycm9yQm91bmRhcmllc1RoYXRBbHJlYWR5RmFpbGVkID0gbnVsbDtcbiAgfVxuXG4gIHtcbiAgICBpZiAoIXJvb3REaWRIYXZlUGFzc2l2ZUVmZmVjdHMpIHtcbiAgICAgIGNvbW1pdERvdWJsZUludm9rZUVmZmVjdHNJbkRFVihyb290LmN1cnJlbnQsIGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBvbkNvbW1pdFJvb3QoZmluaXNoZWRXb3JrLnN0YXRlTm9kZSwgcmVuZGVyUHJpb3JpdHlMZXZlbCk7XG5cbiAge1xuICAgIGlmIChpc0RldlRvb2xzUHJlc2VudCkge1xuICAgICAgcm9vdC5tZW1vaXplZFVwZGF0ZXJzLmNsZWFyKCk7XG4gICAgfVxuICB9XG5cbiAge1xuICAgIG9uQ29tbWl0Um9vdCQxKCk7XG4gIH0gLy8gQWx3YXlzIGNhbGwgdGhpcyBiZWZvcmUgZXhpdGluZyBgY29tbWl0Um9vdGAsIHRvIGVuc3VyZSB0aGF0IGFueVxuICAvLyBhZGRpdGlvbmFsIHdvcmsgb24gdGhpcyByb290IGlzIHNjaGVkdWxlZC5cblxuXG4gIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBub3coKSk7XG5cbiAgaWYgKHJlY292ZXJhYmxlRXJyb3JzICE9PSBudWxsKSB7XG4gICAgLy8gVGhlcmUgd2VyZSBlcnJvcnMgZHVyaW5nIHRoaXMgcmVuZGVyLCBidXQgcmVjb3ZlcmVkIGZyb20gdGhlbSB3aXRob3V0XG4gICAgLy8gbmVlZGluZyB0byBzdXJmYWNlIGl0IHRvIHRoZSBVSS4gV2UgbG9nIHRoZW0gaGVyZS5cbiAgICB2YXIgb25SZWNvdmVyYWJsZUVycm9yID0gcm9vdC5vblJlY292ZXJhYmxlRXJyb3I7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlY292ZXJhYmxlRXJyb3JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcmVjb3ZlcmFibGVFcnJvciA9IHJlY292ZXJhYmxlRXJyb3JzW2ldO1xuICAgICAgdmFyIGNvbXBvbmVudFN0YWNrID0gcmVjb3ZlcmFibGVFcnJvci5zdGFjaztcbiAgICAgIHZhciBkaWdlc3QgPSByZWNvdmVyYWJsZUVycm9yLmRpZ2VzdDtcbiAgICAgIG9uUmVjb3ZlcmFibGVFcnJvcihyZWNvdmVyYWJsZUVycm9yLnZhbHVlLCB7XG4gICAgICAgIGNvbXBvbmVudFN0YWNrOiBjb21wb25lbnRTdGFjayxcbiAgICAgICAgZGlnZXN0OiBkaWdlc3RcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGlmIChoYXNVbmNhdWdodEVycm9yKSB7XG4gICAgaGFzVW5jYXVnaHRFcnJvciA9IGZhbHNlO1xuICAgIHZhciBlcnJvciQxID0gZmlyc3RVbmNhdWdodEVycm9yO1xuICAgIGZpcnN0VW5jYXVnaHRFcnJvciA9IG51bGw7XG4gICAgdGhyb3cgZXJyb3IkMTtcbiAgfSAvLyBJZiB0aGUgcGFzc2l2ZSBlZmZlY3RzIGFyZSB0aGUgcmVzdWx0IG9mIGEgZGlzY3JldGUgcmVuZGVyLCBmbHVzaCB0aGVtXG4gIC8vIHN5bmNocm9ub3VzbHkgYXQgdGhlIGVuZCBvZiB0aGUgY3VycmVudCB0YXNrIHNvIHRoYXQgdGhlIHJlc3VsdCBpc1xuICAvLyBpbW1lZGlhdGVseSBvYnNlcnZhYmxlLiBPdGhlcndpc2UsIHdlIGFzc3VtZSB0aGF0IHRoZXkgYXJlIG5vdFxuICAvLyBvcmRlci1kZXBlbmRlbnQgYW5kIGRvIG5vdCBuZWVkIHRvIGJlIG9ic2VydmVkIGJ5IGV4dGVybmFsIHN5c3RlbXMsIHNvIHdlXG4gIC8vIGNhbiB3YWl0IHVudGlsIGFmdGVyIHBhaW50LlxuICAvLyBUT0RPOiBXZSBjYW4gb3B0aW1pemUgdGhpcyBieSBub3Qgc2NoZWR1bGluZyB0aGUgY2FsbGJhY2sgZWFybGllci4gU2luY2Ugd2VcbiAgLy8gY3VycmVudGx5IHNjaGVkdWxlIHRoZSBjYWxsYmFjayBpbiBtdWx0aXBsZSBwbGFjZXMsIHdpbGwgd2FpdCB1bnRpbCB0aG9zZVxuICAvLyBhcmUgY29uc29saWRhdGVkLlxuXG5cbiAgaWYgKGluY2x1ZGVzU29tZUxhbmUocGVuZGluZ1Bhc3NpdmVFZmZlY3RzTGFuZXMsIFN5bmNMYW5lKSAmJiByb290LnRhZyAhPT0gTGVnYWN5Um9vdCkge1xuICAgIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKTtcbiAgfSAvLyBSZWFkIHRoaXMgYWdhaW4sIHNpbmNlIGEgcGFzc2l2ZSBlZmZlY3QgbWlnaHQgaGF2ZSB1cGRhdGVkIGl0XG5cblxuICByZW1haW5pbmdMYW5lcyA9IHJvb3QucGVuZGluZ0xhbmVzO1xuXG4gIGlmIChpbmNsdWRlc1NvbWVMYW5lKHJlbWFpbmluZ0xhbmVzLCBTeW5jTGFuZSkpIHtcbiAgICB7XG4gICAgICBtYXJrTmVzdGVkVXBkYXRlU2NoZWR1bGVkKCk7XG4gICAgfSAvLyBDb3VudCB0aGUgbnVtYmVyIG9mIHRpbWVzIHRoZSByb290IHN5bmNocm9ub3VzbHkgcmUtcmVuZGVycyB3aXRob3V0XG4gICAgLy8gZmluaXNoaW5nLiBJZiB0aGVyZSBhcmUgdG9vIG1hbnksIGl0IGluZGljYXRlcyBhbiBpbmZpbml0ZSB1cGRhdGUgbG9vcC5cblxuXG4gICAgaWYgKHJvb3QgPT09IHJvb3RXaXRoTmVzdGVkVXBkYXRlcykge1xuICAgICAgbmVzdGVkVXBkYXRlQ291bnQrKztcbiAgICB9IGVsc2Uge1xuICAgICAgbmVzdGVkVXBkYXRlQ291bnQgPSAwO1xuICAgICAgcm9vdFdpdGhOZXN0ZWRVcGRhdGVzID0gcm9vdDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgbmVzdGVkVXBkYXRlQ291bnQgPSAwO1xuICB9IC8vIElmIGxheW91dCB3b3JrIHdhcyBzY2hlZHVsZWQsIGZsdXNoIGl0IG5vdy5cblxuXG4gIGZsdXNoU3luY0NhbGxiYWNrcygpO1xuXG4gIHtcbiAgICBtYXJrQ29tbWl0U3RvcHBlZCgpO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKSB7XG4gIC8vIFJldHVybnMgd2hldGhlciBwYXNzaXZlIGVmZmVjdHMgd2VyZSBmbHVzaGVkLlxuICAvLyBUT0RPOiBDb21iaW5lIHRoaXMgY2hlY2sgd2l0aCB0aGUgb25lIGluIGZsdXNoUGFzc2l2ZUVGZmVjdHNJbXBsLiBXZSBzaG91bGRcbiAgLy8gcHJvYmFibHkganVzdCBjb21iaW5lIHRoZSB0d28gZnVuY3Rpb25zLiBJIGJlbGlldmUgdGhleSB3ZXJlIG9ubHkgc2VwYXJhdGVcbiAgLy8gaW4gdGhlIGZpcnN0IHBsYWNlIGJlY2F1c2Ugd2UgdXNlZCB0byB3cmFwIGl0IHdpdGhcbiAgLy8gYFNjaGVkdWxlci5ydW5XaXRoUHJpb3JpdHlgLCB3aGljaCBhY2NlcHRzIGEgZnVuY3Rpb24uIEJ1dCBub3cgd2UgdHJhY2sgdGhlXG4gIC8vIHByaW9yaXR5IHdpdGhpbiBSZWFjdCBpdHNlbGYsIHNvIHdlIGNhbiBtdXRhdGUgdGhlIHZhcmlhYmxlIGRpcmVjdGx5LlxuICBpZiAocm9vdFdpdGhQZW5kaW5nUGFzc2l2ZUVmZmVjdHMgIT09IG51bGwpIHtcbiAgICB2YXIgcmVuZGVyUHJpb3JpdHkgPSBsYW5lc1RvRXZlbnRQcmlvcml0eShwZW5kaW5nUGFzc2l2ZUVmZmVjdHNMYW5lcyk7XG4gICAgdmFyIHByaW9yaXR5ID0gbG93ZXJFdmVudFByaW9yaXR5KERlZmF1bHRFdmVudFByaW9yaXR5LCByZW5kZXJQcmlvcml0eSk7XG4gICAgdmFyIHByZXZUcmFuc2l0aW9uID0gUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uO1xuICAgIHZhciBwcmV2aW91c1ByaW9yaXR5ID0gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KCk7XG5cbiAgICB0cnkge1xuICAgICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uID0gbnVsbDtcbiAgICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmlvcml0eSk7XG4gICAgICByZXR1cm4gZmx1c2hQYXNzaXZlRWZmZWN0c0ltcGwoKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KHByZXZpb3VzUHJpb3JpdHkpO1xuICAgICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uID0gcHJldlRyYW5zaXRpb247IC8vIE9uY2UgcGFzc2l2ZSBlZmZlY3RzIGhhdmUgcnVuIGZvciB0aGUgdHJlZSAtIGdpdmluZyBjb21wb25lbnRzIGFcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBlbnF1ZXVlUGVuZGluZ1Bhc3NpdmVQcm9maWxlckVmZmVjdChmaWJlcikge1xuICB7XG4gICAgcGVuZGluZ1Bhc3NpdmVQcm9maWxlckVmZmVjdHMucHVzaChmaWJlcik7XG5cbiAgICBpZiAoIXJvb3REb2VzSGF2ZVBhc3NpdmVFZmZlY3RzKSB7XG4gICAgICByb290RG9lc0hhdmVQYXNzaXZlRWZmZWN0cyA9IHRydWU7XG4gICAgICBzY2hlZHVsZUNhbGxiYWNrJDEoTm9ybWFsUHJpb3JpdHksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZmx1c2hQYXNzaXZlRWZmZWN0cygpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBmbHVzaFBhc3NpdmVFZmZlY3RzSW1wbCgpIHtcbiAgaWYgKHJvb3RXaXRoUGVuZGluZ1Bhc3NpdmVFZmZlY3RzID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IC8vIENhY2hlIGFuZCBjbGVhciB0aGUgdHJhbnNpdGlvbnMgZmxhZ1xuXG5cbiAgdmFyIHRyYW5zaXRpb25zID0gcGVuZGluZ1Bhc3NpdmVUcmFuc2l0aW9ucztcbiAgcGVuZGluZ1Bhc3NpdmVUcmFuc2l0aW9ucyA9IG51bGw7XG4gIHZhciByb290ID0gcm9vdFdpdGhQZW5kaW5nUGFzc2l2ZUVmZmVjdHM7XG4gIHZhciBsYW5lcyA9IHBlbmRpbmdQYXNzaXZlRWZmZWN0c0xhbmVzO1xuICByb290V2l0aFBlbmRpbmdQYXNzaXZlRWZmZWN0cyA9IG51bGw7IC8vIFRPRE86IFRoaXMgaXMgc29tZXRpbWVzIG91dCBvZiBzeW5jIHdpdGggcm9vdFdpdGhQZW5kaW5nUGFzc2l2ZUVmZmVjdHMuXG4gIC8vIEZpZ3VyZSBvdXQgd2h5IGFuZCBmaXggaXQuIEl0J3Mgbm90IGNhdXNpbmcgYW55IGtub3duIGlzc3VlcyAocHJvYmFibHlcbiAgLy8gYmVjYXVzZSBpdCdzIG9ubHkgdXNlZCBmb3IgcHJvZmlsaW5nKSwgYnV0IGl0J3MgYSByZWZhY3RvciBoYXphcmQuXG5cbiAgcGVuZGluZ1Bhc3NpdmVFZmZlY3RzTGFuZXMgPSBOb0xhbmVzO1xuXG4gIGlmICgoZXhlY3V0aW9uQ29udGV4dCAmIChSZW5kZXJDb250ZXh0IHwgQ29tbWl0Q29udGV4dCkpICE9PSBOb0NvbnRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmbHVzaCBwYXNzaXZlIGVmZmVjdHMgd2hpbGUgYWxyZWFkeSByZW5kZXJpbmcuJyk7XG4gIH1cblxuICB7XG4gICAgaXNGbHVzaGluZ1Bhc3NpdmVFZmZlY3RzID0gdHJ1ZTtcbiAgICBkaWRTY2hlZHVsZVVwZGF0ZUR1cmluZ1Bhc3NpdmVFZmZlY3RzID0gZmFsc2U7XG4gIH1cblxuICB7XG4gICAgbWFya1Bhc3NpdmVFZmZlY3RzU3RhcnRlZChsYW5lcyk7XG4gIH1cblxuICB2YXIgcHJldkV4ZWN1dGlvbkNvbnRleHQgPSBleGVjdXRpb25Db250ZXh0O1xuICBleGVjdXRpb25Db250ZXh0IHw9IENvbW1pdENvbnRleHQ7XG4gIGNvbW1pdFBhc3NpdmVVbm1vdW50RWZmZWN0cyhyb290LmN1cnJlbnQpO1xuICBjb21taXRQYXNzaXZlTW91bnRFZmZlY3RzKHJvb3QsIHJvb3QuY3VycmVudCwgbGFuZXMsIHRyYW5zaXRpb25zKTsgLy8gVE9ETzogTW92ZSB0byBjb21taXRQYXNzaXZlTW91bnRFZmZlY3RzXG5cbiAge1xuICAgIHZhciBwcm9maWxlckVmZmVjdHMgPSBwZW5kaW5nUGFzc2l2ZVByb2ZpbGVyRWZmZWN0cztcbiAgICBwZW5kaW5nUGFzc2l2ZVByb2ZpbGVyRWZmZWN0cyA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9maWxlckVmZmVjdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBfZmliZXIgPSBwcm9maWxlckVmZmVjdHNbaV07XG4gICAgICBjb21taXRQYXNzaXZlRWZmZWN0RHVyYXRpb25zKHJvb3QsIF9maWJlcik7XG4gICAgfVxuICB9XG5cbiAge1xuICAgIG1hcmtQYXNzaXZlRWZmZWN0c1N0b3BwZWQoKTtcbiAgfVxuXG4gIHtcbiAgICBjb21taXREb3VibGVJbnZva2VFZmZlY3RzSW5ERVYocm9vdC5jdXJyZW50LCB0cnVlKTtcbiAgfVxuXG4gIGV4ZWN1dGlvbkNvbnRleHQgPSBwcmV2RXhlY3V0aW9uQ29udGV4dDtcbiAgZmx1c2hTeW5jQ2FsbGJhY2tzKCk7XG5cbiAge1xuICAgIC8vIElmIGFkZGl0aW9uYWwgcGFzc2l2ZSBlZmZlY3RzIHdlcmUgc2NoZWR1bGVkLCBpbmNyZW1lbnQgYSBjb3VudGVyLiBJZiB0aGlzXG4gICAgLy8gZXhjZWVkcyB0aGUgbGltaXQsIHdlJ2xsIGZpcmUgYSB3YXJuaW5nLlxuICAgIGlmIChkaWRTY2hlZHVsZVVwZGF0ZUR1cmluZ1Bhc3NpdmVFZmZlY3RzKSB7XG4gICAgICBpZiAocm9vdCA9PT0gcm9vdFdpdGhQYXNzaXZlTmVzdGVkVXBkYXRlcykge1xuICAgICAgICBuZXN0ZWRQYXNzaXZlVXBkYXRlQ291bnQrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5lc3RlZFBhc3NpdmVVcGRhdGVDb3VudCA9IDA7XG4gICAgICAgIHJvb3RXaXRoUGFzc2l2ZU5lc3RlZFVwZGF0ZXMgPSByb290O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBuZXN0ZWRQYXNzaXZlVXBkYXRlQ291bnQgPSAwO1xuICAgIH1cblxuICAgIGlzRmx1c2hpbmdQYXNzaXZlRWZmZWN0cyA9IGZhbHNlO1xuICAgIGRpZFNjaGVkdWxlVXBkYXRlRHVyaW5nUGFzc2l2ZUVmZmVjdHMgPSBmYWxzZTtcbiAgfSAvLyBUT0RPOiBNb3ZlIHRvIGNvbW1pdFBhc3NpdmVNb3VudEVmZmVjdHNcblxuXG4gIG9uUG9zdENvbW1pdFJvb3Qocm9vdCk7XG5cbiAge1xuICAgIHZhciBzdGF0ZU5vZGUgPSByb290LmN1cnJlbnQuc3RhdGVOb2RlO1xuICAgIHN0YXRlTm9kZS5lZmZlY3REdXJhdGlvbiA9IDA7XG4gICAgc3RhdGVOb2RlLnBhc3NpdmVFZmZlY3REdXJhdGlvbiA9IDA7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gaXNBbHJlYWR5RmFpbGVkTGVnYWN5RXJyb3JCb3VuZGFyeShpbnN0YW5jZSkge1xuICByZXR1cm4gbGVnYWN5RXJyb3JCb3VuZGFyaWVzVGhhdEFscmVhZHlGYWlsZWQgIT09IG51bGwgJiYgbGVnYWN5RXJyb3JCb3VuZGFyaWVzVGhhdEFscmVhZHlGYWlsZWQuaGFzKGluc3RhbmNlKTtcbn1cbmZ1bmN0aW9uIG1hcmtMZWdhY3lFcnJvckJvdW5kYXJ5QXNGYWlsZWQoaW5zdGFuY2UpIHtcbiAgaWYgKGxlZ2FjeUVycm9yQm91bmRhcmllc1RoYXRBbHJlYWR5RmFpbGVkID09PSBudWxsKSB7XG4gICAgbGVnYWN5RXJyb3JCb3VuZGFyaWVzVGhhdEFscmVhZHlGYWlsZWQgPSBuZXcgU2V0KFtpbnN0YW5jZV0pO1xuICB9IGVsc2Uge1xuICAgIGxlZ2FjeUVycm9yQm91bmRhcmllc1RoYXRBbHJlYWR5RmFpbGVkLmFkZChpbnN0YW5jZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJlcGFyZVRvVGhyb3dVbmNhdWdodEVycm9yKGVycm9yKSB7XG4gIGlmICghaGFzVW5jYXVnaHRFcnJvcikge1xuICAgIGhhc1VuY2F1Z2h0RXJyb3IgPSB0cnVlO1xuICAgIGZpcnN0VW5jYXVnaHRFcnJvciA9IGVycm9yO1xuICB9XG59XG5cbnZhciBvblVuY2F1Z2h0RXJyb3IgPSBwcmVwYXJlVG9UaHJvd1VuY2F1Z2h0RXJyb3I7XG5cbmZ1bmN0aW9uIGNhcHR1cmVDb21taXRQaGFzZUVycm9yT25Sb290KHJvb3RGaWJlciwgc291cmNlRmliZXIsIGVycm9yKSB7XG4gIHZhciBlcnJvckluZm8gPSBjcmVhdGVDYXB0dXJlZFZhbHVlQXRGaWJlcihlcnJvciwgc291cmNlRmliZXIpO1xuICB2YXIgdXBkYXRlID0gY3JlYXRlUm9vdEVycm9yVXBkYXRlKHJvb3RGaWJlciwgZXJyb3JJbmZvLCBTeW5jTGFuZSk7XG4gIHZhciByb290ID0gZW5xdWV1ZVVwZGF0ZShyb290RmliZXIsIHVwZGF0ZSwgU3luY0xhbmUpO1xuICB2YXIgZXZlbnRUaW1lID0gcmVxdWVzdEV2ZW50VGltZSgpO1xuXG4gIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgbWFya1Jvb3RVcGRhdGVkKHJvb3QsIFN5bmNMYW5lLCBldmVudFRpbWUpO1xuICAgIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBldmVudFRpbWUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKHNvdXJjZUZpYmVyLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvciQxKSB7XG4gIHtcbiAgICByZXBvcnRVbmNhdWdodEVycm9ySW5ERVYoZXJyb3IkMSk7XG4gICAgc2V0SXNSdW5uaW5nSW5zZXJ0aW9uRWZmZWN0KGZhbHNlKTtcbiAgfVxuXG4gIGlmIChzb3VyY2VGaWJlci50YWcgPT09IEhvc3RSb290KSB7XG4gICAgLy8gRXJyb3Igd2FzIHRocm93biBhdCB0aGUgcm9vdC4gVGhlcmUgaXMgbm8gcGFyZW50LCBzbyB0aGUgcm9vdFxuICAgIC8vIGl0c2VsZiBzaG91bGQgY2FwdHVyZSBpdC5cbiAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvck9uUm9vdChzb3VyY2VGaWJlciwgc291cmNlRmliZXIsIGVycm9yJDEpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBmaWJlciA9IG51bGw7XG5cbiAge1xuICAgIGZpYmVyID0gbmVhcmVzdE1vdW50ZWRBbmNlc3RvcjtcbiAgfVxuXG4gIHdoaWxlIChmaWJlciAhPT0gbnVsbCkge1xuICAgIGlmIChmaWJlci50YWcgPT09IEhvc3RSb290KSB7XG4gICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvck9uUm9vdChmaWJlciwgc291cmNlRmliZXIsIGVycm9yJDEpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAoZmliZXIudGFnID09PSBDbGFzc0NvbXBvbmVudCkge1xuICAgICAgdmFyIGN0b3IgPSBmaWJlci50eXBlO1xuICAgICAgdmFyIGluc3RhbmNlID0gZmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICBpZiAodHlwZW9mIGN0b3IuZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yID09PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRDYXRjaCA9PT0gJ2Z1bmN0aW9uJyAmJiAhaXNBbHJlYWR5RmFpbGVkTGVnYWN5RXJyb3JCb3VuZGFyeShpbnN0YW5jZSkpIHtcbiAgICAgICAgdmFyIGVycm9ySW5mbyA9IGNyZWF0ZUNhcHR1cmVkVmFsdWVBdEZpYmVyKGVycm9yJDEsIHNvdXJjZUZpYmVyKTtcbiAgICAgICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZUNsYXNzRXJyb3JVcGRhdGUoZmliZXIsIGVycm9ySW5mbywgU3luY0xhbmUpO1xuICAgICAgICB2YXIgcm9vdCA9IGVucXVldWVVcGRhdGUoZmliZXIsIHVwZGF0ZSwgU3luY0xhbmUpO1xuICAgICAgICB2YXIgZXZlbnRUaW1lID0gcmVxdWVzdEV2ZW50VGltZSgpO1xuXG4gICAgICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgbWFya1Jvb3RVcGRhdGVkKHJvb3QsIFN5bmNMYW5lLCBldmVudFRpbWUpO1xuICAgICAgICAgIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBldmVudFRpbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZpYmVyID0gZmliZXIucmV0dXJuO1xuICB9XG5cbiAge1xuICAgIC8vIFRPRE86IFVudGlsIHdlIHJlLWxhbmQgc2tpcFVubW91bnRlZEJvdW5kYXJpZXMgKHNlZSAjMjAxNDcpLCB0aGlzIHdhcm5pbmdcbiAgICAvLyB3aWxsIGZpcmUgZm9yIGVycm9ycyB0aGF0IGFyZSB0aHJvd24gYnkgZGVzdHJveSBmdW5jdGlvbnMgaW5zaWRlIGRlbGV0ZWRcbiAgICAvLyB0cmVlcy4gV2hhdCBpdCBzaG91bGQgaW5zdGVhZCBkbyBpcyBwcm9wYWdhdGUgdGhlIGVycm9yIHRvIHRoZSBwYXJlbnQgb2ZcbiAgICAvLyB0aGUgZGVsZXRlZCB0cmVlLiBJbiB0aGUgbWVhbnRpbWUsIGRvIG5vdCBhZGQgdGhpcyB3YXJuaW5nIHRvIHRoZVxuICAgIC8vIGFsbG93bGlzdDsgdGhpcyBpcyBvbmx5IGZvciBvdXIgaW50ZXJuYWwgdXNlLlxuICAgIGVycm9yKCdJbnRlcm5hbCBSZWFjdCBlcnJvcjogQXR0ZW1wdGVkIHRvIGNhcHR1cmUgYSBjb21taXQgcGhhc2UgZXJyb3IgJyArICdpbnNpZGUgYSBkZXRhY2hlZCB0cmVlLiBUaGlzIGluZGljYXRlcyBhIGJ1ZyBpbiBSZWFjdC4gTGlrZWx5ICcgKyAnY2F1c2VzIGluY2x1ZGUgZGVsZXRpbmcgdGhlIHNhbWUgZmliZXIgbW9yZSB0aGFuIG9uY2UsIGNvbW1pdHRpbmcgYW4gJyArICdhbHJlYWR5LWZpbmlzaGVkIHRyZWUsIG9yIGFuIGluY29uc2lzdGVudCByZXR1cm4gcG9pbnRlci5cXG5cXG4nICsgJ0Vycm9yIG1lc3NhZ2U6XFxuXFxuJXMnLCBlcnJvciQxKTtcbiAgfVxufVxuZnVuY3Rpb24gcGluZ1N1c3BlbmRlZFJvb3Qocm9vdCwgd2FrZWFibGUsIHBpbmdlZExhbmVzKSB7XG4gIHZhciBwaW5nQ2FjaGUgPSByb290LnBpbmdDYWNoZTtcblxuICBpZiAocGluZ0NhY2hlICE9PSBudWxsKSB7XG4gICAgLy8gVGhlIHdha2VhYmxlIHJlc29sdmVkLCBzbyB3ZSBubyBsb25nZXIgbmVlZCB0byBtZW1vaXplLCBiZWNhdXNlIGl0IHdpbGxcbiAgICAvLyBuZXZlciBiZSB0aHJvd24gYWdhaW4uXG4gICAgcGluZ0NhY2hlLmRlbGV0ZSh3YWtlYWJsZSk7XG4gIH1cblxuICB2YXIgZXZlbnRUaW1lID0gcmVxdWVzdEV2ZW50VGltZSgpO1xuICBtYXJrUm9vdFBpbmdlZChyb290LCBwaW5nZWRMYW5lcyk7XG4gIHdhcm5JZlN1c3BlbnNlUmVzb2x1dGlvbk5vdFdyYXBwZWRXaXRoQWN0REVWKHJvb3QpO1xuXG4gIGlmICh3b3JrSW5Qcm9ncmVzc1Jvb3QgPT09IHJvb3QgJiYgaXNTdWJzZXRPZkxhbmVzKHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzLCBwaW5nZWRMYW5lcykpIHtcbiAgICAvLyBSZWNlaXZlZCBhIHBpbmcgYXQgdGhlIHNhbWUgcHJpb3JpdHkgbGV2ZWwgYXQgd2hpY2ggd2UncmUgY3VycmVudGx5XG4gICAgLy8gcmVuZGVyaW5nLiBXZSBtaWdodCB3YW50IHRvIHJlc3RhcnQgdGhpcyByZW5kZXIuIFRoaXMgc2hvdWxkIG1pcnJvclxuICAgIC8vIHRoZSBsb2dpYyBvZiB3aGV0aGVyIG9yIG5vdCBhIHJvb3Qgc3VzcGVuZHMgb25jZSBpdCBjb21wbGV0ZXMuXG4gICAgLy8gVE9ETzogSWYgd2UncmUgcmVuZGVyaW5nIHN5bmMgZWl0aGVyIGR1ZSB0byBTeW5jLCBCYXRjaGVkIG9yIGV4cGlyZWQsXG4gICAgLy8gd2Ugc2hvdWxkIHByb2JhYmx5IG5ldmVyIHJlc3RhcnQuXG4gICAgLy8gSWYgd2UncmUgc3VzcGVuZGVkIHdpdGggZGVsYXksIG9yIGlmIGl0J3MgYSByZXRyeSwgd2UnbGwgYWx3YXlzIHN1c3BlbmRcbiAgICAvLyBzbyB3ZSBjYW4gYWx3YXlzIHJlc3RhcnQuXG4gICAgaWYgKHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPT09IFJvb3RTdXNwZW5kZWRXaXRoRGVsYXkgfHwgd29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9PT0gUm9vdFN1c3BlbmRlZCAmJiBpbmNsdWRlc09ubHlSZXRyaWVzKHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzKSAmJiBub3coKSAtIGdsb2JhbE1vc3RSZWNlbnRGYWxsYmFja1RpbWUgPCBGQUxMQkFDS19USFJPVFRMRV9NUykge1xuICAgICAgLy8gUmVzdGFydCBmcm9tIHRoZSByb290LlxuICAgICAgcHJlcGFyZUZyZXNoU3RhY2socm9vdCwgTm9MYW5lcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEV2ZW4gdGhvdWdoIHdlIGNhbid0IHJlc3RhcnQgcmlnaHQgbm93LCB3ZSBtaWdodCBnZXQgYW5cbiAgICAgIC8vIG9wcG9ydHVuaXR5IGxhdGVyLiBTbyB3ZSBtYXJrIHRoaXMgcmVuZGVyIGFzIGhhdmluZyBhIHBpbmcuXG4gICAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RQaW5nZWRMYW5lcyA9IG1lcmdlTGFuZXMod29ya0luUHJvZ3Jlc3NSb290UGluZ2VkTGFuZXMsIHBpbmdlZExhbmVzKTtcbiAgICB9XG4gIH1cblxuICBlbnN1cmVSb290SXNTY2hlZHVsZWQocm9vdCwgZXZlbnRUaW1lKTtcbn1cblxuZnVuY3Rpb24gcmV0cnlUaW1lZE91dEJvdW5kYXJ5KGJvdW5kYXJ5RmliZXIsIHJldHJ5TGFuZSkge1xuICAvLyBUaGUgYm91bmRhcnkgZmliZXIgKGEgU3VzcGVuc2UgY29tcG9uZW50IG9yIFN1c3BlbnNlTGlzdCBjb21wb25lbnQpXG4gIC8vIHByZXZpb3VzbHkgd2FzIHJlbmRlcmVkIGluIGl0cyBmYWxsYmFjayBzdGF0ZS4gT25lIG9mIHRoZSBwcm9taXNlcyB0aGF0XG4gIC8vIHN1c3BlbmRlZCBpdCBoYXMgcmVzb2x2ZWQsIHdoaWNoIG1lYW5zIGF0IGxlYXN0IHBhcnQgb2YgdGhlIHRyZWUgd2FzXG4gIC8vIGxpa2VseSB1bmJsb2NrZWQuIFRyeSByZW5kZXJpbmcgYWdhaW4sIGF0IGEgbmV3IGxhbmVzLlxuICBpZiAocmV0cnlMYW5lID09PSBOb0xhbmUpIHtcbiAgICAvLyBUT0RPOiBBc3NpZ24gdGhpcyB0byBgc3VzcGVuc2VTdGF0ZS5yZXRyeUxhbmVgPyB0byBhdm9pZFxuICAgIC8vIHVubmVjZXNzYXJ5IGVudGFuZ2xlbWVudD9cbiAgICByZXRyeUxhbmUgPSByZXF1ZXN0UmV0cnlMYW5lKGJvdW5kYXJ5RmliZXIpO1xuICB9IC8vIFRPRE86IFNwZWNpYWwgY2FzZSBpZGxlIHByaW9yaXR5P1xuXG5cbiAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgdmFyIHJvb3QgPSBlbnF1ZXVlQ29uY3VycmVudFJlbmRlckZvckxhbmUoYm91bmRhcnlGaWJlciwgcmV0cnlMYW5lKTtcblxuICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgIG1hcmtSb290VXBkYXRlZChyb290LCByZXRyeUxhbmUsIGV2ZW50VGltZSk7XG4gICAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIGV2ZW50VGltZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmV0cnlEZWh5ZHJhdGVkU3VzcGVuc2VCb3VuZGFyeShib3VuZGFyeUZpYmVyKSB7XG4gIHZhciBzdXNwZW5zZVN0YXRlID0gYm91bmRhcnlGaWJlci5tZW1vaXplZFN0YXRlO1xuICB2YXIgcmV0cnlMYW5lID0gTm9MYW5lO1xuXG4gIGlmIChzdXNwZW5zZVN0YXRlICE9PSBudWxsKSB7XG4gICAgcmV0cnlMYW5lID0gc3VzcGVuc2VTdGF0ZS5yZXRyeUxhbmU7XG4gIH1cblxuICByZXRyeVRpbWVkT3V0Qm91bmRhcnkoYm91bmRhcnlGaWJlciwgcmV0cnlMYW5lKTtcbn1cbmZ1bmN0aW9uIHJlc29sdmVSZXRyeVdha2VhYmxlKGJvdW5kYXJ5RmliZXIsIHdha2VhYmxlKSB7XG4gIHZhciByZXRyeUxhbmUgPSBOb0xhbmU7IC8vIERlZmF1bHRcblxuICB2YXIgcmV0cnlDYWNoZTtcblxuICBzd2l0Y2ggKGJvdW5kYXJ5RmliZXIudGFnKSB7XG4gICAgY2FzZSBTdXNwZW5zZUNvbXBvbmVudDpcbiAgICAgIHJldHJ5Q2FjaGUgPSBib3VuZGFyeUZpYmVyLnN0YXRlTm9kZTtcbiAgICAgIHZhciBzdXNwZW5zZVN0YXRlID0gYm91bmRhcnlGaWJlci5tZW1vaXplZFN0YXRlO1xuXG4gICAgICBpZiAoc3VzcGVuc2VTdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICByZXRyeUxhbmUgPSBzdXNwZW5zZVN0YXRlLnJldHJ5TGFuZTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHJldHJ5Q2FjaGUgPSBib3VuZGFyeUZpYmVyLnN0YXRlTm9kZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGluZ2VkIHVua25vd24gc3VzcGVuc2UgYm91bmRhcnkgdHlwZS4gJyArICdUaGlzIGlzIHByb2JhYmx5IGEgYnVnIGluIFJlYWN0LicpO1xuICB9XG5cbiAgaWYgKHJldHJ5Q2FjaGUgIT09IG51bGwpIHtcbiAgICAvLyBUaGUgd2FrZWFibGUgcmVzb2x2ZWQsIHNvIHdlIG5vIGxvbmdlciBuZWVkIHRvIG1lbW9pemUsIGJlY2F1c2UgaXQgd2lsbFxuICAgIC8vIG5ldmVyIGJlIHRocm93biBhZ2Fpbi5cbiAgICByZXRyeUNhY2hlLmRlbGV0ZSh3YWtlYWJsZSk7XG4gIH1cblxuICByZXRyeVRpbWVkT3V0Qm91bmRhcnkoYm91bmRhcnlGaWJlciwgcmV0cnlMYW5lKTtcbn0gLy8gQ29tcHV0ZXMgdGhlIG5leHQgSnVzdCBOb3RpY2VhYmxlIERpZmZlcmVuY2UgKEpORCkgYm91bmRhcnkuXG4vLyBUaGUgdGhlb3J5IGlzIHRoYXQgYSBwZXJzb24gY2FuJ3QgdGVsbCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHNtYWxsIGRpZmZlcmVuY2VzIGluIHRpbWUuXG4vLyBUaGVyZWZvcmUsIGlmIHdlIHdhaXQgYSBiaXQgbG9uZ2VyIHRoYW4gbmVjZXNzYXJ5IHRoYXQgd29uJ3QgdHJhbnNsYXRlIHRvIGEgbm90aWNlYWJsZVxuLy8gZGlmZmVyZW5jZSBpbiB0aGUgZXhwZXJpZW5jZS4gSG93ZXZlciwgd2FpdGluZyBmb3IgbG9uZ2VyIG1pZ2h0IG1lYW4gdGhhdCB3ZSBjYW4gYXZvaWRcbi8vIHNob3dpbmcgYW4gaW50ZXJtZWRpYXRlIGxvYWRpbmcgc3RhdGUuIFRoZSBsb25nZXIgd2UgaGF2ZSBhbHJlYWR5IHdhaXRlZCwgdGhlIGhhcmRlciBpdFxuLy8gaXMgdG8gdGVsbCBzbWFsbCBkaWZmZXJlbmNlcyBpbiB0aW1lLiBUaGVyZWZvcmUsIHRoZSBsb25nZXIgd2UndmUgYWxyZWFkeSB3YWl0ZWQsXG4vLyB0aGUgbG9uZ2VyIHdlIGNhbiB3YWl0IGFkZGl0aW9uYWxseS4gQXQgc29tZSBwb2ludCB3ZSBoYXZlIHRvIGdpdmUgdXAgdGhvdWdoLlxuLy8gV2UgcGljayBhIHRyYWluIG1vZGVsIHdoZXJlIHRoZSBuZXh0IGJvdW5kYXJ5IGNvbW1pdHMgYXQgYSBjb25zaXN0ZW50IHNjaGVkdWxlLlxuLy8gVGhlc2UgcGFydGljdWxhciBudW1iZXJzIGFyZSB2YWd1ZSBlc3RpbWF0ZXMuIFdlIGV4cGVjdCB0byBhZGp1c3QgdGhlbSBiYXNlZCBvbiByZXNlYXJjaC5cblxuZnVuY3Rpb24gam5kKHRpbWVFbGFwc2VkKSB7XG4gIHJldHVybiB0aW1lRWxhcHNlZCA8IDEyMCA/IDEyMCA6IHRpbWVFbGFwc2VkIDwgNDgwID8gNDgwIDogdGltZUVsYXBzZWQgPCAxMDgwID8gMTA4MCA6IHRpbWVFbGFwc2VkIDwgMTkyMCA/IDE5MjAgOiB0aW1lRWxhcHNlZCA8IDMwMDAgPyAzMDAwIDogdGltZUVsYXBzZWQgPCA0MzIwID8gNDMyMCA6IGNlaWwodGltZUVsYXBzZWQgLyAxOTYwKSAqIDE5NjA7XG59XG5cbmZ1bmN0aW9uIGNoZWNrRm9yTmVzdGVkVXBkYXRlcygpIHtcbiAgaWYgKG5lc3RlZFVwZGF0ZUNvdW50ID4gTkVTVEVEX1VQREFURV9MSU1JVCkge1xuICAgIG5lc3RlZFVwZGF0ZUNvdW50ID0gMDtcbiAgICByb290V2l0aE5lc3RlZFVwZGF0ZXMgPSBudWxsO1xuICAgIHRocm93IG5ldyBFcnJvcignTWF4aW11bSB1cGRhdGUgZGVwdGggZXhjZWVkZWQuIFRoaXMgY2FuIGhhcHBlbiB3aGVuIGEgY29tcG9uZW50ICcgKyAncmVwZWF0ZWRseSBjYWxscyBzZXRTdGF0ZSBpbnNpZGUgY29tcG9uZW50V2lsbFVwZGF0ZSBvciAnICsgJ2NvbXBvbmVudERpZFVwZGF0ZS4gUmVhY3QgbGltaXRzIHRoZSBudW1iZXIgb2YgbmVzdGVkIHVwZGF0ZXMgdG8gJyArICdwcmV2ZW50IGluZmluaXRlIGxvb3BzLicpO1xuICB9XG5cbiAge1xuICAgIGlmIChuZXN0ZWRQYXNzaXZlVXBkYXRlQ291bnQgPiBORVNURURfUEFTU0lWRV9VUERBVEVfTElNSVQpIHtcbiAgICAgIG5lc3RlZFBhc3NpdmVVcGRhdGVDb3VudCA9IDA7XG4gICAgICByb290V2l0aFBhc3NpdmVOZXN0ZWRVcGRhdGVzID0gbnVsbDtcblxuICAgICAgZXJyb3IoJ01heGltdW0gdXBkYXRlIGRlcHRoIGV4Y2VlZGVkLiBUaGlzIGNhbiBoYXBwZW4gd2hlbiBhIGNvbXBvbmVudCAnICsgXCJjYWxscyBzZXRTdGF0ZSBpbnNpZGUgdXNlRWZmZWN0LCBidXQgdXNlRWZmZWN0IGVpdGhlciBkb2Vzbid0IFwiICsgJ2hhdmUgYSBkZXBlbmRlbmN5IGFycmF5LCBvciBvbmUgb2YgdGhlIGRlcGVuZGVuY2llcyBjaGFuZ2VzIG9uICcgKyAnZXZlcnkgcmVuZGVyLicpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBmbHVzaFJlbmRlclBoYXNlU3RyaWN0TW9kZVdhcm5pbmdzSW5ERVYoKSB7XG4gIHtcbiAgICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5mbHVzaExlZ2FjeUNvbnRleHRXYXJuaW5nKCk7XG5cbiAgICB7XG4gICAgICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5mbHVzaFBlbmRpbmdVbnNhZmVMaWZlY3ljbGVXYXJuaW5ncygpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXREb3VibGVJbnZva2VFZmZlY3RzSW5ERVYoZmliZXIsIGhhc1Bhc3NpdmVFZmZlY3RzKSB7XG4gIHtcbiAgICAvLyBUT0RPIChTdHJpY3RFZmZlY3RzKSBTaG91bGQgd2Ugc2V0IGEgbWFya2VyIG9uIHRoZSByb290IGlmIGl0IGNvbnRhaW5zIHN0cmljdCBlZmZlY3RzXG4gICAgLy8gc28gd2UgZG9uJ3QgdHJhdmVyc2UgdW5uZWNlc3NhcmlseT8gc2ltaWxhciB0byBzdWJ0cmVlRmxhZ3MgYnV0IGp1c3QgYXQgdGhlIHJvb3QgbGV2ZWwuXG4gICAgLy8gTWF5YmUgbm90IGEgYmlnIGRlYWwgc2luY2UgdGhpcyBpcyBERVYgb25seSBiZWhhdmlvci5cbiAgICBzZXRDdXJyZW50RmliZXIoZmliZXIpO1xuICAgIGludm9rZUVmZmVjdHNJbkRldihmaWJlciwgTW91bnRMYXlvdXREZXYsIGludm9rZUxheW91dEVmZmVjdFVubW91bnRJbkRFVik7XG5cbiAgICBpZiAoaGFzUGFzc2l2ZUVmZmVjdHMpIHtcbiAgICAgIGludm9rZUVmZmVjdHNJbkRldihmaWJlciwgTW91bnRQYXNzaXZlRGV2LCBpbnZva2VQYXNzaXZlRWZmZWN0VW5tb3VudEluREVWKTtcbiAgICB9XG5cbiAgICBpbnZva2VFZmZlY3RzSW5EZXYoZmliZXIsIE1vdW50TGF5b3V0RGV2LCBpbnZva2VMYXlvdXRFZmZlY3RNb3VudEluREVWKTtcblxuICAgIGlmIChoYXNQYXNzaXZlRWZmZWN0cykge1xuICAgICAgaW52b2tlRWZmZWN0c0luRGV2KGZpYmVyLCBNb3VudFBhc3NpdmVEZXYsIGludm9rZVBhc3NpdmVFZmZlY3RNb3VudEluREVWKTtcbiAgICB9XG5cbiAgICByZXNldEN1cnJlbnRGaWJlcigpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGludm9rZUVmZmVjdHNJbkRldihmaXJzdENoaWxkLCBmaWJlckZsYWdzLCBpbnZva2VFZmZlY3RGbikge1xuICB7XG4gICAgLy8gV2UgZG9uJ3QgbmVlZCB0byByZS1jaGVjayBTdHJpY3RFZmZlY3RzTW9kZSBoZXJlLlxuICAgIC8vIFRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWQgaWYgdGhhdCBjaGVjayBoYXMgYWxyZWFkeSBwYXNzZWQuXG4gICAgdmFyIGN1cnJlbnQgPSBmaXJzdENoaWxkO1xuICAgIHZhciBzdWJ0cmVlUm9vdCA9IG51bGw7XG5cbiAgICB3aGlsZSAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgdmFyIHByaW1hcnlTdWJ0cmVlRmxhZyA9IGN1cnJlbnQuc3VidHJlZUZsYWdzICYgZmliZXJGbGFncztcblxuICAgICAgaWYgKGN1cnJlbnQgIT09IHN1YnRyZWVSb290ICYmIGN1cnJlbnQuY2hpbGQgIT09IG51bGwgJiYgcHJpbWFyeVN1YnRyZWVGbGFnICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50LmNoaWxkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKChjdXJyZW50LmZsYWdzICYgZmliZXJGbGFncykgIT09IE5vRmxhZ3MpIHtcbiAgICAgICAgICBpbnZva2VFZmZlY3RGbihjdXJyZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjdXJyZW50LnNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgICAgICBjdXJyZW50ID0gY3VycmVudC5zaWJsaW5nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGN1cnJlbnQgPSBzdWJ0cmVlUm9vdCA9IGN1cnJlbnQucmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBkaWRXYXJuU3RhdGVVcGRhdGVGb3JOb3RZZXRNb3VudGVkQ29tcG9uZW50ID0gbnVsbDtcbmZ1bmN0aW9uIHdhcm5BYm91dFVwZGF0ZU9uTm90WWV0TW91bnRlZEZpYmVySW5ERVYoZmliZXIpIHtcbiAge1xuICAgIGlmICgoZXhlY3V0aW9uQ29udGV4dCAmIFJlbmRlckNvbnRleHQpICE9PSBOb0NvbnRleHQpIHtcbiAgICAgIC8vIFdlIGxldCB0aGUgb3RoZXIgd2FybmluZyBhYm91dCByZW5kZXIgcGhhc2UgdXBkYXRlcyBkZWFsIHdpdGggdGhpcyBvbmUuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCEoZmliZXIubW9kZSAmIENvbmN1cnJlbnRNb2RlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciB0YWcgPSBmaWJlci50YWc7XG5cbiAgICBpZiAodGFnICE9PSBJbmRldGVybWluYXRlQ29tcG9uZW50ICYmIHRhZyAhPT0gSG9zdFJvb3QgJiYgdGFnICE9PSBDbGFzc0NvbXBvbmVudCAmJiB0YWcgIT09IEZ1bmN0aW9uQ29tcG9uZW50ICYmIHRhZyAhPT0gRm9yd2FyZFJlZiAmJiB0YWcgIT09IE1lbW9Db21wb25lbnQgJiYgdGFnICE9PSBTaW1wbGVNZW1vQ29tcG9uZW50KSB7XG4gICAgICAvLyBPbmx5IHdhcm4gZm9yIHVzZXItZGVmaW5lZCBjb21wb25lbnRzLCBub3QgaW50ZXJuYWwgb25lcyBsaWtlIFN1c3BlbnNlLlxuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gV2Ugc2hvdyB0aGUgd2hvbGUgc3RhY2sgYnV0IGRlZHVwZSBvbiB0aGUgdG9wIGNvbXBvbmVudCdzIG5hbWUgYmVjYXVzZVxuICAgIC8vIHRoZSBwcm9ibGVtYXRpYyBjb2RlIGFsbW9zdCBhbHdheXMgbGllcyBpbnNpZGUgdGhhdCBjb21wb25lbnQuXG5cblxuICAgIHZhciBjb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ1JlYWN0Q29tcG9uZW50JztcblxuICAgIGlmIChkaWRXYXJuU3RhdGVVcGRhdGVGb3JOb3RZZXRNb3VudGVkQ29tcG9uZW50ICE9PSBudWxsKSB7XG4gICAgICBpZiAoZGlkV2FyblN0YXRlVXBkYXRlRm9yTm90WWV0TW91bnRlZENvbXBvbmVudC5oYXMoY29tcG9uZW50TmFtZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBkaWRXYXJuU3RhdGVVcGRhdGVGb3JOb3RZZXRNb3VudGVkQ29tcG9uZW50LmFkZChjb21wb25lbnROYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGlkV2FyblN0YXRlVXBkYXRlRm9yTm90WWV0TW91bnRlZENvbXBvbmVudCA9IG5ldyBTZXQoW2NvbXBvbmVudE5hbWVdKTtcbiAgICB9XG5cbiAgICB2YXIgcHJldmlvdXNGaWJlciA9IGN1cnJlbnQ7XG5cbiAgICB0cnkge1xuICAgICAgc2V0Q3VycmVudEZpYmVyKGZpYmVyKTtcblxuICAgICAgZXJyb3IoXCJDYW4ndCBwZXJmb3JtIGEgUmVhY3Qgc3RhdGUgdXBkYXRlIG9uIGEgY29tcG9uZW50IHRoYXQgaGFzbid0IG1vdW50ZWQgeWV0LiBcIiArICdUaGlzIGluZGljYXRlcyB0aGF0IHlvdSBoYXZlIGEgc2lkZS1lZmZlY3QgaW4geW91ciByZW5kZXIgZnVuY3Rpb24gdGhhdCAnICsgJ2FzeW5jaHJvbm91c2x5IGxhdGVyIGNhbGxzIHRyaWVzIHRvIHVwZGF0ZSB0aGUgY29tcG9uZW50LiBNb3ZlIHRoaXMgd29yayB0byAnICsgJ3VzZUVmZmVjdCBpbnN0ZWFkLicpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAocHJldmlvdXNGaWJlcikge1xuICAgICAgICBzZXRDdXJyZW50RmliZXIoZmliZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzZXRDdXJyZW50RmliZXIoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbnZhciBiZWdpbldvcmskMTtcblxue1xuICB2YXIgZHVtbXlGaWJlciA9IG51bGw7XG5cbiAgYmVnaW5Xb3JrJDEgPSBmdW5jdGlvbiAoY3VycmVudCwgdW5pdE9mV29yaywgbGFuZXMpIHtcbiAgICAvLyBJZiBhIGNvbXBvbmVudCB0aHJvd3MgYW4gZXJyb3IsIHdlIHJlcGxheSBpdCBhZ2FpbiBpbiBhIHN5bmNocm9ub3VzbHlcbiAgICAvLyBkaXNwYXRjaGVkIGV2ZW50LCBzbyB0aGF0IHRoZSBkZWJ1Z2dlciB3aWxsIHRyZWF0IGl0IGFzIGFuIHVuY2F1Z2h0XG4gICAgLy8gZXJyb3IgU2VlIFJlYWN0RXJyb3JVdGlscyBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICAvLyBCZWZvcmUgZW50ZXJpbmcgdGhlIGJlZ2luIHBoYXNlLCBjb3B5IHRoZSB3b3JrLWluLXByb2dyZXNzIG9udG8gYSBkdW1teVxuICAgIC8vIGZpYmVyLiBJZiBiZWdpbldvcmsgdGhyb3dzLCB3ZSdsbCB1c2UgdGhpcyB0byByZXNldCB0aGUgc3RhdGUuXG4gICAgdmFyIG9yaWdpbmFsV29ya0luUHJvZ3Jlc3NDb3B5ID0gYXNzaWduRmliZXJQcm9wZXJ0aWVzSW5ERVYoZHVtbXlGaWJlciwgdW5pdE9mV29yayk7XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGJlZ2luV29yayhjdXJyZW50LCB1bml0T2ZXb3JrLCBsYW5lcyk7XG4gICAgfSBjYXRjaCAob3JpZ2luYWxFcnJvcikge1xuICAgICAgaWYgKGRpZFN1c3BlbmRPckVycm9yV2hpbGVIeWRyYXRpbmdERVYoKSB8fCBvcmlnaW5hbEVycm9yICE9PSBudWxsICYmIHR5cGVvZiBvcmlnaW5hbEVycm9yID09PSAnb2JqZWN0JyAmJiB0eXBlb2Ygb3JpZ2luYWxFcnJvci50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIERvbid0IHJlcGxheSBwcm9taXNlcy5cbiAgICAgICAgLy8gRG9uJ3QgcmVwbGF5IGVycm9ycyBpZiB3ZSBhcmUgaHlkcmF0aW5nIGFuZCBoYXZlIGFscmVhZHkgc3VzcGVuZGVkIG9yIGhhbmRsZWQgYW4gZXJyb3JcbiAgICAgICAgdGhyb3cgb3JpZ2luYWxFcnJvcjtcbiAgICAgIH0gLy8gS2VlcCB0aGlzIGNvZGUgaW4gc3luYyB3aXRoIGhhbmRsZUVycm9yOyBhbnkgY2hhbmdlcyBoZXJlIG11c3QgaGF2ZVxuICAgICAgLy8gY29ycmVzcG9uZGluZyBjaGFuZ2VzIHRoZXJlLlxuXG5cbiAgICAgIHJlc2V0Q29udGV4dERlcGVuZGVuY2llcygpO1xuICAgICAgcmVzZXRIb29rc0FmdGVyVGhyb3coKTsgLy8gRG9uJ3QgcmVzZXQgY3VycmVudCBkZWJ1ZyBmaWJlciwgc2luY2Ugd2UncmUgYWJvdXQgdG8gd29yayBvbiB0aGVcbiAgICAgIC8vIHNhbWUgZmliZXIgYWdhaW4uXG4gICAgICAvLyBVbndpbmQgdGhlIGZhaWxlZCBzdGFjayBmcmFtZVxuXG4gICAgICB1bndpbmRJbnRlcnJ1cHRlZFdvcmsoY3VycmVudCwgdW5pdE9mV29yayk7IC8vIFJlc3RvcmUgdGhlIG9yaWdpbmFsIHByb3BlcnRpZXMgb2YgdGhlIGZpYmVyLlxuXG4gICAgICBhc3NpZ25GaWJlclByb3BlcnRpZXNJbkRFVih1bml0T2ZXb3JrLCBvcmlnaW5hbFdvcmtJblByb2dyZXNzQ29weSk7XG5cbiAgICAgIGlmICggdW5pdE9mV29yay5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgLy8gUmVzZXQgdGhlIHByb2ZpbGVyIHRpbWVyLlxuICAgICAgICBzdGFydFByb2ZpbGVyVGltZXIodW5pdE9mV29yayk7XG4gICAgICB9IC8vIFJ1biBiZWdpbldvcmsgYWdhaW4uXG5cblxuICAgICAgaW52b2tlR3VhcmRlZENhbGxiYWNrKG51bGwsIGJlZ2luV29yaywgbnVsbCwgY3VycmVudCwgdW5pdE9mV29yaywgbGFuZXMpO1xuXG4gICAgICBpZiAoaGFzQ2F1Z2h0RXJyb3IoKSkge1xuICAgICAgICB2YXIgcmVwbGF5RXJyb3IgPSBjbGVhckNhdWdodEVycm9yKCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiByZXBsYXlFcnJvciA9PT0gJ29iamVjdCcgJiYgcmVwbGF5RXJyb3IgIT09IG51bGwgJiYgcmVwbGF5RXJyb3IuX3N1cHByZXNzTG9nZ2luZyAmJiB0eXBlb2Ygb3JpZ2luYWxFcnJvciA9PT0gJ29iamVjdCcgJiYgb3JpZ2luYWxFcnJvciAhPT0gbnVsbCAmJiAhb3JpZ2luYWxFcnJvci5fc3VwcHJlc3NMb2dnaW5nKSB7XG4gICAgICAgICAgLy8gSWYgc3VwcHJlc3NlZCwgbGV0IHRoZSBmbGFnIGNhcnJ5IG92ZXIgdG8gdGhlIG9yaWdpbmFsIGVycm9yIHdoaWNoIGlzIHRoZSBvbmUgd2UnbGwgcmV0aHJvdy5cbiAgICAgICAgICBvcmlnaW5hbEVycm9yLl9zdXBwcmVzc0xvZ2dpbmcgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9IC8vIFdlIGFsd2F5cyB0aHJvdyB0aGUgb3JpZ2luYWwgZXJyb3IgaW4gY2FzZSB0aGUgc2Vjb25kIHJlbmRlciBwYXNzIGlzIG5vdCBpZGVtcG90ZW50LlxuICAgICAgLy8gVGhpcyBjYW4gaGFwcGVuIGlmIGEgbWVtb2l6ZWQgZnVuY3Rpb24gb3IgQ29tbW9uSlMgbW9kdWxlIGRvZXNuJ3QgdGhyb3cgYWZ0ZXIgZmlyc3QgaW52b2NhdGlvbi5cblxuXG4gICAgICB0aHJvdyBvcmlnaW5hbEVycm9yO1xuICAgIH1cbiAgfTtcbn1cblxudmFyIGRpZFdhcm5BYm91dFVwZGF0ZUluUmVuZGVyID0gZmFsc2U7XG52YXIgZGlkV2FybkFib3V0VXBkYXRlSW5SZW5kZXJGb3JBbm90aGVyQ29tcG9uZW50O1xuXG57XG4gIGRpZFdhcm5BYm91dFVwZGF0ZUluUmVuZGVyRm9yQW5vdGhlckNvbXBvbmVudCA9IG5ldyBTZXQoKTtcbn1cblxuZnVuY3Rpb24gd2FybkFib3V0UmVuZGVyUGhhc2VVcGRhdGVzSW5ERVYoZmliZXIpIHtcbiAge1xuICAgIGlmIChpc1JlbmRlcmluZyAmJiAhZ2V0SXNVcGRhdGluZ09wYXF1ZVZhbHVlSW5SZW5kZXJQaGFzZUluREVWKCkpIHtcbiAgICAgIHN3aXRjaCAoZmliZXIudGFnKSB7XG4gICAgICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciByZW5kZXJpbmdDb21wb25lbnROYW1lID0gd29ya0luUHJvZ3Jlc3MgJiYgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcih3b3JrSW5Qcm9ncmVzcykgfHwgJ1Vua25vd24nOyAvLyBEZWR1cGUgYnkgdGhlIHJlbmRlcmluZyBjb21wb25lbnQgYmVjYXVzZSBpdCdzIHRoZSBvbmUgdGhhdCBuZWVkcyB0byBiZSBmaXhlZC5cblxuICAgICAgICAgICAgdmFyIGRlZHVwZUtleSA9IHJlbmRlcmluZ0NvbXBvbmVudE5hbWU7XG5cbiAgICAgICAgICAgIGlmICghZGlkV2FybkFib3V0VXBkYXRlSW5SZW5kZXJGb3JBbm90aGVyQ29tcG9uZW50LmhhcyhkZWR1cGVLZXkpKSB7XG4gICAgICAgICAgICAgIGRpZFdhcm5BYm91dFVwZGF0ZUluUmVuZGVyRm9yQW5vdGhlckNvbXBvbmVudC5hZGQoZGVkdXBlS2V5KTtcbiAgICAgICAgICAgICAgdmFyIHNldFN0YXRlQ29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdVbmtub3duJztcblxuICAgICAgICAgICAgICBlcnJvcignQ2Fubm90IHVwZGF0ZSBhIGNvbXBvbmVudCAoYCVzYCkgd2hpbGUgcmVuZGVyaW5nIGEgJyArICdkaWZmZXJlbnQgY29tcG9uZW50IChgJXNgKS4gVG8gbG9jYXRlIHRoZSBiYWQgc2V0U3RhdGUoKSBjYWxsIGluc2lkZSBgJXNgLCAnICsgJ2ZvbGxvdyB0aGUgc3RhY2sgdHJhY2UgYXMgZGVzY3JpYmVkIGluIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zZXRzdGF0ZS1pbi1yZW5kZXInLCBzZXRTdGF0ZUNvbXBvbmVudE5hbWUsIHJlbmRlcmluZ0NvbXBvbmVudE5hbWUsIHJlbmRlcmluZ0NvbXBvbmVudE5hbWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZiAoIWRpZFdhcm5BYm91dFVwZGF0ZUluUmVuZGVyKSB7XG4gICAgICAgICAgICAgIGVycm9yKCdDYW5ub3QgdXBkYXRlIGR1cmluZyBhbiBleGlzdGluZyBzdGF0ZSB0cmFuc2l0aW9uIChzdWNoIGFzICcgKyAnd2l0aGluIGByZW5kZXJgKS4gUmVuZGVyIG1ldGhvZHMgc2hvdWxkIGJlIGEgcHVyZSAnICsgJ2Z1bmN0aW9uIG9mIHByb3BzIGFuZCBzdGF0ZS4nKTtcblxuICAgICAgICAgICAgICBkaWRXYXJuQWJvdXRVcGRhdGVJblJlbmRlciA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzdG9yZVBlbmRpbmdVcGRhdGVycyhyb290LCBsYW5lcykge1xuICB7XG4gICAgaWYgKGlzRGV2VG9vbHNQcmVzZW50KSB7XG4gICAgICB2YXIgbWVtb2l6ZWRVcGRhdGVycyA9IHJvb3QubWVtb2l6ZWRVcGRhdGVycztcbiAgICAgIG1lbW9pemVkVXBkYXRlcnMuZm9yRWFjaChmdW5jdGlvbiAoc2NoZWR1bGluZ0ZpYmVyKSB7XG4gICAgICAgIGFkZEZpYmVyVG9MYW5lc01hcChyb290LCBzY2hlZHVsaW5nRmliZXIsIGxhbmVzKTtcbiAgICAgIH0pOyAvLyBUaGlzIGZ1bmN0aW9uIGludGVudGlvbmFsbHkgZG9lcyBub3QgY2xlYXIgbWVtb2l6ZWQgdXBkYXRlcnMuXG4gICAgICAvLyBUaG9zZSBtYXkgc3RpbGwgYmUgcmVsZXZhbnQgdG8gdGhlIGN1cnJlbnQgY29tbWl0XG4gICAgICAvLyBhbmQgYSBmdXR1cmUgb25lIChlLmcuIFN1c3BlbnNlKS5cbiAgICB9XG4gIH1cbn1cbnZhciBmYWtlQWN0Q2FsbGJhY2tOb2RlID0ge307XG5cbmZ1bmN0aW9uIHNjaGVkdWxlQ2FsbGJhY2skMShwcmlvcml0eUxldmVsLCBjYWxsYmFjaykge1xuICB7XG4gICAgLy8gSWYgd2UncmUgY3VycmVudGx5IGluc2lkZSBhbiBgYWN0YCBzY29wZSwgYnlwYXNzIFNjaGVkdWxlciBhbmQgcHVzaCB0b1xuICAgIC8vIHRoZSBgYWN0YCBxdWV1ZSBpbnN0ZWFkLlxuICAgIHZhciBhY3RRdWV1ZSA9IFJlYWN0Q3VycmVudEFjdFF1ZXVlJDEuY3VycmVudDtcblxuICAgIGlmIChhY3RRdWV1ZSAhPT0gbnVsbCkge1xuICAgICAgYWN0UXVldWUucHVzaChjYWxsYmFjayk7XG4gICAgICByZXR1cm4gZmFrZUFjdENhbGxiYWNrTm9kZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHNjaGVkdWxlQ2FsbGJhY2socHJpb3JpdHlMZXZlbCwgY2FsbGJhY2spO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjYW5jZWxDYWxsYmFjayQxKGNhbGxiYWNrTm9kZSkge1xuICBpZiAoIGNhbGxiYWNrTm9kZSA9PT0gZmFrZUFjdENhbGxiYWNrTm9kZSkge1xuICAgIHJldHVybjtcbiAgfSAvLyBJbiBwcm9kdWN0aW9uLCBhbHdheXMgY2FsbCBTY2hlZHVsZXIuIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBzdHJpcHBlZCBvdXQuXG5cblxuICByZXR1cm4gY2FuY2VsQ2FsbGJhY2soY2FsbGJhY2tOb2RlKTtcbn1cblxuZnVuY3Rpb24gc2hvdWxkRm9yY2VGbHVzaEZhbGxiYWNrc0luREVWKCkge1xuICAvLyBOZXZlciBmb3JjZSBmbHVzaCBpbiBwcm9kdWN0aW9uLiBUaGlzIGZ1bmN0aW9uIHNob3VsZCBnZXQgc3RyaXBwZWQgb3V0LlxuICByZXR1cm4gIFJlYWN0Q3VycmVudEFjdFF1ZXVlJDEuY3VycmVudCAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gd2FybklmVXBkYXRlc05vdFdyYXBwZWRXaXRoQWN0REVWKGZpYmVyKSB7XG4gIHtcbiAgICBpZiAoZmliZXIubW9kZSAmIENvbmN1cnJlbnRNb2RlKSB7XG4gICAgICBpZiAoIWlzQ29uY3VycmVudEFjdEVudmlyb25tZW50KCkpIHtcbiAgICAgICAgLy8gTm90IGluIGFuIGFjdCBlbnZpcm9ubWVudC4gTm8gbmVlZCB0byB3YXJuLlxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIExlZ2FjeSBtb2RlIGhhcyBhZGRpdGlvbmFsIGNhc2VzIHdoZXJlIHdlIHN1cHByZXNzIGEgd2FybmluZy5cbiAgICAgIGlmICghaXNMZWdhY3lBY3RFbnZpcm9ubWVudCgpKSB7XG4gICAgICAgIC8vIE5vdCBpbiBhbiBhY3QgZW52aXJvbm1lbnQuIE5vIG5lZWQgdG8gd2Fybi5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXhlY3V0aW9uQ29udGV4dCAhPT0gTm9Db250ZXh0KSB7XG4gICAgICAgIC8vIExlZ2FjeSBtb2RlIGRvZXNuJ3Qgd2FybiBpZiB0aGUgdXBkYXRlIGlzIGJhdGNoZWQsIGkuZS5cbiAgICAgICAgLy8gYmF0Y2hlZFVwZGF0ZXMgb3IgZmx1c2hTeW5jLlxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChmaWJlci50YWcgIT09IEZ1bmN0aW9uQ29tcG9uZW50ICYmIGZpYmVyLnRhZyAhPT0gRm9yd2FyZFJlZiAmJiBmaWJlci50YWcgIT09IFNpbXBsZU1lbW9Db21wb25lbnQpIHtcbiAgICAgICAgLy8gRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHdpdGggcHJlLWhvb2tzIGNvZGUsIGxlZ2FjeSBtb2RlIG9ubHlcbiAgICAgICAgLy8gd2FybnMgZm9yIHVwZGF0ZXMgdGhhdCBvcmlnaW5hdGUgZnJvbSBhIGhvb2suXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoUmVhY3RDdXJyZW50QWN0UXVldWUkMS5jdXJyZW50ID09PSBudWxsKSB7XG4gICAgICB2YXIgcHJldmlvdXNGaWJlciA9IGN1cnJlbnQ7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHNldEN1cnJlbnRGaWJlcihmaWJlcik7XG5cbiAgICAgICAgZXJyb3IoJ0FuIHVwZGF0ZSB0byAlcyBpbnNpZGUgYSB0ZXN0IHdhcyBub3Qgd3JhcHBlZCBpbiBhY3QoLi4uKS5cXG5cXG4nICsgJ1doZW4gdGVzdGluZywgY29kZSB0aGF0IGNhdXNlcyBSZWFjdCBzdGF0ZSB1cGRhdGVzIHNob3VsZCBiZSAnICsgJ3dyYXBwZWQgaW50byBhY3QoLi4uKTpcXG5cXG4nICsgJ2FjdCgoKSA9PiB7XFxuJyArICcgIC8qIGZpcmUgZXZlbnRzIHRoYXQgdXBkYXRlIHN0YXRlICovXFxuJyArICd9KTtcXG4nICsgJy8qIGFzc2VydCBvbiB0aGUgb3V0cHV0ICovXFxuXFxuJyArIFwiVGhpcyBlbnN1cmVzIHRoYXQgeW91J3JlIHRlc3RpbmcgdGhlIGJlaGF2aW9yIHRoZSB1c2VyIHdvdWxkIHNlZSBcIiArICdpbiB0aGUgYnJvd3Nlci4nICsgJyBMZWFybiBtb3JlIGF0IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay93cmFwLXRlc3RzLXdpdGgtYWN0JywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKHByZXZpb3VzRmliZXIpIHtcbiAgICAgICAgICBzZXRDdXJyZW50RmliZXIoZmliZXIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gd2FybklmU3VzcGVuc2VSZXNvbHV0aW9uTm90V3JhcHBlZFdpdGhBY3RERVYocm9vdCkge1xuICB7XG4gICAgaWYgKHJvb3QudGFnICE9PSBMZWdhY3lSb290ICYmIGlzQ29uY3VycmVudEFjdEVudmlyb25tZW50KCkgJiYgUmVhY3RDdXJyZW50QWN0UXVldWUkMS5jdXJyZW50ID09PSBudWxsKSB7XG4gICAgICBlcnJvcignQSBzdXNwZW5kZWQgcmVzb3VyY2UgZmluaXNoZWQgbG9hZGluZyBpbnNpZGUgYSB0ZXN0LCBidXQgdGhlIGV2ZW50ICcgKyAnd2FzIG5vdCB3cmFwcGVkIGluIGFjdCguLi4pLlxcblxcbicgKyAnV2hlbiB0ZXN0aW5nLCBjb2RlIHRoYXQgcmVzb2x2ZXMgc3VzcGVuZGVkIGRhdGEgc2hvdWxkIGJlIHdyYXBwZWQgJyArICdpbnRvIGFjdCguLi4pOlxcblxcbicgKyAnYWN0KCgpID0+IHtcXG4nICsgJyAgLyogZmluaXNoIGxvYWRpbmcgc3VzcGVuZGVkIGRhdGEgKi9cXG4nICsgJ30pO1xcbicgKyAnLyogYXNzZXJ0IG9uIHRoZSBvdXRwdXQgKi9cXG5cXG4nICsgXCJUaGlzIGVuc3VyZXMgdGhhdCB5b3UncmUgdGVzdGluZyB0aGUgYmVoYXZpb3IgdGhlIHVzZXIgd291bGQgc2VlIFwiICsgJ2luIHRoZSBicm93c2VyLicgKyAnIExlYXJuIG1vcmUgYXQgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3dyYXAtdGVzdHMtd2l0aC1hY3QnKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gc2V0SXNSdW5uaW5nSW5zZXJ0aW9uRWZmZWN0KGlzUnVubmluZykge1xuICB7XG4gICAgaXNSdW5uaW5nSW5zZXJ0aW9uRWZmZWN0ID0gaXNSdW5uaW5nO1xuICB9XG59XG5cbi8qIGVzbGludC1kaXNhYmxlIHJlYWN0LWludGVybmFsL3Byb2QtZXJyb3ItY29kZXMgKi9cbnZhciByZXNvbHZlRmFtaWx5ID0gbnVsbDsgLy8gJEZsb3dGaXhNZSBGbG93IGdldHMgY29uZnVzZWQgYnkgYSBXZWFrU2V0IGZlYXR1cmUgY2hlY2sgYmVsb3cuXG5cbnZhciBmYWlsZWRCb3VuZGFyaWVzID0gbnVsbDtcbnZhciBzZXRSZWZyZXNoSGFuZGxlciA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gIHtcbiAgICByZXNvbHZlRmFtaWx5ID0gaGFuZGxlcjtcbiAgfVxufTtcbmZ1bmN0aW9uIHJlc29sdmVGdW5jdGlvbkZvckhvdFJlbG9hZGluZyh0eXBlKSB7XG4gIHtcbiAgICBpZiAocmVzb2x2ZUZhbWlseSA9PT0gbnVsbCkge1xuICAgICAgLy8gSG90IHJlbG9hZGluZyBpcyBkaXNhYmxlZC5cbiAgICAgIHJldHVybiB0eXBlO1xuICAgIH1cblxuICAgIHZhciBmYW1pbHkgPSByZXNvbHZlRmFtaWx5KHR5cGUpO1xuXG4gICAgaWYgKGZhbWlseSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdHlwZTtcbiAgICB9IC8vIFVzZSB0aGUgbGF0ZXN0IGtub3duIGltcGxlbWVudGF0aW9uLlxuXG5cbiAgICByZXR1cm4gZmFtaWx5LmN1cnJlbnQ7XG4gIH1cbn1cbmZ1bmN0aW9uIHJlc29sdmVDbGFzc0ZvckhvdFJlbG9hZGluZyh0eXBlKSB7XG4gIC8vIE5vIGltcGxlbWVudGF0aW9uIGRpZmZlcmVuY2VzLlxuICByZXR1cm4gcmVzb2x2ZUZ1bmN0aW9uRm9ySG90UmVsb2FkaW5nKHR5cGUpO1xufVxuZnVuY3Rpb24gcmVzb2x2ZUZvcndhcmRSZWZGb3JIb3RSZWxvYWRpbmcodHlwZSkge1xuICB7XG4gICAgaWYgKHJlc29sdmVGYW1pbHkgPT09IG51bGwpIHtcbiAgICAgIC8vIEhvdCByZWxvYWRpbmcgaXMgZGlzYWJsZWQuXG4gICAgICByZXR1cm4gdHlwZTtcbiAgICB9XG5cbiAgICB2YXIgZmFtaWx5ID0gcmVzb2x2ZUZhbWlseSh0eXBlKTtcblxuICAgIGlmIChmYW1pbHkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gQ2hlY2sgaWYgd2UncmUgZGVhbGluZyB3aXRoIGEgcmVhbCBmb3J3YXJkUmVmLiBEb24ndCB3YW50IHRvIGNyYXNoIGVhcmx5LlxuICAgICAgaWYgKHR5cGUgIT09IG51bGwgJiYgdHlwZSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiB0eXBlLnJlbmRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBGb3J3YXJkUmVmIGlzIHNwZWNpYWwgYmVjYXVzZSBpdHMgcmVzb2x2ZWQgLnR5cGUgaXMgYW4gb2JqZWN0LFxuICAgICAgICAvLyBidXQgaXQncyBwb3NzaWJsZSB0aGF0IHdlIG9ubHkgaGF2ZSBpdHMgaW5uZXIgcmVuZGVyIGZ1bmN0aW9uIGluIHRoZSBtYXAuXG4gICAgICAgIC8vIElmIHRoYXQgaW5uZXIgcmVuZGVyIGZ1bmN0aW9uIGlzIGRpZmZlcmVudCwgd2UnbGwgYnVpbGQgYSBuZXcgZm9yd2FyZFJlZiB0eXBlLlxuICAgICAgICB2YXIgY3VycmVudFJlbmRlciA9IHJlc29sdmVGdW5jdGlvbkZvckhvdFJlbG9hZGluZyh0eXBlLnJlbmRlcik7XG5cbiAgICAgICAgaWYgKHR5cGUucmVuZGVyICE9PSBjdXJyZW50UmVuZGVyKSB7XG4gICAgICAgICAgdmFyIHN5bnRoZXRpY1R5cGUgPSB7XG4gICAgICAgICAgICAkJHR5cGVvZjogUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRSxcbiAgICAgICAgICAgIHJlbmRlcjogY3VycmVudFJlbmRlclxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBpZiAodHlwZS5kaXNwbGF5TmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzeW50aGV0aWNUeXBlLmRpc3BsYXlOYW1lID0gdHlwZS5kaXNwbGF5TmFtZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gc3ludGhldGljVHlwZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHlwZTtcbiAgICB9IC8vIFVzZSB0aGUgbGF0ZXN0IGtub3duIGltcGxlbWVudGF0aW9uLlxuXG5cbiAgICByZXR1cm4gZmFtaWx5LmN1cnJlbnQ7XG4gIH1cbn1cbmZ1bmN0aW9uIGlzQ29tcGF0aWJsZUZhbWlseUZvckhvdFJlbG9hZGluZyhmaWJlciwgZWxlbWVudCkge1xuICB7XG4gICAgaWYgKHJlc29sdmVGYW1pbHkgPT09IG51bGwpIHtcbiAgICAgIC8vIEhvdCByZWxvYWRpbmcgaXMgZGlzYWJsZWQuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIHByZXZUeXBlID0gZmliZXIuZWxlbWVudFR5cGU7XG4gICAgdmFyIG5leHRUeXBlID0gZWxlbWVudC50eXBlOyAvLyBJZiB3ZSBnb3QgaGVyZSwgd2Uga25vdyB0eXBlcyBhcmVuJ3QgPT09IGVxdWFsLlxuXG4gICAgdmFyIG5lZWRzQ29tcGFyZUZhbWlsaWVzID0gZmFsc2U7XG4gICAgdmFyICQkdHlwZW9mTmV4dFR5cGUgPSB0eXBlb2YgbmV4dFR5cGUgPT09ICdvYmplY3QnICYmIG5leHRUeXBlICE9PSBudWxsID8gbmV4dFR5cGUuJCR0eXBlb2YgOiBudWxsO1xuXG4gICAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG5leHRUeXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBuZWVkc0NvbXBhcmVGYW1pbGllcyA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIGlmICh0eXBlb2YgbmV4dFR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIG5lZWRzQ29tcGFyZUZhbWlsaWVzID0gdHJ1ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKCQkdHlwZW9mTmV4dFR5cGUgPT09IFJFQUNUX0xBWllfVFlQRSkge1xuICAgICAgICAgICAgLy8gV2UgZG9uJ3Qga25vdyB0aGUgaW5uZXIgdHlwZSB5ZXQuXG4gICAgICAgICAgICAvLyBXZSdyZSBnb2luZyB0byBhc3N1bWUgdGhhdCB0aGUgbGF6eSBpbm5lciB0eXBlIGlzIHN0YWJsZSxcbiAgICAgICAgICAgIC8vIGFuZCBzbyBpdCBpcyBzdWZmaWNpZW50IHRvIGF2b2lkIHJlY29uY2lsaW5nIGl0IGF3YXkuXG4gICAgICAgICAgICAvLyBXZSdyZSBub3QgZ29pbmcgdG8gdW53cmFwIG9yIGFjdHVhbGx5IHVzZSB0aGUgbmV3IGxhenkgdHlwZS5cbiAgICAgICAgICAgIG5lZWRzQ29tcGFyZUZhbWlsaWVzID0gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoJCR0eXBlb2ZOZXh0VHlwZSA9PT0gUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRSkge1xuICAgICAgICAgICAgbmVlZHNDb21wYXJlRmFtaWxpZXMgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoJCR0eXBlb2ZOZXh0VHlwZSA9PT0gUkVBQ1RfTEFaWV9UWVBFKSB7XG4gICAgICAgICAgICBuZWVkc0NvbXBhcmVGYW1pbGllcyA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBNZW1vQ29tcG9uZW50OlxuICAgICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgaWYgKCQkdHlwZW9mTmV4dFR5cGUgPT09IFJFQUNUX01FTU9fVFlQRSkge1xuICAgICAgICAgICAgLy8gVE9ETzogaWYgaXQgd2FzIGJ1dCBjYW4gbm8gbG9uZ2VyIGJlIHNpbXBsZSxcbiAgICAgICAgICAgIC8vIHdlIHNob3VsZG4ndCBzZXQgdGhpcy5cbiAgICAgICAgICAgIG5lZWRzQ29tcGFyZUZhbWlsaWVzID0gdHJ1ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKCQkdHlwZW9mTmV4dFR5cGUgPT09IFJFQUNUX0xBWllfVFlQRSkge1xuICAgICAgICAgICAgbmVlZHNDb21wYXJlRmFtaWxpZXMgPSB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IC8vIENoZWNrIGlmIGJvdGggdHlwZXMgaGF2ZSBhIGZhbWlseSBhbmQgaXQncyB0aGUgc2FtZSBvbmUuXG5cblxuICAgIGlmIChuZWVkc0NvbXBhcmVGYW1pbGllcykge1xuICAgICAgLy8gTm90ZTogbWVtbygpIGFuZCBmb3J3YXJkUmVmKCkgd2UnbGwgY29tcGFyZSBvdXRlciByYXRoZXIgdGhhbiBpbm5lciB0eXBlLlxuICAgICAgLy8gVGhpcyBtZWFucyBib3RoIG9mIHRoZW0gbmVlZCB0byBiZSByZWdpc3RlcmVkIHRvIHByZXNlcnZlIHN0YXRlLlxuICAgICAgLy8gSWYgd2UgdW53cmFwcGVkIGFuZCBjb21wYXJlZCB0aGUgaW5uZXIgdHlwZXMgZm9yIHdyYXBwZXJzIGluc3RlYWQsXG4gICAgICAvLyB0aGVuIHdlIHdvdWxkIHJpc2sgZmFsc2VseSBzYXlpbmcgdHdvIHNlcGFyYXRlIG1lbW8oRm9vKVxuICAgICAgLy8gY2FsbHMgYXJlIGVxdWl2YWxlbnQgYmVjYXVzZSB0aGV5IHdyYXAgdGhlIHNhbWUgRm9vIGZ1bmN0aW9uLlxuICAgICAgdmFyIHByZXZGYW1pbHkgPSByZXNvbHZlRmFtaWx5KHByZXZUeXBlKTtcblxuICAgICAgaWYgKHByZXZGYW1pbHkgIT09IHVuZGVmaW5lZCAmJiBwcmV2RmFtaWx5ID09PSByZXNvbHZlRmFtaWx5KG5leHRUeXBlKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtGYWlsZWRFcnJvckJvdW5kYXJ5Rm9ySG90UmVsb2FkaW5nKGZpYmVyKSB7XG4gIHtcbiAgICBpZiAocmVzb2x2ZUZhbWlseSA9PT0gbnVsbCkge1xuICAgICAgLy8gSG90IHJlbG9hZGluZyBpcyBkaXNhYmxlZC5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIFdlYWtTZXQgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZmFpbGVkQm91bmRhcmllcyA9PT0gbnVsbCkge1xuICAgICAgZmFpbGVkQm91bmRhcmllcyA9IG5ldyBXZWFrU2V0KCk7XG4gICAgfVxuXG4gICAgZmFpbGVkQm91bmRhcmllcy5hZGQoZmliZXIpO1xuICB9XG59XG52YXIgc2NoZWR1bGVSZWZyZXNoID0gZnVuY3Rpb24gKHJvb3QsIHVwZGF0ZSkge1xuICB7XG4gICAgaWYgKHJlc29sdmVGYW1pbHkgPT09IG51bGwpIHtcbiAgICAgIC8vIEhvdCByZWxvYWRpbmcgaXMgZGlzYWJsZWQuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHN0YWxlRmFtaWxpZXMgPSB1cGRhdGUuc3RhbGVGYW1pbGllcyxcbiAgICAgICAgdXBkYXRlZEZhbWlsaWVzID0gdXBkYXRlLnVwZGF0ZWRGYW1pbGllcztcbiAgICBmbHVzaFBhc3NpdmVFZmZlY3RzKCk7XG4gICAgZmx1c2hTeW5jKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNjaGVkdWxlRmliZXJzV2l0aEZhbWlsaWVzUmVjdXJzaXZlbHkocm9vdC5jdXJyZW50LCB1cGRhdGVkRmFtaWxpZXMsIHN0YWxlRmFtaWxpZXMpO1xuICAgIH0pO1xuICB9XG59O1xudmFyIHNjaGVkdWxlUm9vdCA9IGZ1bmN0aW9uIChyb290LCBlbGVtZW50KSB7XG4gIHtcbiAgICBpZiAocm9vdC5jb250ZXh0ICE9PSBlbXB0eUNvbnRleHRPYmplY3QpIHtcbiAgICAgIC8vIFN1cGVyIGVkZ2UgY2FzZTogcm9vdCBoYXMgYSBsZWdhY3kgX3JlbmRlclN1YnRyZWUgY29udGV4dFxuICAgICAgLy8gYnV0IHdlIGRvbid0IGtub3cgdGhlIHBhcmVudENvbXBvbmVudCBzbyB3ZSBjYW4ndCBwYXNzIGl0LlxuICAgICAgLy8gSnVzdCBpZ25vcmUuIFdlJ2xsIGRlbGV0ZSB0aGlzIHdpdGggX3JlbmRlclN1YnRyZWUgY29kZSBwYXRoIGxhdGVyLlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKTtcbiAgICBmbHVzaFN5bmMoZnVuY3Rpb24gKCkge1xuICAgICAgdXBkYXRlQ29udGFpbmVyKGVsZW1lbnQsIHJvb3QsIG51bGwsIG51bGwpO1xuICAgIH0pO1xuICB9XG59O1xuXG5mdW5jdGlvbiBzY2hlZHVsZUZpYmVyc1dpdGhGYW1pbGllc1JlY3Vyc2l2ZWx5KGZpYmVyLCB1cGRhdGVkRmFtaWxpZXMsIHN0YWxlRmFtaWxpZXMpIHtcbiAge1xuICAgIHZhciBhbHRlcm5hdGUgPSBmaWJlci5hbHRlcm5hdGUsXG4gICAgICAgIGNoaWxkID0gZmliZXIuY2hpbGQsXG4gICAgICAgIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nLFxuICAgICAgICB0YWcgPSBmaWJlci50YWcsXG4gICAgICAgIHR5cGUgPSBmaWJlci50eXBlO1xuICAgIHZhciBjYW5kaWRhdGVUeXBlID0gbnVsbDtcblxuICAgIHN3aXRjaCAodGFnKSB7XG4gICAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgICAgY2FuZGlkYXRlVHlwZSA9IHR5cGU7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgICAgIGNhbmRpZGF0ZVR5cGUgPSB0eXBlLnJlbmRlcjtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKHJlc29sdmVGYW1pbHkgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgcmVzb2x2ZUZhbWlseSB0byBiZSBzZXQgZHVyaW5nIGhvdCByZWxvYWQuJyk7XG4gICAgfVxuXG4gICAgdmFyIG5lZWRzUmVuZGVyID0gZmFsc2U7XG4gICAgdmFyIG5lZWRzUmVtb3VudCA9IGZhbHNlO1xuXG4gICAgaWYgKGNhbmRpZGF0ZVR5cGUgIT09IG51bGwpIHtcbiAgICAgIHZhciBmYW1pbHkgPSByZXNvbHZlRmFtaWx5KGNhbmRpZGF0ZVR5cGUpO1xuXG4gICAgICBpZiAoZmFtaWx5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHN0YWxlRmFtaWxpZXMuaGFzKGZhbWlseSkpIHtcbiAgICAgICAgICBuZWVkc1JlbW91bnQgPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHVwZGF0ZWRGYW1pbGllcy5oYXMoZmFtaWx5KSkge1xuICAgICAgICAgIGlmICh0YWcgPT09IENsYXNzQ29tcG9uZW50KSB7XG4gICAgICAgICAgICBuZWVkc1JlbW91bnQgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZWVkc1JlbmRlciA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGZhaWxlZEJvdW5kYXJpZXMgIT09IG51bGwpIHtcbiAgICAgIGlmIChmYWlsZWRCb3VuZGFyaWVzLmhhcyhmaWJlcikgfHwgYWx0ZXJuYXRlICE9PSBudWxsICYmIGZhaWxlZEJvdW5kYXJpZXMuaGFzKGFsdGVybmF0ZSkpIHtcbiAgICAgICAgbmVlZHNSZW1vdW50ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobmVlZHNSZW1vdW50KSB7XG4gICAgICBmaWJlci5fZGVidWdOZWVkc1JlbW91bnQgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChuZWVkc1JlbW91bnQgfHwgbmVlZHNSZW5kZXIpIHtcbiAgICAgIHZhciBfcm9vdCA9IGVucXVldWVDb25jdXJyZW50UmVuZGVyRm9yTGFuZShmaWJlciwgU3luY0xhbmUpO1xuXG4gICAgICBpZiAoX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgc2NoZWR1bGVVcGRhdGVPbkZpYmVyKF9yb290LCBmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY2hpbGQgIT09IG51bGwgJiYgIW5lZWRzUmVtb3VudCkge1xuICAgICAgc2NoZWR1bGVGaWJlcnNXaXRoRmFtaWxpZXNSZWN1cnNpdmVseShjaGlsZCwgdXBkYXRlZEZhbWlsaWVzLCBzdGFsZUZhbWlsaWVzKTtcbiAgICB9XG5cbiAgICBpZiAoc2libGluZyAhPT0gbnVsbCkge1xuICAgICAgc2NoZWR1bGVGaWJlcnNXaXRoRmFtaWxpZXNSZWN1cnNpdmVseShzaWJsaW5nLCB1cGRhdGVkRmFtaWxpZXMsIHN0YWxlRmFtaWxpZXMpO1xuICAgIH1cbiAgfVxufVxuXG52YXIgZmluZEhvc3RJbnN0YW5jZXNGb3JSZWZyZXNoID0gZnVuY3Rpb24gKHJvb3QsIGZhbWlsaWVzKSB7XG4gIHtcbiAgICB2YXIgaG9zdEluc3RhbmNlcyA9IG5ldyBTZXQoKTtcbiAgICB2YXIgdHlwZXMgPSBuZXcgU2V0KGZhbWlsaWVzLm1hcChmdW5jdGlvbiAoZmFtaWx5KSB7XG4gICAgICByZXR1cm4gZmFtaWx5LmN1cnJlbnQ7XG4gICAgfSkpO1xuICAgIGZpbmRIb3N0SW5zdGFuY2VzRm9yTWF0Y2hpbmdGaWJlcnNSZWN1cnNpdmVseShyb290LmN1cnJlbnQsIHR5cGVzLCBob3N0SW5zdGFuY2VzKTtcbiAgICByZXR1cm4gaG9zdEluc3RhbmNlcztcbiAgfVxufTtcblxuZnVuY3Rpb24gZmluZEhvc3RJbnN0YW5jZXNGb3JNYXRjaGluZ0ZpYmVyc1JlY3Vyc2l2ZWx5KGZpYmVyLCB0eXBlcywgaG9zdEluc3RhbmNlcykge1xuICB7XG4gICAgdmFyIGNoaWxkID0gZmliZXIuY2hpbGQsXG4gICAgICAgIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nLFxuICAgICAgICB0YWcgPSBmaWJlci50YWcsXG4gICAgICAgIHR5cGUgPSBmaWJlci50eXBlO1xuICAgIHZhciBjYW5kaWRhdGVUeXBlID0gbnVsbDtcblxuICAgIHN3aXRjaCAodGFnKSB7XG4gICAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgICAgY2FuZGlkYXRlVHlwZSA9IHR5cGU7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgICAgIGNhbmRpZGF0ZVR5cGUgPSB0eXBlLnJlbmRlcjtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgdmFyIGRpZE1hdGNoID0gZmFsc2U7XG5cbiAgICBpZiAoY2FuZGlkYXRlVHlwZSAhPT0gbnVsbCkge1xuICAgICAgaWYgKHR5cGVzLmhhcyhjYW5kaWRhdGVUeXBlKSkge1xuICAgICAgICBkaWRNYXRjaCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGRpZE1hdGNoKSB7XG4gICAgICAvLyBXZSBoYXZlIGEgbWF0Y2guIFRoaXMgb25seSBkcmlsbHMgZG93biB0byB0aGUgY2xvc2VzdCBob3N0IGNvbXBvbmVudHMuXG4gICAgICAvLyBUaGVyZSdzIG5vIG5lZWQgdG8gc2VhcmNoIGRlZXBlciBiZWNhdXNlIGZvciB0aGUgcHVycG9zZSBvZiBnaXZpbmdcbiAgICAgIC8vIHZpc3VhbCBmZWVkYmFjaywgXCJmbGFzaGluZ1wiIG91dGVybW9zdCBwYXJlbnQgcmVjdGFuZ2xlcyBpcyBzdWZmaWNpZW50LlxuICAgICAgZmluZEhvc3RJbnN0YW5jZXNGb3JGaWJlclNoYWxsb3dseShmaWJlciwgaG9zdEluc3RhbmNlcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gbWF0Y2gsIG1heWJlIHRoZXJlIHdpbGwgYmUgb25lIGZ1cnRoZXIgZG93biBpbiB0aGUgY2hpbGQgdHJlZS5cbiAgICAgIGlmIChjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICBmaW5kSG9zdEluc3RhbmNlc0Zvck1hdGNoaW5nRmliZXJzUmVjdXJzaXZlbHkoY2hpbGQsIHR5cGVzLCBob3N0SW5zdGFuY2VzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2libGluZyAhPT0gbnVsbCkge1xuICAgICAgZmluZEhvc3RJbnN0YW5jZXNGb3JNYXRjaGluZ0ZpYmVyc1JlY3Vyc2l2ZWx5KHNpYmxpbmcsIHR5cGVzLCBob3N0SW5zdGFuY2VzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZmluZEhvc3RJbnN0YW5jZXNGb3JGaWJlclNoYWxsb3dseShmaWJlciwgaG9zdEluc3RhbmNlcykge1xuICB7XG4gICAgdmFyIGZvdW5kSG9zdEluc3RhbmNlcyA9IGZpbmRDaGlsZEhvc3RJbnN0YW5jZXNGb3JGaWJlclNoYWxsb3dseShmaWJlciwgaG9zdEluc3RhbmNlcyk7XG5cbiAgICBpZiAoZm91bmRIb3N0SW5zdGFuY2VzKSB7XG4gICAgICByZXR1cm47XG4gICAgfSAvLyBJZiB3ZSBkaWRuJ3QgZmluZCBhbnkgaG9zdCBjaGlsZHJlbiwgZmFsbGJhY2sgdG8gY2xvc2VzdCBob3N0IHBhcmVudC5cblxuXG4gICAgdmFyIG5vZGUgPSBmaWJlcjtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBzd2l0Y2ggKG5vZGUudGFnKSB7XG4gICAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgICAgICBob3N0SW5zdGFuY2VzLmFkZChub2RlLnN0YXRlTm9kZSk7XG4gICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgICAgICBob3N0SW5zdGFuY2VzLmFkZChub2RlLnN0YXRlTm9kZS5jb250YWluZXJJbmZvKTtcbiAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAgICBob3N0SW5zdGFuY2VzLmFkZChub2RlLnN0YXRlTm9kZS5jb250YWluZXJJbmZvKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChub2RlLnJldHVybiA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHRvIHJlYWNoIHJvb3QgZmlyc3QuJyk7XG4gICAgICB9XG5cbiAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZmluZENoaWxkSG9zdEluc3RhbmNlc0ZvckZpYmVyU2hhbGxvd2x5KGZpYmVyLCBob3N0SW5zdGFuY2VzKSB7XG4gIHtcbiAgICB2YXIgbm9kZSA9IGZpYmVyO1xuICAgIHZhciBmb3VuZEhvc3RJbnN0YW5jZXMgPSBmYWxzZTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBpZiAobm9kZS50YWcgPT09IEhvc3RDb21wb25lbnQpIHtcbiAgICAgICAgLy8gV2UgZ290IGEgbWF0Y2guXG4gICAgICAgIGZvdW5kSG9zdEluc3RhbmNlcyA9IHRydWU7XG4gICAgICAgIGhvc3RJbnN0YW5jZXMuYWRkKG5vZGUuc3RhdGVOb2RlKTsgLy8gVGhlcmUgbWF5IHN0aWxsIGJlIG1vcmUsIHNvIGtlZXAgc2VhcmNoaW5nLlxuICAgICAgfSBlbHNlIGlmIChub2RlLmNoaWxkICE9PSBudWxsKSB7XG4gICAgICAgIG5vZGUuY2hpbGQucmV0dXJuID0gbm9kZTtcbiAgICAgICAgbm9kZSA9IG5vZGUuY2hpbGQ7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAobm9kZSA9PT0gZmliZXIpIHtcbiAgICAgICAgcmV0dXJuIGZvdW5kSG9zdEluc3RhbmNlcztcbiAgICAgIH1cblxuICAgICAgd2hpbGUgKG5vZGUuc2libGluZyA9PT0gbnVsbCkge1xuICAgICAgICBpZiAobm9kZS5yZXR1cm4gPT09IG51bGwgfHwgbm9kZS5yZXR1cm4gPT09IGZpYmVyKSB7XG4gICAgICAgICAgcmV0dXJuIGZvdW5kSG9zdEluc3RhbmNlcztcbiAgICAgICAgfVxuXG4gICAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICAgIH1cblxuICAgICAgbm9kZS5zaWJsaW5nLnJldHVybiA9IG5vZGUucmV0dXJuO1xuICAgICAgbm9kZSA9IG5vZGUuc2libGluZztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbnZhciBoYXNCYWRNYXBQb2x5ZmlsbDtcblxue1xuICBoYXNCYWRNYXBQb2x5ZmlsbCA9IGZhbHNlO1xuXG4gIHRyeSB7XG4gICAgdmFyIG5vbkV4dGVuc2libGVPYmplY3QgPSBPYmplY3QucHJldmVudEV4dGVuc2lvbnMoe30pO1xuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLW5ldyAqL1xuXG4gICAgbmV3IE1hcChbW25vbkV4dGVuc2libGVPYmplY3QsIG51bGxdXSk7XG4gICAgbmV3IFNldChbbm9uRXh0ZW5zaWJsZU9iamVjdF0pO1xuICAgIC8qIGVzbGludC1lbmFibGUgbm8tbmV3ICovXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBUT0RPOiBDb25zaWRlciB3YXJuaW5nIGFib3V0IGJhZCBwb2x5ZmlsbHNcbiAgICBoYXNCYWRNYXBQb2x5ZmlsbCA9IHRydWU7XG4gIH1cbn1cblxuZnVuY3Rpb24gRmliZXJOb2RlKHRhZywgcGVuZGluZ1Byb3BzLCBrZXksIG1vZGUpIHtcbiAgLy8gSW5zdGFuY2VcbiAgdGhpcy50YWcgPSB0YWc7XG4gIHRoaXMua2V5ID0ga2V5O1xuICB0aGlzLmVsZW1lbnRUeXBlID0gbnVsbDtcbiAgdGhpcy50eXBlID0gbnVsbDtcbiAgdGhpcy5zdGF0ZU5vZGUgPSBudWxsOyAvLyBGaWJlclxuXG4gIHRoaXMucmV0dXJuID0gbnVsbDtcbiAgdGhpcy5jaGlsZCA9IG51bGw7XG4gIHRoaXMuc2libGluZyA9IG51bGw7XG4gIHRoaXMuaW5kZXggPSAwO1xuICB0aGlzLnJlZiA9IG51bGw7XG4gIHRoaXMucGVuZGluZ1Byb3BzID0gcGVuZGluZ1Byb3BzO1xuICB0aGlzLm1lbW9pemVkUHJvcHMgPSBudWxsO1xuICB0aGlzLnVwZGF0ZVF1ZXVlID0gbnVsbDtcbiAgdGhpcy5tZW1vaXplZFN0YXRlID0gbnVsbDtcbiAgdGhpcy5kZXBlbmRlbmNpZXMgPSBudWxsO1xuICB0aGlzLm1vZGUgPSBtb2RlOyAvLyBFZmZlY3RzXG5cbiAgdGhpcy5mbGFncyA9IE5vRmxhZ3M7XG4gIHRoaXMuc3VidHJlZUZsYWdzID0gTm9GbGFncztcbiAgdGhpcy5kZWxldGlvbnMgPSBudWxsO1xuICB0aGlzLmxhbmVzID0gTm9MYW5lcztcbiAgdGhpcy5jaGlsZExhbmVzID0gTm9MYW5lcztcbiAgdGhpcy5hbHRlcm5hdGUgPSBudWxsO1xuXG4gIHtcbiAgICAvLyBOb3RlOiBUaGUgZm9sbG93aW5nIGlzIGRvbmUgdG8gYXZvaWQgYSB2OCBwZXJmb3JtYW5jZSBjbGlmZi5cbiAgICAvL1xuICAgIC8vIEluaXRpYWxpemluZyB0aGUgZmllbGRzIGJlbG93IHRvIHNtaXMgYW5kIGxhdGVyIHVwZGF0aW5nIHRoZW0gd2l0aFxuICAgIC8vIGRvdWJsZSB2YWx1ZXMgd2lsbCBjYXVzZSBGaWJlcnMgdG8gZW5kIHVwIGhhdmluZyBzZXBhcmF0ZSBzaGFwZXMuXG4gICAgLy8gVGhpcyBiZWhhdmlvci9idWcgaGFzIHNvbWV0aGluZyB0byBkbyB3aXRoIE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9uKCkuXG4gICAgLy8gRm9ydHVuYXRlbHkgdGhpcyBvbmx5IGltcGFjdHMgREVWIGJ1aWxkcy5cbiAgICAvLyBVbmZvcnR1bmF0ZWx5IGl0IG1ha2VzIFJlYWN0IHVudXNhYmx5IHNsb3cgZm9yIHNvbWUgYXBwbGljYXRpb25zLlxuICAgIC8vIFRvIHdvcmsgYXJvdW5kIHRoaXMsIGluaXRpYWxpemUgdGhlIGZpZWxkcyBiZWxvdyB3aXRoIGRvdWJsZXMuXG4gICAgLy9cbiAgICAvLyBMZWFybiBtb3JlIGFib3V0IHRoaXMgaGVyZTpcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzE0MzY1XG4gICAgLy8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9ODUzOFxuICAgIHRoaXMuYWN0dWFsRHVyYXRpb24gPSBOdW1iZXIuTmFOO1xuICAgIHRoaXMuYWN0dWFsU3RhcnRUaW1lID0gTnVtYmVyLk5hTjtcbiAgICB0aGlzLnNlbGZCYXNlRHVyYXRpb24gPSBOdW1iZXIuTmFOO1xuICAgIHRoaXMudHJlZUJhc2VEdXJhdGlvbiA9IE51bWJlci5OYU47IC8vIEl0J3Mgb2theSB0byByZXBsYWNlIHRoZSBpbml0aWFsIGRvdWJsZXMgd2l0aCBzbWlzIGFmdGVyIGluaXRpYWxpemF0aW9uLlxuICAgIC8vIFRoaXMgd29uJ3QgdHJpZ2dlciB0aGUgcGVyZm9ybWFuY2UgY2xpZmYgbWVudGlvbmVkIGFib3ZlLFxuICAgIC8vIGFuZCBpdCBzaW1wbGlmaWVzIG90aGVyIHByb2ZpbGVyIGNvZGUgKGluY2x1ZGluZyBEZXZUb29scykuXG5cbiAgICB0aGlzLmFjdHVhbER1cmF0aW9uID0gMDtcbiAgICB0aGlzLmFjdHVhbFN0YXJ0VGltZSA9IC0xO1xuICAgIHRoaXMuc2VsZkJhc2VEdXJhdGlvbiA9IDA7XG4gICAgdGhpcy50cmVlQmFzZUR1cmF0aW9uID0gMDtcbiAgfVxuXG4gIHtcbiAgICAvLyBUaGlzIGlzbid0IGRpcmVjdGx5IHVzZWQgYnV0IGlzIGhhbmR5IGZvciBkZWJ1Z2dpbmcgaW50ZXJuYWxzOlxuICAgIHRoaXMuX2RlYnVnU291cmNlID0gbnVsbDtcbiAgICB0aGlzLl9kZWJ1Z093bmVyID0gbnVsbDtcbiAgICB0aGlzLl9kZWJ1Z05lZWRzUmVtb3VudCA9IGZhbHNlO1xuICAgIHRoaXMuX2RlYnVnSG9va1R5cGVzID0gbnVsbDtcblxuICAgIGlmICghaGFzQmFkTWFwUG9seWZpbGwgJiYgdHlwZW9mIE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zKHRoaXMpO1xuICAgIH1cbiAgfVxufSAvLyBUaGlzIGlzIGEgY29uc3RydWN0b3IgZnVuY3Rpb24sIHJhdGhlciB0aGFuIGEgUE9KTyBjb25zdHJ1Y3Rvciwgc3RpbGxcbi8vIHBsZWFzZSBlbnN1cmUgd2UgZG8gdGhlIGZvbGxvd2luZzpcbi8vIDEpIE5vYm9keSBzaG91bGQgYWRkIGFueSBpbnN0YW5jZSBtZXRob2RzIG9uIHRoaXMuIEluc3RhbmNlIG1ldGhvZHMgY2FuIGJlXG4vLyAgICBtb3JlIGRpZmZpY3VsdCB0byBwcmVkaWN0IHdoZW4gdGhleSBnZXQgb3B0aW1pemVkIGFuZCB0aGV5IGFyZSBhbG1vc3Rcbi8vICAgIG5ldmVyIGlubGluZWQgcHJvcGVybHkgaW4gc3RhdGljIGNvbXBpbGVycy5cbi8vIDIpIE5vYm9keSBzaG91bGQgcmVseSBvbiBgaW5zdGFuY2VvZiBGaWJlcmAgZm9yIHR5cGUgdGVzdGluZy4gV2Ugc2hvdWxkXG4vLyAgICBhbHdheXMga25vdyB3aGVuIGl0IGlzIGEgZmliZXIuXG4vLyAzKSBXZSBtaWdodCB3YW50IHRvIGV4cGVyaW1lbnQgd2l0aCB1c2luZyBudW1lcmljIGtleXMgc2luY2UgdGhleSBhcmUgZWFzaWVyXG4vLyAgICB0byBvcHRpbWl6ZSBpbiBhIG5vbi1KSVQgZW52aXJvbm1lbnQuXG4vLyA0KSBXZSBjYW4gZWFzaWx5IGdvIGZyb20gYSBjb25zdHJ1Y3RvciB0byBhIGNyZWF0ZUZpYmVyIG9iamVjdCBsaXRlcmFsIGlmIHRoYXRcbi8vICAgIGlzIGZhc3Rlci5cbi8vIDUpIEl0IHNob3VsZCBiZSBlYXN5IHRvIHBvcnQgdGhpcyB0byBhIEMgc3RydWN0IGFuZCBrZWVwIGEgQyBpbXBsZW1lbnRhdGlvblxuLy8gICAgY29tcGF0aWJsZS5cblxuXG52YXIgY3JlYXRlRmliZXIgPSBmdW5jdGlvbiAodGFnLCBwZW5kaW5nUHJvcHMsIGtleSwgbW9kZSkge1xuICAvLyAkRmxvd0ZpeE1lOiB0aGUgc2hhcGVzIGFyZSBleGFjdCBoZXJlIGJ1dCBGbG93IGRvZXNuJ3QgbGlrZSBjb25zdHJ1Y3RvcnNcbiAgcmV0dXJuIG5ldyBGaWJlck5vZGUodGFnLCBwZW5kaW5nUHJvcHMsIGtleSwgbW9kZSk7XG59O1xuXG5mdW5jdGlvbiBzaG91bGRDb25zdHJ1Y3QkMShDb21wb25lbnQpIHtcbiAgdmFyIHByb3RvdHlwZSA9IENvbXBvbmVudC5wcm90b3R5cGU7XG4gIHJldHVybiAhIShwcm90b3R5cGUgJiYgcHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnQpO1xufVxuXG5mdW5jdGlvbiBpc1NpbXBsZUZ1bmN0aW9uQ29tcG9uZW50KHR5cGUpIHtcbiAgcmV0dXJuIHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nICYmICFzaG91bGRDb25zdHJ1Y3QkMSh0eXBlKSAmJiB0eXBlLmRlZmF1bHRQcm9wcyA9PT0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gcmVzb2x2ZUxhenlDb21wb25lbnRUYWcoQ29tcG9uZW50KSB7XG4gIGlmICh0eXBlb2YgQ29tcG9uZW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHNob3VsZENvbnN0cnVjdCQxKENvbXBvbmVudCkgPyBDbGFzc0NvbXBvbmVudCA6IEZ1bmN0aW9uQ29tcG9uZW50O1xuICB9IGVsc2UgaWYgKENvbXBvbmVudCAhPT0gdW5kZWZpbmVkICYmIENvbXBvbmVudCAhPT0gbnVsbCkge1xuICAgIHZhciAkJHR5cGVvZiA9IENvbXBvbmVudC4kJHR5cGVvZjtcblxuICAgIGlmICgkJHR5cGVvZiA9PT0gUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRSkge1xuICAgICAgcmV0dXJuIEZvcndhcmRSZWY7XG4gICAgfVxuXG4gICAgaWYgKCQkdHlwZW9mID09PSBSRUFDVF9NRU1PX1RZUEUpIHtcbiAgICAgIHJldHVybiBNZW1vQ29tcG9uZW50O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBJbmRldGVybWluYXRlQ29tcG9uZW50O1xufSAvLyBUaGlzIGlzIHVzZWQgdG8gY3JlYXRlIGFuIGFsdGVybmF0ZSBmaWJlciB0byBkbyB3b3JrIG9uLlxuXG5mdW5jdGlvbiBjcmVhdGVXb3JrSW5Qcm9ncmVzcyhjdXJyZW50LCBwZW5kaW5nUHJvcHMpIHtcbiAgdmFyIHdvcmtJblByb2dyZXNzID0gY3VycmVudC5hbHRlcm5hdGU7XG5cbiAgaWYgKHdvcmtJblByb2dyZXNzID09PSBudWxsKSB7XG4gICAgLy8gV2UgdXNlIGEgZG91YmxlIGJ1ZmZlcmluZyBwb29saW5nIHRlY2huaXF1ZSBiZWNhdXNlIHdlIGtub3cgdGhhdCB3ZSdsbFxuICAgIC8vIG9ubHkgZXZlciBuZWVkIGF0IG1vc3QgdHdvIHZlcnNpb25zIG9mIGEgdHJlZS4gV2UgcG9vbCB0aGUgXCJvdGhlclwiIHVudXNlZFxuICAgIC8vIG5vZGUgdGhhdCB3ZSdyZSBmcmVlIHRvIHJldXNlLiBUaGlzIGlzIGxhemlseSBjcmVhdGVkIHRvIGF2b2lkIGFsbG9jYXRpbmdcbiAgICAvLyBleHRyYSBvYmplY3RzIGZvciB0aGluZ3MgdGhhdCBhcmUgbmV2ZXIgdXBkYXRlZC4gSXQgYWxzbyBhbGxvdyB1cyB0b1xuICAgIC8vIHJlY2xhaW0gdGhlIGV4dHJhIG1lbW9yeSBpZiBuZWVkZWQuXG4gICAgd29ya0luUHJvZ3Jlc3MgPSBjcmVhdGVGaWJlcihjdXJyZW50LnRhZywgcGVuZGluZ1Byb3BzLCBjdXJyZW50LmtleSwgY3VycmVudC5tb2RlKTtcbiAgICB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZSA9IGN1cnJlbnQuZWxlbWVudFR5cGU7XG4gICAgd29ya0luUHJvZ3Jlc3MudHlwZSA9IGN1cnJlbnQudHlwZTtcbiAgICB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUgPSBjdXJyZW50LnN0YXRlTm9kZTtcblxuICAgIHtcbiAgICAgIC8vIERFVi1vbmx5IGZpZWxkc1xuICAgICAgd29ya0luUHJvZ3Jlc3MuX2RlYnVnU291cmNlID0gY3VycmVudC5fZGVidWdTb3VyY2U7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5fZGVidWdPd25lciA9IGN1cnJlbnQuX2RlYnVnT3duZXI7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5fZGVidWdIb29rVHlwZXMgPSBjdXJyZW50Ll9kZWJ1Z0hvb2tUeXBlcztcbiAgICB9XG5cbiAgICB3b3JrSW5Qcm9ncmVzcy5hbHRlcm5hdGUgPSBjdXJyZW50O1xuICAgIGN1cnJlbnQuYWx0ZXJuYXRlID0gd29ya0luUHJvZ3Jlc3M7XG4gIH0gZWxzZSB7XG4gICAgd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzID0gcGVuZGluZ1Byb3BzOyAvLyBOZWVkZWQgYmVjYXVzZSBCbG9ja3Mgc3RvcmUgZGF0YSBvbiB0eXBlLlxuXG4gICAgd29ya0luUHJvZ3Jlc3MudHlwZSA9IGN1cnJlbnQudHlwZTsgLy8gV2UgYWxyZWFkeSBoYXZlIGFuIGFsdGVybmF0ZS5cbiAgICAvLyBSZXNldCB0aGUgZWZmZWN0IHRhZy5cblxuICAgIHdvcmtJblByb2dyZXNzLmZsYWdzID0gTm9GbGFnczsgLy8gVGhlIGVmZmVjdHMgYXJlIG5vIGxvbmdlciB2YWxpZC5cblxuICAgIHdvcmtJblByb2dyZXNzLnN1YnRyZWVGbGFncyA9IE5vRmxhZ3M7XG4gICAgd29ya0luUHJvZ3Jlc3MuZGVsZXRpb25zID0gbnVsbDtcblxuICAgIHtcbiAgICAgIC8vIFdlIGludGVudGlvbmFsbHkgcmVzZXQsIHJhdGhlciB0aGFuIGNvcHksIGFjdHVhbER1cmF0aW9uICYgYWN0dWFsU3RhcnRUaW1lLlxuICAgICAgLy8gVGhpcyBwcmV2ZW50cyB0aW1lIGZyb20gZW5kbGVzc2x5IGFjY3VtdWxhdGluZyBpbiBuZXcgY29tbWl0cy5cbiAgICAgIC8vIFRoaXMgaGFzIHRoZSBkb3duc2lkZSBvZiByZXNldHRpbmcgdmFsdWVzIGZvciBkaWZmZXJlbnQgcHJpb3JpdHkgcmVuZGVycyxcbiAgICAgIC8vIEJ1dCB3b3JrcyBmb3IgeWllbGRpbmcgKHRoZSBjb21tb24gY2FzZSkgYW5kIHNob3VsZCBzdXBwb3J0IHJlc3VtaW5nLlxuICAgICAgd29ya0luUHJvZ3Jlc3MuYWN0dWFsRHVyYXRpb24gPSAwO1xuICAgICAgd29ya0luUHJvZ3Jlc3MuYWN0dWFsU3RhcnRUaW1lID0gLTE7XG4gICAgfVxuICB9IC8vIFJlc2V0IGFsbCBlZmZlY3RzIGV4Y2VwdCBzdGF0aWMgb25lcy5cbiAgLy8gU3RhdGljIGVmZmVjdHMgYXJlIG5vdCBzcGVjaWZpYyB0byBhIHJlbmRlci5cblxuXG4gIHdvcmtJblByb2dyZXNzLmZsYWdzID0gY3VycmVudC5mbGFncyAmIFN0YXRpY01hc2s7XG4gIHdvcmtJblByb2dyZXNzLmNoaWxkTGFuZXMgPSBjdXJyZW50LmNoaWxkTGFuZXM7XG4gIHdvcmtJblByb2dyZXNzLmxhbmVzID0gY3VycmVudC5sYW5lcztcbiAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSBjdXJyZW50LmNoaWxkO1xuICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFByb3BzID0gY3VycmVudC5tZW1vaXplZFByb3BzO1xuICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuICB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZSA9IGN1cnJlbnQudXBkYXRlUXVldWU7IC8vIENsb25lIHRoZSBkZXBlbmRlbmNpZXMgb2JqZWN0LiBUaGlzIGlzIG11dGF0ZWQgZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UsIHNvXG4gIC8vIGl0IGNhbm5vdCBiZSBzaGFyZWQgd2l0aCB0aGUgY3VycmVudCBmaWJlci5cblxuICB2YXIgY3VycmVudERlcGVuZGVuY2llcyA9IGN1cnJlbnQuZGVwZW5kZW5jaWVzO1xuICB3b3JrSW5Qcm9ncmVzcy5kZXBlbmRlbmNpZXMgPSBjdXJyZW50RGVwZW5kZW5jaWVzID09PSBudWxsID8gbnVsbCA6IHtcbiAgICBsYW5lczogY3VycmVudERlcGVuZGVuY2llcy5sYW5lcyxcbiAgICBmaXJzdENvbnRleHQ6IGN1cnJlbnREZXBlbmRlbmNpZXMuZmlyc3RDb250ZXh0XG4gIH07IC8vIFRoZXNlIHdpbGwgYmUgb3ZlcnJpZGRlbiBkdXJpbmcgdGhlIHBhcmVudCdzIHJlY29uY2lsaWF0aW9uXG5cbiAgd29ya0luUHJvZ3Jlc3Muc2libGluZyA9IGN1cnJlbnQuc2libGluZztcbiAgd29ya0luUHJvZ3Jlc3MuaW5kZXggPSBjdXJyZW50LmluZGV4O1xuICB3b3JrSW5Qcm9ncmVzcy5yZWYgPSBjdXJyZW50LnJlZjtcblxuICB7XG4gICAgd29ya0luUHJvZ3Jlc3Muc2VsZkJhc2VEdXJhdGlvbiA9IGN1cnJlbnQuc2VsZkJhc2VEdXJhdGlvbjtcbiAgICB3b3JrSW5Qcm9ncmVzcy50cmVlQmFzZUR1cmF0aW9uID0gY3VycmVudC50cmVlQmFzZUR1cmF0aW9uO1xuICB9XG5cbiAge1xuICAgIHdvcmtJblByb2dyZXNzLl9kZWJ1Z05lZWRzUmVtb3VudCA9IGN1cnJlbnQuX2RlYnVnTmVlZHNSZW1vdW50O1xuXG4gICAgc3dpdGNoICh3b3JrSW5Qcm9ncmVzcy50YWcpIHtcbiAgICAgIGNhc2UgSW5kZXRlcm1pbmF0ZUNvbXBvbmVudDpcbiAgICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICAgIHdvcmtJblByb2dyZXNzLnR5cGUgPSByZXNvbHZlRnVuY3Rpb25Gb3JIb3RSZWxvYWRpbmcoY3VycmVudC50eXBlKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICAgIHdvcmtJblByb2dyZXNzLnR5cGUgPSByZXNvbHZlQ2xhc3NGb3JIb3RSZWxvYWRpbmcoY3VycmVudC50eXBlKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgICAgd29ya0luUHJvZ3Jlc3MudHlwZSA9IHJlc29sdmVGb3J3YXJkUmVmRm9ySG90UmVsb2FkaW5nKGN1cnJlbnQudHlwZSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbn0gLy8gVXNlZCB0byByZXVzZSBhIEZpYmVyIGZvciBhIHNlY29uZCBwYXNzLlxuXG5mdW5jdGlvbiByZXNldFdvcmtJblByb2dyZXNzKHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcykge1xuICAvLyBUaGlzIHJlc2V0cyB0aGUgRmliZXIgdG8gd2hhdCBjcmVhdGVGaWJlciBvciBjcmVhdGVXb3JrSW5Qcm9ncmVzcyB3b3VsZFxuICAvLyBoYXZlIHNldCB0aGUgdmFsdWVzIHRvIGJlZm9yZSBkdXJpbmcgdGhlIGZpcnN0IHBhc3MuIElkZWFsbHkgdGhpcyB3b3VsZG4ndFxuICAvLyBiZSBuZWNlc3NhcnkgYnV0IHVuZm9ydHVuYXRlbHkgbWFueSBjb2RlIHBhdGhzIHJlYWRzIGZyb20gdGhlIHdvcmtJblByb2dyZXNzXG4gIC8vIHdoZW4gdGhleSBzaG91bGQgYmUgcmVhZGluZyBmcm9tIGN1cnJlbnQgYW5kIHdyaXRpbmcgdG8gd29ya0luUHJvZ3Jlc3MuXG4gIC8vIFdlIGFzc3VtZSBwZW5kaW5nUHJvcHMsIGluZGV4LCBrZXksIHJlZiwgcmV0dXJuIGFyZSBzdGlsbCB1bnRvdWNoZWQgdG9cbiAgLy8gYXZvaWQgZG9pbmcgYW5vdGhlciByZWNvbmNpbGlhdGlvbi5cbiAgLy8gUmVzZXQgdGhlIGVmZmVjdCBmbGFncyBidXQga2VlcCBhbnkgUGxhY2VtZW50IHRhZ3MsIHNpbmNlIHRoYXQncyBzb21ldGhpbmdcbiAgLy8gdGhhdCBjaGlsZCBmaWJlciBpcyBzZXR0aW5nLCBub3QgdGhlIHJlY29uY2lsaWF0aW9uLlxuICB3b3JrSW5Qcm9ncmVzcy5mbGFncyAmPSBTdGF0aWNNYXNrIHwgUGxhY2VtZW50OyAvLyBUaGUgZWZmZWN0cyBhcmUgbm8gbG9uZ2VyIHZhbGlkLlxuXG4gIHZhciBjdXJyZW50ID0gd29ya0luUHJvZ3Jlc3MuYWx0ZXJuYXRlO1xuXG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgLy8gUmVzZXQgdG8gY3JlYXRlRmliZXIncyBpbml0aWFsIHZhbHVlcy5cbiAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZExhbmVzID0gTm9MYW5lcztcbiAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IHJlbmRlckxhbmVzO1xuICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gbnVsbDtcbiAgICB3b3JrSW5Qcm9ncmVzcy5zdWJ0cmVlRmxhZ3MgPSBOb0ZsYWdzO1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkUHJvcHMgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gbnVsbDtcbiAgICB3b3JrSW5Qcm9ncmVzcy5kZXBlbmRlbmNpZXMgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZSA9IG51bGw7XG5cbiAgICB7XG4gICAgICAvLyBOb3RlOiBXZSBkb24ndCByZXNldCB0aGUgYWN0dWFsVGltZSBjb3VudHMuIEl0J3MgdXNlZnVsIHRvIGFjY3VtdWxhdGVcbiAgICAgIC8vIGFjdHVhbCB0aW1lIGFjcm9zcyBtdWx0aXBsZSByZW5kZXIgcGFzc2VzLlxuICAgICAgd29ya0luUHJvZ3Jlc3Muc2VsZkJhc2VEdXJhdGlvbiA9IDA7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy50cmVlQmFzZUR1cmF0aW9uID0gMDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gUmVzZXQgdG8gdGhlIGNsb25lZCB2YWx1ZXMgdGhhdCBjcmVhdGVXb3JrSW5Qcm9ncmVzcyB3b3VsZCd2ZS5cbiAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZExhbmVzID0gY3VycmVudC5jaGlsZExhbmVzO1xuICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gY3VycmVudC5sYW5lcztcbiAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IGN1cnJlbnQuY2hpbGQ7XG4gICAgd29ya0luUHJvZ3Jlc3Muc3VidHJlZUZsYWdzID0gTm9GbGFncztcbiAgICB3b3JrSW5Qcm9ncmVzcy5kZWxldGlvbnMgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkUHJvcHMgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7XG4gICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcbiAgICB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZSA9IGN1cnJlbnQudXBkYXRlUXVldWU7IC8vIE5lZWRlZCBiZWNhdXNlIEJsb2NrcyBzdG9yZSBkYXRhIG9uIHR5cGUuXG5cbiAgICB3b3JrSW5Qcm9ncmVzcy50eXBlID0gY3VycmVudC50eXBlOyAvLyBDbG9uZSB0aGUgZGVwZW5kZW5jaWVzIG9iamVjdC4gVGhpcyBpcyBtdXRhdGVkIGR1cmluZyB0aGUgcmVuZGVyIHBoYXNlLCBzb1xuICAgIC8vIGl0IGNhbm5vdCBiZSBzaGFyZWQgd2l0aCB0aGUgY3VycmVudCBmaWJlci5cblxuICAgIHZhciBjdXJyZW50RGVwZW5kZW5jaWVzID0gY3VycmVudC5kZXBlbmRlbmNpZXM7XG4gICAgd29ya0luUHJvZ3Jlc3MuZGVwZW5kZW5jaWVzID0gY3VycmVudERlcGVuZGVuY2llcyA9PT0gbnVsbCA/IG51bGwgOiB7XG4gICAgICBsYW5lczogY3VycmVudERlcGVuZGVuY2llcy5sYW5lcyxcbiAgICAgIGZpcnN0Q29udGV4dDogY3VycmVudERlcGVuZGVuY2llcy5maXJzdENvbnRleHRcbiAgICB9O1xuXG4gICAge1xuICAgICAgLy8gTm90ZTogV2UgZG9uJ3QgcmVzZXQgdGhlIGFjdHVhbFRpbWUgY291bnRzLiBJdCdzIHVzZWZ1bCB0byBhY2N1bXVsYXRlXG4gICAgICAvLyBhY3R1YWwgdGltZSBhY3Jvc3MgbXVsdGlwbGUgcmVuZGVyIHBhc3Nlcy5cbiAgICAgIHdvcmtJblByb2dyZXNzLnNlbGZCYXNlRHVyYXRpb24gPSBjdXJyZW50LnNlbGZCYXNlRHVyYXRpb247XG4gICAgICB3b3JrSW5Qcm9ncmVzcy50cmVlQmFzZUR1cmF0aW9uID0gY3VycmVudC50cmVlQmFzZUR1cmF0aW9uO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbn1cbmZ1bmN0aW9uIGNyZWF0ZUhvc3RSb290RmliZXIodGFnLCBpc1N0cmljdE1vZGUsIGNvbmN1cnJlbnRVcGRhdGVzQnlEZWZhdWx0T3ZlcnJpZGUpIHtcbiAgdmFyIG1vZGU7XG5cbiAgaWYgKHRhZyA9PT0gQ29uY3VycmVudFJvb3QpIHtcbiAgICBtb2RlID0gQ29uY3VycmVudE1vZGU7XG5cbiAgICBpZiAoaXNTdHJpY3RNb2RlID09PSB0cnVlKSB7XG4gICAgICBtb2RlIHw9IFN0cmljdExlZ2FjeU1vZGU7XG5cbiAgICAgIHtcbiAgICAgICAgbW9kZSB8PSBTdHJpY3RFZmZlY3RzTW9kZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgbW9kZSA9IE5vTW9kZTtcbiAgfVxuXG4gIGlmICggaXNEZXZUb29sc1ByZXNlbnQpIHtcbiAgICAvLyBBbHdheXMgY29sbGVjdCBwcm9maWxlIHRpbWluZ3Mgd2hlbiBEZXZUb29scyBhcmUgcHJlc2VudC5cbiAgICAvLyBUaGlzIGVuYWJsZXMgRGV2VG9vbHMgdG8gc3RhcnQgY2FwdHVyaW5nIHRpbWluZyBhdCBhbnkgcG9pbnTigJNcbiAgICAvLyBXaXRob3V0IHNvbWUgbm9kZXMgaW4gdGhlIHRyZWUgaGF2aW5nIGVtcHR5IGJhc2UgdGltZXMuXG4gICAgbW9kZSB8PSBQcm9maWxlTW9kZTtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVGaWJlcihIb3N0Um9vdCwgbnVsbCwgbnVsbCwgbW9kZSk7XG59XG5mdW5jdGlvbiBjcmVhdGVGaWJlckZyb21UeXBlQW5kUHJvcHModHlwZSwgLy8gUmVhY3QkRWxlbWVudFR5cGVcbmtleSwgcGVuZGluZ1Byb3BzLCBvd25lciwgbW9kZSwgbGFuZXMpIHtcbiAgdmFyIGZpYmVyVGFnID0gSW5kZXRlcm1pbmF0ZUNvbXBvbmVudDsgLy8gVGhlIHJlc29sdmVkIHR5cGUgaXMgc2V0IGlmIHdlIGtub3cgd2hhdCB0aGUgZmluYWwgdHlwZSB3aWxsIGJlLiBJLmUuIGl0J3Mgbm90IGxhenkuXG5cbiAgdmFyIHJlc29sdmVkVHlwZSA9IHR5cGU7XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgaWYgKHNob3VsZENvbnN0cnVjdCQxKHR5cGUpKSB7XG4gICAgICBmaWJlclRhZyA9IENsYXNzQ29tcG9uZW50O1xuXG4gICAgICB7XG4gICAgICAgIHJlc29sdmVkVHlwZSA9IHJlc29sdmVDbGFzc0ZvckhvdFJlbG9hZGluZyhyZXNvbHZlZFR5cGUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB7XG4gICAgICAgIHJlc29sdmVkVHlwZSA9IHJlc29sdmVGdW5jdGlvbkZvckhvdFJlbG9hZGluZyhyZXNvbHZlZFR5cGUpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBmaWJlclRhZyA9IEhvc3RDb21wb25lbnQ7XG4gIH0gZWxzZSB7XG4gICAgZ2V0VGFnOiBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgUkVBQ1RfRlJBR01FTlRfVFlQRTpcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZpYmVyRnJvbUZyYWdtZW50KHBlbmRpbmdQcm9wcy5jaGlsZHJlbiwgbW9kZSwgbGFuZXMsIGtleSk7XG5cbiAgICAgIGNhc2UgUkVBQ1RfU1RSSUNUX01PREVfVFlQRTpcbiAgICAgICAgZmliZXJUYWcgPSBNb2RlO1xuICAgICAgICBtb2RlIHw9IFN0cmljdExlZ2FjeU1vZGU7XG5cbiAgICAgICAgaWYgKCAobW9kZSAmIENvbmN1cnJlbnRNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICAgICAgLy8gU3RyaWN0IGVmZmVjdHMgc2hvdWxkIG5ldmVyIHJ1biBvbiBsZWdhY3kgcm9vdHNcbiAgICAgICAgICBtb2RlIHw9IFN0cmljdEVmZmVjdHNNb2RlO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgUkVBQ1RfUFJPRklMRVJfVFlQRTpcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZpYmVyRnJvbVByb2ZpbGVyKHBlbmRpbmdQcm9wcywgbW9kZSwgbGFuZXMsIGtleSk7XG5cbiAgICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfVFlQRTpcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZpYmVyRnJvbVN1c3BlbnNlKHBlbmRpbmdQcm9wcywgbW9kZSwgbGFuZXMsIGtleSk7XG5cbiAgICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfTElTVF9UWVBFOlxuICAgICAgICByZXR1cm4gY3JlYXRlRmliZXJGcm9tU3VzcGVuc2VMaXN0KHBlbmRpbmdQcm9wcywgbW9kZSwgbGFuZXMsIGtleSk7XG5cbiAgICAgIGNhc2UgUkVBQ1RfT0ZGU0NSRUVOX1RZUEU6XG4gICAgICAgIHJldHVybiBjcmVhdGVGaWJlckZyb21PZmZzY3JlZW4ocGVuZGluZ1Byb3BzLCBtb2RlLCBsYW5lcywga2V5KTtcblxuICAgICAgY2FzZSBSRUFDVF9MRUdBQ1lfSElEREVOX1RZUEU6XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuXG4gICAgICBjYXNlIFJFQUNUX1NDT1BFX1RZUEU6XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuXG4gICAgICBjYXNlIFJFQUNUX0NBQ0hFX1RZUEU6XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuXG4gICAgICBjYXNlIFJFQUNUX1RSQUNJTkdfTUFSS0VSX1RZUEU6XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuXG4gICAgICBjYXNlIFJFQUNUX0RFQlVHX1RSQUNJTkdfTU9ERV9UWVBFOlxuXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZmFsbHRocm91Z2hcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAge1xuICAgICAgICAgIGlmICh0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcgJiYgdHlwZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgc3dpdGNoICh0eXBlLiQkdHlwZW9mKSB7XG4gICAgICAgICAgICAgIGNhc2UgUkVBQ1RfUFJPVklERVJfVFlQRTpcbiAgICAgICAgICAgICAgICBmaWJlclRhZyA9IENvbnRleHRQcm92aWRlcjtcbiAgICAgICAgICAgICAgICBicmVhayBnZXRUYWc7XG5cbiAgICAgICAgICAgICAgY2FzZSBSRUFDVF9DT05URVhUX1RZUEU6XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBhIGNvbnN1bWVyXG4gICAgICAgICAgICAgICAgZmliZXJUYWcgPSBDb250ZXh0Q29uc3VtZXI7XG4gICAgICAgICAgICAgICAgYnJlYWsgZ2V0VGFnO1xuXG4gICAgICAgICAgICAgIGNhc2UgUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRTpcbiAgICAgICAgICAgICAgICBmaWJlclRhZyA9IEZvcndhcmRSZWY7XG5cbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlZFR5cGUgPSByZXNvbHZlRm9yd2FyZFJlZkZvckhvdFJlbG9hZGluZyhyZXNvbHZlZFR5cGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrIGdldFRhZztcblxuICAgICAgICAgICAgICBjYXNlIFJFQUNUX01FTU9fVFlQRTpcbiAgICAgICAgICAgICAgICBmaWJlclRhZyA9IE1lbW9Db21wb25lbnQ7XG4gICAgICAgICAgICAgICAgYnJlYWsgZ2V0VGFnO1xuXG4gICAgICAgICAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICAgICAgICAgIGZpYmVyVGFnID0gTGF6eUNvbXBvbmVudDtcbiAgICAgICAgICAgICAgICByZXNvbHZlZFR5cGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIGJyZWFrIGdldFRhZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgaW5mbyA9ICcnO1xuXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcgJiYgdHlwZSAhPT0gbnVsbCAmJiBPYmplY3Qua2V5cyh0eXBlKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgaW5mbyArPSAnIFlvdSBsaWtlbHkgZm9yZ290IHRvIGV4cG9ydCB5b3VyIGNvbXBvbmVudCBmcm9tIHRoZSBmaWxlICcgKyBcIml0J3MgZGVmaW5lZCBpbiwgb3IgeW91IG1pZ2h0IGhhdmUgbWl4ZWQgdXAgZGVmYXVsdCBhbmQgXCIgKyAnbmFtZWQgaW1wb3J0cy4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgb3duZXJOYW1lID0gb3duZXIgPyBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKG93bmVyKSA6IG51bGw7XG5cbiAgICAgICAgICAgIGlmIChvd25lck5hbWUpIHtcbiAgICAgICAgICAgICAgaW5mbyArPSAnXFxuXFxuQ2hlY2sgdGhlIHJlbmRlciBtZXRob2Qgb2YgYCcgKyBvd25lck5hbWUgKyAnYC4nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRWxlbWVudCB0eXBlIGlzIGludmFsaWQ6IGV4cGVjdGVkIGEgc3RyaW5nIChmb3IgYnVpbHQtaW4gJyArICdjb21wb25lbnRzKSBvciBhIGNsYXNzL2Z1bmN0aW9uIChmb3IgY29tcG9zaXRlIGNvbXBvbmVudHMpICcgKyAoXCJidXQgZ290OiBcIiArICh0eXBlID09IG51bGwgPyB0eXBlIDogdHlwZW9mIHR5cGUpICsgXCIuXCIgKyBpbmZvKSk7XG4gICAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgZmliZXIgPSBjcmVhdGVGaWJlcihmaWJlclRhZywgcGVuZGluZ1Byb3BzLCBrZXksIG1vZGUpO1xuICBmaWJlci5lbGVtZW50VHlwZSA9IHR5cGU7XG4gIGZpYmVyLnR5cGUgPSByZXNvbHZlZFR5cGU7XG4gIGZpYmVyLmxhbmVzID0gbGFuZXM7XG5cbiAge1xuICAgIGZpYmVyLl9kZWJ1Z093bmVyID0gb3duZXI7XG4gIH1cblxuICByZXR1cm4gZmliZXI7XG59XG5mdW5jdGlvbiBjcmVhdGVGaWJlckZyb21FbGVtZW50KGVsZW1lbnQsIG1vZGUsIGxhbmVzKSB7XG4gIHZhciBvd25lciA9IG51bGw7XG5cbiAge1xuICAgIG93bmVyID0gZWxlbWVudC5fb3duZXI7XG4gIH1cblxuICB2YXIgdHlwZSA9IGVsZW1lbnQudHlwZTtcbiAgdmFyIGtleSA9IGVsZW1lbnQua2V5O1xuICB2YXIgcGVuZGluZ1Byb3BzID0gZWxlbWVudC5wcm9wcztcbiAgdmFyIGZpYmVyID0gY3JlYXRlRmliZXJGcm9tVHlwZUFuZFByb3BzKHR5cGUsIGtleSwgcGVuZGluZ1Byb3BzLCBvd25lciwgbW9kZSwgbGFuZXMpO1xuXG4gIHtcbiAgICBmaWJlci5fZGVidWdTb3VyY2UgPSBlbGVtZW50Ll9zb3VyY2U7XG4gICAgZmliZXIuX2RlYnVnT3duZXIgPSBlbGVtZW50Ll9vd25lcjtcbiAgfVxuXG4gIHJldHVybiBmaWJlcjtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyRnJvbUZyYWdtZW50KGVsZW1lbnRzLCBtb2RlLCBsYW5lcywga2V5KSB7XG4gIHZhciBmaWJlciA9IGNyZWF0ZUZpYmVyKEZyYWdtZW50LCBlbGVtZW50cywga2V5LCBtb2RlKTtcbiAgZmliZXIubGFuZXMgPSBsYW5lcztcbiAgcmV0dXJuIGZpYmVyO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVGaWJlckZyb21Qcm9maWxlcihwZW5kaW5nUHJvcHMsIG1vZGUsIGxhbmVzLCBrZXkpIHtcbiAge1xuICAgIGlmICh0eXBlb2YgcGVuZGluZ1Byb3BzLmlkICE9PSAnc3RyaW5nJykge1xuICAgICAgZXJyb3IoJ1Byb2ZpbGVyIG11c3Qgc3BlY2lmeSBhbiBcImlkXCIgb2YgdHlwZSBgc3RyaW5nYCBhcyBhIHByb3AuIFJlY2VpdmVkIHRoZSB0eXBlIGAlc2AgaW5zdGVhZC4nLCB0eXBlb2YgcGVuZGluZ1Byb3BzLmlkKTtcbiAgICB9XG4gIH1cblxuICB2YXIgZmliZXIgPSBjcmVhdGVGaWJlcihQcm9maWxlciwgcGVuZGluZ1Byb3BzLCBrZXksIG1vZGUgfCBQcm9maWxlTW9kZSk7XG4gIGZpYmVyLmVsZW1lbnRUeXBlID0gUkVBQ1RfUFJPRklMRVJfVFlQRTtcbiAgZmliZXIubGFuZXMgPSBsYW5lcztcblxuICB7XG4gICAgZmliZXIuc3RhdGVOb2RlID0ge1xuICAgICAgZWZmZWN0RHVyYXRpb246IDAsXG4gICAgICBwYXNzaXZlRWZmZWN0RHVyYXRpb246IDBcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIGZpYmVyO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVGaWJlckZyb21TdXNwZW5zZShwZW5kaW5nUHJvcHMsIG1vZGUsIGxhbmVzLCBrZXkpIHtcbiAgdmFyIGZpYmVyID0gY3JlYXRlRmliZXIoU3VzcGVuc2VDb21wb25lbnQsIHBlbmRpbmdQcm9wcywga2V5LCBtb2RlKTtcbiAgZmliZXIuZWxlbWVudFR5cGUgPSBSRUFDVF9TVVNQRU5TRV9UWVBFO1xuICBmaWJlci5sYW5lcyA9IGxhbmVzO1xuICByZXR1cm4gZmliZXI7XG59XG5mdW5jdGlvbiBjcmVhdGVGaWJlckZyb21TdXNwZW5zZUxpc3QocGVuZGluZ1Byb3BzLCBtb2RlLCBsYW5lcywga2V5KSB7XG4gIHZhciBmaWJlciA9IGNyZWF0ZUZpYmVyKFN1c3BlbnNlTGlzdENvbXBvbmVudCwgcGVuZGluZ1Byb3BzLCBrZXksIG1vZGUpO1xuICBmaWJlci5lbGVtZW50VHlwZSA9IFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRTtcbiAgZmliZXIubGFuZXMgPSBsYW5lcztcbiAgcmV0dXJuIGZpYmVyO1xufVxuZnVuY3Rpb24gY3JlYXRlRmliZXJGcm9tT2Zmc2NyZWVuKHBlbmRpbmdQcm9wcywgbW9kZSwgbGFuZXMsIGtleSkge1xuICB2YXIgZmliZXIgPSBjcmVhdGVGaWJlcihPZmZzY3JlZW5Db21wb25lbnQsIHBlbmRpbmdQcm9wcywga2V5LCBtb2RlKTtcbiAgZmliZXIuZWxlbWVudFR5cGUgPSBSRUFDVF9PRkZTQ1JFRU5fVFlQRTtcbiAgZmliZXIubGFuZXMgPSBsYW5lcztcbiAgdmFyIHByaW1hcnlDaGlsZEluc3RhbmNlID0ge1xuICAgIGlzSGlkZGVuOiBmYWxzZVxuICB9O1xuICBmaWJlci5zdGF0ZU5vZGUgPSBwcmltYXJ5Q2hpbGRJbnN0YW5jZTtcbiAgcmV0dXJuIGZpYmVyO1xufVxuZnVuY3Rpb24gY3JlYXRlRmliZXJGcm9tVGV4dChjb250ZW50LCBtb2RlLCBsYW5lcykge1xuICB2YXIgZmliZXIgPSBjcmVhdGVGaWJlcihIb3N0VGV4dCwgY29udGVudCwgbnVsbCwgbW9kZSk7XG4gIGZpYmVyLmxhbmVzID0gbGFuZXM7XG4gIHJldHVybiBmaWJlcjtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyRnJvbUhvc3RJbnN0YW5jZUZvckRlbGV0aW9uKCkge1xuICB2YXIgZmliZXIgPSBjcmVhdGVGaWJlcihIb3N0Q29tcG9uZW50LCBudWxsLCBudWxsLCBOb01vZGUpO1xuICBmaWJlci5lbGVtZW50VHlwZSA9ICdERUxFVEVEJztcbiAgcmV0dXJuIGZpYmVyO1xufVxuZnVuY3Rpb24gY3JlYXRlRmliZXJGcm9tRGVoeWRyYXRlZEZyYWdtZW50KGRlaHlkcmF0ZWROb2RlKSB7XG4gIHZhciBmaWJlciA9IGNyZWF0ZUZpYmVyKERlaHlkcmF0ZWRGcmFnbWVudCwgbnVsbCwgbnVsbCwgTm9Nb2RlKTtcbiAgZmliZXIuc3RhdGVOb2RlID0gZGVoeWRyYXRlZE5vZGU7XG4gIHJldHVybiBmaWJlcjtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyRnJvbVBvcnRhbChwb3J0YWwsIG1vZGUsIGxhbmVzKSB7XG4gIHZhciBwZW5kaW5nUHJvcHMgPSBwb3J0YWwuY2hpbGRyZW4gIT09IG51bGwgPyBwb3J0YWwuY2hpbGRyZW4gOiBbXTtcbiAgdmFyIGZpYmVyID0gY3JlYXRlRmliZXIoSG9zdFBvcnRhbCwgcGVuZGluZ1Byb3BzLCBwb3J0YWwua2V5LCBtb2RlKTtcbiAgZmliZXIubGFuZXMgPSBsYW5lcztcbiAgZmliZXIuc3RhdGVOb2RlID0ge1xuICAgIGNvbnRhaW5lckluZm86IHBvcnRhbC5jb250YWluZXJJbmZvLFxuICAgIHBlbmRpbmdDaGlsZHJlbjogbnVsbCxcbiAgICAvLyBVc2VkIGJ5IHBlcnNpc3RlbnQgdXBkYXRlc1xuICAgIGltcGxlbWVudGF0aW9uOiBwb3J0YWwuaW1wbGVtZW50YXRpb25cbiAgfTtcbiAgcmV0dXJuIGZpYmVyO1xufSAvLyBVc2VkIGZvciBzdGFzaGluZyBXSVAgcHJvcGVydGllcyB0byByZXBsYXkgZmFpbGVkIHdvcmsgaW4gREVWLlxuXG5mdW5jdGlvbiBhc3NpZ25GaWJlclByb3BlcnRpZXNJbkRFVih0YXJnZXQsIHNvdXJjZSkge1xuICBpZiAodGFyZ2V0ID09PSBudWxsKSB7XG4gICAgLy8gVGhpcyBGaWJlcidzIGluaXRpYWwgcHJvcGVydGllcyB3aWxsIGFsd2F5cyBiZSBvdmVyd3JpdHRlbi5cbiAgICAvLyBXZSBvbmx5IHVzZSBhIEZpYmVyIHRvIGVuc3VyZSB0aGUgc2FtZSBoaWRkZW4gY2xhc3Mgc28gREVWIGlzbid0IHNsb3cuXG4gICAgdGFyZ2V0ID0gY3JlYXRlRmliZXIoSW5kZXRlcm1pbmF0ZUNvbXBvbmVudCwgbnVsbCwgbnVsbCwgTm9Nb2RlKTtcbiAgfSAvLyBUaGlzIGlzIGludGVudGlvbmFsbHkgd3JpdHRlbiBhcyBhIGxpc3Qgb2YgYWxsIHByb3BlcnRpZXMuXG4gIC8vIFdlIHRyaWVkIHRvIHVzZSBPYmplY3QuYXNzaWduKCkgaW5zdGVhZCBidXQgdGhpcyBpcyBjYWxsZWQgaW5cbiAgLy8gdGhlIGhvdHRlc3QgcGF0aCwgYW5kIE9iamVjdC5hc3NpZ24oKSB3YXMgdG9vIHNsb3c6XG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTI1MDJcbiAgLy8gVGhpcyBjb2RlIGlzIERFVi1vbmx5IHNvIHNpemUgaXMgbm90IGEgY29uY2Vybi5cblxuXG4gIHRhcmdldC50YWcgPSBzb3VyY2UudGFnO1xuICB0YXJnZXQua2V5ID0gc291cmNlLmtleTtcbiAgdGFyZ2V0LmVsZW1lbnRUeXBlID0gc291cmNlLmVsZW1lbnRUeXBlO1xuICB0YXJnZXQudHlwZSA9IHNvdXJjZS50eXBlO1xuICB0YXJnZXQuc3RhdGVOb2RlID0gc291cmNlLnN0YXRlTm9kZTtcbiAgdGFyZ2V0LnJldHVybiA9IHNvdXJjZS5yZXR1cm47XG4gIHRhcmdldC5jaGlsZCA9IHNvdXJjZS5jaGlsZDtcbiAgdGFyZ2V0LnNpYmxpbmcgPSBzb3VyY2Uuc2libGluZztcbiAgdGFyZ2V0LmluZGV4ID0gc291cmNlLmluZGV4O1xuICB0YXJnZXQucmVmID0gc291cmNlLnJlZjtcbiAgdGFyZ2V0LnBlbmRpbmdQcm9wcyA9IHNvdXJjZS5wZW5kaW5nUHJvcHM7XG4gIHRhcmdldC5tZW1vaXplZFByb3BzID0gc291cmNlLm1lbW9pemVkUHJvcHM7XG4gIHRhcmdldC51cGRhdGVRdWV1ZSA9IHNvdXJjZS51cGRhdGVRdWV1ZTtcbiAgdGFyZ2V0Lm1lbW9pemVkU3RhdGUgPSBzb3VyY2UubWVtb2l6ZWRTdGF0ZTtcbiAgdGFyZ2V0LmRlcGVuZGVuY2llcyA9IHNvdXJjZS5kZXBlbmRlbmNpZXM7XG4gIHRhcmdldC5tb2RlID0gc291cmNlLm1vZGU7XG4gIHRhcmdldC5mbGFncyA9IHNvdXJjZS5mbGFncztcbiAgdGFyZ2V0LnN1YnRyZWVGbGFncyA9IHNvdXJjZS5zdWJ0cmVlRmxhZ3M7XG4gIHRhcmdldC5kZWxldGlvbnMgPSBzb3VyY2UuZGVsZXRpb25zO1xuICB0YXJnZXQubGFuZXMgPSBzb3VyY2UubGFuZXM7XG4gIHRhcmdldC5jaGlsZExhbmVzID0gc291cmNlLmNoaWxkTGFuZXM7XG4gIHRhcmdldC5hbHRlcm5hdGUgPSBzb3VyY2UuYWx0ZXJuYXRlO1xuXG4gIHtcbiAgICB0YXJnZXQuYWN0dWFsRHVyYXRpb24gPSBzb3VyY2UuYWN0dWFsRHVyYXRpb247XG4gICAgdGFyZ2V0LmFjdHVhbFN0YXJ0VGltZSA9IHNvdXJjZS5hY3R1YWxTdGFydFRpbWU7XG4gICAgdGFyZ2V0LnNlbGZCYXNlRHVyYXRpb24gPSBzb3VyY2Uuc2VsZkJhc2VEdXJhdGlvbjtcbiAgICB0YXJnZXQudHJlZUJhc2VEdXJhdGlvbiA9IHNvdXJjZS50cmVlQmFzZUR1cmF0aW9uO1xuICB9XG5cbiAgdGFyZ2V0Ll9kZWJ1Z1NvdXJjZSA9IHNvdXJjZS5fZGVidWdTb3VyY2U7XG4gIHRhcmdldC5fZGVidWdPd25lciA9IHNvdXJjZS5fZGVidWdPd25lcjtcbiAgdGFyZ2V0Ll9kZWJ1Z05lZWRzUmVtb3VudCA9IHNvdXJjZS5fZGVidWdOZWVkc1JlbW91bnQ7XG4gIHRhcmdldC5fZGVidWdIb29rVHlwZXMgPSBzb3VyY2UuX2RlYnVnSG9va1R5cGVzO1xuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5mdW5jdGlvbiBGaWJlclJvb3ROb2RlKGNvbnRhaW5lckluZm8sIHRhZywgaHlkcmF0ZSwgaWRlbnRpZmllclByZWZpeCwgb25SZWNvdmVyYWJsZUVycm9yKSB7XG4gIHRoaXMudGFnID0gdGFnO1xuICB0aGlzLmNvbnRhaW5lckluZm8gPSBjb250YWluZXJJbmZvO1xuICB0aGlzLnBlbmRpbmdDaGlsZHJlbiA9IG51bGw7XG4gIHRoaXMuY3VycmVudCA9IG51bGw7XG4gIHRoaXMucGluZ0NhY2hlID0gbnVsbDtcbiAgdGhpcy5maW5pc2hlZFdvcmsgPSBudWxsO1xuICB0aGlzLnRpbWVvdXRIYW5kbGUgPSBub1RpbWVvdXQ7XG4gIHRoaXMuY29udGV4dCA9IG51bGw7XG4gIHRoaXMucGVuZGluZ0NvbnRleHQgPSBudWxsO1xuICB0aGlzLmNhbGxiYWNrTm9kZSA9IG51bGw7XG4gIHRoaXMuY2FsbGJhY2tQcmlvcml0eSA9IE5vTGFuZTtcbiAgdGhpcy5ldmVudFRpbWVzID0gY3JlYXRlTGFuZU1hcChOb0xhbmVzKTtcbiAgdGhpcy5leHBpcmF0aW9uVGltZXMgPSBjcmVhdGVMYW5lTWFwKE5vVGltZXN0YW1wKTtcbiAgdGhpcy5wZW5kaW5nTGFuZXMgPSBOb0xhbmVzO1xuICB0aGlzLnN1c3BlbmRlZExhbmVzID0gTm9MYW5lcztcbiAgdGhpcy5waW5nZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHRoaXMuZXhwaXJlZExhbmVzID0gTm9MYW5lcztcbiAgdGhpcy5tdXRhYmxlUmVhZExhbmVzID0gTm9MYW5lcztcbiAgdGhpcy5maW5pc2hlZExhbmVzID0gTm9MYW5lcztcbiAgdGhpcy5lbnRhbmdsZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHRoaXMuZW50YW5nbGVtZW50cyA9IGNyZWF0ZUxhbmVNYXAoTm9MYW5lcyk7XG4gIHRoaXMuaWRlbnRpZmllclByZWZpeCA9IGlkZW50aWZpZXJQcmVmaXg7XG4gIHRoaXMub25SZWNvdmVyYWJsZUVycm9yID0gb25SZWNvdmVyYWJsZUVycm9yO1xuXG4gIHtcbiAgICB0aGlzLm11dGFibGVTb3VyY2VFYWdlckh5ZHJhdGlvbkRhdGEgPSBudWxsO1xuICB9XG5cbiAge1xuICAgIHRoaXMuZWZmZWN0RHVyYXRpb24gPSAwO1xuICAgIHRoaXMucGFzc2l2ZUVmZmVjdER1cmF0aW9uID0gMDtcbiAgfVxuXG4gIHtcbiAgICB0aGlzLm1lbW9pemVkVXBkYXRlcnMgPSBuZXcgU2V0KCk7XG4gICAgdmFyIHBlbmRpbmdVcGRhdGVyc0xhbmVNYXAgPSB0aGlzLnBlbmRpbmdVcGRhdGVyc0xhbmVNYXAgPSBbXTtcblxuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBUb3RhbExhbmVzOyBfaSsrKSB7XG4gICAgICBwZW5kaW5nVXBkYXRlcnNMYW5lTWFwLnB1c2gobmV3IFNldCgpKTtcbiAgICB9XG4gIH1cblxuICB7XG4gICAgc3dpdGNoICh0YWcpIHtcbiAgICAgIGNhc2UgQ29uY3VycmVudFJvb3Q6XG4gICAgICAgIHRoaXMuX2RlYnVnUm9vdFR5cGUgPSBoeWRyYXRlID8gJ2h5ZHJhdGVSb290KCknIDogJ2NyZWF0ZVJvb3QoKSc7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIExlZ2FjeVJvb3Q6XG4gICAgICAgIHRoaXMuX2RlYnVnUm9vdFR5cGUgPSBoeWRyYXRlID8gJ2h5ZHJhdGUoKScgOiAncmVuZGVyKCknO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlRmliZXJSb290KGNvbnRhaW5lckluZm8sIHRhZywgaHlkcmF0ZSwgaW5pdGlhbENoaWxkcmVuLCBoeWRyYXRpb25DYWxsYmFja3MsIGlzU3RyaWN0TW9kZSwgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSwgLy8gVE9ETzogV2UgaGF2ZSBzZXZlcmFsIG9mIHRoZXNlIGFyZ3VtZW50cyB0aGF0IGFyZSBjb25jZXB0dWFsbHkgcGFydCBvZiB0aGVcbi8vIGhvc3QgY29uZmlnLCBidXQgYmVjYXVzZSB0aGV5IGFyZSBwYXNzZWQgaW4gYXQgcnVudGltZSwgd2UgaGF2ZSB0byB0aHJlYWRcbi8vIHRoZW0gdGhyb3VnaCB0aGUgcm9vdCBjb25zdHJ1Y3Rvci4gUGVyaGFwcyB3ZSBzaG91bGQgcHV0IHRoZW0gYWxsIGludG8gYVxuLy8gc2luZ2xlIHR5cGUsIGxpa2UgYSBEeW5hbWljSG9zdENvbmZpZyB0aGF0IGlzIGRlZmluZWQgYnkgdGhlIHJlbmRlcmVyLlxuaWRlbnRpZmllclByZWZpeCwgb25SZWNvdmVyYWJsZUVycm9yLCB0cmFuc2l0aW9uQ2FsbGJhY2tzKSB7XG4gIHZhciByb290ID0gbmV3IEZpYmVyUm9vdE5vZGUoY29udGFpbmVySW5mbywgdGFnLCBoeWRyYXRlLCBpZGVudGlmaWVyUHJlZml4LCBvblJlY292ZXJhYmxlRXJyb3IpO1xuICAvLyBzdGF0ZU5vZGUgaXMgYW55LlxuXG5cbiAgdmFyIHVuaW5pdGlhbGl6ZWRGaWJlciA9IGNyZWF0ZUhvc3RSb290RmliZXIodGFnLCBpc1N0cmljdE1vZGUpO1xuICByb290LmN1cnJlbnQgPSB1bmluaXRpYWxpemVkRmliZXI7XG4gIHVuaW5pdGlhbGl6ZWRGaWJlci5zdGF0ZU5vZGUgPSByb290O1xuXG4gIHtcbiAgICB2YXIgX2luaXRpYWxTdGF0ZSA9IHtcbiAgICAgIGVsZW1lbnQ6IGluaXRpYWxDaGlsZHJlbixcbiAgICAgIGlzRGVoeWRyYXRlZDogaHlkcmF0ZSxcbiAgICAgIGNhY2hlOiBudWxsLFxuICAgICAgLy8gbm90IGVuYWJsZWQgeWV0XG4gICAgICB0cmFuc2l0aW9uczogbnVsbCxcbiAgICAgIHBlbmRpbmdTdXNwZW5zZUJvdW5kYXJpZXM6IG51bGxcbiAgICB9O1xuICAgIHVuaW5pdGlhbGl6ZWRGaWJlci5tZW1vaXplZFN0YXRlID0gX2luaXRpYWxTdGF0ZTtcbiAgfVxuXG4gIGluaXRpYWxpemVVcGRhdGVRdWV1ZSh1bmluaXRpYWxpemVkRmliZXIpO1xuICByZXR1cm4gcm9vdDtcbn1cblxudmFyIFJlYWN0VmVyc2lvbiA9ICcxOC4yLjAnO1xuXG5mdW5jdGlvbiBjcmVhdGVQb3J0YWwoY2hpbGRyZW4sIGNvbnRhaW5lckluZm8sIC8vIFRPRE86IGZpZ3VyZSBvdXQgdGhlIEFQSSBmb3IgY3Jvc3MtcmVuZGVyZXIgaW1wbGVtZW50YXRpb24uXG5pbXBsZW1lbnRhdGlvbikge1xuICB2YXIga2V5ID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiBudWxsO1xuXG4gIHtcbiAgICBjaGVja0tleVN0cmluZ0NvZXJjaW9uKGtleSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC8vIFRoaXMgdGFnIGFsbG93IHVzIHRvIHVuaXF1ZWx5IGlkZW50aWZ5IHRoaXMgYXMgYSBSZWFjdCBQb3J0YWxcbiAgICAkJHR5cGVvZjogUkVBQ1RfUE9SVEFMX1RZUEUsXG4gICAga2V5OiBrZXkgPT0gbnVsbCA/IG51bGwgOiAnJyArIGtleSxcbiAgICBjaGlsZHJlbjogY2hpbGRyZW4sXG4gICAgY29udGFpbmVySW5mbzogY29udGFpbmVySW5mbyxcbiAgICBpbXBsZW1lbnRhdGlvbjogaW1wbGVtZW50YXRpb25cbiAgfTtcbn1cblxudmFyIGRpZFdhcm5BYm91dE5lc3RlZFVwZGF0ZXM7XG52YXIgZGlkV2FybkFib3V0RmluZE5vZGVJblN0cmljdE1vZGU7XG5cbntcbiAgZGlkV2FybkFib3V0TmVzdGVkVXBkYXRlcyA9IGZhbHNlO1xuICBkaWRXYXJuQWJvdXRGaW5kTm9kZUluU3RyaWN0TW9kZSA9IHt9O1xufVxuXG5mdW5jdGlvbiBnZXRDb250ZXh0Rm9yU3VidHJlZShwYXJlbnRDb21wb25lbnQpIHtcbiAgaWYgKCFwYXJlbnRDb21wb25lbnQpIHtcbiAgICByZXR1cm4gZW1wdHlDb250ZXh0T2JqZWN0O1xuICB9XG5cbiAgdmFyIGZpYmVyID0gZ2V0KHBhcmVudENvbXBvbmVudCk7XG4gIHZhciBwYXJlbnRDb250ZXh0ID0gZmluZEN1cnJlbnRVbm1hc2tlZENvbnRleHQoZmliZXIpO1xuXG4gIGlmIChmaWJlci50YWcgPT09IENsYXNzQ29tcG9uZW50KSB7XG4gICAgdmFyIENvbXBvbmVudCA9IGZpYmVyLnR5cGU7XG5cbiAgICBpZiAoaXNDb250ZXh0UHJvdmlkZXIoQ29tcG9uZW50KSkge1xuICAgICAgcmV0dXJuIHByb2Nlc3NDaGlsZENvbnRleHQoZmliZXIsIENvbXBvbmVudCwgcGFyZW50Q29udGV4dCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHBhcmVudENvbnRleHQ7XG59XG5cbmZ1bmN0aW9uIGZpbmRIb3N0SW5zdGFuY2VXaXRoV2FybmluZyhjb21wb25lbnQsIG1ldGhvZE5hbWUpIHtcbiAge1xuICAgIHZhciBmaWJlciA9IGdldChjb21wb25lbnQpO1xuXG4gICAgaWYgKGZpYmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0eXBlb2YgY29tcG9uZW50LnJlbmRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIG5vZGUgb24gYW4gdW5tb3VudGVkIGNvbXBvbmVudC4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoY29tcG9uZW50KS5qb2luKCcsJyk7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkFyZ3VtZW50IGFwcGVhcnMgdG8gbm90IGJlIGEgUmVhY3RDb21wb25lbnQuIEtleXM6IFwiICsga2V5cyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGhvc3RGaWJlciA9IGZpbmRDdXJyZW50SG9zdEZpYmVyKGZpYmVyKTtcblxuICAgIGlmIChob3N0RmliZXIgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmIChob3N0RmliZXIubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgIHZhciBjb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ0NvbXBvbmVudCc7XG5cbiAgICAgIGlmICghZGlkV2FybkFib3V0RmluZE5vZGVJblN0cmljdE1vZGVbY29tcG9uZW50TmFtZV0pIHtcbiAgICAgICAgZGlkV2FybkFib3V0RmluZE5vZGVJblN0cmljdE1vZGVbY29tcG9uZW50TmFtZV0gPSB0cnVlO1xuICAgICAgICB2YXIgcHJldmlvdXNGaWJlciA9IGN1cnJlbnQ7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBzZXRDdXJyZW50RmliZXIoaG9zdEZpYmVyKTtcblxuICAgICAgICAgIGlmIChmaWJlci5tb2RlICYgU3RyaWN0TGVnYWN5TW9kZSkge1xuICAgICAgICAgICAgZXJyb3IoJyVzIGlzIGRlcHJlY2F0ZWQgaW4gU3RyaWN0TW9kZS4gJyArICclcyB3YXMgcGFzc2VkIGFuIGluc3RhbmNlIG9mICVzIHdoaWNoIGlzIGluc2lkZSBTdHJpY3RNb2RlLiAnICsgJ0luc3RlYWQsIGFkZCBhIHJlZiBkaXJlY3RseSB0byB0aGUgZWxlbWVudCB5b3Ugd2FudCB0byByZWZlcmVuY2UuICcgKyAnTGVhcm4gbW9yZSBhYm91dCB1c2luZyByZWZzIHNhZmVseSBoZXJlOiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zdHJpY3QtbW9kZS1maW5kLW5vZGUnLCBtZXRob2ROYW1lLCBtZXRob2ROYW1lLCBjb21wb25lbnROYW1lKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZXJyb3IoJyVzIGlzIGRlcHJlY2F0ZWQgaW4gU3RyaWN0TW9kZS4gJyArICclcyB3YXMgcGFzc2VkIGFuIGluc3RhbmNlIG9mICVzIHdoaWNoIHJlbmRlcnMgU3RyaWN0TW9kZSBjaGlsZHJlbi4gJyArICdJbnN0ZWFkLCBhZGQgYSByZWYgZGlyZWN0bHkgdG8gdGhlIGVsZW1lbnQgeW91IHdhbnQgdG8gcmVmZXJlbmNlLiAnICsgJ0xlYXJuIG1vcmUgYWJvdXQgdXNpbmcgcmVmcyBzYWZlbHkgaGVyZTogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3RyaWN0LW1vZGUtZmluZC1ub2RlJywgbWV0aG9kTmFtZSwgbWV0aG9kTmFtZSwgY29tcG9uZW50TmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIC8vIElkZWFsbHkgdGhpcyBzaG91bGQgcmVzZXQgdG8gcHJldmlvdXMgYnV0IHRoaXMgc2hvdWxkbid0IGJlIGNhbGxlZCBpblxuICAgICAgICAgIC8vIHJlbmRlciBhbmQgdGhlcmUncyBhbm90aGVyIHdhcm5pbmcgZm9yIHRoYXQgYW55d2F5LlxuICAgICAgICAgIGlmIChwcmV2aW91c0ZpYmVyKSB7XG4gICAgICAgICAgICBzZXRDdXJyZW50RmliZXIocHJldmlvdXNGaWJlcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGhvc3RGaWJlci5zdGF0ZU5vZGU7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29udGFpbmVyKGNvbnRhaW5lckluZm8sIHRhZywgaHlkcmF0aW9uQ2FsbGJhY2tzLCBpc1N0cmljdE1vZGUsIGNvbmN1cnJlbnRVcGRhdGVzQnlEZWZhdWx0T3ZlcnJpZGUsIGlkZW50aWZpZXJQcmVmaXgsIG9uUmVjb3ZlcmFibGVFcnJvciwgdHJhbnNpdGlvbkNhbGxiYWNrcykge1xuICB2YXIgaHlkcmF0ZSA9IGZhbHNlO1xuICB2YXIgaW5pdGlhbENoaWxkcmVuID0gbnVsbDtcbiAgcmV0dXJuIGNyZWF0ZUZpYmVyUm9vdChjb250YWluZXJJbmZvLCB0YWcsIGh5ZHJhdGUsIGluaXRpYWxDaGlsZHJlbiwgaHlkcmF0aW9uQ2FsbGJhY2tzLCBpc1N0cmljdE1vZGUsIGNvbmN1cnJlbnRVcGRhdGVzQnlEZWZhdWx0T3ZlcnJpZGUsIGlkZW50aWZpZXJQcmVmaXgsIG9uUmVjb3ZlcmFibGVFcnJvcik7XG59XG5mdW5jdGlvbiBjcmVhdGVIeWRyYXRpb25Db250YWluZXIoaW5pdGlhbENoaWxkcmVuLCAvLyBUT0RPOiBSZW1vdmUgYGNhbGxiYWNrYCB3aGVuIHdlIGRlbGV0ZSBsZWdhY3kgbW9kZS5cbmNhbGxiYWNrLCBjb250YWluZXJJbmZvLCB0YWcsIGh5ZHJhdGlvbkNhbGxiYWNrcywgaXNTdHJpY3RNb2RlLCBjb25jdXJyZW50VXBkYXRlc0J5RGVmYXVsdE92ZXJyaWRlLCBpZGVudGlmaWVyUHJlZml4LCBvblJlY292ZXJhYmxlRXJyb3IsIHRyYW5zaXRpb25DYWxsYmFja3MpIHtcbiAgdmFyIGh5ZHJhdGUgPSB0cnVlO1xuICB2YXIgcm9vdCA9IGNyZWF0ZUZpYmVyUm9vdChjb250YWluZXJJbmZvLCB0YWcsIGh5ZHJhdGUsIGluaXRpYWxDaGlsZHJlbiwgaHlkcmF0aW9uQ2FsbGJhY2tzLCBpc1N0cmljdE1vZGUsIGNvbmN1cnJlbnRVcGRhdGVzQnlEZWZhdWx0T3ZlcnJpZGUsIGlkZW50aWZpZXJQcmVmaXgsIG9uUmVjb3ZlcmFibGVFcnJvcik7IC8vIFRPRE86IE1vdmUgdGhpcyB0byBGaWJlclJvb3QgY29uc3RydWN0b3JcblxuICByb290LmNvbnRleHQgPSBnZXRDb250ZXh0Rm9yU3VidHJlZShudWxsKTsgLy8gU2NoZWR1bGUgdGhlIGluaXRpYWwgcmVuZGVyLiBJbiBhIGh5ZHJhdGlvbiByb290LCB0aGlzIGlzIGRpZmZlcmVudCBmcm9tXG4gIC8vIGEgcmVndWxhciB1cGRhdGUgYmVjYXVzZSB0aGUgaW5pdGlhbCByZW5kZXIgbXVzdCBtYXRjaCB3YXMgd2FzIHJlbmRlcmVkXG4gIC8vIG9uIHRoZSBzZXJ2ZXIuXG4gIC8vIE5PVEU6IFRoaXMgdXBkYXRlIGludGVudGlvbmFsbHkgZG9lc24ndCBoYXZlIGEgcGF5bG9hZC4gV2UncmUgb25seSB1c2luZ1xuICAvLyB0aGUgdXBkYXRlIHRvIHNjaGVkdWxlIHdvcmsgb24gdGhlIHJvb3QgZmliZXIgKGFuZCwgZm9yIGxlZ2FjeSByb290cywgdG9cbiAgLy8gZW5xdWV1ZSB0aGUgY2FsbGJhY2sgaWYgb25lIGlzIHByb3ZpZGVkKS5cblxuICB2YXIgY3VycmVudCA9IHJvb3QuY3VycmVudDtcbiAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgdmFyIGxhbmUgPSByZXF1ZXN0VXBkYXRlTGFuZShjdXJyZW50KTtcbiAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVVwZGF0ZShldmVudFRpbWUsIGxhbmUpO1xuICB1cGRhdGUuY2FsbGJhY2sgPSBjYWxsYmFjayAhPT0gdW5kZWZpbmVkICYmIGNhbGxiYWNrICE9PSBudWxsID8gY2FsbGJhY2sgOiBudWxsO1xuICBlbnF1ZXVlVXBkYXRlKGN1cnJlbnQsIHVwZGF0ZSwgbGFuZSk7XG4gIHNjaGVkdWxlSW5pdGlhbEh5ZHJhdGlvbk9uUm9vdChyb290LCBsYW5lLCBldmVudFRpbWUpO1xuICByZXR1cm4gcm9vdDtcbn1cbmZ1bmN0aW9uIHVwZGF0ZUNvbnRhaW5lcihlbGVtZW50LCBjb250YWluZXIsIHBhcmVudENvbXBvbmVudCwgY2FsbGJhY2spIHtcbiAge1xuICAgIG9uU2NoZWR1bGVSb290KGNvbnRhaW5lciwgZWxlbWVudCk7XG4gIH1cblxuICB2YXIgY3VycmVudCQxID0gY29udGFpbmVyLmN1cnJlbnQ7XG4gIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gIHZhciBsYW5lID0gcmVxdWVzdFVwZGF0ZUxhbmUoY3VycmVudCQxKTtcblxuICB7XG4gICAgbWFya1JlbmRlclNjaGVkdWxlZChsYW5lKTtcbiAgfVxuXG4gIHZhciBjb250ZXh0ID0gZ2V0Q29udGV4dEZvclN1YnRyZWUocGFyZW50Q29tcG9uZW50KTtcblxuICBpZiAoY29udGFpbmVyLmNvbnRleHQgPT09IG51bGwpIHtcbiAgICBjb250YWluZXIuY29udGV4dCA9IGNvbnRleHQ7XG4gIH0gZWxzZSB7XG4gICAgY29udGFpbmVyLnBlbmRpbmdDb250ZXh0ID0gY29udGV4dDtcbiAgfVxuXG4gIHtcbiAgICBpZiAoaXNSZW5kZXJpbmcgJiYgY3VycmVudCAhPT0gbnVsbCAmJiAhZGlkV2FybkFib3V0TmVzdGVkVXBkYXRlcykge1xuICAgICAgZGlkV2FybkFib3V0TmVzdGVkVXBkYXRlcyA9IHRydWU7XG5cbiAgICAgIGVycm9yKCdSZW5kZXIgbWV0aG9kcyBzaG91bGQgYmUgYSBwdXJlIGZ1bmN0aW9uIG9mIHByb3BzIGFuZCBzdGF0ZTsgJyArICd0cmlnZ2VyaW5nIG5lc3RlZCBjb21wb25lbnQgdXBkYXRlcyBmcm9tIHJlbmRlciBpcyBub3QgYWxsb3dlZC4gJyArICdJZiBuZWNlc3NhcnksIHRyaWdnZXIgbmVzdGVkIHVwZGF0ZXMgaW4gY29tcG9uZW50RGlkVXBkYXRlLlxcblxcbicgKyAnQ2hlY2sgdGhlIHJlbmRlciBtZXRob2Qgb2YgJXMuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihjdXJyZW50KSB8fCAnVW5rbm93bicpO1xuICAgIH1cbiAgfVxuXG4gIHZhciB1cGRhdGUgPSBjcmVhdGVVcGRhdGUoZXZlbnRUaW1lLCBsYW5lKTsgLy8gQ2F1dGlvbjogUmVhY3QgRGV2VG9vbHMgY3VycmVudGx5IGRlcGVuZHMgb24gdGhpcyBwcm9wZXJ0eVxuICAvLyBiZWluZyBjYWxsZWQgXCJlbGVtZW50XCIuXG5cbiAgdXBkYXRlLnBheWxvYWQgPSB7XG4gICAgZWxlbWVudDogZWxlbWVudFxuICB9O1xuICBjYWxsYmFjayA9IGNhbGxiYWNrID09PSB1bmRlZmluZWQgPyBudWxsIDogY2FsbGJhY2s7XG5cbiAgaWYgKGNhbGxiYWNrICE9PSBudWxsKSB7XG4gICAge1xuICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBlcnJvcigncmVuZGVyKC4uLik6IEV4cGVjdGVkIHRoZSBsYXN0IG9wdGlvbmFsIGBjYWxsYmFja2AgYXJndW1lbnQgdG8gYmUgYSAnICsgJ2Z1bmN0aW9uLiBJbnN0ZWFkIHJlY2VpdmVkOiAlcy4nLCBjYWxsYmFjayk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlLmNhbGxiYWNrID0gY2FsbGJhY2s7XG4gIH1cblxuICB2YXIgcm9vdCA9IGVucXVldWVVcGRhdGUoY3VycmVudCQxLCB1cGRhdGUsIGxhbmUpO1xuXG4gIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgc2NoZWR1bGVVcGRhdGVPbkZpYmVyKHJvb3QsIGN1cnJlbnQkMSwgbGFuZSwgZXZlbnRUaW1lKTtcbiAgICBlbnRhbmdsZVRyYW5zaXRpb25zKHJvb3QsIGN1cnJlbnQkMSwgbGFuZSk7XG4gIH1cblxuICByZXR1cm4gbGFuZTtcbn1cbmZ1bmN0aW9uIGdldFB1YmxpY1Jvb3RJbnN0YW5jZShjb250YWluZXIpIHtcbiAgdmFyIGNvbnRhaW5lckZpYmVyID0gY29udGFpbmVyLmN1cnJlbnQ7XG5cbiAgaWYgKCFjb250YWluZXJGaWJlci5jaGlsZCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc3dpdGNoIChjb250YWluZXJGaWJlci5jaGlsZC50YWcpIHtcbiAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICByZXR1cm4gZ2V0UHVibGljSW5zdGFuY2UoY29udGFpbmVyRmliZXIuY2hpbGQuc3RhdGVOb2RlKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gY29udGFpbmVyRmliZXIuY2hpbGQuc3RhdGVOb2RlO1xuICB9XG59XG5mdW5jdGlvbiBhdHRlbXB0U3luY2hyb25vdXNIeWRyYXRpb24kMShmaWJlcikge1xuICBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICB7XG4gICAgICAgIHZhciByb290ID0gZmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICAgIGlmIChpc1Jvb3REZWh5ZHJhdGVkKHJvb3QpKSB7XG4gICAgICAgICAgLy8gRmx1c2ggdGhlIGZpcnN0IHNjaGVkdWxlZCBcInVwZGF0ZVwiLlxuICAgICAgICAgIHZhciBsYW5lcyA9IGdldEhpZ2hlc3RQcmlvcml0eVBlbmRpbmdMYW5lcyhyb290KTtcbiAgICAgICAgICBmbHVzaFJvb3Qocm9vdCwgbGFuZXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBmbHVzaFN5bmMoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciByb290ID0gZW5xdWV1ZUNvbmN1cnJlbnRSZW5kZXJGb3JMYW5lKGZpYmVyLCBTeW5jTGFuZSk7XG5cbiAgICAgICAgICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgICAgICAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgU3luY0xhbmUsIGV2ZW50VGltZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTsgLy8gSWYgd2UncmUgc3RpbGwgYmxvY2tlZCBhZnRlciB0aGlzLCB3ZSBuZWVkIHRvIGluY3JlYXNlXG4gICAgICAgIC8vIHRoZSBwcmlvcml0eSBvZiBhbnkgcHJvbWlzZXMgcmVzb2x2aW5nIHdpdGhpbiB0aGlzXG4gICAgICAgIC8vIGJvdW5kYXJ5IHNvIHRoYXQgdGhleSBuZXh0IGF0dGVtcHQgYWxzbyBoYXMgaGlnaGVyIHByaS5cblxuICAgICAgICB2YXIgcmV0cnlMYW5lID0gU3luY0xhbmU7XG4gICAgICAgIG1hcmtSZXRyeUxhbmVJZk5vdEh5ZHJhdGVkKGZpYmVyLCByZXRyeUxhbmUpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBtYXJrUmV0cnlMYW5lSW1wbChmaWJlciwgcmV0cnlMYW5lKSB7XG4gIHZhciBzdXNwZW5zZVN0YXRlID0gZmliZXIubWVtb2l6ZWRTdGF0ZTtcblxuICBpZiAoc3VzcGVuc2VTdGF0ZSAhPT0gbnVsbCAmJiBzdXNwZW5zZVN0YXRlLmRlaHlkcmF0ZWQgIT09IG51bGwpIHtcbiAgICBzdXNwZW5zZVN0YXRlLnJldHJ5TGFuZSA9IGhpZ2hlclByaW9yaXR5TGFuZShzdXNwZW5zZVN0YXRlLnJldHJ5TGFuZSwgcmV0cnlMYW5lKTtcbiAgfVxufSAvLyBJbmNyZWFzZXMgdGhlIHByaW9yaXR5IG9mIHRoZW5hYmxlcyB3aGVuIHRoZXkgcmVzb2x2ZSB3aXRoaW4gdGhpcyBib3VuZGFyeS5cblxuXG5mdW5jdGlvbiBtYXJrUmV0cnlMYW5lSWZOb3RIeWRyYXRlZChmaWJlciwgcmV0cnlMYW5lKSB7XG4gIG1hcmtSZXRyeUxhbmVJbXBsKGZpYmVyLCByZXRyeUxhbmUpO1xuICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuXG4gIGlmIChhbHRlcm5hdGUpIHtcbiAgICBtYXJrUmV0cnlMYW5lSW1wbChhbHRlcm5hdGUsIHJldHJ5TGFuZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGF0dGVtcHRDb250aW51b3VzSHlkcmF0aW9uJDEoZmliZXIpIHtcbiAgaWYgKGZpYmVyLnRhZyAhPT0gU3VzcGVuc2VDb21wb25lbnQpIHtcbiAgICAvLyBXZSBpZ25vcmUgSG9zdFJvb3RzIGhlcmUgYmVjYXVzZSB3ZSBjYW4ndCBpbmNyZWFzZVxuICAgIC8vIHRoZWlyIHByaW9yaXR5IGFuZCB0aGV5IHNob3VsZCBub3Qgc3VzcGVuZCBvbiBJL08sXG4gICAgLy8gc2luY2UgeW91IGhhdmUgdG8gd3JhcCBhbnl0aGluZyB0aGF0IG1pZ2h0IHN1c3BlbmQgaW5cbiAgICAvLyBTdXNwZW5zZS5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgbGFuZSA9IFNlbGVjdGl2ZUh5ZHJhdGlvbkxhbmU7XG4gIHZhciByb290ID0gZW5xdWV1ZUNvbmN1cnJlbnRSZW5kZXJGb3JMYW5lKGZpYmVyLCBsYW5lKTtcblxuICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gICAgc2NoZWR1bGVVcGRhdGVPbkZpYmVyKHJvb3QsIGZpYmVyLCBsYW5lLCBldmVudFRpbWUpO1xuICB9XG5cbiAgbWFya1JldHJ5TGFuZUlmTm90SHlkcmF0ZWQoZmliZXIsIGxhbmUpO1xufVxuZnVuY3Rpb24gYXR0ZW1wdEh5ZHJhdGlvbkF0Q3VycmVudFByaW9yaXR5JDEoZmliZXIpIHtcbiAgaWYgKGZpYmVyLnRhZyAhPT0gU3VzcGVuc2VDb21wb25lbnQpIHtcbiAgICAvLyBXZSBpZ25vcmUgSG9zdFJvb3RzIGhlcmUgYmVjYXVzZSB3ZSBjYW4ndCBpbmNyZWFzZVxuICAgIC8vIHRoZWlyIHByaW9yaXR5IG90aGVyIHRoYW4gc3luY2hyb25vdXNseSBmbHVzaCBpdC5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgbGFuZSA9IHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKTtcbiAgdmFyIHJvb3QgPSBlbnF1ZXVlQ29uY3VycmVudFJlbmRlckZvckxhbmUoZmliZXIsIGxhbmUpO1xuXG4gIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIGxhbmUsIGV2ZW50VGltZSk7XG4gIH1cblxuICBtYXJrUmV0cnlMYW5lSWZOb3RIeWRyYXRlZChmaWJlciwgbGFuZSk7XG59XG5mdW5jdGlvbiBmaW5kSG9zdEluc3RhbmNlV2l0aE5vUG9ydGFscyhmaWJlcikge1xuICB2YXIgaG9zdEZpYmVyID0gZmluZEN1cnJlbnRIb3N0RmliZXJXaXRoTm9Qb3J0YWxzKGZpYmVyKTtcblxuICBpZiAoaG9zdEZpYmVyID09PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gaG9zdEZpYmVyLnN0YXRlTm9kZTtcbn1cblxudmFyIHNob3VsZEVycm9ySW1wbCA9IGZ1bmN0aW9uIChmaWJlcikge1xuICByZXR1cm4gbnVsbDtcbn07XG5cbmZ1bmN0aW9uIHNob3VsZEVycm9yKGZpYmVyKSB7XG4gIHJldHVybiBzaG91bGRFcnJvckltcGwoZmliZXIpO1xufVxuXG52YXIgc2hvdWxkU3VzcGVuZEltcGwgPSBmdW5jdGlvbiAoZmliZXIpIHtcbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuZnVuY3Rpb24gc2hvdWxkU3VzcGVuZChmaWJlcikge1xuICByZXR1cm4gc2hvdWxkU3VzcGVuZEltcGwoZmliZXIpO1xufVxudmFyIG92ZXJyaWRlSG9va1N0YXRlID0gbnVsbDtcbnZhciBvdmVycmlkZUhvb2tTdGF0ZURlbGV0ZVBhdGggPSBudWxsO1xudmFyIG92ZXJyaWRlSG9va1N0YXRlUmVuYW1lUGF0aCA9IG51bGw7XG52YXIgb3ZlcnJpZGVQcm9wcyA9IG51bGw7XG52YXIgb3ZlcnJpZGVQcm9wc0RlbGV0ZVBhdGggPSBudWxsO1xudmFyIG92ZXJyaWRlUHJvcHNSZW5hbWVQYXRoID0gbnVsbDtcbnZhciBzY2hlZHVsZVVwZGF0ZSA9IG51bGw7XG52YXIgc2V0RXJyb3JIYW5kbGVyID0gbnVsbDtcbnZhciBzZXRTdXNwZW5zZUhhbmRsZXIgPSBudWxsO1xuXG57XG4gIHZhciBjb3B5V2l0aERlbGV0ZUltcGwgPSBmdW5jdGlvbiAob2JqLCBwYXRoLCBpbmRleCkge1xuICAgIHZhciBrZXkgPSBwYXRoW2luZGV4XTtcbiAgICB2YXIgdXBkYXRlZCA9IGlzQXJyYXkob2JqKSA/IG9iai5zbGljZSgpIDogYXNzaWduKHt9LCBvYmopO1xuXG4gICAgaWYgKGluZGV4ICsgMSA9PT0gcGF0aC5sZW5ndGgpIHtcbiAgICAgIGlmIChpc0FycmF5KHVwZGF0ZWQpKSB7XG4gICAgICAgIHVwZGF0ZWQuc3BsaWNlKGtleSwgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWxldGUgdXBkYXRlZFtrZXldO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdXBkYXRlZDtcbiAgICB9IC8vICRGbG93Rml4TWUgbnVtYmVyIG9yIHN0cmluZyBpcyBmaW5lIGhlcmVcblxuXG4gICAgdXBkYXRlZFtrZXldID0gY29weVdpdGhEZWxldGVJbXBsKG9ialtrZXldLCBwYXRoLCBpbmRleCArIDEpO1xuICAgIHJldHVybiB1cGRhdGVkO1xuICB9O1xuXG4gIHZhciBjb3B5V2l0aERlbGV0ZSA9IGZ1bmN0aW9uIChvYmosIHBhdGgpIHtcbiAgICByZXR1cm4gY29weVdpdGhEZWxldGVJbXBsKG9iaiwgcGF0aCwgMCk7XG4gIH07XG5cbiAgdmFyIGNvcHlXaXRoUmVuYW1lSW1wbCA9IGZ1bmN0aW9uIChvYmosIG9sZFBhdGgsIG5ld1BhdGgsIGluZGV4KSB7XG4gICAgdmFyIG9sZEtleSA9IG9sZFBhdGhbaW5kZXhdO1xuICAgIHZhciB1cGRhdGVkID0gaXNBcnJheShvYmopID8gb2JqLnNsaWNlKCkgOiBhc3NpZ24oe30sIG9iaik7XG5cbiAgICBpZiAoaW5kZXggKyAxID09PSBvbGRQYXRoLmxlbmd0aCkge1xuICAgICAgdmFyIG5ld0tleSA9IG5ld1BhdGhbaW5kZXhdOyAvLyAkRmxvd0ZpeE1lIG51bWJlciBvciBzdHJpbmcgaXMgZmluZSBoZXJlXG5cbiAgICAgIHVwZGF0ZWRbbmV3S2V5XSA9IHVwZGF0ZWRbb2xkS2V5XTtcblxuICAgICAgaWYgKGlzQXJyYXkodXBkYXRlZCkpIHtcbiAgICAgICAgdXBkYXRlZC5zcGxpY2Uob2xkS2V5LCAxKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSB1cGRhdGVkW29sZEtleV07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vICRGbG93Rml4TWUgbnVtYmVyIG9yIHN0cmluZyBpcyBmaW5lIGhlcmVcbiAgICAgIHVwZGF0ZWRbb2xkS2V5XSA9IGNvcHlXaXRoUmVuYW1lSW1wbCggLy8gJEZsb3dGaXhNZSBudW1iZXIgb3Igc3RyaW5nIGlzIGZpbmUgaGVyZVxuICAgICAgb2JqW29sZEtleV0sIG9sZFBhdGgsIG5ld1BhdGgsIGluZGV4ICsgMSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVwZGF0ZWQ7XG4gIH07XG5cbiAgdmFyIGNvcHlXaXRoUmVuYW1lID0gZnVuY3Rpb24gKG9iaiwgb2xkUGF0aCwgbmV3UGF0aCkge1xuICAgIGlmIChvbGRQYXRoLmxlbmd0aCAhPT0gbmV3UGF0aC5sZW5ndGgpIHtcbiAgICAgIHdhcm4oJ2NvcHlXaXRoUmVuYW1lKCkgZXhwZWN0cyBwYXRocyBvZiB0aGUgc2FtZSBsZW5ndGgnKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5ld1BhdGgubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGlmIChvbGRQYXRoW2ldICE9PSBuZXdQYXRoW2ldKSB7XG4gICAgICAgICAgd2FybignY29weVdpdGhSZW5hbWUoKSBleHBlY3RzIHBhdGhzIHRvIGJlIHRoZSBzYW1lIGV4Y2VwdCBmb3IgdGhlIGRlZXBlc3Qga2V5Jyk7XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY29weVdpdGhSZW5hbWVJbXBsKG9iaiwgb2xkUGF0aCwgbmV3UGF0aCwgMCk7XG4gIH07XG5cbiAgdmFyIGNvcHlXaXRoU2V0SW1wbCA9IGZ1bmN0aW9uIChvYmosIHBhdGgsIGluZGV4LCB2YWx1ZSkge1xuICAgIGlmIChpbmRleCA+PSBwYXRoLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHZhciBrZXkgPSBwYXRoW2luZGV4XTtcbiAgICB2YXIgdXBkYXRlZCA9IGlzQXJyYXkob2JqKSA/IG9iai5zbGljZSgpIDogYXNzaWduKHt9LCBvYmopOyAvLyAkRmxvd0ZpeE1lIG51bWJlciBvciBzdHJpbmcgaXMgZmluZSBoZXJlXG5cbiAgICB1cGRhdGVkW2tleV0gPSBjb3B5V2l0aFNldEltcGwob2JqW2tleV0sIHBhdGgsIGluZGV4ICsgMSwgdmFsdWUpO1xuICAgIHJldHVybiB1cGRhdGVkO1xuICB9O1xuXG4gIHZhciBjb3B5V2l0aFNldCA9IGZ1bmN0aW9uIChvYmosIHBhdGgsIHZhbHVlKSB7XG4gICAgcmV0dXJuIGNvcHlXaXRoU2V0SW1wbChvYmosIHBhdGgsIDAsIHZhbHVlKTtcbiAgfTtcblxuICB2YXIgZmluZEhvb2sgPSBmdW5jdGlvbiAoZmliZXIsIGlkKSB7XG4gICAgLy8gRm9yIG5vdywgdGhlIFwiaWRcIiBvZiBzdGF0ZWZ1bCBob29rcyBpcyBqdXN0IHRoZSBzdGF0ZWZ1bCBob29rIGluZGV4LlxuICAgIC8vIFRoaXMgbWF5IGNoYW5nZSBpbiB0aGUgZnV0dXJlIHdpdGggZS5nLiBuZXN0ZWQgaG9va3MuXG4gICAgdmFyIGN1cnJlbnRIb29rID0gZmliZXIubWVtb2l6ZWRTdGF0ZTtcblxuICAgIHdoaWxlIChjdXJyZW50SG9vayAhPT0gbnVsbCAmJiBpZCA+IDApIHtcbiAgICAgIGN1cnJlbnRIb29rID0gY3VycmVudEhvb2submV4dDtcbiAgICAgIGlkLS07XG4gICAgfVxuXG4gICAgcmV0dXJuIGN1cnJlbnRIb29rO1xuICB9OyAvLyBTdXBwb3J0IERldlRvb2xzIGVkaXRhYmxlIHZhbHVlcyBmb3IgdXNlU3RhdGUgYW5kIHVzZVJlZHVjZXIuXG5cblxuICBvdmVycmlkZUhvb2tTdGF0ZSA9IGZ1bmN0aW9uIChmaWJlciwgaWQsIHBhdGgsIHZhbHVlKSB7XG4gICAgdmFyIGhvb2sgPSBmaW5kSG9vayhmaWJlciwgaWQpO1xuXG4gICAgaWYgKGhvb2sgIT09IG51bGwpIHtcbiAgICAgIHZhciBuZXdTdGF0ZSA9IGNvcHlXaXRoU2V0KGhvb2subWVtb2l6ZWRTdGF0ZSwgcGF0aCwgdmFsdWUpO1xuICAgICAgaG9vay5tZW1vaXplZFN0YXRlID0gbmV3U3RhdGU7XG4gICAgICBob29rLmJhc2VTdGF0ZSA9IG5ld1N0YXRlOyAvLyBXZSBhcmVuJ3QgYWN0dWFsbHkgYWRkaW5nIGFuIHVwZGF0ZSB0byB0aGUgcXVldWUsXG4gICAgICAvLyBiZWNhdXNlIHRoZXJlIGlzIG5vIHVwZGF0ZSB3ZSBjYW4gYWRkIGZvciB1c2VSZWR1Y2VyIGhvb2tzIHRoYXQgd29uJ3QgdHJpZ2dlciBhbiBlcnJvci5cbiAgICAgIC8vIChUaGVyZSdzIG5vIGFwcHJvcHJpYXRlIGFjdGlvbiB0eXBlIGZvciBEZXZUb29scyBvdmVycmlkZXMuKVxuICAgICAgLy8gQXMgYSByZXN1bHQgdGhvdWdoLCBSZWFjdCB3aWxsIHNlZSB0aGUgc2NoZWR1bGVkIHVwZGF0ZSBhcyBhIG5vb3AgYW5kIGJhaWxvdXQuXG4gICAgICAvLyBTaGFsbG93IGNsb25pbmcgcHJvcHMgd29ya3MgYXMgYSB3b3JrYXJvdW5kIGZvciBub3cgdG8gYnlwYXNzIHRoZSBiYWlsb3V0IGNoZWNrLlxuXG4gICAgICBmaWJlci5tZW1vaXplZFByb3BzID0gYXNzaWduKHt9LCBmaWJlci5tZW1vaXplZFByb3BzKTtcbiAgICAgIHZhciByb290ID0gZW5xdWV1ZUNvbmN1cnJlbnRSZW5kZXJGb3JMYW5lKGZpYmVyLCBTeW5jTGFuZSk7XG5cbiAgICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgb3ZlcnJpZGVIb29rU3RhdGVEZWxldGVQYXRoID0gZnVuY3Rpb24gKGZpYmVyLCBpZCwgcGF0aCkge1xuICAgIHZhciBob29rID0gZmluZEhvb2soZmliZXIsIGlkKTtcblxuICAgIGlmIChob29rICE9PSBudWxsKSB7XG4gICAgICB2YXIgbmV3U3RhdGUgPSBjb3B5V2l0aERlbGV0ZShob29rLm1lbW9pemVkU3RhdGUsIHBhdGgpO1xuICAgICAgaG9vay5tZW1vaXplZFN0YXRlID0gbmV3U3RhdGU7XG4gICAgICBob29rLmJhc2VTdGF0ZSA9IG5ld1N0YXRlOyAvLyBXZSBhcmVuJ3QgYWN0dWFsbHkgYWRkaW5nIGFuIHVwZGF0ZSB0byB0aGUgcXVldWUsXG4gICAgICAvLyBiZWNhdXNlIHRoZXJlIGlzIG5vIHVwZGF0ZSB3ZSBjYW4gYWRkIGZvciB1c2VSZWR1Y2VyIGhvb2tzIHRoYXQgd29uJ3QgdHJpZ2dlciBhbiBlcnJvci5cbiAgICAgIC8vIChUaGVyZSdzIG5vIGFwcHJvcHJpYXRlIGFjdGlvbiB0eXBlIGZvciBEZXZUb29scyBvdmVycmlkZXMuKVxuICAgICAgLy8gQXMgYSByZXN1bHQgdGhvdWdoLCBSZWFjdCB3aWxsIHNlZSB0aGUgc2NoZWR1bGVkIHVwZGF0ZSBhcyBhIG5vb3AgYW5kIGJhaWxvdXQuXG4gICAgICAvLyBTaGFsbG93IGNsb25pbmcgcHJvcHMgd29ya3MgYXMgYSB3b3JrYXJvdW5kIGZvciBub3cgdG8gYnlwYXNzIHRoZSBiYWlsb3V0IGNoZWNrLlxuXG4gICAgICBmaWJlci5tZW1vaXplZFByb3BzID0gYXNzaWduKHt9LCBmaWJlci5tZW1vaXplZFByb3BzKTtcbiAgICAgIHZhciByb290ID0gZW5xdWV1ZUNvbmN1cnJlbnRSZW5kZXJGb3JMYW5lKGZpYmVyLCBTeW5jTGFuZSk7XG5cbiAgICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgb3ZlcnJpZGVIb29rU3RhdGVSZW5hbWVQYXRoID0gZnVuY3Rpb24gKGZpYmVyLCBpZCwgb2xkUGF0aCwgbmV3UGF0aCkge1xuICAgIHZhciBob29rID0gZmluZEhvb2soZmliZXIsIGlkKTtcblxuICAgIGlmIChob29rICE9PSBudWxsKSB7XG4gICAgICB2YXIgbmV3U3RhdGUgPSBjb3B5V2l0aFJlbmFtZShob29rLm1lbW9pemVkU3RhdGUsIG9sZFBhdGgsIG5ld1BhdGgpO1xuICAgICAgaG9vay5tZW1vaXplZFN0YXRlID0gbmV3U3RhdGU7XG4gICAgICBob29rLmJhc2VTdGF0ZSA9IG5ld1N0YXRlOyAvLyBXZSBhcmVuJ3QgYWN0dWFsbHkgYWRkaW5nIGFuIHVwZGF0ZSB0byB0aGUgcXVldWUsXG4gICAgICAvLyBiZWNhdXNlIHRoZXJlIGlzIG5vIHVwZGF0ZSB3ZSBjYW4gYWRkIGZvciB1c2VSZWR1Y2VyIGhvb2tzIHRoYXQgd29uJ3QgdHJpZ2dlciBhbiBlcnJvci5cbiAgICAgIC8vIChUaGVyZSdzIG5vIGFwcHJvcHJpYXRlIGFjdGlvbiB0eXBlIGZvciBEZXZUb29scyBvdmVycmlkZXMuKVxuICAgICAgLy8gQXMgYSByZXN1bHQgdGhvdWdoLCBSZWFjdCB3aWxsIHNlZSB0aGUgc2NoZWR1bGVkIHVwZGF0ZSBhcyBhIG5vb3AgYW5kIGJhaWxvdXQuXG4gICAgICAvLyBTaGFsbG93IGNsb25pbmcgcHJvcHMgd29ya3MgYXMgYSB3b3JrYXJvdW5kIGZvciBub3cgdG8gYnlwYXNzIHRoZSBiYWlsb3V0IGNoZWNrLlxuXG4gICAgICBmaWJlci5tZW1vaXplZFByb3BzID0gYXNzaWduKHt9LCBmaWJlci5tZW1vaXplZFByb3BzKTtcbiAgICAgIHZhciByb290ID0gZW5xdWV1ZUNvbmN1cnJlbnRSZW5kZXJGb3JMYW5lKGZpYmVyLCBTeW5jTGFuZSk7XG5cbiAgICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgICAgIH1cbiAgICB9XG4gIH07IC8vIFN1cHBvcnQgRGV2VG9vbHMgcHJvcHMgZm9yIGZ1bmN0aW9uIGNvbXBvbmVudHMsIGZvcndhcmRSZWYsIG1lbW8sIGhvc3QgY29tcG9uZW50cywgZXRjLlxuXG5cbiAgb3ZlcnJpZGVQcm9wcyA9IGZ1bmN0aW9uIChmaWJlciwgcGF0aCwgdmFsdWUpIHtcbiAgICBmaWJlci5wZW5kaW5nUHJvcHMgPSBjb3B5V2l0aFNldChmaWJlci5tZW1vaXplZFByb3BzLCBwYXRoLCB2YWx1ZSk7XG5cbiAgICBpZiAoZmliZXIuYWx0ZXJuYXRlKSB7XG4gICAgICBmaWJlci5hbHRlcm5hdGUucGVuZGluZ1Byb3BzID0gZmliZXIucGVuZGluZ1Byb3BzO1xuICAgIH1cblxuICAgIHZhciByb290ID0gZW5xdWV1ZUNvbmN1cnJlbnRSZW5kZXJGb3JMYW5lKGZpYmVyLCBTeW5jTGFuZSk7XG5cbiAgICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgICAgc2NoZWR1bGVVcGRhdGVPbkZpYmVyKHJvb3QsIGZpYmVyLCBTeW5jTGFuZSwgTm9UaW1lc3RhbXApO1xuICAgIH1cbiAgfTtcblxuICBvdmVycmlkZVByb3BzRGVsZXRlUGF0aCA9IGZ1bmN0aW9uIChmaWJlciwgcGF0aCkge1xuICAgIGZpYmVyLnBlbmRpbmdQcm9wcyA9IGNvcHlXaXRoRGVsZXRlKGZpYmVyLm1lbW9pemVkUHJvcHMsIHBhdGgpO1xuXG4gICAgaWYgKGZpYmVyLmFsdGVybmF0ZSkge1xuICAgICAgZmliZXIuYWx0ZXJuYXRlLnBlbmRpbmdQcm9wcyA9IGZpYmVyLnBlbmRpbmdQcm9wcztcbiAgICB9XG5cbiAgICB2YXIgcm9vdCA9IGVucXVldWVDb25jdXJyZW50UmVuZGVyRm9yTGFuZShmaWJlciwgU3luY0xhbmUpO1xuXG4gICAgaWYgKHJvb3QgIT09IG51bGwpIHtcbiAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgICB9XG4gIH07XG5cbiAgb3ZlcnJpZGVQcm9wc1JlbmFtZVBhdGggPSBmdW5jdGlvbiAoZmliZXIsIG9sZFBhdGgsIG5ld1BhdGgpIHtcbiAgICBmaWJlci5wZW5kaW5nUHJvcHMgPSBjb3B5V2l0aFJlbmFtZShmaWJlci5tZW1vaXplZFByb3BzLCBvbGRQYXRoLCBuZXdQYXRoKTtcblxuICAgIGlmIChmaWJlci5hbHRlcm5hdGUpIHtcbiAgICAgIGZpYmVyLmFsdGVybmF0ZS5wZW5kaW5nUHJvcHMgPSBmaWJlci5wZW5kaW5nUHJvcHM7XG4gICAgfVxuXG4gICAgdmFyIHJvb3QgPSBlbnF1ZXVlQ29uY3VycmVudFJlbmRlckZvckxhbmUoZmliZXIsIFN5bmNMYW5lKTtcblxuICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIFN5bmNMYW5lLCBOb1RpbWVzdGFtcCk7XG4gICAgfVxuICB9O1xuXG4gIHNjaGVkdWxlVXBkYXRlID0gZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgdmFyIHJvb3QgPSBlbnF1ZXVlQ29uY3VycmVudFJlbmRlckZvckxhbmUoZmliZXIsIFN5bmNMYW5lKTtcblxuICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIFN5bmNMYW5lLCBOb1RpbWVzdGFtcCk7XG4gICAgfVxuICB9O1xuXG4gIHNldEVycm9ySGFuZGxlciA9IGZ1bmN0aW9uIChuZXdTaG91bGRFcnJvckltcGwpIHtcbiAgICBzaG91bGRFcnJvckltcGwgPSBuZXdTaG91bGRFcnJvckltcGw7XG4gIH07XG5cbiAgc2V0U3VzcGVuc2VIYW5kbGVyID0gZnVuY3Rpb24gKG5ld1Nob3VsZFN1c3BlbmRJbXBsKSB7XG4gICAgc2hvdWxkU3VzcGVuZEltcGwgPSBuZXdTaG91bGRTdXNwZW5kSW1wbDtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZmluZEhvc3RJbnN0YW5jZUJ5RmliZXIoZmliZXIpIHtcbiAgdmFyIGhvc3RGaWJlciA9IGZpbmRDdXJyZW50SG9zdEZpYmVyKGZpYmVyKTtcblxuICBpZiAoaG9zdEZpYmVyID09PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gaG9zdEZpYmVyLnN0YXRlTm9kZTtcbn1cblxuZnVuY3Rpb24gZW1wdHlGaW5kRmliZXJCeUhvc3RJbnN0YW5jZShpbnN0YW5jZSkge1xuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gZ2V0Q3VycmVudEZpYmVyRm9yRGV2VG9vbHMoKSB7XG4gIHJldHVybiBjdXJyZW50O1xufVxuXG5mdW5jdGlvbiBpbmplY3RJbnRvRGV2VG9vbHMoZGV2VG9vbHNDb25maWcpIHtcbiAgdmFyIGZpbmRGaWJlckJ5SG9zdEluc3RhbmNlID0gZGV2VG9vbHNDb25maWcuZmluZEZpYmVyQnlIb3N0SW5zdGFuY2U7XG4gIHZhciBSZWFjdEN1cnJlbnREaXNwYXRjaGVyID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3RDdXJyZW50RGlzcGF0Y2hlcjtcbiAgcmV0dXJuIGluamVjdEludGVybmFscyh7XG4gICAgYnVuZGxlVHlwZTogZGV2VG9vbHNDb25maWcuYnVuZGxlVHlwZSxcbiAgICB2ZXJzaW9uOiBkZXZUb29sc0NvbmZpZy52ZXJzaW9uLFxuICAgIHJlbmRlcmVyUGFja2FnZU5hbWU6IGRldlRvb2xzQ29uZmlnLnJlbmRlcmVyUGFja2FnZU5hbWUsXG4gICAgcmVuZGVyZXJDb25maWc6IGRldlRvb2xzQ29uZmlnLnJlbmRlcmVyQ29uZmlnLFxuICAgIG92ZXJyaWRlSG9va1N0YXRlOiBvdmVycmlkZUhvb2tTdGF0ZSxcbiAgICBvdmVycmlkZUhvb2tTdGF0ZURlbGV0ZVBhdGg6IG92ZXJyaWRlSG9va1N0YXRlRGVsZXRlUGF0aCxcbiAgICBvdmVycmlkZUhvb2tTdGF0ZVJlbmFtZVBhdGg6IG92ZXJyaWRlSG9va1N0YXRlUmVuYW1lUGF0aCxcbiAgICBvdmVycmlkZVByb3BzOiBvdmVycmlkZVByb3BzLFxuICAgIG92ZXJyaWRlUHJvcHNEZWxldGVQYXRoOiBvdmVycmlkZVByb3BzRGVsZXRlUGF0aCxcbiAgICBvdmVycmlkZVByb3BzUmVuYW1lUGF0aDogb3ZlcnJpZGVQcm9wc1JlbmFtZVBhdGgsXG4gICAgc2V0RXJyb3JIYW5kbGVyOiBzZXRFcnJvckhhbmRsZXIsXG4gICAgc2V0U3VzcGVuc2VIYW5kbGVyOiBzZXRTdXNwZW5zZUhhbmRsZXIsXG4gICAgc2NoZWR1bGVVcGRhdGU6IHNjaGVkdWxlVXBkYXRlLFxuICAgIGN1cnJlbnREaXNwYXRjaGVyUmVmOiBSZWFjdEN1cnJlbnREaXNwYXRjaGVyLFxuICAgIGZpbmRIb3N0SW5zdGFuY2VCeUZpYmVyOiBmaW5kSG9zdEluc3RhbmNlQnlGaWJlcixcbiAgICBmaW5kRmliZXJCeUhvc3RJbnN0YW5jZTogZmluZEZpYmVyQnlIb3N0SW5zdGFuY2UgfHwgZW1wdHlGaW5kRmliZXJCeUhvc3RJbnN0YW5jZSxcbiAgICAvLyBSZWFjdCBSZWZyZXNoXG4gICAgZmluZEhvc3RJbnN0YW5jZXNGb3JSZWZyZXNoOiAgZmluZEhvc3RJbnN0YW5jZXNGb3JSZWZyZXNoICxcbiAgICBzY2hlZHVsZVJlZnJlc2g6ICBzY2hlZHVsZVJlZnJlc2ggLFxuICAgIHNjaGVkdWxlUm9vdDogIHNjaGVkdWxlUm9vdCAsXG4gICAgc2V0UmVmcmVzaEhhbmRsZXI6ICBzZXRSZWZyZXNoSGFuZGxlciAsXG4gICAgLy8gRW5hYmxlcyBEZXZUb29scyB0byBhcHBlbmQgb3duZXIgc3RhY2tzIHRvIGVycm9yIG1lc3NhZ2VzIGluIERFViBtb2RlLlxuICAgIGdldEN1cnJlbnRGaWJlcjogIGdldEN1cnJlbnRGaWJlckZvckRldlRvb2xzICxcbiAgICAvLyBFbmFibGVzIERldlRvb2xzIHRvIGRldGVjdCByZWNvbmNpbGVyIHZlcnNpb24gcmF0aGVyIHRoYW4gcmVuZGVyZXIgdmVyc2lvblxuICAgIC8vIHdoaWNoIG1heSBub3QgbWF0Y2ggZm9yIHRoaXJkIHBhcnR5IHJlbmRlcmVycy5cbiAgICByZWNvbmNpbGVyVmVyc2lvbjogUmVhY3RWZXJzaW9uXG4gIH0pO1xufVxuXG4vKiBnbG9iYWwgcmVwb3J0RXJyb3IgKi9cblxudmFyIGRlZmF1bHRPblJlY292ZXJhYmxlRXJyb3IgPSB0eXBlb2YgcmVwb3J0RXJyb3IgPT09ICdmdW5jdGlvbicgPyAvLyBJbiBtb2Rlcm4gYnJvd3NlcnMsIHJlcG9ydEVycm9yIHdpbGwgZGlzcGF0Y2ggYW4gZXJyb3IgZXZlbnQsXG4vLyBlbXVsYXRpbmcgYW4gdW5jYXVnaHQgSmF2YVNjcmlwdCBlcnJvci5cbnJlcG9ydEVycm9yIDogZnVuY3Rpb24gKGVycm9yKSB7XG4gIC8vIEluIG9sZGVyIGJyb3dzZXJzIGFuZCB0ZXN0IGVudmlyb25tZW50cywgZmFsbGJhY2sgdG8gY29uc29sZS5lcnJvci5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZ1xuICBjb25zb2xlWydlcnJvciddKGVycm9yKTtcbn07XG5cbmZ1bmN0aW9uIFJlYWN0RE9NUm9vdChpbnRlcm5hbFJvb3QpIHtcbiAgdGhpcy5faW50ZXJuYWxSb290ID0gaW50ZXJuYWxSb290O1xufVxuXG5SZWFjdERPTUh5ZHJhdGlvblJvb3QucHJvdG90eXBlLnJlbmRlciA9IFJlYWN0RE9NUm9vdC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKGNoaWxkcmVuKSB7XG4gIHZhciByb290ID0gdGhpcy5faW50ZXJuYWxSb290O1xuXG4gIGlmIChyb290ID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgdXBkYXRlIGFuIHVubW91bnRlZCByb290LicpO1xuICB9XG5cbiAge1xuICAgIGlmICh0eXBlb2YgYXJndW1lbnRzWzFdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcigncmVuZGVyKC4uLik6IGRvZXMgbm90IHN1cHBvcnQgdGhlIHNlY29uZCBjYWxsYmFjayBhcmd1bWVudC4gJyArICdUbyBleGVjdXRlIGEgc2lkZSBlZmZlY3QgYWZ0ZXIgcmVuZGVyaW5nLCBkZWNsYXJlIGl0IGluIGEgY29tcG9uZW50IGJvZHkgd2l0aCB1c2VFZmZlY3QoKS4nKTtcbiAgICB9IGVsc2UgaWYgKGlzVmFsaWRDb250YWluZXIoYXJndW1lbnRzWzFdKSkge1xuICAgICAgZXJyb3IoJ1lvdSBwYXNzZWQgYSBjb250YWluZXIgdG8gdGhlIHNlY29uZCBhcmd1bWVudCBvZiByb290LnJlbmRlciguLi4pLiAnICsgXCJZb3UgZG9uJ3QgbmVlZCB0byBwYXNzIGl0IGFnYWluIHNpbmNlIHlvdSBhbHJlYWR5IHBhc3NlZCBpdCB0byBjcmVhdGUgdGhlIHJvb3QuXCIpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZ3VtZW50c1sxXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGVycm9yKCdZb3UgcGFzc2VkIGEgc2Vjb25kIGFyZ3VtZW50IHRvIHJvb3QucmVuZGVyKC4uLikgYnV0IGl0IG9ubHkgYWNjZXB0cyAnICsgJ29uZSBhcmd1bWVudC4nKTtcbiAgICB9XG5cbiAgICB2YXIgY29udGFpbmVyID0gcm9vdC5jb250YWluZXJJbmZvO1xuXG4gICAgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSAhPT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgICB2YXIgaG9zdEluc3RhbmNlID0gZmluZEhvc3RJbnN0YW5jZVdpdGhOb1BvcnRhbHMocm9vdC5jdXJyZW50KTtcblxuICAgICAgaWYgKGhvc3RJbnN0YW5jZSkge1xuICAgICAgICBpZiAoaG9zdEluc3RhbmNlLnBhcmVudE5vZGUgIT09IGNvbnRhaW5lcikge1xuICAgICAgICAgIGVycm9yKCdyZW5kZXIoLi4uKTogSXQgbG9va3MgbGlrZSB0aGUgUmVhY3QtcmVuZGVyZWQgY29udGVudCBvZiB0aGUgJyArICdyb290IGNvbnRhaW5lciB3YXMgcmVtb3ZlZCB3aXRob3V0IHVzaW5nIFJlYWN0LiBUaGlzIGlzIG5vdCAnICsgJ3N1cHBvcnRlZCBhbmQgd2lsbCBjYXVzZSBlcnJvcnMuIEluc3RlYWQsIGNhbGwgJyArIFwicm9vdC51bm1vdW50KCkgdG8gZW1wdHkgYSByb290J3MgY29udGFpbmVyLlwiKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUNvbnRhaW5lcihjaGlsZHJlbiwgcm9vdCwgbnVsbCwgbnVsbCk7XG59O1xuXG5SZWFjdERPTUh5ZHJhdGlvblJvb3QucHJvdG90eXBlLnVubW91bnQgPSBSZWFjdERPTVJvb3QucHJvdG90eXBlLnVubW91bnQgPSBmdW5jdGlvbiAoKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIGFyZ3VtZW50c1swXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJ3VubW91bnQoLi4uKTogZG9lcyBub3Qgc3VwcG9ydCBhIGNhbGxiYWNrIGFyZ3VtZW50LiAnICsgJ1RvIGV4ZWN1dGUgYSBzaWRlIGVmZmVjdCBhZnRlciByZW5kZXJpbmcsIGRlY2xhcmUgaXQgaW4gYSBjb21wb25lbnQgYm9keSB3aXRoIHVzZUVmZmVjdCgpLicpO1xuICAgIH1cbiAgfVxuXG4gIHZhciByb290ID0gdGhpcy5faW50ZXJuYWxSb290O1xuXG4gIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgdGhpcy5faW50ZXJuYWxSb290ID0gbnVsbDtcbiAgICB2YXIgY29udGFpbmVyID0gcm9vdC5jb250YWluZXJJbmZvO1xuXG4gICAge1xuICAgICAgaWYgKGlzQWxyZWFkeVJlbmRlcmluZygpKSB7XG4gICAgICAgIGVycm9yKCdBdHRlbXB0ZWQgdG8gc3luY2hyb25vdXNseSB1bm1vdW50IGEgcm9vdCB3aGlsZSBSZWFjdCB3YXMgYWxyZWFkeSAnICsgJ3JlbmRlcmluZy4gUmVhY3QgY2Fubm90IGZpbmlzaCB1bm1vdW50aW5nIHRoZSByb290IHVudGlsIHRoZSAnICsgJ2N1cnJlbnQgcmVuZGVyIGhhcyBjb21wbGV0ZWQsIHdoaWNoIG1heSBsZWFkIHRvIGEgcmFjZSBjb25kaXRpb24uJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZmx1c2hTeW5jKGZ1bmN0aW9uICgpIHtcbiAgICAgIHVwZGF0ZUNvbnRhaW5lcihudWxsLCByb290LCBudWxsLCBudWxsKTtcbiAgICB9KTtcbiAgICB1bm1hcmtDb250YWluZXJBc1Jvb3QoY29udGFpbmVyKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gY3JlYXRlUm9vdChjb250YWluZXIsIG9wdGlvbnMpIHtcbiAgaWYgKCFpc1ZhbGlkQ29udGFpbmVyKGNvbnRhaW5lcikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NyZWF0ZVJvb3QoLi4uKTogVGFyZ2V0IGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudC4nKTtcbiAgfVxuXG4gIHdhcm5JZlJlYWN0RE9NQ29udGFpbmVySW5ERVYoY29udGFpbmVyKTtcbiAgdmFyIGlzU3RyaWN0TW9kZSA9IGZhbHNlO1xuICB2YXIgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSA9IGZhbHNlO1xuICB2YXIgaWRlbnRpZmllclByZWZpeCA9ICcnO1xuICB2YXIgb25SZWNvdmVyYWJsZUVycm9yID0gZGVmYXVsdE9uUmVjb3ZlcmFibGVFcnJvcjtcbiAgdmFyIHRyYW5zaXRpb25DYWxsYmFja3MgPSBudWxsO1xuXG4gIGlmIChvcHRpb25zICE9PSBudWxsICYmIG9wdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgIHtcbiAgICAgIGlmIChvcHRpb25zLmh5ZHJhdGUpIHtcbiAgICAgICAgd2FybignaHlkcmF0ZSB0aHJvdWdoIGNyZWF0ZVJvb3QgaXMgZGVwcmVjYXRlZC4gVXNlIFJlYWN0RE9NQ2xpZW50Lmh5ZHJhdGVSb290KGNvbnRhaW5lciwgPEFwcCAvPikgaW5zdGVhZC4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcgJiYgb3B0aW9ucyAhPT0gbnVsbCAmJiBvcHRpb25zLiQkdHlwZW9mID09PSBSRUFDVF9FTEVNRU5UX1RZUEUpIHtcbiAgICAgICAgICBlcnJvcignWW91IHBhc3NlZCBhIEpTWCBlbGVtZW50IHRvIGNyZWF0ZVJvb3QuIFlvdSBwcm9iYWJseSBtZWFudCB0byAnICsgJ2NhbGwgcm9vdC5yZW5kZXIgaW5zdGVhZC4gJyArICdFeGFtcGxlIHVzYWdlOlxcblxcbicgKyAnICBsZXQgcm9vdCA9IGNyZWF0ZVJvb3QoZG9tQ29udGFpbmVyKTtcXG4nICsgJyAgcm9vdC5yZW5kZXIoPEFwcCAvPik7Jyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy51bnN0YWJsZV9zdHJpY3RNb2RlID09PSB0cnVlKSB7XG4gICAgICBpc1N0cmljdE1vZGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmlkZW50aWZpZXJQcmVmaXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWRlbnRpZmllclByZWZpeCA9IG9wdGlvbnMuaWRlbnRpZmllclByZWZpeDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5vblJlY292ZXJhYmxlRXJyb3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb25SZWNvdmVyYWJsZUVycm9yID0gb3B0aW9ucy5vblJlY292ZXJhYmxlRXJyb3I7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMudHJhbnNpdGlvbkNhbGxiYWNrcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0cmFuc2l0aW9uQ2FsbGJhY2tzID0gb3B0aW9ucy50cmFuc2l0aW9uQ2FsbGJhY2tzO1xuICAgIH1cbiAgfVxuXG4gIHZhciByb290ID0gY3JlYXRlQ29udGFpbmVyKGNvbnRhaW5lciwgQ29uY3VycmVudFJvb3QsIG51bGwsIGlzU3RyaWN0TW9kZSwgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSwgaWRlbnRpZmllclByZWZpeCwgb25SZWNvdmVyYWJsZUVycm9yKTtcbiAgbWFya0NvbnRhaW5lckFzUm9vdChyb290LmN1cnJlbnQsIGNvbnRhaW5lcik7XG4gIHZhciByb290Q29udGFpbmVyRWxlbWVudCA9IGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFID8gY29udGFpbmVyLnBhcmVudE5vZGUgOiBjb250YWluZXI7XG4gIGxpc3RlblRvQWxsU3VwcG9ydGVkRXZlbnRzKHJvb3RDb250YWluZXJFbGVtZW50KTtcbiAgcmV0dXJuIG5ldyBSZWFjdERPTVJvb3Qocm9vdCk7XG59XG5cbmZ1bmN0aW9uIFJlYWN0RE9NSHlkcmF0aW9uUm9vdChpbnRlcm5hbFJvb3QpIHtcbiAgdGhpcy5faW50ZXJuYWxSb290ID0gaW50ZXJuYWxSb290O1xufVxuXG5mdW5jdGlvbiBzY2hlZHVsZUh5ZHJhdGlvbih0YXJnZXQpIHtcbiAgaWYgKHRhcmdldCkge1xuICAgIHF1ZXVlRXhwbGljaXRIeWRyYXRpb25UYXJnZXQodGFyZ2V0KTtcbiAgfVxufVxuXG5SZWFjdERPTUh5ZHJhdGlvblJvb3QucHJvdG90eXBlLnVuc3RhYmxlX3NjaGVkdWxlSHlkcmF0aW9uID0gc2NoZWR1bGVIeWRyYXRpb247XG5mdW5jdGlvbiBoeWRyYXRlUm9vdChjb250YWluZXIsIGluaXRpYWxDaGlsZHJlbiwgb3B0aW9ucykge1xuICBpZiAoIWlzVmFsaWRDb250YWluZXIoY29udGFpbmVyKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaHlkcmF0ZVJvb3QoLi4uKTogVGFyZ2V0IGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudC4nKTtcbiAgfVxuXG4gIHdhcm5JZlJlYWN0RE9NQ29udGFpbmVySW5ERVYoY29udGFpbmVyKTtcblxuICB7XG4gICAgaWYgKGluaXRpYWxDaGlsZHJlbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBlcnJvcignTXVzdCBwcm92aWRlIGluaXRpYWwgY2hpbGRyZW4gYXMgc2Vjb25kIGFyZ3VtZW50IHRvIGh5ZHJhdGVSb290LiAnICsgJ0V4YW1wbGUgdXNhZ2U6IGh5ZHJhdGVSb290KGRvbUNvbnRhaW5lciwgPEFwcCAvPiknKTtcbiAgICB9XG4gIH0gLy8gRm9yIG5vdyB3ZSByZXVzZSB0aGUgd2hvbGUgYmFnIG9mIG9wdGlvbnMgc2luY2UgdGhleSBjb250YWluXG4gIC8vIHRoZSBoeWRyYXRpb24gY2FsbGJhY2tzLlxuXG5cbiAgdmFyIGh5ZHJhdGlvbkNhbGxiYWNrcyA9IG9wdGlvbnMgIT0gbnVsbCA/IG9wdGlvbnMgOiBudWxsOyAvLyBUT0RPOiBEZWxldGUgdGhpcyBvcHRpb25cblxuICB2YXIgbXV0YWJsZVNvdXJjZXMgPSBvcHRpb25zICE9IG51bGwgJiYgb3B0aW9ucy5oeWRyYXRlZFNvdXJjZXMgfHwgbnVsbDtcbiAgdmFyIGlzU3RyaWN0TW9kZSA9IGZhbHNlO1xuICB2YXIgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSA9IGZhbHNlO1xuICB2YXIgaWRlbnRpZmllclByZWZpeCA9ICcnO1xuICB2YXIgb25SZWNvdmVyYWJsZUVycm9yID0gZGVmYXVsdE9uUmVjb3ZlcmFibGVFcnJvcjtcblxuICBpZiAob3B0aW9ucyAhPT0gbnVsbCAmJiBvcHRpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAob3B0aW9ucy51bnN0YWJsZV9zdHJpY3RNb2RlID09PSB0cnVlKSB7XG4gICAgICBpc1N0cmljdE1vZGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmlkZW50aWZpZXJQcmVmaXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWRlbnRpZmllclByZWZpeCA9IG9wdGlvbnMuaWRlbnRpZmllclByZWZpeDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5vblJlY292ZXJhYmxlRXJyb3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb25SZWNvdmVyYWJsZUVycm9yID0gb3B0aW9ucy5vblJlY292ZXJhYmxlRXJyb3I7XG4gICAgfVxuICB9XG5cbiAgdmFyIHJvb3QgPSBjcmVhdGVIeWRyYXRpb25Db250YWluZXIoaW5pdGlhbENoaWxkcmVuLCBudWxsLCBjb250YWluZXIsIENvbmN1cnJlbnRSb290LCBoeWRyYXRpb25DYWxsYmFja3MsIGlzU3RyaWN0TW9kZSwgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSwgaWRlbnRpZmllclByZWZpeCwgb25SZWNvdmVyYWJsZUVycm9yKTtcbiAgbWFya0NvbnRhaW5lckFzUm9vdChyb290LmN1cnJlbnQsIGNvbnRhaW5lcik7IC8vIFRoaXMgY2FuJ3QgYmUgYSBjb21tZW50IG5vZGUgc2luY2UgaHlkcmF0aW9uIGRvZXNuJ3Qgd29yayBvbiBjb21tZW50IG5vZGVzIGFueXdheS5cblxuICBsaXN0ZW5Ub0FsbFN1cHBvcnRlZEV2ZW50cyhjb250YWluZXIpO1xuXG4gIGlmIChtdXRhYmxlU291cmNlcykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXV0YWJsZVNvdXJjZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBtdXRhYmxlU291cmNlID0gbXV0YWJsZVNvdXJjZXNbaV07XG4gICAgICByZWdpc3Rlck11dGFibGVTb3VyY2VGb3JIeWRyYXRpb24ocm9vdCwgbXV0YWJsZVNvdXJjZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBSZWFjdERPTUh5ZHJhdGlvblJvb3Qocm9vdCk7XG59XG5mdW5jdGlvbiBpc1ZhbGlkQ29udGFpbmVyKG5vZGUpIHtcbiAgcmV0dXJuICEhKG5vZGUgJiYgKG5vZGUubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSB8fCBub2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9OT0RFIHx8IG5vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUgfHwgIWRpc2FibGVDb21tZW50c0FzRE9NQ29udGFpbmVycyAgKSk7XG59IC8vIFRPRE86IFJlbW92ZSB0aGlzIGZ1bmN0aW9uIHdoaWNoIGFsc28gaW5jbHVkZXMgY29tbWVudCBub2Rlcy5cbi8vIFdlIG9ubHkgdXNlIGl0IGluIHBsYWNlcyB0aGF0IGFyZSBjdXJyZW50bHkgbW9yZSByZWxheGVkLlxuXG5mdW5jdGlvbiBpc1ZhbGlkQ29udGFpbmVyTGVnYWN5KG5vZGUpIHtcbiAgcmV0dXJuICEhKG5vZGUgJiYgKG5vZGUubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSB8fCBub2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9OT0RFIHx8IG5vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUgfHwgbm9kZS5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFICYmIG5vZGUubm9kZVZhbHVlID09PSAnIHJlYWN0LW1vdW50LXBvaW50LXVuc3RhYmxlICcpKTtcbn1cblxuZnVuY3Rpb24gd2FybklmUmVhY3RET01Db250YWluZXJJbkRFVihjb250YWluZXIpIHtcbiAge1xuICAgIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSAmJiBjb250YWluZXIudGFnTmFtZSAmJiBjb250YWluZXIudGFnTmFtZS50b1VwcGVyQ2FzZSgpID09PSAnQk9EWScpIHtcbiAgICAgIGVycm9yKCdjcmVhdGVSb290KCk6IENyZWF0aW5nIHJvb3RzIGRpcmVjdGx5IHdpdGggZG9jdW1lbnQuYm9keSBpcyAnICsgJ2Rpc2NvdXJhZ2VkLCBzaW5jZSBpdHMgY2hpbGRyZW4gYXJlIG9mdGVuIG1hbmlwdWxhdGVkIGJ5IHRoaXJkLXBhcnR5ICcgKyAnc2NyaXB0cyBhbmQgYnJvd3NlciBleHRlbnNpb25zLiBUaGlzIG1heSBsZWFkIHRvIHN1YnRsZSAnICsgJ3JlY29uY2lsaWF0aW9uIGlzc3Vlcy4gVHJ5IHVzaW5nIGEgY29udGFpbmVyIGVsZW1lbnQgY3JlYXRlZCAnICsgJ2ZvciB5b3VyIGFwcC4nKTtcbiAgICB9XG5cbiAgICBpZiAoaXNDb250YWluZXJNYXJrZWRBc1Jvb3QoY29udGFpbmVyKSkge1xuICAgICAgaWYgKGNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyKSB7XG4gICAgICAgIGVycm9yKCdZb3UgYXJlIGNhbGxpbmcgUmVhY3RET01DbGllbnQuY3JlYXRlUm9vdCgpIG9uIGEgY29udGFpbmVyIHRoYXQgd2FzIHByZXZpb3VzbHkgJyArICdwYXNzZWQgdG8gUmVhY3RET00ucmVuZGVyKCkuIFRoaXMgaXMgbm90IHN1cHBvcnRlZC4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yKCdZb3UgYXJlIGNhbGxpbmcgUmVhY3RET01DbGllbnQuY3JlYXRlUm9vdCgpIG9uIGEgY29udGFpbmVyIHRoYXQgJyArICdoYXMgYWxyZWFkeSBiZWVuIHBhc3NlZCB0byBjcmVhdGVSb290KCkgYmVmb3JlLiBJbnN0ZWFkLCBjYWxsICcgKyAncm9vdC5yZW5kZXIoKSBvbiB0aGUgZXhpc3Rpbmcgcm9vdCBpbnN0ZWFkIGlmIHlvdSB3YW50IHRvIHVwZGF0ZSBpdC4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIFJlYWN0Q3VycmVudE93bmVyJDMgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRPd25lcjtcbnZhciB0b3BMZXZlbFVwZGF0ZVdhcm5pbmdzO1xuXG57XG4gIHRvcExldmVsVXBkYXRlV2FybmluZ3MgPSBmdW5jdGlvbiAoY29udGFpbmVyKSB7XG4gICAgaWYgKGNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyICYmIGNvbnRhaW5lci5ub2RlVHlwZSAhPT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgICB2YXIgaG9zdEluc3RhbmNlID0gZmluZEhvc3RJbnN0YW5jZVdpdGhOb1BvcnRhbHMoY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIuY3VycmVudCk7XG5cbiAgICAgIGlmIChob3N0SW5zdGFuY2UpIHtcbiAgICAgICAgaWYgKGhvc3RJbnN0YW5jZS5wYXJlbnROb2RlICE9PSBjb250YWluZXIpIHtcbiAgICAgICAgICBlcnJvcigncmVuZGVyKC4uLik6IEl0IGxvb2tzIGxpa2UgdGhlIFJlYWN0LXJlbmRlcmVkIGNvbnRlbnQgb2YgdGhpcyAnICsgJ2NvbnRhaW5lciB3YXMgcmVtb3ZlZCB3aXRob3V0IHVzaW5nIFJlYWN0LiBUaGlzIGlzIG5vdCAnICsgJ3N1cHBvcnRlZCBhbmQgd2lsbCBjYXVzZSBlcnJvcnMuIEluc3RlYWQsIGNhbGwgJyArICdSZWFjdERPTS51bm1vdW50Q29tcG9uZW50QXROb2RlIHRvIGVtcHR5IGEgY29udGFpbmVyLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGlzUm9vdFJlbmRlcmVkQnlTb21lUmVhY3QgPSAhIWNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyO1xuICAgIHZhciByb290RWwgPSBnZXRSZWFjdFJvb3RFbGVtZW50SW5Db250YWluZXIoY29udGFpbmVyKTtcbiAgICB2YXIgaGFzTm9uUm9vdFJlYWN0Q2hpbGQgPSAhIShyb290RWwgJiYgZ2V0SW5zdGFuY2VGcm9tTm9kZShyb290RWwpKTtcblxuICAgIGlmIChoYXNOb25Sb290UmVhY3RDaGlsZCAmJiAhaXNSb290UmVuZGVyZWRCeVNvbWVSZWFjdCkge1xuICAgICAgZXJyb3IoJ3JlbmRlciguLi4pOiBSZXBsYWNpbmcgUmVhY3QtcmVuZGVyZWQgY2hpbGRyZW4gd2l0aCBhIG5ldyByb290ICcgKyAnY29tcG9uZW50LiBJZiB5b3UgaW50ZW5kZWQgdG8gdXBkYXRlIHRoZSBjaGlsZHJlbiBvZiB0aGlzIG5vZGUsICcgKyAneW91IHNob3VsZCBpbnN0ZWFkIGhhdmUgdGhlIGV4aXN0aW5nIGNoaWxkcmVuIHVwZGF0ZSB0aGVpciBzdGF0ZSAnICsgJ2FuZCByZW5kZXIgdGhlIG5ldyBjb21wb25lbnRzIGluc3RlYWQgb2YgY2FsbGluZyBSZWFjdERPTS5yZW5kZXIuJyk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFICYmIGNvbnRhaW5lci50YWdOYW1lICYmIGNvbnRhaW5lci50YWdOYW1lLnRvVXBwZXJDYXNlKCkgPT09ICdCT0RZJykge1xuICAgICAgZXJyb3IoJ3JlbmRlcigpOiBSZW5kZXJpbmcgY29tcG9uZW50cyBkaXJlY3RseSBpbnRvIGRvY3VtZW50LmJvZHkgaXMgJyArICdkaXNjb3VyYWdlZCwgc2luY2UgaXRzIGNoaWxkcmVuIGFyZSBvZnRlbiBtYW5pcHVsYXRlZCBieSB0aGlyZC1wYXJ0eSAnICsgJ3NjcmlwdHMgYW5kIGJyb3dzZXIgZXh0ZW5zaW9ucy4gVGhpcyBtYXkgbGVhZCB0byBzdWJ0bGUgJyArICdyZWNvbmNpbGlhdGlvbiBpc3N1ZXMuIFRyeSByZW5kZXJpbmcgaW50byBhIGNvbnRhaW5lciBlbGVtZW50IGNyZWF0ZWQgJyArICdmb3IgeW91ciBhcHAuJyk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRSZWFjdFJvb3RFbGVtZW50SW5Db250YWluZXIoY29udGFpbmVyKSB7XG4gIGlmICghY29udGFpbmVyKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBET0NVTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIGNvbnRhaW5lci5kb2N1bWVudEVsZW1lbnQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGNvbnRhaW5lci5maXJzdENoaWxkO1xuICB9XG59XG5cbmZ1bmN0aW9uIG5vb3BPblJlY292ZXJhYmxlRXJyb3IoKSB7Ly8gVGhpcyBpc24ndCByZWFjaGFibGUgYmVjYXVzZSBvblJlY292ZXJhYmxlRXJyb3IgaXNuJ3QgY2FsbGVkIGluIHRoZVxuICAvLyBsZWdhY3kgQVBJLlxufVxuXG5mdW5jdGlvbiBsZWdhY3lDcmVhdGVSb290RnJvbURPTUNvbnRhaW5lcihjb250YWluZXIsIGluaXRpYWxDaGlsZHJlbiwgcGFyZW50Q29tcG9uZW50LCBjYWxsYmFjaywgaXNIeWRyYXRpb25Db250YWluZXIpIHtcbiAgaWYgKGlzSHlkcmF0aW9uQ29udGFpbmVyKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIG9yaWdpbmFsQ2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICAgICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBpbnN0YW5jZSA9IGdldFB1YmxpY1Jvb3RJbnN0YW5jZShyb290KTtcbiAgICAgICAgb3JpZ2luYWxDYWxsYmFjay5jYWxsKGluc3RhbmNlKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIHJvb3QgPSBjcmVhdGVIeWRyYXRpb25Db250YWluZXIoaW5pdGlhbENoaWxkcmVuLCBjYWxsYmFjaywgY29udGFpbmVyLCBMZWdhY3lSb290LCBudWxsLCAvLyBoeWRyYXRpb25DYWxsYmFja3NcbiAgICBmYWxzZSwgLy8gaXNTdHJpY3RNb2RlXG4gICAgZmFsc2UsIC8vIGNvbmN1cnJlbnRVcGRhdGVzQnlEZWZhdWx0T3ZlcnJpZGUsXG4gICAgJycsIC8vIGlkZW50aWZpZXJQcmVmaXhcbiAgICBub29wT25SZWNvdmVyYWJsZUVycm9yKTtcbiAgICBjb250YWluZXIuX3JlYWN0Um9vdENvbnRhaW5lciA9IHJvb3Q7XG4gICAgbWFya0NvbnRhaW5lckFzUm9vdChyb290LmN1cnJlbnQsIGNvbnRhaW5lcik7XG4gICAgdmFyIHJvb3RDb250YWluZXJFbGVtZW50ID0gY29udGFpbmVyLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUgPyBjb250YWluZXIucGFyZW50Tm9kZSA6IGNvbnRhaW5lcjtcbiAgICBsaXN0ZW5Ub0FsbFN1cHBvcnRlZEV2ZW50cyhyb290Q29udGFpbmVyRWxlbWVudCk7XG4gICAgZmx1c2hTeW5jKCk7XG4gICAgcmV0dXJuIHJvb3Q7XG4gIH0gZWxzZSB7XG4gICAgLy8gRmlyc3QgY2xlYXIgYW55IGV4aXN0aW5nIGNvbnRlbnQuXG4gICAgdmFyIHJvb3RTaWJsaW5nO1xuXG4gICAgd2hpbGUgKHJvb3RTaWJsaW5nID0gY29udGFpbmVyLmxhc3RDaGlsZCkge1xuICAgICAgY29udGFpbmVyLnJlbW92ZUNoaWxkKHJvb3RTaWJsaW5nKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgX29yaWdpbmFsQ2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICAgICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBpbnN0YW5jZSA9IGdldFB1YmxpY1Jvb3RJbnN0YW5jZShfcm9vdCk7XG5cbiAgICAgICAgX29yaWdpbmFsQ2FsbGJhY2suY2FsbChpbnN0YW5jZSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIHZhciBfcm9vdCA9IGNyZWF0ZUNvbnRhaW5lcihjb250YWluZXIsIExlZ2FjeVJvb3QsIG51bGwsIC8vIGh5ZHJhdGlvbkNhbGxiYWNrc1xuICAgIGZhbHNlLCAvLyBpc1N0cmljdE1vZGVcbiAgICBmYWxzZSwgLy8gY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSxcbiAgICAnJywgLy8gaWRlbnRpZmllclByZWZpeFxuICAgIG5vb3BPblJlY292ZXJhYmxlRXJyb3IpO1xuXG4gICAgY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIgPSBfcm9vdDtcbiAgICBtYXJrQ29udGFpbmVyQXNSb290KF9yb290LmN1cnJlbnQsIGNvbnRhaW5lcik7XG5cbiAgICB2YXIgX3Jvb3RDb250YWluZXJFbGVtZW50ID0gY29udGFpbmVyLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUgPyBjb250YWluZXIucGFyZW50Tm9kZSA6IGNvbnRhaW5lcjtcblxuICAgIGxpc3RlblRvQWxsU3VwcG9ydGVkRXZlbnRzKF9yb290Q29udGFpbmVyRWxlbWVudCk7IC8vIEluaXRpYWwgbW91bnQgc2hvdWxkIG5vdCBiZSBiYXRjaGVkLlxuXG4gICAgZmx1c2hTeW5jKGZ1bmN0aW9uICgpIHtcbiAgICAgIHVwZGF0ZUNvbnRhaW5lcihpbml0aWFsQ2hpbGRyZW4sIF9yb290LCBwYXJlbnRDb21wb25lbnQsIGNhbGxiYWNrKTtcbiAgICB9KTtcbiAgICByZXR1cm4gX3Jvb3Q7XG4gIH1cbn1cblxuZnVuY3Rpb24gd2Fybk9uSW52YWxpZENhbGxiYWNrJDEoY2FsbGJhY2ssIGNhbGxlck5hbWUpIHtcbiAge1xuICAgIGlmIChjYWxsYmFjayAhPT0gbnVsbCAmJiB0eXBlb2YgY2FsbGJhY2sgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGVycm9yKCclcyguLi4pOiBFeHBlY3RlZCB0aGUgbGFzdCBvcHRpb25hbCBgY2FsbGJhY2tgIGFyZ3VtZW50IHRvIGJlIGEgJyArICdmdW5jdGlvbi4gSW5zdGVhZCByZWNlaXZlZDogJXMuJywgY2FsbGVyTmFtZSwgY2FsbGJhY2spO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBsZWdhY3lSZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lcihwYXJlbnRDb21wb25lbnQsIGNoaWxkcmVuLCBjb250YWluZXIsIGZvcmNlSHlkcmF0ZSwgY2FsbGJhY2spIHtcbiAge1xuICAgIHRvcExldmVsVXBkYXRlV2FybmluZ3MoY29udGFpbmVyKTtcbiAgICB3YXJuT25JbnZhbGlkQ2FsbGJhY2skMShjYWxsYmFjayA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGNhbGxiYWNrLCAncmVuZGVyJyk7XG4gIH1cblxuICB2YXIgbWF5YmVSb290ID0gY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXI7XG4gIHZhciByb290O1xuXG4gIGlmICghbWF5YmVSb290KSB7XG4gICAgLy8gSW5pdGlhbCBtb3VudFxuICAgIHJvb3QgPSBsZWdhY3lDcmVhdGVSb290RnJvbURPTUNvbnRhaW5lcihjb250YWluZXIsIGNoaWxkcmVuLCBwYXJlbnRDb21wb25lbnQsIGNhbGxiYWNrLCBmb3JjZUh5ZHJhdGUpO1xuICB9IGVsc2Uge1xuICAgIHJvb3QgPSBtYXliZVJvb3Q7XG5cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgb3JpZ2luYWxDYWxsYmFjayA9IGNhbGxiYWNrO1xuXG4gICAgICBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGluc3RhbmNlID0gZ2V0UHVibGljUm9vdEluc3RhbmNlKHJvb3QpO1xuICAgICAgICBvcmlnaW5hbENhbGxiYWNrLmNhbGwoaW5zdGFuY2UpO1xuICAgICAgfTtcbiAgICB9IC8vIFVwZGF0ZVxuXG5cbiAgICB1cGRhdGVDb250YWluZXIoY2hpbGRyZW4sIHJvb3QsIHBhcmVudENvbXBvbmVudCwgY2FsbGJhY2spO1xuICB9XG5cbiAgcmV0dXJuIGdldFB1YmxpY1Jvb3RJbnN0YW5jZShyb290KTtcbn1cblxuZnVuY3Rpb24gZmluZERPTU5vZGUoY29tcG9uZW50T3JFbGVtZW50KSB7XG4gIHtcbiAgICB2YXIgb3duZXIgPSBSZWFjdEN1cnJlbnRPd25lciQzLmN1cnJlbnQ7XG5cbiAgICBpZiAob3duZXIgIT09IG51bGwgJiYgb3duZXIuc3RhdGVOb2RlICE9PSBudWxsKSB7XG4gICAgICB2YXIgd2FybmVkQWJvdXRSZWZzSW5SZW5kZXIgPSBvd25lci5zdGF0ZU5vZGUuX3dhcm5lZEFib3V0UmVmc0luUmVuZGVyO1xuXG4gICAgICBpZiAoIXdhcm5lZEFib3V0UmVmc0luUmVuZGVyKSB7XG4gICAgICAgIGVycm9yKCclcyBpcyBhY2Nlc3NpbmcgZmluZERPTU5vZGUgaW5zaWRlIGl0cyByZW5kZXIoKS4gJyArICdyZW5kZXIoKSBzaG91bGQgYmUgYSBwdXJlIGZ1bmN0aW9uIG9mIHByb3BzIGFuZCBzdGF0ZS4gSXQgc2hvdWxkICcgKyAnbmV2ZXIgYWNjZXNzIHNvbWV0aGluZyB0aGF0IHJlcXVpcmVzIHN0YWxlIGRhdGEgZnJvbSB0aGUgcHJldmlvdXMgJyArICdyZW5kZXIsIHN1Y2ggYXMgcmVmcy4gTW92ZSB0aGlzIGxvZ2ljIHRvIGNvbXBvbmVudERpZE1vdW50IGFuZCAnICsgJ2NvbXBvbmVudERpZFVwZGF0ZSBpbnN0ZWFkLicsIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShvd25lci50eXBlKSB8fCAnQSBjb21wb25lbnQnKTtcbiAgICAgIH1cblxuICAgICAgb3duZXIuc3RhdGVOb2RlLl93YXJuZWRBYm91dFJlZnNJblJlbmRlciA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNvbXBvbmVudE9yRWxlbWVudCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoY29tcG9uZW50T3JFbGVtZW50Lm5vZGVUeXBlID09PSBFTEVNRU5UX05PREUpIHtcbiAgICByZXR1cm4gY29tcG9uZW50T3JFbGVtZW50O1xuICB9XG5cbiAge1xuICAgIHJldHVybiBmaW5kSG9zdEluc3RhbmNlV2l0aFdhcm5pbmcoY29tcG9uZW50T3JFbGVtZW50LCAnZmluZERPTU5vZGUnKTtcbiAgfVxufVxuZnVuY3Rpb24gaHlkcmF0ZShlbGVtZW50LCBjb250YWluZXIsIGNhbGxiYWNrKSB7XG4gIHtcbiAgICBlcnJvcignUmVhY3RET00uaHlkcmF0ZSBpcyBubyBsb25nZXIgc3VwcG9ydGVkIGluIFJlYWN0IDE4LiBVc2UgaHlkcmF0ZVJvb3QgJyArICdpbnN0ZWFkLiBVbnRpbCB5b3Ugc3dpdGNoIHRvIHRoZSBuZXcgQVBJLCB5b3VyIGFwcCB3aWxsIGJlaGF2ZSBhcyAnICsgXCJpZiBpdCdzIHJ1bm5pbmcgUmVhY3QgMTcuIExlYXJuIFwiICsgJ21vcmU6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zd2l0Y2gtdG8tY3JlYXRlcm9vdCcpO1xuICB9XG5cbiAgaWYgKCFpc1ZhbGlkQ29udGFpbmVyTGVnYWN5KGNvbnRhaW5lcikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RhcmdldCBjb250YWluZXIgaXMgbm90IGEgRE9NIGVsZW1lbnQuJyk7XG4gIH1cblxuICB7XG4gICAgdmFyIGlzTW9kZXJuUm9vdCA9IGlzQ29udGFpbmVyTWFya2VkQXNSb290KGNvbnRhaW5lcikgJiYgY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIgPT09IHVuZGVmaW5lZDtcblxuICAgIGlmIChpc01vZGVyblJvb3QpIHtcbiAgICAgIGVycm9yKCdZb3UgYXJlIGNhbGxpbmcgUmVhY3RET00uaHlkcmF0ZSgpIG9uIGEgY29udGFpbmVyIHRoYXQgd2FzIHByZXZpb3VzbHkgJyArICdwYXNzZWQgdG8gUmVhY3RET01DbGllbnQuY3JlYXRlUm9vdCgpLiBUaGlzIGlzIG5vdCBzdXBwb3J0ZWQuICcgKyAnRGlkIHlvdSBtZWFuIHRvIGNhbGwgaHlkcmF0ZVJvb3QoY29udGFpbmVyLCBlbGVtZW50KT8nKTtcbiAgICB9XG4gIH0gLy8gVE9ETzogdGhyb3cgb3Igd2FybiBpZiB3ZSBjb3VsZG4ndCBoeWRyYXRlP1xuXG5cbiAgcmV0dXJuIGxlZ2FjeVJlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyKG51bGwsIGVsZW1lbnQsIGNvbnRhaW5lciwgdHJ1ZSwgY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gcmVuZGVyKGVsZW1lbnQsIGNvbnRhaW5lciwgY2FsbGJhY2spIHtcbiAge1xuICAgIGVycm9yKCdSZWFjdERPTS5yZW5kZXIgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCBpbiBSZWFjdCAxOC4gVXNlIGNyZWF0ZVJvb3QgJyArICdpbnN0ZWFkLiBVbnRpbCB5b3Ugc3dpdGNoIHRvIHRoZSBuZXcgQVBJLCB5b3VyIGFwcCB3aWxsIGJlaGF2ZSBhcyAnICsgXCJpZiBpdCdzIHJ1bm5pbmcgUmVhY3QgMTcuIExlYXJuIFwiICsgJ21vcmU6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zd2l0Y2gtdG8tY3JlYXRlcm9vdCcpO1xuICB9XG5cbiAgaWYgKCFpc1ZhbGlkQ29udGFpbmVyTGVnYWN5KGNvbnRhaW5lcikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RhcmdldCBjb250YWluZXIgaXMgbm90IGEgRE9NIGVsZW1lbnQuJyk7XG4gIH1cblxuICB7XG4gICAgdmFyIGlzTW9kZXJuUm9vdCA9IGlzQ29udGFpbmVyTWFya2VkQXNSb290KGNvbnRhaW5lcikgJiYgY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIgPT09IHVuZGVmaW5lZDtcblxuICAgIGlmIChpc01vZGVyblJvb3QpIHtcbiAgICAgIGVycm9yKCdZb3UgYXJlIGNhbGxpbmcgUmVhY3RET00ucmVuZGVyKCkgb24gYSBjb250YWluZXIgdGhhdCB3YXMgcHJldmlvdXNseSAnICsgJ3Bhc3NlZCB0byBSZWFjdERPTUNsaWVudC5jcmVhdGVSb290KCkuIFRoaXMgaXMgbm90IHN1cHBvcnRlZC4gJyArICdEaWQgeW91IG1lYW4gdG8gY2FsbCByb290LnJlbmRlcihlbGVtZW50KT8nKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbGVnYWN5UmVuZGVyU3VidHJlZUludG9Db250YWluZXIobnVsbCwgZWxlbWVudCwgY29udGFpbmVyLCBmYWxzZSwgY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gdW5zdGFibGVfcmVuZGVyU3VidHJlZUludG9Db250YWluZXIocGFyZW50Q29tcG9uZW50LCBlbGVtZW50LCBjb250YWluZXJOb2RlLCBjYWxsYmFjaykge1xuICB7XG4gICAgZXJyb3IoJ1JlYWN0RE9NLnVuc3RhYmxlX3JlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyKCkgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCAnICsgJ2luIFJlYWN0IDE4LiBDb25zaWRlciB1c2luZyBhIHBvcnRhbCBpbnN0ZWFkLiBVbnRpbCB5b3Ugc3dpdGNoIHRvICcgKyBcInRoZSBjcmVhdGVSb290IEFQSSwgeW91ciBhcHAgd2lsbCBiZWhhdmUgYXMgaWYgaXQncyBydW5uaW5nIFJlYWN0IFwiICsgJzE3LiBMZWFybiBtb3JlOiBodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3dpdGNoLXRvLWNyZWF0ZXJvb3QnKTtcbiAgfVxuXG4gIGlmICghaXNWYWxpZENvbnRhaW5lckxlZ2FjeShjb250YWluZXJOb2RlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVGFyZ2V0IGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudC4nKTtcbiAgfVxuXG4gIGlmIChwYXJlbnRDb21wb25lbnQgPT0gbnVsbCB8fCAhaGFzKHBhcmVudENvbXBvbmVudCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhcmVudENvbXBvbmVudCBtdXN0IGJlIGEgdmFsaWQgUmVhY3QgQ29tcG9uZW50Jyk7XG4gIH1cblxuICByZXR1cm4gbGVnYWN5UmVuZGVyU3VidHJlZUludG9Db250YWluZXIocGFyZW50Q29tcG9uZW50LCBlbGVtZW50LCBjb250YWluZXJOb2RlLCBmYWxzZSwgY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gdW5tb3VudENvbXBvbmVudEF0Tm9kZShjb250YWluZXIpIHtcbiAgaWYgKCFpc1ZhbGlkQ29udGFpbmVyTGVnYWN5KGNvbnRhaW5lcikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VubW91bnRDb21wb25lbnRBdE5vZGUoLi4uKTogVGFyZ2V0IGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudC4nKTtcbiAgfVxuXG4gIHtcbiAgICB2YXIgaXNNb2Rlcm5Sb290ID0gaXNDb250YWluZXJNYXJrZWRBc1Jvb3QoY29udGFpbmVyKSAmJiBjb250YWluZXIuX3JlYWN0Um9vdENvbnRhaW5lciA9PT0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKGlzTW9kZXJuUm9vdCkge1xuICAgICAgZXJyb3IoJ1lvdSBhcmUgY2FsbGluZyBSZWFjdERPTS51bm1vdW50Q29tcG9uZW50QXROb2RlKCkgb24gYSBjb250YWluZXIgdGhhdCB3YXMgcHJldmlvdXNseSAnICsgJ3Bhc3NlZCB0byBSZWFjdERPTUNsaWVudC5jcmVhdGVSb290KCkuIFRoaXMgaXMgbm90IHN1cHBvcnRlZC4gRGlkIHlvdSBtZWFuIHRvIGNhbGwgcm9vdC51bm1vdW50KCk/Jyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyKSB7XG4gICAge1xuICAgICAgdmFyIHJvb3RFbCA9IGdldFJlYWN0Um9vdEVsZW1lbnRJbkNvbnRhaW5lcihjb250YWluZXIpO1xuICAgICAgdmFyIHJlbmRlcmVkQnlEaWZmZXJlbnRSZWFjdCA9IHJvb3RFbCAmJiAhZ2V0SW5zdGFuY2VGcm9tTm9kZShyb290RWwpO1xuXG4gICAgICBpZiAocmVuZGVyZWRCeURpZmZlcmVudFJlYWN0KSB7XG4gICAgICAgIGVycm9yKFwidW5tb3VudENvbXBvbmVudEF0Tm9kZSgpOiBUaGUgbm9kZSB5b3UncmUgYXR0ZW1wdGluZyB0byB1bm1vdW50IFwiICsgJ3dhcyByZW5kZXJlZCBieSBhbm90aGVyIGNvcHkgb2YgUmVhY3QuJyk7XG4gICAgICB9XG4gICAgfSAvLyBVbm1vdW50IHNob3VsZCBub3QgYmUgYmF0Y2hlZC5cblxuXG4gICAgZmx1c2hTeW5jKGZ1bmN0aW9uICgpIHtcbiAgICAgIGxlZ2FjeVJlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyKG51bGwsIG51bGwsIGNvbnRhaW5lciwgZmFsc2UsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gJEZsb3dGaXhNZSBUaGlzIHNob3VsZCBwcm9iYWJseSB1c2UgYGRlbGV0ZSBjb250YWluZXIuX3JlYWN0Um9vdENvbnRhaW5lcmBcbiAgICAgICAgY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIgPSBudWxsO1xuICAgICAgICB1bm1hcmtDb250YWluZXJBc1Jvb3QoY29udGFpbmVyKTtcbiAgICAgIH0pO1xuICAgIH0pOyAvLyBJZiB5b3UgY2FsbCB1bm1vdW50Q29tcG9uZW50QXROb2RlIHR3aWNlIGluIHF1aWNrIHN1Y2Nlc3Npb24sIHlvdSdsbFxuICAgIC8vIGdldCBgdHJ1ZWAgdHdpY2UuIFRoYXQncyBwcm9iYWJseSBmaW5lP1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSB7XG4gICAge1xuICAgICAgdmFyIF9yb290RWwgPSBnZXRSZWFjdFJvb3RFbGVtZW50SW5Db250YWluZXIoY29udGFpbmVyKTtcblxuICAgICAgdmFyIGhhc05vblJvb3RSZWFjdENoaWxkID0gISEoX3Jvb3RFbCAmJiBnZXRJbnN0YW5jZUZyb21Ob2RlKF9yb290RWwpKTsgLy8gQ2hlY2sgaWYgdGhlIGNvbnRhaW5lciBpdHNlbGYgaXMgYSBSZWFjdCByb290IG5vZGUuXG5cbiAgICAgIHZhciBpc0NvbnRhaW5lclJlYWN0Um9vdCA9IGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFICYmIGlzVmFsaWRDb250YWluZXJMZWdhY3koY29udGFpbmVyLnBhcmVudE5vZGUpICYmICEhY29udGFpbmVyLnBhcmVudE5vZGUuX3JlYWN0Um9vdENvbnRhaW5lcjtcblxuICAgICAgaWYgKGhhc05vblJvb3RSZWFjdENoaWxkKSB7XG4gICAgICAgIGVycm9yKFwidW5tb3VudENvbXBvbmVudEF0Tm9kZSgpOiBUaGUgbm9kZSB5b3UncmUgYXR0ZW1wdGluZyB0byB1bm1vdW50IFwiICsgJ3dhcyByZW5kZXJlZCBieSBSZWFjdCBhbmQgaXMgbm90IGEgdG9wLWxldmVsIGNvbnRhaW5lci4gJXMnLCBpc0NvbnRhaW5lclJlYWN0Um9vdCA/ICdZb3UgbWF5IGhhdmUgYWNjaWRlbnRhbGx5IHBhc3NlZCBpbiBhIFJlYWN0IHJvb3Qgbm9kZSBpbnN0ZWFkICcgKyAnb2YgaXRzIGNvbnRhaW5lci4nIDogJ0luc3RlYWQsIGhhdmUgdGhlIHBhcmVudCBjb21wb25lbnQgdXBkYXRlIGl0cyBzdGF0ZSBhbmQgJyArICdyZXJlbmRlciBpbiBvcmRlciB0byByZW1vdmUgdGhpcyBjb21wb25lbnQuJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbnNldEF0dGVtcHRTeW5jaHJvbm91c0h5ZHJhdGlvbihhdHRlbXB0U3luY2hyb25vdXNIeWRyYXRpb24kMSk7XG5zZXRBdHRlbXB0Q29udGludW91c0h5ZHJhdGlvbihhdHRlbXB0Q29udGludW91c0h5ZHJhdGlvbiQxKTtcbnNldEF0dGVtcHRIeWRyYXRpb25BdEN1cnJlbnRQcmlvcml0eShhdHRlbXB0SHlkcmF0aW9uQXRDdXJyZW50UHJpb3JpdHkkMSk7XG5zZXRHZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KTtcbnNldEF0dGVtcHRIeWRyYXRpb25BdFByaW9yaXR5KHJ1bldpdGhQcmlvcml0eSk7XG5cbntcbiAgaWYgKHR5cGVvZiBNYXAgIT09ICdmdW5jdGlvbicgfHwgLy8gJEZsb3dJc3N1ZSBGbG93IGluY29ycmVjdGx5IHRoaW5rcyBNYXAgaGFzIG5vIHByb3RvdHlwZVxuICBNYXAucHJvdG90eXBlID09IG51bGwgfHwgdHlwZW9mIE1hcC5wcm90b3R5cGUuZm9yRWFjaCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgU2V0ICE9PSAnZnVuY3Rpb24nIHx8IC8vICRGbG93SXNzdWUgRmxvdyBpbmNvcnJlY3RseSB0aGlua3MgU2V0IGhhcyBubyBwcm90b3R5cGVcbiAgU2V0LnByb3RvdHlwZSA9PSBudWxsIHx8IHR5cGVvZiBTZXQucHJvdG90eXBlLmNsZWFyICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBTZXQucHJvdG90eXBlLmZvckVhY2ggIT09ICdmdW5jdGlvbicpIHtcbiAgICBlcnJvcignUmVhY3QgZGVwZW5kcyBvbiBNYXAgYW5kIFNldCBidWlsdC1pbiB0eXBlcy4gTWFrZSBzdXJlIHRoYXQgeW91IGxvYWQgYSAnICsgJ3BvbHlmaWxsIGluIG9sZGVyIGJyb3dzZXJzLiBodHRwczovL3JlYWN0anMub3JnL2xpbmsvcmVhY3QtcG9seWZpbGxzJyk7XG4gIH1cbn1cblxuc2V0UmVzdG9yZUltcGxlbWVudGF0aW9uKHJlc3RvcmVDb250cm9sbGVkU3RhdGUkMyk7XG5zZXRCYXRjaGluZ0ltcGxlbWVudGF0aW9uKGJhdGNoZWRVcGRhdGVzJDEsIGRpc2NyZXRlVXBkYXRlcywgZmx1c2hTeW5jKTtcblxuZnVuY3Rpb24gY3JlYXRlUG9ydGFsJDEoY2hpbGRyZW4sIGNvbnRhaW5lcikge1xuICB2YXIga2V5ID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiBudWxsO1xuXG4gIGlmICghaXNWYWxpZENvbnRhaW5lcihjb250YWluZXIpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUYXJnZXQgY29udGFpbmVyIGlzIG5vdCBhIERPTSBlbGVtZW50LicpO1xuICB9IC8vIFRPRE86IHBhc3MgUmVhY3RET00gcG9ydGFsIGltcGxlbWVudGF0aW9uIGFzIHRoaXJkIGFyZ3VtZW50XG4gIC8vICRGbG93Rml4TWUgVGhlIEZsb3cgdHlwZSBpcyBvcGFxdWUgYnV0IHRoZXJlJ3Mgbm8gd2F5IHRvIGFjdHVhbGx5IGNyZWF0ZSBpdC5cblxuXG4gIHJldHVybiBjcmVhdGVQb3J0YWwoY2hpbGRyZW4sIGNvbnRhaW5lciwgbnVsbCwga2V5KTtcbn1cblxuZnVuY3Rpb24gcmVuZGVyU3VidHJlZUludG9Db250YWluZXIocGFyZW50Q29tcG9uZW50LCBlbGVtZW50LCBjb250YWluZXJOb2RlLCBjYWxsYmFjaykge1xuICByZXR1cm4gdW5zdGFibGVfcmVuZGVyU3VidHJlZUludG9Db250YWluZXIocGFyZW50Q29tcG9uZW50LCBlbGVtZW50LCBjb250YWluZXJOb2RlLCBjYWxsYmFjayk7XG59XG5cbnZhciBJbnRlcm5hbHMgPSB7XG4gIHVzaW5nQ2xpZW50RW50cnlQb2ludDogZmFsc2UsXG4gIC8vIEtlZXAgaW4gc3luYyB3aXRoIFJlYWN0VGVzdFV0aWxzLmpzLlxuICAvLyBUaGlzIGlzIGFuIGFycmF5IGZvciBiZXR0ZXIgbWluaWZpY2F0aW9uLlxuICBFdmVudHM6IFtnZXRJbnN0YW5jZUZyb21Ob2RlLCBnZXROb2RlRnJvbUluc3RhbmNlLCBnZXRGaWJlckN1cnJlbnRQcm9wc0Zyb21Ob2RlLCBlbnF1ZXVlU3RhdGVSZXN0b3JlLCByZXN0b3JlU3RhdGVJZk5lZWRlZCwgYmF0Y2hlZFVwZGF0ZXMkMV1cbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZVJvb3QkMShjb250YWluZXIsIG9wdGlvbnMpIHtcbiAge1xuICAgIGlmICghSW50ZXJuYWxzLnVzaW5nQ2xpZW50RW50cnlQb2ludCAmJiAhZmFsc2UpIHtcbiAgICAgIGVycm9yKCdZb3UgYXJlIGltcG9ydGluZyBjcmVhdGVSb290IGZyb20gXCJyZWFjdC1kb21cIiB3aGljaCBpcyBub3Qgc3VwcG9ydGVkLiAnICsgJ1lvdSBzaG91bGQgaW5zdGVhZCBpbXBvcnQgaXQgZnJvbSBcInJlYWN0LWRvbS9jbGllbnRcIi4nKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY3JlYXRlUm9vdChjb250YWluZXIsIG9wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBoeWRyYXRlUm9vdCQxKGNvbnRhaW5lciwgaW5pdGlhbENoaWxkcmVuLCBvcHRpb25zKSB7XG4gIHtcbiAgICBpZiAoIUludGVybmFscy51c2luZ0NsaWVudEVudHJ5UG9pbnQgJiYgIWZhbHNlKSB7XG4gICAgICBlcnJvcignWW91IGFyZSBpbXBvcnRpbmcgaHlkcmF0ZVJvb3QgZnJvbSBcInJlYWN0LWRvbVwiIHdoaWNoIGlzIG5vdCBzdXBwb3J0ZWQuICcgKyAnWW91IHNob3VsZCBpbnN0ZWFkIGltcG9ydCBpdCBmcm9tIFwicmVhY3QtZG9tL2NsaWVudFwiLicpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBoeWRyYXRlUm9vdChjb250YWluZXIsIGluaXRpYWxDaGlsZHJlbiwgb3B0aW9ucyk7XG59IC8vIE92ZXJsb2FkIHRoZSBkZWZpbml0aW9uIHRvIHRoZSB0d28gdmFsaWQgc2lnbmF0dXJlcy5cbi8vIFdhcm5pbmcsIHRoaXMgb3B0cy1vdXQgb2YgY2hlY2tpbmcgdGhlIGZ1bmN0aW9uIGJvZHkuXG5cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlZGVjbGFyZVxuZnVuY3Rpb24gZmx1c2hTeW5jJDEoZm4pIHtcbiAge1xuICAgIGlmIChpc0FscmVhZHlSZW5kZXJpbmcoKSkge1xuICAgICAgZXJyb3IoJ2ZsdXNoU3luYyB3YXMgY2FsbGVkIGZyb20gaW5zaWRlIGEgbGlmZWN5Y2xlIG1ldGhvZC4gUmVhY3QgY2Fubm90ICcgKyAnZmx1c2ggd2hlbiBSZWFjdCBpcyBhbHJlYWR5IHJlbmRlcmluZy4gQ29uc2lkZXIgbW92aW5nIHRoaXMgY2FsbCB0byAnICsgJ2Egc2NoZWR1bGVyIHRhc2sgb3IgbWljcm8gdGFzay4nKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmx1c2hTeW5jKGZuKTtcbn1cbnZhciBmb3VuZERldlRvb2xzID0gaW5qZWN0SW50b0RldlRvb2xzKHtcbiAgZmluZEZpYmVyQnlIb3N0SW5zdGFuY2U6IGdldENsb3Nlc3RJbnN0YW5jZUZyb21Ob2RlLFxuICBidW5kbGVUeXBlOiAgMSAsXG4gIHZlcnNpb246IFJlYWN0VmVyc2lvbixcbiAgcmVuZGVyZXJQYWNrYWdlTmFtZTogJ3JlYWN0LWRvbSdcbn0pO1xuXG57XG4gIGlmICghZm91bmREZXZUb29scyAmJiBjYW5Vc2VET00gJiYgd2luZG93LnRvcCA9PT0gd2luZG93LnNlbGYpIHtcbiAgICAvLyBJZiB3ZSdyZSBpbiBDaHJvbWUgb3IgRmlyZWZveCwgcHJvdmlkZSBhIGRvd25sb2FkIGxpbmsgaWYgbm90IGluc3RhbGxlZC5cbiAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdDaHJvbWUnKSA+IC0xICYmIG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignRWRnZScpID09PSAtMSB8fCBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ0ZpcmVmb3gnKSA+IC0xKSB7XG4gICAgICB2YXIgcHJvdG9jb2wgPSB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2w7IC8vIERvbid0IHdhcm4gaW4gZXhvdGljIGNhc2VzIGxpa2UgY2hyb21lLWV4dGVuc2lvbjovLy5cblxuICAgICAgaWYgKC9eKGh0dHBzP3xmaWxlKTokLy50ZXN0KHByb3RvY29sKSkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nXG4gICAgICAgIGNvbnNvbGUuaW5mbygnJWNEb3dubG9hZCB0aGUgUmVhY3QgRGV2VG9vbHMgJyArICdmb3IgYSBiZXR0ZXIgZGV2ZWxvcG1lbnQgZXhwZXJpZW5jZTogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvcmVhY3QtZGV2dG9vbHMnICsgKHByb3RvY29sID09PSAnZmlsZTonID8gJ1xcbllvdSBtaWdodCBuZWVkIHRvIHVzZSBhIGxvY2FsIEhUVFAgc2VydmVyIChpbnN0ZWFkIG9mIGZpbGU6Ly8pOiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9yZWFjdC1kZXZ0b29scy1mYXEnIDogJycpLCAnZm9udC13ZWlnaHQ6Ym9sZCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnRzLl9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVEID0gSW50ZXJuYWxzO1xuZXhwb3J0cy5jcmVhdGVQb3J0YWwgPSBjcmVhdGVQb3J0YWwkMTtcbmV4cG9ydHMuY3JlYXRlUm9vdCA9IGNyZWF0ZVJvb3QkMTtcbmV4cG9ydHMuZmluZERPTU5vZGUgPSBmaW5kRE9NTm9kZTtcbmV4cG9ydHMuZmx1c2hTeW5jID0gZmx1c2hTeW5jJDE7XG5leHBvcnRzLmh5ZHJhdGUgPSBoeWRyYXRlO1xuZXhwb3J0cy5oeWRyYXRlUm9vdCA9IGh5ZHJhdGVSb290JDE7XG5leHBvcnRzLnJlbmRlciA9IHJlbmRlcjtcbmV4cG9ydHMudW5tb3VudENvbXBvbmVudEF0Tm9kZSA9IHVubW91bnRDb21wb25lbnRBdE5vZGU7XG5leHBvcnRzLnVuc3RhYmxlX2JhdGNoZWRVcGRhdGVzID0gYmF0Y2hlZFVwZGF0ZXMkMTtcbmV4cG9ydHMudW5zdGFibGVfcmVuZGVyU3VidHJlZUludG9Db250YWluZXIgPSByZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lcjtcbmV4cG9ydHMudmVyc2lvbiA9IFJlYWN0VmVyc2lvbjtcbiAgICAgICAgICAvKiBnbG9iYWwgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fICovXG5pZiAoXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gIT09ICd1bmRlZmluZWQnICYmXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18ucmVnaXN0ZXJJbnRlcm5hbE1vZHVsZVN0b3AgPT09XG4gICAgJ2Z1bmN0aW9uJ1xuKSB7XG4gIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RvcChuZXcgRXJyb3IoKSk7XG59XG4gICAgICAgIFxuICB9KSgpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykge1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vY2pzL3NjaGVkdWxlci5wcm9kdWN0aW9uLm1pbi5qcycpO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9zY2hlZHVsZXIuZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiIsIi8qKlxuICogQGxpY2Vuc2UgUmVhY3RcbiAqIHNjaGVkdWxlci5kZXZlbG9wbWVudC5qc1xuICpcbiAqIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgICAndXNlIHN0cmljdCc7XG5cbi8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbmlmIChcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RhcnQgPT09XG4gICAgJ2Z1bmN0aW9uJ1xuKSB7XG4gIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RhcnQobmV3IEVycm9yKCkpO1xufVxuICAgICAgICAgIHZhciBlbmFibGVTY2hlZHVsZXJEZWJ1Z2dpbmcgPSBmYWxzZTtcbnZhciBlbmFibGVQcm9maWxpbmcgPSBmYWxzZTtcbnZhciBmcmFtZVlpZWxkTXMgPSA1O1xuXG5mdW5jdGlvbiBwdXNoKGhlYXAsIG5vZGUpIHtcbiAgdmFyIGluZGV4ID0gaGVhcC5sZW5ndGg7XG4gIGhlYXAucHVzaChub2RlKTtcbiAgc2lmdFVwKGhlYXAsIG5vZGUsIGluZGV4KTtcbn1cbmZ1bmN0aW9uIHBlZWsoaGVhcCkge1xuICByZXR1cm4gaGVhcC5sZW5ndGggPT09IDAgPyBudWxsIDogaGVhcFswXTtcbn1cbmZ1bmN0aW9uIHBvcChoZWFwKSB7XG4gIGlmIChoZWFwLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIGZpcnN0ID0gaGVhcFswXTtcbiAgdmFyIGxhc3QgPSBoZWFwLnBvcCgpO1xuXG4gIGlmIChsYXN0ICE9PSBmaXJzdCkge1xuICAgIGhlYXBbMF0gPSBsYXN0O1xuICAgIHNpZnREb3duKGhlYXAsIGxhc3QsIDApO1xuICB9XG5cbiAgcmV0dXJuIGZpcnN0O1xufVxuXG5mdW5jdGlvbiBzaWZ0VXAoaGVhcCwgbm9kZSwgaSkge1xuICB2YXIgaW5kZXggPSBpO1xuXG4gIHdoaWxlIChpbmRleCA+IDApIHtcbiAgICB2YXIgcGFyZW50SW5kZXggPSBpbmRleCAtIDEgPj4+IDE7XG4gICAgdmFyIHBhcmVudCA9IGhlYXBbcGFyZW50SW5kZXhdO1xuXG4gICAgaWYgKGNvbXBhcmUocGFyZW50LCBub2RlKSA+IDApIHtcbiAgICAgIC8vIFRoZSBwYXJlbnQgaXMgbGFyZ2VyLiBTd2FwIHBvc2l0aW9ucy5cbiAgICAgIGhlYXBbcGFyZW50SW5kZXhdID0gbm9kZTtcbiAgICAgIGhlYXBbaW5kZXhdID0gcGFyZW50O1xuICAgICAgaW5kZXggPSBwYXJlbnRJbmRleDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhlIHBhcmVudCBpcyBzbWFsbGVyLiBFeGl0LlxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzaWZ0RG93bihoZWFwLCBub2RlLCBpKSB7XG4gIHZhciBpbmRleCA9IGk7XG4gIHZhciBsZW5ndGggPSBoZWFwLmxlbmd0aDtcbiAgdmFyIGhhbGZMZW5ndGggPSBsZW5ndGggPj4+IDE7XG5cbiAgd2hpbGUgKGluZGV4IDwgaGFsZkxlbmd0aCkge1xuICAgIHZhciBsZWZ0SW5kZXggPSAoaW5kZXggKyAxKSAqIDIgLSAxO1xuICAgIHZhciBsZWZ0ID0gaGVhcFtsZWZ0SW5kZXhdO1xuICAgIHZhciByaWdodEluZGV4ID0gbGVmdEluZGV4ICsgMTtcbiAgICB2YXIgcmlnaHQgPSBoZWFwW3JpZ2h0SW5kZXhdOyAvLyBJZiB0aGUgbGVmdCBvciByaWdodCBub2RlIGlzIHNtYWxsZXIsIHN3YXAgd2l0aCB0aGUgc21hbGxlciBvZiB0aG9zZS5cblxuICAgIGlmIChjb21wYXJlKGxlZnQsIG5vZGUpIDwgMCkge1xuICAgICAgaWYgKHJpZ2h0SW5kZXggPCBsZW5ndGggJiYgY29tcGFyZShyaWdodCwgbGVmdCkgPCAwKSB7XG4gICAgICAgIGhlYXBbaW5kZXhdID0gcmlnaHQ7XG4gICAgICAgIGhlYXBbcmlnaHRJbmRleF0gPSBub2RlO1xuICAgICAgICBpbmRleCA9IHJpZ2h0SW5kZXg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoZWFwW2luZGV4XSA9IGxlZnQ7XG4gICAgICAgIGhlYXBbbGVmdEluZGV4XSA9IG5vZGU7XG4gICAgICAgIGluZGV4ID0gbGVmdEluZGV4O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocmlnaHRJbmRleCA8IGxlbmd0aCAmJiBjb21wYXJlKHJpZ2h0LCBub2RlKSA8IDApIHtcbiAgICAgIGhlYXBbaW5kZXhdID0gcmlnaHQ7XG4gICAgICBoZWFwW3JpZ2h0SW5kZXhdID0gbm9kZTtcbiAgICAgIGluZGV4ID0gcmlnaHRJbmRleDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTmVpdGhlciBjaGlsZCBpcyBzbWFsbGVyLiBFeGl0LlxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21wYXJlKGEsIGIpIHtcbiAgLy8gQ29tcGFyZSBzb3J0IGluZGV4IGZpcnN0LCB0aGVuIHRhc2sgaWQuXG4gIHZhciBkaWZmID0gYS5zb3J0SW5kZXggLSBiLnNvcnRJbmRleDtcbiAgcmV0dXJuIGRpZmYgIT09IDAgPyBkaWZmIDogYS5pZCAtIGIuaWQ7XG59XG5cbi8vIFRPRE86IFVzZSBzeW1ib2xzP1xudmFyIEltbWVkaWF0ZVByaW9yaXR5ID0gMTtcbnZhciBVc2VyQmxvY2tpbmdQcmlvcml0eSA9IDI7XG52YXIgTm9ybWFsUHJpb3JpdHkgPSAzO1xudmFyIExvd1ByaW9yaXR5ID0gNDtcbnZhciBJZGxlUHJpb3JpdHkgPSA1O1xuXG5mdW5jdGlvbiBtYXJrVGFza0Vycm9yZWQodGFzaywgbXMpIHtcbn1cblxuLyogZXNsaW50LWRpc2FibGUgbm8tdmFyICovXG5cbnZhciBoYXNQZXJmb3JtYW5jZU5vdyA9IHR5cGVvZiBwZXJmb3JtYW5jZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHBlcmZvcm1hbmNlLm5vdyA9PT0gJ2Z1bmN0aW9uJztcblxuaWYgKGhhc1BlcmZvcm1hbmNlTm93KSB7XG4gIHZhciBsb2NhbFBlcmZvcm1hbmNlID0gcGVyZm9ybWFuY2U7XG5cbiAgZXhwb3J0cy51bnN0YWJsZV9ub3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGxvY2FsUGVyZm9ybWFuY2Uubm93KCk7XG4gIH07XG59IGVsc2Uge1xuICB2YXIgbG9jYWxEYXRlID0gRGF0ZTtcbiAgdmFyIGluaXRpYWxUaW1lID0gbG9jYWxEYXRlLm5vdygpO1xuXG4gIGV4cG9ydHMudW5zdGFibGVfbm93ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBsb2NhbERhdGUubm93KCkgLSBpbml0aWFsVGltZTtcbiAgfTtcbn0gLy8gTWF4IDMxIGJpdCBpbnRlZ2VyLiBUaGUgbWF4IGludGVnZXIgc2l6ZSBpbiBWOCBmb3IgMzItYml0IHN5c3RlbXMuXG4vLyBNYXRoLnBvdygyLCAzMCkgLSAxXG4vLyAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMTExMVxuXG5cbnZhciBtYXhTaWduZWQzMUJpdEludCA9IDEwNzM3NDE4MjM7IC8vIFRpbWVzIG91dCBpbW1lZGlhdGVseVxuXG52YXIgSU1NRURJQVRFX1BSSU9SSVRZX1RJTUVPVVQgPSAtMTsgLy8gRXZlbnR1YWxseSB0aW1lcyBvdXRcblxudmFyIFVTRVJfQkxPQ0tJTkdfUFJJT1JJVFlfVElNRU9VVCA9IDI1MDtcbnZhciBOT1JNQUxfUFJJT1JJVFlfVElNRU9VVCA9IDUwMDA7XG52YXIgTE9XX1BSSU9SSVRZX1RJTUVPVVQgPSAxMDAwMDsgLy8gTmV2ZXIgdGltZXMgb3V0XG5cbnZhciBJRExFX1BSSU9SSVRZX1RJTUVPVVQgPSBtYXhTaWduZWQzMUJpdEludDsgLy8gVGFza3MgYXJlIHN0b3JlZCBvbiBhIG1pbiBoZWFwXG5cbnZhciB0YXNrUXVldWUgPSBbXTtcbnZhciB0aW1lclF1ZXVlID0gW107IC8vIEluY3JlbWVudGluZyBpZCBjb3VudGVyLiBVc2VkIHRvIG1haW50YWluIGluc2VydGlvbiBvcmRlci5cblxudmFyIHRhc2tJZENvdW50ZXIgPSAxOyAvLyBQYXVzaW5nIHRoZSBzY2hlZHVsZXIgaXMgdXNlZnVsIGZvciBkZWJ1Z2dpbmcuXG52YXIgY3VycmVudFRhc2sgPSBudWxsO1xudmFyIGN1cnJlbnRQcmlvcml0eUxldmVsID0gTm9ybWFsUHJpb3JpdHk7IC8vIFRoaXMgaXMgc2V0IHdoaWxlIHBlcmZvcm1pbmcgd29yaywgdG8gcHJldmVudCByZS1lbnRyYW5jZS5cblxudmFyIGlzUGVyZm9ybWluZ1dvcmsgPSBmYWxzZTtcbnZhciBpc0hvc3RDYWxsYmFja1NjaGVkdWxlZCA9IGZhbHNlO1xudmFyIGlzSG9zdFRpbWVvdXRTY2hlZHVsZWQgPSBmYWxzZTsgLy8gQ2FwdHVyZSBsb2NhbCByZWZlcmVuY2VzIHRvIG5hdGl2ZSBBUElzLCBpbiBjYXNlIGEgcG9seWZpbGwgb3ZlcnJpZGVzIHRoZW0uXG5cbnZhciBsb2NhbFNldFRpbWVvdXQgPSB0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJyA/IHNldFRpbWVvdXQgOiBudWxsO1xudmFyIGxvY2FsQ2xlYXJUaW1lb3V0ID0gdHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJyA/IGNsZWFyVGltZW91dCA6IG51bGw7XG52YXIgbG9jYWxTZXRJbW1lZGlhdGUgPSB0eXBlb2Ygc2V0SW1tZWRpYXRlICE9PSAndW5kZWZpbmVkJyA/IHNldEltbWVkaWF0ZSA6IG51bGw7IC8vIElFIGFuZCBOb2RlLmpzICsganNkb21cblxudmFyIGlzSW5wdXRQZW5kaW5nID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgbmF2aWdhdG9yLnNjaGVkdWxpbmcgIT09IHVuZGVmaW5lZCAmJiBuYXZpZ2F0b3Iuc2NoZWR1bGluZy5pc0lucHV0UGVuZGluZyAhPT0gdW5kZWZpbmVkID8gbmF2aWdhdG9yLnNjaGVkdWxpbmcuaXNJbnB1dFBlbmRpbmcuYmluZChuYXZpZ2F0b3Iuc2NoZWR1bGluZykgOiBudWxsO1xuXG5mdW5jdGlvbiBhZHZhbmNlVGltZXJzKGN1cnJlbnRUaW1lKSB7XG4gIC8vIENoZWNrIGZvciB0YXNrcyB0aGF0IGFyZSBubyBsb25nZXIgZGVsYXllZCBhbmQgYWRkIHRoZW0gdG8gdGhlIHF1ZXVlLlxuICB2YXIgdGltZXIgPSBwZWVrKHRpbWVyUXVldWUpO1xuXG4gIHdoaWxlICh0aW1lciAhPT0gbnVsbCkge1xuICAgIGlmICh0aW1lci5jYWxsYmFjayA9PT0gbnVsbCkge1xuICAgICAgLy8gVGltZXIgd2FzIGNhbmNlbGxlZC5cbiAgICAgIHBvcCh0aW1lclF1ZXVlKTtcbiAgICB9IGVsc2UgaWYgKHRpbWVyLnN0YXJ0VGltZSA8PSBjdXJyZW50VGltZSkge1xuICAgICAgLy8gVGltZXIgZmlyZWQuIFRyYW5zZmVyIHRvIHRoZSB0YXNrIHF1ZXVlLlxuICAgICAgcG9wKHRpbWVyUXVldWUpO1xuICAgICAgdGltZXIuc29ydEluZGV4ID0gdGltZXIuZXhwaXJhdGlvblRpbWU7XG4gICAgICBwdXNoKHRhc2tRdWV1ZSwgdGltZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZW1haW5pbmcgdGltZXJzIGFyZSBwZW5kaW5nLlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRpbWVyID0gcGVlayh0aW1lclF1ZXVlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBoYW5kbGVUaW1lb3V0KGN1cnJlbnRUaW1lKSB7XG4gIGlzSG9zdFRpbWVvdXRTY2hlZHVsZWQgPSBmYWxzZTtcbiAgYWR2YW5jZVRpbWVycyhjdXJyZW50VGltZSk7XG5cbiAgaWYgKCFpc0hvc3RDYWxsYmFja1NjaGVkdWxlZCkge1xuICAgIGlmIChwZWVrKHRhc2tRdWV1ZSkgIT09IG51bGwpIHtcbiAgICAgIGlzSG9zdENhbGxiYWNrU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICAgIHJlcXVlc3RIb3N0Q2FsbGJhY2soZmx1c2hXb3JrKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGZpcnN0VGltZXIgPSBwZWVrKHRpbWVyUXVldWUpO1xuXG4gICAgICBpZiAoZmlyc3RUaW1lciAhPT0gbnVsbCkge1xuICAgICAgICByZXF1ZXN0SG9zdFRpbWVvdXQoaGFuZGxlVGltZW91dCwgZmlyc3RUaW1lci5zdGFydFRpbWUgLSBjdXJyZW50VGltZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGZsdXNoV29yayhoYXNUaW1lUmVtYWluaW5nLCBpbml0aWFsVGltZSkge1xuXG5cbiAgaXNIb3N0Q2FsbGJhY2tTY2hlZHVsZWQgPSBmYWxzZTtcblxuICBpZiAoaXNIb3N0VGltZW91dFNjaGVkdWxlZCkge1xuICAgIC8vIFdlIHNjaGVkdWxlZCBhIHRpbWVvdXQgYnV0IGl0J3Mgbm8gbG9uZ2VyIG5lZWRlZC4gQ2FuY2VsIGl0LlxuICAgIGlzSG9zdFRpbWVvdXRTY2hlZHVsZWQgPSBmYWxzZTtcbiAgICBjYW5jZWxIb3N0VGltZW91dCgpO1xuICB9XG5cbiAgaXNQZXJmb3JtaW5nV29yayA9IHRydWU7XG4gIHZhciBwcmV2aW91c1ByaW9yaXR5TGV2ZWwgPSBjdXJyZW50UHJpb3JpdHlMZXZlbDtcblxuICB0cnkge1xuICAgIGlmIChlbmFibGVQcm9maWxpbmcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB3b3JrTG9vcChoYXNUaW1lUmVtYWluaW5nLCBpbml0aWFsVGltZSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoY3VycmVudFRhc2sgIT09IG51bGwpIHtcbiAgICAgICAgICB2YXIgY3VycmVudFRpbWUgPSBleHBvcnRzLnVuc3RhYmxlX25vdygpO1xuICAgICAgICAgIG1hcmtUYXNrRXJyb3JlZChjdXJyZW50VGFzaywgY3VycmVudFRpbWUpO1xuICAgICAgICAgIGN1cnJlbnRUYXNrLmlzUXVldWVkID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTm8gY2F0Y2ggaW4gcHJvZCBjb2RlIHBhdGguXG4gICAgICByZXR1cm4gd29ya0xvb3AoaGFzVGltZVJlbWFpbmluZywgaW5pdGlhbFRpbWUpO1xuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICBjdXJyZW50VGFzayA9IG51bGw7XG4gICAgY3VycmVudFByaW9yaXR5TGV2ZWwgPSBwcmV2aW91c1ByaW9yaXR5TGV2ZWw7XG4gICAgaXNQZXJmb3JtaW5nV29yayA9IGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHdvcmtMb29wKGhhc1RpbWVSZW1haW5pbmcsIGluaXRpYWxUaW1lKSB7XG4gIHZhciBjdXJyZW50VGltZSA9IGluaXRpYWxUaW1lO1xuICBhZHZhbmNlVGltZXJzKGN1cnJlbnRUaW1lKTtcbiAgY3VycmVudFRhc2sgPSBwZWVrKHRhc2tRdWV1ZSk7XG5cbiAgd2hpbGUgKGN1cnJlbnRUYXNrICE9PSBudWxsICYmICEoZW5hYmxlU2NoZWR1bGVyRGVidWdnaW5nICkpIHtcbiAgICBpZiAoY3VycmVudFRhc2suZXhwaXJhdGlvblRpbWUgPiBjdXJyZW50VGltZSAmJiAoIWhhc1RpbWVSZW1haW5pbmcgfHwgc2hvdWxkWWllbGRUb0hvc3QoKSkpIHtcbiAgICAgIC8vIFRoaXMgY3VycmVudFRhc2sgaGFzbid0IGV4cGlyZWQsIGFuZCB3ZSd2ZSByZWFjaGVkIHRoZSBkZWFkbGluZS5cbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHZhciBjYWxsYmFjayA9IGN1cnJlbnRUYXNrLmNhbGxiYWNrO1xuXG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY3VycmVudFRhc2suY2FsbGJhY2sgPSBudWxsO1xuICAgICAgY3VycmVudFByaW9yaXR5TGV2ZWwgPSBjdXJyZW50VGFzay5wcmlvcml0eUxldmVsO1xuICAgICAgdmFyIGRpZFVzZXJDYWxsYmFja1RpbWVvdXQgPSBjdXJyZW50VGFzay5leHBpcmF0aW9uVGltZSA8PSBjdXJyZW50VGltZTtcblxuICAgICAgdmFyIGNvbnRpbnVhdGlvbkNhbGxiYWNrID0gY2FsbGJhY2soZGlkVXNlckNhbGxiYWNrVGltZW91dCk7XG4gICAgICBjdXJyZW50VGltZSA9IGV4cG9ydHMudW5zdGFibGVfbm93KCk7XG5cbiAgICAgIGlmICh0eXBlb2YgY29udGludWF0aW9uQ2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY3VycmVudFRhc2suY2FsbGJhY2sgPSBjb250aW51YXRpb25DYWxsYmFjaztcbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRUYXNrID09PSBwZWVrKHRhc2tRdWV1ZSkpIHtcbiAgICAgICAgICBwb3AodGFza1F1ZXVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhZHZhbmNlVGltZXJzKGN1cnJlbnRUaW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcG9wKHRhc2tRdWV1ZSk7XG4gICAgfVxuXG4gICAgY3VycmVudFRhc2sgPSBwZWVrKHRhc2tRdWV1ZSk7XG4gIH0gLy8gUmV0dXJuIHdoZXRoZXIgdGhlcmUncyBhZGRpdGlvbmFsIHdvcmtcblxuXG4gIGlmIChjdXJyZW50VGFzayAhPT0gbnVsbCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHZhciBmaXJzdFRpbWVyID0gcGVlayh0aW1lclF1ZXVlKTtcblxuICAgIGlmIChmaXJzdFRpbWVyICE9PSBudWxsKSB7XG4gICAgICByZXF1ZXN0SG9zdFRpbWVvdXQoaGFuZGxlVGltZW91dCwgZmlyc3RUaW1lci5zdGFydFRpbWUgLSBjdXJyZW50VGltZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuc3RhYmxlX3J1bldpdGhQcmlvcml0eShwcmlvcml0eUxldmVsLCBldmVudEhhbmRsZXIpIHtcbiAgc3dpdGNoIChwcmlvcml0eUxldmVsKSB7XG4gICAgY2FzZSBJbW1lZGlhdGVQcmlvcml0eTpcbiAgICBjYXNlIFVzZXJCbG9ja2luZ1ByaW9yaXR5OlxuICAgIGNhc2UgTm9ybWFsUHJpb3JpdHk6XG4gICAgY2FzZSBMb3dQcmlvcml0eTpcbiAgICBjYXNlIElkbGVQcmlvcml0eTpcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHByaW9yaXR5TGV2ZWwgPSBOb3JtYWxQcmlvcml0eTtcbiAgfVxuXG4gIHZhciBwcmV2aW91c1ByaW9yaXR5TGV2ZWwgPSBjdXJyZW50UHJpb3JpdHlMZXZlbDtcbiAgY3VycmVudFByaW9yaXR5TGV2ZWwgPSBwcmlvcml0eUxldmVsO1xuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGV2ZW50SGFuZGxlcigpO1xuICB9IGZpbmFsbHkge1xuICAgIGN1cnJlbnRQcmlvcml0eUxldmVsID0gcHJldmlvdXNQcmlvcml0eUxldmVsO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuc3RhYmxlX25leHQoZXZlbnRIYW5kbGVyKSB7XG4gIHZhciBwcmlvcml0eUxldmVsO1xuXG4gIHN3aXRjaCAoY3VycmVudFByaW9yaXR5TGV2ZWwpIHtcbiAgICBjYXNlIEltbWVkaWF0ZVByaW9yaXR5OlxuICAgIGNhc2UgVXNlckJsb2NraW5nUHJpb3JpdHk6XG4gICAgY2FzZSBOb3JtYWxQcmlvcml0eTpcbiAgICAgIC8vIFNoaWZ0IGRvd24gdG8gbm9ybWFsIHByaW9yaXR5XG4gICAgICBwcmlvcml0eUxldmVsID0gTm9ybWFsUHJpb3JpdHk7XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBBbnl0aGluZyBsb3dlciB0aGFuIG5vcm1hbCBwcmlvcml0eSBzaG91bGQgcmVtYWluIGF0IHRoZSBjdXJyZW50IGxldmVsLlxuICAgICAgcHJpb3JpdHlMZXZlbCA9IGN1cnJlbnRQcmlvcml0eUxldmVsO1xuICAgICAgYnJlYWs7XG4gIH1cblxuICB2YXIgcHJldmlvdXNQcmlvcml0eUxldmVsID0gY3VycmVudFByaW9yaXR5TGV2ZWw7XG4gIGN1cnJlbnRQcmlvcml0eUxldmVsID0gcHJpb3JpdHlMZXZlbDtcblxuICB0cnkge1xuICAgIHJldHVybiBldmVudEhhbmRsZXIoKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBjdXJyZW50UHJpb3JpdHlMZXZlbCA9IHByZXZpb3VzUHJpb3JpdHlMZXZlbDtcbiAgfVxufVxuXG5mdW5jdGlvbiB1bnN0YWJsZV93cmFwQ2FsbGJhY2soY2FsbGJhY2spIHtcbiAgdmFyIHBhcmVudFByaW9yaXR5TGV2ZWwgPSBjdXJyZW50UHJpb3JpdHlMZXZlbDtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBUaGlzIGlzIGEgZm9yayBvZiBydW5XaXRoUHJpb3JpdHksIGlubGluZWQgZm9yIHBlcmZvcm1hbmNlLlxuICAgIHZhciBwcmV2aW91c1ByaW9yaXR5TGV2ZWwgPSBjdXJyZW50UHJpb3JpdHlMZXZlbDtcbiAgICBjdXJyZW50UHJpb3JpdHlMZXZlbCA9IHBhcmVudFByaW9yaXR5TGV2ZWw7XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGN1cnJlbnRQcmlvcml0eUxldmVsID0gcHJldmlvdXNQcmlvcml0eUxldmVsO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gdW5zdGFibGVfc2NoZWR1bGVDYWxsYmFjayhwcmlvcml0eUxldmVsLCBjYWxsYmFjaywgb3B0aW9ucykge1xuICB2YXIgY3VycmVudFRpbWUgPSBleHBvcnRzLnVuc3RhYmxlX25vdygpO1xuICB2YXIgc3RhcnRUaW1lO1xuXG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcgJiYgb3B0aW9ucyAhPT0gbnVsbCkge1xuICAgIHZhciBkZWxheSA9IG9wdGlvbnMuZGVsYXk7XG5cbiAgICBpZiAodHlwZW9mIGRlbGF5ID09PSAnbnVtYmVyJyAmJiBkZWxheSA+IDApIHtcbiAgICAgIHN0YXJ0VGltZSA9IGN1cnJlbnRUaW1lICsgZGVsYXk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXJ0VGltZSA9IGN1cnJlbnRUaW1lO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBzdGFydFRpbWUgPSBjdXJyZW50VGltZTtcbiAgfVxuXG4gIHZhciB0aW1lb3V0O1xuXG4gIHN3aXRjaCAocHJpb3JpdHlMZXZlbCkge1xuICAgIGNhc2UgSW1tZWRpYXRlUHJpb3JpdHk6XG4gICAgICB0aW1lb3V0ID0gSU1NRURJQVRFX1BSSU9SSVRZX1RJTUVPVVQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgVXNlckJsb2NraW5nUHJpb3JpdHk6XG4gICAgICB0aW1lb3V0ID0gVVNFUl9CTE9DS0lOR19QUklPUklUWV9USU1FT1VUO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIElkbGVQcmlvcml0eTpcbiAgICAgIHRpbWVvdXQgPSBJRExFX1BSSU9SSVRZX1RJTUVPVVQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgTG93UHJpb3JpdHk6XG4gICAgICB0aW1lb3V0ID0gTE9XX1BSSU9SSVRZX1RJTUVPVVQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgTm9ybWFsUHJpb3JpdHk6XG4gICAgZGVmYXVsdDpcbiAgICAgIHRpbWVvdXQgPSBOT1JNQUxfUFJJT1JJVFlfVElNRU9VVDtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgdmFyIGV4cGlyYXRpb25UaW1lID0gc3RhcnRUaW1lICsgdGltZW91dDtcbiAgdmFyIG5ld1Rhc2sgPSB7XG4gICAgaWQ6IHRhc2tJZENvdW50ZXIrKyxcbiAgICBjYWxsYmFjazogY2FsbGJhY2ssXG4gICAgcHJpb3JpdHlMZXZlbDogcHJpb3JpdHlMZXZlbCxcbiAgICBzdGFydFRpbWU6IHN0YXJ0VGltZSxcbiAgICBleHBpcmF0aW9uVGltZTogZXhwaXJhdGlvblRpbWUsXG4gICAgc29ydEluZGV4OiAtMVxuICB9O1xuXG4gIGlmIChzdGFydFRpbWUgPiBjdXJyZW50VGltZSkge1xuICAgIC8vIFRoaXMgaXMgYSBkZWxheWVkIHRhc2suXG4gICAgbmV3VGFzay5zb3J0SW5kZXggPSBzdGFydFRpbWU7XG4gICAgcHVzaCh0aW1lclF1ZXVlLCBuZXdUYXNrKTtcblxuICAgIGlmIChwZWVrKHRhc2tRdWV1ZSkgPT09IG51bGwgJiYgbmV3VGFzayA9PT0gcGVlayh0aW1lclF1ZXVlKSkge1xuICAgICAgLy8gQWxsIHRhc2tzIGFyZSBkZWxheWVkLCBhbmQgdGhpcyBpcyB0aGUgdGFzayB3aXRoIHRoZSBlYXJsaWVzdCBkZWxheS5cbiAgICAgIGlmIChpc0hvc3RUaW1lb3V0U2NoZWR1bGVkKSB7XG4gICAgICAgIC8vIENhbmNlbCBhbiBleGlzdGluZyB0aW1lb3V0LlxuICAgICAgICBjYW5jZWxIb3N0VGltZW91dCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXNIb3N0VGltZW91dFNjaGVkdWxlZCA9IHRydWU7XG4gICAgICB9IC8vIFNjaGVkdWxlIGEgdGltZW91dC5cblxuXG4gICAgICByZXF1ZXN0SG9zdFRpbWVvdXQoaGFuZGxlVGltZW91dCwgc3RhcnRUaW1lIC0gY3VycmVudFRpbWUpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBuZXdUYXNrLnNvcnRJbmRleCA9IGV4cGlyYXRpb25UaW1lO1xuICAgIHB1c2godGFza1F1ZXVlLCBuZXdUYXNrKTtcbiAgICAvLyB3YWl0IHVudGlsIHRoZSBuZXh0IHRpbWUgd2UgeWllbGQuXG5cblxuICAgIGlmICghaXNIb3N0Q2FsbGJhY2tTY2hlZHVsZWQgJiYgIWlzUGVyZm9ybWluZ1dvcmspIHtcbiAgICAgIGlzSG9zdENhbGxiYWNrU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICAgIHJlcXVlc3RIb3N0Q2FsbGJhY2soZmx1c2hXb3JrKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3VGFzaztcbn1cblxuZnVuY3Rpb24gdW5zdGFibGVfcGF1c2VFeGVjdXRpb24oKSB7XG59XG5cbmZ1bmN0aW9uIHVuc3RhYmxlX2NvbnRpbnVlRXhlY3V0aW9uKCkge1xuXG4gIGlmICghaXNIb3N0Q2FsbGJhY2tTY2hlZHVsZWQgJiYgIWlzUGVyZm9ybWluZ1dvcmspIHtcbiAgICBpc0hvc3RDYWxsYmFja1NjaGVkdWxlZCA9IHRydWU7XG4gICAgcmVxdWVzdEhvc3RDYWxsYmFjayhmbHVzaFdvcmspO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuc3RhYmxlX2dldEZpcnN0Q2FsbGJhY2tOb2RlKCkge1xuICByZXR1cm4gcGVlayh0YXNrUXVldWUpO1xufVxuXG5mdW5jdGlvbiB1bnN0YWJsZV9jYW5jZWxDYWxsYmFjayh0YXNrKSB7XG4gIC8vIHJlbW92ZSBmcm9tIHRoZSBxdWV1ZSBiZWNhdXNlIHlvdSBjYW4ndCByZW1vdmUgYXJiaXRyYXJ5IG5vZGVzIGZyb20gYW5cbiAgLy8gYXJyYXkgYmFzZWQgaGVhcCwgb25seSB0aGUgZmlyc3Qgb25lLilcblxuXG4gIHRhc2suY2FsbGJhY2sgPSBudWxsO1xufVxuXG5mdW5jdGlvbiB1bnN0YWJsZV9nZXRDdXJyZW50UHJpb3JpdHlMZXZlbCgpIHtcbiAgcmV0dXJuIGN1cnJlbnRQcmlvcml0eUxldmVsO1xufVxuXG52YXIgaXNNZXNzYWdlTG9vcFJ1bm5pbmcgPSBmYWxzZTtcbnZhciBzY2hlZHVsZWRIb3N0Q2FsbGJhY2sgPSBudWxsO1xudmFyIHRhc2tUaW1lb3V0SUQgPSAtMTsgLy8gU2NoZWR1bGVyIHBlcmlvZGljYWxseSB5aWVsZHMgaW4gY2FzZSB0aGVyZSBpcyBvdGhlciB3b3JrIG9uIHRoZSBtYWluXG4vLyB0aHJlYWQsIGxpa2UgdXNlciBldmVudHMuIEJ5IGRlZmF1bHQsIGl0IHlpZWxkcyBtdWx0aXBsZSB0aW1lcyBwZXIgZnJhbWUuXG4vLyBJdCBkb2VzIG5vdCBhdHRlbXB0IHRvIGFsaWduIHdpdGggZnJhbWUgYm91bmRhcmllcywgc2luY2UgbW9zdCB0YXNrcyBkb24ndFxuLy8gbmVlZCB0byBiZSBmcmFtZSBhbGlnbmVkOyBmb3IgdGhvc2UgdGhhdCBkbywgdXNlIHJlcXVlc3RBbmltYXRpb25GcmFtZS5cblxudmFyIGZyYW1lSW50ZXJ2YWwgPSBmcmFtZVlpZWxkTXM7XG52YXIgc3RhcnRUaW1lID0gLTE7XG5cbmZ1bmN0aW9uIHNob3VsZFlpZWxkVG9Ib3N0KCkge1xuICB2YXIgdGltZUVsYXBzZWQgPSBleHBvcnRzLnVuc3RhYmxlX25vdygpIC0gc3RhcnRUaW1lO1xuXG4gIGlmICh0aW1lRWxhcHNlZCA8IGZyYW1lSW50ZXJ2YWwpIHtcbiAgICAvLyBUaGUgbWFpbiB0aHJlYWQgaGFzIG9ubHkgYmVlbiBibG9ja2VkIGZvciBhIHJlYWxseSBzaG9ydCBhbW91bnQgb2YgdGltZTtcbiAgICAvLyBzbWFsbGVyIHRoYW4gYSBzaW5nbGUgZnJhbWUuIERvbid0IHlpZWxkIHlldC5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gLy8gVGhlIG1haW4gdGhyZWFkIGhhcyBiZWVuIGJsb2NrZWQgZm9yIGEgbm9uLW5lZ2xpZ2libGUgYW1vdW50IG9mIHRpbWUuIFdlXG5cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmVxdWVzdFBhaW50KCkge1xuXG59XG5cbmZ1bmN0aW9uIGZvcmNlRnJhbWVSYXRlKGZwcykge1xuICBpZiAoZnBzIDwgMCB8fCBmcHMgPiAxMjUpIHtcbiAgICAvLyBVc2luZyBjb25zb2xlWydlcnJvciddIHRvIGV2YWRlIEJhYmVsIGFuZCBFU0xpbnRcbiAgICBjb25zb2xlWydlcnJvciddKCdmb3JjZUZyYW1lUmF0ZSB0YWtlcyBhIHBvc2l0aXZlIGludCBiZXR3ZWVuIDAgYW5kIDEyNSwgJyArICdmb3JjaW5nIGZyYW1lIHJhdGVzIGhpZ2hlciB0aGFuIDEyNSBmcHMgaXMgbm90IHN1cHBvcnRlZCcpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChmcHMgPiAwKSB7XG4gICAgZnJhbWVJbnRlcnZhbCA9IE1hdGguZmxvb3IoMTAwMCAvIGZwcyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gcmVzZXQgdGhlIGZyYW1lcmF0ZVxuICAgIGZyYW1lSW50ZXJ2YWwgPSBmcmFtZVlpZWxkTXM7XG4gIH1cbn1cblxudmFyIHBlcmZvcm1Xb3JrVW50aWxEZWFkbGluZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHNjaGVkdWxlZEhvc3RDYWxsYmFjayAhPT0gbnVsbCkge1xuICAgIHZhciBjdXJyZW50VGltZSA9IGV4cG9ydHMudW5zdGFibGVfbm93KCk7IC8vIEtlZXAgdHJhY2sgb2YgdGhlIHN0YXJ0IHRpbWUgc28gd2UgY2FuIG1lYXN1cmUgaG93IGxvbmcgdGhlIG1haW4gdGhyZWFkXG4gICAgLy8gaGFzIGJlZW4gYmxvY2tlZC5cblxuICAgIHN0YXJ0VGltZSA9IGN1cnJlbnRUaW1lO1xuICAgIHZhciBoYXNUaW1lUmVtYWluaW5nID0gdHJ1ZTsgLy8gSWYgYSBzY2hlZHVsZXIgdGFzayB0aHJvd3MsIGV4aXQgdGhlIGN1cnJlbnQgYnJvd3NlciB0YXNrIHNvIHRoZVxuICAgIC8vIGVycm9yIGNhbiBiZSBvYnNlcnZlZC5cbiAgICAvL1xuICAgIC8vIEludGVudGlvbmFsbHkgbm90IHVzaW5nIGEgdHJ5LWNhdGNoLCBzaW5jZSB0aGF0IG1ha2VzIHNvbWUgZGVidWdnaW5nXG4gICAgLy8gdGVjaG5pcXVlcyBoYXJkZXIuIEluc3RlYWQsIGlmIGBzY2hlZHVsZWRIb3N0Q2FsbGJhY2tgIGVycm9ycywgdGhlblxuICAgIC8vIGBoYXNNb3JlV29ya2Agd2lsbCByZW1haW4gdHJ1ZSwgYW5kIHdlJ2xsIGNvbnRpbnVlIHRoZSB3b3JrIGxvb3AuXG5cbiAgICB2YXIgaGFzTW9yZVdvcmsgPSB0cnVlO1xuXG4gICAgdHJ5IHtcbiAgICAgIGhhc01vcmVXb3JrID0gc2NoZWR1bGVkSG9zdENhbGxiYWNrKGhhc1RpbWVSZW1haW5pbmcsIGN1cnJlbnRUaW1lKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKGhhc01vcmVXb3JrKSB7XG4gICAgICAgIC8vIElmIHRoZXJlJ3MgbW9yZSB3b3JrLCBzY2hlZHVsZSB0aGUgbmV4dCBtZXNzYWdlIGV2ZW50IGF0IHRoZSBlbmRcbiAgICAgICAgLy8gb2YgdGhlIHByZWNlZGluZyBvbmUuXG4gICAgICAgIHNjaGVkdWxlUGVyZm9ybVdvcmtVbnRpbERlYWRsaW5lKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpc01lc3NhZ2VMb29wUnVubmluZyA9IGZhbHNlO1xuICAgICAgICBzY2hlZHVsZWRIb3N0Q2FsbGJhY2sgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpc01lc3NhZ2VMb29wUnVubmluZyA9IGZhbHNlO1xuICB9IC8vIFlpZWxkaW5nIHRvIHRoZSBicm93c2VyIHdpbGwgZ2l2ZSBpdCBhIGNoYW5jZSB0byBwYWludCwgc28gd2UgY2FuXG59O1xuXG52YXIgc2NoZWR1bGVQZXJmb3JtV29ya1VudGlsRGVhZGxpbmU7XG5cbmlmICh0eXBlb2YgbG9jYWxTZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gTm9kZS5qcyBhbmQgb2xkIElFLlxuICAvLyBUaGVyZSdzIGEgZmV3IHJlYXNvbnMgZm9yIHdoeSB3ZSBwcmVmZXIgc2V0SW1tZWRpYXRlLlxuICAvL1xuICAvLyBVbmxpa2UgTWVzc2FnZUNoYW5uZWwsIGl0IGRvZXNuJ3QgcHJldmVudCBhIE5vZGUuanMgcHJvY2VzcyBmcm9tIGV4aXRpbmcuXG4gIC8vIChFdmVuIHRob3VnaCB0aGlzIGlzIGEgRE9NIGZvcmsgb2YgdGhlIFNjaGVkdWxlciwgeW91IGNvdWxkIGdldCBoZXJlXG4gIC8vIHdpdGggYSBtaXggb2YgTm9kZS5qcyAxNSssIHdoaWNoIGhhcyBhIE1lc3NhZ2VDaGFubmVsLCBhbmQganNkb20uKVxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzIwNzU2XG4gIC8vXG4gIC8vIEJ1dCBhbHNvLCBpdCBydW5zIGVhcmxpZXIgd2hpY2ggaXMgdGhlIHNlbWFudGljIHdlIHdhbnQuXG4gIC8vIElmIG90aGVyIGJyb3dzZXJzIGV2ZXIgaW1wbGVtZW50IGl0LCBpdCdzIGJldHRlciB0byB1c2UgaXQuXG4gIC8vIEFsdGhvdWdoIGJvdGggb2YgdGhlc2Ugd291bGQgYmUgaW5mZXJpb3IgdG8gbmF0aXZlIHNjaGVkdWxpbmcuXG4gIHNjaGVkdWxlUGVyZm9ybVdvcmtVbnRpbERlYWRsaW5lID0gZnVuY3Rpb24gKCkge1xuICAgIGxvY2FsU2V0SW1tZWRpYXRlKHBlcmZvcm1Xb3JrVW50aWxEZWFkbGluZSk7XG4gIH07XG59IGVsc2UgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgLy8gRE9NIGFuZCBXb3JrZXIgZW52aXJvbm1lbnRzLlxuICAvLyBXZSBwcmVmZXIgTWVzc2FnZUNoYW5uZWwgYmVjYXVzZSBvZiB0aGUgNG1zIHNldFRpbWVvdXQgY2xhbXBpbmcuXG4gIHZhciBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gIHZhciBwb3J0ID0gY2hhbm5lbC5wb3J0MjtcbiAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBwZXJmb3JtV29ya1VudGlsRGVhZGxpbmU7XG5cbiAgc2NoZWR1bGVQZXJmb3JtV29ya1VudGlsRGVhZGxpbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcG9ydC5wb3N0TWVzc2FnZShudWxsKTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIFdlIHNob3VsZCBvbmx5IGZhbGxiYWNrIGhlcmUgaW4gbm9uLWJyb3dzZXIgZW52aXJvbm1lbnRzLlxuICBzY2hlZHVsZVBlcmZvcm1Xb3JrVW50aWxEZWFkbGluZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBsb2NhbFNldFRpbWVvdXQocGVyZm9ybVdvcmtVbnRpbERlYWRsaW5lLCAwKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVxdWVzdEhvc3RDYWxsYmFjayhjYWxsYmFjaykge1xuICBzY2hlZHVsZWRIb3N0Q2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICBpZiAoIWlzTWVzc2FnZUxvb3BSdW5uaW5nKSB7XG4gICAgaXNNZXNzYWdlTG9vcFJ1bm5pbmcgPSB0cnVlO1xuICAgIHNjaGVkdWxlUGVyZm9ybVdvcmtVbnRpbERlYWRsaW5lKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVxdWVzdEhvc3RUaW1lb3V0KGNhbGxiYWNrLCBtcykge1xuICB0YXNrVGltZW91dElEID0gbG9jYWxTZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBjYWxsYmFjayhleHBvcnRzLnVuc3RhYmxlX25vdygpKTtcbiAgfSwgbXMpO1xufVxuXG5mdW5jdGlvbiBjYW5jZWxIb3N0VGltZW91dCgpIHtcbiAgbG9jYWxDbGVhclRpbWVvdXQodGFza1RpbWVvdXRJRCk7XG4gIHRhc2tUaW1lb3V0SUQgPSAtMTtcbn1cblxudmFyIHVuc3RhYmxlX3JlcXVlc3RQYWludCA9IHJlcXVlc3RQYWludDtcbnZhciB1bnN0YWJsZV9Qcm9maWxpbmcgPSAgbnVsbDtcblxuZXhwb3J0cy51bnN0YWJsZV9JZGxlUHJpb3JpdHkgPSBJZGxlUHJpb3JpdHk7XG5leHBvcnRzLnVuc3RhYmxlX0ltbWVkaWF0ZVByaW9yaXR5ID0gSW1tZWRpYXRlUHJpb3JpdHk7XG5leHBvcnRzLnVuc3RhYmxlX0xvd1ByaW9yaXR5ID0gTG93UHJpb3JpdHk7XG5leHBvcnRzLnVuc3RhYmxlX05vcm1hbFByaW9yaXR5ID0gTm9ybWFsUHJpb3JpdHk7XG5leHBvcnRzLnVuc3RhYmxlX1Byb2ZpbGluZyA9IHVuc3RhYmxlX1Byb2ZpbGluZztcbmV4cG9ydHMudW5zdGFibGVfVXNlckJsb2NraW5nUHJpb3JpdHkgPSBVc2VyQmxvY2tpbmdQcmlvcml0eTtcbmV4cG9ydHMudW5zdGFibGVfY2FuY2VsQ2FsbGJhY2sgPSB1bnN0YWJsZV9jYW5jZWxDYWxsYmFjaztcbmV4cG9ydHMudW5zdGFibGVfY29udGludWVFeGVjdXRpb24gPSB1bnN0YWJsZV9jb250aW51ZUV4ZWN1dGlvbjtcbmV4cG9ydHMudW5zdGFibGVfZm9yY2VGcmFtZVJhdGUgPSBmb3JjZUZyYW1lUmF0ZTtcbmV4cG9ydHMudW5zdGFibGVfZ2V0Q3VycmVudFByaW9yaXR5TGV2ZWwgPSB1bnN0YWJsZV9nZXRDdXJyZW50UHJpb3JpdHlMZXZlbDtcbmV4cG9ydHMudW5zdGFibGVfZ2V0Rmlyc3RDYWxsYmFja05vZGUgPSB1bnN0YWJsZV9nZXRGaXJzdENhbGxiYWNrTm9kZTtcbmV4cG9ydHMudW5zdGFibGVfbmV4dCA9IHVuc3RhYmxlX25leHQ7XG5leHBvcnRzLnVuc3RhYmxlX3BhdXNlRXhlY3V0aW9uID0gdW5zdGFibGVfcGF1c2VFeGVjdXRpb247XG5leHBvcnRzLnVuc3RhYmxlX3JlcXVlc3RQYWludCA9IHVuc3RhYmxlX3JlcXVlc3RQYWludDtcbmV4cG9ydHMudW5zdGFibGVfcnVuV2l0aFByaW9yaXR5ID0gdW5zdGFibGVfcnVuV2l0aFByaW9yaXR5O1xuZXhwb3J0cy51bnN0YWJsZV9zY2hlZHVsZUNhbGxiYWNrID0gdW5zdGFibGVfc2NoZWR1bGVDYWxsYmFjaztcbmV4cG9ydHMudW5zdGFibGVfc2hvdWxkWWllbGQgPSBzaG91bGRZaWVsZFRvSG9zdDtcbmV4cG9ydHMudW5zdGFibGVfd3JhcENhbGxiYWNrID0gdW5zdGFibGVfd3JhcENhbGxiYWNrO1xuICAgICAgICAgIC8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbmlmIChcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RvcCA9PT1cbiAgICAnZnVuY3Rpb24nXG4pIHtcbiAgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fLnJlZ2lzdGVySW50ZXJuYWxNb2R1bGVTdG9wKG5ldyBFcnJvcigpKTtcbn1cbiAgICAgICAgXG4gIH0pKCk7XG59XG4iLCJpbXBvcnQgeyBGcmFnbWVudCwgdHlwZSBGQywgdHlwZSBSZWFjdE5vZGUgfSBmcm9tIFwicmVhY3RcIlxuXG5leHBvcnQgY29uc3QgZ2V0TGF5b3V0ID0gKFJhd0ltcG9ydDogYW55KTogRkM8eyBjaGlsZHJlbjogUmVhY3ROb2RlIH0+ID0+XG4gIHR5cGVvZiBSYXdJbXBvcnQuTGF5b3V0ID09PSBcImZ1bmN0aW9uXCJcbiAgICA/IFJhd0ltcG9ydC5MYXlvdXRcbiAgICA6IHR5cGVvZiBSYXdJbXBvcnQuZ2V0R2xvYmFsUHJvdmlkZXIgPT09IFwiZnVuY3Rpb25cIlxuICAgID8gUmF3SW1wb3J0LmdldEdsb2JhbFByb3ZpZGVyKClcbiAgICA6IEZyYWdtZW50XG4iLCJleHBvcnRzLmludGVyb3BEZWZhdWx0ID0gZnVuY3Rpb24gKGEpIHtcbiAgcmV0dXJuIGEgJiYgYS5fX2VzTW9kdWxlID8gYSA6IHtkZWZhdWx0OiBhfTtcbn07XG5cbmV4cG9ydHMuZGVmaW5lSW50ZXJvcEZsYWcgPSBmdW5jdGlvbiAoYSkge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYSwgJ19fZXNNb2R1bGUnLCB7dmFsdWU6IHRydWV9KTtcbn07XG5cbmV4cG9ydHMuZXhwb3J0QWxsID0gZnVuY3Rpb24gKHNvdXJjZSwgZGVzdCkge1xuICBPYmplY3Qua2V5cyhzb3VyY2UpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgIGlmIChrZXkgPT09ICdkZWZhdWx0JyB8fCBrZXkgPT09ICdfX2VzTW9kdWxlJyB8fCBkZXN0Lmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZGVzdCwga2V5LCB7XG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBzb3VyY2Vba2V5XTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0pO1xuXG4gIHJldHVybiBkZXN0O1xufTtcblxuZXhwb3J0cy5leHBvcnQgPSBmdW5jdGlvbiAoZGVzdCwgZGVzdE5hbWUsIGdldCkge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZGVzdCwgZGVzdE5hbWUsIHtcbiAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIGdldDogZ2V0LFxuICB9KTtcbn07XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIFJlZnJlc2ggPSByZXF1aXJlKCdyZWFjdC1yZWZyZXNoL3J1bnRpbWUnKTtcbmZ1bmN0aW9uIGRlYm91bmNlKGZ1bmMsIGRlbGF5KSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Rlc3QnKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgICBmdW5jLmNhbGwobnVsbCwgYXJncyk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBsZXQgdGltZW91dCA9IHVuZGVmaW5lZDtcbiAgICBsZXQgbGFzdFRpbWUgPSAwO1xuICAgIHJldHVybiBmdW5jdGlvbiAoYXJncykge1xuICAgICAgLy8gQ2FsbCBpbW1lZGlhdGVseSBpZiBsYXN0IGNhbGwgd2FzIG1vcmUgdGhhbiB0aGUgZGVsYXkgYWdvLlxuICAgICAgLy8gT3RoZXJ3aXNlLCBzZXQgYSB0aW1lb3V0LiBUaGlzIG1lYW5zIHRoZSBmaXJzdCBjYWxsIGlzIGZhc3RcbiAgICAgIC8vIChmb3IgdGhlIGNvbW1vbiBjYXNlIG9mIGEgc2luZ2xlIHVwZGF0ZSksIGFuZCBzdWJzZXF1ZW50IHVwZGF0ZXNcbiAgICAgIC8vIGFyZSBiYXRjaGVkLlxuICAgICAgbGV0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICBpZiAobm93IC0gbGFzdFRpbWUgPiBkZWxheSkge1xuICAgICAgICBsYXN0VGltZSA9IG5vdztcbiAgICAgICAgZnVuYy5jYWxsKG51bGwsIGFyZ3MpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdGltZW91dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBsYXN0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgZnVuYy5jYWxsKG51bGwsIGFyZ3MpO1xuICAgICAgICB9LCBkZWxheSk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxufVxudmFyIGVucXVldWVVcGRhdGUgPSBkZWJvdW5jZShmdW5jdGlvbiAoKSB7XG4gIFJlZnJlc2gucGVyZm9ybVJlYWN0UmVmcmVzaCgpO1xufSwgMzApO1xuXG4vLyBFdmVydGhpbmcgYmVsb3cgaXMgZWl0aGVyIGFkYXB0ZWQgb3IgY29waWVkIGZyb21cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9tZXRyby9ibG9iLzYxZGUxNmJkMWVkZDdlNzM4ZGQwMzExYzg5NTU1YTY0NDAyM2FiMmQvcGFja2FnZXMvbWV0cm8vc3JjL2xpYi9wb2x5ZmlsbHMvcmVxdWlyZS5qc1xuLy8gTUlUIExpY2Vuc2UgLSBDb3B5cmlnaHQgKGMpIEZhY2Vib29rLCBJbmMuIGFuZCBpdHMgYWZmaWxpYXRlcy5cblxubW9kdWxlLmV4cG9ydHMucHJlbHVkZSA9IGZ1bmN0aW9uIChtb2R1bGUpIHtcbiAgd2luZG93LiRSZWZyZXNoUmVnJCA9IGZ1bmN0aW9uICh0eXBlLCBpZCkge1xuICAgIFJlZnJlc2gucmVnaXN0ZXIodHlwZSwgbW9kdWxlLmlkICsgJyAnICsgaWQpO1xuICB9O1xuICB3aW5kb3cuJFJlZnJlc2hTaWckID0gUmVmcmVzaC5jcmVhdGVTaWduYXR1cmVGdW5jdGlvbkZvclRyYW5zZm9ybTtcbn07XG5tb2R1bGUuZXhwb3J0cy5wb3N0bHVkZSA9IGZ1bmN0aW9uIChtb2R1bGUpIHtcbiAgaWYgKGlzUmVhY3RSZWZyZXNoQm91bmRhcnkobW9kdWxlLmV4cG9ydHMpKSB7XG4gICAgcmVnaXN0ZXJFeHBvcnRzRm9yUmVhY3RSZWZyZXNoKG1vZHVsZSk7XG4gICAgaWYgKG1vZHVsZS5ob3QpIHtcbiAgICAgIG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICBpZiAoUmVmcmVzaC5oYXNVbnJlY292ZXJhYmxlRXJyb3JzKCkpIHtcbiAgICAgICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XG4gICAgICAgIH1cbiAgICAgICAgZGF0YS5wcmV2RXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzO1xuICAgICAgfSk7XG4gICAgICBtb2R1bGUuaG90LmFjY2VwdChmdW5jdGlvbiAoZ2V0UGFyZW50cykge1xuICAgICAgICB2YXIgcHJldkV4cG9ydHMgPSBtb2R1bGUuaG90LmRhdGEucHJldkV4cG9ydHM7XG4gICAgICAgIHZhciBuZXh0RXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzO1xuICAgICAgICAvLyBTaW5jZSB3ZSBqdXN0IGV4ZWN1dGVkIHRoZSBjb2RlIGZvciBpdCwgaXQncyBwb3NzaWJsZVxuICAgICAgICAvLyB0aGF0IHRoZSBuZXcgZXhwb3J0cyBtYWtlIGl0IGluZWxpZ2libGUgZm9yIGJlaW5nIGEgYm91bmRhcnkuXG4gICAgICAgIHZhciBpc05vTG9uZ2VyQUJvdW5kYXJ5ID0gIWlzUmVhY3RSZWZyZXNoQm91bmRhcnkobmV4dEV4cG9ydHMpO1xuICAgICAgICAvLyBJdCBjYW4gYWxzbyBiZWNvbWUgaW5lbGlnaWJsZSBpZiBpdHMgZXhwb3J0cyBhcmUgaW5jb21wYXRpYmxlXG4gICAgICAgIC8vIHdpdGggdGhlIHByZXZpb3VzIGV4cG9ydHMuXG4gICAgICAgIC8vIEZvciBleGFtcGxlLCBpZiB5b3UgYWRkL3JlbW92ZS9jaGFuZ2UgZXhwb3J0cywgd2UnbGwgd2FudFxuICAgICAgICAvLyB0byByZS1leGVjdXRlIHRoZSBpbXBvcnRpbmcgbW9kdWxlcywgYW5kIGZvcmNlIHRob3NlIGNvbXBvbmVudHNcbiAgICAgICAgLy8gdG8gcmUtcmVuZGVyLiBTaW1pbGFybHksIGlmIHlvdSBjb252ZXJ0IGEgY2xhc3MgY29tcG9uZW50XG4gICAgICAgIC8vIHRvIGEgZnVuY3Rpb24sIHdlIHdhbnQgdG8gaW52YWxpZGF0ZSB0aGUgYm91bmRhcnkuXG4gICAgICAgIHZhciBkaWRJbnZhbGlkYXRlID0gc2hvdWxkSW52YWxpZGF0ZVJlYWN0UmVmcmVzaEJvdW5kYXJ5KHByZXZFeHBvcnRzLCBuZXh0RXhwb3J0cyk7XG4gICAgICAgIGlmIChpc05vTG9uZ2VyQUJvdW5kYXJ5IHx8IGRpZEludmFsaWRhdGUpIHtcbiAgICAgICAgICAvLyBXZSdsbCBiZSBjb25zZXJ2YXRpdmUuIFRoZSBvbmx5IGNhc2UgaW4gd2hpY2ggd2Ugd29uJ3QgZG8gYSBmdWxsXG4gICAgICAgICAgLy8gcmVsb2FkIGlzIGlmIGFsbCBwYXJlbnQgbW9kdWxlcyBhcmUgYWxzbyByZWZyZXNoIGJvdW5kYXJpZXMuXG4gICAgICAgICAgLy8gSW4gdGhhdCBjYXNlIHdlJ2xsIGFkZCB0aGVtIHRvIHRoZSBjdXJyZW50IHF1ZXVlLlxuICAgICAgICAgIHZhciBwYXJlbnRzID0gZ2V0UGFyZW50cygpO1xuICAgICAgICAgIGlmIChwYXJlbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gTG9va3MgbGlrZSB3ZSBidWJibGVkIHRvIHRoZSByb290LiBDYW4ndCByZWNvdmVyIGZyb20gdGhhdC5cbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHBhcmVudHM7XG4gICAgICAgIH1cbiAgICAgICAgZW5xdWV1ZVVwZGF0ZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59O1xuZnVuY3Rpb24gaXNSZWFjdFJlZnJlc2hCb3VuZGFyeShleHBvcnRzKSB7XG4gIGlmIChSZWZyZXNoLmlzTGlrZWx5Q29tcG9uZW50VHlwZShleHBvcnRzKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmIChleHBvcnRzID09IG51bGwgfHwgdHlwZW9mIGV4cG9ydHMgIT09ICdvYmplY3QnKSB7XG4gICAgLy8gRXhpdCBpZiB3ZSBjYW4ndCBpdGVyYXRlIG92ZXIgZXhwb3J0cy5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIGhhc0V4cG9ydHMgPSBmYWxzZTtcbiAgdmFyIGFyZUFsbEV4cG9ydHNDb21wb25lbnRzID0gdHJ1ZTtcbiAgbGV0IGlzRVNNID0gKCdfX2VzTW9kdWxlJyBpbiBleHBvcnRzKTtcbiAgZm9yICh2YXIga2V5IGluIGV4cG9ydHMpIHtcbiAgICBoYXNFeHBvcnRzID0gdHJ1ZTtcbiAgICBpZiAoa2V5ID09PSAnX19lc01vZHVsZScpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZXhwb3J0cywga2V5KTtcbiAgICBpZiAoZGVzYyAmJiBkZXNjLmdldCAmJiAhaXNFU00pIHtcbiAgICAgIC8vIERvbid0IGludm9rZSBnZXR0ZXJzIGZvciBDSlMgYXMgdGhleSBtYXkgaGF2ZSBzaWRlIGVmZmVjdHMuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHZhciBleHBvcnRWYWx1ZSA9IGV4cG9ydHNba2V5XTtcbiAgICBpZiAoIVJlZnJlc2guaXNMaWtlbHlDb21wb25lbnRUeXBlKGV4cG9ydFZhbHVlKSkge1xuICAgICAgYXJlQWxsRXhwb3J0c0NvbXBvbmVudHMgPSBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGhhc0V4cG9ydHMgJiYgYXJlQWxsRXhwb3J0c0NvbXBvbmVudHM7XG59XG5mdW5jdGlvbiBzaG91bGRJbnZhbGlkYXRlUmVhY3RSZWZyZXNoQm91bmRhcnkocHJldkV4cG9ydHMsIG5leHRFeHBvcnRzKSB7XG4gIHZhciBwcmV2U2lnbmF0dXJlID0gZ2V0UmVmcmVzaEJvdW5kYXJ5U2lnbmF0dXJlKHByZXZFeHBvcnRzKTtcbiAgdmFyIG5leHRTaWduYXR1cmUgPSBnZXRSZWZyZXNoQm91bmRhcnlTaWduYXR1cmUobmV4dEV4cG9ydHMpO1xuICBpZiAocHJldlNpZ25hdHVyZS5sZW5ndGggIT09IG5leHRTaWduYXR1cmUubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuZXh0U2lnbmF0dXJlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHByZXZTaWduYXR1cmVbaV0gIT09IG5leHRTaWduYXR1cmVbaV0pIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8vIFdoZW4gdGhpcyBzaWduYXR1cmUgY2hhbmdlcywgaXQncyB1bnNhZmUgdG8gc3RvcCBhdCB0aGlzIHJlZnJlc2ggYm91bmRhcnkuXG5mdW5jdGlvbiBnZXRSZWZyZXNoQm91bmRhcnlTaWduYXR1cmUoZXhwb3J0cykge1xuICB2YXIgc2lnbmF0dXJlID0gW107XG4gIHNpZ25hdHVyZS5wdXNoKFJlZnJlc2guZ2V0RmFtaWx5QnlUeXBlKGV4cG9ydHMpKTtcbiAgaWYgKGV4cG9ydHMgPT0gbnVsbCB8fCB0eXBlb2YgZXhwb3J0cyAhPT0gJ29iamVjdCcpIHtcbiAgICAvLyBFeGl0IGlmIHdlIGNhbid0IGl0ZXJhdGUgb3ZlciBleHBvcnRzLlxuICAgIC8vIChUaGlzIGlzIGltcG9ydGFudCBmb3IgbGVnYWN5IGVudmlyb25tZW50cy4pXG4gICAgcmV0dXJuIHNpZ25hdHVyZTtcbiAgfVxuICBsZXQgaXNFU00gPSAoJ19fZXNNb2R1bGUnIGluIGV4cG9ydHMpO1xuICBmb3IgKHZhciBrZXkgaW4gZXhwb3J0cykge1xuICAgIGlmIChrZXkgPT09ICdfX2VzTW9kdWxlJykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihleHBvcnRzLCBrZXkpO1xuICAgIGlmIChkZXNjICYmIGRlc2MuZ2V0ICYmICFpc0VTTSkge1xuICAgICAgLy8gRG9uJ3QgaW52b2tlIGdldHRlcnMgZm9yIENKUyBhcyB0aGV5IG1heSBoYXZlIHNpZGUgZWZmZWN0cy5cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgZXhwb3J0VmFsdWUgPSBleHBvcnRzW2tleV07XG4gICAgc2lnbmF0dXJlLnB1c2goa2V5KTtcbiAgICBzaWduYXR1cmUucHVzaChSZWZyZXNoLmdldEZhbWlseUJ5VHlwZShleHBvcnRWYWx1ZSkpO1xuICB9XG4gIHJldHVybiBzaWduYXR1cmU7XG59XG5mdW5jdGlvbiByZWdpc3RlckV4cG9ydHNGb3JSZWFjdFJlZnJlc2gobW9kdWxlKSB7XG4gIHZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMsXG4gICAgaWQgPSBtb2R1bGUuaWQ7XG4gIFJlZnJlc2gucmVnaXN0ZXIoZXhwb3J0cywgaWQgKyAnICVleHBvcnRzJScpO1xuICBpZiAoZXhwb3J0cyA9PSBudWxsIHx8IHR5cGVvZiBleHBvcnRzICE9PSAnb2JqZWN0Jykge1xuICAgIC8vIEV4aXQgaWYgd2UgY2FuJ3QgaXRlcmF0ZSBvdmVyIGV4cG9ydHMuXG4gICAgLy8gKFRoaXMgaXMgaW1wb3J0YW50IGZvciBsZWdhY3kgZW52aXJvbm1lbnRzLilcbiAgICByZXR1cm47XG4gIH1cbiAgbGV0IGlzRVNNID0gKCdfX2VzTW9kdWxlJyBpbiBleHBvcnRzKTtcbiAgZm9yICh2YXIga2V5IGluIGV4cG9ydHMpIHtcbiAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZXhwb3J0cywga2V5KTtcbiAgICBpZiAoZGVzYyAmJiBkZXNjLmdldCAmJiAhaXNFU00pIHtcbiAgICAgIC8vIERvbid0IGludm9rZSBnZXR0ZXJzIGZvciBDSlMgYXMgdGhleSBtYXkgaGF2ZSBzaWRlIGVmZmVjdHMuXG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdmFyIGV4cG9ydFZhbHVlID0gZXhwb3J0c1trZXldO1xuICAgIHZhciB0eXBlSUQgPSBpZCArICcgJWV4cG9ydHMlICcgKyBrZXk7XG4gICAgUmVmcmVzaC5yZWdpc3RlcihleHBvcnRWYWx1ZSwgdHlwZUlEKTtcbiAgfVxufSIsImltcG9ydCB7IHVzZVN0YXRlIH0gZnJvbSBcInJlYWN0XCJcblxuZnVuY3Rpb24gSW5kZXhQb3B1cCgpIHtcbiAgY29uc3QgW2RhdGEsIHNldERhdGFdID0gdXNlU3RhdGUoXCJcIilcblxuICByZXR1cm4gKFxuICAgIDxkaXZcbiAgICAgIHN0eWxlPXt7XG4gICAgICAgIHBhZGRpbmc6IDE2XG4gICAgICB9fT5cbiAgICAgIDxoMj5cbiAgICAgICAgV2VsY29tZSB0byB5b3Vye1wiIFwifVxuICAgICAgICA8YSBocmVmPVwiaHR0cHM6Ly93d3cucGxhc21vLmNvbVwiIHRhcmdldD1cIl9ibGFua1wiPlxuICAgICAgICAgIFBsYXNtb1xuICAgICAgICA8L2E+e1wiIFwifVxuICAgICAgICBFeHRlbnNpb24hXG4gICAgICA8L2gyPlxuICAgICAgPGlucHV0IG9uQ2hhbmdlPXsoZSkgPT4gc2V0RGF0YShlLnRhcmdldC52YWx1ZSl9IHZhbHVlPXtkYXRhfSAvPlxuICAgICAgPGEgaHJlZj1cImh0dHBzOi8vZG9jcy5wbGFzbW8uY29tXCIgdGFyZ2V0PVwiX2JsYW5rXCI+XG4gICAgICAgIFZpZXcgRG9jc1xuICAgICAgPC9hPlxuICAgIDwvZGl2PlxuICApXG59XG5cbmV4cG9ydCBkZWZhdWx0IEluZGV4UG9wdXBcbiJdLCJuYW1lcyI6W10sInZlcnNpb24iOjMsImZpbGUiOiJwb3B1cC43ZmY1ODhmMy5qcy5tYXAifQ== + globalThis.define=__define; })(globalThis.define); \ No newline at end of file diff --git a/packages/whats-ext/build/chrome-mv3-dev/popup.html b/packages/whats-ext/build/chrome-mv3-dev/popup.html new file mode 100644 index 0000000..f19b285 --- /dev/null +++ b/packages/whats-ext/build/chrome-mv3-dev/popup.html @@ -0,0 +1,13 @@ + + + + Example dir + + + + + +
+ + + diff --git a/packages/whats-ext/build/chrome-mv3-dev/static/background/index.js b/packages/whats-ext/build/chrome-mv3-dev/static/background/index.js new file mode 100644 index 0000000..a1a4a74 --- /dev/null +++ b/packages/whats-ext/build/chrome-mv3-dev/static/background/index.js @@ -0,0 +1,382 @@ +(function(define){var __define; typeof define === "function" && (__define=define,define=null); +// modules are defined as an array +// [ module function, map of requires ] +// +// map of requires is short require name -> numeric require +// +// anything defined in a previous bundle is accessed via the +// orig method which is the require for previous bundles + +(function (modules, entry, mainEntry, parcelRequireName, globalName) { + /* eslint-disable no-undef */ + var globalObject = + typeof globalThis !== 'undefined' + ? globalThis + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : typeof global !== 'undefined' + ? global + : {}; + /* eslint-enable no-undef */ + + // Save the require from previous bundle to this closure if any + var previousRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + + var cache = previousRequire.cache || {}; + // Do not use `require` to prevent Webpack from trying to bundle this call + var nodeRequire = + typeof module !== 'undefined' && + typeof module.require === 'function' && + module.require.bind(module); + + function newRequire(name, jumped) { + if (!cache[name]) { + if (!modules[name]) { + // if we cannot find the module within our internal map or + // cache jump to the current global require ie. the last bundle + // that was added to the page. + var currentRequire = + typeof globalObject[parcelRequireName] === 'function' && + globalObject[parcelRequireName]; + if (!jumped && currentRequire) { + return currentRequire(name, true); + } + + // If there are other bundles on this page the require from the + // previous one is saved to 'previousRequire'. Repeat this as + // many times as there are bundles until the module is found or + // we exhaust the require chain. + if (previousRequire) { + return previousRequire(name, true); + } + + // Try the node require function if it exists. + if (nodeRequire && typeof name === 'string') { + return nodeRequire(name); + } + + var err = new Error("Cannot find module '" + name + "'"); + err.code = 'MODULE_NOT_FOUND'; + throw err; + } + + localRequire.resolve = resolve; + localRequire.cache = {}; + + var module = (cache[name] = new newRequire.Module(name)); + + modules[name][0].call( + module.exports, + localRequire, + module, + module.exports, + this + ); + } + + return cache[name].exports; + + function localRequire(x) { + var res = localRequire.resolve(x); + return res === false ? {} : newRequire(res); + } + + function resolve(x) { + var id = modules[name][1][x]; + return id != null ? id : x; + } + } + + function Module(moduleName) { + this.id = moduleName; + this.bundle = newRequire; + this.exports = {}; + } + + newRequire.isParcelRequire = true; + newRequire.Module = Module; + newRequire.modules = modules; + newRequire.cache = cache; + newRequire.parent = previousRequire; + newRequire.register = function (id, exports) { + modules[id] = [ + function (require, module) { + module.exports = exports; + }, + {}, + ]; + }; + + Object.defineProperty(newRequire, 'root', { + get: function () { + return globalObject[parcelRequireName]; + }, + }); + + globalObject[parcelRequireName] = newRequire; + + for (var i = 0; i < entry.length; i++) { + newRequire(entry[i]); + } + + if (mainEntry) { + // Expose entry point to Node, AMD or browser globals + // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js + var mainExports = newRequire(mainEntry); + + // CommonJS + if (typeof exports === 'object' && typeof module !== 'undefined') { + module.exports = mainExports; + + // RequireJS + } else if (typeof define === 'function' && define.amd) { + define(function () { + return mainExports; + }); + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GitHub - pagenote/pagenote: 超简单的网页关键词高亮、标注SDK、能把笔记留在网页里。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Skip to content - - - - - - - - - - - - -
- -
- - - - - - - -
- - - - - -
- - - - - - - - - - -
-
-
- - - - - - - - - - - - - - - -
- -
- -
- -
- - - - / - - pagenote - - - Public template -
- - -
- - - -
- -
-
-

- 超简单的网页关键词高亮、标注SDK、能把笔记留在网页里。 -

- - - - - - - -
- -
- - - - - - -
- - - - -
- - - - - - -

pagenote/pagenote

-
- - -
- - -
- -
- - - - - -
-
- -
- -
-
- - - master - - - - -
-
-
- Switch branches/tags - -
- - - -
- -
- -
- - -
- -
- - - - - - - - - - - - - - - - - -
- - -
-
-
-
- -
- -
- - -
- -
-
-
-

Name already in use

-
-
- -
-
-
-
- -
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch? -
- -
-
- - -
-
- - - - - -
- - - - - - - - -
- Code -
- -
-
- - -
- - -
-
- - - - - - - -
-
-

Latest commit

-
- -
- -
- -
- -
-
- - - - - -
-
- -
- 5503b87 -
-
-
-

Git stats

- -
-
-
-

Files

- - - - - Permalink - -
- - - Failed to load latest commit information. - - - -
-
-
-
Type
-
Name
-
Latest commit message
-
Commit time
-
- -
-
- -
- -
- .github -
- -
-
 
-
- -
-
 
-
- -
-
-
- -
- -
- .idea -
- -
-
 
-
- -
-
 
-
- -
-
-
- -
- -
- .vscode -
- -
-
 
-
- -
-
 
-
- -
-
-
- -
- -
- demos -
- -
-
 
-
- -
-
 
-
- -
-
-
- -
- - - -
-
 
-
- -
-
 
-
- -
-
-
- -
- -
- sdk -
- -
-
 
-
- -
-
 
-
- -
-
-
- -
- -
- shared -
- -
-
 
-
- -
-
 
-
- -
-
-
- -
- -
- snapshots -
- -
-
 
-
- -
-
 
-
- -
-
-
- -
- - - -
-
 
-
- -
-
 
-
- -
-
-
- -
- -
- .npmrc -
- -
-
 
-
- -
-
 
-
- -
-
-
- -
- -
- readme.md -
- -
-
 
-
- -
-
 
-
- -
-
- -
- -
- - -
- - - - -
- -
-
- - -

- readme.md -

-
-
- -
-

关于本项目

-

在网页里选中内容后、高亮、批注、分享,以及扩展你需要的功能,如反馈,搜索等。

-

demo

-

使用方式

-
npm install pagenote --save
-
-import Pagenote from 'pagenote';
-import 'pagenote/dist/pagenote.css';
-var pagenote = new Pagenote('demos',option);
-pagenote.init();
-

目录

-
-- demos // 存静态的演示页面
--- sdk // PAGENOTE 的核心SDK代码
--- snapshots // 项目 demos 图
-
-
-
- -
- - -
-
- -
-
-
-

About

- -

- 超简单的网页关键词高亮、标注SDK、能把笔记留在网页里。 -

-
- - - pagenote.cn/ - -
- -

Topics

-
- - -
- -

Resources

- - - - - - - - - -

Stars

- - -

Watchers

- - -

Forks

- - -
-
- - - - - - -
-
- -

Sponsor this project

- -
    -
-
- -
-
- - -
-
-

- - Packages -

- - -
- No packages published
-
- - - -
-
- - - - - - - - -
-
- -
- -
- - -
- -
- - -
-
- -
- - - - - - - - - - - - - - - - - - - - - diff --git a/src/page_test/tailwind.html b/src/page_test/tailwind.html deleted file mode 100644 index 061c333..0000000 --- a/src/page_test/tailwind.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - Badge — Tailwind CSS Components - - - - - - - - - - - - - - - - - - - -

Badge

Badges are used to inform the user of the status of specific data.

Class name
Type
badge Component Container element
badge-outline
Modifier
transparent badge with [colorful] border
badge-primary
Modifier
badge with `primary` color
badge-secondary
Modifier
badge with `secondary` color
badge-accent
Modifier
badge with `accent` color
badge-ghost
Modifier
badge with `ghost` color
badge-info
Modifier
badge with `info` color
badge-success
Modifier
badge with `success` color
badge-warning
Modifier
badge with `warning` color
badge-error
Modifier
badge with `error` color
badge-lg
Responsive
badge with large size
badge-md
Responsive
badge with medium size (default)
badge-sm
Responsive
badge with small size
badge-xs
Responsive
badge with extra small size
# Badge
Badge
# Badge with brand colors
neutral
primary
secondary
accent
ghost
# Outline badge
neutral
primary
secondary
accent
# Badge sizes
987,654
987,654
987,654
987,654
# Empty badge
<div className="badge badge-lg"></div>
-<div className="badge badge-md"></div>
-<div className="badge badge-sm"></div>
-<div className="badge badge-xs"></div>
<div className="badge badge-lg"></div>
-<div className="badge badge-md"></div>
-<div className="badge badge-sm"></div>
-<div className="badge badge-xs"></div>
# Badge with state colors
- info
- success
- warning
- error
# Badge in a text

Heading - NEW

Heading - NEW

Heading - NEW

Heading - NEW
# Badge in a button
Do you have a question? ask the community
Do you see a bug? open an issue on GitHub
Do you like daisyUI? tweet about it!
Support daisyUI's development: - Open Collective
Badge — Tailwind CSS Components
diff --git a/src/page_test/tailwindcss.html b/src/page_test/tailwindcss.html deleted file mode 100644 index 3ad0ba4..0000000 --- a/src/page_test/tailwindcss.html +++ /dev/null @@ -1,523 +0,0 @@ - -Tailwind CSS 中文文档 - 无需离开您的HTML,即可快速建立现代网站。

无需离开您的HTML,即可快速建立现代网站。

Tailwind CSS 是一个功能类优先的 CSS 框架,它集成了诸如 flex, pt-4, text-center rotate-90 这样的的类,它们能直接在脚本标记语言中组合起来,构建出任何设计。

开始使用
“Tailwind CSS is the only framework that I've seen scale on large teams. It’s easy to customize, adapts to any design, and the build size is tiny.”

Sarah Dayan

Staff Engineer, Algolia

<figure class="bg-gray-100 rounded-xl">
-  <img class="w-32 h-32" src="/sarah-dayan.jpg" alt="" width="384" height="512">
-  <div class="pt-6 space-y-4">
-    <blockquote>
-      <p class="text-lg">
-        “Tailwind CSS is the only framework that I've seen scale
-        on large teams. It’s easy to customize, adapts to any design,
-        and the build size is tiny.”
-      </p>
-    </blockquote>
-    <figcaption>
-      <div>
-        Sarah Dayan
-      </div>
-      <div>
-        Staff Engineer, Algolia
-      </div>
-    </figcaption>
-  </div>
-</figure>
-

“最佳实践”实际上并不起作用。

我曾经写过 几千字的文章 来说明为什么传统的 “语义化类名” 是 CSS 难以维护的原因, 但事实是除非您实际尝试过,您永远不会相信我。 如果您能抑制住想吐槽的冲动,给它一个机会,我真的觉得您会怀疑您是怎么用其他方式来使用 CSS 的。

Adam Wathan
Tailwind CSS 创始人
  • 我直到现在才开始使用 Tailwind CSS,真是个白痴。

    Ryan Florence
    Remix & React Training
    Original tweet by Ryan Florence
  • 如果我今天不得不推荐一种编程方法,那就是使用 Tailwind CSS 的 HTML + CSS。

    Guillermo Rauch
    Vercel
    Original tweet by Guillermo Rauch
  • 我没有任何设计技能,但使用 Tailwind 可以轻松创建美观的网站,而这正是我在 CSS 框架中想要的一切。

    Sara Vieira
    CodeSandbox
  • I started using @tailwindcss. I instantly fell in love with their responsive modifiers, thorough documentation, and how easy it was customizing color palettes.

    Dacey Nolan
    软件工程师
    Original tweet by Dacey Nolan
  • Loved it the very moment I used it.

    Gilbert Rabut Tsurwa
    网页设计师
    Original tweet by Gilbert Rabut Tsurwa
  • 我刚开始接手我的工作的时候很好奇为什么上一个开发者在我们的项目中使用了 Tailwind,但几天之内,我便开始在我所有的个人项目中使用 Tailwind 了。

    Madeline Campbell
    全栈开发人员
    Original tweet by Madeline Campbell
  • There’s one thing that sucks about @tailwindcss - once you’ve used it on a handful of projects it is a real pain in the ass to write normal CSS again.

    Graeme Houston
    JavaScript 开发人员
    Original tweet by Graeme Houston
  • Okay, I’m officially *all* in on the @tailwindcss hype train. Never thought building websites could be so ridiculously fast and flexible.

    Aaron Bushnell
    Programmer @ TrendyMinds
    Original tweet by Aaron Bushnell
  • 使用 CSS 已有十多年了,Tailwind 使我的生活更加轻松。它仍然是CSS,您可以使用 flex,grid 等,但是编写和维护起来更快。

    Debbie O'Brien
    Head of Learning @ Nuxt.js
    Original tweet by Debbie O'Brien
  • 好的,@tailwindcss 震惊了我,现在我感觉就像是个白痴。Okay, @tailwindcss just clicked for me and now I feel like a #!@%&$% idiot.

    Ken Wheeler
    React 工程师
    Original tweet by Ken Wheeler
  • 过去几个月我一直在使用 @tailwindcss,真是太神奇了。我之前已经使用过一些功能类,但 Tailwind 是功能类优先的最正确的方式。

    Jad Limcaco
    设计师
    Original tweet by Jad Limcaco
  • 在过去的两周中终于在实际的客户端项目上使用@tailwindcss之后,我再也不想手动编写 CSS 了。我是一个怀疑论者,但这想法是真实的。

    Luke Redpath
    Ruby & iOS 开发者
    Original tweet by Luke Redpath
  • 我不认为我会喜欢 @tailwindcss... 但花了一天时间将其用于 POC 后,我开始喜欢它!我希望当我们启动公司设计系统时就已经意识到这个问题,并认真考虑进行彻底的重建。

    Jon Bloomer
    前端开发人员
    Original tweet by Jon Bloomer
  • 起初 @tailwindcss 看起来很不愉快,但是现在我迷上了它。

    Andrew Gilliland
    前端开发人员
    Original tweet by Andrew Gilliland

基于约束

设计系统的API。

功能类可以帮助您在系统的约束下工作,而不是在您的样式表中堆满任意的值。它们可以让您轻松地在颜色选择、间距、排版、阴影以及其他一切构成一个精心设计的系统的元素上保持一致。

了解更多 ->

Width

  • w-64
  • w-56
  • w-48
  • w-40
  • w-32
  • w-24
  • w-20
  • w-16
  • w-12
  • w-10
<ul class="space-y-4">
<li>
<div class="w-64 h-3 bg-gradient-to-br from-fuchsia-500 to-purple-600"></div>
</li>
<li>
<div class="w-56 h-3 bg-gradient-to-br from-fuchsia-500 to-purple-600"></div>
</li>
<li>
<div class="w-48 h-3 bg-gradient-to-br from-fuchsia-500 to-purple-600"></div>
</li>
<li>
<div class="w-40 h-3 bg-gradient-to-br from-fuchsia-500 to-purple-600"></div>
</li>
<li>
<div class="w-32 h-3 bg-gradient-to-br from-fuchsia-500 to-purple-600"></div>
</li>
<li>
<div class="w-24 h-3 bg-gradient-to-br from-fuchsia-500 to-purple-600"></div>
</li>
<li>
<div class="w-20 h-3 bg-gradient-to-br from-fuchsia-500 to-purple-600"></div>
</li>
<li>
<div class="w-16 h-3 bg-gradient-to-br from-fuchsia-500 to-purple-600"></div>
</li>
<li>
<div class="w-12 h-3 bg-gradient-to-br from-fuchsia-500 to-purple-600"></div>
</li>
<li>
<div class="w-10 h-3 bg-gradient-to-br from-fuchsia-500 to-purple-600"></div>
</li>
</ul>

构建任何东西

构建您想要的任何东西。

由于 Tailwind 是非常底层的,因此它从不鼓励您设计相同的站点。即使使用相同的调色板和大小比例,也可以轻松的在下个项目中为同一个组件设计出完全不同的外观。

开始 ->
<div class="flex">
-  <div class="flex-none w-48 relative">
-    <img src="/classic-utility-jacket.jpg" alt="" class="absolute inset-0 w-full h-full object-cover" />
-  </div>
-  <form class="flex-auto p-6">
-    <div class="flex flex-wrap">
-      <h1 class="flex-auto text-xl font-semibold">
-          Classic Utility Jacket
-      </h1>
-      <div class="text-xl font-semibold text-gray-500">
-          $110.00
-      </div>
-      <div class="w-full flex-none text-sm font-medium text-gray-500 mt-2">
-        In stock
-      </div>
-    </div>
-    <div class="flex items-baseline mt-4 mb-6">
-      <div class="space-x-2 flex">
-        <label>
-          <input class="w-9 h-9 flex items-center justify-center bg-gray-100 rounded-lg" name="size" type="radio" value="xs" checked>
-          XS
-        </label>
-        <label>
-          <input class="w-9 h-9 flex items-center justify-center" name="size" type="radio" value="s">
-          S
-        </label>
-        <label>
-          <input class="w-9 h-9 flex items-center justify-center" name="size" type="radio" value="m">
-          M
-        </label>
-        <label>
-          <input class="w-9 h-9 flex items-center justify-center" name="size" type="radio" value="l">
-          L
-        </label>
-        <label>
-          <input class="w-9 h-9 flex items-center justify-center" name="size" type="radio" value="xl">
-          XL
-        </label>
-      </div>
-      <div class="ml-auto text-sm text-gray-500 underline">Size Guide</div>
-    </div>
-    <div class="flex space-x-3 mb-4 text-sm font-medium">
-      <div class="flex-auto flex space-x-3">
-        <button class="w-1/2 flex items-center justify-center rounded-md bg-black text-white" type="submit">Buy now</button>
-        <button class="w-1/2 flex items-center justify-center rounded-md border border-gray-300" type="button">Add to bag</button>
-      </div>
-      <button class="flex-none flex items-center justify-center w-9 h-9 rounded-md text-gray-400 border border-gray-300" type="button" aria-label="like">
-        <svg width="20" height="20" fill="currentColor">
-          <path fill-rule="evenodd" clip-rule="evenodd" d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z" />
-        </svg>
-      </button>
-    </div>
-    <p class="text-sm text-gray-500">
-      Free shipping on all continental US orders.
-    </p>
-  </form>
-</div>
-
-

性能

生产环境的体积非常小。

Tailwind automatically removes all unused CSS when building for production, which means your final CSS bundle is the smallest it could possibly be. In fact, most Tailwind projects ship less than 10kB of CSS to the client.

了解更多 ->
Production build
2,413.4kB
Purged
0 unused classes
fixed flex-col rounded-sm shadow px-4 justify-content text-center flex-shrink-0 md:text-left h-16 w-16 md:h-24 md:w-24 rounded-full mx-auto text-lg text-purple-500 md:text-left text-gray-600 text-green-400 text-blue-500 rounded-pill p-4 max-w-screen-xl mt-5 leading-7 whitespace-nowrap sm:gap-6 lg:max-w-4xl lg:mx-auto xl:max-w-none flex-1 xl:mx-0 xl:grid-cols-4 border border-gray-200 text-4xl leading-6 leading-10 font-extrabold leading-5 h-5 w-5 text-green-500 text-5xl leading-none font-extrabold text-white tracking-tight border-t text-sm border-indigo-600 py-4 font-medium px-5 flex items-center space-x-3 text-base leading-6 text-white absolute right-full ml-4 bottom-0 transform -translate-x-1/2 py-3 mx-4 w-full duration-150 h-full transition py-0 pl-4 pr-8 border-transparent bg-transparent text-gray-500 px-5 py-3 appearance-none underline bg-indigo-700 min-w-full divide-y divide-gray-200 items-baseline text-indigo-600 hover:text-indigo-500
<div class="fixed inset-0 flex items-end justify-center px-4 py-6 pointer-events-none sm:p-6 sm:items-start sm:justify-end">
-  <div class="max-w-sm w-full bg-white shadow-lg rounded-lg pointer-events-auto">
-    <div class="rounded-lg shadow-xs overflow-hidden">
-      <div class="p-4">
-        <div class="flex items-start">
-          <div class="flex-shrink-0">
-            <svg class="h-6 w-6 text-green-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
-              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
-            </svg>
-          </div>
-          <div class="ml-3 w-0 flex-1 pt-0.5">
-            <p class="text-sm font-medium text-gray-900">
-              Successfully saved!
-            </p>
-            <p class="mt-1 text-sm text-gray-500">
-              Anyone with a link can now view this file.
-            </p>
-          </div>
-          <div class="ml-4 flex-shrink-0 flex">
-            <button class="inline-flex text-gray-400 focus:outline-none focus:text-gray-500 transition ease-in-out duration-150">
-              <svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
-                <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
-              </svg>
-            </button>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</div>
-
-

移动优先

一切皆是响应式的。

在您的 CSS 中使用大量复杂的媒体查询非常糟糕,因此 Tailwind 可以让您直接在 HTML 中构建响应式的设计。

在功能类前面加上屏幕大小标记,就可以查看在指定断点处的神奇表现。

了解更多 ->
workcation.com
-
-

Entire house

-

Beach House in Collingwood

-
-
-
- - - -
- 4.94 - (128) -
-
·
-
Collingwood, Ontario
-
-
-
-
-

- - Hosted by Kevin Francis -

-
Check availability
-
-
-
-
- -
-
- -
-
- -
-
-
-
-
<div class="grid grid-cols-1 sm:grid-cols-2 sm:px-8 sm:py-12 sm:gap-x-8 md:py-16">
<div class="relative z-10 col-start-1 row-start-1 px-4 pt-40 pb-3 bg-gradient-to-t from-black sm:bg-none">
<p class="text-sm font-medium text-white sm:mb-1 sm:text-gray-500">Entire house</p>
<h2 class="text-xl font-semibold text-white sm:text-2xl sm:leading-7 sm:text-black md:text-3xl">Beach House in Collingwood</h2>
</div>
<div class="col-start-1 row-start-2 px-4 sm:pb-16">
<div class="flex items-center text-sm font-medium my-5 sm:mt-2 sm:mb-4">
<svg width="20" height="20" fill="currentColor" class="text-violet-600">
<path d="M9.05 3.691c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.372 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.539 1.118l-2.8-2.034a1 1 0 00-1.176 0l-2.8 2.034c-.783.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.363-1.118l-2.8-2.034c-.784-.57-.381-1.81.587-1.81H7.03a1 1 0 00.95-.69L9.05 3.69z" />
</svg>
<div class="ml-1">
<span class="text-black">4.94</span>
<span class="sm:hidden md:inline">(128)</span>
</div>
<div class="text-base font-normal mx-2">·</div>
<div>Collingwood, Ontario</div>
</div>
<hr class="w-16 border-gray-300 hidden sm:block">
</div>
<div class="col-start-1 row-start-3 space-y-3 px-4">
<p class="flex items-center text-black text-sm font-medium">
<img src="/kevin-francis.jpg" alt="" class="w-6 h-6 rounded-full mr-2 bg-gray-100">
Hosted by Kevin Francis
</p>
<button type="button" class="bg-violet-100 text-violet-700 text-base font-semibold px-6 py-2 rounded-lg">Check availability</button>
</div>
<div class="col-start-1 row-start-1 flex sm:col-start-2 sm:row-span-3">
<div class="w-full grid grid-cols-3 grid-rows-2 gap-2">
<div class="relative col-span-3 row-span-2 md:col-span-2">
<img src="/beach-house.jpg" alt="" class="absolute inset-0 w-full h-full object-cover bg-gray-100 sm:rounded-lg" />
</div>
<div class="relative hidden md:block">
<img src="/beach-house-interior.jpg" alt="" class="absolute inset-0 w-full h-full object-cover rounded-lg bg-gray-100" />
</div>
<div class="relative hidden md:block">
<img src="/beach-house-view.jpg" alt="" class="absolute inset-0 w-full h-full object-cover rounded-lg bg-gray-100" />
</div>
</div>
</div>
</div>

状态变体

支持 hover 和 focus 状态

想要设置 hover 样式吗?在您想要添加的类前面添加 hover:。可以这样使用的状态还有 focus activedisabled focus-withinfocus-visible、甚至还有像 group-hover 这样的我们自己创造的复杂的状态。

学习更多 ->

Projects

New
  • Title
    API Integration
    Category
    Engineering
    Users
  • Title
    New Benefits Plan
    Category
    Human Resources
    Users
  • New Project
<section class="px-4 sm:px-6 lg:px-4 xl:px-6 pt-4 pb-4 sm:pb-6 lg:pb-4 xl:pb-6 space-y-4">
<header class="flex items-center justify-between">
<h2 class="text-lg leading-6 font-medium text-black">Projects</h2>
<button class="hover:bg-light-blue-200 hover:text-light-blue-800 group flex items-center rounded-md bg-light-blue-100 text-light-blue-600 text-sm font-medium px-4 py-2">
<svg class="group-hover:text-light-blue-600 text-light-blue-500 mr-2" width="12" height="20" fill="currentColor">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 5a1 1 0 011 1v3h3a1 1 0 110 2H7v3a1 1 0 11-2 0v-3H2a1 1 0 110-2h3V6a1 1 0 011-1z"/>
</svg>
New
</button>
</header>
<form class="relative">
<svg width="20" height="20" fill="currentColor" class="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" />
</svg>
<input class="focus:border-light-blue-500 focus:ring-1 focus:ring-light-blue-500 focus:outline-none w-full text-sm text-black placeholder-gray-500 border border-gray-200 rounded-md py-2 pl-10" type="text" aria-label="Filter projects" placeholder="Filter projects" />
</form>
<ul class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-1 xl:grid-cols-2 gap-4">
<li x-for="item in items">
<a :href="item.url" class="hover:bg-light-blue-500 hover:border-transparent hover:shadow-lg group block rounded-lg p-4 border border-gray-200">
<dl class="grid sm:block lg:grid xl:block grid-cols-2 grid-rows-2 items-center">
<div>
<dt class="sr-only">Title</dt>
<dd class="group-hover:text-white leading-6 font-medium text-black">
{item.title}
</dd>
</div>
<div>
<dt class="sr-only">Category</dt>
<dd class="group-hover:text-light-blue-200 text-sm font-medium sm:mb-4 lg:mb-0 xl:mb-4">
{item.category}
</dd>
</div>
<div class="col-start-2 row-start-1 row-end-3">
<dt class="sr-only">Users</dt>
<dd class="flex justify-end sm:justify-start lg:justify-end xl:justify-start -space-x-2">
<img x-for="user in item.users" :src="user.avatar" :alt="user.name" width="48" height="48" class="w-7 h-7 rounded-full bg-gray-100 border-2 border-white" />
</dd>
</div>
</dl>
</a>
</li>
<li class="hover:shadow-lg flex rounded-lg">
<a href="/new" class="hover:border-transparent hover:shadow-xs w-full flex items-center justify-center rounded-lg border-2 border-dashed border-gray-200 text-sm font-medium py-4">
New Project
</a>
</li>
</ul>
</section>

组件驱动

担心复用性问题?大可不必

如果您在一遍又一遍的重复着相同的功能类,那么您最好将他们提取到一个组件或者模板片断,这样就会得到一个单一的源文件,因此可以在一个地方对他们修改。

了解更多 ->

Hank’s Juiciest Beef Burger

Time
20m
Difficulty
· Easy
Servings
· 4 servings
By
Hank Douglas
import Nav from ''
-import NavItem from ''
-import List from ''
-import ListItem from ''
-
-export default function Recipes({ recipes }) {
-  return (
-    <div className="divide-y divide-gray-100">
-      <Nav>
-        <NavItem href="/featured" isActive>Featured</NavItem>
-        <NavItem href="/popular">Popular</NavItem>
-        <NavItem href="/recent">Recent</NavItem>
-      </Nav>
-      <List>
-        {recipes.map((recipe) => (
-          <ListItem key={recipe.id} recipe={recipe} />
-        ))}
-      </List>
-    </div>
-  )
-}
-
-

想保持原来的使用习惯而不是组件框架模式?使用 Tailwind 的 @apply 指令,复制和粘贴那些类名列表,就可以把重复的功能类抽取到一个自定义的 CSS 类中。

了解更多 ->

Weekly one-on-one

Date and time
-
Location
Kitchener, ON
Description
No meeting description
Attendees
Andrew Parsons
Decline
Accept

styles.css

.btn {
-  @apply text-base font-medium rounded-lg p-3;
-}
-
-.btn--primary {
-  @apply bg-rose-500 text-white;
-}
-
-.btn--secondary {
-  @apply bg-gray-100 text-black;
-}
-
-

index.html

</dd>
</div>
</dl>
<footer class="grid grid-cols-2 gap-x-6">
<button class="btn btn--secondary">Decline</button>
<button class="btn btn--primary">Accept</button>
</footer>
</article>

深色模式

支持深色模式

Don’t want to be one of those websites that blinds people when they open it on their phone at 2am? Enable dark mode in your configuration file then throw dark: in front of any color utility to apply it when dark mode is active. Works for background colors, text colors, border colors, and even gradients.

了解更多 ->
-
- -
-

- Ep. 128 -

-

- Scaling CSS at Heroku with Utility Classes -

-

- Full Stack Radio -

-
-
-
-
-
-
-
-
24:16
-
75:50
-
-
-
-
-
- - - -
- -
- - - - - -
-
- - - - -
-
- - - - - -
- -
- 1.0x -
-
-
<div class="bg-white dark:bg-gray-800 rounded-tl-xl sm:rounded-t-xl p-4 pb-6 sm:p-8 lg:p-4 lg:pb-6 xl:p-8 space-y-6 sm:space-y-8 lg:space-y-6 xl:space-y-8">
-  <div class="flex items-center space-x-3.5 sm:space-x-5 lg:space-x-3.5 xl:space-x-5">
-    <img src="/full-stack-radio.png" alt="" width="160" height="160" class="flex-none w-20 h-20 rounded-lg bg-gray-100" />
-    <div class="min-w-0 flex-auto space-y-0.5">
-      <p class="text-lime-600 dark:text-lime-400 text-sm sm:text-base lg:text-sm xl:text-base font-semibold uppercase">
-        <abbr title="Episode">Ep.</abbr> 128
-      </p>
-      <h2 class="text-black dark:text-white text-base sm:text-xl lg:text-base xl:text-xl font-semibold truncate">
-        Scaling CSS at Heroku with Utility Classes
-      </h2>
-      <p class="text-gray-500 dark:text-gray-400 text-base sm:text-lg lg:text-base xl:text-lg font-medium">
-        Full Stack Radio
-      </p>
-    </div>
-  </div>
-  <div class="space-y-2">
-    <div class="bg-gray-200 dark:bg-black rounded-full overflow-hidden">
-      <div class="bg-lime-500 dark:bg-lime-400 w-1/2 h-1.5" role="progressbar" aria-valuenow="1456" aria-valuemin="0" aria-valuemax="4550"></div>
-    </div>
-    <div class="text-gray-500 dark:text-gray-400 flex justify-between text-sm font-medium tabular-nums">
-      <div>24:16</div>
-      <div>75:50</div>
-    </div>
-  </div>
-</div>
-<div class="bg-gray-50 text-black dark:bg-gray-900 dark:text-white lg:rounded-b-xl py-4 px-1 sm:px-3 lg:px-1 xl:px-3 grid grid-cols-5 sm:grid-cols-7 lg:grid-cols-5 xl:grid-cols-7 items-center">
-  <button type="button" class="mx-auto">
-    <svg width="24" height="24" fill="none">
-      <path d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
-    </svg>
-  </button>
-  <button type="button" class="hidden sm:block lg:hidden xl:block mx-auto">
-    <svg width="17" height="18">
-      <path d="M0 0h2v18H0V0zM4 9l13-9v18L4 9z" fill="currentColor" />
-    </svg>
-  </button>
-  <button type="button" class="mx-auto">
-    <svg width="34" height="39" fill="none">
-      <path d="M12.878 26.12c1.781 0 3.09-1.066 3.085-2.515.004-1.104-.665-1.896-1.824-2.075v-.068c.912-.235 1.505-.95 1.5-1.93.005-1.283-1.048-2.379-2.727-2.379-1.602 0-2.89.968-2.932 2.387h1.274c.03-.801.784-1.287 1.64-1.287.892 0 1.475.541 1.471 1.346.004.844-.673 1.398-1.64 1.398h-.738v1.074h.737c1.21 0 1.91.614 1.91 1.491 0 .848-.738 1.424-1.765 1.424-.946 0-1.683-.486-1.734-1.262H9.797c.055 1.424 1.317 2.395 3.08 2.395zm7.734.025c2.016 0 3.196-1.645 3.196-4.504 0-2.838-1.197-4.488-3.196-4.488-2.003 0-3.196 1.645-3.2 4.488 0 2.855 1.18 4.5 3.2 4.504zm0-1.138c-1.18 0-1.892-1.185-1.892-3.366.004-2.174.716-3.371 1.892-3.371 1.172 0 1.888 1.197 1.888 3.37 0 2.182-.712 3.367-1.888 3.367z" fill="currentColor" />
-      <path d="M1 22c0 8.837 7.163 16 16 16s16-7.163 16-16S25.837 6 17 6" stroke="currentColor" stroke-width="1.5" />
-      <path d="M17 0L9 6l8 6V0z" fill="currentColor" />
-    </svg>
-  </button>
-  <button type="button" class="mx-auto">
-    <svg width="50" height="50" fill="none">
-      <circle class="text-gray-300 dark:text-gray-500" cx="25" cy="25" r="24" stroke="currentColor" stroke-width="1.5" />
-      <path d="M18 16h4v18h-4V16zM28 16h4v18h-4z" fill="currentColor" />
-    </svg>
-  </button>
-  <button type="button" class="mx-auto">
-    <svg width="34" height="39" fill="none">
-      <path d="M12.878 26.12c1.781 0 3.09-1.066 3.085-2.515.004-1.104-.665-1.896-1.824-2.075v-.068c.912-.235 1.505-.95 1.5-1.93.005-1.283-1.048-2.379-2.727-2.379-1.602 0-2.89.968-2.932 2.387h1.274c.03-.801.784-1.287 1.64-1.287.892 0 1.475.541 1.471 1.346.004.844-.673 1.398-1.64 1.398h-.738v1.074h.737c1.21 0 1.91.614 1.91 1.491 0 .848-.738 1.424-1.765 1.424-.946 0-1.683-.486-1.734-1.262H9.797c.055 1.424 1.317 2.395 3.08 2.395zm7.734.025c2.016 0 3.196-1.645 3.196-4.504 0-2.838-1.197-4.488-3.196-4.488-2.003 0-3.196 1.645-3.2 4.488 0 2.855 1.18 4.5 3.2 4.504zm0-1.138c-1.18 0-1.892-1.185-1.892-3.366.004-2.174.716-3.371 1.892-3.371 1.172 0 1.888 1.197 1.888 3.37 0 2.182-.712 3.367-1.888 3.367z" fill="currentColor" />
-      <path d="M33 22c0 8.837-7.163 16-16 16S1 30.837 1 22 8.163 6 17 6" stroke="currentColor" stroke-width="1.5" />
-      <path d="M17 0l8 6-8 6V0z" fill="currentColor" />
-    </svg>
-  </button>
-  <button type="button" class="hidden sm:block lg:hidden xl:block mx-auto">
-    <svg width="17" height="18" viewBox="0 0 17 18" fill="none">
-      <path d="M17 0H15V18H17V0Z" fill="currentColor" />
-      <path d="M13 9L0 0V18L13 9Z" fill="currentColor" />
-    </svg>
-  </button>
-  <button type="button" class="mx-auto border border-gray-300 rounded-md text-sm font-medium py-0.5 px-2 text-gray-500 dark:border-gray-600 dark:text-gray-400">
-    1.0x
-  </button>
-</div>
-

定制化

易于扩展、调整和改变。

Tailwind 包含一组精心设计的开箱即用的默认值,但实际上,所有内容都可定制,比如调色板、间距比例、盒子阴影以及鼠标光标样式。

使用 tailwind.config.js 文件构建您自己的设计系统,然后让 Tailwind 将其转换成您自己的定制 CSS 框架。

了解更多 ->

Typography

font-display
Inter
font-body
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mi ultrices non pharetra, eros enim. Habitant suspendisse ultricies.

Color

bg-primary-{50-900}
bg-gray-{50-900}
module.exports = {
-  theme: {
-    fontFamily: {
-      display: ['Inter', 'system-ui', 'sans-serif'],
-      body: ['Inter', 'system-ui', 'sans-serif'],
-    },
-    colors: {
-      primary: {
-        50: '#eef2ff',
-        100: '#e0e7ff',
-        200: '#c7d2fe',
-        300: '#a5b4fc',
-        400: '#818cf8',
-        500: '#6366f1',
-        600: '#4f46e5',
-        700: '#4338ca',
-        800: '#3730a3',
-        900: '#312e81',
-      },
-      gray: {
-        50: '#fafafa',
-        100: '#f4f4f5',
-        200: '#e4e4e7',
-        300: '#d4d4d8',
-        400: '#a1a1aa',
-        500: '#71717a',
-        600: '#52525b',
-        700: '#3f3f46',
-        800: '#27272a',
-        900: '#18181b',
-      },
-    },
-  },
-}
-

现代特性

前沿特性带来舒服体验

Tailwind 具有绝对的现代性,它利用所有最新和最优秀的 CSS 特性为开发者带来尽可能愉悦的体验。

我们提供了一流的 CSS grid 支持,由 CSS 变量支撑的可组合的转换和渐变色,对诸如 :focus-visible 等现代状态选择器的支持,以及其它更多的功能。

了解更多 ->
1
2
3
4
5
<div class="grid grid-flow-col grid-rows-2 grid-cols-3 gap-4">
-  <div>
-    1
-  </div>
-  <div class="col-start-3">
-    2
-  </div>
-  <div>
-    3
-  </div>
-  <div>
-    4
-  </div>
-  <div class="row-start-1 col-start-2 col-span-2">
-    5
-  </div>
-</div>
-
-

编辑器工具

世界一流的 IDE 集成。

担心记不住所有的类名吗?VS Code 的 Tailwind CSS 智能提示扩展涵盖了所有的类。

在编辑器内既可得到智能的自动完成建议、提示及类定义等功能,而且无需配置。

了解更多 ->
<div class="w-full flex items-center justify-between block p-6 space-x-6">
-  <div class="flex-1 truncate">
-    <div class="flex items-center space-x-3">
-      <h3 class="text-gray-900 text-sm font-medium truncate">Jane Cooper</h3>
-      <span class="text-teal-600">Admin</span>
-    </div>
-    <p class="mt-1 text-gray-500 text-sm truncate">Regional Paradigm Technician</p>
-  </div>
-  <img class="w-10 h-10 bg-gray-300 rounded-full flex-shrink-0" src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&amp;ixid=eyJhcHBfaWQiOjEyMDd9&amp;auto=format&amp;fit=facearea&amp;facepad=4&amp;w=256&amp;h=256&amp;q=60" alt="">
-</div>
-<div class="border-t border-gray-200">
-  <div class="-mt-px flex">
-    <div class="w-0 flex-1 flex border-r border-gray-200">
-      <a href="#" class="relative -mr-px w-0 flex-1 inline-flex items-center justify-center py-4 text-sm text-gray-700 font-medium border border-transparent rounded-bl-lg hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 focus:z-10 transition ease-in-out duration-150">
-        <svg class="w-5 h-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
-          <path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z" />
-          <path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z" />
-        </svg>
-        <span class="ml-3">Email</span>
-      </a>
-    </div>
-  </div>
-</div>
-

Problems

  • 'flex' applies the same CSS property as 'block'.

  • 'block' applies the same CSS property as 'flex'.

现成的组件

使用 Tailwind UI 加快开发速度

Tailwind UI 是由 Tailwind CSS 创始团队开发设计的一套精美的、完全响应式的 UI 组件,提供了数百个现成可用的示例供您选择,确保能帮助您找到一个构建项目的完美的起点。

了解更多 ->
diff --git a/src/style.css b/src/style.css deleted file mode 100644 index ac37d84..0000000 --- a/src/style.css +++ /dev/null @@ -1,97 +0,0 @@ -:root { - font-family: Inter, Avenir, Helvetica, Arial, sans-serif; - font-size: 16px; - line-height: 24px; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-text-size-adjust: 100%; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -#app { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; -} -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} -.logo.vanilla:hover { - filter: drop-shadow(0 0 2em #3178c6aa); -} - -.card { - padding: 2em; -} - -.read-the-docs { - color: #888; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} diff --git a/src/typescript.svg b/src/typescript.svg deleted file mode 100644 index d91c910..0000000 --- a/src/typescript.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts deleted file mode 100644 index 11f02fe..0000000 --- a/src/vite-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/vite.config.ts b/vite.config.ts deleted file mode 100644 index 4231653..0000000 --- a/vite.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { defineConfig } from 'vite' - -export default defineConfig({ - build: { - lib: { - entry: './lib/index.ts', - name: 'WhatsElement', - fileName: 'index' - } - } -}) diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..993d806 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,5102 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.2.0", "@ampproject/remapping@^2.2.1": + version "2.2.1" + resolved "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": + version "7.23.5" + resolved "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== + dependencies: + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" + +"@babel/compat-data@^7.23.5": + version "7.23.5" + resolved "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" + integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== + +"@babel/core@^7.19.6", "@babel/core@^7.21.8": + version "7.23.7" + resolved "https://registry.npmmirror.com/@babel/core/-/core-7.23.7.tgz#4d8016e06a14b5f92530a13ed0561730b5c6483f" + integrity sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.7" + "@babel/parser" "^7.23.6" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.7" + "@babel/types" "^7.23.6" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.21.5", "@babel/generator@^7.23.6": + version "7.23.6" + resolved "https://registry.npmmirror.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" + integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== + dependencies: + "@babel/types" "^7.23.6" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.23.6": + version "7.23.6" + resolved "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" + integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== + dependencies: + "@babel/compat-data" "^7.23.5" + "@babel/helper-validator-option" "^7.23.5" + browserslist "^4.22.2" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== + +"@babel/helpers@^7.23.7": + version "7.23.8" + resolved "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.23.8.tgz#fc6b2d65b16847fd50adddbd4232c76378959e34" + integrity sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.7" + "@babel/types" "^7.23.6" + +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.20.15", "@babel/parser@^7.21.3", "@babel/parser@^7.21.8", "@babel/parser@^7.22.15", "@babel/parser@^7.23.6": + version "7.23.6" + resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.23.6.tgz#ba1c9e512bda72a47e285ae42aff9d2a635a9e3b" + integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== + +"@babel/runtime@^7.18.3": + version "7.23.8" + resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.8.tgz#8ee6fe1ac47add7122902f257b8ddf55c898f650" + integrity sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/template@^7.22.15": + version "7.22.15" + resolved "https://registry.npmmirror.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + +"@babel/traverse@^7.21.5", "@babel/traverse@^7.23.7": + version "7.23.7" + resolved "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.23.7.tgz#9a7bf285c928cb99b5ead19c3b1ce5b310c9c305" + integrity sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.6" + "@babel/types" "^7.23.6" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.20.0", "@babel/types@^7.21.5", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6": + version "7.23.6" + resolved "https://registry.npmmirror.com/@babel/types/-/types-7.23.6.tgz#be33fdb151e1f5a56877d704492c240fc71c7ccd" + integrity sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@esbuild/android-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" + integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== + +"@esbuild/android-arm@0.15.18": + version "0.15.18" + resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.15.18.tgz#266d40b8fdcf87962df8af05b76219bc786b4f80" + integrity sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw== + +"@esbuild/android-arm@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682" + integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== + +"@esbuild/android-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2" + integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== + +"@esbuild/darwin-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1" + integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA== + +"@esbuild/darwin-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d" + integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== + +"@esbuild/freebsd-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54" + integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== + +"@esbuild/freebsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e" + integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== + +"@esbuild/linux-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0" + integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== + +"@esbuild/linux-arm@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0" + integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== + +"@esbuild/linux-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7" + integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== + +"@esbuild/linux-loong64@0.15.18": + version "0.15.18" + resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz#128b76ecb9be48b60cf5cfc1c63a4f00691a3239" + integrity sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ== + +"@esbuild/linux-loong64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d" + integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== + +"@esbuild/linux-mips64el@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231" + integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== + +"@esbuild/linux-ppc64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb" + integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== + +"@esbuild/linux-riscv64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6" + integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== + +"@esbuild/linux-s390x@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071" + integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== + +"@esbuild/linux-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338" + integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== + +"@esbuild/netbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1" + integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== + +"@esbuild/openbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae" + integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== + +"@esbuild/sunos-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d" + integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== + +"@esbuild/win32-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9" + integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== + +"@esbuild/win32-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102" + integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== + +"@esbuild/win32-x64@0.18.20": + version "0.18.20" + resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d" + integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== + +"@expo/spawn-async@1.7.2": + version "1.7.2" + resolved "https://registry.npmmirror.com/@expo/spawn-async/-/spawn-async-1.7.2.tgz#fcfe66c3e387245e72154b1a7eae8cada6a47f58" + integrity sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew== + dependencies: + cross-spawn "^7.0.3" + +"@ianvs/prettier-plugin-sort-imports@4.1.1": + version "4.1.1" + resolved "https://registry.npmmirror.com/@ianvs/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.1.1.tgz#364fb49c4104d577c80750dcc27a7bae4338095d" + integrity sha512-kJhXq63ngpTQ2dxgf5GasbPJWsJA3LgoOdd7WGhpUSzLgLgI4IsIzYkbJf9kmpOHe7Vdm/o3PcRA3jmizXUuAQ== + dependencies: + "@babel/core" "^7.21.8" + "@babel/generator" "^7.21.5" + "@babel/parser" "^7.21.8" + "@babel/traverse" "^7.21.5" + "@babel/types" "^7.21.5" + semver "^7.5.2" + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": + version "1.4.15" + resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.20" + resolved "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@lezer/common@^0.15.0", "@lezer/common@^0.15.7": + version "0.15.12" + resolved "https://registry.npmmirror.com/@lezer/common/-/common-0.15.12.tgz#2f21aec551dd5fd7d24eb069f90f54d5bc6ee5e9" + integrity sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig== + +"@lezer/common@^1.0.0": + version "1.2.0" + resolved "https://registry.npmmirror.com/@lezer/common/-/common-1.2.0.tgz#f10493d12c4a196a02ff5fcf5695a516a4039aae" + integrity sha512-Wmvlm4q6tRpwiy20TnB3yyLTZim38Tkc50dPY8biQRwqE+ati/wD84rm3N15hikvdT4uSg9phs9ubjvcLmkpKg== + +"@lezer/lr@^0.15.4": + version "0.15.8" + resolved "https://registry.npmmirror.com/@lezer/lr/-/lr-0.15.8.tgz#1564a911e62b0a0f75ca63794a6aa8c5dc63db21" + integrity sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg== + dependencies: + "@lezer/common" "^0.15.0" + +"@lezer/lr@^1.0.0": + version "1.3.14" + resolved "https://registry.npmmirror.com/@lezer/lr/-/lr-1.3.14.tgz#59d4a3b25698bdac0ef182fa6eadab445fc4f29a" + integrity sha512-z5mY4LStlA3yL7aHT/rqgG614cfcvklS+8oFRFBYrs4YaWLJyKKM4+nN6KopToX0o9Hj6zmH6M5kinOYuy06ug== + dependencies: + "@lezer/common" "^1.0.0" + +"@ljharb/through@^2.3.11": + version "2.3.11" + resolved "https://registry.npmmirror.com/@ljharb/through/-/through-2.3.11.tgz#783600ff12c06f21a76cc26e33abd0b1595092f9" + integrity sha512-ccfcIDlogiXNq5KcbAwbaO7lMh3Tm1i3khMPYpxlK8hH/W53zN81KM9coerRLOnTGu3nfXIniAmQbRI9OxbC0w== + dependencies: + call-bind "^1.0.2" + +"@lmdb/lmdb-darwin-arm64@2.5.2": + version "2.5.2" + resolved "https://registry.npmmirror.com/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.2.tgz#bc66fa43286b5c082e8fee0eacc17995806b6fbe" + integrity sha512-+F8ioQIUN68B4UFiIBYu0QQvgb9FmlKw2ctQMSBfW2QBrZIxz9vD9jCGqTCPqZBRbPHAS/vG1zSXnKqnS2ch/A== + +"@lmdb/lmdb-darwin-arm64@2.7.11": + version "2.7.11" + resolved "https://registry.npmmirror.com/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.7.11.tgz#b717e72f023d4215d14e4c57433c711a53c782cf" + integrity sha512-r6+vYq2vKzE+vgj/rNVRMwAevq0+ZR9IeMFIqcSga+wMtMdXQ27KqQ7uS99/yXASg29bos7yHP3yk4x6Iio0lw== + +"@lmdb/lmdb-darwin-x64@2.5.2": + version "2.5.2" + resolved "https://registry.npmmirror.com/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.2.tgz#89d8390041bce6bab24a82a20392be22faf54ffc" + integrity sha512-KvPH56KRLLx4KSfKBx0m1r7GGGUMXm0jrKmNE7plbHlesZMuPJICtn07HYgQhj1LNsK7Yqwuvnqh1QxhJnF1EA== + +"@lmdb/lmdb-darwin-x64@2.7.11": + version "2.7.11" + resolved "https://registry.npmmirror.com/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.7.11.tgz#b42898b0742b4a82b8224b742b2d174c449cd170" + integrity sha512-jhj1aB4K8ycRL1HOQT5OtzlqOq70jxUQEWRN9Gqh3TIDN30dxXtiHi6EWF516tzw6v2+3QqhDMJh8O6DtTGG8Q== + +"@lmdb/lmdb-linux-arm64@2.5.2": + version "2.5.2" + resolved "https://registry.npmmirror.com/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.2.tgz#14fe4c96c2bb1285f93797f45915fa35ee047268" + integrity sha512-aLl89VHL/wjhievEOlPocoefUyWdvzVrcQ/MHQYZm2JfV1jUsrbr/ZfkPPUFvZBf+VSE+Q0clWs9l29PCX1hTQ== + +"@lmdb/lmdb-linux-arm64@2.7.11": + version "2.7.11" + resolved "https://registry.npmmirror.com/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.7.11.tgz#a8dc8e386d27006cfccbf2a8598290b63d03a9ec" + integrity sha512-7xGEfPPbmVJWcY2Nzqo11B9Nfxs+BAsiiaY/OcT4aaTDdykKeCjvKMQJA3KXCtZ1AtiC9ljyGLi+BfUwdulY5A== + +"@lmdb/lmdb-linux-arm@2.5.2": + version "2.5.2" + resolved "https://registry.npmmirror.com/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.2.tgz#05bde4573ab10cf21827339fe687148f2590cfa1" + integrity sha512-5kQAP21hAkfW5Bl+e0P57dV4dGYnkNIpR7f/GAh6QHlgXx+vp/teVj4PGRZaKAvt0GX6++N6hF8NnGElLDuIDw== + +"@lmdb/lmdb-linux-arm@2.7.11": + version "2.7.11" + resolved "https://registry.npmmirror.com/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.7.11.tgz#2103f48af28336efccaac008fe882dfce33e4ac5" + integrity sha512-dHfLFVSrw/v5X5lkwp0Vl7+NFpEeEYKfMG2DpdFJnnG1RgHQZngZxCaBagFoaJGykRpd2DYF1AeuXBFrAUAXfw== + +"@lmdb/lmdb-linux-x64@2.5.2": + version "2.5.2" + resolved "https://registry.npmmirror.com/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.2.tgz#d2f85afd857d2c33d2caa5b057944574edafcfee" + integrity sha512-xUdUfwDJLGjOUPH3BuPBt0NlIrR7f/QHKgu3GZIXswMMIihAekj2i97oI0iWG5Bok/b+OBjHPfa8IU9velnP/Q== + +"@lmdb/lmdb-linux-x64@2.7.11": + version "2.7.11" + resolved "https://registry.npmmirror.com/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.7.11.tgz#d21ac368022a662610540f2ba8bb6ff0b96a9940" + integrity sha512-vUKI3JrREMQsXX8q0Eq5zX2FlYCKWMmLiCyyJNfZK0Uyf14RBg9VtB3ObQ41b4swYh2EWaltasWVe93Y8+KDng== + +"@lmdb/lmdb-win32-x64@2.5.2": + version "2.5.2" + resolved "https://registry.npmmirror.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.2.tgz#28f643fbc0bec30b07fbe95b137879b6b4d1c9c5" + integrity sha512-zrBczSbXKxEyK2ijtbRdICDygRqWSRPpZMN5dD1T8VMEW5RIhIbwFWw2phDRXuBQdVDpSjalCIUMWMV2h3JaZA== + +"@lmdb/lmdb-win32-x64@2.7.11": + version "2.7.11" + resolved "https://registry.npmmirror.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.7.11.tgz#af2cb4ae6d3a92ecdeb1503b73079417525476d2" + integrity sha512-BJwkHlSUgtB+Ei52Ai32M1AOMerSlzyIGA/KC4dAGL+GGwVMdwG8HGCOA2TxP3KjhbgDPMYkv7bt/NmOmRIFng== + +"@mischnic/json-sourcemap@0.1.0": + version "0.1.0" + resolved "https://registry.npmmirror.com/@mischnic/json-sourcemap/-/json-sourcemap-0.1.0.tgz#38af657be4108140a548638267d02a2ea3336507" + integrity sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA== + dependencies: + "@lezer/common" "^0.15.7" + "@lezer/lr" "^0.15.4" + json5 "^2.2.1" + +"@mischnic/json-sourcemap@^0.1.0": + version "0.1.1" + resolved "https://registry.npmmirror.com/@mischnic/json-sourcemap/-/json-sourcemap-0.1.1.tgz#0ef9b015a8f575dd9a8720d9a6b4dbc988425906" + integrity sha512-iA7+tyVqfrATAIsIRWQG+a7ZLLD0VaOCKV2Wd/v4mqIU3J9c4jx9p7S0nw1XH3gJCKNBOOwACOPYYSUu9pgT+w== + dependencies: + "@lezer/common" "^1.0.0" + "@lezer/lr" "^1.0.0" + json5 "^2.2.1" + +"@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2": + version "3.0.2" + resolved "https://registry.npmmirror.com/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.2.tgz#44d752c1a2dc113f15f781b7cc4f53a307e3fa38" + integrity sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ== + +"@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.2": + version "3.0.2" + resolved "https://registry.npmmirror.com/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.2.tgz#f954f34355712212a8e06c465bc06c40852c6bb3" + integrity sha512-lwriRAHm1Yg4iDf23Oxm9n/t5Zpw1lVnxYU3HnJPTi2lJRkKTrps1KVgvL6m7WvmhYVt/FIsssWay+k45QHeuw== + +"@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.2": + version "3.0.2" + resolved "https://registry.npmmirror.com/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.2.tgz#45c63037f045c2b15c44f80f0393fa24f9655367" + integrity sha512-FU20Bo66/f7He9Fp9sP2zaJ1Q8L9uLPZQDub/WlUip78JlPeMbVL8546HbZfcW9LNciEXc8d+tThSJjSC+tmsg== + +"@msgpackr-extract/msgpackr-extract-linux-arm@3.0.2": + version "3.0.2" + resolved "https://registry.npmmirror.com/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.2.tgz#35707efeafe6d22b3f373caf9e8775e8920d1399" + integrity sha512-MOI9Dlfrpi2Cuc7i5dXdxPbFIgbDBGgKR5F2yWEa6FVEtSWncfVNKW5AKjImAQ6CZlBK9tympdsZJ2xThBiWWA== + +"@msgpackr-extract/msgpackr-extract-linux-x64@3.0.2": + version "3.0.2" + resolved "https://registry.npmmirror.com/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.2.tgz#091b1218b66c341f532611477ef89e83f25fae4f" + integrity sha512-gsWNDCklNy7Ajk0vBBf9jEx04RUxuDQfBse918Ww+Qb9HCPoGzS+XJTLe96iN3BVK7grnLiYghP/M4L8VsaHeA== + +"@msgpackr-extract/msgpackr-extract-win32-x64@3.0.2": + version "3.0.2" + resolved "https://registry.npmmirror.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.2.tgz#0f164b726869f71da3c594171df5ebc1c4b0a407" + integrity sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@parcel/bundler-default@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/bundler-default/-/bundler-default-2.9.3.tgz#df18c4b8390a03f83ac6c89da302f9edf48c8fe2" + integrity sha512-JjJK8dq39/UO/MWI/4SCbB1t/qgpQRFnFDetAAAezQ8oN++b24u1fkMDa/xqQGjbuPmGeTds5zxGgYs7id7PYg== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/graph" "2.9.3" + "@parcel/hash" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + nullthrows "^1.1.1" + +"@parcel/cache@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/cache/-/cache-2.8.3.tgz#169e130cf59913c0ed9fadce1a450e68f710e16f" + integrity sha512-k7xv5vSQrJLdXuglo+Hv3yF4BCSs1tQ/8Vbd6CHTkOhf7LcGg6CPtLw053R/KdMpd/4GPn0QrAsOLdATm1ELtQ== + dependencies: + "@parcel/fs" "2.8.3" + "@parcel/logger" "2.8.3" + "@parcel/utils" "2.8.3" + lmdb "2.5.2" + +"@parcel/cache@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/cache/-/cache-2.9.3.tgz#3ed40b79858fcb7c2c73c0ed4c9807cf2388c8b4" + integrity sha512-Bj/H2uAJJSXtysG7E/x4EgTrE2hXmm7td/bc97K8M9N7+vQjxf7xb0ebgqe84ePVMkj4MVQSMEJkEucXVx4b0Q== + dependencies: + "@parcel/fs" "2.9.3" + "@parcel/logger" "2.9.3" + "@parcel/utils" "2.9.3" + lmdb "2.7.11" + +"@parcel/codeframe@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/codeframe/-/codeframe-2.8.3.tgz#84fb529ef70def7f5bc64f6c59b18d24826f5fcc" + integrity sha512-FE7sY53D6n/+2Pgg6M9iuEC6F5fvmyBkRE4d9VdnOoxhTXtkEqpqYgX7RJ12FAQwNlxKq4suBJQMgQHMF2Kjeg== + dependencies: + chalk "^4.1.0" + +"@parcel/codeframe@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/codeframe/-/codeframe-2.9.3.tgz#056cacaeedae9318878bdee8ffc584178b10ba42" + integrity sha512-z7yTyD6h3dvduaFoHpNqur74/2yDWL++33rjQjIjCaXREBN6dKHoMGMizzo/i4vbiI1p9dDox2FIDEHCMQxqdA== + dependencies: + chalk "^4.1.0" + +"@parcel/compressor-raw@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/compressor-raw/-/compressor-raw-2.9.3.tgz#89f5a3667d844b277ecc3811faf44fc2eeacc8d3" + integrity sha512-jz3t4/ICMsHEqgiTmv5i1DJva2k5QRpZlBELVxfY+QElJTVe8edKJ0TiKcBxh2hx7sm4aUigGmp7JiqqHRRYmA== + dependencies: + "@parcel/plugin" "2.9.3" + +"@parcel/config-default@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/config-default/-/config-default-2.9.3.tgz#343172f9f91563ee6024a323eea9825ae89eedc3" + integrity sha512-tqN5tF7QnVABDZAu76co5E6N8mA9n8bxiWdK4xYyINYFIEHgX172oRTqXTnhEMjlMrdmASxvnGlbaPBaVnrCTw== + dependencies: + "@parcel/bundler-default" "2.9.3" + "@parcel/compressor-raw" "2.9.3" + "@parcel/namer-default" "2.9.3" + "@parcel/optimizer-css" "2.9.3" + "@parcel/optimizer-htmlnano" "2.9.3" + "@parcel/optimizer-image" "2.9.3" + "@parcel/optimizer-svgo" "2.9.3" + "@parcel/optimizer-swc" "2.9.3" + "@parcel/packager-css" "2.9.3" + "@parcel/packager-html" "2.9.3" + "@parcel/packager-js" "2.9.3" + "@parcel/packager-raw" "2.9.3" + "@parcel/packager-svg" "2.9.3" + "@parcel/reporter-dev-server" "2.9.3" + "@parcel/resolver-default" "2.9.3" + "@parcel/runtime-browser-hmr" "2.9.3" + "@parcel/runtime-js" "2.9.3" + "@parcel/runtime-react-refresh" "2.9.3" + "@parcel/runtime-service-worker" "2.9.3" + "@parcel/transformer-babel" "2.9.3" + "@parcel/transformer-css" "2.9.3" + "@parcel/transformer-html" "2.9.3" + "@parcel/transformer-image" "2.9.3" + "@parcel/transformer-js" "2.9.3" + "@parcel/transformer-json" "2.9.3" + "@parcel/transformer-postcss" "2.9.3" + "@parcel/transformer-posthtml" "2.9.3" + "@parcel/transformer-raw" "2.9.3" + "@parcel/transformer-react-refresh-wrap" "2.9.3" + "@parcel/transformer-svg" "2.9.3" + +"@parcel/core@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/core/-/core-2.9.3.tgz#91346afa57d7b731e7c961451462a51af940acf3" + integrity sha512-4KlM1Zr/jpsqWuMXr2zmGsaOUs1zMMFh9vfCNKRZkptf+uk8I3sugHbNdo+F5B+4e2yMuOEb1zgAmvJLeuH6ww== + dependencies: + "@mischnic/json-sourcemap" "^0.1.0" + "@parcel/cache" "2.9.3" + "@parcel/diagnostic" "2.9.3" + "@parcel/events" "2.9.3" + "@parcel/fs" "2.9.3" + "@parcel/graph" "2.9.3" + "@parcel/hash" "2.9.3" + "@parcel/logger" "2.9.3" + "@parcel/package-manager" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/profiler" "2.9.3" + "@parcel/source-map" "^2.1.1" + "@parcel/types" "2.9.3" + "@parcel/utils" "2.9.3" + "@parcel/workers" "2.9.3" + abortcontroller-polyfill "^1.1.9" + base-x "^3.0.8" + browserslist "^4.6.6" + clone "^2.1.1" + dotenv "^7.0.0" + dotenv-expand "^5.1.0" + json5 "^2.2.0" + msgpackr "^1.5.4" + nullthrows "^1.1.1" + semver "^7.5.2" + +"@parcel/diagnostic@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/diagnostic/-/diagnostic-2.8.3.tgz#d560276d5d2804b48beafa1feaf3fc6b2ac5e39d" + integrity sha512-u7wSzuMhLGWZjVNYJZq/SOViS3uFG0xwIcqXw12w54Uozd6BH8JlhVtVyAsq9kqnn7YFkw6pXHqAo5Tzh4FqsQ== + dependencies: + "@mischnic/json-sourcemap" "^0.1.0" + nullthrows "^1.1.1" + +"@parcel/diagnostic@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/diagnostic/-/diagnostic-2.9.3.tgz#23befe6c3b78440fe1e3635086e637da1529b4db" + integrity sha512-6jxBdyB3D7gP4iE66ghUGntWt2v64E6EbD4AetZk+hNJpgudOOPsKTovcMi/i7I4V0qD7WXSF4tvkZUoac0jwA== + dependencies: + "@mischnic/json-sourcemap" "^0.1.0" + nullthrows "^1.1.1" + +"@parcel/events@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/events/-/events-2.8.3.tgz#205f8d874e6ecc2cbdb941bf8d54bae669e571af" + integrity sha512-hoIS4tAxWp8FJk3628bsgKxEvR7bq2scCVYHSqZ4fTi/s0+VymEATrRCUqf+12e5H47uw1/ZjoqrGtBI02pz4w== + +"@parcel/events@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/events/-/events-2.9.3.tgz#b71253384c21f53fd3cced983cd2b287f7330e89" + integrity sha512-K0Scx+Bx9f9p1vuShMzNwIgiaZUkxEnexaKYHYemJrM7pMAqxIuIqhnvwurRCsZOVLUJPDDNJ626cWTc5vIq+A== + +"@parcel/fs-search@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/fs-search/-/fs-search-2.8.3.tgz#1c7d812c110b808758f44c56e61dfffdb09e9451" + integrity sha512-DJBT2N8knfN7Na6PP2mett3spQLTqxFrvl0gv+TJRp61T8Ljc4VuUTb0hqBj+belaASIp3Q+e8+SgaFQu7wLiQ== + dependencies: + detect-libc "^1.0.3" + +"@parcel/fs-search@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/fs-search/-/fs-search-2.9.3.tgz#4993d68478b15db404149a271bb0084382dd2040" + integrity sha512-nsNz3bsOpwS+jphcd+XjZL3F3PDq9lik0O8HPm5f6LYkqKWT+u/kgQzA8OkAHCR3q96LGiHxUywHPEBc27vI4Q== + +"@parcel/fs@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/fs/-/fs-2.8.3.tgz#80536afe877fc8a2bd26be5576b9ba27bb4c5754" + integrity sha512-y+i+oXbT7lP0e0pJZi/YSm1vg0LDsbycFuHZIL80pNwdEppUAtibfJZCp606B7HOjMAlNZOBo48e3hPG3d8jgQ== + dependencies: + "@parcel/fs-search" "2.8.3" + "@parcel/types" "2.8.3" + "@parcel/utils" "2.8.3" + "@parcel/watcher" "^2.0.7" + "@parcel/workers" "2.8.3" + +"@parcel/fs@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/fs/-/fs-2.9.3.tgz#39abd0f71561efccaac3ba6e4b8227705b73e906" + integrity sha512-/PrRKgCRw22G7rNPSpgN3Q+i2nIkZWuvIOAdMG4KWXC4XLp8C9jarNaWd5QEQ75amjhQSl3oUzABzkdCtkKrgg== + dependencies: + "@parcel/fs-search" "2.9.3" + "@parcel/types" "2.9.3" + "@parcel/utils" "2.9.3" + "@parcel/watcher" "^2.0.7" + "@parcel/workers" "2.9.3" + +"@parcel/graph@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/graph/-/graph-2.9.3.tgz#38f6c403ff4a2741390708be510bbf328d311a63" + integrity sha512-3LmRJmF8+OprAr6zJT3X2s8WAhLKkrhi6RsFlMWHifGU5ED1PFcJWFbOwJvSjcAhMQJP0fErcFIK1Ludv3Vm3g== + dependencies: + nullthrows "^1.1.1" + +"@parcel/hash@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/hash/-/hash-2.8.3.tgz#bc2499a27395169616cad2a99e19e69b9098f6e9" + integrity sha512-FVItqzjWmnyP4ZsVgX+G00+6U2IzOvqDtdwQIWisCcVoXJFCqZJDy6oa2qDDFz96xCCCynjRjPdQx2jYBCpfYw== + dependencies: + detect-libc "^1.0.3" + xxhash-wasm "^0.4.2" + +"@parcel/hash@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/hash/-/hash-2.9.3.tgz#bc7727939b1211b0a5d67fd00a9a55b8393c644a" + integrity sha512-qlH5B85XLzVAeijgKPjm1gQu35LoRYX/8igsjnN8vOlbc3O8BYAUIutU58fbHbtE8MJPbxQQUw7tkTjeoujcQQ== + dependencies: + xxhash-wasm "^0.4.2" + +"@parcel/logger@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/logger/-/logger-2.8.3.tgz#e14e4debafb3ca9e87c07c06780f9afc38b2712c" + integrity sha512-Kpxd3O/Vs7nYJIzkdmB6Bvp3l/85ydIxaZaPfGSGTYOfaffSOTkhcW9l6WemsxUrlts4za6CaEWcc4DOvaMOPA== + dependencies: + "@parcel/diagnostic" "2.8.3" + "@parcel/events" "2.8.3" + +"@parcel/logger@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/logger/-/logger-2.9.3.tgz#04362704d7af93d213de6587ff71a1a6d5f714ac" + integrity sha512-5FNBszcV6ilGFcijEOvoNVG6IUJGsnMiaEnGQs7Fvc1dktTjEddnoQbIYhcSZL63wEmzBZOgkT5yDMajJ/41jw== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/events" "2.9.3" + +"@parcel/markdown-ansi@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/markdown-ansi/-/markdown-ansi-2.8.3.tgz#1337d421bb1133ad178f386a8e1b746631bba4a1" + integrity sha512-4v+pjyoh9f5zuU/gJlNvNFGEAb6J90sOBwpKJYJhdWXLZMNFCVzSigxrYO+vCsi8G4rl6/B2c0LcwIMjGPHmFQ== + dependencies: + chalk "^4.1.0" + +"@parcel/markdown-ansi@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/markdown-ansi/-/markdown-ansi-2.9.3.tgz#b4de64eb252ce13e27f6e24e420b607db51097a5" + integrity sha512-/Q4X8F2aN8UNjAJrQ5NfK2OmZf6shry9DqetUSEndQ0fHonk78WKt6LT0zSKEBEW/bB/bXk6mNMsCup6L8ibjQ== + dependencies: + chalk "^4.1.0" + +"@parcel/namer-default@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/namer-default/-/namer-default-2.9.3.tgz#6dca34cbd26b29f0fd200627848c8026d58052e1" + integrity sha512-1ynFEcap48/Ngzwwn318eLYpLUwijuuZoXQPCsEQ21OOIOtfhFQJaPwXTsw6kRitshKq76P2aafE0BioGSqxcA== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/plugin" "2.9.3" + nullthrows "^1.1.1" + +"@parcel/node-resolver-core@3.0.3": + version "3.0.3" + resolved "https://registry.npmmirror.com/@parcel/node-resolver-core/-/node-resolver-core-3.0.3.tgz#cc890e66695b6d28745415106565499af9cb3c47" + integrity sha512-AjxNcZVHHJoNT/A99PKIdFtwvoze8PAiC3yz8E/dRggrDIOboUEodeQYV5Aq++aK76uz/iOP0tST2T8A5rhb1A== + dependencies: + "@mischnic/json-sourcemap" "^0.1.0" + "@parcel/diagnostic" "2.9.3" + "@parcel/fs" "2.9.3" + "@parcel/utils" "2.9.3" + nullthrows "^1.1.1" + semver "^7.5.2" + +"@parcel/optimizer-css@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/optimizer-css/-/optimizer-css-2.9.3.tgz#76f2f77adde9dee7498611f6be3078d0bde0396d" + integrity sha512-RK1QwcSdWDNUsFvuLy0hgnYKtPQebzCb0vPPzqs6LhL+vqUu9utOyRycGaQffHCkHVQP6zGlN+KFssd7YtFGhA== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "^2.1.1" + "@parcel/utils" "2.9.3" + browserslist "^4.6.6" + lightningcss "^1.16.1" + nullthrows "^1.1.1" + +"@parcel/optimizer-data-url@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/optimizer-data-url/-/optimizer-data-url-2.9.3.tgz#54f3bc86708b17718582d84c3cc6b773bbb7983c" + integrity sha512-k8lOKLzgZ24JKOuyrNe5PptoH8GJ78AwnumG1xEOKZ77gZnUgdrn3XdjzE28ZqTI4LFkT3jApUiBKBmqnWDe7Q== + dependencies: + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + isbinaryfile "^4.0.2" + mime "^2.4.4" + +"@parcel/optimizer-htmlnano@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/optimizer-htmlnano/-/optimizer-htmlnano-2.9.3.tgz#d5953a98892e4ba437b6e2022ad85dadacb0c84f" + integrity sha512-9g/KBck3c6DokmJfvJ5zpHFBiCSolaGrcsTGx8C3YPdCTVTI9P1TDCwUxvAr4LjpcIRSa82wlLCI+nF6sSgxKA== + dependencies: + "@parcel/plugin" "2.9.3" + htmlnano "^2.0.0" + nullthrows "^1.1.1" + posthtml "^0.16.5" + svgo "^2.4.0" + +"@parcel/optimizer-image@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/optimizer-image/-/optimizer-image-2.9.3.tgz#80d9be617bf2c695960ff3c5644c87c1775e1f3a" + integrity sha512-530YzthE7kmecnNhPbkAK+26yQNt69pfJrgE0Ev0BZaM1Wu2+33nki7o8qvkTkikhPrurEJLGIXt1qKmbKvCbA== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + "@parcel/workers" "2.9.3" + +"@parcel/optimizer-svgo@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/optimizer-svgo/-/optimizer-svgo-2.9.3.tgz#e4d90f6bc1c8eeb39193759631db1bb86943bf4b" + integrity sha512-ytQS0wY5JJhWU4mL0wfhYDUuHcfuw+Gy2+JcnTm1t1AZXHlOTbU6EzRWNqBShsgXjvdrQQXizAe3B6GFFlFJVQ== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + svgo "^2.4.0" + +"@parcel/optimizer-swc@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/optimizer-swc/-/optimizer-swc-2.9.3.tgz#794a909864f76a366331f023e38082b19213c016" + integrity sha512-GQINNeqtdpL1ombq/Cpwi6IBk02wKJ/JJbYbyfHtk8lxlq13soenpwOlzJ5T9D2fdG+FUhai9NxpN5Ss4lNoAg== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "^2.1.1" + "@parcel/utils" "2.9.3" + "@swc/core" "^1.3.36" + nullthrows "^1.1.1" + +"@parcel/package-manager@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/package-manager/-/package-manager-2.8.3.tgz#ddd0d62feae3cf0fb6cc0537791b3a16296ad458" + integrity sha512-tIpY5pD2lH53p9hpi++GsODy6V3khSTX4pLEGuMpeSYbHthnOViobqIlFLsjni+QA1pfc8NNNIQwSNdGjYflVA== + dependencies: + "@parcel/diagnostic" "2.8.3" + "@parcel/fs" "2.8.3" + "@parcel/logger" "2.8.3" + "@parcel/types" "2.8.3" + "@parcel/utils" "2.8.3" + "@parcel/workers" "2.8.3" + semver "^5.7.1" + +"@parcel/package-manager@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/package-manager/-/package-manager-2.9.3.tgz#e8522671ba6c4f0a07b518957d22a038a7698b24" + integrity sha512-NH6omcNTEupDmW4Lm1e4NUYBjdqkURxgZ4CNESESInHJe6tblVhNB8Rpr1ar7zDar7cly9ILr8P6N3Ei7bTEjg== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/fs" "2.9.3" + "@parcel/logger" "2.9.3" + "@parcel/node-resolver-core" "3.0.3" + "@parcel/types" "2.9.3" + "@parcel/utils" "2.9.3" + "@parcel/workers" "2.9.3" + semver "^7.5.2" + +"@parcel/packager-css@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/packager-css/-/packager-css-2.9.3.tgz#a39a733b6e25e4f982d8b1af8bfc5d727475def0" + integrity sha512-mePiWiYZOULY6e1RdAIJyRoYqXqGci0srOaVZYaP7mnrzvJgA63kaZFFsDiEWghunQpMUuUjM2x/vQVHzxmhKQ== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "^2.1.1" + "@parcel/utils" "2.9.3" + nullthrows "^1.1.1" + +"@parcel/packager-html@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/packager-html/-/packager-html-2.9.3.tgz#53657c13a25e744415ece2990902a2eb6434adbe" + integrity sha512-0Ex+O0EaZf9APNERRNGgGto02hFJ6f5RQEvRWBK55WAV1rXeU+kpjC0c0qZvnUaUtXfpWMsEBkevJCwDkUMeMg== + dependencies: + "@parcel/plugin" "2.9.3" + "@parcel/types" "2.9.3" + "@parcel/utils" "2.9.3" + nullthrows "^1.1.1" + posthtml "^0.16.5" + +"@parcel/packager-js@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/packager-js/-/packager-js-2.9.3.tgz#ef8d3dde67c4da3dd83374b8d13aba9a9f3a7444" + integrity sha512-V5xwkoE3zQ3R+WqAWhA1KGQ791FvJeW6KonOlMI1q76Djjgox68hhObqcLu66AmYNhR2R/wUpkP18hP2z8dSFw== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/hash" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "^2.1.1" + "@parcel/utils" "2.9.3" + globals "^13.2.0" + nullthrows "^1.1.1" + +"@parcel/packager-raw@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/packager-raw/-/packager-raw-2.9.3.tgz#288335d1d1a928796dd07f13911acd2c3aefab8a" + integrity sha512-oPQTNoYanQ2DdJyL61uPYK2py83rKOT8YVh2QWAx0zsSli6Kiy64U3+xOCYWgDVCrHw9+9NpQMuAdSiFg4cq8g== + dependencies: + "@parcel/plugin" "2.9.3" + +"@parcel/packager-svg@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/packager-svg/-/packager-svg-2.9.3.tgz#16ae31fce0656bc8d9e9e1d5334925ed938c66d8" + integrity sha512-p/Ya6UO9DAkaCUFxfFGyeHZDp9YPAlpdnh1OChuwqSFOXFjjeXuoK4KLT+ZRalVBo2Jo8xF70oKMZw4MVvaL7Q== + dependencies: + "@parcel/plugin" "2.9.3" + "@parcel/types" "2.9.3" + "@parcel/utils" "2.9.3" + posthtml "^0.16.4" + +"@parcel/plugin@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/plugin/-/plugin-2.8.3.tgz#7bb30a5775eaa6473c27f002a0a3ee7308d6d669" + integrity sha512-jZ6mnsS4D9X9GaNnvrixDQwlUQJCohDX2hGyM0U0bY2NWU8Km97SjtoCpWjq+XBCx/gpC4g58+fk9VQeZq2vlw== + dependencies: + "@parcel/types" "2.8.3" + +"@parcel/plugin@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/plugin/-/plugin-2.9.3.tgz#90e9a9482fa27735494372f5643db01abcf3fdb6" + integrity sha512-qN85Gqr2GMuxX1dT1mnuO9hOcvlEv1lrYrCxn7CJN2nUhbwcfG+LEvcrCzCOJ6XtIHm+ZBV9h9p7FfoPLvpw+g== + dependencies: + "@parcel/types" "2.9.3" + +"@parcel/profiler@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/profiler/-/profiler-2.9.3.tgz#6575ed6dc4275c0161dce74bd719961236673ce1" + integrity sha512-pyHc9lw8VZDfgZoeZWZU9J0CVEv1Zw9O5+e0DJPDPHuXJYr72ZAOhbljtU3owWKAeW+++Q2AZWkbUGEOjI/e6g== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/events" "2.9.3" + chrome-trace-event "^1.0.2" + +"@parcel/reporter-bundle-buddy@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/reporter-bundle-buddy/-/reporter-bundle-buddy-2.9.3.tgz#36df220be5703ea19d336bf32be60ad7f08dae0e" + integrity sha512-9ftzLZ161USdvnxueT55EWufLI48va0xJfB5MAJLG92VAS1N1FSFgYKdkGFzBKw0eK9UScQNYnntCGC17rBayQ== + dependencies: + "@parcel/plugin" "2.9.3" + +"@parcel/reporter-dev-server@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/reporter-dev-server/-/reporter-dev-server-2.9.3.tgz#5871d19138a1a282fa8b375d4160de7f30138f3d" + integrity sha512-s6eboxdLEtRSvG52xi9IiNbcPKC0XMVmvTckieue2EqGDbDcaHQoHmmwkk0rNq0/Z/UxelGcQXoIYC/0xq3ykQ== + dependencies: + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + +"@parcel/resolver-default@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/resolver-default/-/resolver-default-2.9.3.tgz#9029e8be0efae586834243e8a8c607f739678040" + integrity sha512-8ESJk1COKvDzkmOnppNXoDamNMlYVIvrKc2RuFPmp8nKVj47R6NwMgvwxEaatyPzvkmyTpq5RvG9I3HFc+r4Cw== + dependencies: + "@parcel/node-resolver-core" "3.0.3" + "@parcel/plugin" "2.9.3" + +"@parcel/runtime-browser-hmr@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.9.3.tgz#9db567aaae92c9b2b8abd26ea25ec2b549eebb54" + integrity sha512-EgiDIDrVAWpz7bOzWXqVinQkaFjLwT34wsonpXAbuI7f7r00d52vNAQC9AMu+pTijA3gyKoJ+Q4NWPMZf7ACDA== + dependencies: + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + +"@parcel/runtime-js@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/runtime-js/-/runtime-js-2.8.3.tgz#0baa4c8fbf77eabce05d01ccc186614968ffc0cd" + integrity sha512-IRja0vNKwvMtPgIqkBQh0QtRn0XcxNC8HU1jrgWGRckzu10qJWO+5ULgtOeR4pv9krffmMPqywGXw6l/gvJKYQ== + dependencies: + "@parcel/plugin" "2.8.3" + "@parcel/utils" "2.8.3" + nullthrows "^1.1.1" + +"@parcel/runtime-js@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/runtime-js/-/runtime-js-2.9.3.tgz#481c4f26705e684809bef097bf2cb75052c2982c" + integrity sha512-EvIy+qXcKnB5qxHhe96zmJpSAViNVXHfQI5RSdZ2a7CPwORwhTI+zPNT9sb7xb/WwFw/WuTTgzT40b41DceU6Q== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + nullthrows "^1.1.1" + +"@parcel/runtime-react-refresh@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/runtime-react-refresh/-/runtime-react-refresh-2.9.3.tgz#8d82cd4fbcdc228d439bae232eb3c65d36e62872" + integrity sha512-XBgryZQIyCmi6JwEfMUCmINB3l1TpTp9a2iFxmYNpzHlqj4Ve0saKaqWOVRLvC945ZovWIBzcSW2IYqWKGtbAA== + dependencies: + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + react-error-overlay "6.0.9" + react-refresh "^0.9.0" + +"@parcel/runtime-service-worker@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/runtime-service-worker/-/runtime-service-worker-2.9.3.tgz#93dba721477c84f44458a42b28f75c875f56974d" + integrity sha512-qLJLqv1mMdWL7gyh8aKBFFAuEiJkhUUgLKpdn6eSfH/R7kTtb76WnOwqUrhvEI9bZFUM/8Pa1bzJnPpqSOM+Sw== + dependencies: + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + nullthrows "^1.1.1" + +"@parcel/source-map@2.1.1", "@parcel/source-map@^2.1.1": + version "2.1.1" + resolved "https://registry.npmmirror.com/@parcel/source-map/-/source-map-2.1.1.tgz#fb193b82dba6dd62cc7a76b326f57bb35000a782" + integrity sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew== + dependencies: + detect-libc "^1.0.3" + +"@parcel/transformer-babel@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-babel/-/transformer-babel-2.9.3.tgz#3527388048c606c5ef5fb909959e63be2416e87d" + integrity sha512-pURtEsnsp3h6tOBDuzh9wRvVtw4PgIlqwAArIWdrG7iwqOUYv9D8ME4+ePWEu7MQWAp58hv9pTJtqWv4T+Sq8A== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "^2.1.1" + "@parcel/utils" "2.9.3" + browserslist "^4.6.6" + json5 "^2.2.0" + nullthrows "^1.1.1" + semver "^7.5.2" + +"@parcel/transformer-css@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-css/-/transformer-css-2.9.3.tgz#2ed58f74983d2d7fc224a6df5d17b72eb38764e4" + integrity sha512-duWMdbEBBPjg3fQdXF16iWIdThetDZvCs2TpUD7xOlXH6kR0V5BJy8ONFT15u1RCqIV9hSNGaS3v3I9YRNY5zQ== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "^2.1.1" + "@parcel/utils" "2.9.3" + browserslist "^4.6.6" + lightningcss "^1.16.1" + nullthrows "^1.1.1" + +"@parcel/transformer-graphql@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-graphql/-/transformer-graphql-2.9.3.tgz#6d75c6b9dcb4ecb92a2ed446b5d4233a3a0cb552" + integrity sha512-cIohsH3WlXgn63baU35ZoWHzttmkyE2Q1pexKjszODzSUq3pdcg+9k4rB/z8GGMzXvFRYuBgl2M2Ukqz7SueMg== + dependencies: + "@parcel/plugin" "2.9.3" + graphql "^15.0.0" + graphql-import-macro "^1.0.0" + +"@parcel/transformer-html@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-html/-/transformer-html-2.9.3.tgz#f8b3daa4b633d81dc37772051b4e075940fa8351" + integrity sha512-0NU4omcHzFXA1seqftAXA2KNZaMByoKaNdXnLgBgtCGDiYvOcL+6xGHgY6pw9LvOh5um10KI5TxSIMILoI7VtA== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/hash" "2.9.3" + "@parcel/plugin" "2.9.3" + nullthrows "^1.1.1" + posthtml "^0.16.5" + posthtml-parser "^0.10.1" + posthtml-render "^3.0.0" + semver "^7.5.2" + srcset "4" + +"@parcel/transformer-image@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-image/-/transformer-image-2.9.3.tgz#dd380b949e923662d3c7ced48dbe9d5b919a94e7" + integrity sha512-7CEe35RaPadQzLIuxzTtIxnItvOoy46hcbXtOdDt6lmVa4omuOygZYRIya2lsGIP4JHvAaALMb5nt99a1uTwJg== + dependencies: + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + "@parcel/workers" "2.9.3" + nullthrows "^1.1.1" + +"@parcel/transformer-inline-string@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-inline-string/-/transformer-inline-string-2.9.3.tgz#3501b2e5e311347bc377f3409e3813621275c1ef" + integrity sha512-IZNd0Ksl32psX1M41KbUc4BmvVSoLVnlpaMrh9C/l+piFSkDXWMnF0PONX/RcxYMBIwB2jYllheIKH54naeNaA== + dependencies: + "@parcel/plugin" "2.9.3" + +"@parcel/transformer-js@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-js/-/transformer-js-2.9.3.tgz#4b72022da9bf5aa743a89961c4d61b681bf5e7b9" + integrity sha512-Z2MVVg5FYcPOfxlUwxqb5l9yjTMEqE3KI3zq2MBRUme6AV07KxLmCDF23b6glzZlHWQUE8MXzYCTAkOPCcPz+Q== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "^2.1.1" + "@parcel/utils" "2.9.3" + "@parcel/workers" "2.9.3" + "@swc/helpers" "^0.5.0" + browserslist "^4.6.6" + nullthrows "^1.1.1" + regenerator-runtime "^0.13.7" + semver "^7.5.2" + +"@parcel/transformer-json@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-json/-/transformer-json-2.9.3.tgz#cd16bb657179f2978c7ca49c771555458cdbc307" + integrity sha512-yNL27dbOLhkkrjaQjiQ7Im9VOxmkfuuSNSmS0rA3gEjVcm07SLKRzWkAaPnyx44Lb6bzyOTWwVrb9aMmxgADpA== + dependencies: + "@parcel/plugin" "2.9.3" + json5 "^2.2.0" + +"@parcel/transformer-less@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-less/-/transformer-less-2.9.3.tgz#1bb441f5f628861d33cfff82b9fc70458dc4d695" + integrity sha512-qwF5NQ8rPZjS79tv9RRPxzkZcwLcI4Xg2gHm9c1PvsgoaL2tVNpfjiRA6MOrzfJp+xr7xEzeMDZksOJ1WQiiQg== + dependencies: + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "^2.1.1" + less "^4.1.1" + +"@parcel/transformer-postcss@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-postcss/-/transformer-postcss-2.9.3.tgz#0358facea2ea882266508e18a79390590ee812ab" + integrity sha512-HoDvPqKzhpmvMmHqQhDnt8F1vH61m6plpGiYaYnYv2Om4HHi5ZIq9bO+9QLBnTKfaZ7ndYSefTKOxTYElg7wyw== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/hash" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + clone "^2.1.1" + nullthrows "^1.1.1" + postcss-value-parser "^4.2.0" + semver "^7.5.2" + +"@parcel/transformer-posthtml@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-posthtml/-/transformer-posthtml-2.9.3.tgz#dcffc9f0d667b65f9fe701753334b48b65b958d8" + integrity sha512-2fQGgrzRmaqbWf3y2/T6xhqrNjzqMMKksqJzvc8TMfK6f2kg3Ddjv158eaSW2JdkV39aY7tvAOn5f1uzo74BMA== + dependencies: + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + nullthrows "^1.1.1" + posthtml "^0.16.5" + posthtml-parser "^0.10.1" + posthtml-render "^3.0.0" + semver "^7.5.2" + +"@parcel/transformer-raw@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-raw/-/transformer-raw-2.9.3.tgz#c8e23881ecb45a6dc3fcc5a271cf0d55476beabc" + integrity sha512-oqdPzMC9QzWRbY9J6TZEqltknjno+dY24QWqf8ondmdF2+W+/2mRDu59hhCzQrqUHgTq4FewowRZmSfpzHxwaQ== + dependencies: + "@parcel/plugin" "2.9.3" + +"@parcel/transformer-react-refresh-wrap@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.9.3.tgz#7775292909fa051f6dfd2668da8f34833a47d56c" + integrity sha512-cb9NyU6oJlDblFIlzqIE8AkvRQVGl2IwJNKwD4PdE7Y6sq2okGEPG4hOw3k/Y9JVjM4/2pUORqvjSRhWwd9oVQ== + dependencies: + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + react-refresh "^0.9.0" + +"@parcel/transformer-sass@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-sass/-/transformer-sass-2.9.3.tgz#0b339ff49aab679350a8dfc66c3af32030f253cf" + integrity sha512-i9abj9bKg3xCHghJyTM3rUVxIEn9n1Rl+DFdpyNAD8VZ52COfOshFDQOWNuhU1hEnJOFYCjnfcO0HRTsg3dWmg== + dependencies: + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "^2.1.1" + sass "^1.38.0" + +"@parcel/transformer-svg-react@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-svg-react/-/transformer-svg-react-2.9.3.tgz#5e2df10b65600a327a956818591ce3bf9909e7e0" + integrity sha512-RXmCn58CkCBhpsS1AaRBrSRla0U5JN3r3hb7kQvEb+d7chGnsxCCWsBxtlrxPUjoUFLdQli9rhpCTkiyOBXY2A== + dependencies: + "@parcel/plugin" "2.9.3" + "@svgr/core" "^6.2.0" + "@svgr/plugin-jsx" "^6.2.0" + "@svgr/plugin-svgo" "^6.2.0" + +"@parcel/transformer-svg@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-svg/-/transformer-svg-2.9.3.tgz#087a8ec63fa2377db0478a87d3e2829613b391fc" + integrity sha512-ypmE+dzB09IMCdEAkOsSxq1dEIm2A3h67nAFz4qbfHbwNgXBUuy/jB3ZMwXN/cO0f7SBh/Ap8Jhq6vmGqB5tWw== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/hash" "2.9.3" + "@parcel/plugin" "2.9.3" + nullthrows "^1.1.1" + posthtml "^0.16.5" + posthtml-parser "^0.10.1" + posthtml-render "^3.0.0" + semver "^7.5.2" + +"@parcel/transformer-worklet@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/transformer-worklet/-/transformer-worklet-2.9.3.tgz#7a50035626f50f2d58a5c8e3937cb7c3e3e18350" + integrity sha512-Fgd81OTOvAxAKoBGsQow/mgxELaNG1FeZW4DuDEPo/hR3lbs90oYuVpG2thdx7hmi/W6xqhrLaEN5Ea1v0LvEA== + dependencies: + "@parcel/plugin" "2.9.3" + +"@parcel/types@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/types/-/types-2.8.3.tgz#3306bc5391b6913bd619914894b8cd84a24b30fa" + integrity sha512-FECA1FB7+0UpITKU0D6TgGBpGxYpVSMNEENZbSJxFSajNy3wrko+zwBKQmFOLOiPcEtnGikxNs+jkFWbPlUAtw== + dependencies: + "@parcel/cache" "2.8.3" + "@parcel/diagnostic" "2.8.3" + "@parcel/fs" "2.8.3" + "@parcel/package-manager" "2.8.3" + "@parcel/source-map" "^2.1.1" + "@parcel/workers" "2.8.3" + utility-types "^3.10.0" + +"@parcel/types@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/types/-/types-2.9.3.tgz#170a26203b9088a306862b2dc914c27375d77bbc" + integrity sha512-NSNY8sYtRhvF1SqhnIGgGvJocyWt1K8Tnw5cVepm0g38ywtX6mwkBvMkmeehXkII4mSUn+frD9wGsydTunezvA== + dependencies: + "@parcel/cache" "2.9.3" + "@parcel/diagnostic" "2.9.3" + "@parcel/fs" "2.9.3" + "@parcel/package-manager" "2.9.3" + "@parcel/source-map" "^2.1.1" + "@parcel/workers" "2.9.3" + utility-types "^3.10.0" + +"@parcel/utils@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/utils/-/utils-2.8.3.tgz#0d56c9e8e22c119590a5e044a0e01031965da40e" + integrity sha512-IhVrmNiJ+LOKHcCivG5dnuLGjhPYxQ/IzbnF2DKNQXWBTsYlHkJZpmz7THoeLtLliGmSOZ3ZCsbR8/tJJKmxjA== + dependencies: + "@parcel/codeframe" "2.8.3" + "@parcel/diagnostic" "2.8.3" + "@parcel/hash" "2.8.3" + "@parcel/logger" "2.8.3" + "@parcel/markdown-ansi" "2.8.3" + "@parcel/source-map" "^2.1.1" + chalk "^4.1.0" + +"@parcel/utils@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/utils/-/utils-2.9.3.tgz#d4df6837658f773c725a4934967ab1128a05fdd7" + integrity sha512-cesanjtj/oLehW8Waq9JFPmAImhoiHX03ihc3JTWkrvJYSbD7wYKCDgPAM3JiRAqvh1LZ6P699uITrYWNoRLUg== + dependencies: + "@parcel/codeframe" "2.9.3" + "@parcel/diagnostic" "2.9.3" + "@parcel/hash" "2.9.3" + "@parcel/logger" "2.9.3" + "@parcel/markdown-ansi" "2.9.3" + "@parcel/source-map" "^2.1.1" + chalk "^4.1.0" + nullthrows "^1.1.1" + +"@parcel/watcher-android-arm64@2.2.0": + version "2.2.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.2.0.tgz#3d1a71f251ba829ab884dfe119cc4f4c49c7222b" + integrity sha512-nU2wh00CTQT9rr1TIKTjdQ9lAGYpmz6XuKw0nAwAN+S2A5YiD55BK1u+E5WMCT8YOIDe/n6gaj4o/Bi9294SSQ== + +"@parcel/watcher-android-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.3.0.tgz#d82e74bb564ebd4d8a88791d273a3d2bd61e27ab" + integrity sha512-f4o9eA3dgk0XRT3XhB0UWpWpLnKgrh1IwNJKJ7UJek7eTYccQ8LR7XUWFKqw6aEq5KUNlCcGvSzKqSX/vtWVVA== + +"@parcel/watcher-darwin-arm64@2.2.0": + version "2.2.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.2.0.tgz#9ed47d9e4146d53a39f62577a993426d6ddec2d2" + integrity sha512-cJl0UZDcodciy3TDMomoK/Huxpjlkkim3SyMgWzjovHGOZKNce9guLz2dzuFwfObBFCjfznbFMIvAZ5syXotYw== + +"@parcel/watcher-darwin-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.3.0.tgz#c9cd03f8f233d512fcfc873d5b4e23f1569a82ad" + integrity sha512-mKY+oijI4ahBMc/GygVGvEdOq0L4DxhYgwQqYAz/7yPzuGi79oXrZG52WdpGA1wLBPrYb0T8uBaGFo7I6rvSKw== + +"@parcel/watcher-darwin-x64@2.2.0": + version "2.2.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.2.0.tgz#9b553e61f4a01a0947b1c005619db7b7c9a286d1" + integrity sha512-QI77zxaGrCV1StKcoRYfsUfmUmvPMPfQrubkBBy5XujV2fwaLgZivQOTQMBgp5K2+E19u1ufpspKXAPqSzpbyg== + +"@parcel/watcher-darwin-x64@2.3.0": + version "2.3.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.3.0.tgz#83c902994a2a49b9e1ab5050dba24876fdc2c219" + integrity sha512-20oBj8LcEOnLE3mgpy6zuOq8AplPu9NcSSSfyVKgfOhNAc4eF4ob3ldj0xWjGGbOF7Dcy1Tvm6ytvgdjlfUeow== + +"@parcel/watcher-freebsd-x64@2.3.0": + version "2.3.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.3.0.tgz#7a0f4593a887e2752b706aff2dae509aef430cf6" + integrity sha512-7LftKlaHunueAEiojhCn+Ef2CTXWsLgTl4hq0pkhkTBFI3ssj2bJXmH2L67mKpiAD5dz66JYk4zS66qzdnIOgw== + +"@parcel/watcher-linux-arm-glibc@2.2.0": + version "2.2.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.2.0.tgz#2644f6292b862c52d636978da8711bf2f7b14b24" + integrity sha512-I2GPBcAXazPzabCmfsa3HRRW+MGlqxYd8g8RIueJU+a4o5nyNZDz0CR1cu0INT0QSQXEZV7w6UE8Hz9CF8u3Pg== + +"@parcel/watcher-linux-arm-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.3.0.tgz#3fc90c3ebe67de3648ed2f138068722f9b1d47da" + integrity sha512-1apPw5cD2xBv1XIHPUlq0cO6iAaEUQ3BcY0ysSyD9Kuyw4MoWm1DV+W9mneWI+1g6OeP6dhikiFE6BlU+AToTQ== + +"@parcel/watcher-linux-arm64-glibc@2.2.0": + version "2.2.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.2.0.tgz#b82c1715a20e6725c89b2697a208d2ae488d22da" + integrity sha512-St5mlfp+2lS9AmgixUqfwJa/DwVmTCJxC1HcOubUTz6YFOKIlkHCeUa1Bxi4E/tR/HSez8+heXHL8HQkJ4Bd8g== + +"@parcel/watcher-linux-arm64-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.3.0.tgz#f7bbbf2497d85fd11e4c9e9c26ace8f10ea9bcbc" + integrity sha512-mQ0gBSQEiq1k/MMkgcSB0Ic47UORZBmWoAWlMrTW6nbAGoLZP+h7AtUM7H3oDu34TBFFvjy4JCGP43JlylkTQA== + +"@parcel/watcher-linux-arm64-musl@2.2.0": + version "2.2.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.2.0.tgz#45511adc69c4c89b10965f0dd1519e56a00f512f" + integrity sha512-jS+qfhhoOBVWwMLP65MaG8xdInMK30pPW8wqTCg2AAuVJh5xepMbzkhHJ4zURqHiyY3EiIRuYu4ONJKCxt8iqA== + +"@parcel/watcher-linux-arm64-musl@2.3.0": + version "2.3.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.3.0.tgz#de131a9fcbe1fa0854e9cbf4c55bed3b35bcff43" + integrity sha512-LXZAExpepJew0Gp8ZkJ+xDZaTQjLHv48h0p0Vw2VMFQ8A+RKrAvpFuPVCVwKJCr5SE+zvaG+Etg56qXvTDIedw== + +"@parcel/watcher-linux-x64-glibc@2.2.0": + version "2.2.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.2.0.tgz#f6e878bf40874b1ce9530ec87e5c2e644e9ad5ac" + integrity sha512-xJvJ7R2wJdi47WZBFS691RDOWvP1j/IAs3EXaWVhDI8FFITbWrWaln7KoNcR0Y3T+ZwimFY/cfb0PNht1q895g== + +"@parcel/watcher-linux-x64-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.3.0.tgz#193dd1c798003cdb5a1e59470ff26300f418a943" + integrity sha512-P7Wo91lKSeSgMTtG7CnBS6WrA5otr1K7shhSjKHNePVmfBHDoAOHYRXgUmhiNfbcGk0uMCHVcdbfxtuiZCHVow== + +"@parcel/watcher-linux-x64-musl@2.2.0": + version "2.2.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.2.0.tgz#4a1b7a8f65b42f50b1819185ef56ed3c9e251425" + integrity sha512-D+NMpgr23a+RI5mu8ZPKWy7AqjBOkURFDgP5iIXXEf/K3hm0jJ3ogzi0Ed2237B/CdYREimCgXyeiAlE/FtwyA== + +"@parcel/watcher-linux-x64-musl@2.3.0": + version "2.3.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.3.0.tgz#6dbdb86d96e955ab0fe4a4b60734ec0025a689dd" + integrity sha512-+kiRE1JIq8QdxzwoYY+wzBs9YbJ34guBweTK8nlzLKimn5EQ2b2FSC+tAOpq302BuIMjyuUGvBiUhEcLIGMQ5g== + +"@parcel/watcher-win32-arm64@2.2.0": + version "2.2.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.2.0.tgz#4cdbaf8c1097038e838d12f897ac8595b18dfb1f" + integrity sha512-z225cPn3aygJsyVUOWwfyW+fY0Tvk7N3XCOl66qUPFxpbuXeZuiuuJemmtm8vxyqa3Ur7peU/qJxrpC64aeI7Q== + +"@parcel/watcher-win32-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.3.0.tgz#59da26a431da946e6c74fa6b0f30b120ea6650b6" + integrity sha512-35gXCnaz1AqIXpG42evcoP2+sNL62gZTMZne3IackM+6QlfMcJLy3DrjuL6Iks7Czpd3j4xRBzez3ADCj1l7Aw== + +"@parcel/watcher-win32-ia32@2.3.0": + version "2.3.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.3.0.tgz#3ee6a18b08929cd3b788e8cc9547fd9a540c013a" + integrity sha512-FJS/IBQHhRpZ6PiCjFt1UAcPr0YmCLHRbTc00IBTrelEjlmmgIVLeOx4MSXzx2HFEy5Jo5YdhGpxCuqCyDJ5ow== + +"@parcel/watcher-win32-x64@2.2.0": + version "2.2.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.2.0.tgz#f2fcc255b7cadfd0afa7c51cde36413632075bcc" + integrity sha512-JqGW0RJ61BkKx+yYzIURt9s53P7xMVbv0uxYPzAXLBINGaFmkIKSuUPyBVfy8TMbvp93lvF4SPBNDzVRJfvgOw== + +"@parcel/watcher-win32-x64@2.3.0": + version "2.3.0" + resolved "https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.3.0.tgz#14e7246289861acc589fd608de39fe5d8b4bb0a7" + integrity sha512-dLx+0XRdMnVI62kU3wbXvbIRhLck4aE28bIGKbRGS7BJNt54IIj9+c/Dkqb+7DJEbHUZAX1bwaoM8PqVlHJmCA== + +"@parcel/watcher@2.2.0": + version "2.2.0" + resolved "https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.2.0.tgz#92067954e591d239c3ecfa08add205f88f476068" + integrity sha512-71S4TF+IMyAn24PK4KSkdKtqJDR3zRzb0HE3yXpacItqTM7XfF2f5q9NEGLEVl0dAaBAGfNwDCjH120y25F6Tg== + dependencies: + detect-libc "^1.0.3" + is-glob "^4.0.3" + micromatch "^4.0.5" + node-addon-api "^7.0.0" + optionalDependencies: + "@parcel/watcher-android-arm64" "2.2.0" + "@parcel/watcher-darwin-arm64" "2.2.0" + "@parcel/watcher-darwin-x64" "2.2.0" + "@parcel/watcher-linux-arm-glibc" "2.2.0" + "@parcel/watcher-linux-arm64-glibc" "2.2.0" + "@parcel/watcher-linux-arm64-musl" "2.2.0" + "@parcel/watcher-linux-x64-glibc" "2.2.0" + "@parcel/watcher-linux-x64-musl" "2.2.0" + "@parcel/watcher-win32-arm64" "2.2.0" + "@parcel/watcher-win32-x64" "2.2.0" + +"@parcel/watcher@^2.0.7": + version "2.3.0" + resolved "https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.3.0.tgz#803517abbc3981a1a1221791d9f59dc0590d50f9" + integrity sha512-pW7QaFiL11O0BphO+bq3MgqeX/INAk9jgBldVDYjlQPO4VddoZnF22TcF9onMhnLVHuNqBJeRf+Fj7eezi/+rQ== + dependencies: + detect-libc "^1.0.3" + is-glob "^4.0.3" + micromatch "^4.0.5" + node-addon-api "^7.0.0" + optionalDependencies: + "@parcel/watcher-android-arm64" "2.3.0" + "@parcel/watcher-darwin-arm64" "2.3.0" + "@parcel/watcher-darwin-x64" "2.3.0" + "@parcel/watcher-freebsd-x64" "2.3.0" + "@parcel/watcher-linux-arm-glibc" "2.3.0" + "@parcel/watcher-linux-arm64-glibc" "2.3.0" + "@parcel/watcher-linux-arm64-musl" "2.3.0" + "@parcel/watcher-linux-x64-glibc" "2.3.0" + "@parcel/watcher-linux-x64-musl" "2.3.0" + "@parcel/watcher-win32-arm64" "2.3.0" + "@parcel/watcher-win32-ia32" "2.3.0" + "@parcel/watcher-win32-x64" "2.3.0" + +"@parcel/workers@2.8.3": + version "2.8.3" + resolved "https://registry.npmmirror.com/@parcel/workers/-/workers-2.8.3.tgz#255450ccf4db234082407e4ddda5fd575f08c235" + integrity sha512-+AxBnKgjqVpUHBcHLWIHcjYgKIvHIpZjN33mG5LG9XXvrZiqdWvouEzqEXlVLq5VzzVbKIQQcmsvRy138YErkg== + dependencies: + "@parcel/diagnostic" "2.8.3" + "@parcel/logger" "2.8.3" + "@parcel/types" "2.8.3" + "@parcel/utils" "2.8.3" + chrome-trace-event "^1.0.2" + nullthrows "^1.1.1" + +"@parcel/workers@2.9.3": + version "2.9.3" + resolved "https://registry.npmmirror.com/@parcel/workers/-/workers-2.9.3.tgz#d1d84d3c767b840d0ed7123a03ab7e0f4a2c0731" + integrity sha512-zRrDuZJzTevrrwElYosFztgldhqW6G9q5zOeQXfVQFkkEJCNfg36ixeiofKRU8uu2x+j+T6216mhMNB6HiuY+w== + dependencies: + "@parcel/diagnostic" "2.9.3" + "@parcel/logger" "2.9.3" + "@parcel/profiler" "2.9.3" + "@parcel/types" "2.9.3" + "@parcel/utils" "2.9.3" + nullthrows "^1.1.1" + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@plasmohq/consolidate@0.17.0": + version "0.17.0" + resolved "https://registry.npmmirror.com/@plasmohq/consolidate/-/consolidate-0.17.0.tgz#10d57149fad4da07de8d393a5f123bc7d90ccfe0" + integrity sha512-Na8imBnvzYPtzkK+9Uv9hPZ/oJti/0jgiQWD222SHxHw2QCVuR4KzslxXCy/rS8gGluSiTs1BGVvc3d2O6aJCA== + dependencies: + bluebird "^3.7.2" + +"@plasmohq/init@0.7.0": + version "0.7.0" + resolved "https://registry.npmmirror.com/@plasmohq/init/-/init-0.7.0.tgz#8705db28c3da7e570e8d6f404a4ca1892268d16c" + integrity sha512-P75g48dqOGneJ+n0AcqnLE/TYflcaPc3B7h6EopnCBBYUDnCNBMwYmKAkaf5pnhsEB0ybPS6TU1C2DTGfqaW7A== + +"@plasmohq/parcel-bundler@0.5.5": + version "0.5.5" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-bundler/-/parcel-bundler-0.5.5.tgz#ff4d4f2463b418c3c259557a55b37d62b970d6e4" + integrity sha512-QCMmmfic514CfdXMJ7JMWUnqDzIHKVKyYeqPpUDsXON6JvA1yTmO5mEQSls8+5u/HpocP9QmTskQOHu3RCNX9A== + dependencies: + "@parcel/core" "2.9.3" + "@parcel/diagnostic" "2.9.3" + "@parcel/graph" "2.9.3" + "@parcel/hash" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + nullthrows "1.1.1" + +"@plasmohq/parcel-compressor-utf8@0.0.6": + version "0.0.6" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-compressor-utf8/-/parcel-compressor-utf8-0.0.6.tgz#17ee86d97e997a95b6f894e50c703b8df34164ff" + integrity sha512-dtbZXi2gAHyVhxqxF2SvJtwDOy02QYRjwCJYOFsQR79qwAiuUBaeQ47p++vFrqNX86mo1lUtZniJl63xNQi08w== + dependencies: + "@parcel/plugin" "2.9.3" + +"@plasmohq/parcel-config@0.40.0": + version "0.40.0" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-config/-/parcel-config-0.40.0.tgz#9f277bf14eab8d8dfa0d4f31a716cfa6fc3626cb" + integrity sha512-aDyZIL3ScTmA1CsB/Sym7SxOMVSFUgNQrFovD+sl1M2nrYytqkLDFs7mspCpBlsxCGt97s8rD/kufke21UUHRA== + dependencies: + "@parcel/compressor-raw" "2.9.3" + "@parcel/config-default" "2.9.3" + "@parcel/core" "2.9.3" + "@parcel/optimizer-data-url" "2.9.3" + "@parcel/reporter-bundle-buddy" "2.9.3" + "@parcel/resolver-default" "2.9.3" + "@parcel/runtime-js" "2.8.3" + "@parcel/runtime-service-worker" "2.9.3" + "@parcel/source-map" "2.1.1" + "@parcel/transformer-babel" "2.9.3" + "@parcel/transformer-css" "2.9.3" + "@parcel/transformer-graphql" "2.9.3" + "@parcel/transformer-inline-string" "2.9.3" + "@parcel/transformer-js" "2.9.3" + "@parcel/transformer-less" "2.9.3" + "@parcel/transformer-postcss" "2.9.3" + "@parcel/transformer-raw" "2.9.3" + "@parcel/transformer-react-refresh-wrap" "2.9.3" + "@parcel/transformer-sass" "2.9.3" + "@parcel/transformer-svg-react" "2.9.3" + "@parcel/transformer-worklet" "2.9.3" + "@plasmohq/parcel-bundler" "0.5.5" + "@plasmohq/parcel-compressor-utf8" "0.0.6" + "@plasmohq/parcel-namer-manifest" "0.3.12" + "@plasmohq/parcel-optimizer-encapsulate" "0.0.7" + "@plasmohq/parcel-optimizer-es" "0.4.0" + "@plasmohq/parcel-packager" "0.6.14" + "@plasmohq/parcel-resolver" "0.13.1" + "@plasmohq/parcel-resolver-post" "0.4.2" + "@plasmohq/parcel-runtime" "0.23.0" + "@plasmohq/parcel-transformer-inject-env" "0.2.11" + "@plasmohq/parcel-transformer-inline-css" "0.3.9" + "@plasmohq/parcel-transformer-manifest" "0.17.8" + "@plasmohq/parcel-transformer-svelte" "0.5.2" + "@plasmohq/parcel-transformer-vue" "0.5.0" + +"@plasmohq/parcel-core@0.1.8": + version "0.1.8" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-core/-/parcel-core-0.1.8.tgz#d532ff3e9d6745fd01293a8b677382c3d39c9a6f" + integrity sha512-kMWuazvf925ZAn2yHzzrb4Zsje1titFmvi/C5cXrI0TH58eT7n6GUiRXiOYP4JgGDHs/pEygx3WPuyWVTNF2HQ== + dependencies: + "@parcel/cache" "2.9.3" + "@parcel/core" "2.9.3" + "@parcel/diagnostic" "2.9.3" + "@parcel/events" "2.9.3" + "@parcel/fs" "2.9.3" + "@parcel/graph" "2.9.3" + "@parcel/hash" "2.9.3" + "@parcel/logger" "2.9.3" + "@parcel/package-manager" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "2.1.1" + "@parcel/types" "2.9.3" + "@parcel/utils" "2.9.3" + "@parcel/watcher" "2.2.0" + "@parcel/workers" "2.9.3" + abortcontroller-polyfill "1.7.5" + nullthrows "1.1.1" + +"@plasmohq/parcel-namer-manifest@0.3.12": + version "0.3.12" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-namer-manifest/-/parcel-namer-manifest-0.3.12.tgz#4e4d9c1e7055604cd4b7d68c5d89b8f2abad52e7" + integrity sha512-mNyIVK4nRbjlnXXUygBcmV7xLzgS1HZ3vedxUrMQah0Wp0Y20GFcomToDBC0w9NXIZVSSKY0bRIeh0B6/verfQ== + dependencies: + "@parcel/core" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/types" "2.9.3" + "@parcel/utils" "2.9.3" + +"@plasmohq/parcel-optimizer-encapsulate@0.0.7": + version "0.0.7" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-optimizer-encapsulate/-/parcel-optimizer-encapsulate-0.0.7.tgz#200d8d64c3c21cbcbd9e852b559851e752d8d6b1" + integrity sha512-mA9kY5dwuebQ4vLX6A5yTFo0gZZNWKUHpF6yO0lYq3oP843MyRJS8SxAtzQb4vTlVWPk3SX6Yw81DgBo4I6Xiw== + dependencies: + "@parcel/core" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "2.1.1" + "@parcel/types" "2.9.3" + +"@plasmohq/parcel-optimizer-es@0.4.0": + version "0.4.0" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-optimizer-es/-/parcel-optimizer-es-0.4.0.tgz#7a1ff796c642bbde7e82996d37433e190c6d0425" + integrity sha512-Iz1cTuw38wEbSQ36/dVKh5MyRA12/Ecrx90pqaIkoqA9ZSZuxuWWa7rPa3bVMFkzi28BpVHW1z9EnhVN4188kQ== + dependencies: + "@parcel/core" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "2.1.1" + "@parcel/utils" "2.9.3" + "@swc/core" "1.3.82" + nullthrows "1.1.1" + +"@plasmohq/parcel-packager@0.6.14": + version "0.6.14" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-packager/-/parcel-packager-0.6.14.tgz#8a450408366ae4d6e8e2361f8947504cb44f249c" + integrity sha512-pFab9COfafx66CtOFWgLgKf4TUPLb5EiTO4ecRz1HDINSvPl48ci+3czmtSzOI4+b1uiqZYxUB3eeaMfh9XWpA== + dependencies: + "@parcel/core" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/types" "2.9.3" + "@parcel/utils" "2.9.3" + nullthrows "1.1.1" + +"@plasmohq/parcel-resolver-post@0.4.2": + version "0.4.2" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-resolver-post/-/parcel-resolver-post-0.4.2.tgz#f68cefb7e1fa8d1515fca1dfd285e7c35d47a81a" + integrity sha512-dbrwjUQEhKqKBEgVJjL5ls1p6bpQ3VlDXI5REoaSpwoPcB7TRAcUfTwV4oNGE4eTnw4ElF08JkyslYvKgxosAw== + dependencies: + "@parcel/core" "2.9.3" + "@parcel/hash" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/types" "2.9.3" + "@parcel/utils" "2.9.3" + tsup "7.2.0" + typescript "5.2.2" + +"@plasmohq/parcel-resolver@0.13.1": + version "0.13.1" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-resolver/-/parcel-resolver-0.13.1.tgz#7c205e2a60228954f309bc8009ee47b618431cac" + integrity sha512-IuKr3Ue1+2fsyJPQuHh4Yh36L3FI/2I27X6hC+NHlX/1j9fVYiFk89dTSPNhvAdGN/hwsMjQ/jCiKZGW1157xg== + dependencies: + "@parcel/core" "2.9.3" + "@parcel/hash" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/types" "2.9.3" + fast-glob "3.2.12" + fs-extra "11.1.1" + got "13.0.0" + +"@plasmohq/parcel-runtime@0.23.0": + version "0.23.0" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-runtime/-/parcel-runtime-0.23.0.tgz#a6c9a13002f06fbfe5f187bcb10e04b29497a3c4" + integrity sha512-+ZqH9XksSbWPC6pnvjmvmykxh1SfyYkSKyOeNQSeHsPFo40fADUKOda8Hw/vm/g5p8GIlv5YSb2iYZzCWmKs1g== + dependencies: + "@parcel/core" "2.9.3" + "@parcel/plugin" "2.9.3" + react-refresh "0.14.0" + +"@plasmohq/parcel-transformer-inject-env@0.2.11": + version "0.2.11" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-transformer-inject-env/-/parcel-transformer-inject-env-0.2.11.tgz#311d7a019f9b754452e72d33a9744725a292f65d" + integrity sha512-eGwwoaDbPPwrRcEgOi/BpLVGe5ttrBhs91NBcKMpE/D5gktfbJPD1zHG8MPtQdE4Iq23aG3JUbiT5clmdwtUhQ== + dependencies: + "@parcel/core" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/types" "2.9.3" + +"@plasmohq/parcel-transformer-inline-css@0.3.9": + version "0.3.9" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-transformer-inline-css/-/parcel-transformer-inline-css-0.3.9.tgz#fa6e8e4fc3df5ab394f65455653edf126fc6cf9f" + integrity sha512-da1gVe3TX7J5lC6M04iHzp2NPwhh40n/Gx/Di9o2KLLEYe0q+pKlI5OjN9zf5kpXwXfVO7QzE5B1/tRGoEu2Bw== + dependencies: + "@parcel/core" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/utils" "2.9.3" + browserslist "4.21.10" + lightningcss "1.21.7" + +"@plasmohq/parcel-transformer-manifest@0.17.8": + version "0.17.8" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-transformer-manifest/-/parcel-transformer-manifest-0.17.8.tgz#288f230dac93d2154c625911b3015ad9a4d3cb87" + integrity sha512-G6XISWddf900Q/4ABlFLBJcqvN1VTYF06NytTOMSDO4dOraxGhgZ0CyC990b+LJEa7nc5xf4xhHQxf3mkjALPQ== + dependencies: + "@mischnic/json-sourcemap" "0.1.0" + "@parcel/core" "2.9.3" + "@parcel/diagnostic" "2.9.3" + "@parcel/fs" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/types" "2.9.3" + "@parcel/utils" "2.9.3" + content-security-policy-parser "0.4.1" + json-schema-to-ts "2.9.2" + nullthrows "1.1.1" + +"@plasmohq/parcel-transformer-svelte@0.5.2": + version "0.5.2" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-transformer-svelte/-/parcel-transformer-svelte-0.5.2.tgz#8f3bbfad7f6fd86232178c6af09f87c5833570c5" + integrity sha512-kZevkKYgYB7KZqi1+8k5ELqrSNKakqBwuTLnIT0BOx/8VKTJ6fwkzW0SR1OFsDJIACRFbMLO77u+erwHkodBEA== + dependencies: + "@parcel/core" "2.9.3" + "@parcel/diagnostic" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "2.1.1" + "@parcel/utils" "2.9.3" + svelte "4.0.1" + +"@plasmohq/parcel-transformer-vue@0.5.0": + version "0.5.0" + resolved "https://registry.npmmirror.com/@plasmohq/parcel-transformer-vue/-/parcel-transformer-vue-0.5.0.tgz#b2b484a29c45463dfc29f078ee2de4747d252890" + integrity sha512-/3oVbajt+DRqtbM0RkKFtfyZR8DVjcsYpj1jHqPParGVBiXwgP0D/8Bj5p5/5Iqihs08gzasTcjKcwQKKdj0og== + dependencies: + "@parcel/core" "2.9.3" + "@parcel/diagnostic" "2.9.3" + "@parcel/plugin" "2.9.3" + "@parcel/source-map" "2.1.1" + "@parcel/types" "2.9.3" + "@parcel/utils" "2.9.3" + "@plasmohq/consolidate" "0.17.0" + "@vue/compiler-sfc" "3.3.4" + nullthrows "1.1.1" + semver "7.5.4" + vue "3.3.4" + +"@pnpm/config.env-replace@^1.1.0": + version "1.1.0" + resolved "https://registry.npmmirror.com/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz#ab29da53df41e8948a00f2433f085f54de8b3a4c" + integrity sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w== + +"@pnpm/network.ca-file@^1.0.1": + version "1.0.2" + resolved "https://registry.npmmirror.com/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz#2ab05e09c1af0cdf2fcf5035bea1484e222f7983" + integrity sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA== + dependencies: + graceful-fs "4.2.10" + +"@pnpm/npm-conf@^2.1.0": + version "2.2.2" + resolved "https://registry.npmmirror.com/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz#0058baf1c26cbb63a828f0193795401684ac86f0" + integrity sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA== + dependencies: + "@pnpm/config.env-replace" "^1.1.0" + "@pnpm/network.ca-file" "^1.0.1" + config-chain "^1.1.11" + +"@sindresorhus/is@^5.2.0": + version "5.6.0" + resolved "https://registry.npmmirror.com/@sindresorhus/is/-/is-5.6.0.tgz#41dd6093d34652cddb5d5bdeee04eafc33826668" + integrity sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g== + +"@svgr/babel-plugin-add-jsx-attribute@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz#74a5d648bd0347bda99d82409d87b8ca80b9a1ba" + integrity sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ== + +"@svgr/babel-plugin-remove-jsx-attribute@*": + version "8.0.0" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz#69177f7937233caca3a1afb051906698f2f59186" + integrity sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA== + +"@svgr/babel-plugin-remove-jsx-empty-expression@*": + version "8.0.0" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz#c2c48104cfd7dcd557f373b70a56e9e3bdae1d44" + integrity sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA== + +"@svgr/babel-plugin-replace-jsx-attribute-value@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz#fb9d22ea26d2bc5e0a44b763d4c46d5d3f596c60" + integrity sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg== + +"@svgr/babel-plugin-svg-dynamic-title@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz#01b2024a2b53ffaa5efceaa0bf3e1d5a4c520ce4" + integrity sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw== + +"@svgr/babel-plugin-svg-em-dimensions@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz#dd3fa9f5b24eb4f93bcf121c3d40ff5facecb217" + integrity sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA== + +"@svgr/babel-plugin-transform-react-native-svg@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz#1d8e945a03df65b601551097d8f5e34351d3d305" + integrity sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg== + +"@svgr/babel-plugin-transform-svg-component@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz#48620b9e590e25ff95a80f811544218d27f8a250" + integrity sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ== + +"@svgr/babel-preset@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-preset/-/babel-preset-6.5.1.tgz#b90de7979c8843c5c580c7e2ec71f024b49eb828" + integrity sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "^6.5.1" + "@svgr/babel-plugin-remove-jsx-attribute" "*" + "@svgr/babel-plugin-remove-jsx-empty-expression" "*" + "@svgr/babel-plugin-replace-jsx-attribute-value" "^6.5.1" + "@svgr/babel-plugin-svg-dynamic-title" "^6.5.1" + "@svgr/babel-plugin-svg-em-dimensions" "^6.5.1" + "@svgr/babel-plugin-transform-react-native-svg" "^6.5.1" + "@svgr/babel-plugin-transform-svg-component" "^6.5.1" + +"@svgr/core@^6.2.0": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/core/-/core-6.5.1.tgz#d3e8aa9dbe3fbd747f9ee4282c1c77a27410488a" + integrity sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw== + dependencies: + "@babel/core" "^7.19.6" + "@svgr/babel-preset" "^6.5.1" + "@svgr/plugin-jsx" "^6.5.1" + camelcase "^6.2.0" + cosmiconfig "^7.0.1" + +"@svgr/hast-util-to-babel-ast@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz#81800bd09b5bcdb968bf6ee7c863d2288fdb80d2" + integrity sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw== + dependencies: + "@babel/types" "^7.20.0" + entities "^4.4.0" + +"@svgr/plugin-jsx@^6.2.0", "@svgr/plugin-jsx@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz#0e30d1878e771ca753c94e69581c7971542a7072" + integrity sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw== + dependencies: + "@babel/core" "^7.19.6" + "@svgr/babel-preset" "^6.5.1" + "@svgr/hast-util-to-babel-ast" "^6.5.1" + svg-parser "^2.0.4" + +"@svgr/plugin-svgo@^6.2.0": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz#0f91910e988fc0b842f88e0960c2862e022abe84" + integrity sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ== + dependencies: + cosmiconfig "^7.0.1" + deepmerge "^4.2.2" + svgo "^2.8.0" + +"@swc/core-darwin-arm64@1.3.102": + version "1.3.102" + resolved "https://registry.npmmirror.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.102.tgz#2bbd90a8751e6eee981f857ec3f0b6233208da37" + integrity sha512-CJDxA5Wd2cUMULj3bjx4GEoiYyyiyL8oIOu4Nhrs9X+tlg8DnkCm4nI57RJGP8Mf6BaXPIJkHX8yjcefK2RlDA== + +"@swc/core-darwin-arm64@1.3.82": + version "1.3.82" + resolved "https://registry.npmmirror.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.82.tgz#bbf9874747b51053d8a59ea26c3e235c326f24a3" + integrity sha512-JfsyDW34gVKD3uE0OUpUqYvAD3yseEaicnFP6pB292THtLJb0IKBBnK50vV/RzEJtc1bR3g1kNfxo2PeurZTrA== + +"@swc/core-darwin-x64@1.3.102": + version "1.3.102" + resolved "https://registry.npmmirror.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.102.tgz#df16d51f45771d3c9cca8554b28a3190cdb075cf" + integrity sha512-X5akDkHwk6oAer49oER0qZMjNMkLH3IOZaV1m98uXIasAGyjo5WH1MKPeMLY1sY6V6TrufzwiSwD4ds571ytcg== + +"@swc/core-darwin-x64@1.3.82": + version "1.3.82" + resolved "https://registry.npmmirror.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.82.tgz#145cdde16678e0d793620035783e5b413a16ac43" + integrity sha512-ogQWgNMq7qTpITjcP3dnzkFNj7bh6SwMr859GvtOTrE75H7L7jDWxESfH4f8foB/LGxBKiDNmxKhitCuAsZK4A== + +"@swc/core-linux-arm-gnueabihf@1.3.102": + version "1.3.102" + resolved "https://registry.npmmirror.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.102.tgz#eb71697590c56ea261fa9a4b198c45304c7ece39" + integrity sha512-kJH3XtZP9YQdjq/wYVBeFuiVQl4HaC4WwRrIxAHwe2OyvrwUI43dpW3LpxSggBnxXcVCXYWf36sTnv8S75o2Gw== + +"@swc/core-linux-arm-gnueabihf@1.3.82": + version "1.3.82" + resolved "https://registry.npmmirror.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.82.tgz#0c2f32c5793f2ac8e8ccf416aec84d016c30ef7b" + integrity sha512-7TMXG1lXlNhD0kUiEqs+YlGV4irAdBa2quuy+XI3oJf2fBK6dQfEq4xBy65B3khrorzQS3O0oDGQ+cmdpHExHA== + +"@swc/core-linux-arm64-gnu@1.3.102": + version "1.3.102" + resolved "https://registry.npmmirror.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.102.tgz#75d72d5253d56723fa7054e1a8f313bf3d17b1a2" + integrity sha512-flQP2WDyCgO24WmKA1wjjTx+xfCmavUete2Kp6yrM+631IHLGnr17eu7rYJ/d4EnDBId/ytMyrnWbTVkaVrpbQ== + +"@swc/core-linux-arm64-gnu@1.3.82": + version "1.3.82" + resolved "https://registry.npmmirror.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.82.tgz#2313d4901fa0ebdd2a0f189909073e1e8a07f1d6" + integrity sha512-26JkOujbzcItPAmIbD5vHJxQVy5ihcSu3YHTKwope1h28sApZdtE7S3e2G3gsZRTIdsCQkXUtAQeqHxGWWR3pw== + +"@swc/core-linux-arm64-musl@1.3.102": + version "1.3.102" + resolved "https://registry.npmmirror.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.102.tgz#7db86022fec57c1e06c573d45cef5e911bcc420e" + integrity sha512-bQEQSnC44DyoIGLw1+fNXKVGoCHi7eJOHr8BdH0y1ooy9ArskMjwobBFae3GX4T1AfnrTaejyr0FvLYIb0Zkog== + +"@swc/core-linux-arm64-musl@1.3.82": + version "1.3.82" + resolved "https://registry.npmmirror.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.82.tgz#6e96cf6e52e647fecf27511d766bea90e96f8a2f" + integrity sha512-8Izj9tuuMpoc3cqiPBRtwqpO1BZ/+sfZVsEhLxrbOFlcSb8LnKyMle1g3JMMUwI4EU75RGVIzZMn8A6GOKdJbA== + +"@swc/core-linux-x64-gnu@1.3.102": + version "1.3.102" + resolved "https://registry.npmmirror.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.102.tgz#298a25aa854924bedc7e4b69da52da19f84fc7a8" + integrity sha512-dFvnhpI478svQSxqISMt00MKTDS0e4YtIr+ioZDG/uJ/q+RpcNy3QI2KMm05Fsc8Y0d4krVtvCKWgfUMsJZXAg== + +"@swc/core-linux-x64-gnu@1.3.82": + version "1.3.82" + resolved "https://registry.npmmirror.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.82.tgz#6275c10d7c8c0768550bc7934c9dd8cde4881d92" + integrity sha512-0GSrIBScQwTaPv46T2qB7XnDYxndRCpwH4HMjh6FN+I+lfPUhTSJKW8AonqrqT1TbpFIgvzQs7EnTsD7AnSCow== + +"@swc/core-linux-x64-musl@1.3.102": + version "1.3.102" + resolved "https://registry.npmmirror.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.102.tgz#1bcd911aaa88b96f3bb665b0fd84ef4d21adf886" + integrity sha512-+a0M3CvjeIRNA/jTCzWEDh2V+mhKGvLreHOL7J97oULZy5yg4gf7h8lQX9J8t9QLbf6fsk+0F8bVH1Ie/PbXjA== + +"@swc/core-linux-x64-musl@1.3.82": + version "1.3.82" + resolved "https://registry.npmmirror.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.82.tgz#edb98c30bd0de42bf1a63469937630d942c71988" + integrity sha512-KJUnaaepDKNzrEbwz4jv0iC3/t9x0NSoe06fnkAlhh2+NFKWKKJhVCOBTrpds8n7eylBDIXUlK34XQafjVMUdg== + +"@swc/core-win32-arm64-msvc@1.3.102": + version "1.3.102" + resolved "https://registry.npmmirror.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.102.tgz#59084786364d03fa4a120bdd589a557a00caedeb" + integrity sha512-w76JWLjkZNOfkB25nqdWUNCbt0zJ41CnWrJPZ+LxEai3zAnb2YtgB/cCIrwxDebRuMgE9EJXRj7gDDaTEAMOOQ== + +"@swc/core-win32-arm64-msvc@1.3.82": + version "1.3.82" + resolved "https://registry.npmmirror.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.82.tgz#0a8e9b361aac37d01f684c8a3d3e94e5f8c3b14f" + integrity sha512-TR3MHKhDYIyGyFcyl2d/p1ftceXcubAhX5wRSOdtOyr5+K/v3jbyCCqN7bbqO5o43wQVCwwR/drHleYyDZvg8Q== + +"@swc/core-win32-ia32-msvc@1.3.102": + version "1.3.102" + resolved "https://registry.npmmirror.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.102.tgz#27954889d940a63796d58ff7753f5f27ed381a1f" + integrity sha512-vlDb09HiGqKwz+2cxDS9T5/461ipUQBplvuhW+cCbzzGuPq8lll2xeyZU0N1E4Sz3MVdSPx1tJREuRvlQjrwNg== + +"@swc/core-win32-ia32-msvc@1.3.82": + version "1.3.82" + resolved "https://registry.npmmirror.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.82.tgz#096854ff764282766271f1354ee1214358a8bf01" + integrity sha512-ZX4HzVVt6hs84YUg70UvyBJnBOIspmQQM0iXSzBvOikk3zRoN7BnDwQH4GScvevCEBuou60+i4I6d5kHLOfh8Q== + +"@swc/core-win32-x64-msvc@1.3.102": + version "1.3.102" + resolved "https://registry.npmmirror.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.102.tgz#477da542e6b01b3eb64476ec9a78f497a9b87807" + integrity sha512-E/jfSD7sShllxBwwgDPeXp1UxvIqehj/ShSUqq1pjR/IDRXngcRSXKJK92mJkNFY7suH6BcCWwzrxZgkO7sWmw== + +"@swc/core-win32-x64-msvc@1.3.82": + version "1.3.82" + resolved "https://registry.npmmirror.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.82.tgz#1181070bff4a13a7fcc7f1020eef1571f8c1257a" + integrity sha512-4mJMnex21kbQoaHeAmHnVwQN9/XAfPszJ6n9HI7SVH+aAHnbBIR0M59/b50/CJMjTj5niUGk7EwQ3nhVNOG32g== + +"@swc/core@1.3.82": + version "1.3.82" + resolved "https://registry.npmmirror.com/@swc/core/-/core-1.3.82.tgz#8f6c53db3c23a1769b6c5085fbcb3b1df9548a40" + integrity sha512-jpC1a18HMH67018Ij2jh+hT7JBFu7ZKcQVfrZ8K6JuEY+kjXmbea07P9MbQUZbAe0FB+xi3CqEVCP73MebodJQ== + dependencies: + "@swc/types" "^0.1.4" + optionalDependencies: + "@swc/core-darwin-arm64" "1.3.82" + "@swc/core-darwin-x64" "1.3.82" + "@swc/core-linux-arm-gnueabihf" "1.3.82" + "@swc/core-linux-arm64-gnu" "1.3.82" + "@swc/core-linux-arm64-musl" "1.3.82" + "@swc/core-linux-x64-gnu" "1.3.82" + "@swc/core-linux-x64-musl" "1.3.82" + "@swc/core-win32-arm64-msvc" "1.3.82" + "@swc/core-win32-ia32-msvc" "1.3.82" + "@swc/core-win32-x64-msvc" "1.3.82" + +"@swc/core@^1.3.36": + version "1.3.102" + resolved "https://registry.npmmirror.com/@swc/core/-/core-1.3.102.tgz#870874bcf1d78cd7bb1bc66b31bf2b1a87c1a667" + integrity sha512-OAjNLY/f6QWKSDzaM3bk31A+OYHu6cPa9P/rFIx8X5d24tHXUpRiiq6/PYI6SQRjUPlB72GjsjoEU8F+ALadHg== + dependencies: + "@swc/counter" "^0.1.1" + "@swc/types" "^0.1.5" + optionalDependencies: + "@swc/core-darwin-arm64" "1.3.102" + "@swc/core-darwin-x64" "1.3.102" + "@swc/core-linux-arm-gnueabihf" "1.3.102" + "@swc/core-linux-arm64-gnu" "1.3.102" + "@swc/core-linux-arm64-musl" "1.3.102" + "@swc/core-linux-x64-gnu" "1.3.102" + "@swc/core-linux-x64-musl" "1.3.102" + "@swc/core-win32-arm64-msvc" "1.3.102" + "@swc/core-win32-ia32-msvc" "1.3.102" + "@swc/core-win32-x64-msvc" "1.3.102" + +"@swc/counter@^0.1.1": + version "0.1.2" + resolved "https://registry.npmmirror.com/@swc/counter/-/counter-0.1.2.tgz#bf06d0770e47c6f1102270b744e17b934586985e" + integrity sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw== + +"@swc/helpers@^0.5.0": + version "0.5.3" + resolved "https://registry.npmmirror.com/@swc/helpers/-/helpers-0.5.3.tgz#98c6da1e196f5f08f977658b80d6bd941b5f294f" + integrity sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A== + dependencies: + tslib "^2.4.0" + +"@swc/types@^0.1.4", "@swc/types@^0.1.5": + version "0.1.5" + resolved "https://registry.npmmirror.com/@swc/types/-/types-0.1.5.tgz#043b731d4f56a79b4897a3de1af35e75d56bc63a" + integrity sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw== + +"@szmarczak/http-timer@^5.0.1": + version "5.0.1" + resolved "https://registry.npmmirror.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" + integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== + dependencies: + defer-to-connect "^2.0.1" + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.npmmirror.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + +"@types/chrome@0.0.251": + version "0.0.251" + resolved "https://registry.npmmirror.com/@types/chrome/-/chrome-0.0.251.tgz#dd1a6eaf8657d66a77b42d73b4c5b3c921394c29" + integrity sha512-UF+yr0LEKWWGsKxQ5A3XOSF5SNoU1ctW3pXcWJPpT8OOUTEspYeaLU8spDKe+6xalXeMTS0TBrX1g0b6qlWmkw== + dependencies: + "@types/filesystem" "*" + "@types/har-format" "*" + +"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.1": + version "1.0.5" + resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + +"@types/filesystem@*": + version "0.0.35" + resolved "https://registry.npmmirror.com/@types/filesystem/-/filesystem-0.0.35.tgz#6d6766626083e2b397c09bdc57092827120db11d" + integrity sha512-1eKvCaIBdrD2mmMgy5dwh564rVvfEhZTWVQQGRNn0Nt4ZEnJ0C8oSUCzvMKRA4lGde5oEVo+q2MrTTbV/GHDCQ== + dependencies: + "@types/filewriter" "*" + +"@types/filewriter@*": + version "0.0.32" + resolved "https://registry.npmmirror.com/@types/filewriter/-/filewriter-0.0.32.tgz#3cf7e0f870e54e60ed1bbd9280fa24a9444d3b48" + integrity sha512-Kpi2GXQyYJdjL8mFclL1eDgihn1SIzorMZjD94kdPZh9E4VxGOeyjPxi5LpsM4Zku7P0reqegZTt2GxhmA9VBg== + +"@types/har-format@*": + version "1.2.15" + resolved "https://registry.npmmirror.com/@types/har-format/-/har-format-1.2.15.tgz#f352493638c2f89d706438a19a9eb300b493b506" + integrity sha512-RpQH4rXLuvTXKR0zqHq3go0RVXYv/YVqv4TnPH95VbwUxZdQlK1EtcMvQvMpDngHbt13Csh9Z4qT9AbkiQH5BA== + +"@types/http-cache-semantics@^4.0.2": + version "4.0.4" + resolved "https://registry.npmmirror.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" + integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== + +"@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/node@20.9.0": + version "20.9.0" + resolved "https://registry.npmmirror.com/@types/node/-/node-20.9.0.tgz#bfcdc230583aeb891cf51e73cfdaacdd8deae298" + integrity sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw== + dependencies: + undici-types "~5.26.4" + +"@types/parse-json@^4.0.0": + version "4.0.2" + resolved "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== + +"@types/prop-types@*": + version "15.7.11" + resolved "https://registry.npmmirror.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" + integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== + +"@types/react-dom@18.2.15": + version "18.2.15" + resolved "https://registry.npmmirror.com/@types/react-dom/-/react-dom-18.2.15.tgz#921af67f9ee023ac37ea84b1bc0cc40b898ea522" + integrity sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg== + dependencies: + "@types/react" "*" + +"@types/react@*": + version "18.2.47" + resolved "https://registry.npmmirror.com/@types/react/-/react-18.2.47.tgz#85074b27ab563df01fbc3f68dc64bf7050b0af40" + integrity sha512-xquNkkOirwyCgoClNk85BjP+aqnIS+ckAJ8i37gAbDs14jfW/J23f2GItAf33oiUPQnqNMALiFeoM9Y5mbjpVQ== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/react@18.2.37": + version "18.2.37" + resolved "https://registry.npmmirror.com/@types/react/-/react-18.2.37.tgz#0f03af69e463c0f19a356c2660dbca5d19c44cae" + integrity sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.8" + resolved "https://registry.npmmirror.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" + integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== + +"@vue/compiler-core@3.3.4": + version "3.3.4" + resolved "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz#7fbf591c1c19e1acd28ffd284526e98b4f581128" + integrity sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g== + dependencies: + "@babel/parser" "^7.21.3" + "@vue/shared" "3.3.4" + estree-walker "^2.0.2" + source-map-js "^1.0.2" + +"@vue/compiler-dom@3.3.4": + version "3.3.4" + resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz#f56e09b5f4d7dc350f981784de9713d823341151" + integrity sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w== + dependencies: + "@vue/compiler-core" "3.3.4" + "@vue/shared" "3.3.4" + +"@vue/compiler-sfc@3.3.4": + version "3.3.4" + resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz#b19d942c71938893535b46226d602720593001df" + integrity sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ== + dependencies: + "@babel/parser" "^7.20.15" + "@vue/compiler-core" "3.3.4" + "@vue/compiler-dom" "3.3.4" + "@vue/compiler-ssr" "3.3.4" + "@vue/reactivity-transform" "3.3.4" + "@vue/shared" "3.3.4" + estree-walker "^2.0.2" + magic-string "^0.30.0" + postcss "^8.1.10" + source-map-js "^1.0.2" + +"@vue/compiler-ssr@3.3.4": + version "3.3.4" + resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz#9d1379abffa4f2b0cd844174ceec4a9721138777" + integrity sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ== + dependencies: + "@vue/compiler-dom" "3.3.4" + "@vue/shared" "3.3.4" + +"@vue/reactivity-transform@3.3.4": + version "3.3.4" + resolved "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz#52908476e34d6a65c6c21cd2722d41ed8ae51929" + integrity sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw== + dependencies: + "@babel/parser" "^7.20.15" + "@vue/compiler-core" "3.3.4" + "@vue/shared" "3.3.4" + estree-walker "^2.0.2" + magic-string "^0.30.0" + +"@vue/reactivity@3.3.4": + version "3.3.4" + resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.4.tgz#a27a29c6cd17faba5a0e99fbb86ee951653e2253" + integrity sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ== + dependencies: + "@vue/shared" "3.3.4" + +"@vue/runtime-core@3.3.4": + version "3.3.4" + resolved "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.3.4.tgz#4bb33872bbb583721b340f3088888394195967d1" + integrity sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA== + dependencies: + "@vue/reactivity" "3.3.4" + "@vue/shared" "3.3.4" + +"@vue/runtime-dom@3.3.4": + version "3.3.4" + resolved "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz#992f2579d0ed6ce961f47bbe9bfe4b6791251566" + integrity sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ== + dependencies: + "@vue/runtime-core" "3.3.4" + "@vue/shared" "3.3.4" + csstype "^3.1.1" + +"@vue/server-renderer@3.3.4": + version "3.3.4" + resolved "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.3.4.tgz#ea46594b795d1536f29bc592dd0f6655f7ea4c4c" + integrity sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ== + dependencies: + "@vue/compiler-ssr" "3.3.4" + "@vue/shared" "3.3.4" + +"@vue/shared@3.3.4": + version "3.3.4" + resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz#06e83c5027f464eef861c329be81454bc8b70780" + integrity sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ== + +abortcontroller-polyfill@1.7.5, abortcontroller-polyfill@^1.1.9: + version "1.7.5" + resolved "https://registry.npmmirror.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed" + integrity sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ== + +acorn@^8.10.0, acorn@^8.9.0: + version "8.11.3" + resolved "https://registry.npmmirror.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + +ansi-escapes@^4.3.2: + version "4.3.2" + resolved "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.npmmirror.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +aria-query@^5.3.0: + version "5.3.0" + resolved "https://registry.npmmirror.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +axobject-query@^3.2.1: + version "3.2.1" + resolved "https://registry.npmmirror.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" + integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg== + dependencies: + dequal "^2.0.3" + +b4a@^1.6.4: + version "1.6.4" + resolved "https://registry.npmmirror.com/b4a/-/b4a-1.6.4.tgz#ef1c1422cae5ce6535ec191baeed7567443f36c9" + integrity sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base-x@^3.0.8: + version "3.0.9" + resolved "https://registry.npmmirror.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bl@^4.0.3, bl@^4.1.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.npmmirror.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@4.21.10: + version "4.21.10" + resolved "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" + integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== + dependencies: + caniuse-lite "^1.0.30001517" + electron-to-chromium "^1.4.477" + node-releases "^2.0.13" + update-browserslist-db "^1.0.11" + +browserslist@^4.22.2, browserslist@^4.6.6: + version "4.22.2" + resolved "https://registry.npmmirror.com/browserslist/-/browserslist-4.22.2.tgz#704c4943072bd81ea18997f3bd2180e89c77874b" + integrity sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A== + dependencies: + caniuse-lite "^1.0.30001565" + electron-to-chromium "^1.4.601" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + +buffer@6.0.3: + version "6.0.3" + resolved "https://registry.npmmirror.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +bundle-require@^4.0.0: + version "4.0.2" + resolved "https://registry.npmmirror.com/bundle-require/-/bundle-require-4.0.2.tgz#65fc74ff14eabbba36d26c9a6161bd78fff6b29e" + integrity sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag== + dependencies: + load-tsconfig "^0.2.3" + +cac@^6.7.12: + version "6.7.14" + resolved "https://registry.npmmirror.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" + integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== + +cacheable-lookup@^7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz#3476a8215d046e5a3202a9209dd13fec1f933a27" + integrity sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w== + +cacheable-request@^10.2.8: + version "10.2.14" + resolved "https://registry.npmmirror.com/cacheable-request/-/cacheable-request-10.2.14.tgz#eb915b665fda41b79652782df3f553449c406b9d" + integrity sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ== + dependencies: + "@types/http-cache-semantics" "^4.0.2" + get-stream "^6.0.1" + http-cache-semantics "^4.1.1" + keyv "^4.5.3" + mimic-response "^4.0.0" + normalize-url "^8.0.0" + responselike "^3.0.0" + +call-bind@^1.0.2: + version "1.0.5" + resolved "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== + dependencies: + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.npmmirror.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001517, caniuse-lite@^1.0.30001565: + version "1.0.30001576" + resolved "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz#893be772cf8ee6056d6c1e2d07df365b9ec0a5c4" + integrity sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg== + +chalk@5.3.0, chalk@^5.3.0: + version "5.3.0" + resolved "https://registry.npmmirror.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +change-case@5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/change-case/-/change-case-5.1.2.tgz#1a1feb43f88b7595c6e8db44b5a27b24fa8a9ebd" + integrity sha512-CAtbGEDulyjzs05RXy3uKcwqeztz/dMEuAc1Xu9NQBsbrhuGMneL0u9Dj5SoutLKBFYun8txxYIwhjtLNfUmCA== + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.npmmirror.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.1: + version "3.5.3" + resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.npmmirror.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.npmmirror.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-spinners@^2.5.0: + version "2.9.2" + resolved "https://registry.npmmirror.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== + +cli-width@^4.1.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.npmmirror.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== + +clone@^2.1.1: + version "2.1.2" + resolved "https://registry.npmmirror.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== + +code-red@^1.0.3: + version "1.0.4" + resolved "https://registry.npmmirror.com/code-red/-/code-red-1.0.4.tgz#59ba5c9d1d320a4ef795bc10a28bd42bfebe3e35" + integrity sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.15" + "@types/estree" "^1.0.1" + acorn "^8.10.0" + estree-walker "^3.0.3" + periscopic "^3.1.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.9.0: + version "1.9.1" + resolved "https://registry.npmmirror.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" + integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^4.2.3: + version "4.2.3" + resolved "https://registry.npmmirror.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a" + integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== + dependencies: + color-convert "^2.0.1" + color-string "^1.9.0" + +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.npmmirror.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +config-chain@^1.1.11: + version "1.1.13" + resolved "https://registry.npmmirror.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +content-security-policy-parser@0.4.1: + version "0.4.1" + resolved "https://registry.npmmirror.com/content-security-policy-parser/-/content-security-policy-parser-0.4.1.tgz#27b507649b1b75bc75f179df91919a869ee116b5" + integrity sha512-NNJS8XPnx3OKr/CUOSwDSJw+lWTrZMYnclLKj0Y9CYOfJNJTWLFGPg3u2hYgbXMXKVRkZR2fbyReNQ1mUff/Qg== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +copy-anything@^2.0.1: + version "2.0.6" + resolved "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz#092454ea9584a7b7ad5573062b2a87f5900fc480" + integrity sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw== + dependencies: + is-what "^3.14.1" + +cosmiconfig@^7.0.1: + version "7.1.0" + resolved "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +cosmiconfig@^8.0.0: + version "8.3.6" + resolved "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== + dependencies: + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + path-type "^4.0.0" + +cross-spawn@^7.0.0, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-random-string@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/crypto-random-string/-/crypto-random-string-4.0.0.tgz#5a3cc53d7dd86183df5da0312816ceeeb5bb1fc2" + integrity sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA== + dependencies: + type-fest "^1.0.1" + +css-select@^4.1.3: + version "4.3.0" + resolved "https://registry.npmmirror.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== + dependencies: + boolbase "^1.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-tree@^1.1.2, css-tree@^1.1.3: + version "1.1.3" + resolved "https://registry.npmmirror.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + +css-tree@^2.3.1: + version "2.3.1" + resolved "https://registry.npmmirror.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" + integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== + dependencies: + mdn-data "2.0.30" + source-map-js "^1.0.1" + +css-what@^6.0.1: + version "6.1.0" + resolved "https://registry.npmmirror.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +csso@^4.2.0: + version "4.2.0" + resolved "https://registry.npmmirror.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + +csstype@^3.0.2, csstype@^3.1.1: + version "3.1.3" + resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + +debug@^4.1.0, debug@^4.3.1: + version "4.3.4" + resolved "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.npmmirror.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +defaults@^1.0.3: + version "1.0.4" + resolved "https://registry.npmmirror.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" + integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== + dependencies: + clone "^1.0.2" + +defer-to-connect@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + +define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +dequal@^2.0.3: + version "2.0.3" + resolved "https://registry.npmmirror.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== + +detect-libc@^2.0.0, detect-libc@^2.0.2: + version "2.0.2" + resolved "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" + integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dom-serializer@^1.0.1: + version "1.4.1" + resolved "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.3.0" + resolved "https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^4.2.0, domhandler@^4.2.2, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.npmmirror.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.npmmirror.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +dotenv-expand@10.0.0: + version "10.0.0" + resolved "https://registry.npmmirror.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" + integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== + +dotenv-expand@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== + +dotenv@16.3.1: + version "16.3.1" + resolved "https://registry.npmmirror.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== + +dotenv@^7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/dotenv/-/dotenv-7.0.0.tgz#a2be3cd52736673206e8a85fb5210eea29628e7c" + integrity sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g== + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +electron-to-chromium@^1.4.477, electron-to-chromium@^1.4.601: + version "1.4.625" + resolved "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.625.tgz#a9a1d18ee911f9074a9c42d9e84b1c79b29f4059" + integrity sha512-DENMhh3MFgaPDoXWrVIqSPInQoLImywfCwrSmVl3cf9QHzoZSiutHwGaB/Ql3VkqcQV30rzgdM+BjKqBAJxo5Q== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.npmmirror.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +entities@^3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" + integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== + +entities@^4.4.0: + version "4.5.0" + resolved "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +errno@^0.1.1: + version "0.1.8" + resolved "https://registry.npmmirror.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +esbuild-android-64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz#20a7ae1416c8eaade917fb2453c1259302c637a5" + integrity sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA== + +esbuild-android-arm64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz#9cc0ec60581d6ad267568f29cf4895ffdd9f2f04" + integrity sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ== + +esbuild-darwin-64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz#428e1730ea819d500808f220fbc5207aea6d4410" + integrity sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg== + +esbuild-darwin-arm64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz#b6dfc7799115a2917f35970bfbc93ae50256b337" + integrity sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA== + +esbuild-freebsd-64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz#4e190d9c2d1e67164619ae30a438be87d5eedaf2" + integrity sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA== + +esbuild-freebsd-arm64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz#18a4c0344ee23bd5a6d06d18c76e2fd6d3f91635" + integrity sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA== + +esbuild-linux-32@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz#9a329731ee079b12262b793fb84eea762e82e0ce" + integrity sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg== + +esbuild-linux-64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz#532738075397b994467b514e524aeb520c191b6c" + integrity sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw== + +esbuild-linux-arm64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz#5372e7993ac2da8f06b2ba313710d722b7a86e5d" + integrity sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug== + +esbuild-linux-arm@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz#e734aaf259a2e3d109d4886c9e81ec0f2fd9a9cc" + integrity sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA== + +esbuild-linux-mips64le@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz#c0487c14a9371a84eb08fab0e1d7b045a77105eb" + integrity sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ== + +esbuild-linux-ppc64le@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz#af048ad94eed0ce32f6d5a873f7abe9115012507" + integrity sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w== + +esbuild-linux-riscv64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz#423ed4e5927bd77f842bd566972178f424d455e6" + integrity sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg== + +esbuild-linux-s390x@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz#21d21eaa962a183bfb76312e5a01cc5ae48ce8eb" + integrity sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ== + +esbuild-netbsd-64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz#ae75682f60d08560b1fe9482bfe0173e5110b998" + integrity sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg== + +esbuild-openbsd-64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz#79591a90aa3b03e4863f93beec0d2bab2853d0a8" + integrity sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ== + +esbuild-sunos-64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz#fd528aa5da5374b7e1e93d36ef9b07c3dfed2971" + integrity sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw== + +esbuild-windows-32@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz#0e92b66ecdf5435a76813c4bc5ccda0696f4efc3" + integrity sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ== + +esbuild-windows-64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz#0fc761d785414284fc408e7914226d33f82420d0" + integrity sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw== + +esbuild-windows-arm64@0.15.18: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz#5b5bdc56d341d0922ee94965c89ee120a6a86eb7" + integrity sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ== + +esbuild@^0.15.9: + version "0.15.18" + resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.15.18.tgz#ea894adaf3fbc036d32320a00d4d6e4978a2f36d" + integrity sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q== + optionalDependencies: + "@esbuild/android-arm" "0.15.18" + "@esbuild/linux-loong64" "0.15.18" + esbuild-android-64 "0.15.18" + esbuild-android-arm64 "0.15.18" + esbuild-darwin-64 "0.15.18" + esbuild-darwin-arm64 "0.15.18" + esbuild-freebsd-64 "0.15.18" + esbuild-freebsd-arm64 "0.15.18" + esbuild-linux-32 "0.15.18" + esbuild-linux-64 "0.15.18" + esbuild-linux-arm "0.15.18" + esbuild-linux-arm64 "0.15.18" + esbuild-linux-mips64le "0.15.18" + esbuild-linux-ppc64le "0.15.18" + esbuild-linux-riscv64 "0.15.18" + esbuild-linux-s390x "0.15.18" + esbuild-netbsd-64 "0.15.18" + esbuild-openbsd-64 "0.15.18" + esbuild-sunos-64 "0.15.18" + esbuild-windows-32 "0.15.18" + esbuild-windows-64 "0.15.18" + esbuild-windows-arm64 "0.15.18" + +esbuild@^0.18.2: + version "0.18.20" + resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6" + integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== + optionalDependencies: + "@esbuild/android-arm" "0.18.20" + "@esbuild/android-arm64" "0.18.20" + "@esbuild/android-x64" "0.18.20" + "@esbuild/darwin-arm64" "0.18.20" + "@esbuild/darwin-x64" "0.18.20" + "@esbuild/freebsd-arm64" "0.18.20" + "@esbuild/freebsd-x64" "0.18.20" + "@esbuild/linux-arm" "0.18.20" + "@esbuild/linux-arm64" "0.18.20" + "@esbuild/linux-ia32" "0.18.20" + "@esbuild/linux-loong64" "0.18.20" + "@esbuild/linux-mips64el" "0.18.20" + "@esbuild/linux-ppc64" "0.18.20" + "@esbuild/linux-riscv64" "0.18.20" + "@esbuild/linux-s390x" "0.18.20" + "@esbuild/linux-x64" "0.18.20" + "@esbuild/netbsd-x64" "0.18.20" + "@esbuild/openbsd-x64" "0.18.20" + "@esbuild/sunos-x64" "0.18.20" + "@esbuild/win32-arm64" "0.18.20" + "@esbuild/win32-ia32" "0.18.20" + "@esbuild/win32-x64" "0.18.20" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" + integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== + +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +estree-walker@^3.0.0, estree-walker@^3.0.3: + version "3.0.3" + resolved "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" + integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== + dependencies: + "@types/estree" "^1.0.0" + +events@3.3.0: + version "3.3.0" + resolved "https://registry.npmmirror.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.npmmirror.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + +external-editor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +fast-fifo@^1.1.0, fast-fifo@^1.2.0: + version "1.3.2" + resolved "https://registry.npmmirror.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" + integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== + +fast-glob@3.2.12: + version "3.2.12" + resolved "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-glob@3.3.2, fast-glob@^3.2.9: + version "3.3.2" + resolved "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fastq@^1.6.0: + version "1.16.0" + resolved "https://registry.npmmirror.com/fastq/-/fastq-1.16.0.tgz#83b9a9375692db77a822df081edb6a9cf6839320" + integrity sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA== + dependencies: + reusify "^1.0.4" + +fflate@0.8.1: + version "0.8.1" + resolved "https://registry.npmmirror.com/fflate/-/fflate-0.8.1.tgz#1ed92270674d2ad3c73f077cd0acf26486dae6c9" + integrity sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ== + +figures@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/figures/-/figures-5.0.0.tgz#126cd055052dea699f8a54e8c9450e6ecfc44d5f" + integrity sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg== + dependencies: + escape-string-regexp "^5.0.0" + is-unicode-supported "^1.2.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.npmmirror.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + +form-data-encoder@^2.1.2: + version "2.1.4" + resolved "https://registry.npmmirror.com/form-data-encoder/-/form-data-encoder-2.1.4.tgz#261ea35d2a70d48d30ec7a9603130fa5515e9cd5" + integrity sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw== + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@11.1.1: + version "11.1.1" + resolved "https://registry.npmmirror.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" + integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== + dependencies: + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-port@7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/get-port/-/get-port-7.0.0.tgz#ffcd83da826146529e307a341d7801cae351daff" + integrity sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw== + +get-stream@^6.0.0, get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.npmmirror.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^10.3.10: + version "10.3.10" + resolved "https://registry.npmmirror.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^13.2.0: + version "13.24.0" + resolved "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== + dependencies: + type-fest "^0.20.2" + +globby@^11.0.3: + version "11.1.0" + resolved "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +got@13.0.0: + version "13.0.0" + resolved "https://registry.npmmirror.com/got/-/got-13.0.0.tgz#a2402862cef27a5d0d1b07c0fb25d12b58175422" + integrity sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA== + dependencies: + "@sindresorhus/is" "^5.2.0" + "@szmarczak/http-timer" "^5.0.1" + cacheable-lookup "^7.0.0" + cacheable-request "^10.2.8" + decompress-response "^6.0.0" + form-data-encoder "^2.1.2" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" + responselike "^3.0.0" + +got@^12.1.0: + version "12.6.1" + resolved "https://registry.npmmirror.com/got/-/got-12.6.1.tgz#8869560d1383353204b5a9435f782df9c091f549" + integrity sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ== + dependencies: + "@sindresorhus/is" "^5.2.0" + "@szmarczak/http-timer" "^5.0.1" + cacheable-lookup "^7.0.0" + cacheable-request "^10.2.8" + decompress-response "^6.0.0" + form-data-encoder "^2.1.2" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" + responselike "^3.0.0" + +graceful-fs@4.2.10: + version "4.2.10" + resolved "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.11" + resolved "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +graphql-import-macro@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/graphql-import-macro/-/graphql-import-macro-1.0.0.tgz#987c62bdebf5f26c77bb0e67a5f67afd7d0b5f42" + integrity sha512-YK4g6iP60H++MpP93tb0VwOg7aM5iIC0hdSQKTrEDANeLWf0KFAT9dwlBeMDrhY+jcW7qsAEDtaw58cgVnQXAw== + dependencies: + graphql "^15.0.0" + +graphql@^15.0.0: + version "15.8.0" + resolved "https://registry.npmmirror.com/graphql/-/graphql-15.8.0.tgz#33410e96b012fa3bdb1091cc99a94769db212b38" + integrity sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== + dependencies: + get-intrinsic "^1.2.2" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + +htmlnano@^2.0.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/htmlnano/-/htmlnano-2.1.0.tgz#67b31b3cd3fad23f0b610ca628fdb48382209c3c" + integrity sha512-jVGRE0Ep9byMBKEu0Vxgl8dhXYOUk0iNQ2pjsG+BcRB0u0oDF5A9p/iBGMg/PGKYUyMD0OAGu8dVT5Lzj8S58g== + dependencies: + cosmiconfig "^8.0.0" + posthtml "^0.16.5" + timsort "^0.3.0" + +htmlparser2@^7.1.1: + version "7.2.0" + resolved "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-7.2.0.tgz#8817cdea38bbc324392a90b1990908e81a65f5a5" + integrity sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.2" + domutils "^2.8.0" + entities "^3.0.1" + +http-cache-semantics@^4.1.1: + version "4.1.1" + resolved "https://registry.npmmirror.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http2-wrapper@^2.1.10: + version "2.2.1" + resolved "https://registry.npmmirror.com/http2-wrapper/-/http2-wrapper-2.2.1.tgz#310968153dcdedb160d8b72114363ef5fce1f64a" + integrity sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.2.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +ieee754@^1.1.13, ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@5.2.4: + version "5.2.4" + resolved "https://registry.npmmirror.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +ignore@^5.2.0: + version "5.3.0" + resolved "https://registry.npmmirror.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== + +image-size@~0.5.0: + version "0.5.5" + resolved "https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + integrity sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ== + +immutable@^4.0.0: + version "4.3.4" + resolved "https://registry.npmmirror.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" + integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA== + +import-fresh@^3.2.1, import-fresh@^3.3.0: + version "3.3.0" + resolved "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +inherits@^2.0.3, inherits@^2.0.4: + version "2.0.4" + resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@^1.3.4, ini@~1.3.0: + version "1.3.8" + resolved "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +inquirer@9.2.12: + version "9.2.12" + resolved "https://registry.npmmirror.com/inquirer/-/inquirer-9.2.12.tgz#0348e9311765b7c93fce143bb1c0ef1ae879b1d7" + integrity sha512-mg3Fh9g2zfuVWJn6lhST0O7x4n03k7G8Tx5nvikJkbq8/CK47WDVm+UznF0G6s5Zi0KcyUisr6DU8T67N5U+1Q== + dependencies: + "@ljharb/through" "^2.3.11" + ansi-escapes "^4.3.2" + chalk "^5.3.0" + cli-cursor "^3.1.0" + cli-width "^4.1.0" + external-editor "^3.1.0" + figures "^5.0.0" + lodash "^4.17.21" + mute-stream "1.0.0" + ora "^5.4.1" + run-async "^3.0.0" + rxjs "^7.8.1" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wrap-ansi "^6.2.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.13.0: + version "2.13.1" + resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + +is-json@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/is-json/-/is-json-2.0.1.tgz#6be166d144828a131d686891b983df62c39491ff" + integrity sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/is-path-inside/-/is-path-inside-4.0.0.tgz#805aeb62c47c1b12fc3fd13bfb3ed1e7430071db" + integrity sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA== + +is-reference@^3.0.0, is-reference@^3.0.1: + version "3.0.2" + resolved "https://registry.npmmirror.com/is-reference/-/is-reference-3.0.2.tgz#154747a01f45cd962404ee89d43837af2cba247c" + integrity sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg== + dependencies: + "@types/estree" "*" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +is-unicode-supported@^1.2.0: + version "1.3.0" + resolved "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz#d824984b616c292a2e198207d4a609983842f714" + integrity sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ== + +is-what@^3.14.1: + version "3.14.1" + resolved "https://registry.npmmirror.com/is-what/-/is-what-3.14.1.tgz#e1222f46ddda85dead0fd1c9df131760e77755c1" + integrity sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA== + +isbinaryfile@^4.0.2: + version "4.0.10" + resolved "https://registry.npmmirror.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.npmmirror.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +joycon@^3.0.1: + version "3.1.1" + resolved "https://registry.npmmirror.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" + integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-to-ts@2.9.2: + version "2.9.2" + resolved "https://registry.npmmirror.com/json-schema-to-ts/-/json-schema-to-ts-2.9.2.tgz#a054bc6410f13c7a2fc51aeabac52292e885b98d" + integrity sha512-h9WqLkTVpBbiaPb5OmeUpz/FBLS/kvIJw4oRCPiEisIu2WjMh+aai0QIY2LoOhRFx5r92taGLcerIrzxKBAP6g== + dependencies: + "@babel/runtime" "^7.18.3" + "@types/json-schema" "^7.0.9" + ts-algebra "^1.2.0" + +json5@2.2.3, json5@^2.2.0, json5@^2.2.1, json5@^2.2.3: + version "2.2.3" + resolved "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +less@^4.1.1: + version "4.2.0" + resolved "https://registry.npmmirror.com/less/-/less-4.2.0.tgz#cbefbfaa14a4cd388e2099b2b51f956e1465c450" + integrity sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA== + dependencies: + copy-anything "^2.0.1" + parse-node-version "^1.0.1" + tslib "^2.3.0" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + make-dir "^2.1.0" + mime "^1.4.1" + needle "^3.1.0" + source-map "~0.6.0" + +lightningcss-darwin-arm64@1.21.7: + version "1.21.7" + resolved "https://registry.npmmirror.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.21.7.tgz#0490d5fb8e0a38ec5e58e7c5fad12f7263f54311" + integrity sha512-tt7hIsFio9jZofTVHtCACz6rB6c9RyABMXfA9A/VcKOjS3sq+koX/QkRJWY06utwOImbJIXBC5hbg9t3RkPUAQ== + +lightningcss-darwin-arm64@1.22.1: + version "1.22.1" + resolved "https://registry.npmmirror.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.22.1.tgz#c03c042335fd7e9e1f45c977b39ff6886b8b064f" + integrity sha512-ldvElu+R0QimNTjsKpaZkUv3zf+uefzLy/R1R19jtgOfSRM+zjUCUgDhfEDRmVqJtMwYsdhMI2aJtJChPC6Osg== + +lightningcss-darwin-x64@1.21.7: + version "1.21.7" + resolved "https://registry.npmmirror.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.21.7.tgz#9c9be83d66e34479ddfb54cc292149f96d6af37f" + integrity sha512-F4gS4bf7eWekfPT+TxJNm/pF+QRgZiTrTkQH6cw4/UWfdeZISfuhD5El2dm16giFnY0K5ylIwO+ZusgYNkGSXA== + +lightningcss-darwin-x64@1.22.1: + version "1.22.1" + resolved "https://registry.npmmirror.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.22.1.tgz#cdd380006a176b7faea83d1d642d9c5d65620f74" + integrity sha512-5p2rnlVTv6Gpw4PlTLq925nTVh+HFh4MpegX8dPDYJae+NFVjQ67gY7O6iHIzQjLipDiYejFF0yHrhjU3XgLBQ== + +lightningcss-freebsd-x64@1.21.7: + version "1.21.7" + resolved "https://registry.npmmirror.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.21.7.tgz#c9a622a2b3159198203c99ce7471b877cacf6a1c" + integrity sha512-RMfNzJWXCSfPnL55fcLWEAadcY6QUFT0S8NceNKYzp1KiCZtkJIy6RQ5SaVxPzRqd3iMsahUf5sfnG8N1UQSNQ== + +lightningcss-freebsd-x64@1.22.1: + version "1.22.1" + resolved "https://registry.npmmirror.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.22.1.tgz#dd1b19308e3b0f24b6f79da10fd3975e5e02ebda" + integrity sha512-1FaBtcFrZqB2hkFbAxY//Pnp8koThvyB6AhjbdVqKD4/pu13Rl91fKt2N9qyeQPUt3xy7ORUvSO+dPk3J6EjXg== + +lightningcss-linux-arm-gnueabihf@1.21.7: + version "1.21.7" + resolved "https://registry.npmmirror.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.21.7.tgz#c4b30de126f3dfd4b9689b7f91d7181c65abe50c" + integrity sha512-biSRUDZNx7vubWP1jArw/qqfZKPGpkV/qzunasZzxmqijbZ43sW9faDQYxWNcxPWljJJdF/qs6qcurYFovWtrQ== + +lightningcss-linux-arm-gnueabihf@1.22.1: + version "1.22.1" + resolved "https://registry.npmmirror.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.22.1.tgz#134cf9b41abd44ec53d8bae02c9f6e4f257eb617" + integrity sha512-6rub98tYGfE5I5j0BP8t/2d4BZyu1S7Iz9vUkm0H26snAFHYxLfj3RbQn0xHHIePSetjLnhcg3QlfwUAkD/FYg== + +lightningcss-linux-arm64-gnu@1.21.7: + version "1.21.7" + resolved "https://registry.npmmirror.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.21.7.tgz#79357d765977dfd56a459f6487c8a66d30c8eacb" + integrity sha512-PENY8QekqL9TG3AY/A7rkUBb5ymefGxea7Oe7+x7Hbw4Bz4Hpj5cec5OoMypMqFbURPmpi0fTWx4vSWUPzpDcA== + +lightningcss-linux-arm64-gnu@1.22.1: + version "1.22.1" + resolved "https://registry.npmmirror.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.22.1.tgz#33800723fb3d782c71cc131cf38ca678a0e9d1fa" + integrity sha512-nYO5qGtb/1kkTZu3FeTiM+2B2TAb7m2DkLCTgQIs2bk2o9aEs7I96fwySKcoHWQAiQDGR9sMux9vkV4KQXqPaQ== + +lightningcss-linux-arm64-musl@1.21.7: + version "1.21.7" + resolved "https://registry.npmmirror.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.21.7.tgz#160e07457051df02c4b580dc8d13e5a5f7fe7404" + integrity sha512-pfOipKvA/0X1OjRaZt3870vnV9UGBSjayIqHh0fGx/+aRz3O0MVFHE/60P2UWXpM3YGJEw/hMWtNkrFwqOge8A== + +lightningcss-linux-arm64-musl@1.22.1: + version "1.22.1" + resolved "https://registry.npmmirror.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.22.1.tgz#cff86acaa98a0245add5a333098befc894802137" + integrity sha512-MCV6RuRpzXbunvzwY644iz8cw4oQxvW7oer9xPkdadYqlEyiJJ6wl7FyJOH7Q6ZYH4yjGAUCvxDBxPbnDu9ZVg== + +lightningcss-linux-x64-gnu@1.21.7: + version "1.21.7" + resolved "https://registry.npmmirror.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.21.7.tgz#50c52edfb0ce869b7b23df0ac119ed70e45479d9" + integrity sha512-dgcsis4TAA7s0ia4f31QHX+G4PWPwxk+wJaEQLaV0NdJs09O5hHoA8DpLEr8nrvc/tsRTyVNBP1rDtgzySjpXg== + +lightningcss-linux-x64-gnu@1.22.1: + version "1.22.1" + resolved "https://registry.npmmirror.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.22.1.tgz#3f68602228b49d661db0692548e061456b603ca2" + integrity sha512-RjNgpdM20VUXgV7us/VmlO3Vn2ZRiDnc3/bUxCVvySZWPiVPprpqW/QDWuzkGa+NCUf6saAM5CLsZLSxncXJwg== + +lightningcss-linux-x64-musl@1.21.7: + version "1.21.7" + resolved "https://registry.npmmirror.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.21.7.tgz#c721e301c3d8dd436de14ae98f16bcd8585ca537" + integrity sha512-A+9dXpxld3p4Cd6fxev2eqEvaauYtrgNpXV3t7ioCJy30Oj9nYiNGwiGusM+4MJVcEpUPGUGiuAqY4sWilRDwA== + +lightningcss-linux-x64-musl@1.22.1: + version "1.22.1" + resolved "https://registry.npmmirror.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.22.1.tgz#e713e56798f8a50df3e3f285ef102191a01ef951" + integrity sha512-ZgO4C7Rd6Hv/5MnyY2KxOYmIlzk4rplVolDt3NbkNR8DndnyX0Q5IR4acJWNTBICQ21j3zySzKbcJaiJpk/4YA== + +lightningcss-win32-x64-msvc@1.21.7: + version "1.21.7" + resolved "https://registry.npmmirror.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.21.7.tgz#e86d2eeb8d1cb291e81fffe2b63606f7ed319dce" + integrity sha512-07/8vogEq+C/mF99pdMhh/f19/xreq8N9Ca6AWeVHZIdODyF/pt6KdKSCWDZWIn+3CUxI8gCJWuUWyOc3xymvw== + +lightningcss-win32-x64-msvc@1.22.1: + version "1.22.1" + resolved "https://registry.npmmirror.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.22.1.tgz#48b141554bf05cc4338f064b6892dd5dd16185ef" + integrity sha512-4pozV4eyD0MDET41ZLHAeBo+H04Nm2UEYIk5w/ts40231dRFV7E0cjwbnZvSoc1DXFgecAhiC0L16ruv/ZDCpg== + +lightningcss@1.21.7: + version "1.21.7" + resolved "https://registry.npmmirror.com/lightningcss/-/lightningcss-1.21.7.tgz#9b864625a4ad734aeaecb28649c20705e335e199" + integrity sha512-xITZyh5sLFwRPYUSw15T00Rm7gcQ1qOPuQwNOcvHsTm6nLWTQ723w7zl42wrC5t+xtdg6FPmnXHml1nZxxvp1w== + dependencies: + detect-libc "^1.0.3" + optionalDependencies: + lightningcss-darwin-arm64 "1.21.7" + lightningcss-darwin-x64 "1.21.7" + lightningcss-freebsd-x64 "1.21.7" + lightningcss-linux-arm-gnueabihf "1.21.7" + lightningcss-linux-arm64-gnu "1.21.7" + lightningcss-linux-arm64-musl "1.21.7" + lightningcss-linux-x64-gnu "1.21.7" + lightningcss-linux-x64-musl "1.21.7" + lightningcss-win32-x64-msvc "1.21.7" + +lightningcss@^1.16.1: + version "1.22.1" + resolved "https://registry.npmmirror.com/lightningcss/-/lightningcss-1.22.1.tgz#8108ddecb2e859032bdd99908abd2b37515b1750" + integrity sha512-Fy45PhibiNXkm0cK5FJCbfO8Y6jUpD/YcHf/BtuI+jvYYqSXKF4muk61jjE8YxCR9y+hDYIWSzHTc+bwhDE6rQ== + dependencies: + detect-libc "^1.0.3" + optionalDependencies: + lightningcss-darwin-arm64 "1.22.1" + lightningcss-darwin-x64 "1.22.1" + lightningcss-freebsd-x64 "1.22.1" + lightningcss-linux-arm-gnueabihf "1.22.1" + lightningcss-linux-arm64-gnu "1.22.1" + lightningcss-linux-arm64-musl "1.22.1" + lightningcss-linux-x64-gnu "1.22.1" + lightningcss-linux-x64-musl "1.22.1" + lightningcss-win32-x64-msvc "1.22.1" + +lilconfig@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.0.0.tgz#f8067feb033b5b74dab4602a5f5029420be749bc" + integrity sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +lmdb@2.5.2: + version "2.5.2" + resolved "https://registry.npmmirror.com/lmdb/-/lmdb-2.5.2.tgz#37e28a9fb43405f4dc48c44cec0e13a14c4a6ff1" + integrity sha512-V5V5Xa2Hp9i2XsbDALkBTeHXnBXh/lEmk9p22zdr7jtuOIY9TGhjK6vAvTpOOx9IKU4hJkRWZxn/HsvR1ELLtA== + dependencies: + msgpackr "^1.5.4" + node-addon-api "^4.3.0" + node-gyp-build-optional-packages "5.0.3" + ordered-binary "^1.2.4" + weak-lru-cache "^1.2.2" + optionalDependencies: + "@lmdb/lmdb-darwin-arm64" "2.5.2" + "@lmdb/lmdb-darwin-x64" "2.5.2" + "@lmdb/lmdb-linux-arm" "2.5.2" + "@lmdb/lmdb-linux-arm64" "2.5.2" + "@lmdb/lmdb-linux-x64" "2.5.2" + "@lmdb/lmdb-win32-x64" "2.5.2" + +lmdb@2.7.11: + version "2.7.11" + resolved "https://registry.npmmirror.com/lmdb/-/lmdb-2.7.11.tgz#a24b6d36b5c7ed9889cc2d9e103fdd3f5e144d7e" + integrity sha512-x9bD4hVp7PFLUoELL8RglbNXhAMt5CYhkmss+CEau9KlNoilsTzNi9QDsPZb3KMpOGZXG6jmXhW3bBxE2XVztw== + dependencies: + msgpackr "1.8.5" + node-addon-api "^4.3.0" + node-gyp-build-optional-packages "5.0.6" + ordered-binary "^1.4.0" + weak-lru-cache "^1.2.2" + optionalDependencies: + "@lmdb/lmdb-darwin-arm64" "2.7.11" + "@lmdb/lmdb-darwin-x64" "2.7.11" + "@lmdb/lmdb-linux-arm" "2.7.11" + "@lmdb/lmdb-linux-arm64" "2.7.11" + "@lmdb/lmdb-linux-x64" "2.7.11" + "@lmdb/lmdb-win32-x64" "2.7.11" + +load-tsconfig@^0.2.3: + version "0.2.5" + resolved "https://registry.npmmirror.com/load-tsconfig/-/load-tsconfig-0.2.5.tgz#453b8cd8961bfb912dea77eb6c168fe8cca3d3a1" + integrity sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg== + +locate-character@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/locate-character/-/locate-character-3.0.0.tgz#0305c5b8744f61028ef5d01f444009e00779f974" + integrity sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA== + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.npmmirror.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@^4.1.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +loose-envify@^1.1.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lowercase-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" + integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +"lru-cache@^9.1.1 || ^10.0.0": + version "10.1.0" + resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" + integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== + +magic-string@^0.30.0: + version "0.30.5" + resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9" + integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.15" + +make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + +mdn-data@2.0.30: + version "2.0.30" + resolved "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" + integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.5" + resolved "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime@^1.4.1: + version "1.6.0" + resolved "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@^2.4.4: + version "2.6.0" + resolved "https://registry.npmmirror.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +mimic-response@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/mimic-response/-/mimic-response-4.0.0.tgz#35468b19e7c75d10f5165ea25e75a5ceea7cf70f" + integrity sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg== + +minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.0, minimist@^1.2.3: + version "1.2.8" + resolved "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.4" + resolved "https://registry.npmmirror.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== + +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.npmmirror.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +mnemonic-id@3.2.7: + version "3.2.7" + resolved "https://registry.npmmirror.com/mnemonic-id/-/mnemonic-id-3.2.7.tgz#f7d77d8b39e009ad068117cbafc458a6c6f8cddf" + integrity sha512-kysx9gAGbvrzuFYxKkcRjnsg/NK61ovJOV4F1cHTRl9T5leg+bo6WI0pWIvOFh1Z/yDL0cjA5R3EEGPPLDv/XA== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +msgpackr-extract@^3.0.1, msgpackr-extract@^3.0.2: + version "3.0.2" + resolved "https://registry.npmmirror.com/msgpackr-extract/-/msgpackr-extract-3.0.2.tgz#e05ec1bb4453ddf020551bcd5daaf0092a2c279d" + integrity sha512-SdzXp4kD/Qf8agZ9+iTu6eql0m3kWm1A2y1hkpTeVNENutaB0BwHlSvAIaMxwntmRUAUjon2V4L8Z/njd0Ct8A== + dependencies: + node-gyp-build-optional-packages "5.0.7" + optionalDependencies: + "@msgpackr-extract/msgpackr-extract-darwin-arm64" "3.0.2" + "@msgpackr-extract/msgpackr-extract-darwin-x64" "3.0.2" + "@msgpackr-extract/msgpackr-extract-linux-arm" "3.0.2" + "@msgpackr-extract/msgpackr-extract-linux-arm64" "3.0.2" + "@msgpackr-extract/msgpackr-extract-linux-x64" "3.0.2" + "@msgpackr-extract/msgpackr-extract-win32-x64" "3.0.2" + +msgpackr@1.8.5: + version "1.8.5" + resolved "https://registry.npmmirror.com/msgpackr/-/msgpackr-1.8.5.tgz#8cadfb935357680648f33699d0e833c9179dbfeb" + integrity sha512-mpPs3qqTug6ahbblkThoUY2DQdNXcm4IapwOS3Vm/87vmpzLVelvp9h3It1y9l1VPpiFLV11vfOXnmeEwiIXwg== + optionalDependencies: + msgpackr-extract "^3.0.1" + +msgpackr@^1.5.4: + version "1.10.1" + resolved "https://registry.npmmirror.com/msgpackr/-/msgpackr-1.10.1.tgz#51953bb4ce4f3494f0c4af3f484f01cfbb306555" + integrity sha512-r5VRLv9qouXuLiIBrLpl2d5ZvPt8svdQTl5/vMvE4nzDMyEX4sgW5yWhuBBj5UmgwOTWj8CIdSXn5sAfsHAWIQ== + optionalDependencies: + msgpackr-extract "^3.0.2" + +mute-stream@1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" + integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== + +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + +needle@^3.1.0: + version "3.3.1" + resolved "https://registry.npmmirror.com/needle/-/needle-3.3.1.tgz#63f75aec580c2e77e209f3f324e2cdf3d29bd049" + integrity sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q== + dependencies: + iconv-lite "^0.6.3" + sax "^1.2.4" + +node-abi@^3.3.0: + version "3.54.0" + resolved "https://registry.npmmirror.com/node-abi/-/node-abi-3.54.0.tgz#f6386f7548817acac6434c6cba02999c9aebcc69" + integrity sha512-p7eGEiQil0YUV3ItH4/tBb781L5impVmmx2E9FRKF7d18XXzp4PGT2tdYMFY6wQqgxD0IwNZOiSJ0/K0fSi/OA== + dependencies: + semver "^7.3.5" + +node-addon-api@^4.3.0: + version "4.3.0" + resolved "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" + integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== + +node-addon-api@^6.1.0: + version "6.1.0" + resolved "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" + integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== + +node-addon-api@^7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-7.0.0.tgz#8136add2f510997b3b94814f4af1cce0b0e3962e" + integrity sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA== + +node-gyp-build-optional-packages@5.0.3: + version "5.0.3" + resolved "https://registry.npmmirror.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz#92a89d400352c44ad3975010368072b41ad66c17" + integrity sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA== + +node-gyp-build-optional-packages@5.0.6: + version "5.0.6" + resolved "https://registry.npmmirror.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.6.tgz#2949f5cc7dace3ac470fa2ff1a37456907120a1d" + integrity sha512-2ZJErHG4du9G3/8IWl/l9Bp5BBFy63rno5GVmjQijvTuUZKsl6g8RB4KH/x3NLcV5ZBb4GsXmAuTYr6dRml3Gw== + +node-gyp-build-optional-packages@5.0.7: + version "5.0.7" + resolved "https://registry.npmmirror.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.7.tgz#5d2632bbde0ab2f6e22f1bbac2199b07244ae0b3" + integrity sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w== + +node-object-hash@3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/node-object-hash/-/node-object-hash-3.0.0.tgz#52526f6f42cef098e5cac1d74b96a7137d5c5226" + integrity sha512-jLF6tlyletktvSAawuPmH1SReP0YfZQ+tBrDiTCK+Ai7eXPMS9odi5xW/iKC7ZhrWJJ0Z5xYcW/x+1fVMn1Qvw== + +node-releases@^2.0.13, node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@^8.0.0: + version "8.0.0" + resolved "https://registry.npmmirror.com/normalize-url/-/normalize-url-8.0.0.tgz#593dbd284f743e8dcf6a5ddf8fadff149c82701a" + integrity sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +nullthrows@1.1.1, nullthrows@^1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" + integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== + +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +ora@^5.4.1: + version "5.4.1" + resolved "https://registry.npmmirror.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" + integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== + dependencies: + bl "^4.1.0" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.5.0" + is-interactive "^1.0.0" + is-unicode-supported "^0.1.0" + log-symbols "^4.1.0" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + +ordered-binary@^1.2.4, ordered-binary@^1.4.0: + version "1.5.1" + resolved "https://registry.npmmirror.com/ordered-binary/-/ordered-binary-1.5.1.tgz#94ccbf14181711081ee23931db0dc3f58aaa0df6" + integrity sha512-5VyHfHY3cd0iza71JepYG50My+YUbrFtGoUz2ooEydPyPM7Aai/JW098juLr+RG6+rDJuzNNTsEQu2DZa1A41A== + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== + +p-cancelable@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" + integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== + +package-json@8.1.1: + version "8.1.1" + resolved "https://registry.npmmirror.com/package-json/-/package-json-8.1.1.tgz#3e9948e43df40d1e8e78a85485f1070bf8f03dc8" + integrity sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA== + dependencies: + got "^12.1.0" + registry-auth-token "^5.0.1" + registry-url "^6.0.0" + semver "^7.3.7" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.0.0, parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse-node-version@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.npmmirror.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +periscopic@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/periscopic/-/periscopic-3.1.0.tgz#7e9037bf51c5855bd33b48928828db4afa79d97a" + integrity sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^3.0.0" + is-reference "^3.0.0" + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.npmmirror.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pirates@^4.0.1: + version "4.0.6" + resolved "https://registry.npmmirror.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +plasmo@0.84.0: + version "0.84.0" + resolved "https://registry.npmmirror.com/plasmo/-/plasmo-0.84.0.tgz#e82f70edbd7238ccf362ee4cfab77126f3241abe" + integrity sha512-SK6A/uX5mo4EsYiF7JySTOCp2aMo3ejfpbNey89M0zat9p0yDTKEClvMs9MWKXld5Ae0CXPaMYcZPAMvCMngPQ== + dependencies: + "@expo/spawn-async" "1.7.2" + "@parcel/core" "2.9.3" + "@parcel/fs" "2.9.3" + "@parcel/package-manager" "2.9.3" + "@parcel/watcher" "2.2.0" + "@plasmohq/init" "0.7.0" + "@plasmohq/parcel-config" "0.40.0" + "@plasmohq/parcel-core" "0.1.8" + buffer "6.0.3" + chalk "5.3.0" + change-case "5.1.2" + dotenv "16.3.1" + dotenv-expand "10.0.0" + events "3.3.0" + fast-glob "3.3.2" + fflate "0.8.1" + get-port "7.0.0" + got "13.0.0" + ignore "5.2.4" + inquirer "9.2.12" + is-path-inside "4.0.0" + json5 "2.2.3" + mnemonic-id "3.2.7" + node-object-hash "3.0.0" + package-json "8.1.1" + process "0.11.10" + semver "7.5.4" + sharp "0.32.6" + tempy "3.1.0" + typescript "5.2.2" + +postcss-load-config@^4.0.1: + version "4.0.2" + resolved "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3" + integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ== + dependencies: + lilconfig "^3.0.0" + yaml "^2.3.4" + +postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.1.10, postcss@^8.4.18: + version "8.4.33" + resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.33.tgz#1378e859c9f69bf6f638b990a0212f43e2aaa742" + integrity sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +posthtml-parser@^0.10.1: + version "0.10.2" + resolved "https://registry.npmmirror.com/posthtml-parser/-/posthtml-parser-0.10.2.tgz#df364d7b179f2a6bf0466b56be7b98fd4e97c573" + integrity sha512-PId6zZ/2lyJi9LiKfe+i2xv57oEjJgWbsHGGANwos5AvdQp98i6AtamAl8gzSVFGfQ43Glb5D614cvZf012VKg== + dependencies: + htmlparser2 "^7.1.1" + +posthtml-parser@^0.11.0: + version "0.11.0" + resolved "https://registry.npmmirror.com/posthtml-parser/-/posthtml-parser-0.11.0.tgz#25d1c7bf811ea83559bc4c21c189a29747a24b7a" + integrity sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw== + dependencies: + htmlparser2 "^7.1.1" + +posthtml-render@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/posthtml-render/-/posthtml-render-3.0.0.tgz#97be44931496f495b4f07b99e903cc70ad6a3205" + integrity sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA== + dependencies: + is-json "^2.0.1" + +posthtml@^0.16.4, posthtml@^0.16.5: + version "0.16.6" + resolved "https://registry.npmmirror.com/posthtml/-/posthtml-0.16.6.tgz#e2fc407f67a64d2fa3567afe770409ffdadafe59" + integrity sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ== + dependencies: + posthtml-parser "^0.11.0" + posthtml-render "^3.0.0" + +prebuild-install@^7.1.1: + version "7.1.1" + resolved "https://registry.npmmirror.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" + integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + +prettier@3.0.3: + version "3.0.3" + resolved "https://registry.npmmirror.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643" + integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== + +process@0.11.10: + version "0.11.10" + resolved "https://registry.npmmirror.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.npmmirror.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +queue-tick@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" + integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== + +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +rc@1.2.8, rc@^1.2.7: + version "1.2.8" + resolved "https://registry.npmmirror.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-dom@18.2.0: + version "18.2.0" + resolved "https://registry.npmmirror.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.0" + +react-error-overlay@6.0.9: + version "6.0.9" + resolved "https://registry.npmmirror.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" + integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== + +react-refresh@0.14.0: + version "0.14.0" + resolved "https://registry.npmmirror.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" + integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== + +react-refresh@^0.9.0: + version "0.9.0" + resolved "https://registry.npmmirror.com/react-refresh/-/react-refresh-0.9.0.tgz#71863337adc3e5c2f8a6bfddd12ae3bfe32aafbf" + integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ== + +react@18.2.0: + version "18.2.0" + resolved "https://registry.npmmirror.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + +readable-stream@^3.1.1, readable-stream@^3.4.0: + version "3.6.2" + resolved "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +regenerator-runtime@^0.13.7: + version "0.13.11" + resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + +registry-auth-token@^5.0.1: + version "5.0.2" + resolved "https://registry.npmmirror.com/registry-auth-token/-/registry-auth-token-5.0.2.tgz#8b026cc507c8552ebbe06724136267e63302f756" + integrity sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ== + dependencies: + "@pnpm/npm-conf" "^2.1.0" + +registry-url@^6.0.0: + version "6.0.1" + resolved "https://registry.npmmirror.com/registry-url/-/registry-url-6.0.1.tgz#056d9343680f2f64400032b1e199faa692286c58" + integrity sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q== + dependencies: + rc "1.2.8" + +resolve-alpn@^1.2.0: + version "1.2.1" + resolved "https://registry.npmmirror.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.22.1: + version "1.22.8" + resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +responselike@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/responselike/-/responselike-3.0.0.tgz#20decb6c298aff0dbee1c355ca95461d42823626" + integrity sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg== + dependencies: + lowercase-keys "^3.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rollup@^2.79.1: + version "2.79.1" + resolved "https://registry.npmmirror.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" + integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== + optionalDependencies: + fsevents "~2.3.2" + +rollup@^3.2.5: + version "3.29.4" + resolved "https://registry.npmmirror.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981" + integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== + optionalDependencies: + fsevents "~2.3.2" + +run-async@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/run-async/-/run-async-3.0.0.tgz#42a432f6d76c689522058984384df28be379daad" + integrity sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q== + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rxjs@^7.8.1: + version "7.8.1" + resolved "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + +safe-buffer@^5.0.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sass@^1.38.0: + version "1.69.7" + resolved "https://registry.npmmirror.com/sass/-/sass-1.69.7.tgz#6e7e1c8f51e8162faec3e9619babc7da780af3b7" + integrity sha512-rzj2soDeZ8wtE2egyLXgOOHQvaC2iosZrkF6v3EUG+tBwEvhqUCzm0VP3k9gHF9LXbSrRhT5SksoI56Iw8NPnQ== + dependencies: + chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" + +sax@^1.2.4: + version "1.3.0" + resolved "https://registry.npmmirror.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0" + integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA== + +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.npmmirror.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + dependencies: + loose-envify "^1.1.0" + +semver@7.5.4, semver@^7.3.5, semver@^7.3.7, semver@^7.5.2, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +semver@^5.6.0, semver@^5.7.1: + version "5.7.2" + resolved "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +sharp@0.32.6: + version "0.32.6" + resolved "https://registry.npmmirror.com/sharp/-/sharp-0.32.6.tgz#6ad30c0b7cd910df65d5f355f774aa4fce45732a" + integrity sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w== + dependencies: + color "^4.2.3" + detect-libc "^2.0.2" + node-addon-api "^6.1.0" + prebuild-install "^7.1.1" + semver "^7.5.4" + simple-get "^4.0.1" + tar-fs "^3.0.4" + tunnel-agent "^0.6.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0, simple-get@^4.0.1: + version "4.0.1" + resolved "https://registry.npmmirror.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.npmmirror.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== + dependencies: + is-arrayish "^0.3.1" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +source-map@0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.npmmirror.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" + +source-map@^0.6.1, source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +srcset@4: + version "4.0.0" + resolved "https://registry.npmmirror.com/srcset/-/srcset-4.0.0.tgz#336816b665b14cd013ba545b6fe62357f86e65f4" + integrity sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw== + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.npmmirror.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +streamx@^2.15.0: + version "2.15.6" + resolved "https://registry.npmmirror.com/streamx/-/streamx-2.15.6.tgz#28bf36997ebc7bf6c08f9eba958735231b833887" + integrity sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw== + dependencies: + fast-fifo "^1.1.0" + queue-tick "^1.0.1" + +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + +sucrase@^3.20.3: + version "3.35.0" + resolved "https://registry.npmmirror.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263" + integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "^10.3.10" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +svelte@4.0.1: + version "4.0.1" + resolved "https://registry.npmmirror.com/svelte/-/svelte-4.0.1.tgz#5c01f5f7cb05ac21ffe3a741e0c942972dc47c05" + integrity sha512-7n2u7A5cu8xCY6MBiXh/Mg6Lh3+Mw2qXlTDBYhzvCvmSM4L4gc4MVo540UtGcjqBiA48E1VDW+EUpBr7iuBlPg== + dependencies: + "@ampproject/remapping" "^2.2.1" + "@jridgewell/sourcemap-codec" "^1.4.15" + "@jridgewell/trace-mapping" "^0.3.18" + acorn "^8.9.0" + aria-query "^5.3.0" + axobject-query "^3.2.1" + code-red "^1.0.3" + css-tree "^2.3.1" + estree-walker "^3.0.3" + is-reference "^3.0.1" + locate-character "^3.0.0" + magic-string "^0.30.0" + periscopic "^3.1.0" + +svg-parser@^2.0.4: + version "2.0.4" + resolved "https://registry.npmmirror.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + +svgo@^2.4.0, svgo@^2.8.0: + version "2.8.0" + resolved "https://registry.npmmirror.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" + integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^4.1.3" + css-tree "^1.1.3" + csso "^4.2.0" + picocolors "^1.0.0" + stable "^0.1.8" + +tar-fs@^2.0.0: + version "2.1.1" + resolved "https://registry.npmmirror.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-fs@^3.0.4: + version "3.0.4" + resolved "https://registry.npmmirror.com/tar-fs/-/tar-fs-3.0.4.tgz#a21dc60a2d5d9f55e0089ccd78124f1d3771dbbf" + integrity sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w== + dependencies: + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^3.1.5" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.npmmirror.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tar-stream@^3.1.5: + version "3.1.6" + resolved "https://registry.npmmirror.com/tar-stream/-/tar-stream-3.1.6.tgz#6520607b55a06f4a2e2e04db360ba7d338cc5bab" + integrity sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg== + dependencies: + b4a "^1.6.4" + fast-fifo "^1.2.0" + streamx "^2.15.0" + +temp-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/temp-dir/-/temp-dir-3.0.0.tgz#7f147b42ee41234cc6ba3138cd8e8aa2302acffa" + integrity sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw== + +tempy@3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/tempy/-/tempy-3.1.0.tgz#00958b6df85db8589cb595465e691852aac038e9" + integrity sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g== + dependencies: + is-stream "^3.0.0" + temp-dir "^3.0.0" + type-fest "^2.12.2" + unique-string "^3.0.0" + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.npmmirror.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.npmmirror.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A== + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.npmmirror.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== + dependencies: + punycode "^2.1.0" + +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.npmmirror.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + +ts-algebra@^1.2.0: + version "1.2.2" + resolved "https://registry.npmmirror.com/ts-algebra/-/ts-algebra-1.2.2.tgz#b75d301c28cd4126cd344760a47b43e48e2872e0" + integrity sha512-kloPhf1hq3JbCPOTYoOWDKxebWjNb2o/LKnNfkWhxVVisFFmMJPPdJeGoGmM+iRLyoXAR61e08Pb+vUXINg8aA== + +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + +tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0: + version "2.6.2" + resolved "https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +tsup@7.2.0: + version "7.2.0" + resolved "https://registry.npmmirror.com/tsup/-/tsup-7.2.0.tgz#bb24c0d5e436477900c712e42adc67200607303c" + integrity sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ== + dependencies: + bundle-require "^4.0.0" + cac "^6.7.12" + chokidar "^3.5.1" + debug "^4.3.1" + esbuild "^0.18.2" + execa "^5.0.0" + globby "^11.0.3" + joycon "^3.0.1" + postcss-load-config "^4.0.1" + resolve-from "^5.0.0" + rollup "^3.2.5" + source-map "0.8.0-beta.0" + sucrase "^3.20.3" + tree-kill "^1.2.2" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.npmmirror.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^1.0.1: + version "1.4.0" + resolved "https://registry.npmmirror.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" + integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== + +type-fest@^2.12.2: + version "2.19.0" + resolved "https://registry.npmmirror.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + +typescript@5.2.2: + version "5.2.2" + resolved "https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== + +typescript@^4.8.3: + version "4.9.5" + resolved "https://registry.npmmirror.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +unique-string@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/unique-string/-/unique-string-3.0.0.tgz#84a1c377aff5fd7a8bc6b55d8244b2bd90d75b9a" + integrity sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ== + dependencies: + crypto-random-string "^4.0.0" + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +update-browserslist-db@^1.0.11, update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utility-types@^3.10.0: + version "3.10.0" + resolved "https://registry.npmmirror.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b" + integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== + +vite@^3.1.3: + version "3.2.7" + resolved "https://registry.npmmirror.com/vite/-/vite-3.2.7.tgz#35a62826bd4d6b778ae5db8766d023bcd4e7bef3" + integrity sha512-29pdXjk49xAP0QBr0xXqu2s5jiQIXNvE/xwd0vUizYT2Hzqe4BksNNoWllFVXJf4eLZ+UlVQmXfB4lWrc+t18g== + dependencies: + esbuild "^0.15.9" + postcss "^8.4.18" + resolve "^1.22.1" + rollup "^2.79.1" + optionalDependencies: + fsevents "~2.3.2" + +vue@3.3.4: + version "3.3.4" + resolved "https://registry.npmmirror.com/vue/-/vue-3.3.4.tgz#8ed945d3873667df1d0fcf3b2463ada028f88bd6" + integrity sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw== + dependencies: + "@vue/compiler-dom" "3.3.4" + "@vue/compiler-sfc" "3.3.4" + "@vue/runtime-dom" "3.3.4" + "@vue/server-renderer" "3.3.4" + "@vue/shared" "3.3.4" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== + dependencies: + defaults "^1.0.3" + +weak-lru-cache@^1.2.2: + version "1.2.2" + resolved "https://registry.npmmirror.com/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz#fdbb6741f36bae9540d12f480ce8254060dccd19" + integrity sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw== + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmmirror.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +xxhash-wasm@^0.4.2: + version "0.4.2" + resolved "https://registry.npmmirror.com/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz#752398c131a4dd407b5132ba62ad372029be6f79" + integrity sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yaml@^2.3.4: + version "2.3.4" + resolved "https://registry.npmmirror.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" + integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==