school.js 1.93 MB
!function(I){function g(C){if(n[C])return n[C].exports;var e=n[C]={i:C,l:!1,exports:{}};return I[C].call(e.exports,e,e.exports,g),e.l=!0,e.exports}var n={};return g.m=I,g.c=n,g.i=function(I){return I},g.d=function(I,g,n){Object.defineProperty(I,g,{configurable:!1,enumerable:!0,get:n})},g.n=function(I){var n=I&&I.__esModule?function(){return I.default}:function(){return I};return g.d(n,"a",n),n},g.o=function(I,g){return Object.prototype.hasOwnProperty.call(I,g)},g.p="/dists/",g(g.s=55)}([function(module,exports){eval('/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push("@media " + item[2] + "{" + item[1] + "}");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join("");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === "string")\r\n\t\t\tmodules = [[null, modules, ""]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === "number")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t//  when a module is imported multiple times with different media queries.\r\n\t\t\t//  I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = "(" + item[2] + ") and (" + mediaQuery + ")";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzP2RhMDQiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGlCQUFpQjtBQUNqQztBQUNBO0FBQ0Esd0NBQXdDLGdCQUFnQjtBQUN4RCxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGlCQUFpQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksb0JBQW9CO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiIwLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuXHRNSVQgTGljZW5zZSBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxyXG5cdEF1dGhvciBUb2JpYXMgS29wcGVycyBAc29rcmFcclxuKi9cclxuLy8gY3NzIGJhc2UgY29kZSwgaW5qZWN0ZWQgYnkgdGhlIGNzcy1sb2FkZXJcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcclxuXHR2YXIgbGlzdCA9IFtdO1xyXG5cclxuXHQvLyByZXR1cm4gdGhlIGxpc3Qgb2YgbW9kdWxlcyBhcyBjc3Mgc3RyaW5nXHJcblx0bGlzdC50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xyXG5cdFx0dmFyIHJlc3VsdCA9IFtdO1xyXG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0dmFyIGl0ZW0gPSB0aGlzW2ldO1xyXG5cdFx0XHRpZihpdGVtWzJdKSB7XHJcblx0XHRcdFx0cmVzdWx0LnB1c2goXCJAbWVkaWEgXCIgKyBpdGVtWzJdICsgXCJ7XCIgKyBpdGVtWzFdICsgXCJ9XCIpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHJlc3VsdC5wdXNoKGl0ZW1bMV0pO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gcmVzdWx0LmpvaW4oXCJcIik7XHJcblx0fTtcclxuXHJcblx0Ly8gaW1wb3J0IGEgbGlzdCBvZiBtb2R1bGVzIGludG8gdGhlIGxpc3RcclxuXHRsaXN0LmkgPSBmdW5jdGlvbihtb2R1bGVzLCBtZWRpYVF1ZXJ5KSB7XHJcblx0XHRpZih0eXBlb2YgbW9kdWxlcyA9PT0gXCJzdHJpbmdcIilcclxuXHRcdFx0bW9kdWxlcyA9IFtbbnVsbCwgbW9kdWxlcywgXCJcIl1dO1xyXG5cdFx0dmFyIGFscmVhZHlJbXBvcnRlZE1vZHVsZXMgPSB7fTtcclxuXHRcdGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XHJcblx0XHRcdHZhciBpZCA9IHRoaXNbaV1bMF07XHJcblx0XHRcdGlmKHR5cGVvZiBpZCA9PT0gXCJudW1iZXJcIilcclxuXHRcdFx0XHRhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2lkXSA9IHRydWU7XHJcblx0XHR9XHJcblx0XHRmb3IoaSA9IDA7IGkgPCBtb2R1bGVzLmxlbmd0aDsgaSsrKSB7XHJcblx0XHRcdHZhciBpdGVtID0gbW9kdWxlc1tpXTtcclxuXHRcdFx0Ly8gc2tpcCBhbHJlYWR5IGltcG9ydGVkIG1vZHVsZVxyXG5cdFx0XHQvLyB0aGlzIGltcGxlbWVudGF0aW9uIGlzIG5vdCAxMDAlIHBlcmZlY3QgZm9yIHdlaXJkIG1lZGlhIHF1ZXJ5IGNvbWJpbmF0aW9uc1xyXG5cdFx0XHQvLyAgd2hlbiBhIG1vZHVsZSBpcyBpbXBvcnRlZCBtdWx0aXBsZSB0aW1lcyB3aXRoIGRpZmZlcmVudCBtZWRpYSBxdWVyaWVzLlxyXG5cdFx0XHQvLyAgSSBob3BlIHRoaXMgd2lsbCBuZXZlciBvY2N1ciAoSGV5IHRoaXMgd2F5IHdlIGhhdmUgc21hbGxlciBidW5kbGVzKVxyXG5cdFx0XHRpZih0eXBlb2YgaXRlbVswXSAhPT0gXCJudW1iZXJcIiB8fCAhYWxyZWFkeUltcG9ydGVkTW9kdWxlc1tpdGVtWzBdXSkge1xyXG5cdFx0XHRcdGlmKG1lZGlhUXVlcnkgJiYgIWl0ZW1bMl0pIHtcclxuXHRcdFx0XHRcdGl0ZW1bMl0gPSBtZWRpYVF1ZXJ5O1xyXG5cdFx0XHRcdH0gZWxzZSBpZihtZWRpYVF1ZXJ5KSB7XHJcblx0XHRcdFx0XHRpdGVtWzJdID0gXCIoXCIgKyBpdGVtWzJdICsgXCIpIGFuZCAoXCIgKyBtZWRpYVF1ZXJ5ICsgXCIpXCI7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGxpc3QucHVzaChpdGVtKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH07XHJcblx0cmV0dXJuIGxpc3Q7XHJcbn07XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1xuLy8gbW9kdWxlIGlkID0gMFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports){eval('/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\nvar stylesInDom = {},\n\tmemoize = function(fn) {\n\t\tvar memo;\n\t\treturn function () {\n\t\t\tif (typeof memo === "undefined") memo = fn.apply(this, arguments);\n\t\t\treturn memo;\n\t\t};\n\t},\n\tisOldIE = memoize(function() {\n\t\treturn /msie [6-9]\\b/.test(window.navigator.userAgent.toLowerCase());\n\t}),\n\tgetHeadElement = memoize(function () {\n\t\treturn document.head || document.getElementsByTagName("head")[0];\n\t}),\n\tsingletonElement = null,\n\tsingletonCounter = 0,\n\tstyleElementsInsertedAtTop = [];\n\nmodule.exports = function(list, options) {\n\tif(typeof DEBUG !== "undefined" && DEBUG) {\n\t\tif(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");\n\t}\n\n\toptions = options || {};\n\t// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>\n\t// tags it will allow on a page\n\tif (typeof options.singleton === "undefined") options.singleton = isOldIE();\n\n\t// By default, add <style> tags to the bottom of <head>.\n\tif (typeof options.insertAt === "undefined") options.insertAt = "bottom";\n\n\tvar styles = listToStyles(list);\n\taddStylesToDom(styles, options);\n\n\treturn function update(newList) {\n\t\tvar mayRemove = [];\n\t\tfor(var i = 0; i < styles.length; i++) {\n\t\t\tvar item = styles[i];\n\t\t\tvar domStyle = stylesInDom[item.id];\n\t\t\tdomStyle.refs--;\n\t\t\tmayRemove.push(domStyle);\n\t\t}\n\t\tif(newList) {\n\t\t\tvar newStyles = listToStyles(newList);\n\t\t\taddStylesToDom(newStyles, options);\n\t\t}\n\t\tfor(var i = 0; i < mayRemove.length; i++) {\n\t\t\tvar domStyle = mayRemove[i];\n\t\t\tif(domStyle.refs === 0) {\n\t\t\t\tfor(var j = 0; j < domStyle.parts.length; j++)\n\t\t\t\t\tdomStyle.parts[j]();\n\t\t\t\tdelete stylesInDom[domStyle.id];\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction addStylesToDom(styles, options) {\n\tfor(var i = 0; i < styles.length; i++) {\n\t\tvar item = styles[i];\n\t\tvar domStyle = stylesInDom[item.id];\n\t\tif(domStyle) {\n\t\t\tdomStyle.refs++;\n\t\t\tfor(var j = 0; j < domStyle.parts.length; j++) {\n\t\t\t\tdomStyle.parts[j](item.parts[j]);\n\t\t\t}\n\t\t\tfor(; j < item.parts.length; j++) {\n\t\t\t\tdomStyle.parts.push(addStyle(item.parts[j], options));\n\t\t\t}\n\t\t} else {\n\t\t\tvar parts = [];\n\t\t\tfor(var j = 0; j < item.parts.length; j++) {\n\t\t\t\tparts.push(addStyle(item.parts[j], options));\n\t\t\t}\n\t\t\tstylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};\n\t\t}\n\t}\n}\n\nfunction listToStyles(list) {\n\tvar styles = [];\n\tvar newStyles = {};\n\tfor(var i = 0; i < list.length; i++) {\n\t\tvar item = list[i];\n\t\tvar id = item[0];\n\t\tvar css = item[1];\n\t\tvar media = item[2];\n\t\tvar sourceMap = item[3];\n\t\tvar part = {css: css, media: media, sourceMap: sourceMap};\n\t\tif(!newStyles[id])\n\t\t\tstyles.push(newStyles[id] = {id: id, parts: [part]});\n\t\telse\n\t\t\tnewStyles[id].parts.push(part);\n\t}\n\treturn styles;\n}\n\nfunction insertStyleElement(options, styleElement) {\n\tvar head = getHeadElement();\n\tvar lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];\n\tif (options.insertAt === "top") {\n\t\tif(!lastStyleElementInsertedAtTop) {\n\t\t\thead.insertBefore(styleElement, head.firstChild);\n\t\t} else if(lastStyleElementInsertedAtTop.nextSibling) {\n\t\t\thead.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);\n\t\t} else {\n\t\t\thead.appendChild(styleElement);\n\t\t}\n\t\tstyleElementsInsertedAtTop.push(styleElement);\n\t} else if (options.insertAt === "bottom") {\n\t\thead.appendChild(styleElement);\n\t} else {\n\t\tthrow new Error("Invalid value for parameter \'insertAt\'. Must be \'top\' or \'bottom\'.");\n\t}\n}\n\nfunction removeStyleElement(styleElement) {\n\tstyleElement.parentNode.removeChild(styleElement);\n\tvar idx = styleElementsInsertedAtTop.indexOf(styleElement);\n\tif(idx >= 0) {\n\t\tstyleElementsInsertedAtTop.splice(idx, 1);\n\t}\n}\n\nfunction createStyleElement(options) {\n\tvar styleElement = document.createElement("style");\n\tstyleElement.type = "text/css";\n\tinsertStyleElement(options, styleElement);\n\treturn styleElement;\n}\n\nfunction addStyle(obj, options) {\n\tvar styleElement, update, remove;\n\n\tif (options.singleton) {\n\t\tvar styleIndex = singletonCounter++;\n\t\tstyleElement = singletonElement || (singletonElement = createStyleElement(options));\n\t\tupdate = applyToSingletonTag.bind(null, styleElement, styleIndex, false);\n\t\tremove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);\n\t} else {\n\t\tstyleElement = createStyleElement(options);\n\t\tupdate = applyToTag.bind(null, styleElement);\n\t\tremove = function() {\n\t\t\tremoveStyleElement(styleElement);\n\t\t};\n\t}\n\n\tupdate(obj);\n\n\treturn function updateStyle(newObj) {\n\t\tif(newObj) {\n\t\t\tif(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)\n\t\t\t\treturn;\n\t\t\tupdate(obj = newObj);\n\t\t} else {\n\t\t\tremove();\n\t\t}\n\t};\n}\n\nvar replaceText = (function () {\n\tvar textStore = [];\n\n\treturn function (index, replacement) {\n\t\ttextStore[index] = replacement;\n\t\treturn textStore.filter(Boolean).join(\'\\n\');\n\t};\n})();\n\nfunction applyToSingletonTag(styleElement, index, remove, obj) {\n\tvar css = remove ? "" : obj.css;\n\n\tif (styleElement.styleSheet) {\n\t\tstyleElement.styleSheet.cssText = replaceText(index, css);\n\t} else {\n\t\tvar cssNode = document.createTextNode(css);\n\t\tvar childNodes = styleElement.childNodes;\n\t\tif (childNodes[index]) styleElement.removeChild(childNodes[index]);\n\t\tif (childNodes.length) {\n\t\t\tstyleElement.insertBefore(cssNode, childNodes[index]);\n\t\t} else {\n\t\t\tstyleElement.appendChild(cssNode);\n\t\t}\n\t}\n}\n\nfunction applyToTag(styleElement, obj) {\n\tvar css = obj.css;\n\tvar media = obj.media;\n\tvar sourceMap = obj.sourceMap;\n\n\tif (media) {\n\t\tstyleElement.setAttribute("media", media);\n\t}\n\n\tif (sourceMap) {\n\t\t// https://developer.chrome.com/devtools/docs/javascript-debugging\n\t\t// this makes source maps inside style tags work properly in Chrome\n\t\tcss += \'\\n/*# sourceURL=\' + sourceMap.sources[0] + \' */\';\n\t\t// http://stackoverflow.com/a/26603875\n\t\tcss += "\\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";\n\t}\n\n\tif (styleElement.styleSheet) {\n\t\tstyleElement.styleSheet.cssText = css;\n\t} else {\n\t\twhile(styleElement.firstChild) {\n\t\t\tstyleElement.removeChild(styleElement.firstChild);\n\t\t}\n\t\tstyleElement.appendChild(document.createTextNode(css));\n\t}\n}\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L3Z1ZS1zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzP2MyZmMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxnQkFBZ0IsbUJBQW1CO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixzQkFBc0I7QUFDdEM7QUFDQTtBQUNBLGtCQUFrQiwyQkFBMkI7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZUFBZSxtQkFBbUI7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsMkJBQTJCO0FBQzVDO0FBQ0E7QUFDQSxRQUFRLHVCQUF1QjtBQUMvQjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsaUJBQWlCLHVCQUF1QjtBQUN4QztBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFpQjtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0EsZ0NBQWdDLHNCQUFzQjtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQ7QUFDdkQ7O0FBRUE7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG5cdE1JVCBMaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXG5cdEF1dGhvciBUb2JpYXMgS29wcGVycyBAc29rcmFcbiovXG52YXIgc3R5bGVzSW5Eb20gPSB7fSxcblx0bWVtb2l6ZSA9IGZ1bmN0aW9uKGZuKSB7XG5cdFx0dmFyIG1lbW87XG5cdFx0cmV0dXJuIGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmICh0eXBlb2YgbWVtbyA9PT0gXCJ1bmRlZmluZWRcIikgbWVtbyA9IGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdFx0XHRyZXR1cm4gbWVtbztcblx0XHR9O1xuXHR9LFxuXHRpc09sZElFID0gbWVtb2l6ZShmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gL21zaWUgWzYtOV1cXGIvLnRlc3Qod2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKSk7XG5cdH0pLFxuXHRnZXRIZWFkRWxlbWVudCA9IG1lbW9pemUoZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiBkb2N1bWVudC5oZWFkIHx8IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiaGVhZFwiKVswXTtcblx0fSksXG5cdHNpbmdsZXRvbkVsZW1lbnQgPSBudWxsLFxuXHRzaW5nbGV0b25Db3VudGVyID0gMCxcblx0c3R5bGVFbGVtZW50c0luc2VydGVkQXRUb3AgPSBbXTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihsaXN0LCBvcHRpb25zKSB7XG5cdGlmKHR5cGVvZiBERUJVRyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBERUJVRykge1xuXHRcdGlmKHR5cGVvZiBkb2N1bWVudCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHN0eWxlLWxvYWRlciBjYW5ub3QgYmUgdXNlZCBpbiBhIG5vbi1icm93c2VyIGVudmlyb25tZW50XCIpO1xuXHR9XG5cblx0b3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cdC8vIEZvcmNlIHNpbmdsZS10YWcgc29sdXRpb24gb24gSUU2LTksIHdoaWNoIGhhcyBhIGhhcmQgbGltaXQgb24gdGhlICMgb2YgPHN0eWxlPlxuXHQvLyB0YWdzIGl0IHdpbGwgYWxsb3cgb24gYSBwYWdlXG5cdGlmICh0eXBlb2Ygb3B0aW9ucy5zaW5nbGV0b24gPT09IFwidW5kZWZpbmVkXCIpIG9wdGlvbnMuc2luZ2xldG9uID0gaXNPbGRJRSgpO1xuXG5cdC8vIEJ5IGRlZmF1bHQsIGFkZCA8c3R5bGU+IHRhZ3MgdG8gdGhlIGJvdHRvbSBvZiA8aGVhZD4uXG5cdGlmICh0eXBlb2Ygb3B0aW9ucy5pbnNlcnRBdCA9PT0gXCJ1bmRlZmluZWRcIikgb3B0aW9ucy5pbnNlcnRBdCA9IFwiYm90dG9tXCI7XG5cblx0dmFyIHN0eWxlcyA9IGxpc3RUb1N0eWxlcyhsaXN0KTtcblx0YWRkU3R5bGVzVG9Eb20oc3R5bGVzLCBvcHRpb25zKTtcblxuXHRyZXR1cm4gZnVuY3Rpb24gdXBkYXRlKG5ld0xpc3QpIHtcblx0XHR2YXIgbWF5UmVtb3ZlID0gW107XG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IHN0eWxlcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dmFyIGl0ZW0gPSBzdHlsZXNbaV07XG5cdFx0XHR2YXIgZG9tU3R5bGUgPSBzdHlsZXNJbkRvbVtpdGVtLmlkXTtcblx0XHRcdGRvbVN0eWxlLnJlZnMtLTtcblx0XHRcdG1heVJlbW92ZS5wdXNoKGRvbVN0eWxlKTtcblx0XHR9XG5cdFx0aWYobmV3TGlzdCkge1xuXHRcdFx0dmFyIG5ld1N0eWxlcyA9IGxpc3RUb1N0eWxlcyhuZXdMaXN0KTtcblx0XHRcdGFkZFN0eWxlc1RvRG9tKG5ld1N0eWxlcywgb3B0aW9ucyk7XG5cdFx0fVxuXHRcdGZvcih2YXIgaSA9IDA7IGkgPCBtYXlSZW1vdmUubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciBkb21TdHlsZSA9IG1heVJlbW92ZVtpXTtcblx0XHRcdGlmKGRvbVN0eWxlLnJlZnMgPT09IDApIHtcblx0XHRcdFx0Zm9yKHZhciBqID0gMDsgaiA8IGRvbVN0eWxlLnBhcnRzLmxlbmd0aDsgaisrKVxuXHRcdFx0XHRcdGRvbVN0eWxlLnBhcnRzW2pdKCk7XG5cdFx0XHRcdGRlbGV0ZSBzdHlsZXNJbkRvbVtkb21TdHlsZS5pZF07XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xufVxuXG5mdW5jdGlvbiBhZGRTdHlsZXNUb0RvbShzdHlsZXMsIG9wdGlvbnMpIHtcblx0Zm9yKHZhciBpID0gMDsgaSA8IHN0eWxlcy5sZW5ndGg7IGkrKykge1xuXHRcdHZhciBpdGVtID0gc3R5bGVzW2ldO1xuXHRcdHZhciBkb21TdHlsZSA9IHN0eWxlc0luRG9tW2l0ZW0uaWRdO1xuXHRcdGlmKGRvbVN0eWxlKSB7XG5cdFx0XHRkb21TdHlsZS5yZWZzKys7XG5cdFx0XHRmb3IodmFyIGogPSAwOyBqIDwgZG9tU3R5bGUucGFydHMubGVuZ3RoOyBqKyspIHtcblx0XHRcdFx0ZG9tU3R5bGUucGFydHNbal0oaXRlbS5wYXJ0c1tqXSk7XG5cdFx0XHR9XG5cdFx0XHRmb3IoOyBqIDwgaXRlbS5wYXJ0cy5sZW5ndGg7IGorKykge1xuXHRcdFx0XHRkb21TdHlsZS5wYXJ0cy5wdXNoKGFkZFN0eWxlKGl0ZW0ucGFydHNbal0sIG9wdGlvbnMpKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0dmFyIHBhcnRzID0gW107XG5cdFx0XHRmb3IodmFyIGogPSAwOyBqIDwgaXRlbS5wYXJ0cy5sZW5ndGg7IGorKykge1xuXHRcdFx0XHRwYXJ0cy5wdXNoKGFkZFN0eWxlKGl0ZW0ucGFydHNbal0sIG9wdGlvbnMpKTtcblx0XHRcdH1cblx0XHRcdHN0eWxlc0luRG9tW2l0ZW0uaWRdID0ge2lkOiBpdGVtLmlkLCByZWZzOiAxLCBwYXJ0czogcGFydHN9O1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBsaXN0VG9TdHlsZXMobGlzdCkge1xuXHR2YXIgc3R5bGVzID0gW107XG5cdHZhciBuZXdTdHlsZXMgPSB7fTtcblx0Zm9yKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcblx0XHR2YXIgaXRlbSA9IGxpc3RbaV07XG5cdFx0dmFyIGlkID0gaXRlbVswXTtcblx0XHR2YXIgY3NzID0gaXRlbVsxXTtcblx0XHR2YXIgbWVkaWEgPSBpdGVtWzJdO1xuXHRcdHZhciBzb3VyY2VNYXAgPSBpdGVtWzNdO1xuXHRcdHZhciBwYXJ0ID0ge2NzczogY3NzLCBtZWRpYTogbWVkaWEsIHNvdXJjZU1hcDogc291cmNlTWFwfTtcblx0XHRpZighbmV3U3R5bGVzW2lkXSlcblx0XHRcdHN0eWxlcy5wdXNoKG5ld1N0eWxlc1tpZF0gPSB7aWQ6IGlkLCBwYXJ0czogW3BhcnRdfSk7XG5cdFx0ZWxzZVxuXHRcdFx0bmV3U3R5bGVzW2lkXS5wYXJ0cy5wdXNoKHBhcnQpO1xuXHR9XG5cdHJldHVybiBzdHlsZXM7XG59XG5cbmZ1bmN0aW9uIGluc2VydFN0eWxlRWxlbWVudChvcHRpb25zLCBzdHlsZUVsZW1lbnQpIHtcblx0dmFyIGhlYWQgPSBnZXRIZWFkRWxlbWVudCgpO1xuXHR2YXIgbGFzdFN0eWxlRWxlbWVudEluc2VydGVkQXRUb3AgPSBzdHlsZUVsZW1lbnRzSW5zZXJ0ZWRBdFRvcFtzdHlsZUVsZW1lbnRzSW5zZXJ0ZWRBdFRvcC5sZW5ndGggLSAxXTtcblx0aWYgKG9wdGlvbnMuaW5zZXJ0QXQgPT09IFwidG9wXCIpIHtcblx0XHRpZighbGFzdFN0eWxlRWxlbWVudEluc2VydGVkQXRUb3ApIHtcblx0XHRcdGhlYWQuaW5zZXJ0QmVmb3JlKHN0eWxlRWxlbWVudCwgaGVhZC5maXJzdENoaWxkKTtcblx0XHR9IGVsc2UgaWYobGFzdFN0eWxlRWxlbWVudEluc2VydGVkQXRUb3AubmV4dFNpYmxpbmcpIHtcblx0XHRcdGhlYWQuaW5zZXJ0QmVmb3JlKHN0eWxlRWxlbWVudCwgbGFzdFN0eWxlRWxlbWVudEluc2VydGVkQXRUb3AubmV4dFNpYmxpbmcpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRoZWFkLmFwcGVuZENoaWxkKHN0eWxlRWxlbWVudCk7XG5cdFx0fVxuXHRcdHN0eWxlRWxlbWVudHNJbnNlcnRlZEF0VG9wLnB1c2goc3R5bGVFbGVtZW50KTtcblx0fSBlbHNlIGlmIChvcHRpb25zLmluc2VydEF0ID09PSBcImJvdHRvbVwiKSB7XG5cdFx0aGVhZC5hcHBlbmRDaGlsZChzdHlsZUVsZW1lbnQpO1xuXHR9IGVsc2Uge1xuXHRcdHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdmFsdWUgZm9yIHBhcmFtZXRlciAnaW5zZXJ0QXQnLiBNdXN0IGJlICd0b3AnIG9yICdib3R0b20nLlwiKTtcblx0fVxufVxuXG5mdW5jdGlvbiByZW1vdmVTdHlsZUVsZW1lbnQoc3R5bGVFbGVtZW50KSB7XG5cdHN0eWxlRWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHN0eWxlRWxlbWVudCk7XG5cdHZhciBpZHggPSBzdHlsZUVsZW1lbnRzSW5zZXJ0ZWRBdFRvcC5pbmRleE9mKHN0eWxlRWxlbWVudCk7XG5cdGlmKGlkeCA+PSAwKSB7XG5cdFx0c3R5bGVFbGVtZW50c0luc2VydGVkQXRUb3Auc3BsaWNlKGlkeCwgMSk7XG5cdH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlU3R5bGVFbGVtZW50KG9wdGlvbnMpIHtcblx0dmFyIHN0eWxlRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtcblx0c3R5bGVFbGVtZW50LnR5cGUgPSBcInRleHQvY3NzXCI7XG5cdGluc2VydFN0eWxlRWxlbWVudChvcHRpb25zLCBzdHlsZUVsZW1lbnQpO1xuXHRyZXR1cm4gc3R5bGVFbGVtZW50O1xufVxuXG5mdW5jdGlvbiBhZGRTdHlsZShvYmosIG9wdGlvbnMpIHtcblx0dmFyIHN0eWxlRWxlbWVudCwgdXBkYXRlLCByZW1vdmU7XG5cblx0aWYgKG9wdGlvbnMuc2luZ2xldG9uKSB7XG5cdFx0dmFyIHN0eWxlSW5kZXggPSBzaW5nbGV0b25Db3VudGVyKys7XG5cdFx0c3R5bGVFbGVtZW50ID0gc2luZ2xldG9uRWxlbWVudCB8fCAoc2luZ2xldG9uRWxlbWVudCA9IGNyZWF0ZVN0eWxlRWxlbWVudChvcHRpb25zKSk7XG5cdFx0dXBkYXRlID0gYXBwbHlUb1NpbmdsZXRvblRhZy5iaW5kKG51bGwsIHN0eWxlRWxlbWVudCwgc3R5bGVJbmRleCwgZmFsc2UpO1xuXHRcdHJlbW92ZSA9IGFwcGx5VG9TaW5nbGV0b25UYWcuYmluZChudWxsLCBzdHlsZUVsZW1lbnQsIHN0eWxlSW5kZXgsIHRydWUpO1xuXHR9IGVsc2Uge1xuXHRcdHN0eWxlRWxlbWVudCA9IGNyZWF0ZVN0eWxlRWxlbWVudChvcHRpb25zKTtcblx0XHR1cGRhdGUgPSBhcHBseVRvVGFnLmJpbmQobnVsbCwgc3R5bGVFbGVtZW50KTtcblx0XHRyZW1vdmUgPSBmdW5jdGlvbigpIHtcblx0XHRcdHJlbW92ZVN0eWxlRWxlbWVudChzdHlsZUVsZW1lbnQpO1xuXHRcdH07XG5cdH1cblxuXHR1cGRhdGUob2JqKTtcblxuXHRyZXR1cm4gZnVuY3Rpb24gdXBkYXRlU3R5bGUobmV3T2JqKSB7XG5cdFx0aWYobmV3T2JqKSB7XG5cdFx0XHRpZihuZXdPYmouY3NzID09PSBvYmouY3NzICYmIG5ld09iai5tZWRpYSA9PT0gb2JqLm1lZGlhICYmIG5ld09iai5zb3VyY2VNYXAgPT09IG9iai5zb3VyY2VNYXApXG5cdFx0XHRcdHJldHVybjtcblx0XHRcdHVwZGF0ZShvYmogPSBuZXdPYmopO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZW1vdmUoKTtcblx0XHR9XG5cdH07XG59XG5cbnZhciByZXBsYWNlVGV4dCA9IChmdW5jdGlvbiAoKSB7XG5cdHZhciB0ZXh0U3RvcmUgPSBbXTtcblxuXHRyZXR1cm4gZnVuY3Rpb24gKGluZGV4LCByZXBsYWNlbWVudCkge1xuXHRcdHRleHRTdG9yZVtpbmRleF0gPSByZXBsYWNlbWVudDtcblx0XHRyZXR1cm4gdGV4dFN0b3JlLmZpbHRlcihCb29sZWFuKS5qb2luKCdcXG4nKTtcblx0fTtcbn0pKCk7XG5cbmZ1bmN0aW9uIGFwcGx5VG9TaW5nbGV0b25UYWcoc3R5bGVFbGVtZW50LCBpbmRleCwgcmVtb3ZlLCBvYmopIHtcblx0dmFyIGNzcyA9IHJlbW92ZSA/IFwiXCIgOiBvYmouY3NzO1xuXG5cdGlmIChzdHlsZUVsZW1lbnQuc3R5bGVTaGVldCkge1xuXHRcdHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0LmNzc1RleHQgPSByZXBsYWNlVGV4dChpbmRleCwgY3NzKTtcblx0fSBlbHNlIHtcblx0XHR2YXIgY3NzTm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcyk7XG5cdFx0dmFyIGNoaWxkTm9kZXMgPSBzdHlsZUVsZW1lbnQuY2hpbGROb2Rlcztcblx0XHRpZiAoY2hpbGROb2Rlc1tpbmRleF0pIHN0eWxlRWxlbWVudC5yZW1vdmVDaGlsZChjaGlsZE5vZGVzW2luZGV4XSk7XG5cdFx0aWYgKGNoaWxkTm9kZXMubGVuZ3RoKSB7XG5cdFx0XHRzdHlsZUVsZW1lbnQuaW5zZXJ0QmVmb3JlKGNzc05vZGUsIGNoaWxkTm9kZXNbaW5kZXhdKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0c3R5bGVFbGVtZW50LmFwcGVuZENoaWxkKGNzc05vZGUpO1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBhcHBseVRvVGFnKHN0eWxlRWxlbWVudCwgb2JqKSB7XG5cdHZhciBjc3MgPSBvYmouY3NzO1xuXHR2YXIgbWVkaWEgPSBvYmoubWVkaWE7XG5cdHZhciBzb3VyY2VNYXAgPSBvYmouc291cmNlTWFwO1xuXG5cdGlmIChtZWRpYSkge1xuXHRcdHN0eWxlRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJtZWRpYVwiLCBtZWRpYSk7XG5cdH1cblxuXHRpZiAoc291cmNlTWFwKSB7XG5cdFx0Ly8gaHR0cHM6Ly9kZXZlbG9wZXIuY2hyb21lLmNvbS9kZXZ0b29scy9kb2NzL2phdmFzY3JpcHQtZGVidWdnaW5nXG5cdFx0Ly8gdGhpcyBtYWtlcyBzb3VyY2UgbWFwcyBpbnNpZGUgc3R5bGUgdGFncyB3b3JrIHByb3Blcmx5IGluIENocm9tZVxuXHRcdGNzcyArPSAnXFxuLyojIHNvdXJjZVVSTD0nICsgc291cmNlTWFwLnNvdXJjZXNbMF0gKyAnICovJztcblx0XHQvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yNjYwMzg3NVxuXHRcdGNzcyArPSBcIlxcbi8qIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsXCIgKyBidG9hKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChKU09OLnN0cmluZ2lmeShzb3VyY2VNYXApKSkpICsgXCIgKi9cIjtcblx0fVxuXG5cdGlmIChzdHlsZUVsZW1lbnQuc3R5bGVTaGVldCkge1xuXHRcdHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0LmNzc1RleHQgPSBjc3M7XG5cdH0gZWxzZSB7XG5cdFx0d2hpbGUoc3R5bGVFbGVtZW50LmZpcnN0Q2hpbGQpIHtcblx0XHRcdHN0eWxlRWxlbWVudC5yZW1vdmVDaGlsZChzdHlsZUVsZW1lbnQuZmlyc3RDaGlsZCk7XG5cdFx0fVxuXHRcdHN0eWxlRWxlbWVudC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShjc3MpKTtcblx0fVxufVxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Z1ZS1zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXG4vLyBtb2R1bGUgaWQgPSAxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=')},function(module,exports,__webpack_require__){eval("var __WEBPACK_AMD_DEFINE_RESULT__;/* Zepto v1.2.0 - zepto event ajax form ie - zeptojs.com/license */\r\n(function(global, factory) {\r\n    if(exports === 'object' && typeof module !== 'undefined')\r\n        module.exports = factory(global)\r\n    if (true)\r\n        !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { return factory(global) }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))\r\n    else\r\n        factory(global)\r\n}( typeof window !== \"undefined\" ? window : this, function(window) {\r\n    var Zepto = (function() {\r\n        var undefined, key, $, classList, emptyArray = [], concat = emptyArray.concat, filter = emptyArray.filter, slice = emptyArray.slice,\r\n            document = window.document,\r\n            elementDisplay = {}, classCache = {},\r\n            cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 },\r\n            fragmentRE = /^\\s*<(\\w+|!)[^>]*>/,\r\n            singleTagRE = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,\r\n            tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/ig,\r\n            rootNodeRE = /^(?:body|html)$/i,\r\n            capitalRE = /([A-Z])/g,\r\n\r\n            // special attributes that should be get/set via method calls\r\n            methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],\r\n\r\n            adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ],\r\n            table = document.createElement('table'),\r\n            tableRow = document.createElement('tr'),\r\n            containers = {\r\n                'tr': document.createElement('tbody'),\r\n                'tbody': table, 'thead': table, 'tfoot': table,\r\n                'td': tableRow, 'th': tableRow,\r\n                '*': document.createElement('div')\r\n            },\r\n            readyRE = /complete|loaded|interactive/,\r\n            simpleSelectorRE = /^[\\w-]*$/,\r\n            class2type = {},\r\n            toString = class2type.toString,\r\n            zepto = {},\r\n            camelize, uniq,\r\n            tempParent = document.createElement('div'),\r\n            propMap = {\r\n                'tabindex': 'tabIndex',\r\n                'readonly': 'readOnly',\r\n                'for': 'htmlFor',\r\n                'class': 'className',\r\n                'maxlength': 'maxLength',\r\n                'cellspacing': 'cellSpacing',\r\n                'cellpadding': 'cellPadding',\r\n                'rowspan': 'rowSpan',\r\n                'colspan': 'colSpan',\r\n                'usemap': 'useMap',\r\n                'frameborder': 'frameBorder',\r\n                'contenteditable': 'contentEditable'\r\n            },\r\n            isArray = Array.isArray ||\r\n                function(object){ return object instanceof Array }\r\n\r\n        zepto.matches = function(element, selector) {\r\n            if (!selector || !element || element.nodeType !== 1) return false\r\n            var matchesSelector = element.matches || element.webkitMatchesSelector ||\r\n                element.mozMatchesSelector || element.oMatchesSelector ||\r\n                element.matchesSelector\r\n            if (matchesSelector) return matchesSelector.call(element, selector)\r\n            // fall back to performing a selector:\r\n            var match, parent = element.parentNode, temp = !parent\r\n            if (temp) (parent = tempParent).appendChild(element)\r\n            match = ~zepto.qsa(parent, selector).indexOf(element)\r\n            temp && tempParent.removeChild(element)\r\n            return match\r\n        }\r\n\r\n        function type(obj) {\r\n            return obj == null ? String(obj) :\r\n            class2type[toString.call(obj)] || \"object\"\r\n        }\r\n\r\n        function isFunction(value) { return type(value) == \"function\" }\r\n        function isWindow(obj)     { return obj != null && obj == obj.window }\r\n        function isDocument(obj)   { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }\r\n        function isObject(obj)     { return type(obj) == \"object\" }\r\n        function isPlainObject(obj) {\r\n            return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype\r\n        }\r\n\r\n        function likeArray(obj) {\r\n            var length = !!obj && 'length' in obj && obj.length,\r\n                type = $.type(obj)\r\n\r\n            return 'function' != type && !isWindow(obj) && (\r\n                    'array' == type || length === 0 ||\r\n                    (typeof length == 'number' && length > 0 && (length - 1) in obj)\r\n                )\r\n        }\r\n\r\n        function compact(array) { return filter.call(array, function(item){ return item != null }) }\r\n        function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array }\r\n        camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) }\r\n        function dasherize(str) {\r\n            return str.replace(/::/g, '/')\r\n                .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')\r\n                .replace(/([a-z\\d])([A-Z])/g, '$1_$2')\r\n                .replace(/_/g, '-')\r\n                .toLowerCase()\r\n        }\r\n        uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) }\r\n\r\n        function classRE(name) {\r\n            return name in classCache ?\r\n                classCache[name] : (classCache[name] = new RegExp('(^|\\\\s)' + name + '(\\\\s|$)'))\r\n        }\r\n\r\n        function maybeAddPx(name, value) {\r\n            return (typeof value == \"number\" && !cssNumber[dasherize(name)]) ? value + \"px\" : value\r\n        }\r\n\r\n        function defaultDisplay(nodeName) {\r\n            var element, display\r\n            if (!elementDisplay[nodeName]) {\r\n                element = document.createElement(nodeName)\r\n                document.body.appendChild(element)\r\n                display = getComputedStyle(element, '').getPropertyValue(\"display\")\r\n                element.parentNode.removeChild(element)\r\n                display == \"none\" && (display = \"block\")\r\n                elementDisplay[nodeName] = display\r\n            }\r\n            return elementDisplay[nodeName]\r\n        }\r\n\r\n        function children(element) {\r\n            return 'children' in element ?\r\n                slice.call(element.children) :\r\n                $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node })\r\n        }\r\n\r\n        function Z(dom, selector) {\r\n            var i, len = dom ? dom.length : 0\r\n            for (i = 0; i < len; i++) this[i] = dom[i]\r\n            this.length = len\r\n            this.selector = selector || ''\r\n        }\r\n\r\n        // `$.zepto.fragment` takes a html string and an optional tag name\r\n        // to generate DOM nodes from the given html string.\r\n        // The generated DOM nodes are returned as an array.\r\n        // This function can be overridden in plugins for example to make\r\n        // it compatible with browsers that don't support the DOM fully.\r\n        zepto.fragment = function(html, name, properties) {\r\n            var dom, nodes, container\r\n\r\n            // A special case optimization for a single tag\r\n            if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1))\r\n\r\n            if (!dom) {\r\n                if (html.replace) html = html.replace(tagExpanderRE, \"<$1></$2>\")\r\n                if (name === undefined) name = fragmentRE.test(html) && RegExp.$1\r\n                if (!(name in containers)) name = '*'\r\n\r\n                container = containers[name]\r\n                container.innerHTML = '' + html\r\n                dom = $.each(slice.call(container.childNodes), function(){\r\n                    container.removeChild(this)\r\n                })\r\n            }\r\n\r\n            if (isPlainObject(properties)) {\r\n                nodes = $(dom)\r\n                $.each(properties, function(key, value) {\r\n                    if (methodAttributes.indexOf(key) > -1) nodes[key](value)\r\n                    else nodes.attr(key, value)\r\n                })\r\n            }\r\n\r\n            return dom\r\n        }\r\n\r\n        // `$.zepto.Z` swaps out the prototype of the given `dom` array\r\n        // of nodes with `$.fn` and thus supplying all the Zepto functions\r\n        // to the array. This method can be overridden in plugins.\r\n        zepto.Z = function(dom, selector) {\r\n            return new Z(dom, selector)\r\n        }\r\n\r\n        // `$.zepto.isZ` should return `true` if the given object is a Zepto\r\n        // collection. This method can be overridden in plugins.\r\n        zepto.isZ = function(object) {\r\n            return object instanceof zepto.Z\r\n        }\r\n\r\n        // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and\r\n        // takes a CSS selector and an optional context (and handles various\r\n        // special cases).\r\n        // This method can be overridden in plugins.\r\n        zepto.init = function(selector, context) {\r\n            var dom\r\n            // If nothing given, return an empty Zepto collection\r\n            if (!selector) return zepto.Z()\r\n            // Optimize for string selectors\r\n            else if (typeof selector == 'string') {\r\n                selector = selector.trim()\r\n                // If it's a html fragment, create nodes from it\r\n                // Note: In both Chrome 21 and Firefox 15, DOM error 12\r\n                // is thrown if the fragment doesn't begin with <\r\n                if (selector[0] == '<' && fragmentRE.test(selector))\r\n                    dom = zepto.fragment(selector, RegExp.$1, context), selector = null\r\n                // If there's a context, create a collection on that context first, and select\r\n                // nodes from there\r\n                else if (context !== undefined) return $(context).find(selector)\r\n                // If it's a CSS selector, use it to select nodes.\r\n                else dom = zepto.qsa(document, selector)\r\n            }\r\n            // If a function is given, call it when the DOM is ready\r\n            else if (isFunction(selector)) return $(document).ready(selector)\r\n            // If a Zepto collection is given, just return it\r\n            else if (zepto.isZ(selector)) return selector\r\n            else {\r\n                // normalize array if an array of nodes is given\r\n                if (isArray(selector)) dom = compact(selector)\r\n                // Wrap DOM nodes.\r\n                else if (isObject(selector))\r\n                    dom = [selector], selector = null\r\n                // If it's a html fragment, create nodes from it\r\n                else if (fragmentRE.test(selector))\r\n                    dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null\r\n                // If there's a context, create a collection on that context first, and select\r\n                // nodes from there\r\n                else if (context !== undefined) return $(context).find(selector)\r\n                // And last but no least, if it's a CSS selector, use it to select nodes.\r\n                else dom = zepto.qsa(document, selector)\r\n            }\r\n            // create a new Zepto collection from the nodes found\r\n            return zepto.Z(dom, selector)\r\n        }\r\n\r\n        // `$` will be the base `Zepto` object. When calling this\r\n        // function just call `$.zepto.init, which makes the implementation\r\n        // details of selecting nodes and creating Zepto collections\r\n        // patchable in plugins.\r\n        $ = function(selector, context){\r\n            return zepto.init(selector, context)\r\n        }\r\n\r\n        function extend(target, source, deep) {\r\n            for (key in source)\r\n                if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {\r\n                    if (isPlainObject(source[key]) && !isPlainObject(target[key]))\r\n                        target[key] = {}\r\n                    if (isArray(source[key]) && !isArray(target[key]))\r\n                        target[key] = []\r\n                    extend(target[key], source[key], deep)\r\n                }\r\n                else if (source[key] !== undefined) target[key] = source[key]\r\n        }\r\n\r\n        // Copy all but undefined properties from one or more\r\n        // objects to the `target` object.\r\n        $.extend = function(target){\r\n            var deep, args = slice.call(arguments, 1)\r\n            if (typeof target == 'boolean') {\r\n                deep = target\r\n                target = args.shift()\r\n            }\r\n            args.forEach(function(arg){ extend(target, arg, deep) })\r\n            return target\r\n        }\r\n\r\n        // `$.zepto.qsa` is Zepto's CSS selector implementation which\r\n        // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`.\r\n        // This method can be overridden in plugins.\r\n        zepto.qsa = function(element, selector){\r\n            var found,\r\n                maybeID = selector[0] == '#',\r\n                maybeClass = !maybeID && selector[0] == '.',\r\n                nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked\r\n                isSimple = simpleSelectorRE.test(nameOnly)\r\n            return (element.getElementById && isSimple && maybeID) ? // Safari DocumentFragment doesn't have getElementById\r\n                ( (found = element.getElementById(nameOnly)) ? [found] : [] ) :\r\n                (element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11) ? [] :\r\n                    slice.call(\r\n                        isSimple && !maybeID && element.getElementsByClassName ? // DocumentFragment doesn't have getElementsByClassName/TagName\r\n                            maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class\r\n                                element.getElementsByTagName(selector) : // Or a tag\r\n                            element.querySelectorAll(selector) // Or it's not simple, and we need to query all\r\n                    )\r\n        }\r\n\r\n        function filtered(nodes, selector) {\r\n            return selector == null ? $(nodes) : $(nodes).filter(selector)\r\n        }\r\n\r\n        $.contains = document.documentElement.contains ?\r\n            function(parent, node) {\r\n                return parent !== node && parent.contains(node)\r\n            } :\r\n            function(parent, node) {\r\n                while (node && (node = node.parentNode))\r\n                    if (node === parent) return true\r\n                return false\r\n            }\r\n\r\n        function funcArg(context, arg, idx, payload) {\r\n            return isFunction(arg) ? arg.call(context, idx, payload) : arg\r\n        }\r\n\r\n        function setAttribute(node, name, value) {\r\n            value == null ? node.removeAttribute(name) : node.setAttribute(name, value)\r\n        }\r\n\r\n        // access className property while respecting SVGAnimatedString\r\n        function className(node, value){\r\n            var klass = node.className || '',\r\n                svg   = klass && klass.baseVal !== undefined\r\n\r\n            if (value === undefined) return svg ? klass.baseVal : klass\r\n            svg ? (klass.baseVal = value) : (node.className = value)\r\n        }\r\n\r\n        // \"true\"  => true\r\n        // \"false\" => false\r\n        // \"null\"  => null\r\n        // \"42\"    => 42\r\n        // \"42.5\"  => 42.5\r\n        // \"08\"    => \"08\"\r\n        // JSON    => parse if valid\r\n        // String  => self\r\n        function deserializeValue(value) {\r\n            try {\r\n                return value ?\r\n                value == \"true\" ||\r\n                ( value == \"false\" ? false :\r\n                    value == \"null\" ? null :\r\n                        +value + \"\" == value ? +value :\r\n                            /^[\\[\\{]/.test(value) ? $.parseJSON(value) :\r\n                                value )\r\n                    : value\r\n            } catch(e) {\r\n                return value\r\n            }\r\n        }\r\n\r\n        $.type = type\r\n        $.isFunction = isFunction\r\n        $.isWindow = isWindow\r\n        $.isArray = isArray\r\n        $.isPlainObject = isPlainObject\r\n\r\n        $.isEmptyObject = function(obj) {\r\n            var name\r\n            for (name in obj) return false\r\n            return true\r\n        }\r\n\r\n        $.isNumeric = function(val) {\r\n            var num = Number(val), type = typeof val\r\n            return val != null && type != 'boolean' &&\r\n                (type != 'string' || val.length) &&\r\n                !isNaN(num) && isFinite(num) || false\r\n        }\r\n\r\n        $.inArray = function(elem, array, i){\r\n            return emptyArray.indexOf.call(array, elem, i)\r\n        }\r\n\r\n        $.camelCase = camelize\r\n        $.trim = function(str) {\r\n            return str == null ? \"\" : String.prototype.trim.call(str)\r\n        }\r\n\r\n        // plugin compatibility\r\n        $.uuid = 0\r\n        $.support = { }\r\n        $.expr = { }\r\n        $.noop = function() {}\r\n\r\n        $.map = function(elements, callback){\r\n            var value, values = [], i, key\r\n            if (likeArray(elements))\r\n                for (i = 0; i < elements.length; i++) {\r\n                    value = callback(elements[i], i)\r\n                    if (value != null) values.push(value)\r\n                }\r\n            else\r\n                for (key in elements) {\r\n                    value = callback(elements[key], key)\r\n                    if (value != null) values.push(value)\r\n                }\r\n            return flatten(values)\r\n        }\r\n\r\n        $.each = function(elements, callback){\r\n            var i, key\r\n            if (likeArray(elements)) {\r\n                for (i = 0; i < elements.length; i++)\r\n                    if (callback.call(elements[i], i, elements[i]) === false) return elements\r\n            } else {\r\n                for (key in elements)\r\n                    if (callback.call(elements[key], key, elements[key]) === false) return elements\r\n            }\r\n\r\n            return elements\r\n        }\r\n\r\n        $.grep = function(elements, callback){\r\n            return filter.call(elements, callback)\r\n        }\r\n\r\n        if (window.JSON) $.parseJSON = JSON.parse\r\n\r\n        // Populate the class2type map\r\n        $.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\r\n            class2type[ \"[object \" + name + \"]\" ] = name.toLowerCase()\r\n        })\r\n\r\n        // Define methods that will be available on all\r\n        // Zepto collections\r\n        $.fn = {\r\n            constructor: zepto.Z,\r\n            length: 0,\r\n\r\n            // Because a collection acts like an array\r\n            // copy over these useful array functions.\r\n            forEach: emptyArray.forEach,\r\n            reduce: emptyArray.reduce,\r\n            push: emptyArray.push,\r\n            sort: emptyArray.sort,\r\n            splice: emptyArray.splice,\r\n            indexOf: emptyArray.indexOf,\r\n            concat: function(){\r\n                var i, value, args = []\r\n                for (i = 0; i < arguments.length; i++) {\r\n                    value = arguments[i]\r\n                    args[i] = zepto.isZ(value) ? value.toArray() : value\r\n                }\r\n                return concat.apply(zepto.isZ(this) ? this.toArray() : this, args)\r\n            },\r\n\r\n            // `map` and `slice` in the jQuery API work differently\r\n            // from their array counterparts\r\n            map: function(fn){\r\n                return $($.map(this, function(el, i){ return fn.call(el, i, el) }))\r\n            },\r\n            slice: function(){\r\n                return $(slice.apply(this, arguments))\r\n            },\r\n\r\n            ready: function(callback){\r\n                // need to check if document.body exists for IE as that browser reports\r\n                // document ready when it hasn't yet created the body element\r\n                if (readyRE.test(document.readyState) && document.body) callback($)\r\n                else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false)\r\n                return this\r\n            },\r\n            get: function(idx){\r\n                return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]\r\n            },\r\n            toArray: function(){ return this.get() },\r\n            size: function(){\r\n                return this.length\r\n            },\r\n            remove: function(){\r\n                return this.each(function(){\r\n                    if (this.parentNode != null)\r\n                        this.parentNode.removeChild(this)\r\n                })\r\n            },\r\n            each: function(callback){\r\n                emptyArray.every.call(this, function(el, idx){\r\n                    return callback.call(el, idx, el) !== false\r\n                })\r\n                return this\r\n            },\r\n            filter: function(selector){\r\n                if (isFunction(selector)) return this.not(this.not(selector))\r\n                return $(filter.call(this, function(element){\r\n                    return zepto.matches(element, selector)\r\n                }))\r\n            },\r\n            add: function(selector,context){\r\n                return $(uniq(this.concat($(selector,context))))\r\n            },\r\n            is: function(selector){\r\n                return this.length > 0 && zepto.matches(this[0], selector)\r\n            },\r\n            not: function(selector){\r\n                var nodes=[]\r\n                if (isFunction(selector) && selector.call !== undefined)\r\n                    this.each(function(idx){\r\n                        if (!selector.call(this,idx)) nodes.push(this)\r\n                    })\r\n                else {\r\n                    var excludes = typeof selector == 'string' ? this.filter(selector) :\r\n                        (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)\r\n                    this.forEach(function(el){\r\n                        if (excludes.indexOf(el) < 0) nodes.push(el)\r\n                    })\r\n                }\r\n                return $(nodes)\r\n            },\r\n            has: function(selector){\r\n                return this.filter(function(){\r\n                    return isObject(selector) ?\r\n                        $.contains(this, selector) :\r\n                        $(this).find(selector).size()\r\n                })\r\n            },\r\n            eq: function(idx){\r\n                return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1)\r\n            },\r\n            first: function(){\r\n                var el = this[0]\r\n                return el && !isObject(el) ? el : $(el)\r\n            },\r\n            last: function(){\r\n                var el = this[this.length - 1]\r\n                return el && !isObject(el) ? el : $(el)\r\n            },\r\n            find: function(selector){\r\n                var result, $this = this\r\n                if (!selector) result = $()\r\n                else if (typeof selector == 'object')\r\n                    result = $(selector).filter(function(){\r\n                        var node = this\r\n                        return emptyArray.some.call($this, function(parent){\r\n                            return $.contains(parent, node)\r\n                        })\r\n                    })\r\n                else if (this.length == 1) result = $(zepto.qsa(this[0], selector))\r\n                else result = this.map(function(){ return zepto.qsa(this, selector) })\r\n                return result\r\n            },\r\n            closest: function(selector, context){\r\n                var nodes = [], collection = typeof selector == 'object' && $(selector)\r\n                this.each(function(_, node){\r\n                    while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector)))\r\n                        node = node !== context && !isDocument(node) && node.parentNode\r\n                    if (node && nodes.indexOf(node) < 0) nodes.push(node)\r\n                })\r\n                return $(nodes)\r\n            },\r\n            parents: function(selector){\r\n                var ancestors = [], nodes = this\r\n                while (nodes.length > 0)\r\n                    nodes = $.map(nodes, function(node){\r\n                        if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) {\r\n                            ancestors.push(node)\r\n                            return node\r\n                        }\r\n                    })\r\n                return filtered(ancestors, selector)\r\n            },\r\n            parent: function(selector){\r\n                return filtered(uniq(this.pluck('parentNode')), selector)\r\n            },\r\n            children: function(selector){\r\n                return filtered(this.map(function(){ return children(this) }), selector)\r\n            },\r\n            contents: function() {\r\n                return this.map(function() { return this.contentDocument || slice.call(this.childNodes) })\r\n            },\r\n            siblings: function(selector){\r\n                return filtered(this.map(function(i, el){\r\n                    return filter.call(children(el.parentNode), function(child){ return child!==el })\r\n                }), selector)\r\n            },\r\n            empty: function(){\r\n                return this.each(function(){ this.innerHTML = '' })\r\n            },\r\n            // `pluck` is borrowed from Prototype.js\r\n            pluck: function(property){\r\n                return $.map(this, function(el){ return el[property] })\r\n            },\r\n            show: function(){\r\n                return this.each(function(){\r\n                    this.style.display == \"none\" && (this.style.display = '')\r\n                    if (getComputedStyle(this, '').getPropertyValue(\"display\") == \"none\")\r\n                        this.style.display = defaultDisplay(this.nodeName)\r\n                })\r\n            },\r\n            replaceWith: function(newContent){\r\n                return this.before(newContent).remove()\r\n            },\r\n            wrap: function(structure){\r\n                var func = isFunction(structure)\r\n                if (this[0] && !func)\r\n                    var dom   = $(structure).get(0),\r\n                        clone = dom.parentNode || this.length > 1\r\n\r\n                return this.each(function(index){\r\n                    $(this).wrapAll(\r\n                        func ? structure.call(this, index) :\r\n                            clone ? dom.cloneNode(true) : dom\r\n                    )\r\n                })\r\n            },\r\n            wrapAll: function(structure){\r\n                if (this[0]) {\r\n                    $(this[0]).before(structure = $(structure))\r\n                    var children\r\n                    // drill down to the inmost element\r\n                    while ((children = structure.children()).length) structure = children.first()\r\n                    $(structure).append(this)\r\n                }\r\n                return this\r\n            },\r\n            wrapInner: function(structure){\r\n                var func = isFunction(structure)\r\n                return this.each(function(index){\r\n                    var self = $(this), contents = self.contents(),\r\n                        dom  = func ? structure.call(this, index) : structure\r\n                    contents.length ? contents.wrapAll(dom) : self.append(dom)\r\n                })\r\n            },\r\n            unwrap: function(){\r\n                this.parent().each(function(){\r\n                    $(this).replaceWith($(this).children())\r\n                })\r\n                return this\r\n            },\r\n            clone: function(){\r\n                return this.map(function(){ return this.cloneNode(true) })\r\n            },\r\n            hide: function(){\r\n                return this.css(\"display\", \"none\")\r\n            },\r\n            toggle: function(setting){\r\n                return this.each(function(){\r\n                    var el = $(this)\r\n                        ;(setting === undefined ? el.css(\"display\") == \"none\" : setting) ? el.show() : el.hide()\r\n                })\r\n            },\r\n            prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') },\r\n            next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') },\r\n            html: function(html){\r\n                return 0 in arguments ?\r\n                    this.each(function(idx){\r\n                        var originHtml = this.innerHTML\r\n                        $(this).empty().append( funcArg(this, html, idx, originHtml) )\r\n                    }) :\r\n                    (0 in this ? this[0].innerHTML : null)\r\n            },\r\n            text: function(text){\r\n                return 0 in arguments ?\r\n                    this.each(function(idx){\r\n                        var newText = funcArg(this, text, idx, this.textContent)\r\n                        this.textContent = newText == null ? '' : ''+newText\r\n                    }) :\r\n                    (0 in this ? this.pluck('textContent').join(\"\") : null)\r\n            },\r\n            attr: function(name, value){\r\n                var result\r\n                return (typeof name == 'string' && !(1 in arguments)) ?\r\n                    (0 in this && this[0].nodeType == 1 && (result = this[0].getAttribute(name)) != null ? result : undefined) :\r\n                    this.each(function(idx){\r\n                        if (this.nodeType !== 1) return\r\n                        if (isObject(name)) for (key in name) setAttribute(this, key, name[key])\r\n                        else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name)))\r\n                    })\r\n            },\r\n            removeAttr: function(name){\r\n                return this.each(function(){ this.nodeType === 1 && name.split(' ').forEach(function(attribute){\r\n                    setAttribute(this, attribute)\r\n                }, this)})\r\n            },\r\n            prop: function(name, value){\r\n                name = propMap[name] || name\r\n                return (1 in arguments) ?\r\n                    this.each(function(idx){\r\n                        this[name] = funcArg(this, value, idx, this[name])\r\n                    }) :\r\n                    (this[0] && this[0][name])\r\n            },\r\n            removeProp: function(name){\r\n                name = propMap[name] || name\r\n                return this.each(function(){ delete this[name] })\r\n            },\r\n            data: function(name, value){\r\n                var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase()\r\n\r\n                var data = (1 in arguments) ?\r\n                    this.attr(attrName, value) :\r\n                    this.attr(attrName)\r\n\r\n                return data !== null ? deserializeValue(data) : undefined\r\n            },\r\n            val: function(value){\r\n                if (0 in arguments) {\r\n                    if (value == null) value = \"\"\r\n                    return this.each(function(idx){\r\n                        this.value = funcArg(this, value, idx, this.value)\r\n                    })\r\n                } else {\r\n                    return this[0] && (this[0].multiple ?\r\n                            $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') :\r\n                            this[0].value)\r\n                }\r\n            },\r\n            offset: function(coordinates){\r\n                if (coordinates) return this.each(function(index){\r\n                    var $this = $(this),\r\n                        coords = funcArg(this, coordinates, index, $this.offset()),\r\n                        parentOffset = $this.offsetParent().offset(),\r\n                        props = {\r\n                            top:  coords.top  - parentOffset.top,\r\n                            left: coords.left - parentOffset.left\r\n                        }\r\n\r\n                    if ($this.css('position') == 'static') props['position'] = 'relative'\r\n                    $this.css(props)\r\n                })\r\n                if (!this.length) return null\r\n                if (document.documentElement !== this[0] && !$.contains(document.documentElement, this[0]))\r\n                    return {top: 0, left: 0}\r\n                var obj = this[0].getBoundingClientRect()\r\n                return {\r\n                    left: obj.left + window.pageXOffset,\r\n                    top: obj.top + window.pageYOffset,\r\n                    width: Math.round(obj.width),\r\n                    height: Math.round(obj.height)\r\n                }\r\n            },\r\n            css: function(property, value){\r\n                if (arguments.length < 2) {\r\n                    var element = this[0]\r\n                    if (typeof property == 'string') {\r\n                        if (!element) return\r\n                        return element.style[camelize(property)] || getComputedStyle(element, '').getPropertyValue(property)\r\n                    } else if (isArray(property)) {\r\n                        if (!element) return\r\n                        var props = {}\r\n                        var computedStyle = getComputedStyle(element, '')\r\n                        $.each(property, function(_, prop){\r\n                            props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop))\r\n                        })\r\n                        return props\r\n                    }\r\n                }\r\n\r\n                var css = ''\r\n                if (type(property) == 'string') {\r\n                    if (!value && value !== 0)\r\n                        this.each(function(){ this.style.removeProperty(dasherize(property)) })\r\n                    else\r\n                        css = dasherize(property) + \":\" + maybeAddPx(property, value)\r\n                } else {\r\n                    for (key in property)\r\n                        if (!property[key] && property[key] !== 0)\r\n                            this.each(function(){ this.style.removeProperty(dasherize(key)) })\r\n                        else\r\n                            css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';'\r\n                }\r\n\r\n                return this.each(function(){ this.style.cssText += ';' + css })\r\n            },\r\n            index: function(element){\r\n                return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0])\r\n            },\r\n            hasClass: function(name){\r\n                if (!name) return false\r\n                return emptyArray.some.call(this, function(el){\r\n                    return this.test(className(el))\r\n                }, classRE(name))\r\n            },\r\n            addClass: function(name){\r\n                if (!name) return this\r\n                return this.each(function(idx){\r\n                    if (!('className' in this)) return\r\n                    classList = []\r\n                    var cls = className(this), newName = funcArg(this, name, idx, cls)\r\n                    newName.split(/\\s+/g).forEach(function(klass){\r\n                        if (!$(this).hasClass(klass)) classList.push(klass)\r\n                    }, this)\r\n                    classList.length && className(this, cls + (cls ? \" \" : \"\") + classList.join(\" \"))\r\n                })\r\n            },\r\n            removeClass: function(name){\r\n                return this.each(function(idx){\r\n                    if (!('className' in this)) return\r\n                    if (name === undefined) return className(this, '')\r\n                    classList = className(this)\r\n                    funcArg(this, name, idx, classList).split(/\\s+/g).forEach(function(klass){\r\n                        classList = classList.replace(classRE(klass), \" \")\r\n                    })\r\n                    className(this, classList.trim())\r\n                })\r\n            },\r\n            toggleClass: function(name, when){\r\n                if (!name) return this\r\n                return this.each(function(idx){\r\n                    var $this = $(this), names = funcArg(this, name, idx, className(this))\r\n                    names.split(/\\s+/g).forEach(function(klass){\r\n                        (when === undefined ? !$this.hasClass(klass) : when) ?\r\n                            $this.addClass(klass) : $this.removeClass(klass)\r\n                    })\r\n                })\r\n            },\r\n            scrollTop: function(value){\r\n                if (!this.length) return\r\n                var hasScrollTop = 'scrollTop' in this[0]\r\n                if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset\r\n                return this.each(hasScrollTop ?\r\n                    function(){ this.scrollTop = value } :\r\n                    function(){ this.scrollTo(this.scrollX, value) })\r\n            },\r\n            scrollLeft: function(value){\r\n                if (!this.length) return\r\n                var hasScrollLeft = 'scrollLeft' in this[0]\r\n                if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset\r\n                return this.each(hasScrollLeft ?\r\n                    function(){ this.scrollLeft = value } :\r\n                    function(){ this.scrollTo(value, this.scrollY) })\r\n            },\r\n            position: function() {\r\n                if (!this.length) return\r\n\r\n                var elem = this[0],\r\n                    // Get *real* offsetParent\r\n                    offsetParent = this.offsetParent(),\r\n                    // Get correct offsets\r\n                    offset       = this.offset(),\r\n                    parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset()\r\n\r\n                // Subtract element margins\r\n                // note: when an element has margin: auto the offsetLeft and marginLeft\r\n                // are the same in Safari causing offset.left to incorrectly be 0\r\n                offset.top  -= parseFloat( $(elem).css('margin-top') ) || 0\r\n                offset.left -= parseFloat( $(elem).css('margin-left') ) || 0\r\n\r\n                // Add offsetParent borders\r\n                parentOffset.top  += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0\r\n                parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0\r\n\r\n                // Subtract the two offsets\r\n                return {\r\n                    top:  offset.top  - parentOffset.top,\r\n                    left: offset.left - parentOffset.left\r\n                }\r\n            },\r\n            offsetParent: function() {\r\n                return this.map(function(){\r\n                    var parent = this.offsetParent || document.body\r\n                    while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css(\"position\") == \"static\")\r\n                        parent = parent.offsetParent\r\n                    return parent\r\n                })\r\n            }\r\n        }\r\n\r\n        // for now\r\n        $.fn.detach = $.fn.remove\r\n\r\n        // Generate the `width` and `height` functions\r\n        ;['width', 'height'].forEach(function(dimension){\r\n            var dimensionProperty =\r\n                dimension.replace(/./, function(m){ return m[0].toUpperCase() })\r\n\r\n            $.fn[dimension] = function(value){\r\n                var offset, el = this[0]\r\n                if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] :\r\n                    isDocument(el) ? el.documentElement['scroll' + dimensionProperty] :\r\n                    (offset = this.offset()) && offset[dimension]\r\n                else return this.each(function(idx){\r\n                    el = $(this)\r\n                    el.css(dimension, funcArg(this, value, idx, el[dimension]()))\r\n                })\r\n            }\r\n        })\r\n\r\n        function traverseNode(node, fun) {\r\n            fun(node)\r\n            for (var i = 0, len = node.childNodes.length; i < len; i++)\r\n                traverseNode(node.childNodes[i], fun)\r\n        }\r\n\r\n        // Generate the `after`, `prepend`, `before`, `append`,\r\n        // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods.\r\n        adjacencyOperators.forEach(function(operator, operatorIndex) {\r\n            var inside = operatorIndex % 2 //=> prepend, append\r\n\r\n            $.fn[operator] = function(){\r\n                // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings\r\n                var argType, nodes = $.map(arguments, function(arg) {\r\n                        var arr = []\r\n                        argType = type(arg)\r\n                        if (argType == \"array\") {\r\n                            arg.forEach(function(el) {\r\n                                if (el.nodeType !== undefined) return arr.push(el)\r\n                                else if ($.zepto.isZ(el)) return arr = arr.concat(el.get())\r\n                                arr = arr.concat(zepto.fragment(el))\r\n                            })\r\n                            return arr\r\n                        }\r\n                        return argType == \"object\" || arg == null ?\r\n                            arg : zepto.fragment(arg)\r\n                    }),\r\n                    parent, copyByClone = this.length > 1\r\n                if (nodes.length < 1) return this\r\n\r\n                return this.each(function(_, target){\r\n                    parent = inside ? target : target.parentNode\r\n\r\n                    // convert all methods to a \"before\" operation\r\n                    target = operatorIndex == 0 ? target.nextSibling :\r\n                        operatorIndex == 1 ? target.firstChild :\r\n                            operatorIndex == 2 ? target :\r\n                                null\r\n\r\n                    var parentInDocument = $.contains(document.documentElement, parent)\r\n\r\n                    nodes.forEach(function(node){\r\n                        if (copyByClone) node = node.cloneNode(true)\r\n                        else if (!parent) return $(node).remove()\r\n\r\n                        parent.insertBefore(node, target)\r\n                        if (parentInDocument) traverseNode(node, function(el){\r\n                            if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&\r\n                                (!el.type || el.type === 'text/javascript') && !el.src){\r\n                                var target = el.ownerDocument ? el.ownerDocument.defaultView : window\r\n                                target['eval'].call(target, el.innerHTML)\r\n                            }\r\n                        })\r\n                    })\r\n                })\r\n            }\r\n\r\n            // after    => insertAfter\r\n            // prepend  => prependTo\r\n            // before   => insertBefore\r\n            // append   => appendTo\r\n            $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){\r\n                $(html)[operator](this)\r\n                return this\r\n            }\r\n        })\r\n\r\n        zepto.Z.prototype = Z.prototype = $.fn\r\n\r\n        // Export internal API functions in the `$.zepto` namespace\r\n        zepto.uniq = uniq\r\n        zepto.deserializeValue = deserializeValue\r\n        $.zepto = zepto\r\n\r\n        return $\r\n    })()\r\n\r\n    window.Zepto = Zepto\r\n    window.$ === undefined && (window.$ = Zepto)\r\n\r\n    ;(function($){\r\n        var _zid = 1, undefined,\r\n            slice = Array.prototype.slice,\r\n            isFunction = $.isFunction,\r\n            isString = function(obj){ return typeof obj == 'string' },\r\n            handlers = {},\r\n            specialEvents={},\r\n            focusinSupported = 'onfocusin' in window,\r\n            focus = { focus: 'focusin', blur: 'focusout' },\r\n            hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' }\r\n\r\n        specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'\r\n\r\n        function zid(element) {\r\n            return element._zid || (element._zid = _zid++)\r\n        }\r\n        function findHandlers(element, event, fn, selector) {\r\n            event = parse(event)\r\n            if (event.ns) var matcher = matcherFor(event.ns)\r\n            return (handlers[zid(element)] || []).filter(function(handler) {\r\n                return handler\r\n                    && (!event.e  || handler.e == event.e)\r\n                    && (!event.ns || matcher.test(handler.ns))\r\n                    && (!fn       || zid(handler.fn) === zid(fn))\r\n                    && (!selector || handler.sel == selector)\r\n            })\r\n        }\r\n        function parse(event) {\r\n            var parts = ('' + event).split('.')\r\n            return {e: parts[0], ns: parts.slice(1).sort().join(' ')}\r\n        }\r\n        function matcherFor(ns) {\r\n            return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)')\r\n        }\r\n\r\n        function eventCapture(handler, captureSetting) {\r\n            return handler.del &&\r\n                (!focusinSupported && (handler.e in focus)) ||\r\n                !!captureSetting\r\n        }\r\n\r\n        function realEvent(type) {\r\n            return hover[type] || (focusinSupported && focus[type]) || type\r\n        }\r\n\r\n        function add(element, events, fn, data, selector, delegator, capture){\r\n            var id = zid(element), set = (handlers[id] || (handlers[id] = []))\r\n            events.split(/\\s/).forEach(function(event){\r\n                if (event == 'ready') return $(document).ready(fn)\r\n                var handler   = parse(event)\r\n                handler.fn    = fn\r\n                handler.sel   = selector\r\n                // emulate mouseenter, mouseleave\r\n                if (handler.e in hover) fn = function(e){\r\n                    var related = e.relatedTarget\r\n                    if (!related || (related !== this && !$.contains(this, related)))\r\n                        return handler.fn.apply(this, arguments)\r\n                }\r\n                handler.del   = delegator\r\n                var callback  = delegator || fn\r\n                handler.proxy = function(e){\r\n                    e = compatible(e)\r\n                    if (e.isImmediatePropagationStopped()) return\r\n                    e.data = data\r\n                    var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args))\r\n                    if (result === false) e.preventDefault(), e.stopPropagation()\r\n                    return result\r\n                }\r\n                handler.i = set.length\r\n                set.push(handler)\r\n                if ('addEventListener' in element)\r\n                    element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))\r\n            })\r\n        }\r\n        function remove(element, events, fn, selector, capture){\r\n            var id = zid(element)\r\n                ;(events || '').split(/\\s/).forEach(function(event){\r\n                findHandlers(element, event, fn, selector).forEach(function(handler){\r\n                    delete handlers[id][handler.i]\r\n                    if ('removeEventListener' in element)\r\n                        element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))\r\n                })\r\n            })\r\n        }\r\n\r\n        $.event = { add: add, remove: remove }\r\n\r\n        $.proxy = function(fn, context) {\r\n            var args = (2 in arguments) && slice.call(arguments, 2)\r\n            if (isFunction(fn)) {\r\n                var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) }\r\n                proxyFn._zid = zid(fn)\r\n                return proxyFn\r\n            } else if (isString(context)) {\r\n                if (args) {\r\n                    args.unshift(fn[context], fn)\r\n                    return $.proxy.apply(null, args)\r\n                } else {\r\n                    return $.proxy(fn[context], fn)\r\n                }\r\n            } else {\r\n                throw new TypeError(\"expected function\")\r\n            }\r\n        }\r\n\r\n        $.fn.bind = function(event, data, callback){\r\n            return this.on(event, data, callback)\r\n        }\r\n        $.fn.unbind = function(event, callback){\r\n            return this.off(event, callback)\r\n        }\r\n        $.fn.one = function(event, selector, data, callback){\r\n            return this.on(event, selector, data, callback, 1)\r\n        }\r\n\r\n        var returnTrue = function(){return true},\r\n            returnFalse = function(){return false},\r\n            ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/,\r\n            eventMethods = {\r\n                preventDefault: 'isDefaultPrevented',\r\n                stopImmediatePropagation: 'isImmediatePropagationStopped',\r\n                stopPropagation: 'isPropagationStopped'\r\n            }\r\n\r\n        function compatible(event, source) {\r\n            if (source || !event.isDefaultPrevented) {\r\n                source || (source = event)\r\n\r\n                $.each(eventMethods, function(name, predicate) {\r\n                    var sourceMethod = source[name]\r\n                    event[name] = function(){\r\n                        this[predicate] = returnTrue\r\n                        return sourceMethod && sourceMethod.apply(source, arguments)\r\n                    }\r\n                    event[predicate] = returnFalse\r\n                })\r\n\r\n                event.timeStamp || (event.timeStamp = Date.now())\r\n\r\n                if (source.defaultPrevented !== undefined ? source.defaultPrevented :\r\n                        'returnValue' in source ? source.returnValue === false :\r\n                        source.getPreventDefault && source.getPreventDefault())\r\n                    event.isDefaultPrevented = returnTrue\r\n            }\r\n            return event\r\n        }\r\n\r\n        function createProxy(event) {\r\n            var key, proxy = { originalEvent: event }\r\n            for (key in event)\r\n                if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key]\r\n\r\n            return compatible(proxy, event)\r\n        }\r\n\r\n        $.fn.delegate = function(selector, event, callback){\r\n            return this.on(event, selector, callback)\r\n        }\r\n        $.fn.undelegate = function(selector, event, callback){\r\n            return this.off(event, selector, callback)\r\n        }\r\n\r\n        $.fn.live = function(event, callback){\r\n            $(document.body).delegate(this.selector, event, callback)\r\n            return this\r\n        }\r\n        $.fn.die = function(event, callback){\r\n            $(document.body).undelegate(this.selector, event, callback)\r\n            return this\r\n        }\r\n\r\n        $.fn.on = function(event, selector, data, callback, one){\r\n            var autoRemove, delegator, $this = this\r\n            if (event && !isString(event)) {\r\n                $.each(event, function(type, fn){\r\n                    $this.on(type, selector, data, fn, one)\r\n                })\r\n                return $this\r\n            }\r\n\r\n            if (!isString(selector) && !isFunction(callback) && callback !== false)\r\n                callback = data, data = selector, selector = undefined\r\n            if (callback === undefined || data === false)\r\n                callback = data, data = undefined\r\n\r\n            if (callback === false) callback = returnFalse\r\n\r\n            return $this.each(function(_, element){\r\n                if (one) autoRemove = function(e){\r\n                    remove(element, e.type, callback)\r\n                    return callback.apply(this, arguments)\r\n                }\r\n\r\n                if (selector) delegator = function(e){\r\n                    var evt, match = $(e.target).closest(selector, element).get(0)\r\n                    if (match && match !== element) {\r\n                        evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element})\r\n                        return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1)))\r\n                    }\r\n                }\r\n\r\n                add(element, event, callback, data, selector, delegator || autoRemove)\r\n            })\r\n        }\r\n        $.fn.off = function(event, selector, callback){\r\n            var $this = this\r\n            if (event && !isString(event)) {\r\n                $.each(event, function(type, fn){\r\n                    $this.off(type, selector, fn)\r\n                })\r\n                return $this\r\n            }\r\n\r\n            if (!isString(selector) && !isFunction(callback) && callback !== false)\r\n                callback = selector, selector = undefined\r\n\r\n            if (callback === false) callback = returnFalse\r\n\r\n            return $this.each(function(){\r\n                remove(this, event, callback, selector)\r\n            })\r\n        }\r\n\r\n        $.fn.trigger = function(event, args){\r\n            event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event)\r\n            event._args = args\r\n            return this.each(function(){\r\n                // handle focus(), blur() by calling them directly\r\n                if (event.type in focus && typeof this[event.type] == \"function\") this[event.type]()\r\n                // items in the collection might not be DOM elements\r\n                else if ('dispatchEvent' in this) this.dispatchEvent(event)\r\n                else $(this).triggerHandler(event, args)\r\n            })\r\n        }\r\n\r\n        // triggers event handlers on current element just as if an event occurred,\r\n        // doesn't trigger an actual event, doesn't bubble\r\n        $.fn.triggerHandler = function(event, args){\r\n            var e, result\r\n            this.each(function(i, element){\r\n                e = createProxy(isString(event) ? $.Event(event) : event)\r\n                e._args = args\r\n                e.target = element\r\n                $.each(findHandlers(element, event.type || event), function(i, handler){\r\n                    result = handler.proxy(e)\r\n                    if (e.isImmediatePropagationStopped()) return false\r\n                })\r\n            })\r\n            return result\r\n        }\r\n\r\n        // shortcut methods for `.bind(event, fn)` for each event type\r\n        ;('focusin focusout focus blur load resize scroll unload click dblclick '+\r\n        'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+\r\n        'change select keydown keypress keyup error').split(' ').forEach(function(event) {\r\n            $.fn[event] = function(callback) {\r\n                return (0 in arguments) ?\r\n                    this.bind(event, callback) :\r\n                    this.trigger(event)\r\n            }\r\n        })\r\n\r\n        $.Event = function(type, props) {\r\n            if (!isString(type)) props = type, type = props.type\r\n            var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true\r\n            if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name])\r\n            event.initEvent(type, bubbles, true)\r\n            return compatible(event)\r\n        }\r\n\r\n    })(Zepto)\r\n\r\n    ;(function($){\r\n        var jsonpID = +new Date(),\r\n            document = window.document,\r\n            key,\r\n            name,\r\n            rscript = /<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi,\r\n            scriptTypeRE = /^(?:text|application)\\/javascript/i,\r\n            xmlTypeRE = /^(?:text|application)\\/xml/i,\r\n            jsonType = 'application/json',\r\n            htmlType = 'text/html',\r\n            blankRE = /^\\s*$/,\r\n            originAnchor = document.createElement('a')\r\n\r\n        originAnchor.href = window.location.href\r\n\r\n        // trigger a custom event and return false if it was cancelled\r\n        function triggerAndReturn(context, eventName, data) {\r\n            var event = $.Event(eventName)\r\n            $(context).trigger(event, data)\r\n            return !event.isDefaultPrevented()\r\n        }\r\n\r\n        // trigger an Ajax \"global\" event\r\n        function triggerGlobal(settings, context, eventName, data) {\r\n            if (settings.global) return triggerAndReturn(context || document, eventName, data)\r\n        }\r\n\r\n        // Number of active Ajax requests\r\n        $.active = 0\r\n\r\n        function ajaxStart(settings) {\r\n            if (settings.global && $.active++ === 0) triggerGlobal(settings, null, 'ajaxStart')\r\n        }\r\n        function ajaxStop(settings) {\r\n            if (settings.global && !(--$.active)) triggerGlobal(settings, null, 'ajaxStop')\r\n        }\r\n\r\n        // triggers an extra global event \"ajaxBeforeSend\" that's like \"ajaxSend\" but cancelable\r\n        function ajaxBeforeSend(xhr, settings) {\r\n            var context = settings.context\r\n            if (settings.beforeSend.call(context, xhr, settings) === false ||\r\n                triggerGlobal(settings, context, 'ajaxBeforeSend', [xhr, settings]) === false)\r\n                return false\r\n\r\n            triggerGlobal(settings, context, 'ajaxSend', [xhr, settings])\r\n        }\r\n        function ajaxSuccess(data, xhr, settings, deferred) {\r\n            var context = settings.context, status = 'success'\r\n            settings.success.call(context, data, status, xhr)\r\n            if (deferred) deferred.resolveWith(context, [data, status, xhr])\r\n            triggerGlobal(settings, context, 'ajaxSuccess', [xhr, settings, data])\r\n            ajaxComplete(status, xhr, settings)\r\n        }\r\n        // type: \"timeout\", \"error\", \"abort\", \"parsererror\"\r\n        function ajaxError(error, type, xhr, settings, deferred) {\r\n            var context = settings.context\r\n            settings.error.call(context, xhr, type, error)\r\n            if (deferred) deferred.rejectWith(context, [xhr, type, error])\r\n            triggerGlobal(settings, context, 'ajaxError', [xhr, settings, error || type])\r\n            ajaxComplete(type, xhr, settings)\r\n        }\r\n        // status: \"success\", \"notmodified\", \"error\", \"timeout\", \"abort\", \"parsererror\"\r\n        function ajaxComplete(status, xhr, settings) {\r\n            var context = settings.context\r\n            settings.complete.call(context, xhr, status)\r\n            triggerGlobal(settings, context, 'ajaxComplete', [xhr, settings])\r\n            ajaxStop(settings)\r\n        }\r\n\r\n        function ajaxDataFilter(data, type, settings) {\r\n            if (settings.dataFilter == empty) return data\r\n            var context = settings.context\r\n            return settings.dataFilter.call(context, data, type)\r\n        }\r\n\r\n        // Empty function, used as default callback\r\n        function empty() {}\r\n\r\n        $.ajaxJSONP = function(options, deferred){\r\n            if (!('type' in options)) return $.ajax(options)\r\n\r\n            var _callbackName = options.jsonpCallback,\r\n                callbackName = ($.isFunction(_callbackName) ?\r\n                        _callbackName() : _callbackName) || ('Zepto' + (jsonpID++)),\r\n                script = document.createElement('script'),\r\n                originalCallback = window[callbackName],\r\n                responseData,\r\n                abort = function(errorType) {\r\n                    $(script).triggerHandler('error', errorType || 'abort')\r\n                },\r\n                xhr = { abort: abort }, abortTimeout\r\n\r\n            if (deferred) deferred.promise(xhr)\r\n\r\n            $(script).on('load error', function(e, errorType){\r\n                clearTimeout(abortTimeout)\r\n                $(script).off().remove()\r\n\r\n                if (e.type == 'error' || !responseData) {\r\n                    ajaxError(null, errorType || 'error', xhr, options, deferred)\r\n                } else {\r\n                    ajaxSuccess(responseData[0], xhr, options, deferred)\r\n                }\r\n\r\n                window[callbackName] = originalCallback\r\n                if (responseData && $.isFunction(originalCallback))\r\n                    originalCallback(responseData[0])\r\n\r\n                originalCallback = responseData = undefined\r\n            })\r\n\r\n            if (ajaxBeforeSend(xhr, options) === false) {\r\n                abort('abort')\r\n                return xhr\r\n            }\r\n\r\n            window[callbackName] = function(){\r\n                responseData = arguments\r\n            }\r\n\r\n            script.src = options.url.replace(/\\?(.+)=\\?/, '?$1=' + callbackName)\r\n            document.head.appendChild(script)\r\n\r\n            if (options.timeout > 0) abortTimeout = setTimeout(function(){\r\n                abort('timeout')\r\n            }, options.timeout)\r\n\r\n            return xhr\r\n        }\r\n\r\n        $.ajaxSettings = {\r\n            // Default type of request\r\n            type: 'GET',\r\n            // Callback that is executed before request\r\n            beforeSend: empty,\r\n            // Callback that is executed if the request succeeds\r\n            success: empty,\r\n            // Callback that is executed the the server drops error\r\n            error: empty,\r\n            // Callback that is executed on request complete (both: error and success)\r\n            complete: empty,\r\n            // The context for the callbacks\r\n            context: null,\r\n            // Whether to trigger \"global\" Ajax events\r\n            global: true,\r\n            // Transport\r\n            xhr: function () {\r\n                return new window.XMLHttpRequest()\r\n            },\r\n            // MIME types mapping\r\n            // IIS returns Javascript as \"application/x-javascript\"\r\n            accepts: {\r\n                script: 'text/javascript, application/javascript, application/x-javascript',\r\n                json:   jsonType,\r\n                xml:    'application/xml, text/xml',\r\n                html:   htmlType,\r\n                text:   'text/plain'\r\n            },\r\n            // Whether the request is to another domain\r\n            crossDomain: false,\r\n            // Default timeout\r\n            timeout: 0,\r\n            // Whether data should be serialized to string\r\n            processData: true,\r\n            // Whether the browser should be allowed to cache GET responses\r\n            cache: true,\r\n            //Used to handle the raw response data of XMLHttpRequest.\r\n            //This is a pre-filtering function to sanitize the response.\r\n            //The sanitized response should be returned\r\n            dataFilter: empty\r\n        }\r\n\r\n        function mimeToDataType(mime) {\r\n            if (mime) mime = mime.split(';', 2)[0]\r\n            return mime && ( mime == htmlType ? 'html' :\r\n                    mime == jsonType ? 'json' :\r\n                        scriptTypeRE.test(mime) ? 'script' :\r\n                        xmlTypeRE.test(mime) && 'xml' ) || 'text'\r\n        }\r\n\r\n        function appendQuery(url, query) {\r\n            if (query == '') return url\r\n            return (url + '&' + query).replace(/[&?]{1,2}/, '?')\r\n        }\r\n\r\n        // serialize payload and append it to the URL for GET requests\r\n        function serializeData(options) {\r\n            if (options.processData && options.data && $.type(options.data) != \"string\")\r\n                options.data = $.param(options.data, options.traditional)\r\n            if (options.data && (!options.type || options.type.toUpperCase() == 'GET' || 'jsonp' == options.dataType))\r\n                options.url = appendQuery(options.url, options.data), options.data = undefined\r\n        }\r\n\r\n        $.ajax = function(options){\r\n            var settings = $.extend({}, options || {}),\r\n                deferred = $.Deferred && $.Deferred(),\r\n                urlAnchor, hashIndex\r\n            for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key]\r\n\r\n            ajaxStart(settings)\r\n\r\n            if (!settings.crossDomain) {\r\n                urlAnchor = document.createElement('a')\r\n                urlAnchor.href = settings.url\r\n                // cleans up URL for .href (IE only), see https://github.com/madrobby/zepto/pull/1049\r\n                urlAnchor.href = urlAnchor.href\r\n                settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host)\r\n            }\r\n\r\n            if (!settings.url) settings.url = window.location.toString()\r\n            if ((hashIndex = settings.url.indexOf('#')) > -1) settings.url = settings.url.slice(0, hashIndex)\r\n            serializeData(settings)\r\n\r\n            var dataType = settings.dataType, hasPlaceholder = /\\?.+=\\?/.test(settings.url)\r\n            if (hasPlaceholder) dataType = 'jsonp'\r\n\r\n            if (settings.cache === false || (\r\n                    (!options || options.cache !== true) &&\r\n                    ('script' == dataType || 'jsonp' == dataType)\r\n                ))\r\n                settings.url = appendQuery(settings.url, '_=' + Date.now())\r\n\r\n            if ('jsonp' == dataType) {\r\n                if (!hasPlaceholder)\r\n                    settings.url = appendQuery(settings.url,\r\n                        settings.jsonp ? (settings.jsonp + '=?') : settings.jsonp === false ? '' : 'callback=?')\r\n                return $.ajaxJSONP(settings, deferred)\r\n            }\r\n\r\n            var mime = settings.accepts[dataType],\r\n                headers = { },\r\n                setHeader = function(name, value) { headers[name.toLowerCase()] = [name, value] },\r\n                protocol = /^([\\w-]+:)\\/\\//.test(settings.url) ? RegExp.$1 : window.location.protocol,\r\n                xhr = settings.xhr(),\r\n                nativeSetHeader = xhr.setRequestHeader,\r\n                abortTimeout\r\n\r\n            if (deferred) deferred.promise(xhr)\r\n\r\n            if (!settings.crossDomain) setHeader('X-Requested-With', 'XMLHttpRequest')\r\n            setHeader('Accept', mime || '*/*')\r\n            if (mime = settings.mimeType || mime) {\r\n                if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0]\r\n                xhr.overrideMimeType && xhr.overrideMimeType(mime)\r\n            }\r\n            if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET'))\r\n                setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded')\r\n\r\n            if (settings.headers) for (name in settings.headers) setHeader(name, settings.headers[name])\r\n            xhr.setRequestHeader = setHeader\r\n\r\n            xhr.onreadystatechange = function(){\r\n                if (xhr.readyState == 4) {\r\n                    xhr.onreadystatechange = empty\r\n                    clearTimeout(abortTimeout)\r\n                    var result, error = false\r\n                    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) {\r\n                        dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type'))\r\n\r\n                        if (xhr.responseType == 'arraybuffer' || xhr.responseType == 'blob')\r\n                            result = xhr.response\r\n                        else {\r\n                            result = xhr.responseText\r\n\r\n                            try {\r\n                                // http://perfectionkills.com/global-eval-what-are-the-options/\r\n                                // sanitize response accordingly if data filter callback provided\r\n                                result = ajaxDataFilter(result, dataType, settings)\r\n                                if (dataType == 'script')    (1,eval)(result)\r\n                                else if (dataType == 'xml')  result = xhr.responseXML\r\n                                else if (dataType == 'json') result = blankRE.test(result) ? null : $.parseJSON(result)\r\n                            } catch (e) { error = e }\r\n\r\n                            if (error) return ajaxError(error, 'parsererror', xhr, settings, deferred)\r\n                        }\r\n\r\n                        ajaxSuccess(result, xhr, settings, deferred)\r\n                    } else {\r\n                        ajaxError(xhr.statusText || null, xhr.status ? 'error' : 'abort', xhr, settings, deferred)\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (ajaxBeforeSend(xhr, settings) === false) {\r\n                xhr.abort()\r\n                ajaxError(null, 'abort', xhr, settings, deferred)\r\n                return xhr\r\n            }\r\n\r\n            var async = 'async' in settings ? settings.async : true\r\n            xhr.open(settings.type, settings.url, async, settings.username, settings.password)\r\n\r\n            if (settings.xhrFields) for (name in settings.xhrFields) xhr[name] = settings.xhrFields[name]\r\n\r\n            for (name in headers) nativeSetHeader.apply(xhr, headers[name])\r\n\r\n            if (settings.timeout > 0) abortTimeout = setTimeout(function(){\r\n                xhr.onreadystatechange = empty\r\n                xhr.abort()\r\n                ajaxError(null, 'timeout', xhr, settings, deferred)\r\n            }, settings.timeout)\r\n\r\n            // avoid sending empty string (#319)\r\n            xhr.send(settings.data ? settings.data : null)\r\n            return xhr\r\n        }\r\n\r\n        // handle optional data/success arguments\r\n        function parseArguments(url, data, success, dataType) {\r\n            if ($.isFunction(data)) dataType = success, success = data, data = undefined\r\n            if (!$.isFunction(success)) dataType = success, success = undefined\r\n            return {\r\n                url: url\r\n                , data: data\r\n                , success: success\r\n                , dataType: dataType\r\n            }\r\n        }\r\n\r\n        $.get = function(/* url, data, success, dataType */){\r\n            return $.ajax(parseArguments.apply(null, arguments))\r\n        }\r\n\r\n        $.post = function(/* url, data, success, dataType */){\r\n            var options = parseArguments.apply(null, arguments)\r\n            options.type = 'POST'\r\n            return $.ajax(options)\r\n        }\r\n\r\n        $.getJSON = function(/* url, data, success */){\r\n            var options = parseArguments.apply(null, arguments)\r\n            options.dataType = 'json'\r\n            return $.ajax(options)\r\n        }\r\n\r\n        $.fn.load = function(url, data, success){\r\n            if (!this.length) return this\r\n            var self = this, parts = url.split(/\\s/), selector,\r\n                options = parseArguments(url, data, success),\r\n                callback = options.success\r\n            if (parts.length > 1) options.url = parts[0], selector = parts[1]\r\n            options.success = function(response){\r\n                self.html(selector ?\r\n                    $('<div>').html(response.replace(rscript, \"\")).find(selector)\r\n                    : response)\r\n                callback && callback.apply(self, arguments)\r\n            }\r\n            $.ajax(options)\r\n            return this\r\n        }\r\n\r\n        var escape = encodeURIComponent\r\n\r\n        function serialize(params, obj, traditional, scope){\r\n            var type, array = $.isArray(obj), hash = $.isPlainObject(obj)\r\n            $.each(obj, function(key, value) {\r\n                type = $.type(value)\r\n                if (scope) key = traditional ? scope :\r\n                scope + '[' + (hash || type == 'object' || type == 'array' ? key : '') + ']'\r\n                // handle data in serializeArray() format\r\n                if (!scope && array) params.add(value.name, value.value)\r\n                // recurse into nested objects\r\n                else if (type == \"array\" || (!traditional && type == \"object\"))\r\n                    serialize(params, value, traditional, key)\r\n                else params.add(key, value)\r\n            })\r\n        }\r\n\r\n        $.param = function(obj, traditional){\r\n            var params = []\r\n            params.add = function(key, value) {\r\n                if ($.isFunction(value)) value = value()\r\n                if (value == null) value = \"\"\r\n                this.push(escape(key) + '=' + escape(value))\r\n            }\r\n            serialize(params, obj, traditional)\r\n            return params.join('&').replace(/%20/g, '+')\r\n        }\r\n    })(Zepto)\r\n\r\n    ;(function($){\r\n        $.fn.serializeArray = function() {\r\n            var name, type, result = [],\r\n                add = function(value) {\r\n                    if (value.forEach) return value.forEach(add)\r\n                    result.push({ name: name, value: value })\r\n                }\r\n            if (this[0]) $.each(this[0].elements, function(_, field){\r\n                type = field.type, name = field.name\r\n                if (name && field.nodeName.toLowerCase() != 'fieldset' &&\r\n                    !field.disabled && type != 'submit' && type != 'reset' && type != 'button' && type != 'file' &&\r\n                    ((type != 'radio' && type != 'checkbox') || field.checked))\r\n                    add($(field).val())\r\n            })\r\n            return result\r\n        }\r\n\r\n        $.fn.serialize = function(){\r\n            var result = []\r\n            this.serializeArray().forEach(function(elm){\r\n                result.push(encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value))\r\n            })\r\n            return result.join('&')\r\n        }\r\n\r\n        $.fn.submit = function(callback) {\r\n            if (0 in arguments) this.bind('submit', callback)\r\n            else if (this.length) {\r\n                var event = $.Event('submit')\r\n                this.eq(0).trigger(event)\r\n                if (!event.isDefaultPrevented()) this.get(0).submit()\r\n            }\r\n            return this\r\n        }\r\n\r\n    })(Zepto)\r\n\r\n    ;(function(){\r\n        // getComputedStyle shouldn't freak out when called\r\n        // without a valid element as argument\r\n        try {\r\n            getComputedStyle(undefined)\r\n        } catch(e) {\r\n            var nativeGetComputedStyle = getComputedStyle\r\n            window.getComputedStyle = function(element, pseudoElement){\r\n                try {\r\n                    return nativeGetComputedStyle(element, pseudoElement)\r\n                } catch(e) {\r\n                    return null\r\n                }\r\n            }\r\n        }\r\n    })()\r\n    return Zepto\r\n}))\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L24temVwdG8vbi16ZXB0by5qcz8xMTExIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzREFBMkIseUJBQXlCO0FBQ3BEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLGlCQUFpQjtBQUNoRCx5QkFBeUIsNEdBQTRHO0FBQ3JJO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0I7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsaUNBQWlDOztBQUVqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxvQ0FBb0M7QUFDcEMsb0NBQW9DO0FBQ3BDLG9DQUFvQztBQUNwQyxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGlDQUFpQywwQ0FBMEMsc0JBQXNCO0FBQ2pHLGlDQUFpQztBQUNqQyxpQ0FBaUMsb0RBQW9ELHNDQUFzQztBQUMzSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQiwrQ0FBK0Msb0NBQW9DOztBQUVsSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RCxzQ0FBc0M7QUFDL0Y7O0FBRUE7QUFDQTtBQUNBLHVCQUF1QixTQUFTO0FBQ2hDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1Qyw0QkFBNEI7QUFDbkU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNB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QWlCO0FBQ2pCLGFBQWE7QUFDYjtBQUNBOztBQUVBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLOztBQUVMLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakIsdUJBQXVCLGVBQWU7O0FBRXRDOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMENBQTBDO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHFEQUFxRCxJQUFJO0FBQ3pEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esc0NBQXNDLGVBQWU7QUFDckQ7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMkJBQTJCLEVBQUU7QUFDN0IsbURBQW1ELDhDQUE4QztBQUNqRztBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsWUFBWTs7QUFFekM7QUFDQTs7QUFFQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsMkJBQTJCO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSzs7QUFFTCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxDQUFDIiwiZmlsZSI6IjIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBaZXB0byB2MS4yLjAgLSB6ZXB0byBldmVudCBhamF4IGZvcm0gaWUgLSB6ZXB0b2pzLmNvbS9saWNlbnNlICovXHJcbihmdW5jdGlvbihnbG9iYWwsIGZhY3RvcnkpIHtcclxuICAgIGlmKGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShnbG9iYWwpXHJcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKVxyXG4gICAgICAgIGRlZmluZShmdW5jdGlvbigpIHsgcmV0dXJuIGZhY3RvcnkoZ2xvYmFsKSB9KVxyXG4gICAgZWxzZVxyXG4gICAgICAgIGZhY3RvcnkoZ2xvYmFsKVxyXG59KCB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogdGhpcywgZnVuY3Rpb24od2luZG93KSB7XHJcbiAgICB2YXIgWmVwdG8gPSAoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgdmFyIHVuZGVmaW5lZCwga2V5LCAkLCBjbGFzc0xpc3QsIGVtcHR5QXJyYXkgPSBbXSwgY29uY2F0ID0gZW1wdHlBcnJheS5jb25jYXQsIGZpbHRlciA9IGVtcHR5QXJyYXkuZmlsdGVyLCBzbGljZSA9IGVtcHR5QXJyYXkuc2xpY2UsXHJcbiAgICAgICAgICAgIGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50LFxyXG4gICAgICAgICAgICBlbGVtZW50RGlzcGxheSA9IHt9LCBjbGFzc0NhY2hlID0ge30sXHJcbiAgICAgICAgICAgIGNzc051bWJlciA9IHsgJ2NvbHVtbi1jb3VudCc6IDEsICdjb2x1bW5zJzogMSwgJ2ZvbnQtd2VpZ2h0JzogMSwgJ2xpbmUtaGVpZ2h0JzogMSwnb3BhY2l0eSc6IDEsICd6LWluZGV4JzogMSwgJ3pvb20nOiAxIH0sXHJcbiAgICAgICAgICAgIGZyYWdtZW50UkUgPSAvXlxccyo8KFxcdyt8ISlbXj5dKj4vLFxyXG4gICAgICAgICAgICBzaW5nbGVUYWdSRSA9IC9ePChcXHcrKVxccypcXC8/Pig/OjxcXC9cXDE+fCkkLyxcclxuICAgICAgICAgICAgdGFnRXhwYW5kZXJSRSA9IC88KD8hYXJlYXxicnxjb2x8ZW1iZWR8aHJ8aW1nfGlucHV0fGxpbmt8bWV0YXxwYXJhbSkoKFtcXHc6XSspW14+XSopXFwvPi9pZyxcclxuICAgICAgICAgICAgcm9vdE5vZGVSRSA9IC9eKD86Ym9keXxodG1sKSQvaSxcclxuICAgICAgICAgICAgY2FwaXRhbFJFID0gLyhbQS1aXSkvZyxcclxuXHJcbiAgICAgICAgICAgIC8vIHNwZWNpYWwgYXR0cmlidXRlcyB0aGF0IHNob3VsZCBiZSBnZXQvc2V0IHZpYSBtZXRob2QgY2FsbHNcclxuICAgICAgICAgICAgbWV0aG9kQXR0cmlidXRlcyA9IFsndmFsJywgJ2NzcycsICdodG1sJywgJ3RleHQnLCAnZGF0YScsICd3aWR0aCcsICdoZWlnaHQnLCAnb2Zmc2V0J10sXHJcblxyXG4gICAgICAgICAgICBhZGphY2VuY3lPcGVyYXRvcnMgPSBbICdhZnRlcicsICdwcmVwZW5kJywgJ2JlZm9yZScsICdhcHBlbmQnIF0sXHJcbiAgICAgICAgICAgIHRhYmxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGFibGUnKSxcclxuICAgICAgICAgICAgdGFibGVSb3cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0cicpLFxyXG4gICAgICAgICAgICBjb250YWluZXJzID0ge1xyXG4gICAgICAgICAgICAgICAgJ3RyJzogZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGJvZHknKSxcclxuICAgICAgICAgICAgICAgICd0Ym9keSc6IHRhYmxlLCAndGhlYWQnOiB0YWJsZSwgJ3Rmb290JzogdGFibGUsXHJcbiAgICAgICAgICAgICAgICAndGQnOiB0YWJsZVJvdywgJ3RoJzogdGFibGVSb3csXHJcbiAgICAgICAgICAgICAgICAnKic6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHJlYWR5UkUgPSAvY29tcGxldGV8bG9hZGVkfGludGVyYWN0aXZlLyxcclxuICAgICAgICAgICAgc2ltcGxlU2VsZWN0b3JSRSA9IC9eW1xcdy1dKiQvLFxyXG4gICAgICAgICAgICBjbGFzczJ0eXBlID0ge30sXHJcbiAgICAgICAgICAgIHRvU3RyaW5nID0gY2xhc3MydHlwZS50b1N0cmluZyxcclxuICAgICAgICAgICAgemVwdG8gPSB7fSxcclxuICAgICAgICAgICAgY2FtZWxpemUsIHVuaXEsXHJcbiAgICAgICAgICAgIHRlbXBQYXJlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSxcclxuICAgICAgICAgICAgcHJvcE1hcCA9IHtcclxuICAgICAgICAgICAgICAgICd0YWJpbmRleCc6ICd0YWJJbmRleCcsXHJcbiAgICAgICAgICAgICAgICAncmVhZG9ubHknOiAncmVhZE9ubHknLFxyXG4gICAgICAgICAgICAgICAgJ2Zvcic6ICdodG1sRm9yJyxcclxuICAgICAgICAgICAgICAgICdjbGFzcyc6ICdjbGFzc05hbWUnLFxyXG4gICAgICAgICAgICAgICAgJ21heGxlbmd0aCc6ICdtYXhMZW5ndGgnLFxyXG4gICAgICAgICAgICAgICAgJ2NlbGxzcGFjaW5nJzogJ2NlbGxTcGFjaW5nJyxcclxuICAgICAgICAgICAgICAgICdjZWxscGFkZGluZyc6ICdjZWxsUGFkZGluZycsXHJcbiAgICAgICAgICAgICAgICAncm93c3Bhbic6ICdyb3dTcGFuJyxcclxuICAgICAgICAgICAgICAgICdjb2xzcGFuJzogJ2NvbFNwYW4nLFxyXG4gICAgICAgICAgICAgICAgJ3VzZW1hcCc6ICd1c2VNYXAnLFxyXG4gICAgICAgICAgICAgICAgJ2ZyYW1lYm9yZGVyJzogJ2ZyYW1lQm9yZGVyJyxcclxuICAgICAgICAgICAgICAgICdjb250ZW50ZWRpdGFibGUnOiAnY29udGVudEVkaXRhYmxlJ1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fFxyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24ob2JqZWN0KXsgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIEFycmF5IH1cclxuXHJcbiAgICAgICAgemVwdG8ubWF0Y2hlcyA9IGZ1bmN0aW9uKGVsZW1lbnQsIHNlbGVjdG9yKSB7XHJcbiAgICAgICAgICAgIGlmICghc2VsZWN0b3IgfHwgIWVsZW1lbnQgfHwgZWxlbWVudC5ub2RlVHlwZSAhPT0gMSkgcmV0dXJuIGZhbHNlXHJcbiAgICAgICAgICAgIHZhciBtYXRjaGVzU2VsZWN0b3IgPSBlbGVtZW50Lm1hdGNoZXMgfHwgZWxlbWVudC53ZWJraXRNYXRjaGVzU2VsZWN0b3IgfHxcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQubW96TWF0Y2hlc1NlbGVjdG9yIHx8IGVsZW1lbnQub01hdGNoZXNTZWxlY3RvciB8fFxyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5tYXRjaGVzU2VsZWN0b3JcclxuICAgICAgICAgICAgaWYgKG1hdGNoZXNTZWxlY3RvcikgcmV0dXJuIG1hdGNoZXNTZWxlY3Rvci5jYWxsKGVsZW1lbnQsIHNlbGVjdG9yKVxyXG4gICAgICAgICAgICAvLyBmYWxsIGJhY2sgdG8gcGVyZm9ybWluZyBhIHNlbGVjdG9yOlxyXG4gICAgICAgICAgICB2YXIgbWF0Y2gsIHBhcmVudCA9IGVsZW1lbnQucGFyZW50Tm9kZSwgdGVtcCA9ICFwYXJlbnRcclxuICAgICAgICAgICAgaWYgKHRlbXApIChwYXJlbnQgPSB0ZW1wUGFyZW50KS5hcHBlbmRDaGlsZChlbGVtZW50KVxyXG4gICAgICAgICAgICBtYXRjaCA9IH56ZXB0by5xc2EocGFyZW50LCBzZWxlY3RvcikuaW5kZXhPZihlbGVtZW50KVxyXG4gICAgICAgICAgICB0ZW1wICYmIHRlbXBQYXJlbnQucmVtb3ZlQ2hpbGQoZWxlbWVudClcclxuICAgICAgICAgICAgcmV0dXJuIG1hdGNoXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiB0eXBlKG9iaikge1xyXG4gICAgICAgICAgICByZXR1cm4gb2JqID09IG51bGwgPyBTdHJpbmcob2JqKSA6XHJcbiAgICAgICAgICAgIGNsYXNzMnR5cGVbdG9TdHJpbmcuY2FsbChvYmopXSB8fCBcIm9iamVjdFwiXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7IHJldHVybiB0eXBlKHZhbHVlKSA9PSBcImZ1bmN0aW9uXCIgfVxyXG4gICAgICAgIGZ1bmN0aW9uIGlzV2luZG93KG9iaikgICAgIHsgcmV0dXJuIG9iaiAhPSBudWxsICYmIG9iaiA9PSBvYmoud2luZG93IH1cclxuICAgICAgICBmdW5jdGlvbiBpc0RvY3VtZW50KG9iaikgICB7IHJldHVybiBvYmogIT0gbnVsbCAmJiBvYmoubm9kZVR5cGUgPT0gb2JqLkRPQ1VNRU5UX05PREUgfVxyXG4gICAgICAgIGZ1bmN0aW9uIGlzT2JqZWN0KG9iaikgICAgIHsgcmV0dXJuIHR5cGUob2JqKSA9PSBcIm9iamVjdFwiIH1cclxuICAgICAgICBmdW5jdGlvbiBpc1BsYWluT2JqZWN0KG9iaikge1xyXG4gICAgICAgICAgICByZXR1cm4gaXNPYmplY3Qob2JqKSAmJiAhaXNXaW5kb3cob2JqKSAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKSA9PSBPYmplY3QucHJvdG90eXBlXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiBsaWtlQXJyYXkob2JqKSB7XHJcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSAhIW9iaiAmJiAnbGVuZ3RoJyBpbiBvYmogJiYgb2JqLmxlbmd0aCxcclxuICAgICAgICAgICAgICAgIHR5cGUgPSAkLnR5cGUob2JqKVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuICdmdW5jdGlvbicgIT0gdHlwZSAmJiAhaXNXaW5kb3cob2JqKSAmJiAoXHJcbiAgICAgICAgICAgICAgICAgICAgJ2FycmF5JyA9PSB0eXBlIHx8IGxlbmd0aCA9PT0gMCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICh0eXBlb2YgbGVuZ3RoID09ICdudW1iZXInICYmIGxlbmd0aCA+IDAgJiYgKGxlbmd0aCAtIDEpIGluIG9iailcclxuICAgICAgICAgICAgICAgIClcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGNvbXBhY3QoYXJyYXkpIHsgcmV0dXJuIGZpbHRlci5jYWxsKGFycmF5LCBmdW5jdGlvbihpdGVtKXsgcmV0dXJuIGl0ZW0gIT0gbnVsbCB9KSB9XHJcbiAgICAgICAgZnVuY3Rpb24gZmxhdHRlbihhcnJheSkgeyByZXR1cm4gYXJyYXkubGVuZ3RoID4gMCA/ICQuZm4uY29uY2F0LmFwcGx5KFtdLCBhcnJheSkgOiBhcnJheSB9XHJcbiAgICAgICAgY2FtZWxpemUgPSBmdW5jdGlvbihzdHIpeyByZXR1cm4gc3RyLnJlcGxhY2UoLy0rKC4pPy9nLCBmdW5jdGlvbihtYXRjaCwgY2hyKXsgcmV0dXJuIGNociA/IGNoci50b1VwcGVyQ2FzZSgpIDogJycgfSkgfVxyXG4gICAgICAgIGZ1bmN0aW9uIGRhc2hlcml6ZShzdHIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKC86Oi9nLCAnLycpXHJcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgvKFtBLVpdKykoW0EtWl1bYS16XSkvZywgJyQxXyQyJylcclxuICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oW2EtelxcZF0pKFtBLVpdKS9nLCAnJDFfJDInKVxyXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoL18vZywgJy0nKVxyXG4gICAgICAgICAgICAgICAgLnRvTG93ZXJDYXNlKClcclxuICAgICAgICB9XHJcbiAgICAgICAgdW5pcSA9IGZ1bmN0aW9uKGFycmF5KXsgcmV0dXJuIGZpbHRlci5jYWxsKGFycmF5LCBmdW5jdGlvbihpdGVtLCBpZHgpeyByZXR1cm4gYXJyYXkuaW5kZXhPZihpdGVtKSA9PSBpZHggfSkgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiBjbGFzc1JFKG5hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5hbWUgaW4gY2xhc3NDYWNoZSA/XHJcbiAgICAgICAgICAgICAgICBjbGFzc0NhY2hlW25hbWVdIDogKGNsYXNzQ2FjaGVbbmFtZV0gPSBuZXcgUmVnRXhwKCcoXnxcXFxccyknICsgbmFtZSArICcoXFxcXHN8JCknKSlcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIG1heWJlQWRkUHgobmFtZSwgdmFsdWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuICh0eXBlb2YgdmFsdWUgPT0gXCJudW1iZXJcIiAmJiAhY3NzTnVtYmVyW2Rhc2hlcml6ZShuYW1lKV0pID8gdmFsdWUgKyBcInB4XCIgOiB2YWx1ZVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gZGVmYXVsdERpc3BsYXkobm9kZU5hbWUpIHtcclxuICAgICAgICAgICAgdmFyIGVsZW1lbnQsIGRpc3BsYXlcclxuICAgICAgICAgICAgaWYgKCFlbGVtZW50RGlzcGxheVtub2RlTmFtZV0pIHtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KG5vZGVOYW1lKVxyXG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChlbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgZGlzcGxheSA9IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCwgJycpLmdldFByb3BlcnR5VmFsdWUoXCJkaXNwbGF5XCIpXHJcbiAgICAgICAgICAgICAgICBlbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWxlbWVudClcclxuICAgICAgICAgICAgICAgIGRpc3BsYXkgPT0gXCJub25lXCIgJiYgKGRpc3BsYXkgPSBcImJsb2NrXCIpXHJcbiAgICAgICAgICAgICAgICBlbGVtZW50RGlzcGxheVtub2RlTmFtZV0gPSBkaXNwbGF5XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnREaXNwbGF5W25vZGVOYW1lXVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gY2hpbGRyZW4oZWxlbWVudCkge1xyXG4gICAgICAgICAgICByZXR1cm4gJ2NoaWxkcmVuJyBpbiBlbGVtZW50ID9cclxuICAgICAgICAgICAgICAgIHNsaWNlLmNhbGwoZWxlbWVudC5jaGlsZHJlbikgOlxyXG4gICAgICAgICAgICAgICAgJC5tYXAoZWxlbWVudC5jaGlsZE5vZGVzLCBmdW5jdGlvbihub2RlKXsgaWYgKG5vZGUubm9kZVR5cGUgPT0gMSkgcmV0dXJuIG5vZGUgfSlcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIFooZG9tLCBzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICB2YXIgaSwgbGVuID0gZG9tID8gZG9tLmxlbmd0aCA6IDBcclxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB0aGlzW2ldID0gZG9tW2ldXHJcbiAgICAgICAgICAgIHRoaXMubGVuZ3RoID0gbGVuXHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0b3IgPSBzZWxlY3RvciB8fCAnJ1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gYCQuemVwdG8uZnJhZ21lbnRgIHRha2VzIGEgaHRtbCBzdHJpbmcgYW5kIGFuIG9wdGlvbmFsIHRhZyBuYW1lXHJcbiAgICAgICAgLy8gdG8gZ2VuZXJhdGUgRE9NIG5vZGVzIGZyb20gdGhlIGdpdmVuIGh0bWwgc3RyaW5nLlxyXG4gICAgICAgIC8vIFRoZSBnZW5lcmF0ZWQgRE9NIG5vZGVzIGFyZSByZXR1cm5lZCBhcyBhbiBhcnJheS5cclxuICAgICAgICAvLyBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBvdmVycmlkZGVuIGluIHBsdWdpbnMgZm9yIGV4YW1wbGUgdG8gbWFrZVxyXG4gICAgICAgIC8vIGl0IGNvbXBhdGlibGUgd2l0aCBicm93c2VycyB0aGF0IGRvbid0IHN1cHBvcnQgdGhlIERPTSBmdWxseS5cclxuICAgICAgICB6ZXB0by5mcmFnbWVudCA9IGZ1bmN0aW9uKGh0bWwsIG5hbWUsIHByb3BlcnRpZXMpIHtcclxuICAgICAgICAgICAgdmFyIGRvbSwgbm9kZXMsIGNvbnRhaW5lclxyXG5cclxuICAgICAgICAgICAgLy8gQSBzcGVjaWFsIGNhc2Ugb3B0aW1pemF0aW9uIGZvciBhIHNpbmdsZSB0YWdcclxuICAgICAgICAgICAgaWYgKHNpbmdsZVRhZ1JFLnRlc3QoaHRtbCkpIGRvbSA9ICQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudChSZWdFeHAuJDEpKVxyXG5cclxuICAgICAgICAgICAgaWYgKCFkb20pIHtcclxuICAgICAgICAgICAgICAgIGlmIChodG1sLnJlcGxhY2UpIGh0bWwgPSBodG1sLnJlcGxhY2UodGFnRXhwYW5kZXJSRSwgXCI8JDE+PC8kMj5cIilcclxuICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSB1bmRlZmluZWQpIG5hbWUgPSBmcmFnbWVudFJFLnRlc3QoaHRtbCkgJiYgUmVnRXhwLiQxXHJcbiAgICAgICAgICAgICAgICBpZiAoIShuYW1lIGluIGNvbnRhaW5lcnMpKSBuYW1lID0gJyonXHJcblxyXG4gICAgICAgICAgICAgICAgY29udGFpbmVyID0gY29udGFpbmVyc1tuYW1lXVxyXG4gICAgICAgICAgICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9ICcnICsgaHRtbFxyXG4gICAgICAgICAgICAgICAgZG9tID0gJC5lYWNoKHNsaWNlLmNhbGwoY29udGFpbmVyLmNoaWxkTm9kZXMpLCBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDaGlsZCh0aGlzKVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGlzUGxhaW5PYmplY3QocHJvcGVydGllcykpIHtcclxuICAgICAgICAgICAgICAgIG5vZGVzID0gJChkb20pXHJcbiAgICAgICAgICAgICAgICAkLmVhY2gocHJvcGVydGllcywgZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChtZXRob2RBdHRyaWJ1dGVzLmluZGV4T2Yoa2V5KSA+IC0xKSBub2Rlc1trZXldKHZhbHVlKVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Ugbm9kZXMuYXR0cihrZXksIHZhbHVlKVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGRvbVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gYCQuemVwdG8uWmAgc3dhcHMgb3V0IHRoZSBwcm90b3R5cGUgb2YgdGhlIGdpdmVuIGBkb21gIGFycmF5XHJcbiAgICAgICAgLy8gb2Ygbm9kZXMgd2l0aCBgJC5mbmAgYW5kIHRodXMgc3VwcGx5aW5nIGFsbCB0aGUgWmVwdG8gZnVuY3Rpb25zXHJcbiAgICAgICAgLy8gdG8gdGhlIGFycmF5LiBUaGlzIG1ldGhvZCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBwbHVnaW5zLlxyXG4gICAgICAgIHplcHRvLlogPSBmdW5jdGlvbihkb20sIHNlbGVjdG9yKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgWihkb20sIHNlbGVjdG9yKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gYCQuemVwdG8uaXNaYCBzaG91bGQgcmV0dXJuIGB0cnVlYCBpZiB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgWmVwdG9cclxuICAgICAgICAvLyBjb2xsZWN0aW9uLiBUaGlzIG1ldGhvZCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBwbHVnaW5zLlxyXG4gICAgICAgIHplcHRvLmlzWiA9IGZ1bmN0aW9uKG9iamVjdCkge1xyXG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgemVwdG8uWlxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gYCQuemVwdG8uaW5pdGAgaXMgWmVwdG8ncyBjb3VudGVycGFydCB0byBqUXVlcnkncyBgJC5mbi5pbml0YCBhbmRcclxuICAgICAgICAvLyB0YWtlcyBhIENTUyBzZWxlY3RvciBhbmQgYW4gb3B0aW9uYWwgY29udGV4dCAoYW5kIGhhbmRsZXMgdmFyaW91c1xyXG4gICAgICAgIC8vIHNwZWNpYWwgY2FzZXMpLlxyXG4gICAgICAgIC8vIFRoaXMgbWV0aG9kIGNhbiBiZSBvdmVycmlkZGVuIGluIHBsdWdpbnMuXHJcbiAgICAgICAgemVwdG8uaW5pdCA9IGZ1bmN0aW9uKHNlbGVjdG9yLCBjb250ZXh0KSB7XHJcbiAgICAgICAgICAgIHZhciBkb21cclxuICAgICAgICAgICAgLy8gSWYgbm90aGluZyBnaXZlbiwgcmV0dXJuIGFuIGVtcHR5IFplcHRvIGNvbGxlY3Rpb25cclxuICAgICAgICAgICAgaWYgKCFzZWxlY3RvcikgcmV0dXJuIHplcHRvLlooKVxyXG4gICAgICAgICAgICAvLyBPcHRpbWl6ZSBmb3Igc3RyaW5nIHNlbGVjdG9yc1xyXG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygc2VsZWN0b3IgPT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgICAgIHNlbGVjdG9yID0gc2VsZWN0b3IudHJpbSgpXHJcbiAgICAgICAgICAgICAgICAvLyBJZiBpdCdzIGEgaHRtbCBmcmFnbWVudCwgY3JlYXRlIG5vZGVzIGZyb20gaXRcclxuICAgICAgICAgICAgICAgIC8vIE5vdGU6IEluIGJvdGggQ2hyb21lIDIxIGFuZCBGaXJlZm94IDE1LCBET00gZXJyb3IgMTJcclxuICAgICAgICAgICAgICAgIC8vIGlzIHRocm93biBpZiB0aGUgZnJhZ21lbnQgZG9lc24ndCBiZWdpbiB3aXRoIDxcclxuICAgICAgICAgICAgICAgIGlmIChzZWxlY3RvclswXSA9PSAnPCcgJiYgZnJhZ21lbnRSRS50ZXN0KHNlbGVjdG9yKSlcclxuICAgICAgICAgICAgICAgICAgICBkb20gPSB6ZXB0by5mcmFnbWVudChzZWxlY3RvciwgUmVnRXhwLiQxLCBjb250ZXh0KSwgc2VsZWN0b3IgPSBudWxsXHJcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGVyZSdzIGEgY29udGV4dCwgY3JlYXRlIGEgY29sbGVjdGlvbiBvbiB0aGF0IGNvbnRleHQgZmlyc3QsIGFuZCBzZWxlY3RcclxuICAgICAgICAgICAgICAgIC8vIG5vZGVzIGZyb20gdGhlcmVcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbnRleHQgIT09IHVuZGVmaW5lZCkgcmV0dXJuICQoY29udGV4dCkuZmluZChzZWxlY3RvcilcclxuICAgICAgICAgICAgICAgIC8vIElmIGl0J3MgYSBDU1Mgc2VsZWN0b3IsIHVzZSBpdCB0byBzZWxlY3Qgbm9kZXMuXHJcbiAgICAgICAgICAgICAgICBlbHNlIGRvbSA9IHplcHRvLnFzYShkb2N1bWVudCwgc2VsZWN0b3IpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gSWYgYSBmdW5jdGlvbiBpcyBnaXZlbiwgY2FsbCBpdCB3aGVuIHRoZSBET00gaXMgcmVhZHlcclxuICAgICAgICAgICAgZWxzZSBpZiAoaXNGdW5jdGlvbihzZWxlY3RvcikpIHJldHVybiAkKGRvY3VtZW50KS5yZWFkeShzZWxlY3RvcilcclxuICAgICAgICAgICAgLy8gSWYgYSBaZXB0byBjb2xsZWN0aW9uIGlzIGdpdmVuLCBqdXN0IHJldHVybiBpdFxyXG4gICAgICAgICAgICBlbHNlIGlmICh6ZXB0by5pc1ooc2VsZWN0b3IpKSByZXR1cm4gc2VsZWN0b3JcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBub3JtYWxpemUgYXJyYXkgaWYgYW4gYXJyYXkgb2Ygbm9kZXMgaXMgZ2l2ZW5cclxuICAgICAgICAgICAgICAgIGlmIChpc0FycmF5KHNlbGVjdG9yKSkgZG9tID0gY29tcGFjdChzZWxlY3RvcilcclxuICAgICAgICAgICAgICAgIC8vIFdyYXAgRE9NIG5vZGVzLlxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoaXNPYmplY3Qoc2VsZWN0b3IpKVxyXG4gICAgICAgICAgICAgICAgICAgIGRvbSA9IFtzZWxlY3Rvcl0sIHNlbGVjdG9yID0gbnVsbFxyXG4gICAgICAgICAgICAgICAgLy8gSWYgaXQncyBhIGh0bWwgZnJhZ21lbnQsIGNyZWF0ZSBub2RlcyBmcm9tIGl0XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChmcmFnbWVudFJFLnRlc3Qoc2VsZWN0b3IpKVxyXG4gICAgICAgICAgICAgICAgICAgIGRvbSA9IHplcHRvLmZyYWdtZW50KHNlbGVjdG9yLnRyaW0oKSwgUmVnRXhwLiQxLCBjb250ZXh0KSwgc2VsZWN0b3IgPSBudWxsXHJcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGVyZSdzIGEgY29udGV4dCwgY3JlYXRlIGEgY29sbGVjdGlvbiBvbiB0aGF0IGNvbnRleHQgZmlyc3QsIGFuZCBzZWxlY3RcclxuICAgICAgICAgICAgICAgIC8vIG5vZGVzIGZyb20gdGhlcmVcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbnRleHQgIT09IHVuZGVmaW5lZCkgcmV0dXJuICQoY29udGV4dCkuZmluZChzZWxlY3RvcilcclxuICAgICAgICAgICAgICAgIC8vIEFuZCBsYXN0IGJ1dCBubyBsZWFzdCwgaWYgaXQncyBhIENTUyBzZWxlY3RvciwgdXNlIGl0IHRvIHNlbGVjdCBub2Rlcy5cclxuICAgICAgICAgICAgICAgIGVsc2UgZG9tID0gemVwdG8ucXNhKGRvY3VtZW50LCBzZWxlY3RvcilcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBjcmVhdGUgYSBuZXcgWmVwdG8gY29sbGVjdGlvbiBmcm9tIHRoZSBub2RlcyBmb3VuZFxyXG4gICAgICAgICAgICByZXR1cm4gemVwdG8uWihkb20sIHNlbGVjdG9yKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gYCRgIHdpbGwgYmUgdGhlIGJhc2UgYFplcHRvYCBvYmplY3QuIFdoZW4gY2FsbGluZyB0aGlzXHJcbiAgICAgICAgLy8gZnVuY3Rpb24ganVzdCBjYWxsIGAkLnplcHRvLmluaXQsIHdoaWNoIG1ha2VzIHRoZSBpbXBsZW1lbnRhdGlvblxyXG4gICAgICAgIC8vIGRldGFpbHMgb2Ygc2VsZWN0aW5nIG5vZGVzIGFuZCBjcmVhdGluZyBaZXB0byBjb2xsZWN0aW9uc1xyXG4gICAgICAgIC8vIHBhdGNoYWJsZSBpbiBwbHVnaW5zLlxyXG4gICAgICAgICQgPSBmdW5jdGlvbihzZWxlY3RvciwgY29udGV4dCl7XHJcbiAgICAgICAgICAgIHJldHVybiB6ZXB0by5pbml0KHNlbGVjdG9yLCBjb250ZXh0KVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gZXh0ZW5kKHRhcmdldCwgc291cmNlLCBkZWVwKSB7XHJcbiAgICAgICAgICAgIGZvciAoa2V5IGluIHNvdXJjZSlcclxuICAgICAgICAgICAgICAgIGlmIChkZWVwICYmIChpc1BsYWluT2JqZWN0KHNvdXJjZVtrZXldKSB8fCBpc0FycmF5KHNvdXJjZVtrZXldKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNQbGFpbk9iamVjdChzb3VyY2Vba2V5XSkgJiYgIWlzUGxhaW5PYmplY3QodGFyZ2V0W2tleV0pKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRba2V5XSA9IHt9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXJyYXkoc291cmNlW2tleV0pICYmICFpc0FycmF5KHRhcmdldFtrZXldKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSBbXVxyXG4gICAgICAgICAgICAgICAgICAgIGV4dGVuZCh0YXJnZXRba2V5XSwgc291cmNlW2tleV0sIGRlZXApXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChzb3VyY2Vba2V5XSAhPT0gdW5kZWZpbmVkKSB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBDb3B5IGFsbCBidXQgdW5kZWZpbmVkIHByb3BlcnRpZXMgZnJvbSBvbmUgb3IgbW9yZVxyXG4gICAgICAgIC8vIG9iamVjdHMgdG8gdGhlIGB0YXJnZXRgIG9iamVjdC5cclxuICAgICAgICAkLmV4dGVuZCA9IGZ1bmN0aW9uKHRhcmdldCl7XHJcbiAgICAgICAgICAgIHZhciBkZWVwLCBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGFyZ2V0ID09ICdib29sZWFuJykge1xyXG4gICAgICAgICAgICAgICAgZGVlcCA9IHRhcmdldFxyXG4gICAgICAgICAgICAgICAgdGFyZ2V0ID0gYXJncy5zaGlmdCgpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYXJncy5mb3JFYWNoKGZ1bmN0aW9uKGFyZyl7IGV4dGVuZCh0YXJnZXQsIGFyZywgZGVlcCkgfSlcclxuICAgICAgICAgICAgcmV0dXJuIHRhcmdldFxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gYCQuemVwdG8ucXNhYCBpcyBaZXB0bydzIENTUyBzZWxlY3RvciBpbXBsZW1lbnRhdGlvbiB3aGljaFxyXG4gICAgICAgIC8vIHVzZXMgYGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGxgIGFuZCBvcHRpbWl6ZXMgZm9yIHNvbWUgc3BlY2lhbCBjYXNlcywgbGlrZSBgI2lkYC5cclxuICAgICAgICAvLyBUaGlzIG1ldGhvZCBjYW4gYmUgb3ZlcnJpZGRlbiBpbiBwbHVnaW5zLlxyXG4gICAgICAgIHplcHRvLnFzYSA9IGZ1bmN0aW9uKGVsZW1lbnQsIHNlbGVjdG9yKXtcclxuICAgICAgICAgICAgdmFyIGZvdW5kLFxyXG4gICAgICAgICAgICAgICAgbWF5YmVJRCA9IHNlbGVjdG9yWzBdID09ICcjJyxcclxuICAgICAgICAgICAgICAgIG1heWJlQ2xhc3MgPSAhbWF5YmVJRCAmJiBzZWxlY3RvclswXSA9PSAnLicsXHJcbiAgICAgICAgICAgICAgICBuYW1lT25seSA9IG1heWJlSUQgfHwgbWF5YmVDbGFzcyA/IHNlbGVjdG9yLnNsaWNlKDEpIDogc2VsZWN0b3IsIC8vIEVuc3VyZSB0aGF0IGEgMSBjaGFyIHRhZyBuYW1lIHN0aWxsIGdldHMgY2hlY2tlZFxyXG4gICAgICAgICAgICAgICAgaXNTaW1wbGUgPSBzaW1wbGVTZWxlY3RvclJFLnRlc3QobmFtZU9ubHkpXHJcbiAgICAgICAgICAgIHJldHVybiAoZWxlbWVudC5nZXRFbGVtZW50QnlJZCAmJiBpc1NpbXBsZSAmJiBtYXliZUlEKSA/IC8vIFNhZmFyaSBEb2N1bWVudEZyYWdtZW50IGRvZXNuJ3QgaGF2ZSBnZXRFbGVtZW50QnlJZFxyXG4gICAgICAgICAgICAgICAgKCAoZm91bmQgPSBlbGVtZW50LmdldEVsZW1lbnRCeUlkKG5hbWVPbmx5KSkgPyBbZm91bmRdIDogW10gKSA6XHJcbiAgICAgICAgICAgICAgICAoZWxlbWVudC5ub2RlVHlwZSAhPT0gMSAmJiBlbGVtZW50Lm5vZGVUeXBlICE9PSA5ICYmIGVsZW1lbnQubm9kZVR5cGUgIT09IDExKSA/IFtdIDpcclxuICAgICAgICAgICAgICAgICAgICBzbGljZS5jYWxsKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpc1NpbXBsZSAmJiAhbWF5YmVJRCAmJiBlbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgPyAvLyBEb2N1bWVudEZyYWdtZW50IGRvZXNuJ3QgaGF2ZSBnZXRFbGVtZW50c0J5Q2xhc3NOYW1lL1RhZ05hbWVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heWJlQ2xhc3MgPyBlbGVtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUobmFtZU9ubHkpIDogLy8gSWYgaXQncyBzaW1wbGUsIGl0IGNvdWxkIGJlIGEgY2xhc3NcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKHNlbGVjdG9yKSA6IC8vIE9yIGEgdGFnXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpIC8vIE9yIGl0J3Mgbm90IHNpbXBsZSwgYW5kIHdlIG5lZWQgdG8gcXVlcnkgYWxsXHJcbiAgICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gZmlsdGVyZWQobm9kZXMsIHNlbGVjdG9yKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBzZWxlY3RvciA9PSBudWxsID8gJChub2RlcykgOiAkKG5vZGVzKS5maWx0ZXIoc2VsZWN0b3IpXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAkLmNvbnRhaW5zID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNvbnRhaW5zID9cclxuICAgICAgICAgICAgZnVuY3Rpb24ocGFyZW50LCBub2RlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50ICE9PSBub2RlICYmIHBhcmVudC5jb250YWlucyhub2RlKVxyXG4gICAgICAgICAgICB9IDpcclxuICAgICAgICAgICAgZnVuY3Rpb24ocGFyZW50LCBub2RlKSB7XHJcbiAgICAgICAgICAgICAgICB3aGlsZSAobm9kZSAmJiAobm9kZSA9IG5vZGUucGFyZW50Tm9kZSkpXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUgPT09IHBhcmVudCkgcmV0dXJuIHRydWVcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bmNBcmcoY29udGV4dCwgYXJnLCBpZHgsIHBheWxvYWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGlzRnVuY3Rpb24oYXJnKSA/IGFyZy5jYWxsKGNvbnRleHQsIGlkeCwgcGF5bG9hZCkgOiBhcmdcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHNldEF0dHJpYnV0ZShub2RlLCBuYW1lLCB2YWx1ZSkge1xyXG4gICAgICAgICAgICB2YWx1ZSA9PSBudWxsID8gbm9kZS5yZW1vdmVBdHRyaWJ1dGUobmFtZSkgOiBub2RlLnNldEF0dHJpYnV0ZShuYW1lLCB2YWx1ZSlcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGFjY2VzcyBjbGFzc05hbWUgcHJvcGVydHkgd2hpbGUgcmVzcGVjdGluZyBTVkdBbmltYXRlZFN0cmluZ1xyXG4gICAgICAgIGZ1bmN0aW9uIGNsYXNzTmFtZShub2RlLCB2YWx1ZSl7XHJcbiAgICAgICAgICAgIHZhciBrbGFzcyA9IG5vZGUuY2xhc3NOYW1lIHx8ICcnLFxyXG4gICAgICAgICAgICAgICAgc3ZnICAgPSBrbGFzcyAmJiBrbGFzcy5iYXNlVmFsICE9PSB1bmRlZmluZWRcclxuXHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gc3ZnID8ga2xhc3MuYmFzZVZhbCA6IGtsYXNzXHJcbiAgICAgICAgICAgIHN2ZyA/IChrbGFzcy5iYXNlVmFsID0gdmFsdWUpIDogKG5vZGUuY2xhc3NOYW1lID0gdmFsdWUpXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBcInRydWVcIiAgPT4gdHJ1ZVxyXG4gICAgICAgIC8vIFwiZmFsc2VcIiA9PiBmYWxzZVxyXG4gICAgICAgIC8vIFwibnVsbFwiICA9PiBudWxsXHJcbiAgICAgICAgLy8gXCI0MlwiICAgID0+IDQyXHJcbiAgICAgICAgLy8gXCI0Mi41XCIgID0+IDQyLjVcclxuICAgICAgICAvLyBcIjA4XCIgICAgPT4gXCIwOFwiXHJcbiAgICAgICAgLy8gSlNPTiAgICA9PiBwYXJzZSBpZiB2YWxpZFxyXG4gICAgICAgIC8vIFN0cmluZyAgPT4gc2VsZlxyXG4gICAgICAgIGZ1bmN0aW9uIGRlc2VyaWFsaXplVmFsdWUodmFsdWUpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZSA/XHJcbiAgICAgICAgICAgICAgICB2YWx1ZSA9PSBcInRydWVcIiB8fFxyXG4gICAgICAgICAgICAgICAgKCB2YWx1ZSA9PSBcImZhbHNlXCIgPyBmYWxzZSA6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPT0gXCJudWxsXCIgPyBudWxsIDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgK3ZhbHVlICsgXCJcIiA9PSB2YWx1ZSA/ICt2YWx1ZSA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvXltcXFtcXHtdLy50ZXN0KHZhbHVlKSA/ICQucGFyc2VKU09OKHZhbHVlKSA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgKVxyXG4gICAgICAgICAgICAgICAgICAgIDogdmFsdWVcclxuICAgICAgICAgICAgfSBjYXRjaChlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgJC50eXBlID0gdHlwZVxyXG4gICAgICAgICQuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb25cclxuICAgICAgICAkLmlzV2luZG93ID0gaXNXaW5kb3dcclxuICAgICAgICAkLmlzQXJyYXkgPSBpc0FycmF5XHJcbiAgICAgICAgJC5pc1BsYWluT2JqZWN0ID0gaXNQbGFpbk9iamVjdFxyXG5cclxuICAgICAgICAkLmlzRW1wdHlPYmplY3QgPSBmdW5jdGlvbihvYmopIHtcclxuICAgICAgICAgICAgdmFyIG5hbWVcclxuICAgICAgICAgICAgZm9yIChuYW1lIGluIG9iaikgcmV0dXJuIGZhbHNlXHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAkLmlzTnVtZXJpYyA9IGZ1bmN0aW9uKHZhbCkge1xyXG4gICAgICAgICAgICB2YXIgbnVtID0gTnVtYmVyKHZhbCksIHR5cGUgPSB0eXBlb2YgdmFsXHJcbiAgICAgICAgICAgIHJldHVybiB2YWwgIT0gbnVsbCAmJiB0eXBlICE9ICdib29sZWFuJyAmJlxyXG4gICAgICAgICAgICAgICAgKHR5cGUgIT0gJ3N0cmluZycgfHwgdmFsLmxlbmd0aCkgJiZcclxuICAgICAgICAgICAgICAgICFpc05hTihudW0pICYmIGlzRmluaXRlKG51bSkgfHwgZmFsc2VcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgICQuaW5BcnJheSA9IGZ1bmN0aW9uKGVsZW0sIGFycmF5LCBpKXtcclxuICAgICAgICAgICAgcmV0dXJuIGVtcHR5QXJyYXkuaW5kZXhPZi5jYWxsKGFycmF5LCBlbGVtLCBpKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgJC5jYW1lbENhc2UgPSBjYW1lbGl6ZVxyXG4gICAgICAgICQudHJpbSA9IGZ1bmN0aW9uKHN0cikge1xyXG4gICAgICAgICAgICByZXR1cm4gc3RyID09IG51bGwgPyBcIlwiIDogU3RyaW5nLnByb3RvdHlwZS50cmltLmNhbGwoc3RyKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcGx1Z2luIGNvbXBhdGliaWxpdHlcclxuICAgICAgICAkLnV1aWQgPSAwXHJcbiAgICAgICAgJC5zdXBwb3J0ID0geyB9XHJcbiAgICAgICAgJC5leHByID0geyB9XHJcbiAgICAgICAgJC5ub29wID0gZnVuY3Rpb24oKSB7fVxyXG5cclxuICAgICAgICAkLm1hcCA9IGZ1bmN0aW9uKGVsZW1lbnRzLCBjYWxsYmFjayl7XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZSwgdmFsdWVzID0gW10sIGksIGtleVxyXG4gICAgICAgICAgICBpZiAobGlrZUFycmF5KGVsZW1lbnRzKSlcclxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gY2FsbGJhY2soZWxlbWVudHNbaV0sIGkpXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHZhbHVlcy5wdXNoKHZhbHVlKVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiBlbGVtZW50cykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gY2FsbGJhY2soZWxlbWVudHNba2V5XSwga2V5KVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB2YWx1ZXMucHVzaCh2YWx1ZSlcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGZsYXR0ZW4odmFsdWVzKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgJC5lYWNoID0gZnVuY3Rpb24oZWxlbWVudHMsIGNhbGxiYWNrKXtcclxuICAgICAgICAgICAgdmFyIGksIGtleVxyXG4gICAgICAgICAgICBpZiAobGlrZUFycmF5KGVsZW1lbnRzKSkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjay5jYWxsKGVsZW1lbnRzW2ldLCBpLCBlbGVtZW50c1tpXSkgPT09IGZhbHNlKSByZXR1cm4gZWxlbWVudHNcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGZvciAoa2V5IGluIGVsZW1lbnRzKVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjay5jYWxsKGVsZW1lbnRzW2tleV0sIGtleSwgZWxlbWVudHNba2V5XSkgPT09IGZhbHNlKSByZXR1cm4gZWxlbWVudHNcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnRzXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAkLmdyZXAgPSBmdW5jdGlvbihlbGVtZW50cywgY2FsbGJhY2spe1xyXG4gICAgICAgICAgICByZXR1cm4gZmlsdGVyLmNhbGwoZWxlbWVudHMsIGNhbGxiYWNrKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHdpbmRvdy5KU09OKSAkLnBhcnNlSlNPTiA9IEpTT04ucGFyc2VcclxuXHJcbiAgICAgICAgLy8gUG9wdWxhdGUgdGhlIGNsYXNzMnR5cGUgbWFwXHJcbiAgICAgICAgJC5lYWNoKFwiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvclwiLnNwbGl0KFwiIFwiKSwgZnVuY3Rpb24oaSwgbmFtZSkge1xyXG4gICAgICAgICAgICBjbGFzczJ0eXBlWyBcIltvYmplY3QgXCIgKyBuYW1lICsgXCJdXCIgXSA9IG5hbWUudG9Mb3dlckNhc2UoKVxyXG4gICAgICAgIH0pXHJcblxyXG4gICAgICAgIC8vIERlZmluZSBtZXRob2RzIHRoYXQgd2lsbCBiZSBhdmFpbGFibGUgb24gYWxsXHJcbiAgICAgICAgLy8gWmVwdG8gY29sbGVjdGlvbnNcclxuICAgICAgICAkLmZuID0ge1xyXG4gICAgICAgICAgICBjb25zdHJ1Y3RvcjogemVwdG8uWixcclxuICAgICAgICAgICAgbGVuZ3RoOiAwLFxyXG5cclxuICAgICAgICAgICAgLy8gQmVjYXVzZSBhIGNvbGxlY3Rpb24gYWN0cyBsaWtlIGFuIGFycmF5XHJcbiAgICAgICAgICAgIC8vIGNvcHkgb3ZlciB0aGVzZSB1c2VmdWwgYXJyYXkgZnVuY3Rpb25zLlxyXG4gICAgICAgICAgICBmb3JFYWNoOiBlbXB0eUFycmF5LmZvckVhY2gsXHJcbiAgICAgICAgICAgIHJlZHVjZTogZW1wdHlBcnJheS5yZWR1Y2UsXHJcbiAgICAgICAgICAgIHB1c2g6IGVtcHR5QXJyYXkucHVzaCxcclxuICAgICAgICAgICAgc29ydDogZW1wdHlBcnJheS5zb3J0LFxyXG4gICAgICAgICAgICBzcGxpY2U6IGVtcHR5QXJyYXkuc3BsaWNlLFxyXG4gICAgICAgICAgICBpbmRleE9mOiBlbXB0eUFycmF5LmluZGV4T2YsXHJcbiAgICAgICAgICAgIGNvbmNhdDogZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgICAgIHZhciBpLCB2YWx1ZSwgYXJncyA9IFtdXHJcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBhcmd1bWVudHNbaV1cclxuICAgICAgICAgICAgICAgICAgICBhcmdzW2ldID0gemVwdG8uaXNaKHZhbHVlKSA/IHZhbHVlLnRvQXJyYXkoKSA6IHZhbHVlXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY29uY2F0LmFwcGx5KHplcHRvLmlzWih0aGlzKSA/IHRoaXMudG9BcnJheSgpIDogdGhpcywgYXJncylcclxuICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgIC8vIGBtYXBgIGFuZCBgc2xpY2VgIGluIHRoZSBqUXVlcnkgQVBJIHdvcmsgZGlmZmVyZW50bHlcclxuICAgICAgICAgICAgLy8gZnJvbSB0aGVpciBhcnJheSBjb3VudGVycGFydHNcclxuICAgICAgICAgICAgbWFwOiBmdW5jdGlvbihmbil7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJCgkLm1hcCh0aGlzLCBmdW5jdGlvbihlbCwgaSl7IHJldHVybiBmbi5jYWxsKGVsLCBpLCBlbCkgfSkpXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHNsaWNlOiBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICQoc2xpY2UuYXBwbHkodGhpcywgYXJndW1lbnRzKSlcclxuICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgIHJlYWR5OiBmdW5jdGlvbihjYWxsYmFjayl7XHJcbiAgICAgICAgICAgICAgICAvLyBuZWVkIHRvIGNoZWNrIGlmIGRvY3VtZW50LmJvZHkgZXhpc3RzIGZvciBJRSBhcyB0aGF0IGJyb3dzZXIgcmVwb3J0c1xyXG4gICAgICAgICAgICAgICAgLy8gZG9jdW1lbnQgcmVhZHkgd2hlbiBpdCBoYXNuJ3QgeWV0IGNyZWF0ZWQgdGhlIGJvZHkgZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgaWYgKHJlYWR5UkUudGVzdChkb2N1bWVudC5yZWFkeVN0YXRlKSAmJiBkb2N1bWVudC5ib2R5KSBjYWxsYmFjaygkKVxyXG4gICAgICAgICAgICAgICAgZWxzZSBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdET01Db250ZW50TG9hZGVkJywgZnVuY3Rpb24oKXsgY2FsbGJhY2soJCkgfSwgZmFsc2UpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpc1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKGlkeCl7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaWR4ID09PSB1bmRlZmluZWQgPyBzbGljZS5jYWxsKHRoaXMpIDogdGhpc1tpZHggPj0gMCA/IGlkeCA6IGlkeCArIHRoaXMubGVuZ3RoXVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB0b0FycmF5OiBmdW5jdGlvbigpeyByZXR1cm4gdGhpcy5nZXQoKSB9LFxyXG4gICAgICAgICAgICBzaXplOiBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGVuZ3RoXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHJlbW92ZTogZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5wYXJlbnROb2RlICE9IG51bGwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzKVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZWFjaDogZnVuY3Rpb24oY2FsbGJhY2spe1xyXG4gICAgICAgICAgICAgICAgZW1wdHlBcnJheS5ldmVyeS5jYWxsKHRoaXMsIGZ1bmN0aW9uKGVsLCBpZHgpe1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKGVsLCBpZHgsIGVsKSAhPT0gZmFsc2VcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpc1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBmaWx0ZXI6IGZ1bmN0aW9uKHNlbGVjdG9yKXtcclxuICAgICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHNlbGVjdG9yKSkgcmV0dXJuIHRoaXMubm90KHRoaXMubm90KHNlbGVjdG9yKSlcclxuICAgICAgICAgICAgICAgIHJldHVybiAkKGZpbHRlci5jYWxsKHRoaXMsIGZ1bmN0aW9uKGVsZW1lbnQpe1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB6ZXB0by5tYXRjaGVzKGVsZW1lbnQsIHNlbGVjdG9yKVxyXG4gICAgICAgICAgICAgICAgfSkpXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGFkZDogZnVuY3Rpb24oc2VsZWN0b3IsY29udGV4dCl7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJCh1bmlxKHRoaXMuY29uY2F0KCQoc2VsZWN0b3IsY29udGV4dCkpKSlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaXM6IGZ1bmN0aW9uKHNlbGVjdG9yKXtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmxlbmd0aCA+IDAgJiYgemVwdG8ubWF0Y2hlcyh0aGlzWzBdLCBzZWxlY3RvcilcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbm90OiBmdW5jdGlvbihzZWxlY3Rvcil7XHJcbiAgICAgICAgICAgICAgICB2YXIgbm9kZXM9W11cclxuICAgICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHNlbGVjdG9yKSAmJiBzZWxlY3Rvci5jYWxsICE9PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uKGlkeCl7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc2VsZWN0b3IuY2FsbCh0aGlzLGlkeCkpIG5vZGVzLnB1c2godGhpcylcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGV4Y2x1ZGVzID0gdHlwZW9mIHNlbGVjdG9yID09ICdzdHJpbmcnID8gdGhpcy5maWx0ZXIoc2VsZWN0b3IpIDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGxpa2VBcnJheShzZWxlY3RvcikgJiYgaXNGdW5jdGlvbihzZWxlY3Rvci5pdGVtKSkgPyBzbGljZS5jYWxsKHNlbGVjdG9yKSA6ICQoc2VsZWN0b3IpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uKGVsKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV4Y2x1ZGVzLmluZGV4T2YoZWwpIDwgMCkgbm9kZXMucHVzaChlbClcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICQobm9kZXMpXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGhhczogZnVuY3Rpb24oc2VsZWN0b3Ipe1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyKGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlzT2JqZWN0KHNlbGVjdG9yKSA/XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICQuY29udGFpbnModGhpcywgc2VsZWN0b3IpIDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5maW5kKHNlbGVjdG9yKS5zaXplKClcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGVxOiBmdW5jdGlvbihpZHgpe1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGlkeCA9PT0gLTEgPyB0aGlzLnNsaWNlKGlkeCkgOiB0aGlzLnNsaWNlKGlkeCwgKyBpZHggKyAxKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBmaXJzdDogZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgICAgIHZhciBlbCA9IHRoaXNbMF1cclxuICAgICAgICAgICAgICAgIHJldHVybiBlbCAmJiAhaXNPYmplY3QoZWwpID8gZWwgOiAkKGVsKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBsYXN0OiBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAgICAgdmFyIGVsID0gdGhpc1t0aGlzLmxlbmd0aCAtIDFdXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZWwgJiYgIWlzT2JqZWN0KGVsKSA/IGVsIDogJChlbClcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZmluZDogZnVuY3Rpb24oc2VsZWN0b3Ipe1xyXG4gICAgICAgICAgICAgICAgdmFyIHJlc3VsdCwgJHRoaXMgPSB0aGlzXHJcbiAgICAgICAgICAgICAgICBpZiAoIXNlbGVjdG9yKSByZXN1bHQgPSAkKClcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBzZWxlY3RvciA9PSAnb2JqZWN0JylcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAkKHNlbGVjdG9yKS5maWx0ZXIoZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSB0aGlzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbXB0eUFycmF5LnNvbWUuY2FsbCgkdGhpcywgZnVuY3Rpb24ocGFyZW50KXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkLmNvbnRhaW5zKHBhcmVudCwgbm9kZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5sZW5ndGggPT0gMSkgcmVzdWx0ID0gJCh6ZXB0by5xc2EodGhpc1swXSwgc2VsZWN0b3IpKVxyXG4gICAgICAgICAgICAgICAgZWxzZSByZXN1bHQgPSB0aGlzLm1hcChmdW5jdGlvbigpeyByZXR1cm4gemVwdG8ucXNhKHRoaXMsIHNlbGVjdG9yKSB9KVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjbG9zZXN0OiBmdW5jdGlvbihzZWxlY3RvciwgY29udGV4dCl7XHJcbiAgICAgICAgICAgICAgICB2YXIgbm9kZXMgPSBbXSwgY29sbGVjdGlvbiA9IHR5cGVvZiBzZWxlY3RvciA9PSAnb2JqZWN0JyAmJiAkKHNlbGVjdG9yKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uKF8sIG5vZGUpe1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChub2RlICYmICEoY29sbGVjdGlvbiA/IGNvbGxlY3Rpb24uaW5kZXhPZihub2RlKSA+PSAwIDogemVwdG8ubWF0Y2hlcyhub2RlLCBzZWxlY3RvcikpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZSAhPT0gY29udGV4dCAmJiAhaXNEb2N1bWVudChub2RlKSAmJiBub2RlLnBhcmVudE5vZGVcclxuICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSAmJiBub2Rlcy5pbmRleE9mKG5vZGUpIDwgMCkgbm9kZXMucHVzaChub2RlKVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgIHJldHVybiAkKG5vZGVzKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBwYXJlbnRzOiBmdW5jdGlvbihzZWxlY3Rvcil7XHJcbiAgICAgICAgICAgICAgICB2YXIgYW5jZXN0b3JzID0gW10sIG5vZGVzID0gdGhpc1xyXG4gICAgICAgICAgICAgICAgd2hpbGUgKG5vZGVzLmxlbmd0aCA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgbm9kZXMgPSAkLm1hcChub2RlcywgZnVuY3Rpb24obm9kZSl7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobm9kZSA9IG5vZGUucGFyZW50Tm9kZSkgJiYgIWlzRG9jdW1lbnQobm9kZSkgJiYgYW5jZXN0b3JzLmluZGV4T2Yobm9kZSkgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNlc3RvcnMucHVzaChub2RlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmlsdGVyZWQoYW5jZXN0b3JzLCBzZWxlY3RvcilcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgcGFyZW50OiBmdW5jdGlvbihzZWxlY3Rvcil7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmlsdGVyZWQodW5pcSh0aGlzLnBsdWNrKCdwYXJlbnROb2RlJykpLCBzZWxlY3RvcilcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgY2hpbGRyZW46IGZ1bmN0aW9uKHNlbGVjdG9yKXtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmaWx0ZXJlZCh0aGlzLm1hcChmdW5jdGlvbigpeyByZXR1cm4gY2hpbGRyZW4odGhpcykgfSksIHNlbGVjdG9yKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjb250ZW50czogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLmNvbnRlbnREb2N1bWVudCB8fCBzbGljZS5jYWxsKHRoaXMuY2hpbGROb2RlcykgfSlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgc2libGluZ3M6IGZ1bmN0aW9uKHNlbGVjdG9yKXtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmaWx0ZXJlZCh0aGlzLm1hcChmdW5jdGlvbihpLCBlbCl7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbHRlci5jYWxsKGNoaWxkcmVuKGVsLnBhcmVudE5vZGUpLCBmdW5jdGlvbihjaGlsZCl7IHJldHVybiBjaGlsZCE9PWVsIH0pXHJcbiAgICAgICAgICAgICAgICB9KSwgc2VsZWN0b3IpXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGVtcHR5OiBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpeyB0aGlzLmlubmVySFRNTCA9ICcnIH0pXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIC8vIGBwbHVja2AgaXMgYm9ycm93ZWQgZnJvbSBQcm90b3R5cGUuanNcclxuICAgICAgICAgICAgcGx1Y2s6IGZ1bmN0aW9uKHByb3BlcnR5KXtcclxuICAgICAgICAgICAgICAgIHJldHVybiAkLm1hcCh0aGlzLCBmdW5jdGlvbihlbCl7IHJldHVybiBlbFtwcm9wZXJ0eV0gfSlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgc2hvdzogZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0eWxlLmRpc3BsYXkgPT0gXCJub25lXCIgJiYgKHRoaXMuc3R5bGUuZGlzcGxheSA9ICcnKVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChnZXRDb21wdXRlZFN0eWxlKHRoaXMsICcnKS5nZXRQcm9wZXJ0eVZhbHVlKFwiZGlzcGxheVwiKSA9PSBcIm5vbmVcIilcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHlsZS5kaXNwbGF5ID0gZGVmYXVsdERpc3BsYXkodGhpcy5ub2RlTmFtZSlcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHJlcGxhY2VXaXRoOiBmdW5jdGlvbihuZXdDb250ZW50KXtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmJlZm9yZShuZXdDb250ZW50KS5yZW1vdmUoKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB3cmFwOiBmdW5jdGlvbihzdHJ1Y3R1cmUpe1xyXG4gICAgICAgICAgICAgICAgdmFyIGZ1bmMgPSBpc0Z1bmN0aW9uKHN0cnVjdHVyZSlcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzWzBdICYmICFmdW5jKVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkb20gICA9ICQoc3RydWN0dXJlKS5nZXQoMCksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsb25lID0gZG9tLnBhcmVudE5vZGUgfHwgdGhpcy5sZW5ndGggPiAxXHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihpbmRleCl7XHJcbiAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS53cmFwQWxsKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmdW5jID8gc3RydWN0dXJlLmNhbGwodGhpcywgaW5kZXgpIDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb25lID8gZG9tLmNsb25lTm9kZSh0cnVlKSA6IGRvbVxyXG4gICAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHdyYXBBbGw6IGZ1bmN0aW9uKHN0cnVjdHVyZSl7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpc1swXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICQodGhpc1swXSkuYmVmb3JlKHN0cnVjdHVyZSA9ICQoc3RydWN0dXJlKSlcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRyZW5cclxuICAgICAgICAgICAgICAgICAgICAvLyBkcmlsbCBkb3duIHRvIHRoZSBpbm1vc3QgZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlICgoY2hpbGRyZW4gPSBzdHJ1Y3R1cmUuY2hpbGRyZW4oKSkubGVuZ3RoKSBzdHJ1Y3R1cmUgPSBjaGlsZHJlbi5maXJzdCgpXHJcbiAgICAgICAgICAgICAgICAgICAgJChzdHJ1Y3R1cmUpLmFwcGVuZCh0aGlzKVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXNcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgd3JhcElubmVyOiBmdW5jdGlvbihzdHJ1Y3R1cmUpe1xyXG4gICAgICAgICAgICAgICAgdmFyIGZ1bmMgPSBpc0Z1bmN0aW9uKHN0cnVjdHVyZSlcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oaW5kZXgpe1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzZWxmID0gJCh0aGlzKSwgY29udGVudHMgPSBzZWxmLmNvbnRlbnRzKCksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbSAgPSBmdW5jID8gc3RydWN0dXJlLmNhbGwodGhpcywgaW5kZXgpIDogc3RydWN0dXJlXHJcbiAgICAgICAgICAgICAgICAgICAgY29udGVudHMubGVuZ3RoID8gY29udGVudHMud3JhcEFsbChkb20pIDogc2VsZi5hcHBlbmQoZG9tKVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgdW53cmFwOiBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wYXJlbnQoKS5lYWNoKGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5yZXBsYWNlV2l0aCgkKHRoaXMpLmNoaWxkcmVuKCkpXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXNcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgY2xvbmU6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24oKXsgcmV0dXJuIHRoaXMuY2xvbmVOb2RlKHRydWUpIH0pXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGhpZGU6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jc3MoXCJkaXNwbGF5XCIsIFwibm9uZVwiKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB0b2dnbGU6IGZ1bmN0aW9uKHNldHRpbmcpe1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbCA9ICQodGhpcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgOyhzZXR0aW5nID09PSB1bmRlZmluZWQgPyBlbC5jc3MoXCJkaXNwbGF5XCIpID09IFwibm9uZVwiIDogc2V0dGluZykgPyBlbC5zaG93KCkgOiBlbC5oaWRlKClcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHByZXY6IGZ1bmN0aW9uKHNlbGVjdG9yKXsgcmV0dXJuICQodGhpcy5wbHVjaygncHJldmlvdXNFbGVtZW50U2libGluZycpKS5maWx0ZXIoc2VsZWN0b3IgfHwgJyonKSB9LFxyXG4gICAgICAgICAgICBuZXh0OiBmdW5jdGlvbihzZWxlY3Rvcil7IHJldHVybiAkKHRoaXMucGx1Y2soJ25leHRFbGVtZW50U2libGluZycpKS5maWx0ZXIoc2VsZWN0b3IgfHwgJyonKSB9LFxyXG4gICAgICAgICAgICBodG1sOiBmdW5jdGlvbihodG1sKXtcclxuICAgICAgICAgICAgICAgIHJldHVybiAwIGluIGFyZ3VtZW50cyA/XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uKGlkeCl7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcmlnaW5IdG1sID0gdGhpcy5pbm5lckhUTUxcclxuICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5lbXB0eSgpLmFwcGVuZCggZnVuY0FyZyh0aGlzLCBodG1sLCBpZHgsIG9yaWdpbkh0bWwpIClcclxuICAgICAgICAgICAgICAgICAgICB9KSA6XHJcbiAgICAgICAgICAgICAgICAgICAgKDAgaW4gdGhpcyA/IHRoaXNbMF0uaW5uZXJIVE1MIDogbnVsbClcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgdGV4dDogZnVuY3Rpb24odGV4dCl7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gMCBpbiBhcmd1bWVudHMgP1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbihpZHgpe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3VGV4dCA9IGZ1bmNBcmcodGhpcywgdGV4dCwgaWR4LCB0aGlzLnRleHRDb250ZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRleHRDb250ZW50ID0gbmV3VGV4dCA9PSBudWxsID8gJycgOiAnJytuZXdUZXh0XHJcbiAgICAgICAgICAgICAgICAgICAgfSkgOlxyXG4gICAgICAgICAgICAgICAgICAgICgwIGluIHRoaXMgPyB0aGlzLnBsdWNrKCd0ZXh0Q29udGVudCcpLmpvaW4oXCJcIikgOiBudWxsKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBhdHRyOiBmdW5jdGlvbihuYW1lLCB2YWx1ZSl7XHJcbiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKHR5cGVvZiBuYW1lID09ICdzdHJpbmcnICYmICEoMSBpbiBhcmd1bWVudHMpKSA/XHJcbiAgICAgICAgICAgICAgICAgICAgKDAgaW4gdGhpcyAmJiB0aGlzWzBdLm5vZGVUeXBlID09IDEgJiYgKHJlc3VsdCA9IHRoaXNbMF0uZ2V0QXR0cmlidXRlKG5hbWUpKSAhPSBudWxsID8gcmVzdWx0IDogdW5kZWZpbmVkKSA6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uKGlkeCl7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm5vZGVUeXBlICE9PSAxKSByZXR1cm5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2JqZWN0KG5hbWUpKSBmb3IgKGtleSBpbiBuYW1lKSBzZXRBdHRyaWJ1dGUodGhpcywga2V5LCBuYW1lW2tleV0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Ugc2V0QXR0cmlidXRlKHRoaXMsIG5hbWUsIGZ1bmNBcmcodGhpcywgdmFsdWUsIGlkeCwgdGhpcy5nZXRBdHRyaWJ1dGUobmFtZSkpKVxyXG4gICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHJlbW92ZUF0dHI6IGZ1bmN0aW9uKG5hbWUpe1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpeyB0aGlzLm5vZGVUeXBlID09PSAxICYmIG5hbWUuc3BsaXQoJyAnKS5mb3JFYWNoKGZ1bmN0aW9uKGF0dHJpYnV0ZSl7XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0QXR0cmlidXRlKHRoaXMsIGF0dHJpYnV0ZSlcclxuICAgICAgICAgICAgICAgIH0sIHRoaXMpfSlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgcHJvcDogZnVuY3Rpb24obmFtZSwgdmFsdWUpe1xyXG4gICAgICAgICAgICAgICAgbmFtZSA9IHByb3BNYXBbbmFtZV0gfHwgbmFtZVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICgxIGluIGFyZ3VtZW50cykgP1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbihpZHgpe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzW25hbWVdID0gZnVuY0FyZyh0aGlzLCB2YWx1ZSwgaWR4LCB0aGlzW25hbWVdKVxyXG4gICAgICAgICAgICAgICAgICAgIH0pIDpcclxuICAgICAgICAgICAgICAgICAgICAodGhpc1swXSAmJiB0aGlzWzBdW25hbWVdKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICByZW1vdmVQcm9wOiBmdW5jdGlvbihuYW1lKXtcclxuICAgICAgICAgICAgICAgIG5hbWUgPSBwcm9wTWFwW25hbWVdIHx8IG5hbWVcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXsgZGVsZXRlIHRoaXNbbmFtZV0gfSlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZGF0YTogZnVuY3Rpb24obmFtZSwgdmFsdWUpe1xyXG4gICAgICAgICAgICAgICAgdmFyIGF0dHJOYW1lID0gJ2RhdGEtJyArIG5hbWUucmVwbGFjZShjYXBpdGFsUkUsICctJDEnKS50b0xvd2VyQ2FzZSgpXHJcblxyXG4gICAgICAgICAgICAgICAgdmFyIGRhdGEgPSAoMSBpbiBhcmd1bWVudHMpID9cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmF0dHIoYXR0ck5hbWUsIHZhbHVlKSA6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hdHRyKGF0dHJOYW1lKVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhICE9PSBudWxsID8gZGVzZXJpYWxpemVWYWx1ZShkYXRhKSA6IHVuZGVmaW5lZFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB2YWw6IGZ1bmN0aW9uKHZhbHVlKXtcclxuICAgICAgICAgICAgICAgIGlmICgwIGluIGFyZ3VtZW50cykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB2YWx1ZSA9IFwiXCJcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKGlkeCl7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSBmdW5jQXJnKHRoaXMsIHZhbHVlLCBpZHgsIHRoaXMudmFsdWUpXHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXNbMF0gJiYgKHRoaXNbMF0ubXVsdGlwbGUgP1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzWzBdKS5maW5kKCdvcHRpb24nKS5maWx0ZXIoZnVuY3Rpb24oKXsgcmV0dXJuIHRoaXMuc2VsZWN0ZWQgfSkucGx1Y2soJ3ZhbHVlJykgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1swXS52YWx1ZSlcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgb2Zmc2V0OiBmdW5jdGlvbihjb29yZGluYXRlcyl7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29vcmRpbmF0ZXMpIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oaW5kZXgpe1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciAkdGhpcyA9ICQodGhpcyksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvb3JkcyA9IGZ1bmNBcmcodGhpcywgY29vcmRpbmF0ZXMsIGluZGV4LCAkdGhpcy5vZmZzZXQoKSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE9mZnNldCA9ICR0aGlzLm9mZnNldFBhcmVudCgpLm9mZnNldCgpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wcyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogIGNvb3Jkcy50b3AgIC0gcGFyZW50T2Zmc2V0LnRvcCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IGNvb3Jkcy5sZWZ0IC0gcGFyZW50T2Zmc2V0LmxlZnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoJHRoaXMuY3NzKCdwb3NpdGlvbicpID09ICdzdGF0aWMnKSBwcm9wc1sncG9zaXRpb24nXSA9ICdyZWxhdGl2ZSdcclxuICAgICAgICAgICAgICAgICAgICAkdGhpcy5jc3MocHJvcHMpXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmxlbmd0aCkgcmV0dXJuIG51bGxcclxuICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgIT09IHRoaXNbMF0gJiYgISQuY29udGFpbnMoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCB0aGlzWzBdKSlcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge3RvcDogMCwgbGVmdDogMH1cclxuICAgICAgICAgICAgICAgIHZhciBvYmogPSB0aGlzWzBdLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGxlZnQ6IG9iai5sZWZ0ICsgd2luZG93LnBhZ2VYT2Zmc2V0LFxyXG4gICAgICAgICAgICAgICAgICAgIHRvcDogb2JqLnRvcCArIHdpbmRvdy5wYWdlWU9mZnNldCxcclxuICAgICAgICAgICAgICAgICAgICB3aWR0aDogTWF0aC5yb3VuZChvYmoud2lkdGgpLFxyXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogTWF0aC5yb3VuZChvYmouaGVpZ2h0KVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjc3M6IGZ1bmN0aW9uKHByb3BlcnR5LCB2YWx1ZSl7XHJcbiAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudCA9IHRoaXNbMF1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHByb3BlcnR5ID09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZWxlbWVudCkgcmV0dXJuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50LnN0eWxlW2NhbWVsaXplKHByb3BlcnR5KV0gfHwgZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50LCAnJykuZ2V0UHJvcGVydHlWYWx1ZShwcm9wZXJ0eSlcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkocHJvcGVydHkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZWxlbWVudCkgcmV0dXJuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcm9wcyA9IHt9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb21wdXRlZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50LCAnJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgJC5lYWNoKHByb3BlcnR5LCBmdW5jdGlvbihfLCBwcm9wKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BzW3Byb3BdID0gKGVsZW1lbnQuc3R5bGVbY2FtZWxpemUocHJvcCldIHx8IGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShwcm9wKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByb3BzXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHZhciBjc3MgPSAnJ1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGUocHJvcGVydHkpID09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF2YWx1ZSAmJiB2YWx1ZSAhPT0gMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uKCl7IHRoaXMuc3R5bGUucmVtb3ZlUHJvcGVydHkoZGFzaGVyaXplKHByb3BlcnR5KSkgfSlcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzcyA9IGRhc2hlcml6ZShwcm9wZXJ0eSkgKyBcIjpcIiArIG1heWJlQWRkUHgocHJvcGVydHksIHZhbHVlKVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiBwcm9wZXJ0eSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFwcm9wZXJ0eVtrZXldICYmIHByb3BlcnR5W2tleV0gIT09IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVhY2goZnVuY3Rpb24oKXsgdGhpcy5zdHlsZS5yZW1vdmVQcm9wZXJ0eShkYXNoZXJpemUoa2V5KSkgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzICs9IGRhc2hlcml6ZShrZXkpICsgJzonICsgbWF5YmVBZGRQeChrZXksIHByb3BlcnR5W2tleV0pICsgJzsnXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpeyB0aGlzLnN0eWxlLmNzc1RleHQgKz0gJzsnICsgY3NzIH0pXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGluZGV4OiBmdW5jdGlvbihlbGVtZW50KXtcclxuICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50ID8gdGhpcy5pbmRleE9mKCQoZWxlbWVudClbMF0pIDogdGhpcy5wYXJlbnQoKS5jaGlsZHJlbigpLmluZGV4T2YodGhpc1swXSlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgaGFzQ2xhc3M6IGZ1bmN0aW9uKG5hbWUpe1xyXG4gICAgICAgICAgICAgICAgaWYgKCFuYW1lKSByZXR1cm4gZmFsc2VcclxuICAgICAgICAgICAgICAgIHJldHVybiBlbXB0eUFycmF5LnNvbWUuY2FsbCh0aGlzLCBmdW5jdGlvbihlbCl7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudGVzdChjbGFzc05hbWUoZWwpKVxyXG4gICAgICAgICAgICAgICAgfSwgY2xhc3NSRShuYW1lKSlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgYWRkQ2xhc3M6IGZ1bmN0aW9uKG5hbWUpe1xyXG4gICAgICAgICAgICAgICAgaWYgKCFuYW1lKSByZXR1cm4gdGhpc1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihpZHgpe1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKCdjbGFzc05hbWUnIGluIHRoaXMpKSByZXR1cm5cclxuICAgICAgICAgICAgICAgICAgICBjbGFzc0xpc3QgPSBbXVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbHMgPSBjbGFzc05hbWUodGhpcyksIG5ld05hbWUgPSBmdW5jQXJnKHRoaXMsIG5hbWUsIGlkeCwgY2xzKVxyXG4gICAgICAgICAgICAgICAgICAgIG5ld05hbWUuc3BsaXQoL1xccysvZykuZm9yRWFjaChmdW5jdGlvbihrbGFzcyl7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJCh0aGlzKS5oYXNDbGFzcyhrbGFzcykpIGNsYXNzTGlzdC5wdXNoKGtsYXNzKVxyXG4gICAgICAgICAgICAgICAgICAgIH0sIHRoaXMpXHJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NMaXN0Lmxlbmd0aCAmJiBjbGFzc05hbWUodGhpcywgY2xzICsgKGNscyA/IFwiIFwiIDogXCJcIikgKyBjbGFzc0xpc3Quam9pbihcIiBcIikpXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICByZW1vdmVDbGFzczogZnVuY3Rpb24obmFtZSl7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKGlkeCl7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEoJ2NsYXNzTmFtZScgaW4gdGhpcykpIHJldHVyblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSB1bmRlZmluZWQpIHJldHVybiBjbGFzc05hbWUodGhpcywgJycpXHJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NMaXN0ID0gY2xhc3NOYW1lKHRoaXMpXHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY0FyZyh0aGlzLCBuYW1lLCBpZHgsIGNsYXNzTGlzdCkuc3BsaXQoL1xccysvZykuZm9yRWFjaChmdW5jdGlvbihrbGFzcyl7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTGlzdCA9IGNsYXNzTGlzdC5yZXBsYWNlKGNsYXNzUkUoa2xhc3MpLCBcIiBcIilcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSh0aGlzLCBjbGFzc0xpc3QudHJpbSgpKVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgdG9nZ2xlQ2xhc3M6IGZ1bmN0aW9uKG5hbWUsIHdoZW4pe1xyXG4gICAgICAgICAgICAgICAgaWYgKCFuYW1lKSByZXR1cm4gdGhpc1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihpZHgpe1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciAkdGhpcyA9ICQodGhpcyksIG5hbWVzID0gZnVuY0FyZyh0aGlzLCBuYW1lLCBpZHgsIGNsYXNzTmFtZSh0aGlzKSlcclxuICAgICAgICAgICAgICAgICAgICBuYW1lcy5zcGxpdCgvXFxzKy9nKS5mb3JFYWNoKGZ1bmN0aW9uKGtsYXNzKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgKHdoZW4gPT09IHVuZGVmaW5lZCA/ICEkdGhpcy5oYXNDbGFzcyhrbGFzcykgOiB3aGVuKSA/XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy5hZGRDbGFzcyhrbGFzcykgOiAkdGhpcy5yZW1vdmVDbGFzcyhrbGFzcylcclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgc2Nyb2xsVG9wOiBmdW5jdGlvbih2YWx1ZSl7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMubGVuZ3RoKSByZXR1cm5cclxuICAgICAgICAgICAgICAgIHZhciBoYXNTY3JvbGxUb3AgPSAnc2Nyb2xsVG9wJyBpbiB0aGlzWzBdXHJcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGhhc1Njcm9sbFRvcCA/IHRoaXNbMF0uc2Nyb2xsVG9wIDogdGhpc1swXS5wYWdlWU9mZnNldFxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChoYXNTY3JvbGxUb3AgP1xyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKCl7IHRoaXMuc2Nyb2xsVG9wID0gdmFsdWUgfSA6XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oKXsgdGhpcy5zY3JvbGxUbyh0aGlzLnNjcm9sbFgsIHZhbHVlKSB9KVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBzY3JvbGxMZWZ0OiBmdW5jdGlvbih2YWx1ZSl7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMubGVuZ3RoKSByZXR1cm5cclxuICAgICAgICAgICAgICAgIHZhciBoYXNTY3JvbGxMZWZ0ID0gJ3Njcm9sbExlZnQnIGluIHRoaXNbMF1cclxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gaGFzU2Nyb2xsTGVmdCA/IHRoaXNbMF0uc2Nyb2xsTGVmdCA6IHRoaXNbMF0ucGFnZVhPZmZzZXRcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goaGFzU2Nyb2xsTGVmdCA/XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oKXsgdGhpcy5zY3JvbGxMZWZ0ID0gdmFsdWUgfSA6XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oKXsgdGhpcy5zY3JvbGxUbyh2YWx1ZSwgdGhpcy5zY3JvbGxZKSB9KVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBwb3NpdGlvbjogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMubGVuZ3RoKSByZXR1cm5cclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgZWxlbSA9IHRoaXNbMF0sXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gR2V0ICpyZWFsKiBvZmZzZXRQYXJlbnRcclxuICAgICAgICAgICAgICAgICAgICBvZmZzZXRQYXJlbnQgPSB0aGlzLm9mZnNldFBhcmVudCgpLFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIEdldCBjb3JyZWN0IG9mZnNldHNcclxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQgICAgICAgPSB0aGlzLm9mZnNldCgpLFxyXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudE9mZnNldCA9IHJvb3ROb2RlUkUudGVzdChvZmZzZXRQYXJlbnRbMF0ubm9kZU5hbWUpID8geyB0b3A6IDAsIGxlZnQ6IDAgfSA6IG9mZnNldFBhcmVudC5vZmZzZXQoKVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIFN1YnRyYWN0IGVsZW1lbnQgbWFyZ2luc1xyXG4gICAgICAgICAgICAgICAgLy8gbm90ZTogd2hlbiBhbiBlbGVtZW50IGhhcyBtYXJnaW46IGF1dG8gdGhlIG9mZnNldExlZnQgYW5kIG1hcmdpbkxlZnRcclxuICAgICAgICAgICAgICAgIC8vIGFyZSB0aGUgc2FtZSBpbiBTYWZhcmkgY2F1c2luZyBvZmZzZXQubGVmdCB0byBpbmNvcnJlY3RseSBiZSAwXHJcbiAgICAgICAgICAgICAgICBvZmZzZXQudG9wICAtPSBwYXJzZUZsb2F0KCAkKGVsZW0pLmNzcygnbWFyZ2luLXRvcCcpICkgfHwgMFxyXG4gICAgICAgICAgICAgICAgb2Zmc2V0LmxlZnQgLT0gcGFyc2VGbG9hdCggJChlbGVtKS5jc3MoJ21hcmdpbi1sZWZ0JykgKSB8fCAwXHJcblxyXG4gICAgICAgICAgICAgICAgLy8gQWRkIG9mZnNldFBhcmVudCBib3JkZXJzXHJcbiAgICAgICAgICAgICAgICBwYXJlbnRPZmZzZXQudG9wICArPSBwYXJzZUZsb2F0KCAkKG9mZnNldFBhcmVudFswXSkuY3NzKCdib3JkZXItdG9wLXdpZHRoJykgKSB8fCAwXHJcbiAgICAgICAgICAgICAgICBwYXJlbnRPZmZzZXQubGVmdCArPSBwYXJzZUZsb2F0KCAkKG9mZnNldFBhcmVudFswXSkuY3NzKCdib3JkZXItbGVmdC13aWR0aCcpICkgfHwgMFxyXG5cclxuICAgICAgICAgICAgICAgIC8vIFN1YnRyYWN0IHRoZSB0d28gb2Zmc2V0c1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICB0b3A6ICBvZmZzZXQudG9wICAtIHBhcmVudE9mZnNldC50b3AsXHJcbiAgICAgICAgICAgICAgICAgICAgbGVmdDogb2Zmc2V0LmxlZnQgLSBwYXJlbnRPZmZzZXQubGVmdFxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBvZmZzZXRQYXJlbnQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudCA9IHRoaXMub2Zmc2V0UGFyZW50IHx8IGRvY3VtZW50LmJvZHlcclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAocGFyZW50ICYmICFyb290Tm9kZVJFLnRlc3QocGFyZW50Lm5vZGVOYW1lKSAmJiAkKHBhcmVudCkuY3NzKFwicG9zaXRpb25cIikgPT0gXCJzdGF0aWNcIilcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gcGFyZW50Lm9mZnNldFBhcmVudFxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJlbnRcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGZvciBub3dcclxuICAgICAgICAkLmZuLmRldGFjaCA9ICQuZm4ucmVtb3ZlXHJcblxyXG4gICAgICAgIC8vIEdlbmVyYXRlIHRoZSBgd2lkdGhgIGFuZCBgaGVpZ2h0YCBmdW5jdGlvbnNcclxuICAgICAgICA7Wyd3aWR0aCcsICdoZWlnaHQnXS5mb3JFYWNoKGZ1bmN0aW9uKGRpbWVuc2lvbil7XHJcbiAgICAgICAgICAgIHZhciBkaW1lbnNpb25Qcm9wZXJ0eSA9XHJcbiAgICAgICAgICAgICAgICBkaW1lbnNpb24ucmVwbGFjZSgvLi8sIGZ1bmN0aW9uKG0peyByZXR1cm4gbVswXS50b1VwcGVyQ2FzZSgpIH0pXHJcblxyXG4gICAgICAgICAgICAkLmZuW2RpbWVuc2lvbl0gPSBmdW5jdGlvbih2YWx1ZSl7XHJcbiAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0LCBlbCA9IHRoaXNbMF1cclxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gaXNXaW5kb3coZWwpID8gZWxbJ2lubmVyJyArIGRpbWVuc2lvblByb3BlcnR5XSA6XHJcbiAgICAgICAgICAgICAgICAgICAgaXNEb2N1bWVudChlbCkgPyBlbC5kb2N1bWVudEVsZW1lbnRbJ3Njcm9sbCcgKyBkaW1lbnNpb25Qcm9wZXJ0eV0gOlxyXG4gICAgICAgICAgICAgICAgICAgIChvZmZzZXQgPSB0aGlzLm9mZnNldCgpKSAmJiBvZmZzZXRbZGltZW5zaW9uXVxyXG4gICAgICAgICAgICAgICAgZWxzZSByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKGlkeCl7XHJcbiAgICAgICAgICAgICAgICAgICAgZWwgPSAkKHRoaXMpXHJcbiAgICAgICAgICAgICAgICAgICAgZWwuY3NzKGRpbWVuc2lvbiwgZnVuY0FyZyh0aGlzLCB2YWx1ZSwgaWR4LCBlbFtkaW1lbnNpb25dKCkpKVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pXHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHRyYXZlcnNlTm9kZShub2RlLCBmdW4pIHtcclxuICAgICAgICAgICAgZnVuKG5vZGUpXHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBub2RlLmNoaWxkTm9kZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspXHJcbiAgICAgICAgICAgICAgICB0cmF2ZXJzZU5vZGUobm9kZS5jaGlsZE5vZGVzW2ldLCBmdW4pXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBHZW5lcmF0ZSB0aGUgYGFmdGVyYCwgYHByZXBlbmRgLCBgYmVmb3JlYCwgYGFwcGVuZGAsXHJcbiAgICAgICAgLy8gYGluc2VydEFmdGVyYCwgYGluc2VydEJlZm9yZWAsIGBhcHBlbmRUb2AsIGFuZCBgcHJlcGVuZFRvYCBtZXRob2RzLlxyXG4gICAgICAgIGFkamFjZW5jeU9wZXJhdG9ycy5mb3JFYWNoKGZ1bmN0aW9uKG9wZXJhdG9yLCBvcGVyYXRvckluZGV4KSB7XHJcbiAgICAgICAgICAgIHZhciBpbnNpZGUgPSBvcGVyYXRvckluZGV4ICUgMiAvLz0+IHByZXBlbmQsIGFwcGVuZFxyXG5cclxuICAgICAgICAgICAgJC5mbltvcGVyYXRvcl0gPSBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAgICAgLy8gYXJndW1lbnRzIGNhbiBiZSBub2RlcywgYXJyYXlzIG9mIG5vZGVzLCBaZXB0byBvYmplY3RzIGFuZCBIVE1MIHN0cmluZ3NcclxuICAgICAgICAgICAgICAgIHZhciBhcmdUeXBlLCBub2RlcyA9ICQubWFwKGFyZ3VtZW50cywgZnVuY3Rpb24oYXJnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhcnIgPSBbXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmdUeXBlID0gdHlwZShhcmcpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcmdUeXBlID09IFwiYXJyYXlcIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnLmZvckVhY2goZnVuY3Rpb24oZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWwubm9kZVR5cGUgIT09IHVuZGVmaW5lZCkgcmV0dXJuIGFyci5wdXNoKGVsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCQuemVwdG8uaXNaKGVsKSkgcmV0dXJuIGFyciA9IGFyci5jb25jYXQoZWwuZ2V0KCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyID0gYXJyLmNvbmNhdCh6ZXB0by5mcmFnbWVudChlbCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFyclxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhcmdUeXBlID09IFwib2JqZWN0XCIgfHwgYXJnID09IG51bGwgP1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnIDogemVwdG8uZnJhZ21lbnQoYXJnKVxyXG4gICAgICAgICAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudCwgY29weUJ5Q2xvbmUgPSB0aGlzLmxlbmd0aCA+IDFcclxuICAgICAgICAgICAgICAgIGlmIChub2Rlcy5sZW5ndGggPCAxKSByZXR1cm4gdGhpc1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oXywgdGFyZ2V0KXtcclxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQgPSBpbnNpZGUgPyB0YXJnZXQgOiB0YXJnZXQucGFyZW50Tm9kZVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBjb252ZXJ0IGFsbCBtZXRob2RzIHRvIGEgXCJiZWZvcmVcIiBvcGVyYXRpb25cclxuICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPSBvcGVyYXRvckluZGV4ID09IDAgPyB0YXJnZXQubmV4dFNpYmxpbmcgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvckluZGV4ID09IDEgPyB0YXJnZXQuZmlyc3RDaGlsZCA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvckluZGV4ID09IDIgPyB0YXJnZXQgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGxcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudEluRG9jdW1lbnQgPSAkLmNvbnRhaW5zKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgcGFyZW50KVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBub2Rlcy5mb3JFYWNoKGZ1bmN0aW9uKG5vZGUpe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29weUJ5Q2xvbmUpIG5vZGUgPSBub2RlLmNsb25lTm9kZSh0cnVlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghcGFyZW50KSByZXR1cm4gJChub2RlKS5yZW1vdmUoKVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShub2RlLCB0YXJnZXQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnRJbkRvY3VtZW50KSB0cmF2ZXJzZU5vZGUobm9kZSwgZnVuY3Rpb24oZWwpe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsLm5vZGVOYW1lICE9IG51bGwgJiYgZWwubm9kZU5hbWUudG9VcHBlckNhc2UoKSA9PT0gJ1NDUklQVCcgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoIWVsLnR5cGUgfHwgZWwudHlwZSA9PT0gJ3RleHQvamF2YXNjcmlwdCcpICYmICFlbC5zcmMpe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSBlbC5vd25lckRvY3VtZW50ID8gZWwub3duZXJEb2N1bWVudC5kZWZhdWx0VmlldyA6IHdpbmRvd1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFsnZXZhbCddLmNhbGwodGFyZ2V0LCBlbC5pbm5lckhUTUwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGFmdGVyICAgID0+IGluc2VydEFmdGVyXHJcbiAgICAgICAgICAgIC8vIHByZXBlbmQgID0+IHByZXBlbmRUb1xyXG4gICAgICAgICAgICAvLyBiZWZvcmUgICA9PiBpbnNlcnRCZWZvcmVcclxuICAgICAgICAgICAgLy8gYXBwZW5kICAgPT4gYXBwZW5kVG9cclxuICAgICAgICAgICAgJC5mbltpbnNpZGUgPyBvcGVyYXRvcisnVG8nIDogJ2luc2VydCcrKG9wZXJhdG9ySW5kZXggPyAnQmVmb3JlJyA6ICdBZnRlcicpXSA9IGZ1bmN0aW9uKGh0bWwpe1xyXG4gICAgICAgICAgICAgICAgJChodG1sKVtvcGVyYXRvcl0odGhpcylcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG5cclxuICAgICAgICB6ZXB0by5aLnByb3RvdHlwZSA9IFoucHJvdG90eXBlID0gJC5mblxyXG5cclxuICAgICAgICAvLyBFeHBvcnQgaW50ZXJuYWwgQVBJIGZ1bmN0aW9ucyBpbiB0aGUgYCQuemVwdG9gIG5hbWVzcGFjZVxyXG4gICAgICAgIHplcHRvLnVuaXEgPSB1bmlxXHJcbiAgICAgICAgemVwdG8uZGVzZXJpYWxpemVWYWx1ZSA9IGRlc2VyaWFsaXplVmFsdWVcclxuICAgICAgICAkLnplcHRvID0gemVwdG9cclxuXHJcbiAgICAgICAgcmV0dXJuICRcclxuICAgIH0pKClcclxuXHJcbiAgICB3aW5kb3cuWmVwdG8gPSBaZXB0b1xyXG4gICAgd2luZG93LiQgPT09IHVuZGVmaW5lZCAmJiAod2luZG93LiQgPSBaZXB0bylcclxuXHJcbiAgICA7KGZ1bmN0aW9uKCQpe1xyXG4gICAgICAgIHZhciBfemlkID0gMSwgdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICBzbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZSxcclxuICAgICAgICAgICAgaXNGdW5jdGlvbiA9ICQuaXNGdW5jdGlvbixcclxuICAgICAgICAgICAgaXNTdHJpbmcgPSBmdW5jdGlvbihvYmopeyByZXR1cm4gdHlwZW9mIG9iaiA9PSAnc3RyaW5nJyB9LFxyXG4gICAgICAgICAgICBoYW5kbGVycyA9IHt9LFxyXG4gICAgICAgICAgICBzcGVjaWFsRXZlbnRzPXt9LFxyXG4gICAgICAgICAgICBmb2N1c2luU3VwcG9ydGVkID0gJ29uZm9jdXNpbicgaW4gd2luZG93LFxyXG4gICAgICAgICAgICBmb2N1cyA9IHsgZm9jdXM6ICdmb2N1c2luJywgYmx1cjogJ2ZvY3Vzb3V0JyB9LFxyXG4gICAgICAgICAgICBob3ZlciA9IHsgbW91c2VlbnRlcjogJ21vdXNlb3ZlcicsIG1vdXNlbGVhdmU6ICdtb3VzZW91dCcgfVxyXG5cclxuICAgICAgICBzcGVjaWFsRXZlbnRzLmNsaWNrID0gc3BlY2lhbEV2ZW50cy5tb3VzZWRvd24gPSBzcGVjaWFsRXZlbnRzLm1vdXNldXAgPSBzcGVjaWFsRXZlbnRzLm1vdXNlbW92ZSA9ICdNb3VzZUV2ZW50cydcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gemlkKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQuX3ppZCB8fCAoZWxlbWVudC5femlkID0gX3ppZCsrKVxyXG4gICAgICAgIH1cclxuICAgICAgICBmdW5jdGlvbiBmaW5kSGFuZGxlcnMoZWxlbWVudCwgZXZlbnQsIGZuLCBzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICBldmVudCA9IHBhcnNlKGV2ZW50KVxyXG4gICAgICAgICAgICBpZiAoZXZlbnQubnMpIHZhciBtYXRjaGVyID0gbWF0Y2hlckZvcihldmVudC5ucylcclxuICAgICAgICAgICAgcmV0dXJuIChoYW5kbGVyc1t6aWQoZWxlbWVudCldIHx8IFtdKS5maWx0ZXIoZnVuY3Rpb24oaGFuZGxlcikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZXJcclxuICAgICAgICAgICAgICAgICAgICAmJiAoIWV2ZW50LmUgIHx8IGhhbmRsZXIuZSA9PSBldmVudC5lKVxyXG4gICAgICAgICAgICAgICAgICAgICYmICghZXZlbnQubnMgfHwgbWF0Y2hlci50ZXN0KGhhbmRsZXIubnMpKVxyXG4gICAgICAgICAgICAgICAgICAgICYmICghZm4gICAgICAgfHwgemlkKGhhbmRsZXIuZm4pID09PSB6aWQoZm4pKVxyXG4gICAgICAgICAgICAgICAgICAgICYmICghc2VsZWN0b3IgfHwgaGFuZGxlci5zZWwgPT0gc2VsZWN0b3IpXHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIHBhcnNlKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIHZhciBwYXJ0cyA9ICgnJyArIGV2ZW50KS5zcGxpdCgnLicpXHJcbiAgICAgICAgICAgIHJldHVybiB7ZTogcGFydHNbMF0sIG5zOiBwYXJ0cy5zbGljZSgxKS5zb3J0KCkuam9pbignICcpfVxyXG4gICAgICAgIH1cclxuICAgICAgICBmdW5jdGlvbiBtYXRjaGVyRm9yKG5zKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVnRXhwKCcoPzpefCApJyArIG5zLnJlcGxhY2UoJyAnLCAnIC4qID8nKSArICcoPzogfCQpJylcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGV2ZW50Q2FwdHVyZShoYW5kbGVyLCBjYXB0dXJlU2V0dGluZykge1xyXG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlci5kZWwgJiZcclxuICAgICAgICAgICAgICAgICghZm9jdXNpblN1cHBvcnRlZCAmJiAoaGFuZGxlci5lIGluIGZvY3VzKSkgfHxcclxuICAgICAgICAgICAgICAgICEhY2FwdHVyZVNldHRpbmdcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHJlYWxFdmVudCh0eXBlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBob3Zlclt0eXBlXSB8fCAoZm9jdXNpblN1cHBvcnRlZCAmJiBmb2N1c1t0eXBlXSkgfHwgdHlwZVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gYWRkKGVsZW1lbnQsIGV2ZW50cywgZm4sIGRhdGEsIHNlbGVjdG9yLCBkZWxlZ2F0b3IsIGNhcHR1cmUpe1xyXG4gICAgICAgICAgICB2YXIgaWQgPSB6aWQoZWxlbWVudCksIHNldCA9IChoYW5kbGVyc1tpZF0gfHwgKGhhbmRsZXJzW2lkXSA9IFtdKSlcclxuICAgICAgICAgICAgZXZlbnRzLnNwbGl0KC9cXHMvKS5mb3JFYWNoKGZ1bmN0aW9uKGV2ZW50KXtcclxuICAgICAgICAgICAgICAgIGlmIChldmVudCA9PSAncmVhZHknKSByZXR1cm4gJChkb2N1bWVudCkucmVhZHkoZm4pXHJcbiAgICAgICAgICAgICAgICB2YXIgaGFuZGxlciAgID0gcGFyc2UoZXZlbnQpXHJcbiAgICAgICAgICAgICAgICBoYW5kbGVyLmZuICAgID0gZm5cclxuICAgICAgICAgICAgICAgIGhhbmRsZXIuc2VsICAgPSBzZWxlY3RvclxyXG4gICAgICAgICAgICAgICAgLy8gZW11bGF0ZSBtb3VzZWVudGVyLCBtb3VzZWxlYXZlXHJcbiAgICAgICAgICAgICAgICBpZiAoaGFuZGxlci5lIGluIGhvdmVyKSBmbiA9IGZ1bmN0aW9uKGUpe1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWxhdGVkID0gZS5yZWxhdGVkVGFyZ2V0XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFyZWxhdGVkIHx8IChyZWxhdGVkICE9PSB0aGlzICYmICEkLmNvbnRhaW5zKHRoaXMsIHJlbGF0ZWQpKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZXIuZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaGFuZGxlci5kZWwgICA9IGRlbGVnYXRvclxyXG4gICAgICAgICAgICAgICAgdmFyIGNhbGxiYWNrICA9IGRlbGVnYXRvciB8fCBmblxyXG4gICAgICAgICAgICAgICAgaGFuZGxlci5wcm94eSA9IGZ1bmN0aW9uKGUpe1xyXG4gICAgICAgICAgICAgICAgICAgIGUgPSBjb21wYXRpYmxlKGUpXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGUuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQoKSkgcmV0dXJuXHJcbiAgICAgICAgICAgICAgICAgICAgZS5kYXRhID0gZGF0YVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBjYWxsYmFjay5hcHBseShlbGVtZW50LCBlLl9hcmdzID09IHVuZGVmaW5lZCA/IFtlXSA6IFtlXS5jb25jYXQoZS5fYXJncykpXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gZmFsc2UpIGUucHJldmVudERlZmF1bHQoKSwgZS5zdG9wUHJvcGFnYXRpb24oKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGhhbmRsZXIuaSA9IHNldC5sZW5ndGhcclxuICAgICAgICAgICAgICAgIHNldC5wdXNoKGhhbmRsZXIpXHJcbiAgICAgICAgICAgICAgICBpZiAoJ2FkZEV2ZW50TGlzdGVuZXInIGluIGVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKHJlYWxFdmVudChoYW5kbGVyLmUpLCBoYW5kbGVyLnByb3h5LCBldmVudENhcHR1cmUoaGFuZGxlciwgY2FwdHVyZSkpXHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlbW92ZShlbGVtZW50LCBldmVudHMsIGZuLCBzZWxlY3RvciwgY2FwdHVyZSl7XHJcbiAgICAgICAgICAgIHZhciBpZCA9IHppZChlbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgOyhldmVudHMgfHwgJycpLnNwbGl0KC9cXHMvKS5mb3JFYWNoKGZ1bmN0aW9uKGV2ZW50KXtcclxuICAgICAgICAgICAgICAgIGZpbmRIYW5kbGVycyhlbGVtZW50LCBldmVudCwgZm4sIHNlbGVjdG9yKS5mb3JFYWNoKGZ1bmN0aW9uKGhhbmRsZXIpe1xyXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBoYW5kbGVyc1tpZF1baGFuZGxlci5pXVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICgncmVtb3ZlRXZlbnRMaXN0ZW5lcicgaW4gZWxlbWVudClcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHJlYWxFdmVudChoYW5kbGVyLmUpLCBoYW5kbGVyLnByb3h5LCBldmVudENhcHR1cmUoaGFuZGxlciwgY2FwdHVyZSkpXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgJC5ldmVudCA9IHsgYWRkOiBhZGQsIHJlbW92ZTogcmVtb3ZlIH1cclxuXHJcbiAgICAgICAgJC5wcm94eSA9IGZ1bmN0aW9uKGZuLCBjb250ZXh0KSB7XHJcbiAgICAgICAgICAgIHZhciBhcmdzID0gKDIgaW4gYXJndW1lbnRzKSAmJiBzbGljZS5jYWxsKGFyZ3VtZW50cywgMilcclxuICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24oZm4pKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgcHJveHlGbiA9IGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShjb250ZXh0LCBhcmdzID8gYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKSA6IGFyZ3VtZW50cykgfVxyXG4gICAgICAgICAgICAgICAgcHJveHlGbi5femlkID0gemlkKGZuKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3h5Rm5cclxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc1N0cmluZyhjb250ZXh0KSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MpIHtcclxuICAgICAgICAgICAgICAgICAgICBhcmdzLnVuc2hpZnQoZm5bY29udGV4dF0sIGZuKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAkLnByb3h5LmFwcGx5KG51bGwsIGFyZ3MpXHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAkLnByb3h5KGZuW2NvbnRleHRdLCBmbilcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJleHBlY3RlZCBmdW5jdGlvblwiKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAkLmZuLmJpbmQgPSBmdW5jdGlvbihldmVudCwgZGF0YSwgY2FsbGJhY2spe1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vbihldmVudCwgZGF0YSwgY2FsbGJhY2spXHJcbiAgICAgICAgfVxyXG4gICAgICAgICQuZm4udW5iaW5kID0gZnVuY3Rpb24oZXZlbnQsIGNhbGxiYWNrKXtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMub2ZmKGV2ZW50LCBjYWxsYmFjaylcclxuICAgICAgICB9XHJcbiAgICAgICAgJC5mbi5vbmUgPSBmdW5jdGlvbihldmVudCwgc2VsZWN0b3IsIGRhdGEsIGNhbGxiYWNrKXtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMub24oZXZlbnQsIHNlbGVjdG9yLCBkYXRhLCBjYWxsYmFjaywgMSlcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciByZXR1cm5UcnVlID0gZnVuY3Rpb24oKXtyZXR1cm4gdHJ1ZX0sXHJcbiAgICAgICAgICAgIHJldHVybkZhbHNlID0gZnVuY3Rpb24oKXtyZXR1cm4gZmFsc2V9LFxyXG4gICAgICAgICAgICBpZ25vcmVQcm9wZXJ0aWVzID0gL14oW0EtWl18cmV0dXJuVmFsdWUkfGxheWVyW1hZXSR8d2Via2l0TW92ZW1lbnRbWFldJCkvLFxyXG4gICAgICAgICAgICBldmVudE1ldGhvZHMgPSB7XHJcbiAgICAgICAgICAgICAgICBwcmV2ZW50RGVmYXVsdDogJ2lzRGVmYXVsdFByZXZlbnRlZCcsXHJcbiAgICAgICAgICAgICAgICBzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb246ICdpc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCcsXHJcbiAgICAgICAgICAgICAgICBzdG9wUHJvcGFnYXRpb246ICdpc1Byb3BhZ2F0aW9uU3RvcHBlZCdcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiBjb21wYXRpYmxlKGV2ZW50LCBzb3VyY2UpIHtcclxuICAgICAgICAgICAgaWYgKHNvdXJjZSB8fCAhZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKSB7XHJcbiAgICAgICAgICAgICAgICBzb3VyY2UgfHwgKHNvdXJjZSA9IGV2ZW50KVxyXG5cclxuICAgICAgICAgICAgICAgICQuZWFjaChldmVudE1ldGhvZHMsIGZ1bmN0aW9uKG5hbWUsIHByZWRpY2F0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzb3VyY2VNZXRob2QgPSBzb3VyY2VbbmFtZV1cclxuICAgICAgICAgICAgICAgICAgICBldmVudFtuYW1lXSA9IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbcHJlZGljYXRlXSA9IHJldHVyblRydWVcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNvdXJjZU1ldGhvZCAmJiBzb3VyY2VNZXRob2QuYXBwbHkoc291cmNlLCBhcmd1bWVudHMpXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50W3ByZWRpY2F0ZV0gPSByZXR1cm5GYWxzZVxyXG4gICAgICAgICAgICAgICAgfSlcclxuXHJcbiAgICAgICAgICAgICAgICBldmVudC50aW1lU3RhbXAgfHwgKGV2ZW50LnRpbWVTdGFtcCA9IERhdGUubm93KCkpXHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHNvdXJjZS5kZWZhdWx0UHJldmVudGVkICE9PSB1bmRlZmluZWQgPyBzb3VyY2UuZGVmYXVsdFByZXZlbnRlZCA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdyZXR1cm5WYWx1ZScgaW4gc291cmNlID8gc291cmNlLnJldHVyblZhbHVlID09PSBmYWxzZSA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZS5nZXRQcmV2ZW50RGVmYXVsdCAmJiBzb3VyY2UuZ2V0UHJldmVudERlZmF1bHQoKSlcclxuICAgICAgICAgICAgICAgICAgICBldmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQgPSByZXR1cm5UcnVlXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGV2ZW50XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiBjcmVhdGVQcm94eShldmVudCkge1xyXG4gICAgICAgICAgICB2YXIga2V5LCBwcm94eSA9IHsgb3JpZ2luYWxFdmVudDogZXZlbnQgfVxyXG4gICAgICAgICAgICBmb3IgKGtleSBpbiBldmVudClcclxuICAgICAgICAgICAgICAgIGlmICghaWdub3JlUHJvcGVydGllcy50ZXN0KGtleSkgJiYgZXZlbnRba2V5XSAhPT0gdW5kZWZpbmVkKSBwcm94eVtrZXldID0gZXZlbnRba2V5XVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGNvbXBhdGlibGUocHJveHksIGV2ZW50KVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgJC5mbi5kZWxlZ2F0ZSA9IGZ1bmN0aW9uKHNlbGVjdG9yLCBldmVudCwgY2FsbGJhY2spe1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vbihldmVudCwgc2VsZWN0b3IsIGNhbGxiYWNrKVxyXG4gICAgICAgIH1cclxuICAgICAgICAkLmZuLnVuZGVsZWdhdGUgPSBmdW5jdGlvbihzZWxlY3RvciwgZXZlbnQsIGNhbGxiYWNrKXtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMub2ZmKGV2ZW50LCBzZWxlY3RvciwgY2FsbGJhY2spXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAkLmZuLmxpdmUgPSBmdW5jdGlvbihldmVudCwgY2FsbGJhY2spe1xyXG4gICAgICAgICAgICAkKGRvY3VtZW50LmJvZHkpLmRlbGVnYXRlKHRoaXMuc2VsZWN0b3IsIGV2ZW50LCBjYWxsYmFjaylcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXNcclxuICAgICAgICB9XHJcbiAgICAgICAgJC5mbi5kaWUgPSBmdW5jdGlvbihldmVudCwgY2FsbGJhY2spe1xyXG4gICAgICAgICAgICAkKGRvY3VtZW50LmJvZHkpLnVuZGVsZWdhdGUodGhpcy5zZWxlY3RvciwgZXZlbnQsIGNhbGxiYWNrKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpc1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgJC5mbi5vbiA9IGZ1bmN0aW9uKGV2ZW50LCBzZWxlY3RvciwgZGF0YSwgY2FsbGJhY2ssIG9uZSl7XHJcbiAgICAgICAgICAgIHZhciBhdXRvUmVtb3ZlLCBkZWxlZ2F0b3IsICR0aGlzID0gdGhpc1xyXG4gICAgICAgICAgICBpZiAoZXZlbnQgJiYgIWlzU3RyaW5nKGV2ZW50KSkge1xyXG4gICAgICAgICAgICAgICAgJC5lYWNoKGV2ZW50LCBmdW5jdGlvbih0eXBlLCBmbil7XHJcbiAgICAgICAgICAgICAgICAgICAgJHRoaXMub24odHlwZSwgc2VsZWN0b3IsIGRhdGEsIGZuLCBvbmUpXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICR0aGlzXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghaXNTdHJpbmcoc2VsZWN0b3IpICYmICFpc0Z1bmN0aW9uKGNhbGxiYWNrKSAmJiBjYWxsYmFjayAhPT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICBjYWxsYmFjayA9IGRhdGEsIGRhdGEgPSBzZWxlY3Rvciwgc2VsZWN0b3IgPSB1bmRlZmluZWRcclxuICAgICAgICAgICAgaWYgKGNhbGxiYWNrID09PSB1bmRlZmluZWQgfHwgZGF0YSA9PT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICBjYWxsYmFjayA9IGRhdGEsIGRhdGEgPSB1bmRlZmluZWRcclxuXHJcbiAgICAgICAgICAgIGlmIChjYWxsYmFjayA9PT0gZmFsc2UpIGNhbGxiYWNrID0gcmV0dXJuRmFsc2VcclxuXHJcbiAgICAgICAgICAgIHJldHVybiAkdGhpcy5lYWNoKGZ1bmN0aW9uKF8sIGVsZW1lbnQpe1xyXG4gICAgICAgICAgICAgICAgaWYgKG9uZSkgYXV0b1JlbW92ZSA9IGZ1bmN0aW9uKGUpe1xyXG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZShlbGVtZW50LCBlLnR5cGUsIGNhbGxiYWNrKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmd1bWVudHMpXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdG9yKSBkZWxlZ2F0b3IgPSBmdW5jdGlvbihlKXtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXZ0LCBtYXRjaCA9ICQoZS50YXJnZXQpLmNsb3Nlc3Qoc2VsZWN0b3IsIGVsZW1lbnQpLmdldCgwKVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaCAmJiBtYXRjaCAhPT0gZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBldnQgPSAkLmV4dGVuZChjcmVhdGVQcm94eShlKSwge2N1cnJlbnRUYXJnZXQ6IG1hdGNoLCBsaXZlRmlyZWQ6IGVsZW1lbnR9KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGF1dG9SZW1vdmUgfHwgY2FsbGJhY2spLmFwcGx5KG1hdGNoLCBbZXZ0XS5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKSlcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgYWRkKGVsZW1lbnQsIGV2ZW50LCBjYWxsYmFjaywgZGF0YSwgc2VsZWN0b3IsIGRlbGVnYXRvciB8fCBhdXRvUmVtb3ZlKVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgIH1cclxuICAgICAgICAkLmZuLm9mZiA9IGZ1bmN0aW9uKGV2ZW50LCBzZWxlY3RvciwgY2FsbGJhY2spe1xyXG4gICAgICAgICAgICB2YXIgJHRoaXMgPSB0aGlzXHJcbiAgICAgICAgICAgIGlmIChldmVudCAmJiAhaXNTdHJpbmcoZXZlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAkLmVhY2goZXZlbnQsIGZ1bmN0aW9uKHR5cGUsIGZuKXtcclxuICAgICAgICAgICAgICAgICAgICAkdGhpcy5vZmYodHlwZSwgc2VsZWN0b3IsIGZuKVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgIHJldHVybiAkdGhpc1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIWlzU3RyaW5nKHNlbGVjdG9yKSAmJiAhaXNGdW5jdGlvbihjYWxsYmFjaykgJiYgY2FsbGJhY2sgIT09IGZhbHNlKVxyXG4gICAgICAgICAgICAgICAgY2FsbGJhY2sgPSBzZWxlY3Rvciwgc2VsZWN0b3IgPSB1bmRlZmluZWRcclxuXHJcbiAgICAgICAgICAgIGlmIChjYWxsYmFjayA9PT0gZmFsc2UpIGNhbGxiYWNrID0gcmV0dXJuRmFsc2VcclxuXHJcbiAgICAgICAgICAgIHJldHVybiAkdGhpcy5lYWNoKGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICAgICByZW1vdmUodGhpcywgZXZlbnQsIGNhbGxiYWNrLCBzZWxlY3RvcilcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgICQuZm4udHJpZ2dlciA9IGZ1bmN0aW9uKGV2ZW50LCBhcmdzKXtcclxuICAgICAgICAgICAgZXZlbnQgPSAoaXNTdHJpbmcoZXZlbnQpIHx8ICQuaXNQbGFpbk9iamVjdChldmVudCkpID8gJC5FdmVudChldmVudCkgOiBjb21wYXRpYmxlKGV2ZW50KVxyXG4gICAgICAgICAgICBldmVudC5fYXJncyA9IGFyZ3NcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAgICAgLy8gaGFuZGxlIGZvY3VzKCksIGJsdXIoKSBieSBjYWxsaW5nIHRoZW0gZGlyZWN0bHlcclxuICAgICAgICAgICAgICAgIGlmIChldmVudC50eXBlIGluIGZvY3VzICYmIHR5cGVvZiB0aGlzW2V2ZW50LnR5cGVdID09IFwiZnVuY3Rpb25cIikgdGhpc1tldmVudC50eXBlXSgpXHJcbiAgICAgICAgICAgICAgICAvLyBpdGVtcyBpbiB0aGUgY29sbGVjdGlvbiBtaWdodCBub3QgYmUgRE9NIGVsZW1lbnRzXHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICgnZGlzcGF0Y2hFdmVudCcgaW4gdGhpcykgdGhpcy5kaXNwYXRjaEV2ZW50KGV2ZW50KVxyXG4gICAgICAgICAgICAgICAgZWxzZSAkKHRoaXMpLnRyaWdnZXJIYW5kbGVyKGV2ZW50LCBhcmdzKVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gdHJpZ2dlcnMgZXZlbnQgaGFuZGxlcnMgb24gY3VycmVudCBlbGVtZW50IGp1c3QgYXMgaWYgYW4gZXZlbnQgb2NjdXJyZWQsXHJcbiAgICAgICAgLy8gZG9lc24ndCB0cmlnZ2VyIGFuIGFjdHVhbCBldmVudCwgZG9lc24ndCBidWJibGVcclxuICAgICAgICAkLmZuLnRyaWdnZXJIYW5kbGVyID0gZnVuY3Rpb24oZXZlbnQsIGFyZ3Mpe1xyXG4gICAgICAgICAgICB2YXIgZSwgcmVzdWx0XHJcbiAgICAgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbihpLCBlbGVtZW50KXtcclxuICAgICAgICAgICAgICAgIGUgPSBjcmVhdGVQcm94eShpc1N0cmluZyhldmVudCkgPyAkLkV2ZW50KGV2ZW50KSA6IGV2ZW50KVxyXG4gICAgICAgICAgICAgICAgZS5fYXJncyA9IGFyZ3NcclxuICAgICAgICAgICAgICAgIGUudGFyZ2V0ID0gZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgJC5lYWNoKGZpbmRIYW5kbGVycyhlbGVtZW50LCBldmVudC50eXBlIHx8IGV2ZW50KSwgZnVuY3Rpb24oaSwgaGFuZGxlcil7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gaGFuZGxlci5wcm94eShlKVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlLmlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkKCkpIHJldHVybiBmYWxzZVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdFxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gc2hvcnRjdXQgbWV0aG9kcyBmb3IgYC5iaW5kKGV2ZW50LCBmbilgIGZvciBlYWNoIGV2ZW50IHR5cGVcclxuICAgICAgICA7KCdmb2N1c2luIGZvY3Vzb3V0IGZvY3VzIGJsdXIgbG9hZCByZXNpemUgc2Nyb2xsIHVubG9hZCBjbGljayBkYmxjbGljayAnK1xyXG4gICAgICAgICdtb3VzZWRvd24gbW91c2V1cCBtb3VzZW1vdmUgbW91c2VvdmVyIG1vdXNlb3V0IG1vdXNlZW50ZXIgbW91c2VsZWF2ZSAnK1xyXG4gICAgICAgICdjaGFuZ2Ugc2VsZWN0IGtleWRvd24ga2V5cHJlc3Mga2V5dXAgZXJyb3InKS5zcGxpdCgnICcpLmZvckVhY2goZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgICAgICAgICAgJC5mbltldmVudF0gPSBmdW5jdGlvbihjYWxsYmFjaykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICgwIGluIGFyZ3VtZW50cykgP1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYmluZChldmVudCwgY2FsbGJhY2spIDpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZlbnQpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG5cclxuICAgICAgICAkLkV2ZW50ID0gZnVuY3Rpb24odHlwZSwgcHJvcHMpIHtcclxuICAgICAgICAgICAgaWYgKCFpc1N0cmluZyh0eXBlKSkgcHJvcHMgPSB0eXBlLCB0eXBlID0gcHJvcHMudHlwZVxyXG4gICAgICAgICAgICB2YXIgZXZlbnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudChzcGVjaWFsRXZlbnRzW3R5cGVdIHx8ICdFdmVudHMnKSwgYnViYmxlcyA9IHRydWVcclxuICAgICAgICAgICAgaWYgKHByb3BzKSBmb3IgKHZhciBuYW1lIGluIHByb3BzKSAobmFtZSA9PSAnYnViYmxlcycpID8gKGJ1YmJsZXMgPSAhIXByb3BzW25hbWVdKSA6IChldmVudFtuYW1lXSA9IHByb3BzW25hbWVdKVxyXG4gICAgICAgICAgICBldmVudC5pbml0RXZlbnQodHlwZSwgYnViYmxlcywgdHJ1ZSlcclxuICAgICAgICAgICAgcmV0dXJuIGNvbXBhdGlibGUoZXZlbnQpXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH0pKFplcHRvKVxyXG5cclxuICAgIDsoZnVuY3Rpb24oJCl7XHJcbiAgICAgICAgdmFyIGpzb25wSUQgPSArbmV3IERhdGUoKSxcclxuICAgICAgICAgICAgZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQsXHJcbiAgICAgICAgICAgIGtleSxcclxuICAgICAgICAgICAgbmFtZSxcclxuICAgICAgICAgICAgcnNjcmlwdCA9IC88c2NyaXB0XFxiW148XSooPzooPyE8XFwvc2NyaXB0Pik8W148XSopKjxcXC9zY3JpcHQ+L2dpLFxyXG4gICAgICAgICAgICBzY3JpcHRUeXBlUkUgPSAvXig/OnRleHR8YXBwbGljYXRpb24pXFwvamF2YXNjcmlwdC9pLFxyXG4gICAgICAgICAgICB4bWxUeXBlUkUgPSAvXig/OnRleHR8YXBwbGljYXRpb24pXFwveG1sL2ksXHJcbiAgICAgICAgICAgIGpzb25UeXBlID0gJ2FwcGxpY2F0aW9uL2pzb24nLFxyXG4gICAgICAgICAgICBodG1sVHlwZSA9ICd0ZXh0L2h0bWwnLFxyXG4gICAgICAgICAgICBibGFua1JFID0gL15cXHMqJC8sXHJcbiAgICAgICAgICAgIG9yaWdpbkFuY2hvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKVxyXG5cclxuICAgICAgICBvcmlnaW5BbmNob3IuaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmXHJcblxyXG4gICAgICAgIC8vIHRyaWdnZXIgYSBjdXN0b20gZXZlbnQgYW5kIHJldHVybiBmYWxzZSBpZiBpdCB3YXMgY2FuY2VsbGVkXHJcbiAgICAgICAgZnVuY3Rpb24gdHJpZ2dlckFuZFJldHVybihjb250ZXh0LCBldmVudE5hbWUsIGRhdGEpIHtcclxuICAgICAgICAgICAgdmFyIGV2ZW50ID0gJC5FdmVudChldmVudE5hbWUpXHJcbiAgICAgICAgICAgICQoY29udGV4dCkudHJpZ2dlcihldmVudCwgZGF0YSlcclxuICAgICAgICAgICAgcmV0dXJuICFldmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gdHJpZ2dlciBhbiBBamF4IFwiZ2xvYmFsXCIgZXZlbnRcclxuICAgICAgICBmdW5jdGlvbiB0cmlnZ2VyR2xvYmFsKHNldHRpbmdzLCBjb250ZXh0LCBldmVudE5hbWUsIGRhdGEpIHtcclxuICAgICAgICAgICAgaWYgKHNldHRpbmdzLmdsb2JhbCkgcmV0dXJuIHRyaWdnZXJBbmRSZXR1cm4oY29udGV4dCB8fCBkb2N1bWVudCwgZXZlbnROYW1lLCBkYXRhKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gTnVtYmVyIG9mIGFjdGl2ZSBBamF4IHJlcXVlc3RzXHJcbiAgICAgICAgJC5hY3RpdmUgPSAwXHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGFqYXhTdGFydChzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBpZiAoc2V0dGluZ3MuZ2xvYmFsICYmICQuYWN0aXZlKysgPT09IDApIHRyaWdnZXJHbG9iYWwoc2V0dGluZ3MsIG51bGwsICdhamF4U3RhcnQnKVxyXG4gICAgICAgIH1cclxuICAgICAgICBmdW5jdGlvbiBhamF4U3RvcChzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBpZiAoc2V0dGluZ3MuZ2xvYmFsICYmICEoLS0kLmFjdGl2ZSkpIHRyaWdnZXJHbG9iYWwoc2V0dGluZ3MsIG51bGwsICdhamF4U3RvcCcpXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyB0cmlnZ2VycyBhbiBleHRyYSBnbG9iYWwgZXZlbnQgXCJhamF4QmVmb3JlU2VuZFwiIHRoYXQncyBsaWtlIFwiYWpheFNlbmRcIiBidXQgY2FuY2VsYWJsZVxyXG4gICAgICAgIGZ1bmN0aW9uIGFqYXhCZWZvcmVTZW5kKHhociwgc2V0dGluZ3MpIHtcclxuICAgICAgICAgICAgdmFyIGNvbnRleHQgPSBzZXR0aW5ncy5jb250ZXh0XHJcbiAgICAgICAgICAgIGlmIChzZXR0aW5ncy5iZWZvcmVTZW5kLmNhbGwoY29udGV4dCwgeGhyLCBzZXR0aW5ncykgPT09IGZhbHNlIHx8XHJcbiAgICAgICAgICAgICAgICB0cmlnZ2VyR2xvYmFsKHNldHRpbmdzLCBjb250ZXh0LCAnYWpheEJlZm9yZVNlbmQnLCBbeGhyLCBzZXR0aW5nc10pID09PSBmYWxzZSlcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxyXG5cclxuICAgICAgICAgICAgdHJpZ2dlckdsb2JhbChzZXR0aW5ncywgY29udGV4dCwgJ2FqYXhTZW5kJywgW3hociwgc2V0dGluZ3NdKVxyXG4gICAgICAgIH1cclxuICAgICAgICBmdW5jdGlvbiBhamF4U3VjY2VzcyhkYXRhLCB4aHIsIHNldHRpbmdzLCBkZWZlcnJlZCkge1xyXG4gICAgICAgICAgICB2YXIgY29udGV4dCA9IHNldHRpbmdzLmNvbnRleHQsIHN0YXR1cyA9ICdzdWNjZXNzJ1xyXG4gICAgICAgICAgICBzZXR0aW5ncy5zdWNjZXNzLmNhbGwoY29udGV4dCwgZGF0YSwgc3RhdHVzLCB4aHIpXHJcbiAgICAgICAgICAgIGlmIChkZWZlcnJlZCkgZGVmZXJyZWQucmVzb2x2ZVdpdGgoY29udGV4dCwgW2RhdGEsIHN0YXR1cywgeGhyXSlcclxuICAgICAgICAgICAgdHJpZ2dlckdsb2JhbChzZXR0aW5ncywgY29udGV4dCwgJ2FqYXhTdWNjZXNzJywgW3hociwgc2V0dGluZ3MsIGRhdGFdKVxyXG4gICAgICAgICAgICBhamF4Q29tcGxldGUoc3RhdHVzLCB4aHIsIHNldHRpbmdzKVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyB0eXBlOiBcInRpbWVvdXRcIiwgXCJlcnJvclwiLCBcImFib3J0XCIsIFwicGFyc2VyZXJyb3JcIlxyXG4gICAgICAgIGZ1bmN0aW9uIGFqYXhFcnJvcihlcnJvciwgdHlwZSwgeGhyLCBzZXR0aW5ncywgZGVmZXJyZWQpIHtcclxuICAgICAgICAgICAgdmFyIGNvbnRleHQgPSBzZXR0aW5ncy5jb250ZXh0XHJcbiAgICAgICAgICAgIHNldHRpbmdzLmVycm9yLmNhbGwoY29udGV4dCwgeGhyLCB0eXBlLCBlcnJvcilcclxuICAgICAgICAgICAgaWYgKGRlZmVycmVkKSBkZWZlcnJlZC5yZWplY3RXaXRoKGNvbnRleHQsIFt4aHIsIHR5cGUsIGVycm9yXSlcclxuICAgICAgICAgICAgdHJpZ2dlckdsb2JhbChzZXR0aW5ncywgY29udGV4dCwgJ2FqYXhFcnJvcicsIFt4aHIsIHNldHRpbmdzLCBlcnJvciB8fCB0eXBlXSlcclxuICAgICAgICAgICAgYWpheENvbXBsZXRlKHR5cGUsIHhociwgc2V0dGluZ3MpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHN0YXR1czogXCJzdWNjZXNzXCIsIFwibm90bW9kaWZpZWRcIiwgXCJlcnJvclwiLCBcInRpbWVvdXRcIiwgXCJhYm9ydFwiLCBcInBhcnNlcmVycm9yXCJcclxuICAgICAgICBmdW5jdGlvbiBhamF4Q29tcGxldGUoc3RhdHVzLCB4aHIsIHNldHRpbmdzKSB7XHJcbiAgICAgICAgICAgIHZhciBjb250ZXh0ID0gc2V0dGluZ3MuY29udGV4dFxyXG4gICAgICAgICAgICBzZXR0aW5ncy5jb21wbGV0ZS5jYWxsKGNvbnRleHQsIHhociwgc3RhdHVzKVxyXG4gICAgICAgICAgICB0cmlnZ2VyR2xvYmFsKHNldHRpbmdzLCBjb250ZXh0LCAnYWpheENvbXBsZXRlJywgW3hociwgc2V0dGluZ3NdKVxyXG4gICAgICAgICAgICBhamF4U3RvcChzZXR0aW5ncylcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGFqYXhEYXRhRmlsdGVyKGRhdGEsIHR5cGUsIHNldHRpbmdzKSB7XHJcbiAgICAgICAgICAgIGlmIChzZXR0aW5ncy5kYXRhRmlsdGVyID09IGVtcHR5KSByZXR1cm4gZGF0YVxyXG4gICAgICAgICAgICB2YXIgY29udGV4dCA9IHNldHRpbmdzLmNvbnRleHRcclxuICAgICAgICAgICAgcmV0dXJuIHNldHRpbmdzLmRhdGFGaWx0ZXIuY2FsbChjb250ZXh0LCBkYXRhLCB0eXBlKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRW1wdHkgZnVuY3Rpb24sIHVzZWQgYXMgZGVmYXVsdCBjYWxsYmFja1xyXG4gICAgICAgIGZ1bmN0aW9uIGVtcHR5KCkge31cclxuXHJcbiAgICAgICAgJC5hamF4SlNPTlAgPSBmdW5jdGlvbihvcHRpb25zLCBkZWZlcnJlZCl7XHJcbiAgICAgICAgICAgIGlmICghKCd0eXBlJyBpbiBvcHRpb25zKSkgcmV0dXJuICQuYWpheChvcHRpb25zKVxyXG5cclxuICAgICAgICAgICAgdmFyIF9jYWxsYmFja05hbWUgPSBvcHRpb25zLmpzb25wQ2FsbGJhY2ssXHJcbiAgICAgICAgICAgICAgICBjYWxsYmFja05hbWUgPSAoJC5pc0Z1bmN0aW9uKF9jYWxsYmFja05hbWUpID9cclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NhbGxiYWNrTmFtZSgpIDogX2NhbGxiYWNrTmFtZSkgfHwgKCdaZXB0bycgKyAoanNvbnBJRCsrKSksXHJcbiAgICAgICAgICAgICAgICBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKSxcclxuICAgICAgICAgICAgICAgIG9yaWdpbmFsQ2FsbGJhY2sgPSB3aW5kb3dbY2FsbGJhY2tOYW1lXSxcclxuICAgICAgICAgICAgICAgIHJlc3BvbnNlRGF0YSxcclxuICAgICAgICAgICAgICAgIGFib3J0ID0gZnVuY3Rpb24oZXJyb3JUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgJChzY3JpcHQpLnRyaWdnZXJIYW5kbGVyKCdlcnJvcicsIGVycm9yVHlwZSB8fCAnYWJvcnQnKVxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIHhociA9IHsgYWJvcnQ6IGFib3J0IH0sIGFib3J0VGltZW91dFxyXG5cclxuICAgICAgICAgICAgaWYgKGRlZmVycmVkKSBkZWZlcnJlZC5wcm9taXNlKHhocilcclxuXHJcbiAgICAgICAgICAgICQoc2NyaXB0KS5vbignbG9hZCBlcnJvcicsIGZ1bmN0aW9uKGUsIGVycm9yVHlwZSl7XHJcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoYWJvcnRUaW1lb3V0KVxyXG4gICAgICAgICAgICAgICAgJChzY3JpcHQpLm9mZigpLnJlbW92ZSgpXHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGUudHlwZSA9PSAnZXJyb3InIHx8ICFyZXNwb25zZURhdGEpIHtcclxuICAgICAgICAgICAgICAgICAgICBhamF4RXJyb3IobnVsbCwgZXJyb3JUeXBlIHx8ICdlcnJvcicsIHhociwgb3B0aW9ucywgZGVmZXJyZWQpXHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGFqYXhTdWNjZXNzKHJlc3BvbnNlRGF0YVswXSwgeGhyLCBvcHRpb25zLCBkZWZlcnJlZClcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB3aW5kb3dbY2FsbGJhY2tOYW1lXSA9IG9yaWdpbmFsQ2FsbGJhY2tcclxuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZURhdGEgJiYgJC5pc0Z1bmN0aW9uKG9yaWdpbmFsQ2FsbGJhY2spKVxyXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsQ2FsbGJhY2socmVzcG9uc2VEYXRhWzBdKVxyXG5cclxuICAgICAgICAgICAgICAgIG9yaWdpbmFsQ2FsbGJhY2sgPSByZXNwb25zZURhdGEgPSB1bmRlZmluZWRcclxuICAgICAgICAgICAgfSlcclxuXHJcbiAgICAgICAgICAgIGlmIChhamF4QmVmb3JlU2VuZCh4aHIsIG9wdGlvbnMpID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgYWJvcnQoJ2Fib3J0JylcclxuICAgICAgICAgICAgICAgIHJldHVybiB4aHJcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgd2luZG93W2NhbGxiYWNrTmFtZV0gPSBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAgICAgcmVzcG9uc2VEYXRhID0gYXJndW1lbnRzXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHNjcmlwdC5zcmMgPSBvcHRpb25zLnVybC5yZXBsYWNlKC9cXD8oLispPVxcPy8sICc/JDE9JyArIGNhbGxiYWNrTmFtZSlcclxuICAgICAgICAgICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpXHJcblxyXG4gICAgICAgICAgICBpZiAob3B0aW9ucy50aW1lb3V0ID4gMCkgYWJvcnRUaW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAgICAgYWJvcnQoJ3RpbWVvdXQnKVxyXG4gICAgICAgICAgICB9LCBvcHRpb25zLnRpbWVvdXQpXHJcblxyXG4gICAgICAgICAgICByZXR1cm4geGhyXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAkLmFqYXhTZXR0aW5ncyA9IHtcclxuICAgICAgICAgICAgLy8gRGVmYXVsdCB0eXBlIG9mIHJlcXVlc3RcclxuICAgICAgICAgICAgdHlwZTogJ0dFVCcsXHJcbiAgICAgICAgICAgIC8vIENhbGxiYWNrIHRoYXQgaXMgZXhlY3V0ZWQgYmVmb3JlIHJlcXVlc3RcclxuICAgICAgICAgICAgYmVmb3JlU2VuZDogZW1wdHksXHJcbiAgICAgICAgICAgIC8vIENhbGxiYWNrIHRoYXQgaXMgZXhlY3V0ZWQgaWYgdGhlIHJlcXVlc3Qgc3VjY2VlZHNcclxuICAgICAgICAgICAgc3VjY2VzczogZW1wdHksXHJcbiAgICAgICAgICAgIC8vIENhbGxiYWNrIHRoYXQgaXMgZXhlY3V0ZWQgdGhlIHRoZSBzZXJ2ZXIgZHJvcHMgZXJyb3JcclxuICAgICAgICAgICAgZXJyb3I6IGVtcHR5LFxyXG4gICAgICAgICAgICAvLyBDYWxsYmFjayB0aGF0IGlzIGV4ZWN1dGVkIG9uIHJlcXVlc3QgY29tcGxldGUgKGJvdGg6IGVycm9yIGFuZCBzdWNjZXNzKVxyXG4gICAgICAgICAgICBjb21wbGV0ZTogZW1wdHksXHJcbiAgICAgICAgICAgIC8vIFRoZSBjb250ZXh0IGZvciB0aGUgY2FsbGJhY2tzXHJcbiAgICAgICAgICAgIGNvbnRleHQ6IG51bGwsXHJcbiAgICAgICAgICAgIC8vIFdoZXRoZXIgdG8gdHJpZ2dlciBcImdsb2JhbFwiIEFqYXggZXZlbnRzXHJcbiAgICAgICAgICAgIGdsb2JhbDogdHJ1ZSxcclxuICAgICAgICAgICAgLy8gVHJhbnNwb3J0XHJcbiAgICAgICAgICAgIHhocjogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB3aW5kb3cuWE1MSHR0cFJlcXVlc3QoKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvLyBNSU1FIHR5cGVzIG1hcHBpbmdcclxuICAgICAgICAgICAgLy8gSUlTIHJldHVybnMgSmF2YXNjcmlwdCBhcyBcImFwcGxpY2F0aW9uL3gtamF2YXNjcmlwdFwiXHJcbiAgICAgICAgICAgIGFjY2VwdHM6IHtcclxuICAgICAgICAgICAgICAgIHNjcmlwdDogJ3RleHQvamF2YXNjcmlwdCwgYXBwbGljYXRpb24vamF2YXNjcmlwdCwgYXBwbGljYXRpb24veC1qYXZhc2NyaXB0JyxcclxuICAgICAgICAgICAgICAgIGpzb246ICAganNvblR5cGUsXHJcbiAgICAgICAgICAgICAgICB4bWw6ICAgICdhcHBsaWNhdGlvbi94bWwsIHRleHQveG1sJyxcclxuICAgICAgICAgICAgICAgIGh0bWw6ICAgaHRtbFR5cGUsXHJcbiAgICAgICAgICAgICAgICB0ZXh0OiAgICd0ZXh0L3BsYWluJ1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvLyBXaGV0aGVyIHRoZSByZXF1ZXN0IGlzIHRvIGFub3RoZXIgZG9tYWluXHJcbiAgICAgICAgICAgIGNyb3NzRG9tYWluOiBmYWxzZSxcclxuICAgICAgICAgICAgLy8gRGVmYXVsdCB0aW1lb3V0XHJcbiAgICAgICAgICAgIHRpbWVvdXQ6IDAsXHJcbiAgICAgICAgICAgIC8vIFdoZXRoZXIgZGF0YSBzaG91bGQgYmUgc2VyaWFsaXplZCB0byBzdHJpbmdcclxuICAgICAgICAgICAgcHJvY2Vzc0RhdGE6IHRydWUsXHJcbiAgICAgICAgICAgIC8vIFdoZXRoZXIgdGhlIGJyb3dzZXIgc2hvdWxkIGJlIGFsbG93ZWQgdG8gY2FjaGUgR0VUIHJlc3BvbnNlc1xyXG4gICAgICAgICAgICBjYWNoZTogdHJ1ZSxcclxuICAgICAgICAgICAgLy9Vc2VkIHRvIGhhbmRsZSB0aGUgcmF3IHJlc3BvbnNlIGRhdGEgb2YgWE1MSHR0cFJlcXVlc3QuXHJcbiAgICAgICAgICAgIC8vVGhpcyBpcyBhIHByZS1maWx0ZXJpbmcgZnVuY3Rpb24gdG8gc2FuaXRpemUgdGhlIHJlc3BvbnNlLlxyXG4gICAgICAgICAgICAvL1RoZSBzYW5pdGl6ZWQgcmVzcG9uc2Ugc2hvdWxkIGJlIHJldHVybmVkXHJcbiAgICAgICAgICAgIGRhdGFGaWx0ZXI6IGVtcHR5XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiBtaW1lVG9EYXRhVHlwZShtaW1lKSB7XHJcbiAgICAgICAgICAgIGlmIChtaW1lKSBtaW1lID0gbWltZS5zcGxpdCgnOycsIDIpWzBdXHJcbiAgICAgICAgICAgIHJldHVybiBtaW1lICYmICggbWltZSA9PSBodG1sVHlwZSA/ICdodG1sJyA6XHJcbiAgICAgICAgICAgICAgICAgICAgbWltZSA9PSBqc29uVHlwZSA/ICdqc29uJyA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmlwdFR5cGVSRS50ZXN0KG1pbWUpID8gJ3NjcmlwdCcgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB4bWxUeXBlUkUudGVzdChtaW1lKSAmJiAneG1sJyApIHx8ICd0ZXh0J1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gYXBwZW5kUXVlcnkodXJsLCBxdWVyeSkge1xyXG4gICAgICAgICAgICBpZiAocXVlcnkgPT0gJycpIHJldHVybiB1cmxcclxuICAgICAgICAgICAgcmV0dXJuICh1cmwgKyAnJicgKyBxdWVyeSkucmVwbGFjZSgvWyY/XXsxLDJ9LywgJz8nKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gc2VyaWFsaXplIHBheWxvYWQgYW5kIGFwcGVuZCBpdCB0byB0aGUgVVJMIGZvciBHRVQgcmVxdWVzdHNcclxuICAgICAgICBmdW5jdGlvbiBzZXJpYWxpemVEYXRhKG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMucHJvY2Vzc0RhdGEgJiYgb3B0aW9ucy5kYXRhICYmICQudHlwZShvcHRpb25zLmRhdGEpICE9IFwic3RyaW5nXCIpXHJcbiAgICAgICAgICAgICAgICBvcHRpb25zLmRhdGEgPSAkLnBhcmFtKG9wdGlvbnMuZGF0YSwgb3B0aW9ucy50cmFkaXRpb25hbClcclxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGF0YSAmJiAoIW9wdGlvbnMudHlwZSB8fCBvcHRpb25zLnR5cGUudG9VcHBlckNhc2UoKSA9PSAnR0VUJyB8fCAnanNvbnAnID09IG9wdGlvbnMuZGF0YVR5cGUpKVxyXG4gICAgICAgICAgICAgICAgb3B0aW9ucy51cmwgPSBhcHBlbmRRdWVyeShvcHRpb25zLnVybCwgb3B0aW9ucy5kYXRhKSwgb3B0aW9ucy5kYXRhID0gdW5kZWZpbmVkXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAkLmFqYXggPSBmdW5jdGlvbihvcHRpb25zKXtcclxuICAgICAgICAgICAgdmFyIHNldHRpbmdzID0gJC5leHRlbmQoe30sIG9wdGlvbnMgfHwge30pLFxyXG4gICAgICAgICAgICAgICAgZGVmZXJyZWQgPSAkLkRlZmVycmVkICYmICQuRGVmZXJyZWQoKSxcclxuICAgICAgICAgICAgICAgIHVybEFuY2hvciwgaGFzaEluZGV4XHJcbiAgICAgICAgICAgIGZvciAoa2V5IGluICQuYWpheFNldHRpbmdzKSBpZiAoc2V0dGluZ3Nba2V5XSA9PT0gdW5kZWZpbmVkKSBzZXR0aW5nc1trZXldID0gJC5hamF4U2V0dGluZ3Nba2V5XVxyXG5cclxuICAgICAgICAgICAgYWpheFN0YXJ0KHNldHRpbmdzKVxyXG5cclxuICAgICAgICAgICAgaWYgKCFzZXR0aW5ncy5jcm9zc0RvbWFpbikge1xyXG4gICAgICAgICAgICAgICAgdXJsQW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpXHJcbiAgICAgICAgICAgICAgICB1cmxBbmNob3IuaHJlZiA9IHNldHRpbmdzLnVybFxyXG4gICAgICAgICAgICAgICAgLy8gY2xlYW5zIHVwIFVSTCBmb3IgLmhyZWYgKElFIG9ubHkpLCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL21hZHJvYmJ5L3plcHRvL3B1bGwvMTA0OVxyXG4gICAgICAgICAgICAgICAgdXJsQW5jaG9yLmhyZWYgPSB1cmxBbmNob3IuaHJlZlxyXG4gICAgICAgICAgICAgICAgc2V0dGluZ3MuY3Jvc3NEb21haW4gPSAob3JpZ2luQW5jaG9yLnByb3RvY29sICsgJy8vJyArIG9yaWdpbkFuY2hvci5ob3N0KSAhPT0gKHVybEFuY2hvci5wcm90b2NvbCArICcvLycgKyB1cmxBbmNob3IuaG9zdClcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCFzZXR0aW5ncy51cmwpIHNldHRpbmdzLnVybCA9IHdpbmRvdy5sb2NhdGlvbi50b1N0cmluZygpXHJcbiAgICAgICAgICAgIGlmICgoaGFzaEluZGV4ID0gc2V0dGluZ3MudXJsLmluZGV4T2YoJyMnKSkgPiAtMSkgc2V0dGluZ3MudXJsID0gc2V0dGluZ3MudXJsLnNsaWNlKDAsIGhhc2hJbmRleClcclxuICAgICAgICAgICAgc2VyaWFsaXplRGF0YShzZXR0aW5ncylcclxuXHJcbiAgICAgICAgICAgIHZhciBkYXRhVHlwZSA9IHNldHRpbmdzLmRhdGFUeXBlLCBoYXNQbGFjZWhvbGRlciA9IC9cXD8uKz1cXD8vLnRlc3Qoc2V0dGluZ3MudXJsKVxyXG4gICAgICAgICAgICBpZiAoaGFzUGxhY2Vob2xkZXIpIGRhdGFUeXBlID0gJ2pzb25wJ1xyXG5cclxuICAgICAgICAgICAgaWYgKHNldHRpbmdzLmNhY2hlID09PSBmYWxzZSB8fCAoXHJcbiAgICAgICAgICAgICAgICAgICAgKCFvcHRpb25zIHx8IG9wdGlvbnMuY2FjaGUgIT09IHRydWUpICYmXHJcbiAgICAgICAgICAgICAgICAgICAgKCdzY3JpcHQnID09IGRhdGFUeXBlIHx8ICdqc29ucCcgPT0gZGF0YVR5cGUpXHJcbiAgICAgICAgICAgICAgICApKVxyXG4gICAgICAgICAgICAgICAgc2V0dGluZ3MudXJsID0gYXBwZW5kUXVlcnkoc2V0dGluZ3MudXJsLCAnXz0nICsgRGF0ZS5ub3coKSlcclxuXHJcbiAgICAgICAgICAgIGlmICgnanNvbnAnID09IGRhdGFUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWhhc1BsYWNlaG9sZGVyKVxyXG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmdzLnVybCA9IGFwcGVuZFF1ZXJ5KHNldHRpbmdzLnVybCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3MuanNvbnAgPyAoc2V0dGluZ3MuanNvbnAgKyAnPT8nKSA6IHNldHRpbmdzLmpzb25wID09PSBmYWxzZSA/ICcnIDogJ2NhbGxiYWNrPT8nKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICQuYWpheEpTT05QKHNldHRpbmdzLCBkZWZlcnJlZClcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdmFyIG1pbWUgPSBzZXR0aW5ncy5hY2NlcHRzW2RhdGFUeXBlXSxcclxuICAgICAgICAgICAgICAgIGhlYWRlcnMgPSB7IH0sXHJcbiAgICAgICAgICAgICAgICBzZXRIZWFkZXIgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSkgeyBoZWFkZXJzW25hbWUudG9Mb3dlckNhc2UoKV0gPSBbbmFtZSwgdmFsdWVdIH0sXHJcbiAgICAgICAgICAgICAgICBwcm90b2NvbCA9IC9eKFtcXHctXSs6KVxcL1xcLy8udGVzdChzZXR0aW5ncy51cmwpID8gUmVnRXhwLiQxIDogd2luZG93LmxvY2F0aW9uLnByb3RvY29sLFxyXG4gICAgICAgICAgICAgICAgeGhyID0gc2V0dGluZ3MueGhyKCksXHJcbiAgICAgICAgICAgICAgICBuYXRpdmVTZXRIZWFkZXIgPSB4aHIuc2V0UmVxdWVzdEhlYWRlcixcclxuICAgICAgICAgICAgICAgIGFib3J0VGltZW91dFxyXG5cclxuICAgICAgICAgICAgaWYgKGRlZmVycmVkKSBkZWZlcnJlZC5wcm9taXNlKHhocilcclxuXHJcbiAgICAgICAgICAgIGlmICghc2V0dGluZ3MuY3Jvc3NEb21haW4pIHNldEhlYWRlcignWC1SZXF1ZXN0ZWQtV2l0aCcsICdYTUxIdHRwUmVxdWVzdCcpXHJcbiAgICAgICAgICAgIHNldEhlYWRlcignQWNjZXB0JywgbWltZSB8fCAnKi8qJylcclxuICAgICAgICAgICAgaWYgKG1pbWUgPSBzZXR0aW5ncy5taW1lVHlwZSB8fCBtaW1lKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAobWltZS5pbmRleE9mKCcsJykgPiAtMSkgbWltZSA9IG1pbWUuc3BsaXQoJywnLCAyKVswXVxyXG4gICAgICAgICAgICAgICAgeGhyLm92ZXJyaWRlTWltZVR5cGUgJiYgeGhyLm92ZXJyaWRlTWltZVR5cGUobWltZSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc2V0dGluZ3MuY29udGVudFR5cGUgfHwgKHNldHRpbmdzLmNvbnRlbnRUeXBlICE9PSBmYWxzZSAmJiBzZXR0aW5ncy5kYXRhICYmIHNldHRpbmdzLnR5cGUudG9VcHBlckNhc2UoKSAhPSAnR0VUJykpXHJcbiAgICAgICAgICAgICAgICBzZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsIHNldHRpbmdzLmNvbnRlbnRUeXBlIHx8ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKVxyXG5cclxuICAgICAgICAgICAgaWYgKHNldHRpbmdzLmhlYWRlcnMpIGZvciAobmFtZSBpbiBzZXR0aW5ncy5oZWFkZXJzKSBzZXRIZWFkZXIobmFtZSwgc2V0dGluZ3MuaGVhZGVyc1tuYW1lXSlcclxuICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIgPSBzZXRIZWFkZXJcclxuXHJcbiAgICAgICAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAgICAgaWYgKHhoci5yZWFkeVN0YXRlID09IDQpIHtcclxuICAgICAgICAgICAgICAgICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZW1wdHlcclxuICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoYWJvcnRUaW1lb3V0KVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQsIGVycm9yID0gZmFsc2VcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKHhoci5zdGF0dXMgPj0gMjAwICYmIHhoci5zdGF0dXMgPCAzMDApIHx8IHhoci5zdGF0dXMgPT0gMzA0IHx8ICh4aHIuc3RhdHVzID09IDAgJiYgcHJvdG9jb2wgPT0gJ2ZpbGU6JykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGUgPSBkYXRhVHlwZSB8fCBtaW1lVG9EYXRhVHlwZShzZXR0aW5ncy5taW1lVHlwZSB8fCB4aHIuZ2V0UmVzcG9uc2VIZWFkZXIoJ2NvbnRlbnQtdHlwZScpKVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHhoci5yZXNwb25zZVR5cGUgPT0gJ2FycmF5YnVmZmVyJyB8fCB4aHIucmVzcG9uc2VUeXBlID09ICdibG9iJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHhoci5yZXNwb25zZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHhoci5yZXNwb25zZVRleHRcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly9wZXJmZWN0aW9ua2lsbHMuY29tL2dsb2JhbC1ldmFsLXdoYXQtYXJlLXRoZS1vcHRpb25zL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNhbml0aXplIHJlc3BvbnNlIGFjY29yZGluZ2x5IGlmIGRhdGEgZmlsdGVyIGNhbGxiYWNrIHByb3ZpZGVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gYWpheERhdGFGaWx0ZXIocmVzdWx0LCBkYXRhVHlwZSwgc2V0dGluZ3MpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFUeXBlID09ICdzY3JpcHQnKSAgICAoMSxldmFsKShyZXN1bHQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZGF0YVR5cGUgPT0gJ3htbCcpICByZXN1bHQgPSB4aHIucmVzcG9uc2VYTUxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChkYXRhVHlwZSA9PSAnanNvbicpIHJlc3VsdCA9IGJsYW5rUkUudGVzdChyZXN1bHQpID8gbnVsbCA6ICQucGFyc2VKU09OKHJlc3VsdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsgZXJyb3IgPSBlIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHJldHVybiBhamF4RXJyb3IoZXJyb3IsICdwYXJzZXJlcnJvcicsIHhociwgc2V0dGluZ3MsIGRlZmVycmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhamF4U3VjY2VzcyhyZXN1bHQsIHhociwgc2V0dGluZ3MsIGRlZmVycmVkKVxyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFqYXhFcnJvcih4aHIuc3RhdHVzVGV4dCB8fCBudWxsLCB4aHIuc3RhdHVzID8gJ2Vycm9yJyA6ICdhYm9ydCcsIHhociwgc2V0dGluZ3MsIGRlZmVycmVkKVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGFqYXhCZWZvcmVTZW5kKHhociwgc2V0dGluZ3MpID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgeGhyLmFib3J0KClcclxuICAgICAgICAgICAgICAgIGFqYXhFcnJvcihudWxsLCAnYWJvcnQnLCB4aHIsIHNldHRpbmdzLCBkZWZlcnJlZClcclxuICAgICAgICAgICAgICAgIHJldHVybiB4aHJcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdmFyIGFzeW5jID0gJ2FzeW5jJyBpbiBzZXR0aW5ncyA/IHNldHRpbmdzLmFzeW5jIDogdHJ1ZVxyXG4gICAgICAgICAgICB4aHIub3BlbihzZXR0aW5ncy50eXBlLCBzZXR0aW5ncy51cmwsIGFzeW5jLCBzZXR0aW5ncy51c2VybmFtZSwgc2V0dGluZ3MucGFzc3dvcmQpXHJcblxyXG4gICAgICAgICAgICBpZiAoc2V0dGluZ3MueGhyRmllbGRzKSBmb3IgKG5hbWUgaW4gc2V0dGluZ3MueGhyRmllbGRzKSB4aHJbbmFtZV0gPSBzZXR0aW5ncy54aHJGaWVsZHNbbmFtZV1cclxuXHJcbiAgICAgICAgICAgIGZvciAobmFtZSBpbiBoZWFkZXJzKSBuYXRpdmVTZXRIZWFkZXIuYXBwbHkoeGhyLCBoZWFkZXJzW25hbWVdKVxyXG5cclxuICAgICAgICAgICAgaWYgKHNldHRpbmdzLnRpbWVvdXQgPiAwKSBhYm9ydFRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZW1wdHlcclxuICAgICAgICAgICAgICAgIHhoci5hYm9ydCgpXHJcbiAgICAgICAgICAgICAgICBhamF4RXJyb3IobnVsbCwgJ3RpbWVvdXQnLCB4aHIsIHNldHRpbmdzLCBkZWZlcnJlZClcclxuICAgICAgICAgICAgfSwgc2V0dGluZ3MudGltZW91dClcclxuXHJcbiAgICAgICAgICAgIC8vIGF2b2lkIHNlbmRpbmcgZW1wdHkgc3RyaW5nICgjMzE5KVxyXG4gICAgICAgICAgICB4aHIuc2VuZChzZXR0aW5ncy5kYXRhID8gc2V0dGluZ3MuZGF0YSA6IG51bGwpXHJcbiAgICAgICAgICAgIHJldHVybiB4aHJcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGhhbmRsZSBvcHRpb25hbCBkYXRhL3N1Y2Nlc3MgYXJndW1lbnRzXHJcbiAgICAgICAgZnVuY3Rpb24gcGFyc2VBcmd1bWVudHModXJsLCBkYXRhLCBzdWNjZXNzLCBkYXRhVHlwZSkge1xyXG4gICAgICAgICAgICBpZiAoJC5pc0Z1bmN0aW9uKGRhdGEpKSBkYXRhVHlwZSA9IHN1Y2Nlc3MsIHN1Y2Nlc3MgPSBkYXRhLCBkYXRhID0gdW5kZWZpbmVkXHJcbiAgICAgICAgICAgIGlmICghJC5pc0Z1bmN0aW9uKHN1Y2Nlc3MpKSBkYXRhVHlwZSA9IHN1Y2Nlc3MsIHN1Y2Nlc3MgPSB1bmRlZmluZWRcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIHVybDogdXJsXHJcbiAgICAgICAgICAgICAgICAsIGRhdGE6IGRhdGFcclxuICAgICAgICAgICAgICAgICwgc3VjY2Vzczogc3VjY2Vzc1xyXG4gICAgICAgICAgICAgICAgLCBkYXRhVHlwZTogZGF0YVR5cGVcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgJC5nZXQgPSBmdW5jdGlvbigvKiB1cmwsIGRhdGEsIHN1Y2Nlc3MsIGRhdGFUeXBlICovKXtcclxuICAgICAgICAgICAgcmV0dXJuICQuYWpheChwYXJzZUFyZ3VtZW50cy5hcHBseShudWxsLCBhcmd1bWVudHMpKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgJC5wb3N0ID0gZnVuY3Rpb24oLyogdXJsLCBkYXRhLCBzdWNjZXNzLCBkYXRhVHlwZSAqLyl7XHJcbiAgICAgICAgICAgIHZhciBvcHRpb25zID0gcGFyc2VBcmd1bWVudHMuYXBwbHkobnVsbCwgYXJndW1lbnRzKVxyXG4gICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAnUE9TVCdcclxuICAgICAgICAgICAgcmV0dXJuICQuYWpheChvcHRpb25zKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgJC5nZXRKU09OID0gZnVuY3Rpb24oLyogdXJsLCBkYXRhLCBzdWNjZXNzICovKXtcclxuICAgICAgICAgICAgdmFyIG9wdGlvbnMgPSBwYXJzZUFyZ3VtZW50cy5hcHBseShudWxsLCBhcmd1bWVudHMpXHJcbiAgICAgICAgICAgIG9wdGlvbnMuZGF0YVR5cGUgPSAnanNvbidcclxuICAgICAgICAgICAgcmV0dXJuICQuYWpheChvcHRpb25zKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgJC5mbi5sb2FkID0gZnVuY3Rpb24odXJsLCBkYXRhLCBzdWNjZXNzKXtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmxlbmd0aCkgcmV0dXJuIHRoaXNcclxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzLCBwYXJ0cyA9IHVybC5zcGxpdCgvXFxzLyksIHNlbGVjdG9yLFxyXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHBhcnNlQXJndW1lbnRzKHVybCwgZGF0YSwgc3VjY2VzcyksXHJcbiAgICAgICAgICAgICAgICBjYWxsYmFjayA9IG9wdGlvbnMuc3VjY2Vzc1xyXG4gICAgICAgICAgICBpZiAocGFydHMubGVuZ3RoID4gMSkgb3B0aW9ucy51cmwgPSBwYXJ0c1swXSwgc2VsZWN0b3IgPSBwYXJ0c1sxXVxyXG4gICAgICAgICAgICBvcHRpb25zLnN1Y2Nlc3MgPSBmdW5jdGlvbihyZXNwb25zZSl7XHJcbiAgICAgICAgICAgICAgICBzZWxmLmh0bWwoc2VsZWN0b3IgP1xyXG4gICAgICAgICAgICAgICAgICAgICQoJzxkaXY+JykuaHRtbChyZXNwb25zZS5yZXBsYWNlKHJzY3JpcHQsIFwiXCIpKS5maW5kKHNlbGVjdG9yKVxyXG4gICAgICAgICAgICAgICAgICAgIDogcmVzcG9uc2UpXHJcbiAgICAgICAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjay5hcHBseShzZWxmLCBhcmd1bWVudHMpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgJC5hamF4KG9wdGlvbnMpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgZXNjYXBlID0gZW5jb2RlVVJJQ29tcG9uZW50XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHNlcmlhbGl6ZShwYXJhbXMsIG9iaiwgdHJhZGl0aW9uYWwsIHNjb3BlKXtcclxuICAgICAgICAgICAgdmFyIHR5cGUsIGFycmF5ID0gJC5pc0FycmF5KG9iaiksIGhhc2ggPSAkLmlzUGxhaW5PYmplY3Qob2JqKVxyXG4gICAgICAgICAgICAkLmVhY2gob2JqLCBmdW5jdGlvbihrZXksIHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICB0eXBlID0gJC50eXBlKHZhbHVlKVxyXG4gICAgICAgICAgICAgICAgaWYgKHNjb3BlKSBrZXkgPSB0cmFkaXRpb25hbCA/IHNjb3BlIDpcclxuICAgICAgICAgICAgICAgIHNjb3BlICsgJ1snICsgKGhhc2ggfHwgdHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdhcnJheScgPyBrZXkgOiAnJykgKyAnXSdcclxuICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBkYXRhIGluIHNlcmlhbGl6ZUFycmF5KCkgZm9ybWF0XHJcbiAgICAgICAgICAgICAgICBpZiAoIXNjb3BlICYmIGFycmF5KSBwYXJhbXMuYWRkKHZhbHVlLm5hbWUsIHZhbHVlLnZhbHVlKVxyXG4gICAgICAgICAgICAgICAgLy8gcmVjdXJzZSBpbnRvIG5lc3RlZCBvYmplY3RzXHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlID09IFwiYXJyYXlcIiB8fCAoIXRyYWRpdGlvbmFsICYmIHR5cGUgPT0gXCJvYmplY3RcIikpXHJcbiAgICAgICAgICAgICAgICAgICAgc2VyaWFsaXplKHBhcmFtcywgdmFsdWUsIHRyYWRpdGlvbmFsLCBrZXkpXHJcbiAgICAgICAgICAgICAgICBlbHNlIHBhcmFtcy5hZGQoa2V5LCB2YWx1ZSlcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgICQucGFyYW0gPSBmdW5jdGlvbihvYmosIHRyYWRpdGlvbmFsKXtcclxuICAgICAgICAgICAgdmFyIHBhcmFtcyA9IFtdXHJcbiAgICAgICAgICAgIHBhcmFtcy5hZGQgPSBmdW5jdGlvbihrZXksIHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoJC5pc0Z1bmN0aW9uKHZhbHVlKSkgdmFsdWUgPSB2YWx1ZSgpXHJcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgdmFsdWUgPSBcIlwiXHJcbiAgICAgICAgICAgICAgICB0aGlzLnB1c2goZXNjYXBlKGtleSkgKyAnPScgKyBlc2NhcGUodmFsdWUpKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHNlcmlhbGl6ZShwYXJhbXMsIG9iaiwgdHJhZGl0aW9uYWwpXHJcbiAgICAgICAgICAgIHJldHVybiBwYXJhbXMuam9pbignJicpLnJlcGxhY2UoLyUyMC9nLCAnKycpXHJcbiAgICAgICAgfVxyXG4gICAgfSkoWmVwdG8pXHJcblxyXG4gICAgOyhmdW5jdGlvbigkKXtcclxuICAgICAgICAkLmZuLnNlcmlhbGl6ZUFycmF5ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHZhciBuYW1lLCB0eXBlLCByZXN1bHQgPSBbXSxcclxuICAgICAgICAgICAgICAgIGFkZCA9IGZ1bmN0aW9uKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmZvckVhY2gpIHJldHVybiB2YWx1ZS5mb3JFYWNoKGFkZClcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaCh7IG5hbWU6IG5hbWUsIHZhbHVlOiB2YWx1ZSB9KVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodGhpc1swXSkgJC5lYWNoKHRoaXNbMF0uZWxlbWVudHMsIGZ1bmN0aW9uKF8sIGZpZWxkKXtcclxuICAgICAgICAgICAgICAgIHR5cGUgPSBmaWVsZC50eXBlLCBuYW1lID0gZmllbGQubmFtZVxyXG4gICAgICAgICAgICAgICAgaWYgKG5hbWUgJiYgZmllbGQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSAhPSAnZmllbGRzZXQnICYmXHJcbiAgICAgICAgICAgICAgICAgICAgIWZpZWxkLmRpc2FibGVkICYmIHR5cGUgIT0gJ3N1Ym1pdCcgJiYgdHlwZSAhPSAncmVzZXQnICYmIHR5cGUgIT0gJ2J1dHRvbicgJiYgdHlwZSAhPSAnZmlsZScgJiZcclxuICAgICAgICAgICAgICAgICAgICAoKHR5cGUgIT0gJ3JhZGlvJyAmJiB0eXBlICE9ICdjaGVja2JveCcpIHx8IGZpZWxkLmNoZWNrZWQpKVxyXG4gICAgICAgICAgICAgICAgICAgIGFkZCgkKGZpZWxkKS52YWwoKSlcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdFxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgJC5mbi5zZXJpYWxpemUgPSBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gW11cclxuICAgICAgICAgICAgdGhpcy5zZXJpYWxpemVBcnJheSgpLmZvckVhY2goZnVuY3Rpb24oZWxtKXtcclxuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChlbG0ubmFtZSkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQoZWxtLnZhbHVlKSlcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5qb2luKCcmJylcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgICQuZm4uc3VibWl0ID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgaWYgKDAgaW4gYXJndW1lbnRzKSB0aGlzLmJpbmQoJ3N1Ym1pdCcsIGNhbGxiYWNrKVxyXG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGV2ZW50ID0gJC5FdmVudCgnc3VibWl0JylcclxuICAgICAgICAgICAgICAgIHRoaXMuZXEoMCkudHJpZ2dlcihldmVudClcclxuICAgICAgICAgICAgICAgIGlmICghZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkpIHRoaXMuZ2V0KDApLnN1Ym1pdCgpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXNcclxuICAgICAgICB9XHJcblxyXG4gICAgfSkoWmVwdG8pXHJcblxyXG4gICAgOyhmdW5jdGlvbigpe1xyXG4gICAgICAgIC8vIGdldENvbXB1dGVkU3R5bGUgc2hvdWxkbid0IGZyZWFrIG91dCB3aGVuIGNhbGxlZFxyXG4gICAgICAgIC8vIHdpdGhvdXQgYSB2YWxpZCBlbGVtZW50IGFzIGFyZ3VtZW50XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgZ2V0Q29tcHV0ZWRTdHlsZSh1bmRlZmluZWQpXHJcbiAgICAgICAgfSBjYXRjaChlKSB7XHJcbiAgICAgICAgICAgIHZhciBuYXRpdmVHZXRDb21wdXRlZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZVxyXG4gICAgICAgICAgICB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIHBzZXVkb0VsZW1lbnQpe1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlR2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50LCBwc2V1ZG9FbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgfSBjYXRjaChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGxcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH0pKClcclxuICAgIHJldHVybiBaZXB0b1xyXG59KSlcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vbi16ZXB0by9uLXplcHRvLmpzXG4vLyBtb2R1bGUgaWQgPSAyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=");
},function(module,exports){eval("// removed by extract-text-webpack-plugin\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL2xlc3Mvc2Nob29sX2ludHJvLmxlc3M/ZDY1OCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSIsImZpbGUiOiIzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gcmVtb3ZlZCBieSBleHRyYWN0LXRleHQtd2VicGFjay1wbHVnaW5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9hc3NldHMvbGVzcy9zY2hvb2xfaW50cm8ubGVzc1xuLy8gbW9kdWxlIGlkID0gM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9")},function(module,exports,__webpack_require__){eval("/* WEBPACK VAR INJECTION */(function(global) {var require;var require;/*!\n * Less - Leaner CSS v2.7.1\n * http://lesscss.org\n *\n * Copyright (c) 2009-2016, Alexis Sellier <self@cloudhead.net>\n * Licensed under the Apache-2.0 License.\n *\n */\n\n /** * @license Apache-2.0\n */\n\n(function(f){if(true){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.less = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return require(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\nvar addDataAttr = require(\"./utils\").addDataAttr,\n    browser = require(\"./browser\");\n\nmodule.exports = function(window, options) {\n\n    // use options from the current script tag data attribues\n    addDataAttr(options, browser.currentScript(window));\n\n    if (options.isFileProtocol === undefined) {\n        options.isFileProtocol = /^(file|(chrome|safari)(-extension)?|resource|qrc|app):/.test(window.location.protocol);\n    }\n\n    // Load styles asynchronously (default: false)\n    //\n    // This is set to `false` by default, so that the body\n    // doesn't start loading before the stylesheets are parsed.\n    // Setting this to `true` can result in flickering.\n    //\n    options.async = options.async || false;\n    options.fileAsync = options.fileAsync || false;\n\n    // Interval between watch polls\n    options.poll = options.poll || (options.isFileProtocol ? 1000 : 1500);\n\n    options.env = options.env || (window.location.hostname == '127.0.0.1' ||\n        window.location.hostname == '0.0.0.0'   ||\n        window.location.hostname == 'localhost' ||\n        (window.location.port &&\n            window.location.port.length > 0)      ||\n        options.isFileProtocol                   ? 'development'\n        : 'production');\n\n    var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(window.location.hash);\n    if (dumpLineNumbers) {\n        options.dumpLineNumbers = dumpLineNumbers[1];\n    }\n\n    if (options.useFileCache === undefined) {\n        options.useFileCache = true;\n    }\n\n    if (options.onReady === undefined) {\n        options.onReady = true;\n    }\n\n};\n\n},{\"./browser\":3,\"./utils\":10}],2:[function(require,module,exports){\n/**\n * Kicks off less and compiles any stylesheets\n * used in the browser distributed version of less\n * to kick-start less using the browser api\n */\n/*global window, document */\n\n// shim Promise if required\nrequire('promise/polyfill.js');\n\nvar options = window.less || {};\nrequire(\"./add-default-options\")(window, options);\n\nvar less = module.exports = require(\"./index\")(window, options);\n\nwindow.less = less;\n\nvar css, head, style;\n\n// Always restore page visibility\nfunction resolveOrReject(data) {\n    if (data.filename) {\n        console.warn(data);\n    }\n    if (!options.async) {\n        head.removeChild(style);\n    }\n}\n\nif (options.onReady) {\n    if (/!watch/.test(window.location.hash)) {\n        less.watch();\n    }\n    // Simulate synchronous stylesheet loading by blocking page rendering\n    if (!options.async) {\n        css = 'body { display: none !important }';\n        head = document.head || document.getElementsByTagName('head')[0];\n        style = document.createElement('style');\n\n        style.type = 'text/css';\n        if (style.styleSheet) {\n            style.styleSheet.cssText = css;\n        } else {\n            style.appendChild(document.createTextNode(css));\n        }\n\n        head.appendChild(style);\n    }\n    less.registerStylesheetsImmediately();\n    less.pageLoadFinished = less.refresh(less.env === 'development').then(resolveOrReject, resolveOrReject);\n}\n\n},{\"./add-default-options\":1,\"./index\":8,\"promise/polyfill.js\":97}],3:[function(require,module,exports){\nvar utils = require(\"./utils\");\nmodule.exports = {\n    createCSS: function (document, styles, sheet) {\n        // Strip the query-string\n        var href = sheet.href || '';\n\n        // If there is no title set, use the filename, minus the extension\n        var id = 'less:' + (sheet.title || utils.extractId(href));\n\n        // If this has already been inserted into the DOM, we may need to replace it\n        var oldStyleNode = document.getElementById(id);\n        var keepOldStyleNode = false;\n\n        // Create a new stylesheet node for insertion or (if necessary) replacement\n        var styleNode = document.createElement('style');\n        styleNode.setAttribute('type', 'text/css');\n        if (sheet.media) {\n            styleNode.setAttribute('media', sheet.media);\n        }\n        styleNode.id = id;\n\n        if (!styleNode.styleSheet) {\n            styleNode.appendChild(document.createTextNode(styles));\n\n            // If new contents match contents of oldStyleNode, don't replace oldStyleNode\n            keepOldStyleNode = (oldStyleNode !== null && oldStyleNode.childNodes.length > 0 && styleNode.childNodes.length > 0 &&\n                oldStyleNode.firstChild.nodeValue === styleNode.firstChild.nodeValue);\n        }\n\n        var head = document.getElementsByTagName('head')[0];\n\n        // If there is no oldStyleNode, just append; otherwise, only append if we need\n        // to replace oldStyleNode with an updated stylesheet\n        if (oldStyleNode === null || keepOldStyleNode === false) {\n            var nextEl = sheet && sheet.nextSibling || null;\n            if (nextEl) {\n                nextEl.parentNode.insertBefore(styleNode, nextEl);\n            } else {\n                head.appendChild(styleNode);\n            }\n        }\n        if (oldStyleNode && keepOldStyleNode === false) {\n            oldStyleNode.parentNode.removeChild(oldStyleNode);\n        }\n\n        // For IE.\n        // This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash.\n        // See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head\n        if (styleNode.styleSheet) {\n            try {\n                styleNode.styleSheet.cssText = styles;\n            } catch (e) {\n                throw new Error(\"Couldn't reassign styleSheet.cssText.\");\n            }\n        }\n    },\n    currentScript: function(window) {\n        var document = window.document;\n        return document.currentScript || (function() {\n            var scripts = document.getElementsByTagName(\"script\");\n            return scripts[scripts.length - 1];\n        })();\n    }\n};\n\n},{\"./utils\":10}],4:[function(require,module,exports){\n// Cache system is a bit outdated and could do with work\n\nmodule.exports = function(window, options, logger) {\n    var cache = null;\n    if (options.env !== 'development') {\n        try {\n            cache = (typeof window.localStorage === 'undefined') ? null : window.localStorage;\n        } catch (_) {}\n    }\n    return {\n        setCSS: function(path, lastModified, modifyVars, styles) {\n            if (cache) {\n                logger.info('saving ' + path + ' to cache.');\n                try {\n                    cache.setItem(path, styles);\n                    cache.setItem(path + ':timestamp', lastModified);\n                    if (modifyVars) {\n                        cache.setItem(path + ':vars', JSON.stringify(modifyVars));\n                    }\n                } catch(e) {\n                    //TODO - could do with adding more robust error handling\n                    logger.error('failed to save \"' + path + '\" to local storage for caching.');\n                }\n            }\n        },\n        getCSS: function(path, webInfo, modifyVars) {\n            var css       = cache && cache.getItem(path),\n                timestamp = cache && cache.getItem(path + ':timestamp'),\n                vars      = cache && cache.getItem(path + ':vars');\n\n            modifyVars = modifyVars || {};\n\n            if (timestamp && webInfo.lastModified &&\n                (new Date(webInfo.lastModified).valueOf() ===\n                    new Date(timestamp).valueOf()) &&\n                (!modifyVars && !vars || JSON.stringify(modifyVars) === vars)) {\n                // Use local copy\n                return css;\n            }\n        }\n    };\n};\n\n},{}],5:[function(require,module,exports){\nvar utils = require(\"./utils\"),\n    browser = require(\"./browser\");\n\nmodule.exports = function(window, less, options) {\n\n    function errorHTML(e, rootHref) {\n        var id = 'less-error-message:' + utils.extractId(rootHref || \"\");\n        var template = '<li><label>{line}</label><pre class=\"{class}\">{content}</pre></li>';\n        var elem = window.document.createElement('div'), timer, content, errors = [];\n        var filename = e.filename || rootHref;\n        var filenameNoPath = filename.match(/([^\\/]+(\\?.*)?)$/)[1];\n\n        elem.id        = id;\n        elem.className = \"less-error-message\";\n\n        content = '<h3>'  + (e.type || \"Syntax\") + \"Error: \" + (e.message || 'There is an error in your .less file') +\n            '</h3>' + '<p>in <a href=\"' + filename   + '\">' + filenameNoPath + \"</a> \";\n\n        var errorline = function (e, i, classname) {\n            if (e.extract[i] !== undefined) {\n                errors.push(template.replace(/\\{line\\}/, (parseInt(e.line, 10) || 0) + (i - 1))\n                    .replace(/\\{class\\}/, classname)\n                    .replace(/\\{content\\}/, e.extract[i]));\n            }\n        };\n\n        if (e.extract) {\n            errorline(e, 0, '');\n            errorline(e, 1, 'line');\n            errorline(e, 2, '');\n            content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +\n                '<ul>' + errors.join('') + '</ul>';\n        }\n        if (e.stack && (e.extract || options.logLevel >= 4)) {\n            content += '<br/>Stack Trace</br />' + e.stack.split('\\n').slice(1).join('<br/>');\n        }\n        elem.innerHTML = content;\n\n        // CSS for error messages\n        browser.createCSS(window.document, [\n            '.less-error-message ul, .less-error-message li {',\n            'list-style-type: none;',\n            'margin-right: 15px;',\n            'padding: 4px 0;',\n            'margin: 0;',\n            '}',\n            '.less-error-message label {',\n            'font-size: 12px;',\n            'margin-right: 15px;',\n            'padding: 4px 0;',\n            'color: #cc7777;',\n            '}',\n            '.less-error-message pre {',\n            'color: #dd6666;',\n            'padding: 4px 0;',\n            'margin: 0;',\n            'display: inline-block;',\n            '}',\n            '.less-error-message pre.line {',\n            'color: #ff0000;',\n            '}',\n            '.less-error-message h3 {',\n            'font-size: 20px;',\n            'font-weight: bold;',\n            'padding: 15px 0 5px 0;',\n            'margin: 0;',\n            '}',\n            '.less-error-message a {',\n            'color: #10a',\n            '}',\n            '.less-error-message .error {',\n            'color: red;',\n            'font-weight: bold;',\n            'padding-bottom: 2px;',\n            'border-bottom: 1px dashed red;',\n            '}'\n        ].join('\\n'), { title: 'error-message' });\n\n        elem.style.cssText = [\n            \"font-family: Arial, sans-serif\",\n            \"border: 1px solid #e00\",\n            \"background-color: #eee\",\n            \"border-radius: 5px\",\n            \"-webkit-border-radius: 5px\",\n            \"-moz-border-radius: 5px\",\n            \"color: #e00\",\n            \"padding: 15px\",\n            \"margin-bottom: 15px\"\n        ].join(';');\n\n        if (options.env === 'development') {\n            timer = setInterval(function () {\n                var document = window.document,\n                    body = document.body;\n                if (body) {\n                    if (document.getElementById(id)) {\n                        body.replaceChild(elem, document.getElementById(id));\n                    } else {\n                        body.insertBefore(elem, body.firstChild);\n                    }\n                    clearInterval(timer);\n                }\n            }, 10);\n        }\n    }\n\n    function removeErrorHTML(path) {\n        var node = window.document.getElementById('less-error-message:' + utils.extractId(path));\n        if (node) {\n            node.parentNode.removeChild(node);\n        }\n    }\n\n    function removeErrorConsole(path) {\n        //no action\n    }\n\n    function removeError(path) {\n        if (!options.errorReporting || options.errorReporting === \"html\") {\n            removeErrorHTML(path);\n        } else if (options.errorReporting === \"console\") {\n            removeErrorConsole(path);\n        } else if (typeof options.errorReporting === 'function') {\n            options.errorReporting(\"remove\", path);\n        }\n    }\n\n    function errorConsole(e, rootHref) {\n        var template = '{line} {content}';\n        var filename = e.filename || rootHref;\n        var errors = [];\n        var content = (e.type || \"Syntax\") + \"Error: \" + (e.message || 'There is an error in your .less file') +\n            \" in \" + filename + \" \";\n\n        var errorline = function (e, i, classname) {\n            if (e.extract[i] !== undefined) {\n                errors.push(template.replace(/\\{line\\}/, (parseInt(e.line, 10) || 0) + (i - 1))\n                    .replace(/\\{class\\}/, classname)\n                    .replace(/\\{content\\}/, e.extract[i]));\n            }\n        };\n\n        if (e.extract) {\n            errorline(e, 0, '');\n            errorline(e, 1, 'line');\n            errorline(e, 2, '');\n            content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\\n' +\n                errors.join('\\n');\n        }\n        if (e.stack && (e.extract || options.logLevel >= 4)) {\n            content += '\\nStack Trace\\n' + e.stack;\n        }\n        less.logger.error(content);\n    }\n\n    function error(e, rootHref) {\n        if (!options.errorReporting || options.errorReporting === \"html\") {\n            errorHTML(e, rootHref);\n        } else if (options.errorReporting === \"console\") {\n            errorConsole(e, rootHref);\n        } else if (typeof options.errorReporting === 'function') {\n            options.errorReporting(\"add\", e, rootHref);\n        }\n    }\n\n    return {\n        add: error,\n        remove: removeError\n    };\n};\n\n},{\"./browser\":3,\"./utils\":10}],6:[function(require,module,exports){\n/*global window, XMLHttpRequest */\n\nmodule.exports = function(options, logger) {\n\n    var AbstractFileManager = require(\"../less/environment/abstract-file-manager.js\");\n\n    var fileCache = {};\n\n    //TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load\n\n    function getXMLHttpRequest() {\n        if (window.XMLHttpRequest && (window.location.protocol !== \"file:\" || !(\"ActiveXObject\" in window))) {\n            return new XMLHttpRequest();\n        } else {\n            try {\n                /*global ActiveXObject */\n                return new ActiveXObject(\"Microsoft.XMLHTTP\");\n            } catch (e) {\n                logger.error(\"browser doesn't support AJAX.\");\n                return null;\n            }\n        }\n    }\n\n    var FileManager = function() {\n    };\n\n    FileManager.prototype = new AbstractFileManager();\n\n    FileManager.prototype.alwaysMakePathsAbsolute = function alwaysMakePathsAbsolute() {\n        return true;\n    };\n    FileManager.prototype.join = function join(basePath, laterPath) {\n        if (!basePath) {\n            return laterPath;\n        }\n        return this.extractUrlParts(laterPath, basePath).path;\n    };\n    FileManager.prototype.doXHR = function doXHR(url, type, callback, errback) {\n\n        var xhr = getXMLHttpRequest();\n        var async = options.isFileProtocol ? options.fileAsync : true;\n\n        if (typeof xhr.overrideMimeType === 'function') {\n            xhr.overrideMimeType('text/css');\n        }\n        logger.debug(\"XHR: Getting '\" + url + \"'\");\n        xhr.open('GET', url, async);\n        xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');\n        xhr.send(null);\n\n        function handleResponse(xhr, callback, errback) {\n            if (xhr.status >= 200 && xhr.status < 300) {\n                callback(xhr.responseText,\n                    xhr.getResponseHeader(\"Last-Modified\"));\n            } else if (typeof errback === 'function') {\n                errback(xhr.status, url);\n            }\n        }\n\n        if (options.isFileProtocol && !options.fileAsync) {\n            if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {\n                callback(xhr.responseText);\n            } else {\n                errback(xhr.status, url);\n            }\n        } else if (async) {\n            xhr.onreadystatechange = function () {\n                if (xhr.readyState == 4) {\n                    handleResponse(xhr, callback, errback);\n                }\n            };\n        } else {\n            handleResponse(xhr, callback, errback);\n        }\n    };\n    FileManager.prototype.supports = function(filename, currentDirectory, options, environment) {\n        return true;\n    };\n\n    FileManager.prototype.clearFileCache = function() {\n        fileCache = {};\n    };\n\n    FileManager.prototype.loadFile = function loadFile(filename, currentDirectory, options, environment, callback) {\n        if (currentDirectory && !this.isPathAbsolute(filename)) {\n            filename = currentDirectory + filename;\n        }\n\n        options = options || {};\n\n        // sheet may be set to the stylesheet for the initial load or a collection of properties including\n        // some context variables for imports\n        var hrefParts = this.extractUrlParts(filename, window.location.href);\n        var href      = hrefParts.url;\n\n        if (options.useFileCache && fileCache[href]) {\n            try {\n                var lessText = fileCache[href];\n                callback(null, { contents: lessText, filename: href, webInfo: { lastModified: new Date() }});\n            } catch (e) {\n                callback({filename: href, message: \"Error loading file \" + href + \" error was \" + e.message});\n            }\n            return;\n        }\n\n        this.doXHR(href, options.mime, function doXHRCallback(data, lastModified) {\n            // per file cache\n            fileCache[href] = data;\n\n            // Use remote copy (re-parse)\n            callback(null, { contents: data, filename: href, webInfo: { lastModified: lastModified }});\n        }, function doXHRError(status, url) {\n            callback({ type: 'File', message: \"'\" + url + \"' wasn't found (\" + status + \")\", href: href });\n        });\n    };\n\n    return FileManager;\n};\n\n},{\"../less/environment/abstract-file-manager.js\":15}],7:[function(require,module,exports){\nmodule.exports = function() {\n\n    var functionRegistry = require(\"./../less/functions/function-registry\");\n\n    function imageSize() {\n        throw {\n            type: \"Runtime\",\n            message: \"Image size functions are not supported in browser version of less\"\n        };\n    }\n\n    var imageFunctions = {\n        \"image-size\": function(filePathNode) {\n            imageSize(this, filePathNode);\n            return -1;\n        },\n        \"image-width\": function(filePathNode) {\n            imageSize(this, filePathNode);\n            return -1;\n        },\n        \"image-height\": function(filePathNode) {\n            imageSize(this, filePathNode);\n            return -1;\n        }\n    };\n\n    functionRegistry.addMultiple(imageFunctions);\n};\n\n},{\"./../less/functions/function-registry\":22}],8:[function(require,module,exports){\n//\n// index.js\n// Should expose the additional browser functions on to the less object\n//\nvar addDataAttr = require(\"./utils\").addDataAttr,\n    browser = require(\"./browser\");\n\nmodule.exports = function(window, options) {\n    var document = window.document;\n    var less = require('../less')();\n\n    //module.exports = less;\n    less.options = options;\n    var environment = less.environment,\n        FileManager = require(\"./file-manager\")(options, less.logger),\n        fileManager = new FileManager();\n    environment.addFileManager(fileManager);\n    less.FileManager = FileManager;\n\n    require(\"./log-listener\")(less, options);\n    var errors = require(\"./error-reporting\")(window, less, options);\n    var cache = less.cache = options.cache || require(\"./cache\")(window, options, less.logger);\n    require('./image-size')(less.environment);\n\n    //Setup user functions\n    if (options.functions) {\n        less.functions.functionRegistry.addMultiple(options.functions);\n    }\n\n    var typePattern = /^text\\/(x-)?less$/;\n\n    function postProcessCSS(styles) { // deprecated, use a plugin for postprocesstasks\n        if (options.postProcessor && typeof options.postProcessor === 'function') {\n            styles = options.postProcessor.call(styles, styles) || styles;\n        }\n        return styles;\n    }\n\n    function clone(obj) {\n        var cloned = {};\n        for (var prop in obj) {\n            if (obj.hasOwnProperty(prop)) {\n                cloned[prop] = obj[prop];\n            }\n        }\n        return cloned;\n    }\n\n    // only really needed for phantom\n    function bind(func, thisArg) {\n        var curryArgs = Array.prototype.slice.call(arguments, 2);\n        return function() {\n            var args = curryArgs.concat(Array.prototype.slice.call(arguments, 0));\n            return func.apply(thisArg, args);\n        };\n    }\n\n    function loadStyles(modifyVars) {\n        var styles = document.getElementsByTagName('style'),\n            style;\n\n        for (var i = 0; i < styles.length; i++) {\n            style = styles[i];\n            if (style.type.match(typePattern)) {\n                var instanceOptions = clone(options);\n                instanceOptions.modifyVars = modifyVars;\n                var lessText = style.innerHTML || '';\n                instanceOptions.filename = document.location.href.replace(/#.*$/, '');\n\n                /*jshint loopfunc:true */\n                // use closure to store current style\n                less.render(lessText, instanceOptions,\n                        bind(function(style, e, result) {\n                            if (e) {\n                                errors.add(e, \"inline\");\n                            } else {\n                                style.type = 'text/css';\n                                if (style.styleSheet) {\n                                    style.styleSheet.cssText = result.css;\n                                } else {\n                                    style.innerHTML = result.css;\n                                }\n                            }\n                        }, null, style));\n            }\n        }\n    }\n\n    function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {\n\n        var instanceOptions = clone(options);\n        addDataAttr(instanceOptions, sheet);\n        instanceOptions.mime = sheet.type;\n\n        if (modifyVars) {\n            instanceOptions.modifyVars = modifyVars;\n        }\n\n        function loadInitialFileCallback(loadedFile) {\n\n            var data = loadedFile.contents,\n                path = loadedFile.filename,\n                webInfo = loadedFile.webInfo;\n\n            var newFileInfo = {\n                currentDirectory: fileManager.getPath(path),\n                filename: path,\n                rootFilename: path,\n                relativeUrls: instanceOptions.relativeUrls};\n\n            newFileInfo.entryPath = newFileInfo.currentDirectory;\n            newFileInfo.rootpath = instanceOptions.rootpath || newFileInfo.currentDirectory;\n\n            if (webInfo) {\n                webInfo.remaining = remaining;\n\n                var css = cache.getCSS(path, webInfo, instanceOptions.modifyVars);\n                if (!reload && css) {\n                    webInfo.local = true;\n                    callback(null, css, data, sheet, webInfo, path);\n                    return;\n                }\n\n            }\n\n            //TODO add tests around how this behaves when reloading\n            errors.remove(path);\n\n            instanceOptions.rootFileInfo = newFileInfo;\n            less.render(data, instanceOptions, function(e, result) {\n                if (e) {\n                    e.href = path;\n                    callback(e);\n                } else {\n                    result.css = postProcessCSS(result.css);\n                    cache.setCSS(sheet.href, webInfo.lastModified, instanceOptions.modifyVars, result.css);\n                    callback(null, result.css, data, sheet, webInfo, path);\n                }\n            });\n        }\n\n        fileManager.loadFile(sheet.href, null, instanceOptions, environment, function(e, loadedFile) {\n            if (e) {\n                callback(e);\n                return;\n            }\n            loadInitialFileCallback(loadedFile);\n        });\n    }\n\n    function loadStyleSheets(callback, reload, modifyVars) {\n        for (var i = 0; i < less.sheets.length; i++) {\n            loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars);\n        }\n    }\n\n    function initRunningMode() {\n        if (less.env === 'development') {\n            less.watchTimer = setInterval(function () {\n                if (less.watchMode) {\n                    fileManager.clearFileCache();\n                    loadStyleSheets(function (e, css, _, sheet, webInfo) {\n                        if (e) {\n                            errors.add(e, e.href || sheet.href);\n                        } else if (css) {\n                            browser.createCSS(window.document, css, sheet);\n                        }\n                    });\n                }\n            }, options.poll);\n        }\n    }\n\n    //\n    // Watch mode\n    //\n    less.watch   = function () {\n        if (!less.watchMode ) {\n            less.env = 'development';\n            initRunningMode();\n        }\n        this.watchMode = true;\n        return true;\n    };\n\n    less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; };\n\n    //\n    // Synchronously get all <link> tags with the 'rel' attribute set to\n    // \"stylesheet/less\".\n    //\n    less.registerStylesheetsImmediately = function() {\n        var links = document.getElementsByTagName('link');\n        less.sheets = [];\n\n        for (var i = 0; i < links.length; i++) {\n            if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&\n                (links[i].type.match(typePattern)))) {\n                less.sheets.push(links[i]);\n            }\n        }\n    };\n\n    //\n    // Asynchronously get all <link> tags with the 'rel' attribute set to\n    // \"stylesheet/less\", returning a Promise.\n    //\n    less.registerStylesheets = function() {\n        return new Promise(function(resolve, reject) {\n            less.registerStylesheetsImmediately();\n            resolve();\n        });\n    };\n\n    //\n    // With this function, it's possible to alter variables and re-render\n    // CSS without reloading less-files\n    //\n    less.modifyVars = function(record) {\n        return less.refresh(true, record, false);\n    };\n\n    less.refresh = function (reload, modifyVars, clearFileCache) {\n        if ((reload || clearFileCache) && clearFileCache !== false) {\n            fileManager.clearFileCache();\n        }\n        return new Promise(function (resolve, reject) {\n            var startTime, endTime, totalMilliseconds, remainingSheets;\n            startTime = endTime = new Date();\n\n            // Set counter for remaining unprocessed sheets\n            remainingSheets = less.sheets.length;\n\n            if (remainingSheets === 0) {\n\n                endTime = new Date();\n                totalMilliseconds = endTime - startTime;\n                less.logger.info(\"Less has finished and no sheets were loaded.\");\n                resolve({\n                    startTime: startTime,\n                    endTime: endTime,\n                    totalMilliseconds: totalMilliseconds,\n                    sheets: less.sheets.length\n                });\n\n            } else {\n                // Relies on less.sheets array, callback seems to be guaranteed to be called for every element of the array\n                loadStyleSheets(function (e, css, _, sheet, webInfo) {\n                    if (e) {\n                        errors.add(e, e.href || sheet.href);\n                        reject(e);\n                        return;\n                    }\n                    if (webInfo.local) {\n                        less.logger.info(\"Loading \" + sheet.href + \" from cache.\");\n                    } else {\n                        less.logger.info(\"Rendered \" + sheet.href + \" successfully.\");\n                    }\n                    browser.createCSS(window.document, css, sheet);\n                    less.logger.info(\"CSS for \" + sheet.href + \" generated in \" + (new Date() - endTime) + 'ms');\n\n                    // Count completed sheet\n                    remainingSheets--;\n\n                    // Check if the last remaining sheet was processed and then call the promise\n                    if (remainingSheets === 0) {\n                        totalMilliseconds = new Date() - startTime;\n                        less.logger.info(\"Less has finished. CSS generated in \" + totalMilliseconds + 'ms');\n                        resolve({\n                            startTime: startTime,\n                            endTime: endTime,\n                            totalMilliseconds: totalMilliseconds,\n                            sheets: less.sheets.length\n                        });\n                    }\n                    endTime = new Date();\n                }, reload, modifyVars);\n            }\n\n            loadStyles(modifyVars);\n        });\n    };\n\n    less.refreshStyles = loadStyles;\n    return less;\n};\n\n},{\"../less\":31,\"./browser\":3,\"./cache\":4,\"./error-reporting\":5,\"./file-manager\":6,\"./image-size\":7,\"./log-listener\":9,\"./utils\":10}],9:[function(require,module,exports){\nmodule.exports = function(less, options) {\n\n    var logLevel_debug = 4,\n        logLevel_info = 3,\n        logLevel_warn = 2,\n        logLevel_error = 1;\n\n    // The amount of logging in the javascript console.\n    // 3 - Debug, information and errors\n    // 2 - Information and errors\n    // 1 - Errors\n    // 0 - None\n    // Defaults to 2\n    options.logLevel = typeof options.logLevel !== 'undefined' ? options.logLevel : (options.env === 'development' ?  logLevel_info : logLevel_error);\n\n    if (!options.loggers) {\n        options.loggers = [{\n            debug: function(msg) {\n                if (options.logLevel >= logLevel_debug) {\n                    console.log(msg);\n                }\n            },\n            info: function(msg) {\n                if (options.logLevel >= logLevel_info) {\n                    console.log(msg);\n                }\n            },\n            warn: function(msg) {\n                if (options.logLevel >= logLevel_warn) {\n                    console.warn(msg);\n                }\n            },\n            error: function(msg) {\n                if (options.logLevel >= logLevel_error) {\n                    console.error(msg);\n                }\n            }\n        }];\n    }\n    for (var i = 0; i < options.loggers.length; i++) {\n        less.logger.addListener(options.loggers[i]);\n    }\n};\n\n},{}],10:[function(require,module,exports){\nmodule.exports = {\n    extractId: function(href) {\n        return href.replace(/^[a-z-]+:\\/+?[^\\/]+/, '')  // Remove protocol & domain\n            .replace(/[\\?\\&]livereload=\\w+/, '')        // Remove LiveReload cachebuster\n            .replace(/^\\//, '')                         // Remove root /\n            .replace(/\\.[a-zA-Z]+$/, '')                // Remove simple extension\n            .replace(/[^\\.\\w-]+/g, '-')                 // Replace illegal characters\n            .replace(/\\./g, ':');                       // Replace dots with colons(for valid id)\n    },\n    addDataAttr: function(options, tag) {\n        for (var opt in tag.dataset) {\n            if (tag.dataset.hasOwnProperty(opt)) {\n                if (opt === \"env\" || opt === \"dumpLineNumbers\" || opt === \"rootpath\" || opt === \"errorReporting\") {\n                    options[opt] = tag.dataset[opt];\n                } else {\n                    try {\n                        options[opt] = JSON.parse(tag.dataset[opt]);\n                    }\n                    catch(_) {}\n                }\n            }\n        }\n    }\n};\n\n},{}],11:[function(require,module,exports){\nvar contexts = {};\nmodule.exports = contexts;\n\nvar copyFromOriginal = function copyFromOriginal(original, destination, propertiesToCopy) {\n    if (!original) { return; }\n\n    for (var i = 0; i < propertiesToCopy.length; i++) {\n        if (original.hasOwnProperty(propertiesToCopy[i])) {\n            destination[propertiesToCopy[i]] = original[propertiesToCopy[i]];\n        }\n    }\n};\n\n/*\n parse is used whilst parsing\n */\nvar parseCopyProperties = [\n    // options\n    'paths',            // option - unmodified - paths to search for imports on\n    'relativeUrls',     // option - whether to adjust URL's to be relative\n    'rootpath',         // option - rootpath to append to URL's\n    'strictImports',    // option -\n    'insecure',         // option - whether to allow imports from insecure ssl hosts\n    'dumpLineNumbers',  // option - whether to dump line numbers\n    'compress',         // option - whether to compress\n    'syncImport',       // option - whether to import synchronously\n    'chunkInput',       // option - whether to chunk input. more performant but causes parse issues.\n    'mime',             // browser only - mime type for sheet import\n    'useFileCache',     // browser only - whether to use the per file session cache\n    // context\n    'processImports',   // option & context - whether to process imports. if false then imports will not be imported.\n                        // Used by the import manager to stop multiple import visitors being created.\n    'pluginManager'     // Used as the plugin manager for the session\n];\n\ncontexts.Parse = function(options) {\n    copyFromOriginal(options, this, parseCopyProperties);\n\n    if (typeof this.paths === \"string\") { this.paths = [this.paths]; }\n};\n\nvar evalCopyProperties = [\n    'paths',          // additional include paths\n    'compress',       // whether to compress\n    'ieCompat',       // whether to enforce IE compatibility (IE8 data-uri)\n    'strictMath',     // whether math has to be within parenthesis\n    'strictUnits',    // whether units need to evaluate correctly\n    'sourceMap',      // whether to output a source map\n    'importMultiple', // whether we are currently importing multiple copies\n    'urlArgs',        // whether to add args into url tokens\n    'javascriptEnabled',// option - whether JavaScript is enabled. if undefined, defaults to true\n    'pluginManager',  // Used as the plugin manager for the session\n    'importantScope'  // used to bubble up !important statements\n    ];\n\ncontexts.Eval = function(options, frames) {\n    copyFromOriginal(options, this, evalCopyProperties);\n\n    if (typeof this.paths === \"string\") { this.paths = [this.paths]; }\n\n    this.frames = frames || [];\n    this.importantScope = this.importantScope || [];\n};\n\ncontexts.Eval.prototype.inParenthesis = function () {\n    if (!this.parensStack) {\n        this.parensStack = [];\n    }\n    this.parensStack.push(true);\n};\n\ncontexts.Eval.prototype.outOfParenthesis = function () {\n    this.parensStack.pop();\n};\n\ncontexts.Eval.prototype.isMathOn = function () {\n    return this.strictMath ? (this.parensStack && this.parensStack.length) : true;\n};\n\ncontexts.Eval.prototype.isPathRelative = function (path) {\n    return !/^(?:[a-z-]+:|\\/|#)/i.test(path);\n};\n\ncontexts.Eval.prototype.normalizePath = function( path ) {\n    var\n      segments = path.split(\"/\").reverse(),\n      segment;\n\n    path = [];\n    while (segments.length !== 0 ) {\n        segment = segments.pop();\n        switch( segment ) {\n            case \".\":\n                break;\n            case \"..\":\n                if ((path.length === 0) || (path[path.length - 1] === \"..\")) {\n                    path.push( segment );\n                } else {\n                    path.pop();\n                }\n                break;\n            default:\n                path.push( segment );\n                break;\n        }\n    }\n\n    return path.join(\"/\");\n};\n\n//todo - do the same for the toCSS ?\n\n},{}],12:[function(require,module,exports){\nmodule.exports = {\n    'aliceblue':'#f0f8ff',\n    'antiquewhite':'#faebd7',\n    'aqua':'#00ffff',\n    'aquamarine':'#7fffd4',\n    'azure':'#f0ffff',\n    'beige':'#f5f5dc',\n    'bisque':'#ffe4c4',\n    'black':'#000000',\n    'blanchedalmond':'#ffebcd',\n    'blue':'#0000ff',\n    'blueviolet':'#8a2be2',\n    'brown':'#a52a2a',\n    'burlywood':'#deb887',\n    'cadetblue':'#5f9ea0',\n    'chartreuse':'#7fff00',\n    'chocolate':'#d2691e',\n    'coral':'#ff7f50',\n    'cornflowerblue':'#6495ed',\n    'cornsilk':'#fff8dc',\n    'crimson':'#dc143c',\n    'cyan':'#00ffff',\n    'darkblue':'#00008b',\n    'darkcyan':'#008b8b',\n    'darkgoldenrod':'#b8860b',\n    'darkgray':'#a9a9a9',\n    'darkgrey':'#a9a9a9',\n    'darkgreen':'#006400',\n    'darkkhaki':'#bdb76b',\n    'darkmagenta':'#8b008b',\n    'darkolivegreen':'#556b2f',\n    'darkorange':'#ff8c00',\n    'darkorchid':'#9932cc',\n    'darkred':'#8b0000',\n    'darksalmon':'#e9967a',\n    'darkseagreen':'#8fbc8f',\n    'darkslateblue':'#483d8b',\n    'darkslategray':'#2f4f4f',\n    'darkslategrey':'#2f4f4f',\n    'darkturquoise':'#00ced1',\n    'darkviolet':'#9400d3',\n    'deeppink':'#ff1493',\n    'deepskyblue':'#00bfff',\n    'dimgray':'#696969',\n    'dimgrey':'#696969',\n    'dodgerblue':'#1e90ff',\n    'firebrick':'#b22222',\n    'floralwhite':'#fffaf0',\n    'forestgreen':'#228b22',\n    'fuchsia':'#ff00ff',\n    'gainsboro':'#dcdcdc',\n    'ghostwhite':'#f8f8ff',\n    'gold':'#ffd700',\n    'goldenrod':'#daa520',\n    'gray':'#808080',\n    'grey':'#808080',\n    'green':'#008000',\n    'greenyellow':'#adff2f',\n    'honeydew':'#f0fff0',\n    'hotpink':'#ff69b4',\n    'indianred':'#cd5c5c',\n    'indigo':'#4b0082',\n    'ivory':'#fffff0',\n    'khaki':'#f0e68c',\n    'lavender':'#e6e6fa',\n    'lavenderblush':'#fff0f5',\n    'lawngreen':'#7cfc00',\n    'lemonchiffon':'#fffacd',\n    'lightblue':'#add8e6',\n    'lightcoral':'#f08080',\n    'lightcyan':'#e0ffff',\n    'lightgoldenrodyellow':'#fafad2',\n    'lightgray':'#d3d3d3',\n    'lightgrey':'#d3d3d3',\n    'lightgreen':'#90ee90',\n    'lightpink':'#ffb6c1',\n    'lightsalmon':'#ffa07a',\n    'lightseagreen':'#20b2aa',\n    'lightskyblue':'#87cefa',\n    'lightslategray':'#778899',\n    'lightslategrey':'#778899',\n    'lightsteelblue':'#b0c4de',\n    'lightyellow':'#ffffe0',\n    'lime':'#00ff00',\n    'limegreen':'#32cd32',\n    'linen':'#faf0e6',\n    'magenta':'#ff00ff',\n    'maroon':'#800000',\n    'mediumaquamarine':'#66cdaa',\n    'mediumblue':'#0000cd',\n    'mediumorchid':'#ba55d3',\n    'mediumpurple':'#9370d8',\n    'mediumseagreen':'#3cb371',\n    'mediumslateblue':'#7b68ee',\n    'mediumspringgreen':'#00fa9a',\n    'mediumturquoise':'#48d1cc',\n    'mediumvioletred':'#c71585',\n    'midnightblue':'#191970',\n    'mintcream':'#f5fffa',\n    'mistyrose':'#ffe4e1',\n    'moccasin':'#ffe4b5',\n    'navajowhite':'#ffdead',\n    'navy':'#000080',\n    'oldlace':'#fdf5e6',\n    'olive':'#808000',\n    'olivedrab':'#6b8e23',\n    'orange':'#ffa500',\n    'orangered':'#ff4500',\n    'orchid':'#da70d6',\n    'palegoldenrod':'#eee8aa',\n    'palegreen':'#98fb98',\n    'paleturquoise':'#afeeee',\n    'palevioletred':'#d87093',\n    'papayawhip':'#ffefd5',\n    'peachpuff':'#ffdab9',\n    'peru':'#cd853f',\n    'pink':'#ffc0cb',\n    'plum':'#dda0dd',\n    'powderblue':'#b0e0e6',\n    'purple':'#800080',\n    'rebeccapurple':'#663399',\n    'red':'#ff0000',\n    'rosybrown':'#bc8f8f',\n    'royalblue':'#4169e1',\n    'saddlebrown':'#8b4513',\n    'salmon':'#fa8072',\n    'sandybrown':'#f4a460',\n    'seagreen':'#2e8b57',\n    'seashell':'#fff5ee',\n    'sienna':'#a0522d',\n    'silver':'#c0c0c0',\n    'skyblue':'#87ceeb',\n    'slateblue':'#6a5acd',\n    'slategray':'#708090',\n    'slategrey':'#708090',\n    'snow':'#fffafa',\n    'springgreen':'#00ff7f',\n    'steelblue':'#4682b4',\n    'tan':'#d2b48c',\n    'teal':'#008080',\n    'thistle':'#d8bfd8',\n    'tomato':'#ff6347',\n    'turquoise':'#40e0d0',\n    'violet':'#ee82ee',\n    'wheat':'#f5deb3',\n    'white':'#ffffff',\n    'whitesmoke':'#f5f5f5',\n    'yellow':'#ffff00',\n    'yellowgreen':'#9acd32'\n};\n},{}],13:[function(require,module,exports){\nmodule.exports = {\n    colors: require(\"./colors\"),\n    unitConversions: require(\"./unit-conversions\")\n};\n\n},{\"./colors\":12,\"./unit-conversions\":14}],14:[function(require,module,exports){\nmodule.exports = {\n    length: {\n        'm': 1,\n        'cm': 0.01,\n        'mm': 0.001,\n        'in': 0.0254,\n        'px': 0.0254 / 96,\n        'pt': 0.0254 / 72,\n        'pc': 0.0254 / 72 * 12\n    },\n    duration: {\n        's': 1,\n        'ms': 0.001\n    },\n    angle: {\n        'rad': 1 / (2 * Math.PI),\n        'deg': 1 / 360,\n        'grad': 1 / 400,\n        'turn': 1\n    }\n};\n},{}],15:[function(require,module,exports){\nvar abstractFileManager = function() {\n};\n\nabstractFileManager.prototype.getPath = function (filename) {\n    var j = filename.lastIndexOf('?');\n    if (j > 0) {\n        filename = filename.slice(0, j);\n    }\n    j = filename.lastIndexOf('/');\n    if (j < 0) {\n        j = filename.lastIndexOf('\\\\');\n    }\n    if (j < 0) {\n        return \"\";\n    }\n    return filename.slice(0, j + 1);\n};\n\nabstractFileManager.prototype.tryAppendExtension = function(path, ext) {\n    return /(\\.[a-z]*$)|([\\?;].*)$/.test(path) ? path : path + ext;\n};\n\nabstractFileManager.prototype.tryAppendLessExtension = function(path) {\n    return this.tryAppendExtension(path, '.less');\n};\n\nabstractFileManager.prototype.supportsSync = function() {\n    return false;\n};\n\nabstractFileManager.prototype.alwaysMakePathsAbsolute = function() {\n    return false;\n};\n\nabstractFileManager.prototype.isPathAbsolute = function(filename) {\n    return (/^(?:[a-z-]+:|\\/|\\\\|#)/i).test(filename);\n};\n\nabstractFileManager.prototype.join = function(basePath, laterPath) {\n    if (!basePath) {\n        return laterPath;\n    }\n    return basePath + laterPath;\n};\nabstractFileManager.prototype.pathDiff = function pathDiff(url, baseUrl) {\n    // diff between two paths to create a relative path\n\n    var urlParts = this.extractUrlParts(url),\n        baseUrlParts = this.extractUrlParts(baseUrl),\n        i, max, urlDirectories, baseUrlDirectories, diff = \"\";\n    if (urlParts.hostPart !== baseUrlParts.hostPart) {\n        return \"\";\n    }\n    max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);\n    for (i = 0; i < max; i++) {\n        if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }\n    }\n    baseUrlDirectories = baseUrlParts.directories.slice(i);\n    urlDirectories = urlParts.directories.slice(i);\n    for (i = 0; i < baseUrlDirectories.length - 1; i++) {\n        diff += \"../\";\n    }\n    for (i = 0; i < urlDirectories.length - 1; i++) {\n        diff += urlDirectories[i] + \"/\";\n    }\n    return diff;\n};\n// helper function, not part of API\nabstractFileManager.prototype.extractUrlParts = function extractUrlParts(url, baseUrl) {\n    // urlParts[1] = protocol://hostname/ OR /\n    // urlParts[2] = / if path relative to host base\n    // urlParts[3] = directories\n    // urlParts[4] = filename\n    // urlParts[5] = parameters\n\n    var urlPartsRegex = /^((?:[a-z-]+:)?\\/{2}(?:[^\\/\\?#]*\\/)|([\\/\\\\]))?((?:[^\\/\\\\\\?#]*[\\/\\\\])*)([^\\/\\\\\\?#]*)([#\\?].*)?$/i,\n        urlParts = url.match(urlPartsRegex),\n        returner = {}, directories = [], i, baseUrlParts;\n\n    if (!urlParts) {\n        throw new Error(\"Could not parse sheet href - '\" + url + \"'\");\n    }\n\n    // Stylesheets in IE don't always return the full path\n    if (baseUrl && (!urlParts[1] || urlParts[2])) {\n        baseUrlParts = baseUrl.match(urlPartsRegex);\n        if (!baseUrlParts) {\n            throw new Error(\"Could not parse page url - '\" + baseUrl + \"'\");\n        }\n        urlParts[1] = urlParts[1] || baseUrlParts[1] || \"\";\n        if (!urlParts[2]) {\n            urlParts[3] = baseUrlParts[3] + urlParts[3];\n        }\n    }\n\n    if (urlParts[3]) {\n        directories = urlParts[3].replace(/\\\\/g, \"/\").split(\"/\");\n\n        // extract out . before .. so .. doesn't absorb a non-directory\n        for (i = 0; i < directories.length; i++) {\n            if (directories[i] === \".\") {\n                directories.splice(i, 1);\n                i -= 1;\n            }\n        }\n\n        for (i = 0; i < directories.length; i++) {\n            if (directories[i] === \"..\" && i > 0) {\n                directories.splice(i - 1, 2);\n                i -= 2;\n            }\n        }\n    }\n\n    returner.hostPart = urlParts[1];\n    returner.directories = directories;\n    returner.path = (urlParts[1] || \"\") + directories.join(\"/\");\n    returner.fileUrl = returner.path + (urlParts[4] || \"\");\n    returner.url = returner.fileUrl + (urlParts[5] || \"\");\n    return returner;\n};\n\nmodule.exports = abstractFileManager;\n\n},{}],16:[function(require,module,exports){\nvar logger = require(\"../logger\");\nvar environment = function(externalEnvironment, fileManagers) {\n    this.fileManagers = fileManagers || [];\n    externalEnvironment = externalEnvironment || {};\n\n    var optionalFunctions = [\"encodeBase64\", \"mimeLookup\", \"charsetLookup\", \"getSourceMapGenerator\"],\n        requiredFunctions = [],\n        functions = requiredFunctions.concat(optionalFunctions);\n\n    for (var i = 0; i < functions.length; i++) {\n        var propName = functions[i],\n            environmentFunc = externalEnvironment[propName];\n        if (environmentFunc) {\n            this[propName] = environmentFunc.bind(externalEnvironment);\n        } else if (i < requiredFunctions.length) {\n            this.warn(\"missing required function in environment - \" + propName);\n        }\n    }\n};\n\nenvironment.prototype.getFileManager = function (filename, currentDirectory, options, environment, isSync) {\n\n    if (!filename) {\n        logger.warn(\"getFileManager called with no filename.. Please report this issue. continuing.\");\n    }\n    if (currentDirectory == null) {\n        logger.warn(\"getFileManager called with null directory.. Please report this issue. continuing.\");\n    }\n\n    var fileManagers = this.fileManagers;\n    if (options.pluginManager) {\n        fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers());\n    }\n    for (var i = fileManagers.length - 1; i >= 0 ; i--) {\n        var fileManager = fileManagers[i];\n        if (fileManager[isSync ? \"supportsSync\" : \"supports\"](filename, currentDirectory, options, environment)) {\n            return fileManager;\n        }\n    }\n    return null;\n};\n\nenvironment.prototype.addFileManager = function (fileManager) {\n    this.fileManagers.push(fileManager);\n};\n\nenvironment.prototype.clearFileManagers = function () {\n    this.fileManagers = [];\n};\n\nmodule.exports = environment;\n\n},{\"../logger\":33}],17:[function(require,module,exports){\nvar Color = require(\"../tree/color\"),\n    functionRegistry = require(\"./function-registry\");\n\n// Color Blending\n// ref: http://www.w3.org/TR/compositing-1\n\nfunction colorBlend(mode, color1, color2) {\n    var ab = color1.alpha, cb, // backdrop\n        as = color2.alpha, cs, // source\n        ar, cr, r = [];        // result\n\n    ar = as + ab * (1 - as);\n    for (var i = 0; i < 3; i++) {\n        cb = color1.rgb[i] / 255;\n        cs = color2.rgb[i] / 255;\n        cr = mode(cb, cs);\n        if (ar) {\n            cr = (as * cs + ab * (cb -\n                  as * (cb + cs - cr))) / ar;\n        }\n        r[i] = cr * 255;\n    }\n\n    return new Color(r, ar);\n}\n\nvar colorBlendModeFunctions = {\n    multiply: function(cb, cs) {\n        return cb * cs;\n    },\n    screen: function(cb, cs) {\n        return cb + cs - cb * cs;\n    },\n    overlay: function(cb, cs) {\n        cb *= 2;\n        return (cb <= 1) ?\n            colorBlendModeFunctions.multiply(cb, cs) :\n            colorBlendModeFunctions.screen(cb - 1, cs);\n    },\n    softlight: function(cb, cs) {\n        var d = 1, e = cb;\n        if (cs > 0.5) {\n            e = 1;\n            d = (cb > 0.25) ? Math.sqrt(cb)\n                : ((16 * cb - 12) * cb + 4) * cb;\n        }\n        return cb - (1 - 2 * cs) * e * (d - cb);\n    },\n    hardlight: function(cb, cs) {\n        return colorBlendModeFunctions.overlay(cs, cb);\n    },\n    difference: function(cb, cs) {\n        return Math.abs(cb - cs);\n    },\n    exclusion: function(cb, cs) {\n        return cb + cs - 2 * cb * cs;\n    },\n\n    // non-w3c functions:\n    average: function(cb, cs) {\n        return (cb + cs) / 2;\n    },\n    negation: function(cb, cs) {\n        return 1 - Math.abs(cb + cs - 1);\n    }\n};\n\nfor (var f in colorBlendModeFunctions) {\n    if (colorBlendModeFunctions.hasOwnProperty(f)) {\n        colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]);\n    }\n}\n\nfunctionRegistry.addMultiple(colorBlend);\n\n},{\"../tree/color\":50,\"./function-registry\":22}],18:[function(require,module,exports){\nvar Dimension = require(\"../tree/dimension\"),\n    Color = require(\"../tree/color\"),\n    Quoted = require(\"../tree/quoted\"),\n    Anonymous = require(\"../tree/anonymous\"),\n    functionRegistry = require(\"./function-registry\"),\n    colorFunctions;\n\nfunction clamp(val) {\n    return Math.min(1, Math.max(0, val));\n}\nfunction hsla(color) {\n    return colorFunctions.hsla(color.h, color.s, color.l, color.a);\n}\nfunction number(n) {\n    if (n instanceof Dimension) {\n        return parseFloat(n.unit.is('%') ? n.value / 100 : n.value);\n    } else if (typeof n === 'number') {\n        return n;\n    } else {\n        throw {\n            type: \"Argument\",\n            message: \"color functions take numbers as parameters\"\n        };\n    }\n}\nfunction scaled(n, size) {\n    if (n instanceof Dimension && n.unit.is('%')) {\n        return parseFloat(n.value * size / 100);\n    } else {\n        return number(n);\n    }\n}\ncolorFunctions = {\n    rgb: function (r, g, b) {\n        return colorFunctions.rgba(r, g, b, 1.0);\n    },\n    rgba: function (r, g, b, a) {\n        var rgb = [r, g, b].map(function (c) { return scaled(c, 255); });\n        a = number(a);\n        return new Color(rgb, a);\n    },\n    hsl: function (h, s, l) {\n        return colorFunctions.hsla(h, s, l, 1.0);\n    },\n    hsla: function (h, s, l, a) {\n\n        var m1, m2;\n\n        function hue(h) {\n            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);\n            if (h * 6 < 1) {\n                return m1 + (m2 - m1) * h * 6;\n            }\n            else if (h * 2 < 1) {\n                return m2;\n            }\n            else if (h * 3 < 2) {\n                return m1 + (m2 - m1) * (2 / 3 - h) * 6;\n            }\n            else {\n                return m1;\n            }\n        }\n\n        h = (number(h) % 360) / 360;\n        s = clamp(number(s)); l = clamp(number(l)); a = clamp(number(a));\n\n        m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;\n        m1 = l * 2 - m2;\n\n        return colorFunctions.rgba(hue(h + 1 / 3) * 255,\n            hue(h)       * 255,\n            hue(h - 1 / 3) * 255,\n            a);\n    },\n\n    hsv: function(h, s, v) {\n        return colorFunctions.hsva(h, s, v, 1.0);\n    },\n\n    hsva: function(h, s, v, a) {\n        h = ((number(h) % 360) / 360) * 360;\n        s = number(s); v = number(v); a = number(a);\n\n        var i, f;\n        i = Math.floor((h / 60) % 6);\n        f = (h / 60) - i;\n\n        var vs = [v,\n            v * (1 - s),\n            v * (1 - f * s),\n            v * (1 - (1 - f) * s)];\n        var perm = [[0, 3, 1],\n            [2, 0, 1],\n            [1, 0, 3],\n            [1, 2, 0],\n            [3, 1, 0],\n            [0, 1, 2]];\n\n        return colorFunctions.rgba(vs[perm[i][0]] * 255,\n            vs[perm[i][1]] * 255,\n            vs[perm[i][2]] * 255,\n            a);\n    },\n\n    hue: function (color) {\n        return new Dimension(color.toHSL().h);\n    },\n    saturation: function (color) {\n        return new Dimension(color.toHSL().s * 100, '%');\n    },\n    lightness: function (color) {\n        return new Dimension(color.toHSL().l * 100, '%');\n    },\n    hsvhue: function(color) {\n        return new Dimension(color.toHSV().h);\n    },\n    hsvsaturation: function (color) {\n        return new Dimension(color.toHSV().s * 100, '%');\n    },\n    hsvvalue: function (color) {\n        return new Dimension(color.toHSV().v * 100, '%');\n    },\n    red: function (color) {\n        return new Dimension(color.rgb[0]);\n    },\n    green: function (color) {\n        return new Dimension(color.rgb[1]);\n    },\n    blue: function (color) {\n        return new Dimension(color.rgb[2]);\n    },\n    alpha: function (color) {\n        return new Dimension(color.toHSL().a);\n    },\n    luma: function (color) {\n        return new Dimension(color.luma() * color.alpha * 100, '%');\n    },\n    luminance: function (color) {\n        var luminance =\n            (0.2126 * color.rgb[0] / 255) +\n                (0.7152 * color.rgb[1] / 255) +\n                (0.0722 * color.rgb[2] / 255);\n\n        return new Dimension(luminance * color.alpha * 100, '%');\n    },\n    saturate: function (color, amount, method) {\n        // filter: saturate(3.2);\n        // should be kept as is, so check for color\n        if (!color.rgb) {\n            return null;\n        }\n        var hsl = color.toHSL();\n\n        if (typeof method !== \"undefined\" && method.value === \"relative\") {\n            hsl.s +=  hsl.s * amount.value / 100;\n        }\n        else {\n            hsl.s += amount.value / 100;\n        }\n        hsl.s = clamp(hsl.s);\n        return hsla(hsl);\n    },\n    desaturate: function (color, amount, method) {\n        var hsl = color.toHSL();\n\n        if (typeof method !== \"undefined\" && method.value === \"relative\") {\n            hsl.s -=  hsl.s * amount.value / 100;\n        }\n        else {\n            hsl.s -= amount.value / 100;\n        }\n        hsl.s = clamp(hsl.s);\n        return hsla(hsl);\n    },\n    lighten: function (color, amount, method) {\n        var hsl = color.toHSL();\n\n        if (typeof method !== \"undefined\" && method.value === \"relative\") {\n            hsl.l +=  hsl.l * amount.value / 100;\n        }\n        else {\n            hsl.l += amount.value / 100;\n        }\n        hsl.l = clamp(hsl.l);\n        return hsla(hsl);\n    },\n    darken: function (color, amount, method) {\n        var hsl = color.toHSL();\n\n        if (typeof method !== \"undefined\" && method.value === \"relative\") {\n            hsl.l -=  hsl.l * amount.value / 100;\n        }\n        else {\n            hsl.l -= amount.value / 100;\n        }\n        hsl.l = clamp(hsl.l);\n        return hsla(hsl);\n    },\n    fadein: function (color, amount, method) {\n        var hsl = color.toHSL();\n\n        if (typeof method !== \"undefined\" && method.value === \"relative\") {\n            hsl.a +=  hsl.a * amount.value / 100;\n        }\n        else {\n            hsl.a += amount.value / 100;\n        }\n        hsl.a = clamp(hsl.a);\n        return hsla(hsl);\n    },\n    fadeout: function (color, amount, method) {\n        var hsl = color.toHSL();\n\n        if (typeof method !== \"undefined\" && method.value === \"relative\") {\n            hsl.a -=  hsl.a * amount.value / 100;\n        }\n        else {\n            hsl.a -= amount.value / 100;\n        }\n        hsl.a = clamp(hsl.a);\n        return hsla(hsl);\n    },\n    fade: function (color, amount) {\n        var hsl = color.toHSL();\n\n        hsl.a = amount.value / 100;\n        hsl.a = clamp(hsl.a);\n        return hsla(hsl);\n    },\n    spin: function (color, amount) {\n        var hsl = color.toHSL();\n        var hue = (hsl.h + amount.value) % 360;\n\n        hsl.h = hue < 0 ? 360 + hue : hue;\n\n        return hsla(hsl);\n    },\n    //\n    // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein\n    // http://sass-lang.com\n    //\n    mix: function (color1, color2, weight) {\n        if (!color1.toHSL || !color2.toHSL) {\n            console.log(color2.type);\n            console.dir(color2);\n        }\n        if (!weight) {\n            weight = new Dimension(50);\n        }\n        var p = weight.value / 100.0;\n        var w = p * 2 - 1;\n        var a = color1.toHSL().a - color2.toHSL().a;\n\n        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;\n        var w2 = 1 - w1;\n\n        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,\n            color1.rgb[1] * w1 + color2.rgb[1] * w2,\n            color1.rgb[2] * w1 + color2.rgb[2] * w2];\n\n        var alpha = color1.alpha * p + color2.alpha * (1 - p);\n\n        return new Color(rgb, alpha);\n    },\n    greyscale: function (color) {\n        return colorFunctions.desaturate(color, new Dimension(100));\n    },\n    contrast: function (color, color1, color2, threshold) {\n        // Return which of `color1` and `color2` has the greatest contrast with `color`\n        // according to the standard WCAG contrast ratio calculation.\n        // http://www.w3.org/TR/WCAG20/#contrast-ratiodef\n        // The threshold param is no longer used, in line with SASS.\n        // filter: contrast(3.2);\n        // should be kept as is, so check for color\n        if (!color.rgb) {\n            return null;\n        }\n        if (typeof color1 === 'undefined') {\n            color1 = colorFunctions.rgba(0, 0, 0, 1.0);\n        }\n        if (typeof color2 === 'undefined') {\n            color2 = colorFunctions.rgba(255, 255, 255, 1.0);\n        }\n        var contrast1, contrast2;\n        var luma = color.luma();\n        var luma1 = color1.luma();\n        var luma2 = color2.luma();\n        // Calculate contrast ratios for each color\n        if (luma > luma1) {\n            contrast1 = (luma + 0.05) / (luma1 + 0.05);\n        } else {\n            contrast1 = (luma1 + 0.05) / (luma + 0.05);\n        }\n        if (luma > luma2) {\n            contrast2 = (luma + 0.05) / (luma2 + 0.05);\n        } else {\n            contrast2 = (luma2 + 0.05) / (luma + 0.05);\n        }\n        if (contrast1 > contrast2) {\n            return color1;\n        } else {\n            return color2;\n        }\n    },\n    argb: function (color) {\n        return new Anonymous(color.toARGB());\n    },\n    color: function(c) {\n        if ((c instanceof Quoted) &&\n            (/^#([a-f0-9]{6}|[a-f0-9]{3})$/i.test(c.value))) {\n            return new Color(c.value.slice(1));\n        }\n        if ((c instanceof Color) || (c = Color.fromKeyword(c.value))) {\n            c.value = undefined;\n            return c;\n        }\n        throw {\n            type:    \"Argument\",\n            message: \"argument must be a color keyword or 3/6 digit hex e.g. #FFF\"\n        };\n    },\n    tint: function(color, amount) {\n        return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount);\n    },\n    shade: function(color, amount) {\n        return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount);\n    }\n};\nfunctionRegistry.addMultiple(colorFunctions);\n\n},{\"../tree/anonymous\":46,\"../tree/color\":50,\"../tree/dimension\":56,\"../tree/quoted\":73,\"./function-registry\":22}],19:[function(require,module,exports){\nmodule.exports = function(environment) {\n    var Quoted = require(\"../tree/quoted\"),\n        URL = require(\"../tree/url\"),\n        functionRegistry = require(\"./function-registry\"),\n        fallback = function(functionThis, node) {\n            return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context);\n        },\n        logger = require('../logger');\n\n    functionRegistry.add(\"data-uri\", function(mimetypeNode, filePathNode) {\n\n        if (!filePathNode) {\n            filePathNode = mimetypeNode;\n            mimetypeNode = null;\n        }\n\n        var mimetype = mimetypeNode && mimetypeNode.value;\n        var filePath = filePathNode.value;\n        var currentFileInfo = this.currentFileInfo;\n        var currentDirectory = currentFileInfo.relativeUrls ?\n            currentFileInfo.currentDirectory : currentFileInfo.entryPath;\n\n        var fragmentStart = filePath.indexOf('#');\n        var fragment = '';\n        if (fragmentStart !== -1) {\n            fragment = filePath.slice(fragmentStart);\n            filePath = filePath.slice(0, fragmentStart);\n        }\n\n        var fileManager = environment.getFileManager(filePath, currentDirectory, this.context, environment, true);\n\n        if (!fileManager) {\n            return fallback(this, filePathNode);\n        }\n\n        var useBase64 = false;\n\n        // detect the mimetype if not given\n        if (!mimetypeNode) {\n\n            mimetype = environment.mimeLookup(filePath);\n\n            if (mimetype === \"image/svg+xml\") {\n                useBase64 = false;\n            } else {\n                // use base 64 unless it's an ASCII or UTF-8 format\n                var charset = environment.charsetLookup(mimetype);\n                useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0;\n            }\n            if (useBase64) { mimetype += ';base64'; }\n        }\n        else {\n            useBase64 = /;base64$/.test(mimetype);\n        }\n\n        var fileSync = fileManager.loadFileSync(filePath, currentDirectory, this.context, environment);\n        if (!fileSync.contents) {\n            logger.warn(\"Skipped data-uri embedding of \" + filePath + \" because file not found\");\n            return fallback(this, filePathNode || mimetypeNode);\n        }\n        var buf = fileSync.contents;\n        if (useBase64 && !environment.encodeBase64) {\n            return fallback(this, filePathNode);\n        }\n\n        buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf);\n\n        var uri = \"data:\" + mimetype + ',' + buf + fragment;\n\n        // IE8 cannot handle a data-uri larger than 32,768 characters. If this is exceeded\n        // and the --ieCompat flag is enabled, return a normal url() instead.\n        var DATA_URI_MAX = 32768;\n        if (uri.length >= DATA_URI_MAX) {\n\n            if (this.context.ieCompat !== false) {\n                logger.warn(\"Skipped data-uri embedding of \" + filePath + \" because its size (\" + uri.length +\n                    \" characters) exceeds IE8-safe \" + DATA_URI_MAX + \" characters!\");\n\n                return fallback(this, filePathNode || mimetypeNode);\n            }\n        }\n\n        return new URL(new Quoted('\"' + uri + '\"', uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);\n    });\n};\n\n},{\"../logger\":33,\"../tree/quoted\":73,\"../tree/url\":80,\"./function-registry\":22}],20:[function(require,module,exports){\nvar Keyword = require(\"../tree/keyword\"),\n    functionRegistry = require(\"./function-registry\");\n\nvar defaultFunc = {\n    eval: function () {\n        var v = this.value_, e = this.error_;\n        if (e) {\n            throw e;\n        }\n        if (v != null) {\n            return v ? Keyword.True : Keyword.False;\n        }\n    },\n    value: function (v) {\n        this.value_ = v;\n    },\n    error: function (e) {\n        this.error_ = e;\n    },\n    reset: function () {\n        this.value_ = this.error_ = null;\n    }\n};\n\nfunctionRegistry.add(\"default\", defaultFunc.eval.bind(defaultFunc));\n\nmodule.exports = defaultFunc;\n\n},{\"../tree/keyword\":65,\"./function-registry\":22}],21:[function(require,module,exports){\nvar Expression = require(\"../tree/expression\");\n\nvar functionCaller = function(name, context, index, currentFileInfo) {\n    this.name = name.toLowerCase();\n    this.index = index;\n    this.context = context;\n    this.currentFileInfo = currentFileInfo;\n\n    this.func = context.frames[0].functionRegistry.get(this.name);\n};\nfunctionCaller.prototype.isValid = function() {\n    return Boolean(this.func);\n};\nfunctionCaller.prototype.call = function(args) {\n\n    // This code is terrible and should be replaced as per this issue...\n    // https://github.com/less/less.js/issues/2477\n    if (Array.isArray(args)) {\n        args = args.filter(function (item) {\n            if (item.type === \"Comment\") {\n                return false;\n            }\n            return true;\n        })\n        .map(function(item) {\n            if (item.type === \"Expression\") {\n                var subNodes = item.value.filter(function (item) {\n                    if (item.type === \"Comment\") {\n                        return false;\n                    }\n                    return true;\n                });\n                if (subNodes.length === 1) {\n                    return subNodes[0];\n                } else {\n                    return new Expression(subNodes);\n                }\n            }\n            return item;\n        });\n    }\n\n    return this.func.apply(this, args);\n};\n\nmodule.exports = functionCaller;\n\n},{\"../tree/expression\":59}],22:[function(require,module,exports){\nfunction makeRegistry( base ) {\n    return {\n        _data: {},\n        add: function(name, func) {\n            // precautionary case conversion, as later querying of\n            // the registry by function-caller uses lower case as well.\n            name = name.toLowerCase();\n\n            if (this._data.hasOwnProperty(name)) {\n                //TODO warn\n            }\n            this._data[name] = func;\n        },\n        addMultiple: function(functions) {\n            Object.keys(functions).forEach(\n                function(name) {\n                    this.add(name, functions[name]);\n                }.bind(this));\n        },\n        get: function(name) {\n            return this._data[name] || ( base && base.get( name ));\n        },\n        inherit : function() {\n            return makeRegistry( this );\n        }\n    };\n}\n\nmodule.exports = makeRegistry( null );\n},{}],23:[function(require,module,exports){\nmodule.exports = function(environment) {\n    var functions = {\n        functionRegistry: require(\"./function-registry\"),\n        functionCaller: require(\"./function-caller\")\n    };\n\n    //register functions\n    require(\"./default\");\n    require(\"./color\");\n    require(\"./color-blending\");\n    require(\"./data-uri\")(environment);\n    require(\"./math\");\n    require(\"./number\");\n    require(\"./string\");\n    require(\"./svg\")(environment);\n    require(\"./types\");\n\n    return functions;\n};\n\n},{\"./color\":18,\"./color-blending\":17,\"./data-uri\":19,\"./default\":20,\"./function-caller\":21,\"./function-registry\":22,\"./math\":25,\"./number\":26,\"./string\":27,\"./svg\":28,\"./types\":29}],24:[function(require,module,exports){\nvar Dimension = require(\"../tree/dimension\");\n\nvar MathHelper = function() {\n};\nMathHelper._math = function (fn, unit, n) {\n    if (!(n instanceof Dimension)) {\n        throw { type: \"Argument\", message: \"argument must be a number\" };\n    }\n    if (unit == null) {\n        unit = n.unit;\n    } else {\n        n = n.unify();\n    }\n    return new Dimension(fn(parseFloat(n.value)), unit);\n};\nmodule.exports = MathHelper;\n},{\"../tree/dimension\":56}],25:[function(require,module,exports){\nvar functionRegistry = require(\"./function-registry\"),\n    mathHelper = require(\"./math-helper.js\");\n\nvar mathFunctions = {\n    // name,  unit\n    ceil:  null,\n    floor: null,\n    sqrt:  null,\n    abs:   null,\n    tan:   \"\",\n    sin:   \"\",\n    cos:   \"\",\n    atan:  \"rad\",\n    asin:  \"rad\",\n    acos:  \"rad\"\n};\n\nfor (var f in mathFunctions) {\n    if (mathFunctions.hasOwnProperty(f)) {\n        mathFunctions[f] = mathHelper._math.bind(null, Math[f], mathFunctions[f]);\n    }\n}\n\nmathFunctions.round = function (n, f) {\n    var fraction = typeof f === \"undefined\" ? 0 : f.value;\n    return mathHelper._math(function(num) { return num.toFixed(fraction); }, null, n);\n};\n\nfunctionRegistry.addMultiple(mathFunctions);\n\n},{\"./function-registry\":22,\"./math-helper.js\":24}],26:[function(require,module,exports){\nvar Dimension = require(\"../tree/dimension\"),\n    Anonymous = require(\"../tree/anonymous\"),\n    functionRegistry = require(\"./function-registry\"),\n    mathHelper = require(\"./math-helper.js\");\n\nvar minMax = function (isMin, args) {\n    args = Array.prototype.slice.call(args);\n    switch(args.length) {\n        case 0: throw { type: \"Argument\", message: \"one or more arguments required\" };\n    }\n    var i, j, current, currentUnified, referenceUnified, unit, unitStatic, unitClone,\n        order  = [], // elems only contains original argument values.\n        values = {}; // key is the unit.toString() for unified Dimension values,\n    // value is the index into the order array.\n    for (i = 0; i < args.length; i++) {\n        current = args[i];\n        if (!(current instanceof Dimension)) {\n            if (Array.isArray(args[i].value)) {\n                Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value));\n            }\n            continue;\n        }\n        currentUnified = current.unit.toString() === \"\" && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify();\n        unit = currentUnified.unit.toString() === \"\" && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString();\n        unitStatic = unit !== \"\" && unitStatic === undefined || unit !== \"\" && order[0].unify().unit.toString() === \"\" ? unit : unitStatic;\n        unitClone = unit !== \"\" && unitClone === undefined ? current.unit.toString() : unitClone;\n        j = values[\"\"] !== undefined && unit !== \"\" && unit === unitStatic ? values[\"\"] : values[unit];\n        if (j === undefined) {\n            if (unitStatic !== undefined && unit !== unitStatic) {\n                throw{ type: \"Argument\", message: \"incompatible types\" };\n            }\n            values[unit] = order.length;\n            order.push(current);\n            continue;\n        }\n        referenceUnified = order[j].unit.toString() === \"\" && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify();\n        if ( isMin && currentUnified.value < referenceUnified.value ||\n            !isMin && currentUnified.value > referenceUnified.value) {\n            order[j] = current;\n        }\n    }\n    if (order.length == 1) {\n        return order[0];\n    }\n    args = order.map(function (a) { return a.toCSS(this.context); }).join(this.context.compress ? \",\" : \", \");\n    return new Anonymous((isMin ? \"min\" : \"max\") + \"(\" + args + \")\");\n};\nfunctionRegistry.addMultiple({\n    min: function () {\n        return minMax(true, arguments);\n    },\n    max: function () {\n        return minMax(false, arguments);\n    },\n    convert: function (val, unit) {\n        return val.convertTo(unit.value);\n    },\n    pi: function () {\n        return new Dimension(Math.PI);\n    },\n    mod: function(a, b) {\n        return new Dimension(a.value % b.value, a.unit);\n    },\n    pow: function(x, y) {\n        if (typeof x === \"number\" && typeof y === \"number\") {\n            x = new Dimension(x);\n            y = new Dimension(y);\n        } else if (!(x instanceof Dimension) || !(y instanceof Dimension)) {\n            throw { type: \"Argument\", message: \"arguments must be numbers\" };\n        }\n\n        return new Dimension(Math.pow(x.value, y.value), x.unit);\n    },\n    percentage: function (n) {\n        var result = mathHelper._math(function(num) {\n            return num * 100;\n        }, '%', n);\n\n        return result;\n    }\n});\n\n},{\"../tree/anonymous\":46,\"../tree/dimension\":56,\"./function-registry\":22,\"./math-helper.js\":24}],27:[function(require,module,exports){\nvar Quoted = require(\"../tree/quoted\"),\n    Anonymous = require(\"../tree/anonymous\"),\n    JavaScript = require(\"../tree/javascript\"),\n    functionRegistry = require(\"./function-registry\");\n\nfunctionRegistry.addMultiple({\n    e: function (str) {\n        return new Anonymous(str instanceof JavaScript ? str.evaluated : str.value);\n    },\n    escape: function (str) {\n        return new Anonymous(\n            encodeURI(str.value).replace(/=/g, \"%3D\").replace(/:/g, \"%3A\").replace(/#/g, \"%23\").replace(/;/g, \"%3B\")\n                .replace(/\\(/g, \"%28\").replace(/\\)/g, \"%29\"));\n    },\n    replace: function (string, pattern, replacement, flags) {\n        var result = string.value;\n        replacement = (replacement.type === \"Quoted\") ?\n            replacement.value : replacement.toCSS();\n        result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement);\n        return new Quoted(string.quote || '', result, string.escaped);\n    },\n    '%': function (string /* arg, arg, ...*/) {\n        var args = Array.prototype.slice.call(arguments, 1),\n            result = string.value;\n\n        for (var i = 0; i < args.length; i++) {\n            /*jshint loopfunc:true */\n            result = result.replace(/%[sda]/i, function(token) {\n                var value = ((args[i].type === \"Quoted\") &&\n                    token.match(/s/i)) ? args[i].value : args[i].toCSS();\n                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;\n            });\n        }\n        result = result.replace(/%%/g, '%');\n        return new Quoted(string.quote || '', result, string.escaped);\n    }\n});\n\n},{\"../tree/anonymous\":46,\"../tree/javascript\":63,\"../tree/quoted\":73,\"./function-registry\":22}],28:[function(require,module,exports){\nmodule.exports = function(environment) {\n    var Dimension = require(\"../tree/dimension\"),\n        Color = require(\"../tree/color\"),\n        Expression = require(\"../tree/expression\"),\n        Quoted = require(\"../tree/quoted\"),\n        URL = require(\"../tree/url\"),\n        functionRegistry = require(\"./function-registry\");\n\n    functionRegistry.add(\"svg-gradient\", function(direction) {\n\n        var stops,\n            gradientDirectionSvg,\n            gradientType = \"linear\",\n            rectangleDimension = 'x=\"0\" y=\"0\" width=\"1\" height=\"1\"',\n            renderEnv = {compress: false},\n            returner,\n            directionValue = direction.toCSS(renderEnv),\n\t\t\ti, color, position, positionValue, alpha;\n\n        function throwArgumentDescriptor() {\n            throw { type: \"Argument\",\n\t\t\t\t\tmessage: \"svg-gradient expects direction, start_color [start_position], [color position,]...,\" +\n\t\t\t\t\t\t\t\" end_color [end_position] or direction, color list\" };\n        }\n\n        if (arguments.length == 2) {\n            if (arguments[1].value.length < 2) {\n                throwArgumentDescriptor();\n            }\n            stops = arguments[1].value;\n        } else if (arguments.length < 3) {\n            throwArgumentDescriptor();\n        } else {\n            stops = Array.prototype.slice.call(arguments, 1);\n        }\n\n        switch (directionValue) {\n            case \"to bottom\":\n                gradientDirectionSvg = 'x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\"';\n                break;\n            case \"to right\":\n                gradientDirectionSvg = 'x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\"';\n                break;\n            case \"to bottom right\":\n                gradientDirectionSvg = 'x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\"';\n                break;\n            case \"to top right\":\n                gradientDirectionSvg = 'x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\"';\n                break;\n            case \"ellipse\":\n            case \"ellipse at center\":\n                gradientType = \"radial\";\n                gradientDirectionSvg = 'cx=\"50%\" cy=\"50%\" r=\"75%\"';\n                rectangleDimension = 'x=\"-50\" y=\"-50\" width=\"101\" height=\"101\"';\n                break;\n            default:\n                throw { type: \"Argument\", message: \"svg-gradient direction must be 'to bottom', 'to right',\" +\n                    \" 'to bottom right', 'to top right' or 'ellipse at center'\" };\n        }\n        returner = '<?xml version=\"1.0\" ?>' +\n            '<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"100%\" height=\"100%\" viewBox=\"0 0 1 1\" preserveAspectRatio=\"none\">' +\n            '<' + gradientType + 'Gradient id=\"gradient\" gradientUnits=\"userSpaceOnUse\" ' + gradientDirectionSvg + '>';\n\n        for (i = 0; i < stops.length; i+= 1) {\n            if (stops[i] instanceof Expression) {\n                color = stops[i].value[0];\n                position = stops[i].value[1];\n            } else {\n                color = stops[i];\n                position = undefined;\n            }\n\n            if (!(color instanceof Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension))) {\n                throwArgumentDescriptor();\n            }\n            positionValue = position ? position.toCSS(renderEnv) : i === 0 ? \"0%\" : \"100%\";\n            alpha = color.alpha;\n            returner += '<stop offset=\"' + positionValue + '\" stop-color=\"' + color.toRGB() + '\"' + (alpha < 1 ? ' stop-opacity=\"' + alpha + '\"' : '') + '/>';\n        }\n        returner += '</' + gradientType + 'Gradient>' +\n            '<rect ' + rectangleDimension + ' fill=\"url(#gradient)\" /></svg>';\n\n        returner = encodeURIComponent(returner);\n\n        returner = \"data:image/svg+xml,\" + returner;\n        return new URL(new Quoted(\"'\" + returner + \"'\", returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);\n    });\n};\n\n},{\"../tree/color\":50,\"../tree/dimension\":56,\"../tree/expression\":59,\"../tree/quoted\":73,\"../tree/url\":80,\"./function-registry\":22}],29:[function(require,module,exports){\nvar Keyword = require(\"../tree/keyword\"),\n    DetachedRuleset = require(\"../tree/detached-ruleset\"),\n    Dimension = require(\"../tree/dimension\"),\n    Color = require(\"../tree/color\"),\n    Quoted = require(\"../tree/quoted\"),\n    Anonymous = require(\"../tree/anonymous\"),\n    URL = require(\"../tree/url\"),\n    Operation = require(\"../tree/operation\"),\n    functionRegistry = require(\"./function-registry\");\n\nvar isa = function (n, Type) {\n        return (n instanceof Type) ? Keyword.True : Keyword.False;\n    },\n    isunit = function (n, unit) {\n        if (unit === undefined) {\n            throw { type: \"Argument\", message: \"missing the required second argument to isunit.\" };\n        }\n        unit = typeof unit.value === \"string\" ? unit.value : unit;\n        if (typeof unit !== \"string\") {\n            throw { type: \"Argument\", message: \"Second argument to isunit should be a unit or a string.\" };\n        }\n        return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False;\n    },\n    getItemsFromNode = function(node) {\n        // handle non-array values as an array of length 1\n        // return 'undefined' if index is invalid\n        var items = Array.isArray(node.value) ?\n            node.value : Array(node);\n\n        return items;\n    };\nfunctionRegistry.addMultiple({\n    isruleset: function (n) {\n        return isa(n, DetachedRuleset);\n    },\n    iscolor: function (n) {\n        return isa(n, Color);\n    },\n    isnumber: function (n) {\n        return isa(n, Dimension);\n    },\n    isstring: function (n) {\n        return isa(n, Quoted);\n    },\n    iskeyword: function (n) {\n        return isa(n, Keyword);\n    },\n    isurl: function (n) {\n        return isa(n, URL);\n    },\n    ispixel: function (n) {\n        return isunit(n, 'px');\n    },\n    ispercentage: function (n) {\n        return isunit(n, '%');\n    },\n    isem: function (n) {\n        return isunit(n, 'em');\n    },\n    isunit: isunit,\n    unit: function (val, unit) {\n        if (!(val instanceof Dimension)) {\n            throw { type: \"Argument\",\n                message: \"the first argument to unit must be a number\" +\n                    (val instanceof Operation ? \". Have you forgotten parenthesis?\" : \"\") };\n        }\n        if (unit) {\n            if (unit instanceof Keyword) {\n                unit = unit.value;\n            } else {\n                unit = unit.toCSS();\n            }\n        } else {\n            unit = \"\";\n        }\n        return new Dimension(val.value, unit);\n    },\n    \"get-unit\": function (n) {\n        return new Anonymous(n.unit);\n    },\n    extract: function(values, index) {\n        index = index.value - 1; // (1-based index)\n\n        return getItemsFromNode(values)[index];\n    },\n    length: function(values) {\n        return new Dimension(getItemsFromNode(values).length);\n    }\n});\n\n},{\"../tree/anonymous\":46,\"../tree/color\":50,\"../tree/detached-ruleset\":55,\"../tree/dimension\":56,\"../tree/keyword\":65,\"../tree/operation\":71,\"../tree/quoted\":73,\"../tree/url\":80,\"./function-registry\":22}],30:[function(require,module,exports){\nvar contexts = require(\"./contexts\"),\n    Parser = require('./parser/parser'),\n    FunctionImporter = require('./plugins/function-importer');\n\nmodule.exports = function(environment) {\n\n    // FileInfo = {\n    //  'relativeUrls' - option - whether to adjust URL's to be relative\n    //  'filename' - full resolved filename of current file\n    //  'rootpath' - path to append to normal URLs for this node\n    //  'currentDirectory' - path to the current file, absolute\n    //  'rootFilename' - filename of the base file\n    //  'entryPath' - absolute path to the entry file\n    //  'reference' - whether the file should not be output and only output parts that are referenced\n\n    var ImportManager = function(context, rootFileInfo) {\n        this.rootFilename = rootFileInfo.filename;\n        this.paths = context.paths || [];  // Search paths, when importing\n        this.contents = {};             // map - filename to contents of all the files\n        this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore\n        this.mime = context.mime;\n        this.error = null;\n        this.context = context;\n        // Deprecated? Unused outside of here, could be useful.\n        this.queue = [];        // Files which haven't been imported yet\n        this.files = {};        // Holds the imported parse trees.\n    };\n    /**\n     * Add an import to be imported\n     * @param path - the raw path\n     * @param tryAppendLessExtension - whether to try appending the less extension (if the path has no extension)\n     * @param currentFileInfo - the current file info (used for instance to work out relative paths)\n     * @param importOptions - import options\n     * @param callback - callback for when it is imported\n     */\n    ImportManager.prototype.push = function (path, tryAppendLessExtension, currentFileInfo, importOptions, callback) {\n        var importManager = this;\n        this.queue.push(path);\n\n        var fileParsedFunc = function (e, root, fullPath) {\n            importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue\n\n            var importedEqualsRoot = fullPath === importManager.rootFilename;\n            if (importOptions.optional && e) {\n                callback(null, {rules:[]}, false, null);\n            }\n            else {\n                importManager.files[fullPath] = root;\n                if (e && !importManager.error) { importManager.error = e; }\n                callback(e, root, importedEqualsRoot, fullPath);\n            }\n        };\n\n        var newFileInfo = {\n            relativeUrls: this.context.relativeUrls,\n            entryPath: currentFileInfo.entryPath,\n            rootpath: currentFileInfo.rootpath,\n            rootFilename: currentFileInfo.rootFilename\n        };\n\n        var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment);\n\n        if (!fileManager) {\n            fileParsedFunc({ message: \"Could not find a file-manager for \" + path });\n            return;\n        }\n\n        if (tryAppendLessExtension) {\n            path = fileManager.tryAppendExtension(path, importOptions.plugin ? \".js\" : \".less\");\n        }\n\n        var loadFileCallback = function(loadedFile) {\n            var resolvedFilename = loadedFile.filename,\n                contents = loadedFile.contents.replace(/^\\uFEFF/, '');\n\n            // Pass on an updated rootpath if path of imported file is relative and file\n            // is in a (sub|sup) directory\n            //\n            // Examples:\n            // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/',\n            //   then rootpath should become 'less/module/nav/'\n            // - If path of imported file is '../mixins.less' and rootpath is 'less/',\n            //   then rootpath should become 'less/../'\n            newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename);\n            if (newFileInfo.relativeUrls) {\n                newFileInfo.rootpath = fileManager.join(\n                    (importManager.context.rootpath || \"\"),\n                    fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));\n\n                if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) {\n                    newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath);\n                }\n            }\n            newFileInfo.filename = resolvedFilename;\n\n            var newEnv = new contexts.Parse(importManager.context);\n\n            newEnv.processImports = false;\n            importManager.contents[resolvedFilename] = contents;\n\n            if (currentFileInfo.reference || importOptions.reference) {\n                newFileInfo.reference = true;\n            }\n\n            if (importOptions.plugin) {\n                new FunctionImporter(newEnv, newFileInfo).eval(contents, function (e, root) {\n                    fileParsedFunc(e, root, resolvedFilename);\n                });\n            } else if (importOptions.inline) {\n                fileParsedFunc(null, contents, resolvedFilename);\n            } else {\n                new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) {\n                    fileParsedFunc(e, root, resolvedFilename);\n                });\n            }\n        };\n\n        var promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, this.context, environment,\n            function(err, loadedFile) {\n            if (err) {\n                fileParsedFunc(err);\n            } else {\n                loadFileCallback(loadedFile);\n            }\n        });\n        if (promise) {\n            promise.then(loadFileCallback, fileParsedFunc);\n        }\n    };\n    return ImportManager;\n};\n\n},{\"./contexts\":11,\"./parser/parser\":38,\"./plugins/function-importer\":40}],31:[function(require,module,exports){\nmodule.exports = function(environment, fileManagers) {\n    var SourceMapOutput, SourceMapBuilder, ParseTree, ImportManager, Environment;\n\n    var less = {\n        version: [2, 7, 1],\n        data: require('./data'),\n        tree: require('./tree'),\n        Environment: (Environment = require(\"./environment/environment\")),\n        AbstractFileManager: require(\"./environment/abstract-file-manager\"),\n        environment: (environment = new Environment(environment, fileManagers)),\n        visitors: require('./visitors'),\n        Parser: require('./parser/parser'),\n        functions: require('./functions')(environment),\n        contexts: require(\"./contexts\"),\n        SourceMapOutput: (SourceMapOutput = require('./source-map-output')(environment)),\n        SourceMapBuilder: (SourceMapBuilder = require('./source-map-builder')(SourceMapOutput, environment)),\n        ParseTree: (ParseTree = require('./parse-tree')(SourceMapBuilder)),\n        ImportManager: (ImportManager = require('./import-manager')(environment)),\n        render: require(\"./render\")(environment, ParseTree, ImportManager),\n        parse: require(\"./parse\")(environment, ParseTree, ImportManager),\n        LessError: require('./less-error'),\n        transformTree: require('./transform-tree'),\n        utils: require('./utils'),\n        PluginManager: require('./plugin-manager'),\n        logger: require('./logger')\n    };\n\n    return less;\n};\n\n},{\"./contexts\":11,\"./data\":13,\"./environment/abstract-file-manager\":15,\"./environment/environment\":16,\"./functions\":23,\"./import-manager\":30,\"./less-error\":32,\"./logger\":33,\"./parse\":35,\"./parse-tree\":34,\"./parser/parser\":38,\"./plugin-manager\":39,\"./render\":41,\"./source-map-builder\":42,\"./source-map-output\":43,\"./transform-tree\":44,\"./tree\":62,\"./utils\":83,\"./visitors\":87}],32:[function(require,module,exports){\nvar utils = require(\"./utils\");\n\nvar LessError = module.exports = function LessError(e, importManager, currentFilename) {\n\n    Error.call(this);\n\n    var filename = e.filename || currentFilename;\n\n    if (importManager && filename) {\n        var input = importManager.contents[filename],\n            loc = utils.getLocation(e.index, input),\n            line = loc.line,\n            col  = loc.column,\n            callLine = e.call && utils.getLocation(e.call, input).line,\n            lines = input.split('\\n');\n\n        this.type = e.type || 'Syntax';\n        this.filename = filename;\n        this.index = e.index;\n        this.line = typeof line === 'number' ? line + 1 : null;\n        this.callLine = callLine + 1;\n        this.callExtract = lines[callLine];\n        this.column = col;\n        this.extract = [\n            lines[line - 1],\n            lines[line],\n            lines[line + 1]\n        ];\n    }\n    this.message = e.message;\n    this.stack = e.stack;\n};\n\nif (typeof Object.create === 'undefined') {\n    var F = function () {};\n    F.prototype = Error.prototype;\n    LessError.prototype = new F();\n} else {\n    LessError.prototype = Object.create(Error.prototype);\n}\n\nLessError.prototype.constructor = LessError;\n\n},{\"./utils\":83}],33:[function(require,module,exports){\nmodule.exports = {\n    error: function(msg) {\n        this._fireEvent(\"error\", msg);\n    },\n    warn: function(msg) {\n        this._fireEvent(\"warn\", msg);\n    },\n    info: function(msg) {\n        this._fireEvent(\"info\", msg);\n    },\n    debug: function(msg) {\n        this._fireEvent(\"debug\", msg);\n    },\n    addListener: function(listener) {\n        this._listeners.push(listener);\n    },\n    removeListener: function(listener) {\n        for (var i = 0; i < this._listeners.length; i++) {\n            if (this._listeners[i] === listener) {\n                this._listeners.splice(i, 1);\n                return;\n            }\n        }\n    },\n    _fireEvent: function(type, msg) {\n        for (var i = 0; i < this._listeners.length; i++) {\n            var logFunction = this._listeners[i][type];\n            if (logFunction) {\n                logFunction(msg);\n            }\n        }\n    },\n    _listeners: []\n};\n\n},{}],34:[function(require,module,exports){\nvar LessError = require('./less-error'),\n    transformTree = require(\"./transform-tree\"),\n    logger = require(\"./logger\");\n\nmodule.exports = function(SourceMapBuilder) {\n    var ParseTree = function(root, imports) {\n        this.root = root;\n        this.imports = imports;\n    };\n\n    ParseTree.prototype.toCSS = function(options) {\n        var evaldRoot, result = {}, sourceMapBuilder;\n        try {\n            evaldRoot = transformTree(this.root, options);\n        } catch (e) {\n            throw new LessError(e, this.imports);\n        }\n\n        try {\n            var compress = Boolean(options.compress);\n            if (compress) {\n                logger.warn(\"The compress option has been deprecated. We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.\");\n            }\n\n            var toCSSOptions = {\n                compress: compress,\n                dumpLineNumbers: options.dumpLineNumbers,\n                strictUnits: Boolean(options.strictUnits),\n                numPrecision: 8};\n\n            if (options.sourceMap) {\n                sourceMapBuilder = new SourceMapBuilder(options.sourceMap);\n                result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports);\n            } else {\n                result.css = evaldRoot.toCSS(toCSSOptions);\n            }\n        } catch (e) {\n            throw new LessError(e, this.imports);\n        }\n\n        if (options.pluginManager) {\n            var postProcessors = options.pluginManager.getPostProcessors();\n            for (var i = 0; i < postProcessors.length; i++) {\n                result.css = postProcessors[i].process(result.css, { sourceMap: sourceMapBuilder, options: options, imports: this.imports });\n            }\n        }\n        if (options.sourceMap) {\n            result.map = sourceMapBuilder.getExternalSourceMap();\n        }\n\n        result.imports = [];\n        for (var file in this.imports.files) {\n            if (this.imports.files.hasOwnProperty(file) && file !== this.imports.rootFilename) {\n                result.imports.push(file);\n            }\n        }\n        return result;\n    };\n    return ParseTree;\n};\n\n},{\"./less-error\":32,\"./logger\":33,\"./transform-tree\":44}],35:[function(require,module,exports){\nvar PromiseConstructor,\n    contexts = require(\"./contexts\"),\n    Parser = require('./parser/parser'),\n    PluginManager = require('./plugin-manager');\n\nmodule.exports = function(environment, ParseTree, ImportManager) {\n    var parse = function (input, options, callback) {\n        options = options || {};\n\n        if (typeof options === 'function') {\n            callback = options;\n            options = {};\n        }\n\n        if (!callback) {\n            if (!PromiseConstructor) {\n                PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise;\n            }\n            var self = this;\n            return new PromiseConstructor(function (resolve, reject) {\n                parse.call(self, input, options, function(err, output) {\n                    if (err) {\n                        reject(err);\n                    } else {\n                        resolve(output);\n                    }\n                });\n            });\n        } else {\n            var context,\n                rootFileInfo,\n                pluginManager = new PluginManager(this);\n\n            pluginManager.addPlugins(options.plugins);\n            options.pluginManager = pluginManager;\n\n            context = new contexts.Parse(options);\n\n            if (options.rootFileInfo) {\n                rootFileInfo = options.rootFileInfo;\n            } else {\n                var filename = options.filename || \"input\";\n                var entryPath = filename.replace(/[^\\/\\\\]*$/, \"\");\n                rootFileInfo = {\n                    filename: filename,\n                    relativeUrls: context.relativeUrls,\n                    rootpath: context.rootpath || \"\",\n                    currentDirectory: entryPath,\n                    entryPath: entryPath,\n                    rootFilename: filename\n                };\n                // add in a missing trailing slash\n                if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== \"/\") {\n                    rootFileInfo.rootpath += \"/\";\n                }\n            }\n\n            var imports = new ImportManager(context, rootFileInfo);\n\n            new Parser(context, imports, rootFileInfo)\n                .parse(input, function (e, root) {\n                if (e) { return callback(e); }\n                callback(null, root, imports, options);\n            }, options);\n        }\n    };\n    return parse;\n};\n\n},{\"./contexts\":11,\"./parser/parser\":38,\"./plugin-manager\":39,\"promise\":undefined}],36:[function(require,module,exports){\n// Split the input into chunks.\nmodule.exports = function (input, fail) {\n    var len = input.length, level = 0, parenLevel = 0,\n        lastOpening, lastOpeningParen, lastMultiComment, lastMultiCommentEndBrace,\n        chunks = [], emitFrom = 0,\n        chunkerCurrentIndex, currentChunkStartIndex, cc, cc2, matched;\n\n    function emitChunk(force) {\n        var len = chunkerCurrentIndex - emitFrom;\n        if (((len < 512) && !force) || !len) {\n            return;\n        }\n        chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1));\n        emitFrom = chunkerCurrentIndex + 1;\n    }\n\n    for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) {\n        cc = input.charCodeAt(chunkerCurrentIndex);\n        if (((cc >= 97) && (cc <= 122)) || (cc < 34)) {\n            // a-z or whitespace\n            continue;\n        }\n\n        switch (cc) {\n            case 40:                        // (\n                parenLevel++;\n                lastOpeningParen = chunkerCurrentIndex;\n                continue;\n            case 41:                        // )\n                if (--parenLevel < 0) {\n                    return fail(\"missing opening `(`\", chunkerCurrentIndex);\n                }\n                continue;\n            case 59:                        // ;\n                if (!parenLevel) { emitChunk(); }\n                continue;\n            case 123:                       // {\n                level++;\n                lastOpening = chunkerCurrentIndex;\n                continue;\n            case 125:                       // }\n                if (--level < 0) {\n                    return fail(\"missing opening `{`\", chunkerCurrentIndex);\n                }\n                if (!level && !parenLevel) { emitChunk(); }\n                continue;\n            case 92:                        // \\\n                if (chunkerCurrentIndex < len - 1) { chunkerCurrentIndex++; continue; }\n                return fail(\"unescaped `\\\\`\", chunkerCurrentIndex);\n            case 34:\n            case 39:\n            case 96:                        // \", ' and `\n                matched = 0;\n                currentChunkStartIndex = chunkerCurrentIndex;\n                for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) {\n                    cc2 = input.charCodeAt(chunkerCurrentIndex);\n                    if (cc2 > 96) { continue; }\n                    if (cc2 == cc) { matched = 1; break; }\n                    if (cc2 == 92) {        // \\\n                        if (chunkerCurrentIndex == len - 1) {\n                            return fail(\"unescaped `\\\\`\", chunkerCurrentIndex);\n                        }\n                        chunkerCurrentIndex++;\n                    }\n                }\n                if (matched) { continue; }\n                return fail(\"unmatched `\" + String.fromCharCode(cc) + \"`\", currentChunkStartIndex);\n            case 47:                        // /, check for comment\n                if (parenLevel || (chunkerCurrentIndex == len - 1)) { continue; }\n                cc2 = input.charCodeAt(chunkerCurrentIndex + 1);\n                if (cc2 == 47) {\n                    // //, find lnfeed\n                    for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) {\n                        cc2 = input.charCodeAt(chunkerCurrentIndex);\n                        if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; }\n                    }\n                } else if (cc2 == 42) {\n                    // /*, find */\n                    lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex;\n                    for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) {\n                        cc2 = input.charCodeAt(chunkerCurrentIndex);\n                        if (cc2 == 125) { lastMultiCommentEndBrace = chunkerCurrentIndex; }\n                        if (cc2 != 42) { continue; }\n                        if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { break; }\n                    }\n                    if (chunkerCurrentIndex == len - 1) {\n                        return fail(\"missing closing `*/`\", currentChunkStartIndex);\n                    }\n                    chunkerCurrentIndex++;\n                }\n                continue;\n            case 42:                       // *, check for unmatched */\n                if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) {\n                    return fail(\"unmatched `/*`\", chunkerCurrentIndex);\n                }\n                continue;\n        }\n    }\n\n    if (level !== 0) {\n        if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) {\n            return fail(\"missing closing `}` or `*/`\", lastOpening);\n        } else {\n            return fail(\"missing closing `}`\", lastOpening);\n        }\n    } else if (parenLevel !== 0) {\n        return fail(\"missing closing `)`\", lastOpeningParen);\n    }\n\n    emitChunk(true);\n    return chunks;\n};\n\n},{}],37:[function(require,module,exports){\nvar chunker = require('./chunker');\n\nmodule.exports = function() {\n    var input,       // LeSS input string\n        j,           // current chunk\n        saveStack = [],   // holds state for backtracking\n        furthest,    // furthest index the parser has gone to\n        furthestPossibleErrorMessage,// if this is furthest we got to, this is the probably cause\n        chunks,      // chunkified input\n        current,     // current chunk\n        currentPos,  // index of current chunk, in `input`\n        parserInput = {};\n\n    var CHARCODE_SPACE = 32,\n        CHARCODE_TAB = 9,\n        CHARCODE_LF = 10,\n        CHARCODE_CR = 13,\n        CHARCODE_PLUS = 43,\n        CHARCODE_COMMA = 44,\n        CHARCODE_FORWARD_SLASH = 47,\n        CHARCODE_9 = 57;\n\n    function skipWhitespace(length) {\n        var oldi = parserInput.i, oldj = j,\n            curr = parserInput.i - currentPos,\n            endIndex = parserInput.i + current.length - curr,\n            mem = (parserInput.i += length),\n            inp = input,\n            c, nextChar, comment;\n\n        for (; parserInput.i < endIndex; parserInput.i++) {\n            c = inp.charCodeAt(parserInput.i);\n\n            if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) {\n                nextChar = inp.charAt(parserInput.i + 1);\n                if (nextChar === '/') {\n                    comment = {index: parserInput.i, isLineComment: true};\n                    var nextNewLine = inp.indexOf(\"\\n\", parserInput.i + 2);\n                    if (nextNewLine < 0) {\n                        nextNewLine = endIndex;\n                    }\n                    parserInput.i = nextNewLine;\n                    comment.text = inp.substr(comment.index, parserInput.i - comment.index);\n                    parserInput.commentStore.push(comment);\n                    continue;\n                } else if (nextChar === '*') {\n                    var nextStarSlash = inp.indexOf(\"*/\", parserInput.i + 2);\n                    if (nextStarSlash >= 0) {\n                        comment = {\n                            index: parserInput.i,\n                            text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i),\n                            isLineComment: false\n                        };\n                        parserInput.i += comment.text.length - 1;\n                        parserInput.commentStore.push(comment);\n                        continue;\n                    }\n                }\n                break;\n            }\n\n            if ((c !== CHARCODE_SPACE) && (c !== CHARCODE_LF) && (c !== CHARCODE_TAB) && (c !== CHARCODE_CR)) {\n                break;\n            }\n        }\n\n        current = current.slice(length + parserInput.i - mem + curr);\n        currentPos = parserInput.i;\n\n        if (!current.length) {\n            if (j < chunks.length - 1) {\n                current = chunks[++j];\n                skipWhitespace(0); // skip space at the beginning of a chunk\n                return true; // things changed\n            }\n            parserInput.finished = true;\n        }\n\n        return oldi !== parserInput.i || oldj !== j;\n    }\n\n    parserInput.save = function() {\n        currentPos = parserInput.i;\n        saveStack.push( { current: current, i: parserInput.i, j: j });\n    };\n    parserInput.restore = function(possibleErrorMessage) {\n\n        if (parserInput.i > furthest || (parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage)) {\n            furthest = parserInput.i;\n            furthestPossibleErrorMessage = possibleErrorMessage;\n        }\n        var state = saveStack.pop();\n        current = state.current;\n        currentPos = parserInput.i = state.i;\n        j = state.j;\n    };\n    parserInput.forget = function() {\n        saveStack.pop();\n    };\n    parserInput.isWhitespace = function (offset) {\n        var pos = parserInput.i + (offset || 0),\n            code = input.charCodeAt(pos);\n        return (code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF);\n    };\n\n    // Specialization of $(tok)\n    parserInput.$re = function(tok) {\n        if (parserInput.i > currentPos) {\n            current = current.slice(parserInput.i - currentPos);\n            currentPos = parserInput.i;\n        }\n\n        var m = tok.exec(current);\n        if (!m) {\n            return null;\n        }\n\n        skipWhitespace(m[0].length);\n        if (typeof m === \"string\") {\n            return m;\n        }\n\n        return m.length === 1 ? m[0] : m;\n    };\n\n    parserInput.$char = function(tok) {\n        if (input.charAt(parserInput.i) !== tok) {\n            return null;\n        }\n        skipWhitespace(1);\n        return tok;\n    };\n\n    parserInput.$str = function(tok) {\n        var tokLength = tok.length;\n\n        // https://jsperf.com/string-startswith/21\n        for (var i = 0; i < tokLength; i++) {\n            if (input.charAt(parserInput.i + i) !== tok.charAt(i)) {\n                return null;\n            }\n        }\n\n        skipWhitespace(tokLength);\n        return tok;\n    };\n\n    parserInput.$quoted = function() {\n\n        var startChar = input.charAt(parserInput.i);\n        if (startChar !== \"'\" && startChar !== '\"') {\n            return;\n        }\n        var length = input.length,\n            currentPosition = parserInput.i;\n\n        for (var i = 1; i + currentPosition < length; i++) {\n            var nextChar = input.charAt(i + currentPosition);\n            switch(nextChar) {\n                case \"\\\\\":\n                    i++;\n                    continue;\n                case \"\\r\":\n                case \"\\n\":\n                    break;\n                case startChar:\n                    var str = input.substr(currentPosition, i + 1);\n                    skipWhitespace(i + 1);\n                    return str;\n                default:\n            }\n        }\n        return null;\n    };\n\n    parserInput.autoCommentAbsorb = true;\n    parserInput.commentStore = [];\n    parserInput.finished = false;\n\n    // Same as $(), but don't change the state of the parser,\n    // just return the match.\n    parserInput.peek = function(tok) {\n        if (typeof tok === 'string') {\n            // https://jsperf.com/string-startswith/21\n            for (var i = 0; i < tok.length; i++) {\n                if (input.charAt(parserInput.i + i) !== tok.charAt(i)) {\n                    return false;\n                }\n            }\n            return true;\n        } else {\n            return tok.test(current);\n        }\n    };\n\n    // Specialization of peek()\n    // TODO remove or change some currentChar calls to peekChar\n    parserInput.peekChar = function(tok) {\n        return input.charAt(parserInput.i) === tok;\n    };\n\n    parserInput.currentChar = function() {\n        return input.charAt(parserInput.i);\n    };\n\n    parserInput.getInput = function() {\n        return input;\n    };\n\n    parserInput.peekNotNumeric = function() {\n        var c = input.charCodeAt(parserInput.i);\n        //Is the first char of the dimension 0-9, '.', '+' or '-'\n        return (c > CHARCODE_9 || c < CHARCODE_PLUS) || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA;\n    };\n\n    parserInput.start = function(str, chunkInput, failFunction) {\n        input = str;\n        parserInput.i = j = currentPos = furthest = 0;\n\n        // chunking apparently makes things quicker (but my tests indicate\n        // it might actually make things slower in node at least)\n        // and it is a non-perfect parse - it can't recognise\n        // unquoted urls, meaning it can't distinguish comments\n        // meaning comments with quotes or {}() in them get 'counted'\n        // and then lead to parse errors.\n        // In addition if the chunking chunks in the wrong place we might\n        // not be able to parse a parser statement in one go\n        // this is officially deprecated but can be switched on via an option\n        // in the case it causes too much performance issues.\n        if (chunkInput) {\n            chunks = chunker(str, failFunction);\n        } else {\n            chunks = [str];\n        }\n\n        current = chunks[0];\n\n        skipWhitespace(0);\n    };\n\n    parserInput.end = function() {\n        var message,\n            isFinished = parserInput.i >= input.length;\n\n        if (parserInput.i < furthest) {\n            message = furthestPossibleErrorMessage;\n            parserInput.i = furthest;\n        }\n        return {\n            isFinished: isFinished,\n            furthest: parserInput.i,\n            furthestPossibleErrorMessage: message,\n            furthestReachedEnd: parserInput.i >= input.length - 1,\n            furthestChar: input[parserInput.i]\n        };\n    };\n\n    return parserInput;\n};\n\n},{\"./chunker\":36}],38:[function(require,module,exports){\nvar LessError = require('../less-error'),\n    tree = require(\"../tree\"),\n    visitors = require(\"../visitors\"),\n    getParserInput = require(\"./parser-input\"),\n    utils = require(\"../utils\");\n\n//\n// less.js - parser\n//\n//    A relatively straight-forward predictive parser.\n//    There is no tokenization/lexing stage, the input is parsed\n//    in one sweep.\n//\n//    To make the parser fast enough to run in the browser, several\n//    optimization had to be made:\n//\n//    - Matching and slicing on a huge input is often cause of slowdowns.\n//      The solution is to chunkify the input into smaller strings.\n//      The chunks are stored in the `chunks` var,\n//      `j` holds the current chunk index, and `currentPos` holds\n//      the index of the current chunk in relation to `input`.\n//      This gives us an almost 4x speed-up.\n//\n//    - In many cases, we don't need to match individual tokens;\n//      for example, if a value doesn't hold any variables, operations\n//      or dynamic references, the parser can effectively 'skip' it,\n//      treating it as a literal.\n//      An example would be '1px solid #000' - which evaluates to itself,\n//      we don't need to know what the individual components are.\n//      The drawback, of course is that you don't get the benefits of\n//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,\n//      and a smaller speed-up in the code-gen.\n//\n//\n//    Token matching is done with the `$` function, which either takes\n//    a terminal string or regexp, or a non-terminal function to call.\n//    It also takes care of moving all the indices forwards.\n//`\n//\nvar Parser = function Parser(context, imports, fileInfo) {\n    var parsers,\n        parserInput = getParserInput();\n\n    function error(msg, type) {\n        throw new LessError(\n            {\n                index: parserInput.i,\n                filename: fileInfo.filename,\n                type: type || 'Syntax',\n                message: msg\n            },\n            imports\n        );\n    }\n\n    function expect(arg, msg, index) {\n        // some older browsers return typeof 'function' for RegExp\n        var result = (arg instanceof Function) ? arg.call(parsers) : parserInput.$re(arg);\n        if (result) {\n            return result;\n        }\n        error(msg || (typeof arg === 'string' ? \"expected '\" + arg + \"' got '\" + parserInput.currentChar() + \"'\"\n                                               : \"unexpected token\"));\n    }\n\n    // Specialization of expect()\n    function expectChar(arg, msg) {\n        if (parserInput.$char(arg)) {\n            return arg;\n        }\n        error(msg || \"expected '\" + arg + \"' got '\" + parserInput.currentChar() + \"'\");\n    }\n\n    function getDebugInfo(index) {\n        var filename = fileInfo.filename;\n\n        return {\n            lineNumber: utils.getLocation(index, parserInput.getInput()).line + 1,\n            fileName: filename\n        };\n    }\n\n    //\n    // The Parser\n    //\n    return {\n\n        //\n        // Parse an input string into an abstract syntax tree,\n        // @param str A string containing 'less' markup\n        // @param callback call `callback` when done.\n        // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply\n        //\n        parse: function (str, callback, additionalData) {\n            var root, error = null, globalVars, modifyVars, ignored, preText = \"\";\n\n            globalVars = (additionalData && additionalData.globalVars) ? Parser.serializeVars(additionalData.globalVars) + '\\n' : '';\n            modifyVars = (additionalData && additionalData.modifyVars) ? '\\n' + Parser.serializeVars(additionalData.modifyVars) : '';\n\n            if (context.pluginManager) {\n                var preProcessors = context.pluginManager.getPreProcessors();\n                for (var i = 0; i < preProcessors.length; i++) {\n                    str = preProcessors[i].process(str, { context: context, imports: imports, fileInfo: fileInfo });\n                }\n            }\n\n            if (globalVars || (additionalData && additionalData.banner)) {\n                preText = ((additionalData && additionalData.banner) ? additionalData.banner : \"\") + globalVars;\n                ignored = imports.contentsIgnoredChars;\n                ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0;\n                ignored[fileInfo.filename] += preText.length;\n            }\n\n            str = str.replace(/\\r\\n?/g, '\\n');\n            // Remove potential UTF Byte Order Mark\n            str = preText + str.replace(/^\\uFEFF/, '') + modifyVars;\n            imports.contents[fileInfo.filename] = str;\n\n            // Start with the primary rule.\n            // The whole syntax tree is held under a Ruleset node,\n            // with the `root` property set to true, so no `{}` are\n            // output. The callback is called when the input is parsed.\n            try {\n                parserInput.start(str, context.chunkInput, function fail(msg, index) {\n                    throw new LessError({\n                        index: index,\n                        type: 'Parse',\n                        message: msg,\n                        filename: fileInfo.filename\n                    }, imports);\n                });\n\n                root = new(tree.Ruleset)(null, this.parsers.primary());\n                root.root = true;\n                root.firstRoot = true;\n            } catch (e) {\n                return callback(new LessError(e, imports, fileInfo.filename));\n            }\n\n            // If `i` is smaller than the `input.length - 1`,\n            // it means the parser wasn't able to parse the whole\n            // string, so we've got a parsing error.\n            //\n            // We try to extract a \\n delimited string,\n            // showing the line where the parse error occurred.\n            // We split it up into two parts (the part which parsed,\n            // and the part which didn't), so we can color them differently.\n            var endInfo = parserInput.end();\n            if (!endInfo.isFinished) {\n\n                var message = endInfo.furthestPossibleErrorMessage;\n\n                if (!message) {\n                    message = \"Unrecognised input\";\n                    if (endInfo.furthestChar === '}') {\n                        message += \". Possibly missing opening '{'\";\n                    } else if (endInfo.furthestChar === ')') {\n                        message += \". Possibly missing opening '('\";\n                    } else if (endInfo.furthestReachedEnd) {\n                        message += \". Possibly missing something\";\n                    }\n                }\n\n                error = new LessError({\n                    type: \"Parse\",\n                    message: message,\n                    index: endInfo.furthest,\n                    filename: fileInfo.filename\n                }, imports);\n            }\n\n            var finish = function (e) {\n                e = error || e || imports.error;\n\n                if (e) {\n                    if (!(e instanceof LessError)) {\n                        e = new LessError(e, imports, fileInfo.filename);\n                    }\n\n                    return callback(e);\n                }\n                else {\n                    return callback(null, root);\n                }\n            };\n\n            if (context.processImports !== false) {\n                new visitors.ImportVisitor(imports, finish)\n                    .run(root);\n            } else {\n                return finish();\n            }\n        },\n\n        //\n        // Here in, the parsing rules/functions\n        //\n        // The basic structure of the syntax tree generated is as follows:\n        //\n        //   Ruleset ->  Rule -> Value -> Expression -> Entity\n        //\n        // Here's some Less code:\n        //\n        //    .class {\n        //      color: #fff;\n        //      border: 1px solid #000;\n        //      width: @w + 4px;\n        //      > .child {...}\n        //    }\n        //\n        // And here's what the parse tree might look like:\n        //\n        //     Ruleset (Selector '.class', [\n        //         Rule (\"color\",  Value ([Expression [Color #fff]]))\n        //         Rule (\"border\", Value ([Expression [Dimension 1px][Keyword \"solid\"][Color #000]]))\n        //         Rule (\"width\",  Value ([Expression [Operation \" + \" [Variable \"@w\"][Dimension 4px]]]))\n        //         Ruleset (Selector [Element '>', '.child'], [...])\n        //     ])\n        //\n        //  In general, most rules will try to parse a token with the `$re()` function, and if the return\n        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check\n        //  first, before parsing, that's when we use `peek()`.\n        //\n        parsers: parsers = {\n            //\n            // The `primary` rule is the *entry* and *exit* point of the parser.\n            // The rules here can appear at any level of the parse tree.\n            //\n            // The recursive nature of the grammar is an interplay between the `block`\n            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,\n            // as represented by this simplified grammar:\n            //\n            //     primary  →  (ruleset | rule)+\n            //     ruleset  →  selector+ block\n            //     block    →  '{' primary '}'\n            //\n            // Only at one point is the primary rule not called from the\n            // block rule: at the root level.\n            //\n            primary: function () {\n                var mixin = this.mixin, root = [], node;\n\n                while (true) {\n                    while (true) {\n                        node = this.comment();\n                        if (!node) { break; }\n                        root.push(node);\n                    }\n                    // always process comments before deciding if finished\n                    if (parserInput.finished) {\n                        break;\n                    }\n                    if (parserInput.peek('}')) {\n                        break;\n                    }\n\n                    node = this.extendRule();\n                    if (node) {\n                        root = root.concat(node);\n                        continue;\n                    }\n\n                    node = mixin.definition() || this.rule() || this.ruleset() ||\n                        mixin.call() || this.rulesetCall() || this.entities.call() || this.directive();\n                    if (node) {\n                        root.push(node);\n                    } else {\n                        var foundSemiColon = false;\n                        while (parserInput.$char(\";\")) {\n                            foundSemiColon = true;\n                        }\n                        if (!foundSemiColon) {\n                            break;\n                        }\n                    }\n                }\n\n                return root;\n            },\n\n            // comments are collected by the main parsing mechanism and then assigned to nodes\n            // where the current structure allows it\n            comment: function () {\n                if (parserInput.commentStore.length) {\n                    var comment = parserInput.commentStore.shift();\n                    return new(tree.Comment)(comment.text, comment.isLineComment, comment.index, fileInfo);\n                }\n            },\n\n            //\n            // Entities are tokens which can be found inside an Expression\n            //\n            entities: {\n                //\n                // A string, which supports escaping \" and '\n                //\n                //     \"milky way\" 'he\\'s the one!'\n                //\n                quoted: function () {\n                    var str, index = parserInput.i, isEscaped = false;\n\n                    parserInput.save();\n                    if (parserInput.$char(\"~\")) {\n                        isEscaped = true;\n                    }\n                    str = parserInput.$quoted();\n                    if (!str) {\n                        parserInput.restore();\n                        return;\n                    }\n                    parserInput.forget();\n\n                    return new(tree.Quoted)(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo);\n                },\n\n                //\n                // A catch-all word, such as:\n                //\n                //     black border-collapse\n                //\n                keyword: function () {\n                    var k = parserInput.$char(\"%\") || parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]*/);\n                    if (k) {\n                        return tree.Color.fromKeyword(k) || new(tree.Keyword)(k);\n                    }\n                },\n\n                //\n                // A function call\n                //\n                //     rgb(255, 0, 255)\n                //\n                // We also try to catch IE's `alpha()`, but let the `alpha` parser\n                // deal with the details.\n                //\n                // The arguments are parsed with the `entities.arguments` parser.\n                //\n                call: function () {\n                    var name, nameLC, args, alpha, index = parserInput.i;\n\n                    // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18\n                    if (parserInput.peek(/^url\\(/i)) {\n                        return;\n                    }\n\n                    parserInput.save();\n\n                    name = parserInput.$re(/^([\\w-]+|%|progid:[\\w\\.]+)\\(/);\n                    if (!name) { parserInput.forget(); return; }\n\n                    name = name[1];\n                    nameLC = name.toLowerCase();\n\n                    if (nameLC === 'alpha') {\n                        alpha = parsers.alpha();\n                        if (alpha) {\n                            parserInput.forget();\n                            return alpha;\n                        }\n                    }\n\n                    args = this.arguments();\n\n                    if (! parserInput.$char(')')) {\n                        parserInput.restore(\"Could not parse call arguments or missing ')'\");\n                        return;\n                    }\n\n                    parserInput.forget();\n                    return new(tree.Call)(name, args, index, fileInfo);\n                },\n                arguments: function () {\n                    var argsSemiColon = [], argsComma = [],\n                        expressions = [],\n                        isSemiColonSeparated, value, arg;\n\n                    parserInput.save();\n\n                    while (true) {\n\n                        arg = parsers.detachedRuleset() || this.assignment() || parsers.expression();\n\n                        if (!arg) {\n                            break;\n                        }\n\n                        value = arg;\n\n                        if (arg.value && arg.value.length == 1) {\n                            value = arg.value[0];\n                        }\n\n                        if (value) {\n                            expressions.push(value);\n                        }\n\n                        argsComma.push(value);\n\n                        if (parserInput.$char(',')) {\n                            continue;\n                        }\n\n                        if (parserInput.$char(';') || isSemiColonSeparated) {\n\n                            isSemiColonSeparated = true;\n\n                            if (expressions.length > 1) {\n                                value = new(tree.Value)(expressions);\n                            }\n                            argsSemiColon.push(value);\n\n                            expressions = [];\n                        }\n                    }\n\n                    parserInput.forget();\n                    return isSemiColonSeparated ? argsSemiColon : argsComma;\n                },\n                literal: function () {\n                    return this.dimension() ||\n                           this.color() ||\n                           this.quoted() ||\n                           this.unicodeDescriptor();\n                },\n\n                // Assignments are argument entities for calls.\n                // They are present in ie filter properties as shown below.\n                //\n                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )\n                //\n\n                assignment: function () {\n                    var key, value;\n                    parserInput.save();\n                    key = parserInput.$re(/^\\w+(?=\\s?=)/i);\n                    if (!key) {\n                        parserInput.restore();\n                        return;\n                    }\n                    if (!parserInput.$char('=')) {\n                        parserInput.restore();\n                        return;\n                    }\n                    value = parsers.entity();\n                    if (value) {\n                        parserInput.forget();\n                        return new(tree.Assignment)(key, value);\n                    } else {\n                        parserInput.restore();\n                    }\n                },\n\n                //\n                // Parse url() tokens\n                //\n                // We use a specific rule for urls, because they don't really behave like\n                // standard function calls. The difference is that the argument doesn't have\n                // to be enclosed within a string, so it can't be parsed as an Expression.\n                //\n                url: function () {\n                    var value, index = parserInput.i;\n\n                    parserInput.autoCommentAbsorb = false;\n\n                    if (!parserInput.$str(\"url(\")) {\n                        parserInput.autoCommentAbsorb = true;\n                        return;\n                    }\n\n                    value = this.quoted() || this.variable() ||\n                            parserInput.$re(/^(?:(?:\\\\[\\(\\)'\"])|[^\\(\\)'\"])+/) || \"\";\n\n                    parserInput.autoCommentAbsorb = true;\n\n                    expectChar(')');\n\n                    return new(tree.URL)((value.value != null || value instanceof tree.Variable) ?\n                                        value : new(tree.Anonymous)(value), index, fileInfo);\n                },\n\n                //\n                // A Variable entity, such as `@fink`, in\n                //\n                //     width: @fink + 2px\n                //\n                // We use a different parser for variable definitions,\n                // see `parsers.variable`.\n                //\n                variable: function () {\n                    var name, index = parserInput.i;\n\n                    if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\\w-]+/))) {\n                        return new(tree.Variable)(name, index, fileInfo);\n                    }\n                },\n\n                // A variable entity using the protective {} e.g. @{var}\n                variableCurly: function () {\n                    var curly, index = parserInput.i;\n\n                    if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\\{([\\w-]+)\\}/))) {\n                        return new(tree.Variable)(\"@\" + curly[1], index, fileInfo);\n                    }\n                },\n\n                //\n                // A Hexadecimal color\n                //\n                //     #4F3C2F\n                //\n                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.\n                //\n                color: function () {\n                    var rgb;\n\n                    if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {\n                        // strip colons, brackets, whitespaces and other characters that should not\n                        // definitely be part of color string\n                        var colorCandidateString = rgb.input.match(/^#([\\w]+).*/);\n                        colorCandidateString = colorCandidateString[1];\n                        if (!colorCandidateString.match(/^[A-Fa-f0-9]+$/)) { // verify if candidate consists only of allowed HEX characters\n                            error(\"Invalid HEX color code\");\n                        }\n                        return new(tree.Color)(rgb[1], undefined, '#' + colorCandidateString);\n                    }\n                },\n\n                colorKeyword: function () {\n                    parserInput.save();\n                    var autoCommentAbsorb = parserInput.autoCommentAbsorb;\n                    parserInput.autoCommentAbsorb = false;\n                    var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/);\n                    parserInput.autoCommentAbsorb = autoCommentAbsorb;\n                    if (!k) {\n                        parserInput.forget();\n                        return;\n                    }\n                    parserInput.restore();\n                    var color = tree.Color.fromKeyword(k);\n                    if (color) {\n                        parserInput.$str(k);\n                        return color;\n                    }\n                },\n\n                //\n                // A Dimension, that is, a number and a unit\n                //\n                //     0.5em 95%\n                //\n                dimension: function () {\n                    if (parserInput.peekNotNumeric()) {\n                        return;\n                    }\n\n                    var value = parserInput.$re(/^([+-]?\\d*\\.?\\d+)(%|[a-z_]+)?/i);\n                    if (value) {\n                        return new(tree.Dimension)(value[1], value[2]);\n                    }\n                },\n\n                //\n                // A unicode descriptor, as is used in unicode-range\n                //\n                // U+0??  or U+00A1-00A9\n                //\n                unicodeDescriptor: function () {\n                    var ud;\n\n                    ud = parserInput.$re(/^U\\+[0-9a-fA-F?]+(\\-[0-9a-fA-F?]+)?/);\n                    if (ud) {\n                        return new(tree.UnicodeDescriptor)(ud[0]);\n                    }\n                },\n\n                //\n                // JavaScript code to be evaluated\n                //\n                //     `window.location.href`\n                //\n                javascript: function () {\n                    var js, index = parserInput.i;\n\n                    parserInput.save();\n\n                    var escape = parserInput.$char(\"~\");\n                    var jsQuote = parserInput.$char(\"`\");\n\n                    if (!jsQuote) {\n                        parserInput.restore();\n                        return;\n                    }\n\n                    js = parserInput.$re(/^[^`]*`/);\n                    if (js) {\n                        parserInput.forget();\n                        return new(tree.JavaScript)(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo);\n                    }\n                    parserInput.restore(\"invalid javascript definition\");\n                }\n            },\n\n            //\n            // The variable part of a variable definition. Used in the `rule` parser\n            //\n            //     @fink:\n            //\n            variable: function () {\n                var name;\n\n                if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\\w-]+)\\s*:/))) { return name[1]; }\n            },\n\n            //\n            // The variable part of a variable definition. Used in the `rule` parser\n            //\n            //     @fink();\n            //\n            rulesetCall: function () {\n                var name;\n\n                if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\\w-]+)\\(\\s*\\)\\s*;/))) {\n                    return new tree.RulesetCall(name[1]);\n                }\n            },\n\n            //\n            // extend syntax - used to extend selectors\n            //\n            extend: function(isRule) {\n                var elements, e, index = parserInput.i, option, extendList, extend;\n\n                if (!parserInput.$str(isRule ? \"&:extend(\" : \":extend(\")) {\n                    return;\n                }\n\n                do {\n                    option = null;\n                    elements = null;\n                    while (! (option = parserInput.$re(/^(all)(?=\\s*(\\)|,))/))) {\n                        e = this.element();\n                        if (!e) {\n                            break;\n                        }\n                        if (elements) {\n                            elements.push(e);\n                        } else {\n                            elements = [ e ];\n                        }\n                    }\n\n                    option = option && option[1];\n                    if (!elements) {\n                        error(\"Missing target selector for :extend().\");\n                    }\n                    extend = new(tree.Extend)(new(tree.Selector)(elements), option, index, fileInfo);\n                    if (extendList) {\n                        extendList.push(extend);\n                    } else {\n                        extendList = [ extend ];\n                    }\n                } while (parserInput.$char(\",\"));\n\n                expect(/^\\)/);\n\n                if (isRule) {\n                    expect(/^;/);\n                }\n\n                return extendList;\n            },\n\n            //\n            // extendRule - used in a rule to extend all the parent selectors\n            //\n            extendRule: function() {\n                return this.extend(true);\n            },\n\n            //\n            // Mixins\n            //\n            mixin: {\n                //\n                // A Mixin call, with an optional argument list\n                //\n                //     #mixins > .square(#fff);\n                //     .rounded(4px, black);\n                //     .button;\n                //\n                // The `while` loop is there because mixins can be\n                // namespaced, but we only support the child and descendant\n                // selector for now.\n                //\n                call: function () {\n                    var s = parserInput.currentChar(), important = false, index = parserInput.i, elemIndex,\n                        elements, elem, e, c, args;\n\n                    if (s !== '.' && s !== '#') { return; }\n\n                    parserInput.save(); // stop us absorbing part of an invalid selector\n\n                    while (true) {\n                        elemIndex = parserInput.i;\n                        e = parserInput.$re(/^[#.](?:[\\w-]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/);\n                        if (!e) {\n                            break;\n                        }\n                        elem = new(tree.Element)(c, e, elemIndex, fileInfo);\n                        if (elements) {\n                            elements.push(elem);\n                        } else {\n                            elements = [ elem ];\n                        }\n                        c = parserInput.$char('>');\n                    }\n\n                    if (elements) {\n                        if (parserInput.$char('(')) {\n                            args = this.args(true).args;\n                            expectChar(')');\n                        }\n\n                        if (parsers.important()) {\n                            important = true;\n                        }\n\n                        if (parsers.end()) {\n                            parserInput.forget();\n                            return new(tree.mixin.Call)(elements, args, index, fileInfo, important);\n                        }\n                    }\n\n                    parserInput.restore();\n                },\n                args: function (isCall) {\n                    var entities = parsers.entities,\n                        returner = { args:null, variadic: false },\n                        expressions = [], argsSemiColon = [], argsComma = [],\n                        isSemiColonSeparated, expressionContainsNamed, name, nameLoop,\n                        value, arg, expand;\n\n                    parserInput.save();\n\n                    while (true) {\n                        if (isCall) {\n                            arg = parsers.detachedRuleset() || parsers.expression();\n                        } else {\n                            parserInput.commentStore.length = 0;\n                            if (parserInput.$str(\"...\")) {\n                                returner.variadic = true;\n                                if (parserInput.$char(\";\") && !isSemiColonSeparated) {\n                                    isSemiColonSeparated = true;\n                                }\n                                (isSemiColonSeparated ? argsSemiColon : argsComma)\n                                    .push({ variadic: true });\n                                break;\n                            }\n                            arg = entities.variable() || entities.literal() || entities.keyword();\n                        }\n\n                        if (!arg) {\n                            break;\n                        }\n\n                        nameLoop = null;\n                        if (arg.throwAwayComments) {\n                            arg.throwAwayComments();\n                        }\n                        value = arg;\n                        var val = null;\n\n                        if (isCall) {\n                            // Variable\n                            if (arg.value && arg.value.length == 1) {\n                                val = arg.value[0];\n                            }\n                        } else {\n                            val = arg;\n                        }\n\n                        if (val && val instanceof tree.Variable) {\n                            if (parserInput.$char(':')) {\n                                if (expressions.length > 0) {\n                                    if (isSemiColonSeparated) {\n                                        error(\"Cannot mix ; and , as delimiter types\");\n                                    }\n                                    expressionContainsNamed = true;\n                                }\n\n                                value = parsers.detachedRuleset() || parsers.expression();\n\n                                if (!value) {\n                                    if (isCall) {\n                                        error(\"could not understand value for named argument\");\n                                    } else {\n                                        parserInput.restore();\n                                        returner.args = [];\n                                        return returner;\n                                    }\n                                }\n                                nameLoop = (name = val.name);\n                            } else if (parserInput.$str(\"...\")) {\n                                if (!isCall) {\n                                    returner.variadic = true;\n                                    if (parserInput.$char(\";\") && !isSemiColonSeparated) {\n                                        isSemiColonSeparated = true;\n                                    }\n                                    (isSemiColonSeparated ? argsSemiColon : argsComma)\n                                        .push({ name: arg.name, variadic: true });\n                                    break;\n                                } else {\n                                    expand = true;\n                                }\n                            } else if (!isCall) {\n                                name = nameLoop = val.name;\n                                value = null;\n                            }\n                        }\n\n                        if (value) {\n                            expressions.push(value);\n                        }\n\n                        argsComma.push({ name:nameLoop, value:value, expand:expand });\n\n                        if (parserInput.$char(',')) {\n                            continue;\n                        }\n\n                        if (parserInput.$char(';') || isSemiColonSeparated) {\n\n                            if (expressionContainsNamed) {\n                                error(\"Cannot mix ; and , as delimiter types\");\n                            }\n\n                            isSemiColonSeparated = true;\n\n                            if (expressions.length > 1) {\n                                value = new(tree.Value)(expressions);\n                            }\n                            argsSemiColon.push({ name:name, value:value, expand:expand });\n\n                            name = null;\n                            expressions = [];\n                            expressionContainsNamed = false;\n                        }\n                    }\n\n                    parserInput.forget();\n                    returner.args = isSemiColonSeparated ? argsSemiColon : argsComma;\n                    return returner;\n                },\n                //\n                // A Mixin definition, with a list of parameters\n                //\n                //     .rounded (@radius: 2px, @color) {\n                //        ...\n                //     }\n                //\n                // Until we have a finer grained state-machine, we have to\n                // do a look-ahead, to make sure we don't have a mixin call.\n                // See the `rule` function for more information.\n                //\n                // We start by matching `.rounded (`, and then proceed on to\n                // the argument list, which has optional default values.\n                // We store the parameters in `params`, with a `value` key,\n                // if there is a value, such as in the case of `@radius`.\n                //\n                // Once we've got our params list, and a closing `)`, we parse\n                // the `{...}` block.\n                //\n                definition: function () {\n                    var name, params = [], match, ruleset, cond, variadic = false;\n                    if ((parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#') ||\n                        parserInput.peek(/^[^{]*\\}/)) {\n                        return;\n                    }\n\n                    parserInput.save();\n\n                    match = parserInput.$re(/^([#.](?:[\\w-]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\\s*\\(/);\n                    if (match) {\n                        name = match[1];\n\n                        var argInfo = this.args(false);\n                        params = argInfo.args;\n                        variadic = argInfo.variadic;\n\n                        // .mixincall(\"@{a}\");\n                        // looks a bit like a mixin definition..\n                        // also\n                        // .mixincall(@a: {rule: set;});\n                        // so we have to be nice and restore\n                        if (!parserInput.$char(')')) {\n                            parserInput.restore(\"Missing closing ')'\");\n                            return;\n                        }\n\n                        parserInput.commentStore.length = 0;\n\n                        if (parserInput.$str(\"when\")) { // Guard\n                            cond = expect(parsers.conditions, 'expected condition');\n                        }\n\n                        ruleset = parsers.block();\n\n                        if (ruleset) {\n                            parserInput.forget();\n                            return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);\n                        } else {\n                            parserInput.restore();\n                        }\n                    } else {\n                        parserInput.forget();\n                    }\n                }\n            },\n\n            //\n            // Entities are the smallest recognized token,\n            // and can be found inside a rule's value.\n            //\n            entity: function () {\n                var entities = this.entities;\n\n                return this.comment() || entities.literal() || entities.variable() || entities.url() ||\n                       entities.call()    || entities.keyword()  || entities.javascript();\n            },\n\n            //\n            // A Rule terminator. Note that we use `peek()` to check for '}',\n            // because the `block` rule will be expecting it, but we still need to make sure\n            // it's there, if ';' was omitted.\n            //\n            end: function () {\n                return parserInput.$char(';') || parserInput.peek('}');\n            },\n\n            //\n            // IE's alpha function\n            //\n            //     alpha(opacity=88)\n            //\n            alpha: function () {\n                var value;\n\n                // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18\n                if (! parserInput.$re(/^opacity=/i)) { return; }\n                value = parserInput.$re(/^\\d+/);\n                if (!value) {\n                    value = expect(this.entities.variable, \"Could not parse alpha\");\n                }\n                expectChar(')');\n                return new(tree.Alpha)(value);\n            },\n\n            //\n            // A Selector Element\n            //\n            //     div\n            //     + h1\n            //     #socks\n            //     input[type=\"text\"]\n            //\n            // Elements are the building blocks for Selectors,\n            // they are made out of a `Combinator` (see combinator rule),\n            // and an element name, such as a tag a class, or `*`.\n            //\n            element: function () {\n                var e, c, v, index = parserInput.i;\n\n                c = this.combinator();\n\n                e = parserInput.$re(/^(?:\\d+\\.\\d+|\\d+)%/) ||\n                    parserInput.$re(/^(?:[.#]?|:*)(?:[\\w-]|[^\\x00-\\x9f]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||\n                    parserInput.$char('*') || parserInput.$char('&') || this.attribute() ||\n                    parserInput.$re(/^\\([^&()@]+\\)/) ||  parserInput.$re(/^[\\.#:](?=@)/) ||\n                    this.entities.variableCurly();\n\n                if (! e) {\n                    parserInput.save();\n                    if (parserInput.$char('(')) {\n                        if ((v = this.selector()) && parserInput.$char(')')) {\n                            e = new(tree.Paren)(v);\n                            parserInput.forget();\n                        } else {\n                            parserInput.restore(\"Missing closing ')'\");\n                        }\n                    } else {\n                        parserInput.forget();\n                    }\n                }\n\n                if (e) { return new(tree.Element)(c, e, index, fileInfo); }\n            },\n\n            //\n            // Combinators combine elements together, in a Selector.\n            //\n            // Because our parser isn't white-space sensitive, special care\n            // has to be taken, when parsing the descendant combinator, ` `,\n            // as it's an empty space. We have to check the previous character\n            // in the input, to see if it's a ` ` character. More info on how\n            // we deal with this in *combinator.js*.\n            //\n            combinator: function () {\n                var c = parserInput.currentChar();\n\n                if (c === '/') {\n                    parserInput.save();\n                    var slashedCombinator = parserInput.$re(/^\\/[a-z]+\\//i);\n                    if (slashedCombinator) {\n                        parserInput.forget();\n                        return new(tree.Combinator)(slashedCombinator);\n                    }\n                    parserInput.restore();\n                }\n\n                if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') {\n                    parserInput.i++;\n                    if (c === '^' && parserInput.currentChar() === '^') {\n                        c = '^^';\n                        parserInput.i++;\n                    }\n                    while (parserInput.isWhitespace()) { parserInput.i++; }\n                    return new(tree.Combinator)(c);\n                } else if (parserInput.isWhitespace(-1)) {\n                    return new(tree.Combinator)(\" \");\n                } else {\n                    return new(tree.Combinator)(null);\n                }\n            },\n            //\n            // A CSS selector (see selector below)\n            // with less extensions e.g. the ability to extend and guard\n            //\n            lessSelector: function () {\n                return this.selector(true);\n            },\n            //\n            // A CSS Selector\n            //\n            //     .class > div + h1\n            //     li a:hover\n            //\n            // Selectors are made out of one or more Elements, see above.\n            //\n            selector: function (isLess) {\n                var index = parserInput.i, elements, extendList, c, e, allExtends, when, condition;\n\n                while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$str(\"when\"))) || (e = this.element())) {\n                    if (when) {\n                        condition = expect(this.conditions, 'expected condition');\n                    } else if (condition) {\n                        error(\"CSS guard can only be used at the end of selector\");\n                    } else if (extendList) {\n                        if (allExtends) {\n                            allExtends = allExtends.concat(extendList);\n                        } else {\n                            allExtends = extendList;\n                        }\n                    } else {\n                        if (allExtends) { error(\"Extend can only be used at the end of selector\"); }\n                        c = parserInput.currentChar();\n                        if (elements) {\n                            elements.push(e);\n                        } else {\n                            elements = [ e ];\n                        }\n                        e = null;\n                    }\n                    if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') {\n                        break;\n                    }\n                }\n\n                if (elements) { return new(tree.Selector)(elements, allExtends, condition, index, fileInfo); }\n                if (allExtends) { error(\"Extend must be used to extend a selector, it cannot be used on its own\"); }\n            },\n            attribute: function () {\n                if (! parserInput.$char('[')) { return; }\n\n                var entities = this.entities,\n                    key, val, op;\n\n                if (!(key = entities.variableCurly())) {\n                    key = expect(/^(?:[_A-Za-z0-9-\\*]*\\|)?(?:[_A-Za-z0-9-]|\\\\.)+/);\n                }\n\n                op = parserInput.$re(/^[|~*$^]?=/);\n                if (op) {\n                    val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\\w-]+/) || entities.variableCurly();\n                }\n\n                expectChar(']');\n\n                return new(tree.Attribute)(key, op, val);\n            },\n\n            //\n            // The `block` rule is used by `ruleset` and `mixin.definition`.\n            // It's a wrapper around the `primary` rule, with added `{}`.\n            //\n            block: function () {\n                var content;\n                if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) {\n                    return content;\n                }\n            },\n\n            blockRuleset: function() {\n                var block = this.block();\n\n                if (block) {\n                    block = new tree.Ruleset(null, block);\n                }\n                return block;\n            },\n\n            detachedRuleset: function() {\n                var blockRuleset = this.blockRuleset();\n                if (blockRuleset) {\n                    return new tree.DetachedRuleset(blockRuleset);\n                }\n            },\n\n            //\n            // div, .class, body > p {...}\n            //\n            ruleset: function () {\n                var selectors, s, rules, debugInfo;\n\n                parserInput.save();\n\n                if (context.dumpLineNumbers) {\n                    debugInfo = getDebugInfo(parserInput.i);\n                }\n\n                while (true) {\n                    s = this.lessSelector();\n                    if (!s) {\n                        break;\n                    }\n                    if (selectors) {\n                        selectors.push(s);\n                    } else {\n                        selectors = [ s ];\n                    }\n                    parserInput.commentStore.length = 0;\n                    if (s.condition && selectors.length > 1) {\n                        error(\"Guards are only currently allowed on a single selector.\");\n                    }\n                    if (! parserInput.$char(',')) { break; }\n                    if (s.condition) {\n                        error(\"Guards are only currently allowed on a single selector.\");\n                    }\n                    parserInput.commentStore.length = 0;\n                }\n\n                if (selectors && (rules = this.block())) {\n                    parserInput.forget();\n                    var ruleset = new(tree.Ruleset)(selectors, rules, context.strictImports);\n                    if (context.dumpLineNumbers) {\n                        ruleset.debugInfo = debugInfo;\n                    }\n                    return ruleset;\n                } else {\n                    parserInput.restore();\n                }\n            },\n            rule: function (tryAnonymous) {\n                var name, value, startOfRule = parserInput.i, c = parserInput.currentChar(), important, merge, isVariable;\n\n                if (c === '.' || c === '#' || c === '&' || c === ':') { return; }\n\n                parserInput.save();\n\n                name = this.variable() || this.ruleProperty();\n                if (name) {\n                    isVariable = typeof name === \"string\";\n\n                    if (isVariable) {\n                        value = this.detachedRuleset();\n                    }\n\n                    parserInput.commentStore.length = 0;\n                    if (!value) {\n                        // a name returned by this.ruleProperty() is always an array of the form:\n                        // [string-1, ..., string-n, \"\"] or [string-1, ..., string-n, \"+\"]\n                        // where each item is a tree.Keyword or tree.Variable\n                        merge = !isVariable && name.length > 1 && name.pop().value;\n\n                        // prefer to try to parse first if its a variable or we are compressing\n                        // but always fallback on the other one\n                        var tryValueFirst = !tryAnonymous && (context.compress || isVariable);\n\n                        if (tryValueFirst) {\n                            value = this.value();\n                        }\n                        if (!value) {\n                            value = this.anonymousValue();\n                            if (value) {\n                                parserInput.forget();\n                                // anonymous values absorb the end ';' which is required for them to work\n                                return new (tree.Rule)(name, value, false, merge, startOfRule, fileInfo);\n                            }\n                        }\n                        if (!tryValueFirst && !value) {\n                            value = this.value();\n                        }\n\n                        important = this.important();\n                    }\n\n                    if (value && this.end()) {\n                        parserInput.forget();\n                        return new (tree.Rule)(name, value, important, merge, startOfRule, fileInfo);\n                    } else {\n                        parserInput.restore();\n                        if (value && !tryAnonymous) {\n                            return this.rule(true);\n                        }\n                    }\n                } else {\n                    parserInput.forget();\n                }\n            },\n            anonymousValue: function () {\n                var match = parserInput.$re(/^([^@+\\/'\"*`(;{}-]*);/);\n                if (match) {\n                    return new(tree.Anonymous)(match[1]);\n                }\n            },\n\n            //\n            // An @import directive\n            //\n            //     @import \"lib\";\n            //\n            // Depending on our environment, importing is done differently:\n            // In the browser, it's an XHR request, in Node, it would be a\n            // file-system operation. The function used for importing is\n            // stored in `import`, which we pass to the Import constructor.\n            //\n            \"import\": function () {\n                var path, features, index = parserInput.i;\n\n                var dir = parserInput.$re(/^@import?\\s+/);\n\n                if (dir) {\n                    var options = (dir ? this.importOptions() : null) || {};\n\n                    if ((path = this.entities.quoted() || this.entities.url())) {\n                        features = this.mediaFeatures();\n\n                        if (!parserInput.$char(';')) {\n                            parserInput.i = index;\n                            error(\"missing semi-colon or unrecognised media features on import\");\n                        }\n                        features = features && new(tree.Value)(features);\n                        return new(tree.Import)(path, features, options, index, fileInfo);\n                    }\n                    else {\n                        parserInput.i = index;\n                        error(\"malformed import statement\");\n                    }\n                }\n            },\n\n            importOptions: function() {\n                var o, options = {}, optionName, value;\n\n                // list of options, surrounded by parens\n                if (! parserInput.$char('(')) { return null; }\n                do {\n                    o = this.importOption();\n                    if (o) {\n                        optionName = o;\n                        value = true;\n                        switch(optionName) {\n                            case \"css\":\n                                optionName = \"less\";\n                                value = false;\n                                break;\n                            case \"once\":\n                                optionName = \"multiple\";\n                                value = false;\n                                break;\n                        }\n                        options[optionName] = value;\n                        if (! parserInput.$char(',')) { break; }\n                    }\n                } while (o);\n                expectChar(')');\n                return options;\n            },\n\n            importOption: function() {\n                var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/);\n                if (opt) {\n                    return opt[1];\n                }\n            },\n\n            mediaFeature: function () {\n                var entities = this.entities, nodes = [], e, p;\n                parserInput.save();\n                do {\n                    e = entities.keyword() || entities.variable();\n                    if (e) {\n                        nodes.push(e);\n                    } else if (parserInput.$char('(')) {\n                        p = this.property();\n                        e = this.value();\n                        if (parserInput.$char(')')) {\n                            if (p && e) {\n                                nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, null, parserInput.i, fileInfo, true)));\n                            } else if (e) {\n                                nodes.push(new(tree.Paren)(e));\n                            } else {\n                                error(\"badly formed media feature definition\");\n                            }\n                        } else {\n                            error(\"Missing closing ')'\", \"Parse\");\n                        }\n                    }\n                } while (e);\n\n                parserInput.forget();\n                if (nodes.length > 0) {\n                    return new(tree.Expression)(nodes);\n                }\n            },\n\n            mediaFeatures: function () {\n                var entities = this.entities, features = [], e;\n                do {\n                    e = this.mediaFeature();\n                    if (e) {\n                        features.push(e);\n                        if (! parserInput.$char(',')) { break; }\n                    } else {\n                        e = entities.variable();\n                        if (e) {\n                            features.push(e);\n                            if (! parserInput.$char(',')) { break; }\n                        }\n                    }\n                } while (e);\n\n                return features.length > 0 ? features : null;\n            },\n\n            media: function () {\n                var features, rules, media, debugInfo, index = parserInput.i;\n\n                if (context.dumpLineNumbers) {\n                    debugInfo = getDebugInfo(index);\n                }\n\n                parserInput.save();\n\n                if (parserInput.$str(\"@media\")) {\n                    features = this.mediaFeatures();\n\n                    rules = this.block();\n\n                    if (!rules) {\n                        error(\"media definitions require block statements after any features\");\n                    }\n\n                    parserInput.forget();\n\n                    media = new(tree.Media)(rules, features, index, fileInfo);\n                    if (context.dumpLineNumbers) {\n                        media.debugInfo = debugInfo;\n                    }\n\n                    return media;\n                }\n\n                parserInput.restore();\n            },\n\n            //\n            // A @plugin directive, used to import compiler extensions dynamically.\n            //\n            //     @plugin \"lib\";\n            //\n            // Depending on our environment, importing is done differently:\n            // In the browser, it's an XHR request, in Node, it would be a\n            // file-system operation. The function used for importing is\n            // stored in `import`, which we pass to the Import constructor.\n            //\n            plugin: function () {\n                var path,\n                    index = parserInput.i,\n                    dir   = parserInput.$re(/^@plugin?\\s+/);\n\n                if (dir) {\n                    var options = { plugin : true };\n\n                    if ((path = this.entities.quoted() || this.entities.url())) {\n\n                        if (!parserInput.$char(';')) {\n                            parserInput.i = index;\n                            error(\"missing semi-colon on plugin\");\n                        }\n\n                        return new(tree.Import)(path, null, options, index, fileInfo);\n                    }\n                    else {\n                        parserInput.i = index;\n                        error(\"malformed plugin statement\");\n                    }\n                }\n            },\n\n            //\n            // A CSS Directive\n            //\n            //     @charset \"utf-8\";\n            //\n            directive: function () {\n                var index = parserInput.i, name, value, rules, nonVendorSpecificName,\n                    hasIdentifier, hasExpression, hasUnknown, hasBlock = true, isRooted = true;\n\n                if (parserInput.currentChar() !== '@') { return; }\n\n                value = this['import']() || this.plugin() || this.media();\n                if (value) {\n                    return value;\n                }\n\n                parserInput.save();\n\n                name = parserInput.$re(/^@[a-z-]+/);\n\n                if (!name) { return; }\n\n                nonVendorSpecificName = name;\n                if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {\n                    nonVendorSpecificName = \"@\" + name.slice(name.indexOf('-', 2) + 1);\n                }\n\n                switch(nonVendorSpecificName) {\n                    case \"@charset\":\n                        hasIdentifier = true;\n                        hasBlock = false;\n                        break;\n                    case \"@namespace\":\n                        hasExpression = true;\n                        hasBlock = false;\n                        break;\n                    case \"@keyframes\":\n                    case \"@counter-style\":\n                        hasIdentifier = true;\n                        break;\n                    case \"@document\":\n                    case \"@supports\":\n                        hasUnknown = true;\n                        isRooted = false;\n                        break;\n                    default:\n                        hasUnknown = true;\n                        break;\n                }\n\n                parserInput.commentStore.length = 0;\n\n                if (hasIdentifier) {\n                    value = this.entity();\n                    if (!value) {\n                        error(\"expected \" + name + \" identifier\");\n                    }\n                } else if (hasExpression) {\n                    value = this.expression();\n                    if (!value) {\n                        error(\"expected \" + name + \" expression\");\n                    }\n                } else if (hasUnknown) {\n                    value = (parserInput.$re(/^[^{;]+/) || '').trim();\n                    hasBlock = (parserInput.currentChar() == '{');\n                    if (value) {\n                        value = new(tree.Anonymous)(value);\n                    }\n                }\n\n                if (hasBlock) {\n                    rules = this.blockRuleset();\n                }\n\n                if (rules || (!hasBlock && value && parserInput.$char(';'))) {\n                    parserInput.forget();\n                    return new (tree.Directive)(name, value, rules, index, fileInfo,\n                        context.dumpLineNumbers ? getDebugInfo(index) : null,\n                        isRooted\n                    );\n                }\n\n                parserInput.restore(\"directive options not recognised\");\n            },\n\n            //\n            // A Value is a comma-delimited list of Expressions\n            //\n            //     font-family: Baskerville, Georgia, serif;\n            //\n            // In a Rule, a Value represents everything after the `:`,\n            // and before the `;`.\n            //\n            value: function () {\n                var e, expressions = [];\n\n                do {\n                    e = this.expression();\n                    if (e) {\n                        expressions.push(e);\n                        if (! parserInput.$char(',')) { break; }\n                    }\n                } while (e);\n\n                if (expressions.length > 0) {\n                    return new(tree.Value)(expressions);\n                }\n            },\n            important: function () {\n                if (parserInput.currentChar() === '!') {\n                    return parserInput.$re(/^! *important/);\n                }\n            },\n            sub: function () {\n                var a, e;\n\n                parserInput.save();\n                if (parserInput.$char('(')) {\n                    a = this.addition();\n                    if (a && parserInput.$char(')')) {\n                        parserInput.forget();\n                        e = new(tree.Expression)([a]);\n                        e.parens = true;\n                        return e;\n                    }\n                    parserInput.restore(\"Expected ')'\");\n                    return;\n                }\n                parserInput.restore();\n            },\n            multiplication: function () {\n                var m, a, op, operation, isSpaced;\n                m = this.operand();\n                if (m) {\n                    isSpaced = parserInput.isWhitespace(-1);\n                    while (true) {\n                        if (parserInput.peek(/^\\/[*\\/]/)) {\n                            break;\n                        }\n\n                        parserInput.save();\n\n                        op = parserInput.$char('/') || parserInput.$char('*');\n\n                        if (!op) { parserInput.forget(); break; }\n\n                        a = this.operand();\n\n                        if (!a) { parserInput.restore(); break; }\n                        parserInput.forget();\n\n                        m.parensInOp = true;\n                        a.parensInOp = true;\n                        operation = new(tree.Operation)(op, [operation || m, a], isSpaced);\n                        isSpaced = parserInput.isWhitespace(-1);\n                    }\n                    return operation || m;\n                }\n            },\n            addition: function () {\n                var m, a, op, operation, isSpaced;\n                m = this.multiplication();\n                if (m) {\n                    isSpaced = parserInput.isWhitespace(-1);\n                    while (true) {\n                        op = parserInput.$re(/^[-+]\\s+/) || (!isSpaced && (parserInput.$char('+') || parserInput.$char('-')));\n                        if (!op) {\n                            break;\n                        }\n                        a = this.multiplication();\n                        if (!a) {\n                            break;\n                        }\n\n                        m.parensInOp = true;\n                        a.parensInOp = true;\n                        operation = new(tree.Operation)(op, [operation || m, a], isSpaced);\n                        isSpaced = parserInput.isWhitespace(-1);\n                    }\n                    return operation || m;\n                }\n            },\n            conditions: function () {\n                var a, b, index = parserInput.i, condition;\n\n                a = this.condition();\n                if (a) {\n                    while (true) {\n                        if (!parserInput.peek(/^,\\s*(not\\s*)?\\(/) || !parserInput.$char(',')) {\n                            break;\n                        }\n                        b = this.condition();\n                        if (!b) {\n                            break;\n                        }\n                        condition = new(tree.Condition)('or', condition || a, b, index);\n                    }\n                    return condition || a;\n                }\n            },\n            condition: function () {\n                var result, logical, next;\n                function or() {\n                    return parserInput.$str(\"or\");\n                }\n\n                result = this.conditionAnd(this);\n                if (!result) {\n                    return ;\n                }\n                logical = or();\n                if (logical) {\n                    next = this.condition();\n                    if (next) {\n                        result = new(tree.Condition)(logical, result, next);\n                    } else {\n                        return ;\n                    }\n                }\n                return result;\n            },\n            conditionAnd: function () {\n                var result, logical, next;\n                function insideCondition(me) {\n                    return me.negatedCondition() || me.parenthesisCondition();\n                }\n                function and() {\n                    return parserInput.$str(\"and\");\n                }\n\n                result = insideCondition(this);\n                if (!result) {\n                    return ;\n                }\n                logical = and();\n                if (logical) {\n                    next = this.conditionAnd();\n                    if (next) {\n                        result = new(tree.Condition)(logical, result, next);\n                    } else {\n                        return ;\n                    }\n                }\n                return result;\n            },\n            negatedCondition: function () {\n                if (parserInput.$str(\"not\")) {\n                    var result = this.parenthesisCondition();\n                    if (result) {\n                        result.negate = !result.negate;\n                    }\n                    return result;\n                }\n            },\n            parenthesisCondition: function () {\n                function tryConditionFollowedByParenthesis(me) {\n                    var body;\n                    parserInput.save();\n                    body = me.condition();\n                    if (!body) {\n                        parserInput.restore();\n                        return ;\n                    }\n                    if (!parserInput.$char(')')) {\n                        parserInput.restore();\n                        return ;\n                    }\n                    parserInput.forget();\n                    return body;\n                }\n\n                var body;\n                parserInput.save();\n                if (!parserInput.$str(\"(\")) {\n                    parserInput.restore();\n                    return ;\n                }\n                body = tryConditionFollowedByParenthesis(this);\n                if (body) {\n                    parserInput.forget();\n                    return body;\n                }\n\n                body = this.atomicCondition();\n                if (!body) {\n                    parserInput.restore();\n                    return ;\n                }\n                if (!parserInput.$char(')')) {\n                    parserInput.restore(\"expected ')' got '\" + parserInput.currentChar() + \"'\");\n                    return ;\n                }\n                parserInput.forget();\n                return body;\n            },\n            atomicCondition: function () {\n                var entities = this.entities, index = parserInput.i, a, b, c, op;\n\n                a = this.addition() || entities.keyword() || entities.quoted();\n                if (a) {\n                    if (parserInput.$char('>')) {\n                        if (parserInput.$char('=')) {\n                            op = \">=\";\n                        } else {\n                            op = '>';\n                        }\n                    } else\n                    if (parserInput.$char('<')) {\n                        if (parserInput.$char('=')) {\n                            op = \"<=\";\n                        } else {\n                            op = '<';\n                        }\n                    } else\n                    if (parserInput.$char('=')) {\n                        if (parserInput.$char('>')) {\n                            op = \"=>\";\n                        } else if (parserInput.$char('<')) {\n                            op = '=<';\n                        } else {\n                            op = '=';\n                        }\n                    }\n                    if (op) {\n                        b = this.addition() || entities.keyword() || entities.quoted();\n                        if (b) {\n                            c = new(tree.Condition)(op, a, b, index, false);\n                        } else {\n                            error('expected expression');\n                        }\n                    } else {\n                        c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, false);\n                    }\n                    return c;\n                }\n            },\n\n            //\n            // An operand is anything that can be part of an operation,\n            // such as a Color, or a Variable\n            //\n            operand: function () {\n                var entities = this.entities, negate;\n\n                if (parserInput.peek(/^-[@\\(]/)) {\n                    negate = parserInput.$char('-');\n                }\n\n                var o = this.sub() || entities.dimension() ||\n                        entities.color() || entities.variable() ||\n                        entities.call() || entities.colorKeyword();\n\n                if (negate) {\n                    o.parensInOp = true;\n                    o = new(tree.Negative)(o);\n                }\n\n                return o;\n            },\n\n            //\n            // Expressions either represent mathematical operations,\n            // or white-space delimited Entities.\n            //\n            //     1px solid black\n            //     @var * 2\n            //\n            expression: function () {\n                var entities = [], e, delim;\n\n                do {\n                    e = this.comment();\n                    if (e) {\n                        entities.push(e);\n                        continue;\n                    }\n                    e = this.addition() || this.entity();\n                    if (e) {\n                        entities.push(e);\n                        // operations do not allow keyword \"/\" dimension (e.g. small/20px) so we support that here\n                        if (!parserInput.peek(/^\\/[\\/*]/)) {\n                            delim = parserInput.$char('/');\n                            if (delim) {\n                                entities.push(new(tree.Anonymous)(delim));\n                            }\n                        }\n                    }\n                } while (e);\n                if (entities.length > 0) {\n                    return new(tree.Expression)(entities);\n                }\n            },\n            property: function () {\n                var name = parserInput.$re(/^(\\*?-?[_a-zA-Z0-9-]+)\\s*:/);\n                if (name) {\n                    return name[1];\n                }\n            },\n            ruleProperty: function () {\n                var name = [], index = [], s, k;\n\n                parserInput.save();\n\n                var simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\\s*:/);\n                if (simpleProperty) {\n                    name = [new(tree.Keyword)(simpleProperty[1])];\n                    parserInput.forget();\n                    return name;\n                }\n\n                function match(re) {\n                    var i = parserInput.i,\n                        chunk = parserInput.$re(re);\n                    if (chunk) {\n                        index.push(i);\n                        return name.push(chunk[1]);\n                    }\n                }\n\n                match(/^(\\*?)/);\n                while (true) {\n                    if (!match(/^((?:[\\w-]+)|(?:@\\{[\\w-]+\\}))/)) {\n                        break;\n                    }\n                }\n\n                if ((name.length > 1) && match(/^((?:\\+_|\\+)?)\\s*:/)) {\n                    parserInput.forget();\n\n                    // at last, we have the complete match now. move forward,\n                    // convert name particles to tree objects and return:\n                    if (name[0] === '') {\n                        name.shift();\n                        index.shift();\n                    }\n                    for (k = 0; k < name.length; k++) {\n                        s = name[k];\n                        name[k] = (s.charAt(0) !== '@') ?\n                            new(tree.Keyword)(s) :\n                            new(tree.Variable)('@' + s.slice(2, -1),\n                                index[k], fileInfo);\n                    }\n                    return name;\n                }\n                parserInput.restore();\n            }\n        }\n    };\n};\nParser.serializeVars = function(vars) {\n    var s = '';\n\n    for (var name in vars) {\n        if (Object.hasOwnProperty.call(vars, name)) {\n            var value = vars[name];\n            s += ((name[0] === '@') ? '' : '@') + name + ': ' + value +\n                ((String(value).slice(-1) === ';') ? '' : ';');\n        }\n    }\n\n    return s;\n};\n\nmodule.exports = Parser;\n\n},{\"../less-error\":32,\"../tree\":62,\"../utils\":83,\"../visitors\":87,\"./parser-input\":37}],39:[function(require,module,exports){\n/**\n * Plugin Manager\n */\nvar PluginManager = function(less) {\n    this.less = less;\n    this.visitors = [];\n    this.preProcessors = [];\n    this.postProcessors = [];\n    this.installedPlugins = [];\n    this.fileManagers = [];\n};\n/**\n * Adds all the plugins in the array\n * @param {Array} plugins\n */\nPluginManager.prototype.addPlugins = function(plugins) {\n    if (plugins) {\n        for (var i = 0; i < plugins.length; i++) {\n            this.addPlugin(plugins[i]);\n        }\n    }\n};\n/**\n *\n * @param plugin\n */\nPluginManager.prototype.addPlugin = function(plugin) {\n    this.installedPlugins.push(plugin);\n    plugin.install(this.less, this);\n};\n/**\n * Adds a visitor. The visitor object has options on itself to determine\n * when it should run.\n * @param visitor\n */\nPluginManager.prototype.addVisitor = function(visitor) {\n    this.visitors.push(visitor);\n};\n/**\n * Adds a pre processor object\n * @param {object} preProcessor\n * @param {number} priority - guidelines 1 = before import, 1000 = import, 2000 = after import\n */\nPluginManager.prototype.addPreProcessor = function(preProcessor, priority) {\n    var indexToInsertAt;\n    for (indexToInsertAt = 0; indexToInsertAt < this.preProcessors.length; indexToInsertAt++) {\n        if (this.preProcessors[indexToInsertAt].priority >= priority) {\n            break;\n        }\n    }\n    this.preProcessors.splice(indexToInsertAt, 0, {preProcessor: preProcessor, priority: priority});\n};\n/**\n * Adds a post processor object\n * @param {object} postProcessor\n * @param {number} priority - guidelines 1 = before compression, 1000 = compression, 2000 = after compression\n */\nPluginManager.prototype.addPostProcessor = function(postProcessor, priority) {\n    var indexToInsertAt;\n    for (indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) {\n        if (this.postProcessors[indexToInsertAt].priority >= priority) {\n            break;\n        }\n    }\n    this.postProcessors.splice(indexToInsertAt, 0, {postProcessor: postProcessor, priority: priority});\n};\n/**\n *\n * @param manager\n */\nPluginManager.prototype.addFileManager = function(manager) {\n    this.fileManagers.push(manager);\n};\n/**\n *\n * @returns {Array}\n * @private\n */\nPluginManager.prototype.getPreProcessors = function() {\n    var preProcessors = [];\n    for (var i = 0; i < this.preProcessors.length; i++) {\n        preProcessors.push(this.preProcessors[i].preProcessor);\n    }\n    return preProcessors;\n};\n/**\n *\n * @returns {Array}\n * @private\n */\nPluginManager.prototype.getPostProcessors = function() {\n    var postProcessors = [];\n    for (var i = 0; i < this.postProcessors.length; i++) {\n        postProcessors.push(this.postProcessors[i].postProcessor);\n    }\n    return postProcessors;\n};\n/**\n *\n * @returns {Array}\n * @private\n */\nPluginManager.prototype.getVisitors = function() {\n    return this.visitors;\n};\n/**\n *\n * @returns {Array}\n * @private\n */\nPluginManager.prototype.getFileManagers = function() {\n    return this.fileManagers;\n};\nmodule.exports = PluginManager;\n\n},{}],40:[function(require,module,exports){\nvar LessError = require('../less-error'),\n    tree = require(\"../tree\");\n\nvar FunctionImporter = module.exports = function FunctionImporter(context, fileInfo) {\n    this.fileInfo = fileInfo;\n};\n\nFunctionImporter.prototype.eval = function(contents, callback) {\n    var loaded = {},\n        loader,\n        registry;\n\n    registry = {\n        add: function(name, func) {\n            loaded[name] = func;\n        },\n        addMultiple: function(functions) {\n            Object.keys(functions).forEach(function(name) {\n                loaded[name] = functions[name];\n            });\n        }\n    };\n\n    try {\n        loader = new Function(\"functions\", \"tree\", \"fileInfo\", contents);\n        loader(registry, tree, this.fileInfo);\n    } catch(e) {\n        callback(new LessError({\n            message: \"Plugin evaluation error: '\" + e.name + ': ' + e.message.replace(/[\"]/g, \"'\") + \"'\" ,\n            filename: this.fileInfo.filename\n        }), null );\n    }\n\n    callback(null, { functions: loaded });\n};\n\n},{\"../less-error\":32,\"../tree\":62}],41:[function(require,module,exports){\nvar PromiseConstructor;\n\nmodule.exports = function(environment, ParseTree, ImportManager) {\n    var render = function (input, options, callback) {\n        if (typeof options === 'function') {\n            callback = options;\n            options = {};\n        }\n\n        if (!callback) {\n            if (!PromiseConstructor) {\n                PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise;\n            }\n            var self = this;\n            return new PromiseConstructor(function (resolve, reject) {\n                render.call(self, input, options, function(err, output) {\n                    if (err) {\n                        reject(err);\n                    } else {\n                        resolve(output);\n                    }\n                });\n            });\n        } else {\n            this.parse(input, options, function(err, root, imports, options) {\n                if (err) { return callback(err); }\n\n                var result;\n                try {\n                    var parseTree = new ParseTree(root, imports);\n                    result = parseTree.toCSS(options);\n                }\n                catch (err) { return callback(err); }\n\n                callback(null, result);\n            });\n        }\n    };\n\n    return render;\n};\n\n},{\"promise\":undefined}],42:[function(require,module,exports){\nmodule.exports = function (SourceMapOutput, environment) {\n\n    var SourceMapBuilder = function (options) {\n        this.options = options;\n    };\n\n    SourceMapBuilder.prototype.toCSS = function(rootNode, options, imports) {\n        var sourceMapOutput = new SourceMapOutput(\n            {\n                contentsIgnoredCharsMap: imports.contentsIgnoredChars,\n                rootNode: rootNode,\n                contentsMap: imports.contents,\n                sourceMapFilename: this.options.sourceMapFilename,\n                sourceMapURL: this.options.sourceMapURL,\n                outputFilename: this.options.sourceMapOutputFilename,\n                sourceMapBasepath: this.options.sourceMapBasepath,\n                sourceMapRootpath: this.options.sourceMapRootpath,\n                outputSourceFiles: this.options.outputSourceFiles,\n                sourceMapGenerator: this.options.sourceMapGenerator,\n                sourceMapFileInline: this.options.sourceMapFileInline\n            });\n\n        var css = sourceMapOutput.toCSS(options);\n        this.sourceMap = sourceMapOutput.sourceMap;\n        this.sourceMapURL = sourceMapOutput.sourceMapURL;\n        if (this.options.sourceMapInputFilename) {\n            this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename);\n        }\n        return css + this.getCSSAppendage();\n    };\n\n    SourceMapBuilder.prototype.getCSSAppendage = function() {\n\n        var sourceMapURL = this.sourceMapURL;\n        if (this.options.sourceMapFileInline) {\n            if (this.sourceMap === undefined) {\n                return \"\";\n            }\n            sourceMapURL = \"data:application/json;base64,\" + environment.encodeBase64(this.sourceMap);\n        }\n\n        if (sourceMapURL) {\n            return \"/*# sourceMappingURL=\" + sourceMapURL + \" */\";\n        }\n        return \"\";\n    };\n\n    SourceMapBuilder.prototype.getExternalSourceMap = function() {\n        return this.sourceMap;\n    };\n    SourceMapBuilder.prototype.setExternalSourceMap = function(sourceMap) {\n        this.sourceMap = sourceMap;\n    };\n\n    SourceMapBuilder.prototype.isInline = function() {\n        return this.options.sourceMapFileInline;\n    };\n    SourceMapBuilder.prototype.getSourceMapURL = function() {\n        return this.sourceMapURL;\n    };\n    SourceMapBuilder.prototype.getOutputFilename = function() {\n        return this.options.sourceMapOutputFilename;\n    };\n    SourceMapBuilder.prototype.getInputFilename = function() {\n        return this.sourceMapInputFilename;\n    };\n\n    return SourceMapBuilder;\n};\n\n},{}],43:[function(require,module,exports){\nmodule.exports = function (environment) {\n\n    var SourceMapOutput = function (options) {\n        this._css = [];\n        this._rootNode = options.rootNode;\n        this._contentsMap = options.contentsMap;\n        this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap;\n        if (options.sourceMapFilename) {\n            this._sourceMapFilename = options.sourceMapFilename.replace(/\\\\/g, '/');\n        }\n        this._outputFilename = options.outputFilename;\n        this.sourceMapURL = options.sourceMapURL;\n        if (options.sourceMapBasepath) {\n            this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\\\/g, '/');\n        }\n        if (options.sourceMapRootpath) {\n            this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\\\/g, '/');\n            if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') {\n                this._sourceMapRootpath += '/';\n            }\n        } else {\n            this._sourceMapRootpath = \"\";\n        }\n        this._outputSourceFiles = options.outputSourceFiles;\n        this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator();\n\n        this._lineNumber = 0;\n        this._column = 0;\n    };\n\n    SourceMapOutput.prototype.normalizeFilename = function(filename) {\n        filename = filename.replace(/\\\\/g, '/');\n\n        if (this._sourceMapBasepath && filename.indexOf(this._sourceMapBasepath) === 0) {\n            filename = filename.substring(this._sourceMapBasepath.length);\n            if (filename.charAt(0) === '\\\\' || filename.charAt(0) === '/') {\n                filename = filename.substring(1);\n            }\n        }\n        return (this._sourceMapRootpath || \"\") + filename;\n    };\n\n    SourceMapOutput.prototype.add = function(chunk, fileInfo, index, mapLines) {\n\n        //ignore adding empty strings\n        if (!chunk) {\n            return;\n        }\n\n        var lines,\n            sourceLines,\n            columns,\n            sourceColumns,\n            i;\n\n        if (fileInfo) {\n            var inputSource = this._contentsMap[fileInfo.filename];\n\n            // remove vars/banner added to the top of the file\n            if (this._contentsIgnoredCharsMap[fileInfo.filename]) {\n                // adjust the index\n                index -= this._contentsIgnoredCharsMap[fileInfo.filename];\n                if (index < 0) { index = 0; }\n                // adjust the source\n                inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]);\n            }\n            inputSource = inputSource.substring(0, index);\n            sourceLines = inputSource.split(\"\\n\");\n            sourceColumns = sourceLines[sourceLines.length - 1];\n        }\n\n        lines = chunk.split(\"\\n\");\n        columns = lines[lines.length - 1];\n\n        if (fileInfo) {\n            if (!mapLines) {\n                this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column},\n                    original: { line: sourceLines.length, column: sourceColumns.length},\n                    source: this.normalizeFilename(fileInfo.filename)});\n            } else {\n                for (i = 0; i < lines.length; i++) {\n                    this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0},\n                        original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0},\n                        source: this.normalizeFilename(fileInfo.filename)});\n                }\n            }\n        }\n\n        if (lines.length === 1) {\n            this._column += columns.length;\n        } else {\n            this._lineNumber += lines.length - 1;\n            this._column = columns.length;\n        }\n\n        this._css.push(chunk);\n    };\n\n    SourceMapOutput.prototype.isEmpty = function() {\n        return this._css.length === 0;\n    };\n\n    SourceMapOutput.prototype.toCSS = function(context) {\n        this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null });\n\n        if (this._outputSourceFiles) {\n            for (var filename in this._contentsMap) {\n                if (this._contentsMap.hasOwnProperty(filename)) {\n                    var source = this._contentsMap[filename];\n                    if (this._contentsIgnoredCharsMap[filename]) {\n                        source = source.slice(this._contentsIgnoredCharsMap[filename]);\n                    }\n                    this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source);\n                }\n            }\n        }\n\n        this._rootNode.genCSS(context, this);\n\n        if (this._css.length > 0) {\n            var sourceMapURL,\n                sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON());\n\n            if (this.sourceMapURL) {\n                sourceMapURL = this.sourceMapURL;\n            } else if (this._sourceMapFilename) {\n                sourceMapURL = this._sourceMapFilename;\n            }\n            this.sourceMapURL = sourceMapURL;\n\n            this.sourceMap = sourceMapContent;\n        }\n\n        return this._css.join('');\n    };\n\n    return SourceMapOutput;\n};\n\n},{}],44:[function(require,module,exports){\nvar contexts = require(\"./contexts\"),\n    visitor = require(\"./visitors\"),\n    tree = require(\"./tree\");\n\nmodule.exports = function(root, options) {\n    options = options || {};\n    var evaldRoot,\n        variables = options.variables,\n        evalEnv = new contexts.Eval(options);\n\n    //\n    // Allows setting variables with a hash, so:\n    //\n    //   `{ color: new tree.Color('#f01') }` will become:\n    //\n    //   new tree.Rule('@color',\n    //     new tree.Value([\n    //       new tree.Expression([\n    //         new tree.Color('#f01')\n    //       ])\n    //     ])\n    //   )\n    //\n    if (typeof variables === 'object' && !Array.isArray(variables)) {\n        variables = Object.keys(variables).map(function (k) {\n            var value = variables[k];\n\n            if (! (value instanceof tree.Value)) {\n                if (! (value instanceof tree.Expression)) {\n                    value = new tree.Expression([value]);\n                }\n                value = new tree.Value([value]);\n            }\n            return new tree.Rule('@' + k, value, false, null, 0);\n        });\n        evalEnv.frames = [new tree.Ruleset(null, variables)];\n    }\n\n    var preEvalVisitors = [],\n        visitors = [\n            new visitor.JoinSelectorVisitor(),\n            new visitor.MarkVisibleSelectorsVisitor(true),\n            new visitor.ExtendVisitor(),\n            new visitor.ToCSSVisitor({compress: Boolean(options.compress)})\n        ], i;\n\n    if (options.pluginManager) {\n        var pluginVisitors = options.pluginManager.getVisitors();\n        for (i = 0; i < pluginVisitors.length; i++) {\n            var pluginVisitor = pluginVisitors[i];\n            if (pluginVisitor.isPreEvalVisitor) {\n                preEvalVisitors.push(pluginVisitor);\n            } else {\n                if (pluginVisitor.isPreVisitor) {\n                    visitors.splice(0, 0, pluginVisitor);\n                } else {\n                    visitors.push(pluginVisitor);\n                }\n            }\n        }\n    }\n\n    for (i = 0; i < preEvalVisitors.length; i++) {\n        preEvalVisitors[i].run(root);\n    }\n\n    evaldRoot = root.eval(evalEnv);\n\n    for (i = 0; i < visitors.length; i++) {\n        visitors[i].run(evaldRoot);\n    }\n\n    return evaldRoot;\n};\n\n},{\"./contexts\":11,\"./tree\":62,\"./visitors\":87}],45:[function(require,module,exports){\nvar Node = require(\"./node\");\n\nvar Alpha = function (val) {\n    this.value = val;\n};\nAlpha.prototype = new Node();\nAlpha.prototype.type = \"Alpha\";\n\nAlpha.prototype.accept = function (visitor) {\n    this.value = visitor.visit(this.value);\n};\nAlpha.prototype.eval = function (context) {\n    if (this.value.eval) { return new Alpha(this.value.eval(context)); }\n    return this;\n};\nAlpha.prototype.genCSS = function (context, output) {\n    output.add(\"alpha(opacity=\");\n\n    if (this.value.genCSS) {\n        this.value.genCSS(context, output);\n    } else {\n        output.add(this.value);\n    }\n\n    output.add(\")\");\n};\n\nmodule.exports = Alpha;\n\n},{\"./node\":70}],46:[function(require,module,exports){\nvar Node = require(\"./node\");\n\nvar Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) {\n    this.value = value;\n    this.index = index;\n    this.mapLines = mapLines;\n    this.currentFileInfo = currentFileInfo;\n    this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike;\n    this.allowRoot = true;\n    this.copyVisibilityInfo(visibilityInfo);\n};\nAnonymous.prototype = new Node();\nAnonymous.prototype.type = \"Anonymous\";\nAnonymous.prototype.eval = function () {\n    return new Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo());\n};\nAnonymous.prototype.compare = function (other) {\n    return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;\n};\nAnonymous.prototype.isRulesetLike = function() {\n    return this.rulesetLike;\n};\nAnonymous.prototype.genCSS = function (context, output) {\n    output.add(this.value, this.currentFileInfo, this.index, this.mapLines);\n};\nmodule.exports = Anonymous;\n\n},{\"./node\":70}],47:[function(require,module,exports){\nvar Node = require(\"./node\");\n\nvar Assignment = function (key, val) {\n    this.key = key;\n    this.value = val;\n};\n\nAssignment.prototype = new Node();\nAssignment.prototype.type = \"Assignment\";\nAssignment.prototype.accept = function (visitor) {\n    this.value = visitor.visit(this.value);\n};\nAssignment.prototype.eval = function (context) {\n    if (this.value.eval) {\n        return new Assignment(this.key, this.value.eval(context));\n    }\n    return this;\n};\nAssignment.prototype.genCSS = function (context, output) {\n    output.add(this.key + '=');\n    if (this.value.genCSS) {\n        this.value.genCSS(context, output);\n    } else {\n        output.add(this.value);\n    }\n};\nmodule.exports = Assignment;\n\n},{\"./node\":70}],48:[function(require,module,exports){\nvar Node = require(\"./node\");\n\nvar Attribute = function (key, op, value) {\n    this.key = key;\n    this.op = op;\n    this.value = value;\n};\nAttribute.prototype = new Node();\nAttribute.prototype.type = \"Attribute\";\nAttribute.prototype.eval = function (context) {\n    return new Attribute(this.key.eval ? this.key.eval(context) : this.key,\n        this.op, (this.value && this.value.eval) ? this.value.eval(context) : this.value);\n};\nAttribute.prototype.genCSS = function (context, output) {\n    output.add(this.toCSS(context));\n};\nAttribute.prototype.toCSS = function (context) {\n    var value = this.key.toCSS ? this.key.toCSS(context) : this.key;\n\n    if (this.op) {\n        value += this.op;\n        value += (this.value.toCSS ? this.value.toCSS(context) : this.value);\n    }\n\n    return '[' + value + ']';\n};\nmodule.exports = Attribute;\n\n},{\"./node\":70}],49:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    FunctionCaller = require(\"../functions/function-caller\");\n//\n// A function call node.\n//\nvar Call = function (name, args, index, currentFileInfo) {\n    this.name = name;\n    this.args = args;\n    this.index = index;\n    this.currentFileInfo = currentFileInfo;\n};\nCall.prototype = new Node();\nCall.prototype.type = \"Call\";\nCall.prototype.accept = function (visitor) {\n    if (this.args) {\n        this.args = visitor.visitArray(this.args);\n    }\n};\n//\n// When evaluating a function call,\n// we either find the function in the functionRegistry,\n// in which case we call it, passing the  evaluated arguments,\n// if this returns null or we cannot find the function, we\n// simply print it out as it appeared originally [2].\n//\n// The reason why we evaluate the arguments, is in the case where\n// we try to pass a variable to a function, like: `saturate(@color)`.\n// The function should receive the value, not the variable.\n//\nCall.prototype.eval = function (context) {\n    var args = this.args.map(function (a) { return a.eval(context); }),\n        result, funcCaller = new FunctionCaller(this.name, context, this.index, this.currentFileInfo);\n\n    if (funcCaller.isValid()) {\n        try {\n            result = funcCaller.call(args);\n        } catch (e) {\n            throw { type: e.type || \"Runtime\",\n                    message: \"error evaluating function `\" + this.name + \"`\" +\n                             (e.message ? ': ' + e.message : ''),\n                    index: this.index, filename: this.currentFileInfo.filename };\n        }\n\n        if (result != null) {\n            result.index = this.index;\n            result.currentFileInfo = this.currentFileInfo;\n            return result;\n        }\n    }\n\n    return new Call(this.name, args, this.index, this.currentFileInfo);\n};\nCall.prototype.genCSS = function (context, output) {\n    output.add(this.name + \"(\", this.currentFileInfo, this.index);\n\n    for (var i = 0; i < this.args.length; i++) {\n        this.args[i].genCSS(context, output);\n        if (i + 1 < this.args.length) {\n            output.add(\", \");\n        }\n    }\n\n    output.add(\")\");\n};\nmodule.exports = Call;\n\n},{\"../functions/function-caller\":21,\"./node\":70}],50:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    colors = require(\"../data/colors\");\n\n//\n// RGB Colors - #ff0014, #eee\n//\nvar Color = function (rgb, a, originalForm) {\n    //\n    // The end goal here, is to parse the arguments\n    // into an integer triplet, such as `128, 255, 0`\n    //\n    // This facilitates operations and conversions.\n    //\n    if (Array.isArray(rgb)) {\n        this.rgb = rgb;\n    } else if (rgb.length == 6) {\n        this.rgb = rgb.match(/.{2}/g).map(function (c) {\n            return parseInt(c, 16);\n        });\n    } else {\n        this.rgb = rgb.split('').map(function (c) {\n            return parseInt(c + c, 16);\n        });\n    }\n    this.alpha = typeof a === 'number' ? a : 1;\n    if (typeof originalForm !== 'undefined') {\n        this.value = originalForm;\n    }\n};\n\nColor.prototype = new Node();\nColor.prototype.type = \"Color\";\n\nfunction clamp(v, max) {\n    return Math.min(Math.max(v, 0), max);\n}\n\nfunction toHex(v) {\n    return '#' + v.map(function (c) {\n        c = clamp(Math.round(c), 255);\n        return (c < 16 ? '0' : '') + c.toString(16);\n    }).join('');\n}\n\nColor.prototype.luma = function () {\n    var r = this.rgb[0] / 255,\n        g = this.rgb[1] / 255,\n        b = this.rgb[2] / 255;\n\n    r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4);\n    g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4);\n    b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4);\n\n    return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n};\nColor.prototype.genCSS = function (context, output) {\n    output.add(this.toCSS(context));\n};\nColor.prototype.toCSS = function (context, doNotCompress) {\n    var compress = context && context.compress && !doNotCompress, color, alpha;\n\n    // `value` is set if this color was originally\n    // converted from a named color string so we need\n    // to respect this and try to output named color too.\n    if (this.value) {\n        return this.value;\n    }\n\n    // If we have some transparency, the only way to represent it\n    // is via `rgba`. Otherwise, we use the hex representation,\n    // which has better compatibility with older browsers.\n    // Values are capped between `0` and `255`, rounded and zero-padded.\n    alpha = this.fround(context, this.alpha);\n    if (alpha < 1) {\n        return \"rgba(\" + this.rgb.map(function (c) {\n            return clamp(Math.round(c), 255);\n        }).concat(clamp(alpha, 1))\n            .join(',' + (compress ? '' : ' ')) + \")\";\n    }\n\n    color = this.toRGB();\n\n    if (compress) {\n        var splitcolor = color.split('');\n\n        // Convert color to short format\n        if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) {\n            color = '#' + splitcolor[1] + splitcolor[3] + splitcolor[5];\n        }\n    }\n\n    return color;\n};\n\n//\n// Operations have to be done per-channel, if not,\n// channels will spill onto each other. Once we have\n// our result, in the form of an integer triplet,\n// we create a new Color node to hold the result.\n//\nColor.prototype.operate = function (context, op, other) {\n    var rgb = [];\n    var alpha = this.alpha * (1 - other.alpha) + other.alpha;\n    for (var c = 0; c < 3; c++) {\n        rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]);\n    }\n    return new Color(rgb, alpha);\n};\nColor.prototype.toRGB = function () {\n    return toHex(this.rgb);\n};\nColor.prototype.toHSL = function () {\n    var r = this.rgb[0] / 255,\n        g = this.rgb[1] / 255,\n        b = this.rgb[2] / 255,\n        a = this.alpha;\n\n    var max = Math.max(r, g, b), min = Math.min(r, g, b);\n    var h, s, l = (max + min) / 2, d = max - min;\n\n    if (max === min) {\n        h = s = 0;\n    } else {\n        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n        switch (max) {\n            case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n            case g: h = (b - r) / d + 2;               break;\n            case b: h = (r - g) / d + 4;               break;\n        }\n        h /= 6;\n    }\n    return { h: h * 360, s: s, l: l, a: a };\n};\n//Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript\nColor.prototype.toHSV = function () {\n    var r = this.rgb[0] / 255,\n        g = this.rgb[1] / 255,\n        b = this.rgb[2] / 255,\n        a = this.alpha;\n\n    var max = Math.max(r, g, b), min = Math.min(r, g, b);\n    var h, s, v = max;\n\n    var d = max - min;\n    if (max === 0) {\n        s = 0;\n    } else {\n        s = d / max;\n    }\n\n    if (max === min) {\n        h = 0;\n    } else {\n        switch(max) {\n            case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n            case g: h = (b - r) / d + 2; break;\n            case b: h = (r - g) / d + 4; break;\n        }\n        h /= 6;\n    }\n    return { h: h * 360, s: s, v: v, a: a };\n};\nColor.prototype.toARGB = function () {\n    return toHex([this.alpha * 255].concat(this.rgb));\n};\nColor.prototype.compare = function (x) {\n    return (x.rgb &&\n        x.rgb[0] === this.rgb[0] &&\n        x.rgb[1] === this.rgb[1] &&\n        x.rgb[2] === this.rgb[2] &&\n        x.alpha  === this.alpha) ? 0 : undefined;\n};\n\nColor.fromKeyword = function(keyword) {\n    var c, key = keyword.toLowerCase();\n    if (colors.hasOwnProperty(key)) {\n        c = new Color(colors[key].slice(1));\n    }\n    else if (key === \"transparent\") {\n        c = new Color([0, 0, 0], 0);\n    }\n\n    if (c) {\n        c.value = keyword;\n        return c;\n    }\n};\nmodule.exports = Color;\n\n},{\"../data/colors\":12,\"./node\":70}],51:[function(require,module,exports){\nvar Node = require(\"./node\");\n\nvar Combinator = function (value) {\n    if (value === ' ') {\n        this.value = ' ';\n        this.emptyOrWhitespace = true;\n    } else {\n        this.value = value ? value.trim() : \"\";\n        this.emptyOrWhitespace = this.value === \"\";\n    }\n};\nCombinator.prototype = new Node();\nCombinator.prototype.type = \"Combinator\";\nvar _noSpaceCombinators = {\n    '': true,\n    ' ': true,\n    '|': true\n};\nCombinator.prototype.genCSS = function (context, output) {\n    var spaceOrEmpty = (context.compress || _noSpaceCombinators[this.value]) ? '' : ' ';\n    output.add(spaceOrEmpty + this.value + spaceOrEmpty);\n};\nmodule.exports = Combinator;\n\n},{\"./node\":70}],52:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    getDebugInfo = require(\"./debug-info\");\n\nvar Comment = function (value, isLineComment, index, currentFileInfo) {\n    this.value = value;\n    this.isLineComment = isLineComment;\n    this.currentFileInfo = currentFileInfo;\n    this.allowRoot = true;\n};\nComment.prototype = new Node();\nComment.prototype.type = \"Comment\";\nComment.prototype.genCSS = function (context, output) {\n    if (this.debugInfo) {\n        output.add(getDebugInfo(context, this), this.currentFileInfo, this.index);\n    }\n    output.add(this.value);\n};\nComment.prototype.isSilent = function(context) {\n    var isCompressed = context.compress && this.value[2] !== \"!\";\n    return this.isLineComment || isCompressed;\n};\nmodule.exports = Comment;\n\n},{\"./debug-info\":54,\"./node\":70}],53:[function(require,module,exports){\nvar Node = require(\"./node\");\n\nvar Condition = function (op, l, r, i, negate) {\n    this.op = op.trim();\n    this.lvalue = l;\n    this.rvalue = r;\n    this.index = i;\n    this.negate = negate;\n};\nCondition.prototype = new Node();\nCondition.prototype.type = \"Condition\";\nCondition.prototype.accept = function (visitor) {\n    this.lvalue = visitor.visit(this.lvalue);\n    this.rvalue = visitor.visit(this.rvalue);\n};\nCondition.prototype.eval = function (context) {\n    var result = (function (op, a, b) {\n        switch (op) {\n            case 'and': return a && b;\n            case 'or':  return a || b;\n            default:\n                switch (Node.compare(a, b)) {\n                    case -1:\n                        return op === '<' || op === '=<' || op === '<=';\n                    case 0:\n                        return op === '=' || op === '>=' || op === '=<' || op === '<=';\n                    case 1:\n                        return op === '>' || op === '>=';\n                    default:\n                        return false;\n                }\n        }\n    })(this.op, this.lvalue.eval(context), this.rvalue.eval(context));\n\n    return this.negate ? !result : result;\n};\nmodule.exports = Condition;\n\n},{\"./node\":70}],54:[function(require,module,exports){\nvar debugInfo = function(context, ctx, lineSeparator) {\n    var result = \"\";\n    if (context.dumpLineNumbers && !context.compress) {\n        switch(context.dumpLineNumbers) {\n            case 'comments':\n                result = debugInfo.asComment(ctx);\n                break;\n            case 'mediaquery':\n                result = debugInfo.asMediaQuery(ctx);\n                break;\n            case 'all':\n                result = debugInfo.asComment(ctx) + (lineSeparator || \"\") + debugInfo.asMediaQuery(ctx);\n                break;\n        }\n    }\n    return result;\n};\n\ndebugInfo.asComment = function(ctx) {\n    return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\\n';\n};\n\ndebugInfo.asMediaQuery = function(ctx) {\n    var filenameWithProtocol = ctx.debugInfo.fileName;\n    if (!/^[a-z]+:\\/\\//i.test(filenameWithProtocol)) {\n        filenameWithProtocol = 'file://' + filenameWithProtocol;\n    }\n    return '@media -sass-debug-info{filename{font-family:' +\n        filenameWithProtocol.replace(/([.:\\/\\\\])/g, function (a) {\n            if (a == '\\\\') {\n                a = '\\/';\n            }\n            return '\\\\' + a;\n        }) +\n        '}line{font-family:\\\\00003' + ctx.debugInfo.lineNumber + '}}\\n';\n};\n\nmodule.exports = debugInfo;\n\n},{}],55:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    contexts = require(\"../contexts\");\n\nvar DetachedRuleset = function (ruleset, frames) {\n    this.ruleset = ruleset;\n    this.frames = frames;\n};\nDetachedRuleset.prototype = new Node();\nDetachedRuleset.prototype.type = \"DetachedRuleset\";\nDetachedRuleset.prototype.evalFirst = true;\nDetachedRuleset.prototype.accept = function (visitor) {\n    this.ruleset = visitor.visit(this.ruleset);\n};\nDetachedRuleset.prototype.eval = function (context) {\n    var frames = this.frames || context.frames.slice(0);\n    return new DetachedRuleset(this.ruleset, frames);\n};\nDetachedRuleset.prototype.callEval = function (context) {\n    return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context);\n};\nmodule.exports = DetachedRuleset;\n\n},{\"../contexts\":11,\"./node\":70}],56:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    unitConversions = require(\"../data/unit-conversions\"),\n    Unit = require(\"./unit\"),\n    Color = require(\"./color\");\n\n//\n// A number with a unit\n//\nvar Dimension = function (value, unit) {\n    this.value = parseFloat(value);\n    this.unit = (unit && unit instanceof Unit) ? unit :\n      new Unit(unit ? [unit] : undefined);\n};\n\nDimension.prototype = new Node();\nDimension.prototype.type = \"Dimension\";\nDimension.prototype.accept = function (visitor) {\n    this.unit = visitor.visit(this.unit);\n};\nDimension.prototype.eval = function (context) {\n    return this;\n};\nDimension.prototype.toColor = function () {\n    return new Color([this.value, this.value, this.value]);\n};\nDimension.prototype.genCSS = function (context, output) {\n    if ((context && context.strictUnits) && !this.unit.isSingular()) {\n        throw new Error(\"Multiple units in dimension. Correct the units or use the unit function. Bad unit: \" + this.unit.toString());\n    }\n\n    var value = this.fround(context, this.value),\n        strValue = String(value);\n\n    if (value !== 0 && value < 0.000001 && value > -0.000001) {\n        // would be output 1e-6 etc.\n        strValue = value.toFixed(20).replace(/0+$/, \"\");\n    }\n\n    if (context && context.compress) {\n        // Zero values doesn't need a unit\n        if (value === 0 && this.unit.isLength()) {\n            output.add(strValue);\n            return;\n        }\n\n        // Float values doesn't need a leading zero\n        if (value > 0 && value < 1) {\n            strValue = (strValue).substr(1);\n        }\n    }\n\n    output.add(strValue);\n    this.unit.genCSS(context, output);\n};\n\n// In an operation between two Dimensions,\n// we default to the first Dimension's unit,\n// so `1px + 2` will yield `3px`.\nDimension.prototype.operate = function (context, op, other) {\n    /*jshint noempty:false */\n    var value = this._operate(context, op, this.value, other.value),\n        unit = this.unit.clone();\n\n    if (op === '+' || op === '-') {\n        if (unit.numerator.length === 0 && unit.denominator.length === 0) {\n            unit = other.unit.clone();\n            if (this.unit.backupUnit) {\n                unit.backupUnit = this.unit.backupUnit;\n            }\n        } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) {\n            // do nothing\n        } else {\n            other = other.convertTo(this.unit.usedUnits());\n\n            if (context.strictUnits && other.unit.toString() !== unit.toString()) {\n                throw new Error(\"Incompatible units. Change the units or use the unit function. Bad units: '\" + unit.toString() +\n                    \"' and '\" + other.unit.toString() + \"'.\");\n            }\n\n            value = this._operate(context, op, this.value, other.value);\n        }\n    } else if (op === '*') {\n        unit.numerator = unit.numerator.concat(other.unit.numerator).sort();\n        unit.denominator = unit.denominator.concat(other.unit.denominator).sort();\n        unit.cancel();\n    } else if (op === '/') {\n        unit.numerator = unit.numerator.concat(other.unit.denominator).sort();\n        unit.denominator = unit.denominator.concat(other.unit.numerator).sort();\n        unit.cancel();\n    }\n    return new Dimension(value, unit);\n};\nDimension.prototype.compare = function (other) {\n    var a, b;\n\n    if (!(other instanceof Dimension)) {\n        return undefined;\n    }\n\n    if (this.unit.isEmpty() || other.unit.isEmpty()) {\n        a = this;\n        b = other;\n    } else {\n        a = this.unify();\n        b = other.unify();\n        if (a.unit.compare(b.unit) !== 0) {\n            return undefined;\n        }\n    }\n\n    return Node.numericCompare(a.value, b.value);\n};\nDimension.prototype.unify = function () {\n    return this.convertTo({ length: 'px', duration: 's', angle: 'rad' });\n};\nDimension.prototype.convertTo = function (conversions) {\n    var value = this.value, unit = this.unit.clone(),\n        i, groupName, group, targetUnit, derivedConversions = {}, applyUnit;\n\n    if (typeof conversions === 'string') {\n        for (i in unitConversions) {\n            if (unitConversions[i].hasOwnProperty(conversions)) {\n                derivedConversions = {};\n                derivedConversions[i] = conversions;\n            }\n        }\n        conversions = derivedConversions;\n    }\n    applyUnit = function (atomicUnit, denominator) {\n        /* jshint loopfunc:true */\n        if (group.hasOwnProperty(atomicUnit)) {\n            if (denominator) {\n                value = value / (group[atomicUnit] / group[targetUnit]);\n            } else {\n                value = value * (group[atomicUnit] / group[targetUnit]);\n            }\n\n            return targetUnit;\n        }\n\n        return atomicUnit;\n    };\n\n    for (groupName in conversions) {\n        if (conversions.hasOwnProperty(groupName)) {\n            targetUnit = conversions[groupName];\n            group = unitConversions[groupName];\n\n            unit.map(applyUnit);\n        }\n    }\n\n    unit.cancel();\n\n    return new Dimension(value, unit);\n};\nmodule.exports = Dimension;\n\n},{\"../data/unit-conversions\":14,\"./color\":50,\"./node\":70,\"./unit\":79}],57:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    Selector = require(\"./selector\"),\n    Ruleset = require(\"./ruleset\");\n\nvar Directive = function (name, value, rules, index, currentFileInfo, debugInfo, isRooted, visibilityInfo) {\n    var i;\n\n    this.name  = name;\n    this.value = value;\n    if (rules) {\n        if (Array.isArray(rules)) {\n            this.rules = rules;\n        } else {\n            this.rules = [rules];\n            this.rules[0].selectors = (new Selector([], null, null, this.index, currentFileInfo)).createEmptySelectors();\n        }\n        for (i = 0; i < this.rules.length; i++) {\n            this.rules[i].allowImports = true;\n        }\n    }\n    this.index = index;\n    this.currentFileInfo = currentFileInfo;\n    this.debugInfo = debugInfo;\n    this.isRooted = isRooted || false;\n    this.copyVisibilityInfo(visibilityInfo);\n    this.allowRoot = true;\n};\n\nDirective.prototype = new Node();\nDirective.prototype.type = \"Directive\";\nDirective.prototype.accept = function (visitor) {\n    var value = this.value, rules = this.rules;\n    if (rules) {\n        this.rules = visitor.visitArray(rules);\n    }\n    if (value) {\n        this.value = visitor.visit(value);\n    }\n};\nDirective.prototype.isRulesetLike = function() {\n    return this.rules || !this.isCharset();\n};\nDirective.prototype.isCharset = function() {\n    return \"@charset\" === this.name;\n};\nDirective.prototype.genCSS = function (context, output) {\n    var value = this.value, rules = this.rules;\n    output.add(this.name, this.currentFileInfo, this.index);\n    if (value) {\n        output.add(' ');\n        value.genCSS(context, output);\n    }\n    if (rules) {\n        this.outputRuleset(context, output, rules);\n    } else {\n        output.add(';');\n    }\n};\nDirective.prototype.eval = function (context) {\n    var mediaPathBackup, mediaBlocksBackup, value = this.value, rules = this.rules;\n\n    //media stored inside other directive should not bubble over it\n    //backpup media bubbling information\n    mediaPathBackup = context.mediaPath;\n    mediaBlocksBackup = context.mediaBlocks;\n    //deleted media bubbling information\n    context.mediaPath = [];\n    context.mediaBlocks = [];\n\n    if (value) {\n        value = value.eval(context);\n    }\n    if (rules) {\n        // assuming that there is only one rule at this point - that is how parser constructs the rule\n        rules = [rules[0].eval(context)];\n        rules[0].root = true;\n    }\n    //restore media bubbling information\n    context.mediaPath = mediaPathBackup;\n    context.mediaBlocks = mediaBlocksBackup;\n\n    return new Directive(this.name, value, rules,\n        this.index, this.currentFileInfo, this.debugInfo, this.isRooted, this.visibilityInfo());\n};\nDirective.prototype.variable = function (name) {\n    if (this.rules) {\n        // assuming that there is only one rule at this point - that is how parser constructs the rule\n        return Ruleset.prototype.variable.call(this.rules[0], name);\n    }\n};\nDirective.prototype.find = function () {\n    if (this.rules) {\n        // assuming that there is only one rule at this point - that is how parser constructs the rule\n        return Ruleset.prototype.find.apply(this.rules[0], arguments);\n    }\n};\nDirective.prototype.rulesets = function () {\n    if (this.rules) {\n        // assuming that there is only one rule at this point - that is how parser constructs the rule\n        return Ruleset.prototype.rulesets.apply(this.rules[0]);\n    }\n};\nDirective.prototype.outputRuleset = function (context, output, rules) {\n    var ruleCnt = rules.length, i;\n    context.tabLevel = (context.tabLevel | 0) + 1;\n\n    // Compressed\n    if (context.compress) {\n        output.add('{');\n        for (i = 0; i < ruleCnt; i++) {\n            rules[i].genCSS(context, output);\n        }\n        output.add('}');\n        context.tabLevel--;\n        return;\n    }\n\n    // Non-compressed\n    var tabSetStr = '\\n' + Array(context.tabLevel).join(\"  \"), tabRuleStr = tabSetStr + \"  \";\n    if (!ruleCnt) {\n        output.add(\" {\" + tabSetStr + '}');\n    } else {\n        output.add(\" {\" + tabRuleStr);\n        rules[0].genCSS(context, output);\n        for (i = 1; i < ruleCnt; i++) {\n            output.add(tabRuleStr);\n            rules[i].genCSS(context, output);\n        }\n        output.add(tabSetStr + '}');\n    }\n\n    context.tabLevel--;\n};\nmodule.exports = Directive;\n\n},{\"./node\":70,\"./ruleset\":76,\"./selector\":77}],58:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    Paren = require(\"./paren\"),\n    Combinator = require(\"./combinator\");\n\nvar Element = function (combinator, value, index, currentFileInfo, info) {\n    this.combinator = combinator instanceof Combinator ?\n                      combinator : new Combinator(combinator);\n\n    if (typeof value === 'string') {\n        this.value = value.trim();\n    } else if (value) {\n        this.value = value;\n    } else {\n        this.value = \"\";\n    }\n    this.index = index;\n    this.currentFileInfo = currentFileInfo;\n    this.copyVisibilityInfo(info);\n};\nElement.prototype = new Node();\nElement.prototype.type = \"Element\";\nElement.prototype.accept = function (visitor) {\n    var value = this.value;\n    this.combinator = visitor.visit(this.combinator);\n    if (typeof value === \"object\") {\n        this.value = visitor.visit(value);\n    }\n};\nElement.prototype.eval = function (context) {\n    return new Element(this.combinator,\n                             this.value.eval ? this.value.eval(context) : this.value,\n                             this.index,\n                             this.currentFileInfo, this.visibilityInfo());\n};\nElement.prototype.clone = function () {\n    return new Element(this.combinator,\n        this.value,\n        this.index,\n        this.currentFileInfo, this.visibilityInfo());\n};\nElement.prototype.genCSS = function (context, output) {\n    output.add(this.toCSS(context), this.currentFileInfo, this.index);\n};\nElement.prototype.toCSS = function (context) {\n    context = context || {};\n    var value = this.value, firstSelector = context.firstSelector;\n    if (value instanceof Paren) {\n        // selector in parens should not be affected by outer selector\n        // flags (breaks only interpolated selectors - see #1973)\n        context.firstSelector = true;\n    }\n    value = value.toCSS ? value.toCSS(context) : value;\n    context.firstSelector = firstSelector;\n    if (value === '' && this.combinator.value.charAt(0) === '&') {\n        return '';\n    } else {\n        return this.combinator.toCSS(context) + value;\n    }\n};\nmodule.exports = Element;\n\n},{\"./combinator\":51,\"./node\":70,\"./paren\":72}],59:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    Paren = require(\"./paren\"),\n    Comment = require(\"./comment\");\n\nvar Expression = function (value) {\n    this.value = value;\n    if (!value) {\n        throw new Error(\"Expression requires an array parameter\");\n    }\n};\nExpression.prototype = new Node();\nExpression.prototype.type = \"Expression\";\nExpression.prototype.accept = function (visitor) {\n    this.value = visitor.visitArray(this.value);\n};\nExpression.prototype.eval = function (context) {\n    var returnValue,\n        inParenthesis = this.parens && !this.parensInOp,\n        doubleParen = false;\n    if (inParenthesis) {\n        context.inParenthesis();\n    }\n    if (this.value.length > 1) {\n        returnValue = new Expression(this.value.map(function (e) {\n            return e.eval(context);\n        }));\n    } else if (this.value.length === 1) {\n        if (this.value[0].parens && !this.value[0].parensInOp) {\n            doubleParen = true;\n        }\n        returnValue = this.value[0].eval(context);\n    } else {\n        returnValue = this;\n    }\n    if (inParenthesis) {\n        context.outOfParenthesis();\n    }\n    if (this.parens && this.parensInOp && !(context.isMathOn()) && !doubleParen) {\n        returnValue = new Paren(returnValue);\n    }\n    return returnValue;\n};\nExpression.prototype.genCSS = function (context, output) {\n    for (var i = 0; i < this.value.length; i++) {\n        this.value[i].genCSS(context, output);\n        if (i + 1 < this.value.length) {\n            output.add(\" \");\n        }\n    }\n};\nExpression.prototype.throwAwayComments = function () {\n    this.value = this.value.filter(function(v) {\n        return !(v instanceof Comment);\n    });\n};\nmodule.exports = Expression;\n\n},{\"./comment\":52,\"./node\":70,\"./paren\":72}],60:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    Selector = require(\"./selector\");\n\nvar Extend = function Extend(selector, option, index, currentFileInfo, visibilityInfo) {\n    this.selector = selector;\n    this.option = option;\n    this.index = index;\n    this.object_id = Extend.next_id++;\n    this.parent_ids = [this.object_id];\n    this.currentFileInfo = currentFileInfo || {};\n    this.copyVisibilityInfo(visibilityInfo);\n    this.allowRoot = true;\n\n    switch(option) {\n        case \"all\":\n            this.allowBefore = true;\n            this.allowAfter = true;\n            break;\n        default:\n            this.allowBefore = false;\n            this.allowAfter = false;\n            break;\n    }\n};\nExtend.next_id = 0;\n\nExtend.prototype = new Node();\nExtend.prototype.type = \"Extend\";\nExtend.prototype.accept = function (visitor) {\n    this.selector = visitor.visit(this.selector);\n};\nExtend.prototype.eval = function (context) {\n    return new Extend(this.selector.eval(context), this.option, this.index, this.currentFileInfo, this.visibilityInfo());\n};\nExtend.prototype.clone = function (context) {\n    return new Extend(this.selector, this.option, this.index, this.currentFileInfo, this.visibilityInfo());\n};\n//it concatenates (joins) all selectors in selector array\nExtend.prototype.findSelfSelectors = function (selectors) {\n    var selfElements = [],\n        i,\n        selectorElements;\n\n    for (i = 0; i < selectors.length; i++) {\n        selectorElements = selectors[i].elements;\n        // duplicate the logic in genCSS function inside the selector node.\n        // future TODO - move both logics into the selector joiner visitor\n        if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === \"\") {\n            selectorElements[0].combinator.value = ' ';\n        }\n        selfElements = selfElements.concat(selectors[i].elements);\n    }\n\n    this.selfSelectors = [new Selector(selfElements)];\n    this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo());\n};\nmodule.exports = Extend;\n\n},{\"./node\":70,\"./selector\":77}],61:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    Media = require(\"./media\"),\n    URL = require(\"./url\"),\n    Quoted = require(\"./quoted\"),\n    Ruleset = require(\"./ruleset\"),\n    Anonymous = require(\"./anonymous\");\n\n//\n// CSS @import node\n//\n// The general strategy here is that we don't want to wait\n// for the parsing to be completed, before we start importing\n// the file. That's because in the context of a browser,\n// most of the time will be spent waiting for the server to respond.\n//\n// On creation, we push the import path to our import queue, though\n// `import,push`, we also pass it a callback, which it'll call once\n// the file has been fetched, and parsed.\n//\nvar Import = function (path, features, options, index, currentFileInfo, visibilityInfo) {\n    this.options = options;\n    this.index = index;\n    this.path = path;\n    this.features = features;\n    this.currentFileInfo = currentFileInfo;\n    this.allowRoot = true;\n\n    if (this.options.less !== undefined || this.options.inline) {\n        this.css = !this.options.less || this.options.inline;\n    } else {\n        var pathValue = this.getPath();\n        if (pathValue && /[#\\.\\&\\?\\/]css([\\?;].*)?$/.test(pathValue)) {\n            this.css = true;\n        }\n    }\n    this.copyVisibilityInfo(visibilityInfo);\n};\n\n//\n// The actual import node doesn't return anything, when converted to CSS.\n// The reason is that it's used at the evaluation stage, so that the rules\n// it imports can be treated like any other rules.\n//\n// In `eval`, we make sure all Import nodes get evaluated, recursively, so\n// we end up with a flat structure, which can easily be imported in the parent\n// ruleset.\n//\nImport.prototype = new Node();\nImport.prototype.type = \"Import\";\nImport.prototype.accept = function (visitor) {\n    if (this.features) {\n        this.features = visitor.visit(this.features);\n    }\n    this.path = visitor.visit(this.path);\n    if (!this.options.plugin && !this.options.inline && this.root) {\n        this.root = visitor.visit(this.root);\n    }\n};\nImport.prototype.genCSS = function (context, output) {\n    if (this.css && this.path.currentFileInfo.reference === undefined) {\n        output.add(\"@import \", this.currentFileInfo, this.index);\n        this.path.genCSS(context, output);\n        if (this.features) {\n            output.add(\" \");\n            this.features.genCSS(context, output);\n        }\n        output.add(';');\n    }\n};\nImport.prototype.getPath = function () {\n    return (this.path instanceof URL) ?\n        this.path.value.value : this.path.value;\n};\nImport.prototype.isVariableImport = function () {\n    var path = this.path;\n    if (path instanceof URL) {\n        path = path.value;\n    }\n    if (path instanceof Quoted) {\n        return path.containsVariables();\n    }\n\n    return true;\n};\nImport.prototype.evalForImport = function (context) {\n    var path = this.path;\n\n    if (path instanceof URL) {\n        path = path.value;\n    }\n\n    return new Import(path.eval(context), this.features, this.options, this.index, this.currentFileInfo, this.visibilityInfo());\n};\nImport.prototype.evalPath = function (context) {\n    var path = this.path.eval(context);\n    var rootpath = this.currentFileInfo && this.currentFileInfo.rootpath;\n\n    if (!(path instanceof URL)) {\n        if (rootpath) {\n            var pathValue = path.value;\n            // Add the base path if the import is relative\n            if (pathValue && context.isPathRelative(pathValue)) {\n                path.value = rootpath + pathValue;\n            }\n        }\n        path.value = context.normalizePath(path.value);\n    }\n\n    return path;\n};\nImport.prototype.eval = function (context) {\n    var result = this.doEval(context);\n    if (this.options.reference || this.blocksVisibility()) {\n        if (result.length || result.length === 0) {\n            result.forEach(function (node) {\n                    node.addVisibilityBlock();\n                }\n            );\n        } else {\n            result.addVisibilityBlock();\n        }\n    }\n    return result;\n};\nImport.prototype.doEval = function (context) {\n    var ruleset, registry,\n        features = this.features && this.features.eval(context);\n\n    if (this.options.plugin) {\n        registry = context.frames[0] && context.frames[0].functionRegistry;\n        if ( registry && this.root && this.root.functions ) {\n            registry.addMultiple( this.root.functions );\n        }\n        return [];\n    }\n\n    if (this.skip) {\n        if (typeof this.skip === \"function\") {\n            this.skip = this.skip();\n        }\n        if (this.skip) {\n            return [];\n        }\n    }\n    if (this.options.inline) {\n        var contents = new Anonymous(this.root, 0,\n          {\n              filename: this.importedFilename,\n              reference: this.path.currentFileInfo && this.path.currentFileInfo.reference\n          }, true, true);\n\n        return this.features ? new Media([contents], this.features.value) : [contents];\n    } else if (this.css) {\n        var newImport = new Import(this.evalPath(context), features, this.options, this.index);\n        if (!newImport.css && this.error) {\n            throw this.error;\n        }\n        return newImport;\n    } else {\n        ruleset = new Ruleset(null, this.root.rules.slice(0));\n        ruleset.evalImports(context);\n\n        return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules;\n    }\n};\nmodule.exports = Import;\n\n},{\"./anonymous\":46,\"./media\":66,\"./node\":70,\"./quoted\":73,\"./ruleset\":76,\"./url\":80}],62:[function(require,module,exports){\nvar tree = {};\n\ntree.Node = require('./node');\ntree.Alpha = require('./alpha');\ntree.Color = require('./color');\ntree.Directive = require('./directive');\ntree.DetachedRuleset = require('./detached-ruleset');\ntree.Operation = require('./operation');\ntree.Dimension = require('./dimension');\ntree.Unit = require('./unit');\ntree.Keyword = require('./keyword');\ntree.Variable = require('./variable');\ntree.Ruleset = require('./ruleset');\ntree.Element = require('./element');\ntree.Attribute = require('./attribute');\ntree.Combinator = require('./combinator');\ntree.Selector = require('./selector');\ntree.Quoted = require('./quoted');\ntree.Expression = require('./expression');\ntree.Rule = require('./rule');\ntree.Call = require('./call');\ntree.URL = require('./url');\ntree.Import = require('./import');\ntree.mixin = {\n    Call: require('./mixin-call'),\n    Definition: require('./mixin-definition')\n};\ntree.Comment = require('./comment');\ntree.Anonymous = require('./anonymous');\ntree.Value = require('./value');\ntree.JavaScript = require('./javascript');\ntree.Assignment = require('./assignment');\ntree.Condition = require('./condition');\ntree.Paren = require('./paren');\ntree.Media = require('./media');\ntree.UnicodeDescriptor = require('./unicode-descriptor');\ntree.Negative = require('./negative');\ntree.Extend = require('./extend');\ntree.RulesetCall = require('./ruleset-call');\n\nmodule.exports = tree;\n\n},{\"./alpha\":45,\"./anonymous\":46,\"./assignment\":47,\"./attribute\":48,\"./call\":49,\"./color\":50,\"./combinator\":51,\"./comment\":52,\"./condition\":53,\"./detached-ruleset\":55,\"./dimension\":56,\"./directive\":57,\"./element\":58,\"./expression\":59,\"./extend\":60,\"./import\":61,\"./javascript\":63,\"./keyword\":65,\"./media\":66,\"./mixin-call\":67,\"./mixin-definition\":68,\"./negative\":69,\"./node\":70,\"./operation\":71,\"./paren\":72,\"./quoted\":73,\"./rule\":74,\"./ruleset\":76,\"./ruleset-call\":75,\"./selector\":77,\"./unicode-descriptor\":78,\"./unit\":79,\"./url\":80,\"./value\":81,\"./variable\":82}],63:[function(require,module,exports){\nvar JsEvalNode = require(\"./js-eval-node\"),\n    Dimension = require(\"./dimension\"),\n    Quoted = require(\"./quoted\"),\n    Anonymous = require(\"./anonymous\");\n\nvar JavaScript = function (string, escaped, index, currentFileInfo) {\n    this.escaped = escaped;\n    this.expression = string;\n    this.index = index;\n    this.currentFileInfo = currentFileInfo;\n};\nJavaScript.prototype = new JsEvalNode();\nJavaScript.prototype.type = \"JavaScript\";\nJavaScript.prototype.eval = function(context) {\n    var result = this.evaluateJavaScript(this.expression, context);\n\n    if (typeof result === 'number') {\n        return new Dimension(result);\n    } else if (typeof result === 'string') {\n        return new Quoted('\"' + result + '\"', result, this.escaped, this.index);\n    } else if (Array.isArray(result)) {\n        return new Anonymous(result.join(', '));\n    } else {\n        return new Anonymous(result);\n    }\n};\n\nmodule.exports = JavaScript;\n\n},{\"./anonymous\":46,\"./dimension\":56,\"./js-eval-node\":64,\"./quoted\":73}],64:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    Variable = require(\"./variable\");\n\nvar JsEvalNode = function() {\n};\nJsEvalNode.prototype = new Node();\n\nJsEvalNode.prototype.evaluateJavaScript = function (expression, context) {\n    var result,\n        that = this,\n        evalContext = {};\n\n    if (context.javascriptEnabled !== undefined && !context.javascriptEnabled) {\n        throw { message: \"You are using JavaScript, which has been disabled.\",\n            filename: this.currentFileInfo.filename,\n            index: this.index };\n    }\n\n    expression = expression.replace(/@\\{([\\w-]+)\\}/g, function (_, name) {\n        return that.jsify(new Variable('@' + name, that.index, that.currentFileInfo).eval(context));\n    });\n\n    try {\n        expression = new Function('return (' + expression + ')');\n    } catch (e) {\n        throw { message: \"JavaScript evaluation error: \" + e.message + \" from `\" + expression + \"`\" ,\n            filename: this.currentFileInfo.filename,\n            index: this.index };\n    }\n\n    var variables = context.frames[0].variables();\n    for (var k in variables) {\n        if (variables.hasOwnProperty(k)) {\n            /*jshint loopfunc:true */\n            evalContext[k.slice(1)] = {\n                value: variables[k].value,\n                toJS: function () {\n                    return this.value.eval(context).toCSS();\n                }\n            };\n        }\n    }\n\n    try {\n        result = expression.call(evalContext);\n    } catch (e) {\n        throw { message: \"JavaScript evaluation error: '\" + e.name + ': ' + e.message.replace(/[\"]/g, \"'\") + \"'\" ,\n            filename: this.currentFileInfo.filename,\n            index: this.index };\n    }\n    return result;\n};\nJsEvalNode.prototype.jsify = function (obj) {\n    if (Array.isArray(obj.value) && (obj.value.length > 1)) {\n        return '[' + obj.value.map(function (v) { return v.toCSS(); }).join(', ') + ']';\n    } else {\n        return obj.toCSS();\n    }\n};\n\nmodule.exports = JsEvalNode;\n\n},{\"./node\":70,\"./variable\":82}],65:[function(require,module,exports){\nvar Node = require(\"./node\");\n\nvar Keyword = function (value) { this.value = value; };\nKeyword.prototype = new Node();\nKeyword.prototype.type = \"Keyword\";\nKeyword.prototype.genCSS = function (context, output) {\n    if (this.value === '%') { throw { type: \"Syntax\", message: \"Invalid % without number\" }; }\n    output.add(this.value);\n};\n\nKeyword.True = new Keyword('true');\nKeyword.False = new Keyword('false');\n\nmodule.exports = Keyword;\n\n},{\"./node\":70}],66:[function(require,module,exports){\nvar Ruleset = require(\"./ruleset\"),\n    Value = require(\"./value\"),\n    Selector = require(\"./selector\"),\n    Anonymous = require(\"./anonymous\"),\n    Expression = require(\"./expression\"),\n    Directive = require(\"./directive\");\n\nvar Media = function (value, features, index, currentFileInfo, visibilityInfo) {\n    this.index = index;\n    this.currentFileInfo = currentFileInfo;\n\n    var selectors = (new Selector([], null, null, this.index, this.currentFileInfo)).createEmptySelectors();\n\n    this.features = new Value(features);\n    this.rules = [new Ruleset(selectors, value)];\n    this.rules[0].allowImports = true;\n    this.copyVisibilityInfo(visibilityInfo);\n    this.allowRoot = true;\n};\nMedia.prototype = new Directive();\nMedia.prototype.type = \"Media\";\nMedia.prototype.isRulesetLike = true;\nMedia.prototype.accept = function (visitor) {\n    if (this.features) {\n        this.features = visitor.visit(this.features);\n    }\n    if (this.rules) {\n        this.rules = visitor.visitArray(this.rules);\n    }\n};\nMedia.prototype.genCSS = function (context, output) {\n    output.add('@media ', this.currentFileInfo, this.index);\n    this.features.genCSS(context, output);\n    this.outputRuleset(context, output, this.rules);\n};\nMedia.prototype.eval = function (context) {\n    if (!context.mediaBlocks) {\n        context.mediaBlocks = [];\n        context.mediaPath = [];\n    }\n\n    var media = new Media(null, [], this.index, this.currentFileInfo, this.visibilityInfo());\n    if (this.debugInfo) {\n        this.rules[0].debugInfo = this.debugInfo;\n        media.debugInfo = this.debugInfo;\n    }\n    var strictMathBypass = false;\n    if (!context.strictMath) {\n        strictMathBypass = true;\n        context.strictMath = true;\n    }\n    try {\n        media.features = this.features.eval(context);\n    }\n    finally {\n        if (strictMathBypass) {\n            context.strictMath = false;\n        }\n    }\n\n    context.mediaPath.push(media);\n    context.mediaBlocks.push(media);\n\n    this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit();\n    context.frames.unshift(this.rules[0]);\n    media.rules = [this.rules[0].eval(context)];\n    context.frames.shift();\n\n    context.mediaPath.pop();\n\n    return context.mediaPath.length === 0 ? media.evalTop(context) :\n                media.evalNested(context);\n};\nMedia.prototype.evalTop = function (context) {\n    var result = this;\n\n    // Render all dependent Media blocks.\n    if (context.mediaBlocks.length > 1) {\n        var selectors = (new Selector([], null, null, this.index, this.currentFileInfo)).createEmptySelectors();\n        result = new Ruleset(selectors, context.mediaBlocks);\n        result.multiMedia = true;\n        result.copyVisibilityInfo(this.visibilityInfo());\n    }\n\n    delete context.mediaBlocks;\n    delete context.mediaPath;\n\n    return result;\n};\nMedia.prototype.evalNested = function (context) {\n    var i, value,\n        path = context.mediaPath.concat([this]);\n\n    // Extract the media-query conditions separated with `,` (OR).\n    for (i = 0; i < path.length; i++) {\n        value = path[i].features instanceof Value ?\n                    path[i].features.value : path[i].features;\n        path[i] = Array.isArray(value) ? value : [value];\n    }\n\n    // Trace all permutations to generate the resulting media-query.\n    //\n    // (a, b and c) with nested (d, e) ->\n    //    a and d\n    //    a and e\n    //    b and c and d\n    //    b and c and e\n    this.features = new Value(this.permute(path).map(function (path) {\n        path = path.map(function (fragment) {\n            return fragment.toCSS ? fragment : new Anonymous(fragment);\n        });\n\n        for (i = path.length - 1; i > 0; i--) {\n            path.splice(i, 0, new Anonymous(\"and\"));\n        }\n\n        return new Expression(path);\n    }));\n\n    // Fake a tree-node that doesn't output anything.\n    return new Ruleset([], []);\n};\nMedia.prototype.permute = function (arr) {\n    if (arr.length === 0) {\n        return [];\n    } else if (arr.length === 1) {\n        return arr[0];\n    } else {\n        var result = [];\n        var rest = this.permute(arr.slice(1));\n        for (var i = 0; i < rest.length; i++) {\n            for (var j = 0; j < arr[0].length; j++) {\n                result.push([arr[0][j]].concat(rest[i]));\n            }\n        }\n        return result;\n    }\n};\nMedia.prototype.bubbleSelectors = function (selectors) {\n    if (!selectors) {\n        return;\n    }\n    this.rules = [new Ruleset(selectors.slice(0), [this.rules[0]])];\n};\nmodule.exports = Media;\n\n},{\"./anonymous\":46,\"./directive\":57,\"./expression\":59,\"./ruleset\":76,\"./selector\":77,\"./value\":81}],67:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    Selector = require(\"./selector\"),\n    MixinDefinition = require(\"./mixin-definition\"),\n    defaultFunc = require(\"../functions/default\");\n\nvar MixinCall = function (elements, args, index, currentFileInfo, important) {\n    this.selector = new Selector(elements);\n    this.arguments = args || [];\n    this.index = index;\n    this.currentFileInfo = currentFileInfo;\n    this.important = important;\n    this.allowRoot = true;\n};\nMixinCall.prototype = new Node();\nMixinCall.prototype.type = \"MixinCall\";\nMixinCall.prototype.accept = function (visitor) {\n    if (this.selector) {\n        this.selector = visitor.visit(this.selector);\n    }\n    if (this.arguments.length) {\n        this.arguments = visitor.visitArray(this.arguments);\n    }\n};\nMixinCall.prototype.eval = function (context) {\n    var mixins, mixin, mixinPath, args = [], arg, argValue,\n        rules = [], match = false, i, m, f, isRecursive, isOneFound,\n        candidates = [], candidate, conditionResult = [], defaultResult, defFalseEitherCase = -1,\n        defNone = 0, defTrue = 1, defFalse = 2, count, originalRuleset, noArgumentsFilter;\n\n    function calcDefGroup(mixin, mixinPath) {\n        var f, p, namespace;\n\n        for (f = 0; f < 2; f++) {\n            conditionResult[f] = true;\n            defaultFunc.value(f);\n            for (p = 0; p < mixinPath.length && conditionResult[f]; p++) {\n                namespace = mixinPath[p];\n                if (namespace.matchCondition) {\n                    conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context);\n                }\n            }\n            if (mixin.matchCondition) {\n                conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context);\n            }\n        }\n        if (conditionResult[0] || conditionResult[1]) {\n            if (conditionResult[0] != conditionResult[1]) {\n                return conditionResult[1] ?\n                    defTrue : defFalse;\n            }\n\n            return defNone;\n        }\n        return defFalseEitherCase;\n    }\n\n    for (i = 0; i < this.arguments.length; i++) {\n        arg = this.arguments[i];\n        argValue = arg.value.eval(context);\n        if (arg.expand && Array.isArray(argValue.value)) {\n            argValue = argValue.value;\n            for (m = 0; m < argValue.length; m++) {\n                args.push({value: argValue[m]});\n            }\n        } else {\n            args.push({name: arg.name, value: argValue});\n        }\n    }\n\n    noArgumentsFilter = function(rule) {return rule.matchArgs(null, context);};\n\n    for (i = 0; i < context.frames.length; i++) {\n        if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) {\n            isOneFound = true;\n\n            // To make `default()` function independent of definition order we have two \"subpasses\" here.\n            // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),\n            // and build candidate list with corresponding flags. Then, when we know all possible matches,\n            // we make a final decision.\n\n            for (m = 0; m < mixins.length; m++) {\n                mixin = mixins[m].rule;\n                mixinPath = mixins[m].path;\n                isRecursive = false;\n                for (f = 0; f < context.frames.length; f++) {\n                    if ((!(mixin instanceof MixinDefinition)) && mixin === (context.frames[f].originalRuleset || context.frames[f])) {\n                        isRecursive = true;\n                        break;\n                    }\n                }\n                if (isRecursive) {\n                    continue;\n                }\n\n                if (mixin.matchArgs(args, context)) {\n                    candidate = {mixin: mixin, group: calcDefGroup(mixin, mixinPath)};\n\n                    if (candidate.group !== defFalseEitherCase) {\n                        candidates.push(candidate);\n                    }\n\n                    match = true;\n                }\n            }\n\n            defaultFunc.reset();\n\n            count = [0, 0, 0];\n            for (m = 0; m < candidates.length; m++) {\n                count[candidates[m].group]++;\n            }\n\n            if (count[defNone] > 0) {\n                defaultResult = defFalse;\n            } else {\n                defaultResult = defTrue;\n                if ((count[defTrue] + count[defFalse]) > 1) {\n                    throw { type: 'Runtime',\n                        message: 'Ambiguous use of `default()` found when matching for `' + this.format(args) + '`',\n                        index: this.index, filename: this.currentFileInfo.filename };\n                }\n            }\n\n            for (m = 0; m < candidates.length; m++) {\n                candidate = candidates[m].group;\n                if ((candidate === defNone) || (candidate === defaultResult)) {\n                    try {\n                        mixin = candidates[m].mixin;\n                        if (!(mixin instanceof MixinDefinition)) {\n                            originalRuleset = mixin.originalRuleset || mixin;\n                            mixin = new MixinDefinition(\"\", [], mixin.rules, null, false, null, originalRuleset.visibilityInfo());\n                            mixin.originalRuleset = originalRuleset;\n                        }\n                        var newRules = mixin.evalCall(context, args, this.important).rules;\n                        this._setVisibilityToReplacement(newRules);\n                        Array.prototype.push.apply(rules, newRules);\n                    } catch (e) {\n                        throw { message: e.message, index: this.index, filename: this.currentFileInfo.filename, stack: e.stack };\n                    }\n                }\n            }\n\n            if (match) {\n                return rules;\n            }\n        }\n    }\n    if (isOneFound) {\n        throw { type:    'Runtime',\n            message: 'No matching definition was found for `' + this.format(args) + '`',\n            index:   this.index, filename: this.currentFileInfo.filename };\n    } else {\n        throw { type:    'Name',\n            message: this.selector.toCSS().trim() + \" is undefined\",\n            index:   this.index, filename: this.currentFileInfo.filename };\n    }\n};\n\nMixinCall.prototype._setVisibilityToReplacement = function (replacement) {\n    var i, rule;\n    if (this.blocksVisibility()) {\n        for (i = 0; i < replacement.length; i++) {\n            rule = replacement[i];\n            rule.addVisibilityBlock();\n        }\n    }\n};\nMixinCall.prototype.format = function (args) {\n    return this.selector.toCSS().trim() + '(' +\n        (args ? args.map(function (a) {\n            var argValue = \"\";\n            if (a.name) {\n                argValue += a.name + \":\";\n            }\n            if (a.value.toCSS) {\n                argValue += a.value.toCSS();\n            } else {\n                argValue += \"???\";\n            }\n            return argValue;\n        }).join(', ') : \"\") + \")\";\n};\nmodule.exports = MixinCall;\n\n},{\"../functions/default\":20,\"./mixin-definition\":68,\"./node\":70,\"./selector\":77}],68:[function(require,module,exports){\nvar Selector = require(\"./selector\"),\n    Element = require(\"./element\"),\n    Ruleset = require(\"./ruleset\"),\n    Rule = require(\"./rule\"),\n    Expression = require(\"./expression\"),\n    contexts = require(\"../contexts\");\n\nvar Definition = function (name, params, rules, condition, variadic, frames, visibilityInfo) {\n    this.name = name;\n    this.selectors = [new Selector([new Element(null, name, this.index, this.currentFileInfo)])];\n    this.params = params;\n    this.condition = condition;\n    this.variadic = variadic;\n    this.arity = params.length;\n    this.rules = rules;\n    this._lookups = {};\n    var optionalParameters = [];\n    this.required = params.reduce(function (count, p) {\n        if (!p.name || (p.name && !p.value)) {\n            return count + 1;\n        }\n        else {\n            optionalParameters.push(p.name);\n            return count;\n        }\n    }, 0);\n    this.optionalParameters = optionalParameters;\n    this.frames = frames;\n    this.copyVisibilityInfo(visibilityInfo);\n    this.allowRoot = true;\n};\nDefinition.prototype = new Ruleset();\nDefinition.prototype.type = \"MixinDefinition\";\nDefinition.prototype.evalFirst = true;\nDefinition.prototype.accept = function (visitor) {\n    if (this.params && this.params.length) {\n        this.params = visitor.visitArray(this.params);\n    }\n    this.rules = visitor.visitArray(this.rules);\n    if (this.condition) {\n        this.condition = visitor.visit(this.condition);\n    }\n};\nDefinition.prototype.evalParams = function (context, mixinEnv, args, evaldArguments) {\n    /*jshint boss:true */\n    var frame = new Ruleset(null, null),\n        varargs, arg,\n        params = this.params.slice(0),\n        i, j, val, name, isNamedFound, argIndex, argsLength = 0;\n\n    if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) {\n        frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit();\n    }\n    mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames));\n\n    if (args) {\n        args = args.slice(0);\n        argsLength = args.length;\n\n        for (i = 0; i < argsLength; i++) {\n            arg = args[i];\n            if (name = (arg && arg.name)) {\n                isNamedFound = false;\n                for (j = 0; j < params.length; j++) {\n                    if (!evaldArguments[j] && name === params[j].name) {\n                        evaldArguments[j] = arg.value.eval(context);\n                        frame.prependRule(new Rule(name, arg.value.eval(context)));\n                        isNamedFound = true;\n                        break;\n                    }\n                }\n                if (isNamedFound) {\n                    args.splice(i, 1);\n                    i--;\n                    continue;\n                } else {\n                    throw { type: 'Runtime', message: \"Named argument for \" + this.name +\n                        ' ' + args[i].name + ' not found' };\n                }\n            }\n        }\n    }\n    argIndex = 0;\n    for (i = 0; i < params.length; i++) {\n        if (evaldArguments[i]) { continue; }\n\n        arg = args && args[argIndex];\n\n        if (name = params[i].name) {\n            if (params[i].variadic) {\n                varargs = [];\n                for (j = argIndex; j < argsLength; j++) {\n                    varargs.push(args[j].value.eval(context));\n                }\n                frame.prependRule(new Rule(name, new Expression(varargs).eval(context)));\n            } else {\n                val = arg && arg.value;\n                if (val) {\n                    val = val.eval(context);\n                } else if (params[i].value) {\n                    val = params[i].value.eval(mixinEnv);\n                    frame.resetCache();\n                } else {\n                    throw { type: 'Runtime', message: \"wrong number of arguments for \" + this.name +\n                        ' (' + argsLength + ' for ' + this.arity + ')' };\n                }\n\n                frame.prependRule(new Rule(name, val));\n                evaldArguments[i] = val;\n            }\n        }\n\n        if (params[i].variadic && args) {\n            for (j = argIndex; j < argsLength; j++) {\n                evaldArguments[j] = args[j].value.eval(context);\n            }\n        }\n        argIndex++;\n    }\n\n    return frame;\n};\nDefinition.prototype.makeImportant = function() {\n    var rules = !this.rules ? this.rules : this.rules.map(function (r) {\n        if (r.makeImportant) {\n            return r.makeImportant(true);\n        } else {\n            return r;\n        }\n    });\n    var result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames);\n    return result;\n};\nDefinition.prototype.eval = function (context) {\n    return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || context.frames.slice(0));\n};\nDefinition.prototype.evalCall = function (context, args, important) {\n    var _arguments = [],\n        mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames,\n        frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments),\n        rules, ruleset;\n\n    frame.prependRule(new Rule('@arguments', new Expression(_arguments).eval(context)));\n\n    rules = this.rules.slice(0);\n\n    ruleset = new Ruleset(null, rules);\n    ruleset.originalRuleset = this;\n    ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames)));\n    if (important) {\n        ruleset = ruleset.makeImportant();\n    }\n    return ruleset;\n};\nDefinition.prototype.matchCondition = function (args, context) {\n    if (this.condition && !this.condition.eval(\n        new contexts.Eval(context,\n            [this.evalParams(context, /* the parameter variables*/\n                new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])]\n            .concat(this.frames || []) // the parent namespace/mixin frames\n            .concat(context.frames)))) { // the current environment frames\n        return false;\n    }\n    return true;\n};\nDefinition.prototype.matchArgs = function (args, context) {\n    var allArgsCnt = (args && args.length) || 0, len, optionalParameters = this.optionalParameters;\n    var requiredArgsCnt = !args ? 0 : args.reduce(function (count, p) {\n        if (optionalParameters.indexOf(p.name) < 0) {\n            return count + 1;\n        } else {\n            return count;\n        }\n    }, 0);\n\n    if (! this.variadic) {\n        if (requiredArgsCnt < this.required) {\n            return false;\n        }\n        if (allArgsCnt > this.params.length) {\n            return false;\n        }\n    } else {\n        if (requiredArgsCnt < (this.required - 1)) {\n            return false;\n        }\n    }\n\n    // check patterns\n    len = Math.min(requiredArgsCnt, this.arity);\n\n    for (var i = 0; i < len; i++) {\n        if (!this.params[i].name && !this.params[i].variadic) {\n            if (args[i].value.eval(context).toCSS() != this.params[i].value.eval(context).toCSS()) {\n                return false;\n            }\n        }\n    }\n    return true;\n};\nmodule.exports = Definition;\n\n},{\"../contexts\":11,\"./element\":58,\"./expression\":59,\"./rule\":74,\"./ruleset\":76,\"./selector\":77}],69:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    Operation = require(\"./operation\"),\n    Dimension = require(\"./dimension\");\n\nvar Negative = function (node) {\n    this.value = node;\n};\nNegative.prototype = new Node();\nNegative.prototype.type = \"Negative\";\nNegative.prototype.genCSS = function (context, output) {\n    output.add('-');\n    this.value.genCSS(context, output);\n};\nNegative.prototype.eval = function (context) {\n    if (context.isMathOn()) {\n        return (new Operation('*', [new Dimension(-1), this.value])).eval(context);\n    }\n    return new Negative(this.value.eval(context));\n};\nmodule.exports = Negative;\n\n},{\"./dimension\":56,\"./node\":70,\"./operation\":71}],70:[function(require,module,exports){\nvar Node = function() {\n};\nNode.prototype.toCSS = function (context) {\n    var strs = [];\n    this.genCSS(context, {\n        add: function(chunk, fileInfo, index) {\n            strs.push(chunk);\n        },\n        isEmpty: function () {\n            return strs.length === 0;\n        }\n    });\n    return strs.join('');\n};\nNode.prototype.genCSS = function (context, output) {\n    output.add(this.value);\n};\nNode.prototype.accept = function (visitor) {\n    this.value = visitor.visit(this.value);\n};\nNode.prototype.eval = function () { return this; };\nNode.prototype._operate = function (context, op, a, b) {\n    switch (op) {\n        case '+': return a + b;\n        case '-': return a - b;\n        case '*': return a * b;\n        case '/': return a / b;\n    }\n};\nNode.prototype.fround = function(context, value) {\n    var precision = context && context.numPrecision;\n    //add \"epsilon\" to ensure numbers like 1.000000005 (represented as 1.000000004999....) are properly rounded...\n    return (precision == null) ? value : Number((value + 2e-16).toFixed(precision));\n};\nNode.compare = function (a, b) {\n    /* returns:\n     -1: a < b\n     0: a = b\n     1: a > b\n     and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */\n\n    if ((a.compare) &&\n        // for \"symmetric results\" force toCSS-based comparison\n        // of Quoted or Anonymous if either value is one of those\n        !(b.type === \"Quoted\" || b.type === \"Anonymous\")) {\n        return a.compare(b);\n    } else if (b.compare) {\n        return -b.compare(a);\n    } else if (a.type !== b.type) {\n        return undefined;\n    }\n\n    a = a.value;\n    b = b.value;\n    if (!Array.isArray(a)) {\n        return a === b ? 0 : undefined;\n    }\n    if (a.length !== b.length) {\n        return undefined;\n    }\n    for (var i = 0; i < a.length; i++) {\n        if (Node.compare(a[i], b[i]) !== 0) {\n            return undefined;\n        }\n    }\n    return 0;\n};\n\nNode.numericCompare = function (a, b) {\n    return a  <  b ? -1\n        : a === b ?  0\n        : a  >  b ?  1 : undefined;\n};\n// Returns true if this node represents root of ast imported by reference\nNode.prototype.blocksVisibility = function () {\n    if (this.visibilityBlocks == null) {\n        this.visibilityBlocks = 0;\n    }\n    return this.visibilityBlocks !== 0;\n};\nNode.prototype.addVisibilityBlock = function () {\n    if (this.visibilityBlocks == null) {\n        this.visibilityBlocks = 0;\n    }\n    this.visibilityBlocks = this.visibilityBlocks + 1;\n};\nNode.prototype.removeVisibilityBlock = function () {\n    if (this.visibilityBlocks == null) {\n        this.visibilityBlocks = 0;\n    }\n    this.visibilityBlocks = this.visibilityBlocks - 1;\n};\n//Turns on node visibility - if called node will be shown in output regardless\n//of whether it comes from import by reference or not\nNode.prototype.ensureVisibility = function () {\n    this.nodeVisible = true;\n};\n//Turns off node visibility - if called node will NOT be shown in output regardless\n//of whether it comes from import by reference or not\nNode.prototype.ensureInvisibility = function () {\n    this.nodeVisible = false;\n};\n// return values:\n// false - the node must not be visible\n// true - the node must be visible\n// undefined or null - the node has the same visibility as its parent\nNode.prototype.isVisible = function () {\n    return this.nodeVisible;\n};\nNode.prototype.visibilityInfo = function() {\n    return {\n        visibilityBlocks: this.visibilityBlocks,\n        nodeVisible: this.nodeVisible\n    };\n};\nNode.prototype.copyVisibilityInfo = function(info) {\n    if (!info) {\n        return;\n    }\n    this.visibilityBlocks = info.visibilityBlocks;\n    this.nodeVisible = info.nodeVisible;\n};\nmodule.exports = Node;\n\n},{}],71:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    Color = require(\"./color\"),\n    Dimension = require(\"./dimension\");\n\nvar Operation = function (op, operands, isSpaced) {\n    this.op = op.trim();\n    this.operands = operands;\n    this.isSpaced = isSpaced;\n};\nOperation.prototype = new Node();\nOperation.prototype.type = \"Operation\";\nOperation.prototype.accept = function (visitor) {\n    this.operands = visitor.visit(this.operands);\n};\nOperation.prototype.eval = function (context) {\n    var a = this.operands[0].eval(context),\n        b = this.operands[1].eval(context);\n\n    if (context.isMathOn()) {\n        if (a instanceof Dimension && b instanceof Color) {\n            a = a.toColor();\n        }\n        if (b instanceof Dimension && a instanceof Color) {\n            b = b.toColor();\n        }\n        if (!a.operate) {\n            throw { type: \"Operation\",\n                    message: \"Operation on an invalid type\" };\n        }\n\n        return a.operate(context, this.op, b);\n    } else {\n        return new Operation(this.op, [a, b], this.isSpaced);\n    }\n};\nOperation.prototype.genCSS = function (context, output) {\n    this.operands[0].genCSS(context, output);\n    if (this.isSpaced) {\n        output.add(\" \");\n    }\n    output.add(this.op);\n    if (this.isSpaced) {\n        output.add(\" \");\n    }\n    this.operands[1].genCSS(context, output);\n};\n\nmodule.exports = Operation;\n\n},{\"./color\":50,\"./dimension\":56,\"./node\":70}],72:[function(require,module,exports){\nvar Node = require(\"./node\");\n\nvar Paren = function (node) {\n    this.value = node;\n};\nParen.prototype = new Node();\nParen.prototype.type = \"Paren\";\nParen.prototype.genCSS = function (context, output) {\n    output.add('(');\n    this.value.genCSS(context, output);\n    output.add(')');\n};\nParen.prototype.eval = function (context) {\n    return new Paren(this.value.eval(context));\n};\nmodule.exports = Paren;\n\n},{\"./node\":70}],73:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    JsEvalNode = require(\"./js-eval-node\"),\n    Variable = require(\"./variable\");\n\nvar Quoted = function (str, content, escaped, index, currentFileInfo) {\n    this.escaped = (escaped == null) ? true : escaped;\n    this.value = content || '';\n    this.quote = str.charAt(0);\n    this.index = index;\n    this.currentFileInfo = currentFileInfo;\n};\nQuoted.prototype = new JsEvalNode();\nQuoted.prototype.type = \"Quoted\";\nQuoted.prototype.genCSS = function (context, output) {\n    if (!this.escaped) {\n        output.add(this.quote, this.currentFileInfo, this.index);\n    }\n    output.add(this.value);\n    if (!this.escaped) {\n        output.add(this.quote);\n    }\n};\nQuoted.prototype.containsVariables = function() {\n    return this.value.match(/(`([^`]+)`)|@\\{([\\w-]+)\\}/);\n};\nQuoted.prototype.eval = function (context) {\n    var that = this, value = this.value;\n    var javascriptReplacement = function (_, exp) {\n        return String(that.evaluateJavaScript(exp, context));\n    };\n    var interpolationReplacement = function (_, name) {\n        var v = new Variable('@' + name, that.index, that.currentFileInfo).eval(context, true);\n        return (v instanceof Quoted) ? v.value : v.toCSS();\n    };\n    function iterativeReplace(value, regexp, replacementFnc) {\n        var evaluatedValue = value;\n        do {\n            value = evaluatedValue;\n            evaluatedValue = value.replace(regexp, replacementFnc);\n        } while (value !== evaluatedValue);\n        return evaluatedValue;\n    }\n    value = iterativeReplace(value, /`([^`]+)`/g, javascriptReplacement);\n    value = iterativeReplace(value, /@\\{([\\w-]+)\\}/g, interpolationReplacement);\n    return new Quoted(this.quote + value + this.quote, value, this.escaped, this.index, this.currentFileInfo);\n};\nQuoted.prototype.compare = function (other) {\n    // when comparing quoted strings allow the quote to differ\n    if (other.type === \"Quoted\" && !this.escaped && !other.escaped) {\n        return Node.numericCompare(this.value, other.value);\n    } else {\n        return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;\n    }\n};\nmodule.exports = Quoted;\n\n},{\"./js-eval-node\":64,\"./node\":70,\"./variable\":82}],74:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    Value = require(\"./value\"),\n    Keyword = require(\"./keyword\");\n\nvar Rule = function (name, value, important, merge, index, currentFileInfo, inline, variable) {\n    this.name = name;\n    this.value = (value instanceof Node) ? value : new Value([value]); //value instanceof tree.Value || value instanceof tree.Ruleset ??\n    this.important = important ? ' ' + important.trim() : '';\n    this.merge = merge;\n    this.index = index;\n    this.currentFileInfo = currentFileInfo;\n    this.inline = inline || false;\n    this.variable = (variable !== undefined) ? variable\n        : (name.charAt && (name.charAt(0) === '@'));\n    this.allowRoot = true;\n};\n\nfunction evalName(context, name) {\n    var value = \"\", i, n = name.length,\n        output = {add: function (s) {value += s;}};\n    for (i = 0; i < n; i++) {\n        name[i].eval(context).genCSS(context, output);\n    }\n    return value;\n}\n\nRule.prototype = new Node();\nRule.prototype.type = \"Rule\";\nRule.prototype.genCSS = function (context, output) {\n    output.add(this.name + (context.compress ? ':' : ': '), this.currentFileInfo, this.index);\n    try {\n        this.value.genCSS(context, output);\n    }\n    catch(e) {\n        e.index = this.index;\n        e.filename = this.currentFileInfo.filename;\n        throw e;\n    }\n    output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? \"\" : \";\"), this.currentFileInfo, this.index);\n};\nRule.prototype.eval = function (context) {\n    var strictMathBypass = false, name = this.name, evaldValue, variable = this.variable;\n    if (typeof name !== \"string\") {\n        // expand 'primitive' name directly to get\n        // things faster (~10% for benchmark.less):\n        name = (name.length === 1) && (name[0] instanceof Keyword) ?\n                name[0].value : evalName(context, name);\n        variable = false; // never treat expanded interpolation as new variable name\n    }\n    if (name === \"font\" && !context.strictMath) {\n        strictMathBypass = true;\n        context.strictMath = true;\n    }\n    try {\n        context.importantScope.push({});\n        evaldValue = this.value.eval(context);\n\n        if (!this.variable && evaldValue.type === \"DetachedRuleset\") {\n            throw { message: \"Rulesets cannot be evaluated on a property.\",\n                    index: this.index, filename: this.currentFileInfo.filename };\n        }\n        var important = this.important,\n            importantResult = context.importantScope.pop();\n        if (!important && importantResult.important) {\n            important = importantResult.important;\n        }\n\n        return new Rule(name,\n                          evaldValue,\n                          important,\n                          this.merge,\n                          this.index, this.currentFileInfo, this.inline,\n                              variable);\n    }\n    catch(e) {\n        if (typeof e.index !== 'number') {\n            e.index = this.index;\n            e.filename = this.currentFileInfo.filename;\n        }\n        throw e;\n    }\n    finally {\n        if (strictMathBypass) {\n            context.strictMath = false;\n        }\n    }\n};\nRule.prototype.makeImportant = function () {\n    return new Rule(this.name,\n                          this.value,\n                          \"!important\",\n                          this.merge,\n                          this.index, this.currentFileInfo, this.inline);\n};\n\nmodule.exports = Rule;\n},{\"./keyword\":65,\"./node\":70,\"./value\":81}],75:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    Variable = require(\"./variable\");\n\nvar RulesetCall = function (variable) {\n    this.variable = variable;\n    this.allowRoot = true;\n};\nRulesetCall.prototype = new Node();\nRulesetCall.prototype.type = \"RulesetCall\";\nRulesetCall.prototype.eval = function (context) {\n    var detachedRuleset = new Variable(this.variable).eval(context);\n    return detachedRuleset.callEval(context);\n};\nmodule.exports = RulesetCall;\n\n},{\"./node\":70,\"./variable\":82}],76:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    Rule = require(\"./rule\"),\n    Selector = require(\"./selector\"),\n    Element = require(\"./element\"),\n    Paren = require(\"./paren\"),\n    contexts = require(\"../contexts\"),\n    globalFunctionRegistry = require(\"../functions/function-registry\"),\n    defaultFunc = require(\"../functions/default\"),\n    getDebugInfo = require(\"./debug-info\");\n\nvar Ruleset = function (selectors, rules, strictImports, visibilityInfo) {\n    this.selectors = selectors;\n    this.rules = rules;\n    this._lookups = {};\n    this.strictImports = strictImports;\n    this.copyVisibilityInfo(visibilityInfo);\n    this.allowRoot = true;\n};\nRuleset.prototype = new Node();\nRuleset.prototype.type = \"Ruleset\";\nRuleset.prototype.isRuleset = true;\nRuleset.prototype.isRulesetLike = true;\nRuleset.prototype.accept = function (visitor) {\n    if (this.paths) {\n        this.paths = visitor.visitArray(this.paths, true);\n    } else if (this.selectors) {\n        this.selectors = visitor.visitArray(this.selectors);\n    }\n    if (this.rules && this.rules.length) {\n        this.rules = visitor.visitArray(this.rules);\n    }\n};\nRuleset.prototype.eval = function (context) {\n    var thisSelectors = this.selectors, selectors,\n        selCnt, selector, i, hasOnePassingSelector = false;\n\n    if (thisSelectors && (selCnt = thisSelectors.length)) {\n        selectors = [];\n        defaultFunc.error({\n            type: \"Syntax\",\n            message: \"it is currently only allowed in parametric mixin guards,\"\n        });\n        for (i = 0; i < selCnt; i++) {\n            selector = thisSelectors[i].eval(context);\n            selectors.push(selector);\n            if (selector.evaldCondition) {\n                hasOnePassingSelector = true;\n            }\n        }\n        defaultFunc.reset();\n    } else {\n        hasOnePassingSelector = true;\n    }\n\n    var rules = this.rules ? this.rules.slice(0) : null,\n        ruleset = new Ruleset(selectors, rules, this.strictImports, this.visibilityInfo()),\n        rule, subRule;\n\n    ruleset.originalRuleset = this;\n    ruleset.root = this.root;\n    ruleset.firstRoot = this.firstRoot;\n    ruleset.allowImports = this.allowImports;\n\n    if (this.debugInfo) {\n        ruleset.debugInfo = this.debugInfo;\n    }\n\n    if (!hasOnePassingSelector) {\n        rules.length = 0;\n    }\n\n    // inherit a function registry from the frames stack when possible;\n    // otherwise from the global registry\n    ruleset.functionRegistry = (function (frames) {\n        var i = 0,\n            n = frames.length,\n            found;\n        for ( ; i !== n ; ++i ) {\n            found = frames[ i ].functionRegistry;\n            if ( found ) { return found; }\n        }\n        return globalFunctionRegistry;\n    }(context.frames)).inherit();\n\n    // push the current ruleset to the frames stack\n    var ctxFrames = context.frames;\n    ctxFrames.unshift(ruleset);\n\n    // currrent selectors\n    var ctxSelectors = context.selectors;\n    if (!ctxSelectors) {\n        context.selectors = ctxSelectors = [];\n    }\n    ctxSelectors.unshift(this.selectors);\n\n    // Evaluate imports\n    if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {\n        ruleset.evalImports(context);\n    }\n\n    // Store the frames around mixin definitions,\n    // so they can be evaluated like closures when the time comes.\n    var rsRules = ruleset.rules, rsRuleCnt = rsRules ? rsRules.length : 0;\n    for (i = 0; i < rsRuleCnt; i++) {\n        if (rsRules[i].evalFirst) {\n            rsRules[i] = rsRules[i].eval(context);\n        }\n    }\n\n    var mediaBlockCount = (context.mediaBlocks && context.mediaBlocks.length) || 0;\n\n    // Evaluate mixin calls.\n    for (i = 0; i < rsRuleCnt; i++) {\n        if (rsRules[i].type === \"MixinCall\") {\n            /*jshint loopfunc:true */\n            rules = rsRules[i].eval(context).filter(function(r) {\n                if ((r instanceof Rule) && r.variable) {\n                    // do not pollute the scope if the variable is\n                    // already there. consider returning false here\n                    // but we need a way to \"return\" variable from mixins\n                    return !(ruleset.variable(r.name));\n                }\n                return true;\n            });\n            rsRules.splice.apply(rsRules, [i, 1].concat(rules));\n            rsRuleCnt += rules.length - 1;\n            i += rules.length - 1;\n            ruleset.resetCache();\n        } else if (rsRules[i].type === \"RulesetCall\") {\n            /*jshint loopfunc:true */\n            rules = rsRules[i].eval(context).rules.filter(function(r) {\n                if ((r instanceof Rule) && r.variable) {\n                    // do not pollute the scope at all\n                    return false;\n                }\n                return true;\n            });\n            rsRules.splice.apply(rsRules, [i, 1].concat(rules));\n            rsRuleCnt += rules.length - 1;\n            i += rules.length - 1;\n            ruleset.resetCache();\n        }\n    }\n\n    // Evaluate everything else\n    for (i = 0; i < rsRules.length; i++) {\n        rule = rsRules[i];\n        if (!rule.evalFirst) {\n            rsRules[i] = rule = rule.eval ? rule.eval(context) : rule;\n        }\n    }\n\n    // Evaluate everything else\n    for (i = 0; i < rsRules.length; i++) {\n        rule = rsRules[i];\n        // for rulesets, check if it is a css guard and can be removed\n        if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) {\n            // check if it can be folded in (e.g. & where)\n            if (rule.selectors[0].isJustParentSelector()) {\n                rsRules.splice(i--, 1);\n\n                for (var j = 0; j < rule.rules.length; j++) {\n                    subRule = rule.rules[j];\n                    subRule.copyVisibilityInfo(rule.visibilityInfo());\n                    if (!(subRule instanceof Rule) || !subRule.variable) {\n                        rsRules.splice(++i, 0, subRule);\n                    }\n                }\n            }\n        }\n    }\n\n    // Pop the stack\n    ctxFrames.shift();\n    ctxSelectors.shift();\n\n    if (context.mediaBlocks) {\n        for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) {\n            context.mediaBlocks[i].bubbleSelectors(selectors);\n        }\n    }\n\n    return ruleset;\n};\nRuleset.prototype.evalImports = function(context) {\n    var rules = this.rules, i, importRules;\n    if (!rules) { return; }\n\n    for (i = 0; i < rules.length; i++) {\n        if (rules[i].type === \"Import\") {\n            importRules = rules[i].eval(context);\n            if (importRules && (importRules.length || importRules.length === 0)) {\n                rules.splice.apply(rules, [i, 1].concat(importRules));\n                i+= importRules.length - 1;\n            } else {\n                rules.splice(i, 1, importRules);\n            }\n            this.resetCache();\n        }\n    }\n};\nRuleset.prototype.makeImportant = function() {\n    var result = new Ruleset(this.selectors, this.rules.map(function (r) {\n        if (r.makeImportant) {\n            return r.makeImportant();\n        } else {\n            return r;\n        }\n    }), this.strictImports, this.visibilityInfo());\n\n    return result;\n};\nRuleset.prototype.matchArgs = function (args) {\n    return !args || args.length === 0;\n};\n// lets you call a css selector with a guard\nRuleset.prototype.matchCondition = function (args, context) {\n    var lastSelector = this.selectors[this.selectors.length - 1];\n    if (!lastSelector.evaldCondition) {\n        return false;\n    }\n    if (lastSelector.condition &&\n        !lastSelector.condition.eval(\n            new contexts.Eval(context,\n                context.frames))) {\n        return false;\n    }\n    return true;\n};\nRuleset.prototype.resetCache = function () {\n    this._rulesets = null;\n    this._variables = null;\n    this._lookups = {};\n};\nRuleset.prototype.variables = function () {\n    if (!this._variables) {\n        this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) {\n            if (r instanceof Rule && r.variable === true) {\n                hash[r.name] = r;\n            }\n            // when evaluating variables in an import statement, imports have not been eval'd\n            // so we need to go inside import statements.\n            // guard against root being a string (in the case of inlined less)\n            if (r.type === \"Import\" && r.root && r.root.variables) {\n                var vars = r.root.variables();\n                for (var name in vars) {\n                    if (vars.hasOwnProperty(name)) {\n                        hash[name] = vars[name];\n                    }\n                }\n            }\n            return hash;\n        }, {});\n    }\n    return this._variables;\n};\nRuleset.prototype.variable = function (name) {\n    return this.variables()[name];\n};\nRuleset.prototype.rulesets = function () {\n    if (!this.rules) { return []; }\n\n    var filtRules = [], rules = this.rules, cnt = rules.length,\n        i, rule;\n\n    for (i = 0; i < cnt; i++) {\n        rule = rules[i];\n        if (rule.isRuleset) {\n            filtRules.push(rule);\n        }\n    }\n\n    return filtRules;\n};\nRuleset.prototype.prependRule = function (rule) {\n    var rules = this.rules;\n    if (rules) {\n        rules.unshift(rule);\n    } else {\n        this.rules = [ rule ];\n    }\n};\nRuleset.prototype.find = function (selector, self, filter) {\n    self = self || this;\n    var rules = [], match, foundMixins,\n        key = selector.toCSS();\n\n    if (key in this._lookups) { return this._lookups[key]; }\n\n    this.rulesets().forEach(function (rule) {\n        if (rule !== self) {\n            for (var j = 0; j < rule.selectors.length; j++) {\n                match = selector.match(rule.selectors[j]);\n                if (match) {\n                    if (selector.elements.length > match) {\n                        if (!filter || filter(rule)) {\n                            foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter);\n                            for (var i = 0; i < foundMixins.length; ++i) {\n                                foundMixins[i].path.push(rule);\n                            }\n                            Array.prototype.push.apply(rules, foundMixins);\n                        }\n                    } else {\n                        rules.push({ rule: rule, path: []});\n                    }\n                    break;\n                }\n            }\n        }\n    });\n    this._lookups[key] = rules;\n    return rules;\n};\nRuleset.prototype.genCSS = function (context, output) {\n    var i, j,\n        charsetRuleNodes = [],\n        ruleNodes = [],\n        debugInfo,     // Line number debugging\n        rule,\n        path;\n\n    context.tabLevel = (context.tabLevel || 0);\n\n    if (!this.root) {\n        context.tabLevel++;\n    }\n\n    var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(\"  \"),\n        tabSetStr = context.compress ? '' : Array(context.tabLevel).join(\"  \"),\n        sep;\n\n    function isRulesetLikeNode(rule) {\n        // if it has nested rules, then it should be treated like a ruleset\n        // medias and comments do not have nested rules, but should be treated like rulesets anyway\n        // some directives and anonymous nodes are ruleset like, others are not\n        if (typeof rule.isRulesetLike === \"boolean\") {\n            return rule.isRulesetLike;\n        } else if (typeof rule.isRulesetLike === \"function\") {\n            return rule.isRulesetLike();\n        }\n\n        //anything else is assumed to be a rule\n        return false;\n    }\n\n    var charsetNodeIndex = 0;\n    var importNodeIndex = 0;\n    for (i = 0; i < this.rules.length; i++) {\n        rule = this.rules[i];\n        if (rule.type === \"Comment\") {\n            if (importNodeIndex === i) {\n                importNodeIndex++;\n            }\n            ruleNodes.push(rule);\n        } else if (rule.isCharset && rule.isCharset()) {\n            ruleNodes.splice(charsetNodeIndex, 0, rule);\n            charsetNodeIndex++;\n            importNodeIndex++;\n        } else if (rule.type === \"Import\") {\n            ruleNodes.splice(importNodeIndex, 0, rule);\n            importNodeIndex++;\n        } else {\n            ruleNodes.push(rule);\n        }\n    }\n    ruleNodes = charsetRuleNodes.concat(ruleNodes);\n\n    // If this is the root node, we don't render\n    // a selector, or {}.\n    if (!this.root) {\n        debugInfo = getDebugInfo(context, this, tabSetStr);\n\n        if (debugInfo) {\n            output.add(debugInfo);\n            output.add(tabSetStr);\n        }\n\n        var paths = this.paths, pathCnt = paths.length,\n            pathSubCnt;\n\n        sep = context.compress ? ',' : (',\\n' + tabSetStr);\n\n        for (i = 0; i < pathCnt; i++) {\n            path = paths[i];\n            if (!(pathSubCnt = path.length)) { continue; }\n            if (i > 0) { output.add(sep); }\n\n            context.firstSelector = true;\n            path[0].genCSS(context, output);\n\n            context.firstSelector = false;\n            for (j = 1; j < pathSubCnt; j++) {\n                path[j].genCSS(context, output);\n            }\n        }\n\n        output.add((context.compress ? '{' : ' {\\n') + tabRuleStr);\n    }\n\n    // Compile rules and rulesets\n    for (i = 0; i < ruleNodes.length; i++) {\n        rule = ruleNodes[i];\n\n        if (i + 1 === ruleNodes.length) {\n            context.lastRule = true;\n        }\n\n        var currentLastRule = context.lastRule;\n        if (isRulesetLikeNode(rule)) {\n            context.lastRule = false;\n        }\n\n        if (rule.genCSS) {\n            rule.genCSS(context, output);\n        } else if (rule.value) {\n            output.add(rule.value.toString());\n        }\n\n        context.lastRule = currentLastRule;\n\n        if (!context.lastRule) {\n            output.add(context.compress ? '' : ('\\n' + tabRuleStr));\n        } else {\n            context.lastRule = false;\n        }\n    }\n\n    if (!this.root) {\n        output.add((context.compress ? '}' : '\\n' + tabSetStr + '}'));\n        context.tabLevel--;\n    }\n\n    if (!output.isEmpty() && !context.compress && this.firstRoot) {\n        output.add('\\n');\n    }\n};\n\nRuleset.prototype.joinSelectors = function (paths, context, selectors) {\n    for (var s = 0; s < selectors.length; s++) {\n        this.joinSelector(paths, context, selectors[s]);\n    }\n};\n\nRuleset.prototype.joinSelector = function (paths, context, selector) {\n\n    function createParenthesis(elementsToPak, originalElement) {\n        var replacementParen, j;\n        if (elementsToPak.length === 0) {\n            replacementParen = new Paren(elementsToPak[0]);\n        } else {\n            var insideParent = [];\n            for (j = 0; j < elementsToPak.length; j++) {\n                insideParent.push(new Element(null, elementsToPak[j], originalElement.index, originalElement.currentFileInfo));\n            }\n            replacementParen = new Paren(new Selector(insideParent));\n        }\n        return replacementParen;\n    }\n\n    function createSelector(containedElement, originalElement) {\n        var element, selector;\n        element = new Element(null, containedElement, originalElement.index, originalElement.currentFileInfo);\n        selector = new Selector([element]);\n        return selector;\n    }\n\n    // joins selector path from `beginningPath` with selector path in `addPath`\n    // `replacedElement` contains element that is being replaced by `addPath`\n    // returns concatenated path\n    function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) {\n        var newSelectorPath, lastSelector, newJoinedSelector;\n        // our new selector path\n        newSelectorPath = [];\n\n        //construct the joined selector - if & is the first thing this will be empty,\n        // if not newJoinedSelector will be the last set of elements in the selector\n        if (beginningPath.length > 0) {\n            newSelectorPath = beginningPath.slice(0);\n            lastSelector = newSelectorPath.pop();\n            newJoinedSelector = originalSelector.createDerived(lastSelector.elements.slice(0));\n        }\n        else {\n            newJoinedSelector = originalSelector.createDerived([]);\n        }\n\n        if (addPath.length > 0) {\n            // /deep/ is a combinator that is valid without anything in front of it\n            // so if the & does not have a combinator that is \"\" or \" \" then\n            // and there is a combinator on the parent, then grab that.\n            // this also allows + a { & .b { .a & { ... though not sure why you would want to do that\n            var combinator = replacedElement.combinator, parentEl = addPath[0].elements[0];\n            if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) {\n                combinator = parentEl.combinator;\n            }\n            // join the elements so far with the first part of the parent\n            newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.index, replacedElement.currentFileInfo));\n            newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1));\n        }\n\n        // now add the joined selector - but only if it is not empty\n        if (newJoinedSelector.elements.length !== 0) {\n            newSelectorPath.push(newJoinedSelector);\n        }\n\n        //put together the parent selectors after the join (e.g. the rest of the parent)\n        if (addPath.length > 1) {\n            var restOfPath = addPath.slice(1);\n            restOfPath = restOfPath.map(function (selector) {\n                return selector.createDerived(selector.elements, []);\n            });\n            newSelectorPath = newSelectorPath.concat(restOfPath);\n        }\n        return newSelectorPath;\n    }\n\n    // joins selector path from `beginningPath` with every selector path in `addPaths` array\n    // `replacedElement` contains element that is being replaced by `addPath`\n    // returns array with all concatenated paths\n    function addAllReplacementsIntoPath( beginningPath, addPaths, replacedElement, originalSelector, result) {\n        var j;\n        for (j = 0; j < beginningPath.length; j++) {\n            var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector);\n            result.push(newSelectorPath);\n        }\n        return result;\n    }\n\n    function mergeElementsOnToSelectors(elements, selectors) {\n        var i, sel;\n\n        if (elements.length === 0) {\n            return ;\n        }\n        if (selectors.length === 0) {\n            selectors.push([ new Selector(elements) ]);\n            return;\n        }\n\n        for (i = 0; i < selectors.length; i++) {\n            sel = selectors[i];\n\n            // if the previous thing in sel is a parent this needs to join on to it\n            if (sel.length > 0) {\n                sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements));\n            }\n            else {\n                sel.push(new Selector(elements));\n            }\n        }\n    }\n\n    // replace all parent selectors inside `inSelector` by content of `context` array\n    // resulting selectors are returned inside `paths` array\n    // returns true if `inSelector` contained at least one parent selector\n    function replaceParentSelector(paths, context, inSelector) {\n        // The paths are [[Selector]]\n        // The first list is a list of comma separated selectors\n        // The inner list is a list of inheritance separated selectors\n        // e.g.\n        // .a, .b {\n        //   .c {\n        //   }\n        // }\n        // == [[.a] [.c]] [[.b] [.c]]\n        //\n        var i, j, k, currentElements, newSelectors, selectorsMultiplied, sel, el, hadParentSelector = false, length, lastSelector;\n        function findNestedSelector(element) {\n            var maybeSelector;\n            if (element.value.type !== 'Paren') {\n                return null;\n            }\n\n            maybeSelector = element.value.value;\n            if (maybeSelector.type !== 'Selector') {\n                return null;\n            }\n\n            return maybeSelector;\n        }\n\n        // the elements from the current selector so far\n        currentElements = [];\n        // the current list of new selectors to add to the path.\n        // We will build it up. We initiate it with one empty selector as we \"multiply\" the new selectors\n        // by the parents\n        newSelectors = [\n            []\n        ];\n\n        for (i = 0; i < inSelector.elements.length; i++) {\n            el = inSelector.elements[i];\n            // non parent reference elements just get added\n            if (el.value !== \"&\") {\n                var nestedSelector = findNestedSelector(el);\n                if (nestedSelector != null) {\n                    // merge the current list of non parent selector elements\n                    // on to the current list of selectors to add\n                    mergeElementsOnToSelectors(currentElements, newSelectors);\n\n                    var nestedPaths = [], replaced, replacedNewSelectors = [];\n                    replaced = replaceParentSelector(nestedPaths, context, nestedSelector);\n                    hadParentSelector = hadParentSelector || replaced;\n                    //the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors\n                    for (k = 0; k < nestedPaths.length; k++) {\n                        var replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el);\n                        addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors);\n                    }\n                    newSelectors = replacedNewSelectors;\n                    currentElements = [];\n\n                } else {\n                    currentElements.push(el);\n                }\n\n            } else {\n                hadParentSelector = true;\n                // the new list of selectors to add\n                selectorsMultiplied = [];\n\n                // merge the current list of non parent selector elements\n                // on to the current list of selectors to add\n                mergeElementsOnToSelectors(currentElements, newSelectors);\n\n                // loop through our current selectors\n                for (j = 0; j < newSelectors.length; j++) {\n                    sel = newSelectors[j];\n                    // if we don't have any parent paths, the & might be in a mixin so that it can be used\n                    // whether there are parents or not\n                    if (context.length === 0) {\n                        // the combinator used on el should now be applied to the next element instead so that\n                        // it is not lost\n                        if (sel.length > 0) {\n                            sel[0].elements.push(new Element(el.combinator, '', el.index, el.currentFileInfo));\n                        }\n                        selectorsMultiplied.push(sel);\n                    }\n                    else {\n                        // and the parent selectors\n                        for (k = 0; k < context.length; k++) {\n                            // We need to put the current selectors\n                            // then join the last selector's elements on to the parents selectors\n                            var newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector);\n                            // add that to our new set of selectors\n                            selectorsMultiplied.push(newSelectorPath);\n                        }\n                    }\n                }\n\n                // our new selectors has been multiplied, so reset the state\n                newSelectors = selectorsMultiplied;\n                currentElements = [];\n            }\n        }\n\n        // if we have any elements left over (e.g. .a& .b == .b)\n        // add them on to all the current selectors\n        mergeElementsOnToSelectors(currentElements, newSelectors);\n\n        for (i = 0; i < newSelectors.length; i++) {\n            length = newSelectors[i].length;\n            if (length > 0) {\n                paths.push(newSelectors[i]);\n                lastSelector = newSelectors[i][length - 1];\n                newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList);\n                //newSelectors[i][length - 1].copyVisibilityInfo(inSelector.visibilityInfo());\n            }\n        }\n\n        return hadParentSelector;\n    }\n\n    function deriveSelector(visibilityInfo, deriveFrom) {\n        var newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition);\n        newSelector.copyVisibilityInfo(visibilityInfo);\n        return newSelector;\n    }\n\n    // joinSelector code follows\n    var i, newPaths, hadParentSelector;\n\n    newPaths = [];\n    hadParentSelector = replaceParentSelector(newPaths, context, selector);\n\n    if (!hadParentSelector) {\n        if (context.length > 0) {\n            newPaths = [];\n            for (i = 0; i < context.length; i++) {\n                //var concatenated = [];\n                //context[i].forEach(function(entry) {\n                //    var newEntry = entry.createDerived(entry.elements, entry.extendList, entry.evaldCondition);\n                //    newEntry.copyVisibilityInfo(selector.visibilityInfo());\n                //    concatenated.push(newEntry);\n                //}, this);\n                var concatenated = context[i].map(deriveSelector.bind(this, selector.visibilityInfo()));\n\n                concatenated.push(selector);\n                newPaths.push(concatenated);\n            }\n        }\n        else {\n            newPaths = [[selector]];\n        }\n    }\n\n    for (i = 0; i < newPaths.length; i++) {\n        paths.push(newPaths[i]);\n    }\n\n};\nmodule.exports = Ruleset;\n\n},{\"../contexts\":11,\"../functions/default\":20,\"../functions/function-registry\":22,\"./debug-info\":54,\"./element\":58,\"./node\":70,\"./paren\":72,\"./rule\":74,\"./selector\":77}],77:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    Element = require(\"./element\");\n\nvar Selector = function (elements, extendList, condition, index, currentFileInfo, visibilityInfo) {\n    this.elements = elements;\n    this.extendList = extendList;\n    this.condition = condition;\n    this.currentFileInfo = currentFileInfo || {};\n    if (!condition) {\n        this.evaldCondition = true;\n    }\n    this.copyVisibilityInfo(visibilityInfo);\n};\nSelector.prototype = new Node();\nSelector.prototype.type = \"Selector\";\nSelector.prototype.accept = function (visitor) {\n    if (this.elements) {\n        this.elements = visitor.visitArray(this.elements);\n    }\n    if (this.extendList) {\n        this.extendList = visitor.visitArray(this.extendList);\n    }\n    if (this.condition) {\n        this.condition = visitor.visit(this.condition);\n    }\n};\nSelector.prototype.createDerived = function(elements, extendList, evaldCondition) {\n    var info = this.visibilityInfo();\n    evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition;\n    var newSelector = new Selector(elements, extendList || this.extendList, null, this.index, this.currentFileInfo, info);\n    newSelector.evaldCondition = evaldCondition;\n    newSelector.mediaEmpty = this.mediaEmpty;\n    return newSelector;\n};\nSelector.prototype.createEmptySelectors = function() {\n    var el = new Element('', '&', this.index, this.currentFileInfo),\n        sels = [new Selector([el], null, null, this.index, this.currentFileInfo)];\n    sels[0].mediaEmpty = true;\n    return sels;\n};\nSelector.prototype.match = function (other) {\n    var elements = this.elements,\n        len = elements.length,\n        olen, i;\n\n    other.CacheElements();\n\n    olen = other._elements.length;\n    if (olen === 0 || len < olen) {\n        return 0;\n    } else {\n        for (i = 0; i < olen; i++) {\n            if (elements[i].value !== other._elements[i]) {\n                return 0;\n            }\n        }\n    }\n\n    return olen; // return number of matched elements\n};\nSelector.prototype.CacheElements = function() {\n    if (this._elements) {\n        return;\n    }\n\n    var elements = this.elements.map( function(v) {\n        return v.combinator.value + (v.value.value || v.value);\n    }).join(\"\").match(/[,&#\\*\\.\\w-]([\\w-]|(\\\\.))*/g);\n\n    if (elements) {\n        if (elements[0] === \"&\") {\n            elements.shift();\n        }\n    } else {\n        elements = [];\n    }\n\n    this._elements = elements;\n};\nSelector.prototype.isJustParentSelector = function() {\n    return !this.mediaEmpty &&\n        this.elements.length === 1 &&\n        this.elements[0].value === '&' &&\n        (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === '');\n};\nSelector.prototype.eval = function (context) {\n    var evaldCondition = this.condition && this.condition.eval(context),\n        elements = this.elements, extendList = this.extendList;\n\n    elements = elements && elements.map(function (e) { return e.eval(context); });\n    extendList = extendList && extendList.map(function(extend) { return extend.eval(context); });\n\n    return this.createDerived(elements, extendList, evaldCondition);\n};\nSelector.prototype.genCSS = function (context, output) {\n    var i, element;\n    if ((!context || !context.firstSelector) && this.elements[0].combinator.value === \"\") {\n        output.add(' ', this.currentFileInfo, this.index);\n    }\n    if (!this._css) {\n        //TODO caching? speed comparison?\n        for (i = 0; i < this.elements.length; i++) {\n            element = this.elements[i];\n            element.genCSS(context, output);\n        }\n    }\n};\nSelector.prototype.getIsOutput = function() {\n    return this.evaldCondition;\n};\nmodule.exports = Selector;\n\n},{\"./element\":58,\"./node\":70}],78:[function(require,module,exports){\nvar Node = require(\"./node\");\n\nvar UnicodeDescriptor = function (value) {\n    this.value = value;\n};\nUnicodeDescriptor.prototype = new Node();\nUnicodeDescriptor.prototype.type = \"UnicodeDescriptor\";\n\nmodule.exports = UnicodeDescriptor;\n\n},{\"./node\":70}],79:[function(require,module,exports){\nvar Node = require(\"./node\"),\n    unitConversions = require(\"../data/unit-conversions\");\n\nvar Unit = function (numerator, denominator, backupUnit) {\n    this.numerator = numerator ? numerator.slice(0).sort() : [];\n    this.denominator = denominator ? denominator.slice(0).sort() : [];\n    if (backupUnit) {\n        this.backupUnit = backupUnit;\n    } else if (numerator && numerator.length) {\n        this.backupUnit = numerator[0];\n    }\n};\n\nUnit.prototype = new Node();\nUnit.prototype.type = \"Unit\";\nUnit.prototype.clone = function () {\n    return new Unit(this.numerator.slice(0), this.denominator.slice(0), this.backupUnit);\n};\nUnit.prototype.genCSS = function (context, output) {\n    // Dimension checks the unit is singular and throws an error if in strict math mode.\n    var strictUnits = context && context.strictUnits;\n    if (this.numerator.length === 1) {\n        output.add(this.numerator[0]); // the ideal situation\n    } else if (!strictUnits && this.backupUnit) {\n        output.add(this.backupUnit);\n    } else if (!strictUnits && this.denominator.length) {\n        output.add(this.denominator[0]);\n    }\n};\nUnit.prototype.toString = function () {\n    var i, returnStr = this.numerator.join(\"*\");\n    for (i = 0; i < this.denominator.length; i++) {\n        returnStr += \"/\" + this.denominator[i];\n    }\n    return returnStr;\n};\nUnit.prototype.compare = function (other) {\n    return this.is(other.toString()) ? 0 : undefined;\n};\nUnit.prototype.is = function (unitString) {\n    return this.toString().toUpperCase() === unitString.toUpperCase();\n};\nUnit.prototype.isLength = function () {\n    return Boolean(this.toCSS().match(/px|em|%|in|cm|mm|pc|pt|ex/));\n};\nUnit.prototype.isEmpty = function () {\n    return this.numerator.length === 0 && this.denominator.length === 0;\n};\nUnit.prototype.isSingular = function() {\n    return this.numerator.length <= 1 && this.denominator.length === 0;\n};\nUnit.prototype.map = function(callback) {\n    var i;\n\n    for (i = 0; i < this.numerator.length; i++) {\n        this.numerator[i] = callback(this.numerator[i], false);\n    }\n\n    for (i = 0; i < this.denominator.length; i++) {\n        this.denominator[i] = callback(this.denominator[i], true);\n    }\n};\nUnit.prototype.usedUnits = function() {\n    var group, result = {}, mapUnit, groupName;\n\n    mapUnit = function (atomicUnit) {\n        /*jshint loopfunc:true */\n        if (group.hasOwnProperty(atomicUnit) && !result[groupName]) {\n            result[groupName] = atomicUnit;\n        }\n\n        return atomicUnit;\n    };\n\n    for (groupName in unitConversions) {\n        if (unitConversions.hasOwnProperty(groupName)) {\n            group = unitConversions[groupName];\n\n            this.map(mapUnit);\n        }\n    }\n\n    return result;\n};\nUnit.prototype.cancel = function () {\n    var counter = {}, atomicUnit, i;\n\n    for (i = 0; i < this.numerator.length; i++) {\n        atomicUnit = this.numerator[i];\n        counter[atomicUnit] = (counter[atomicUnit] || 0) + 1;\n    }\n\n    for (i = 0; i < this.denominator.length; i++) {\n        atomicUnit = this.denominator[i];\n        counter[atomicUnit] = (counter[atomicUnit] || 0) - 1;\n    }\n\n    this.numerator = [];\n    this.denominator = [];\n\n    for (atomicUnit in counter) {\n        if (counter.hasOwnProperty(atomicUnit)) {\n            var count = counter[atomicUnit];\n\n            if (count > 0) {\n                for (i = 0; i < count; i++) {\n                    this.numerator.push(atomicUnit);\n                }\n            } else if (count < 0) {\n                for (i = 0; i < -count; i++) {\n                    this.denominator.push(atomicUnit);\n                }\n            }\n        }\n    }\n\n    this.numerator.sort();\n    this.denominator.sort();\n};\nmodule.exports = Unit;\n\n},{\"../data/unit-conversions\":14,\"./node\":70}],80:[function(require,module,exports){\nvar Node = require(\"./node\");\n\nvar URL = function (val, index, currentFileInfo, isEvald) {\n    this.value = val;\n    this.currentFileInfo = currentFileInfo;\n    this.index = index;\n    this.isEvald = isEvald;\n};\nURL.prototype = new Node();\nURL.prototype.type = \"Url\";\nURL.prototype.accept = function (visitor) {\n    this.value = visitor.visit(this.value);\n};\nURL.prototype.genCSS = function (context, output) {\n    output.add(\"url(\");\n    this.value.genCSS(context, output);\n    output.add(\")\");\n};\nURL.prototype.eval = function (context) {\n    var val = this.value.eval(context),\n        rootpath;\n\n    if (!this.isEvald) {\n        // Add the base path if the URL is relative\n        rootpath = this.currentFileInfo && this.currentFileInfo.rootpath;\n        if (rootpath &&\n            typeof val.value === \"string\" &&\n            context.isPathRelative(val.value)) {\n\n            if (!val.quote) {\n                rootpath = rootpath.replace(/[\\(\\)'\"\\s]/g, function(match) { return \"\\\\\" + match; });\n            }\n            val.value = rootpath + val.value;\n        }\n\n        val.value = context.normalizePath(val.value);\n\n        // Add url args if enabled\n        if (context.urlArgs) {\n            if (!val.value.match(/^\\s*data:/)) {\n                var delimiter = val.value.indexOf('?') === -1 ? '?' : '&';\n                var urlArgs = delimiter + context.urlArgs;\n                if (val.value.indexOf('#') !== -1) {\n                    val.value = val.value.replace('#', urlArgs + '#');\n                } else {\n                    val.value += urlArgs;\n                }\n            }\n        }\n    }\n\n    return new URL(val, this.index, this.currentFileInfo, true);\n};\nmodule.exports = URL;\n\n},{\"./node\":70}],81:[function(require,module,exports){\nvar Node = require(\"./node\");\n\nvar Value = function (value) {\n    this.value = value;\n    if (!value) {\n        throw new Error(\"Value requires an array argument\");\n    }\n};\nValue.prototype = new Node();\nValue.prototype.type = \"Value\";\nValue.prototype.accept = function (visitor) {\n    if (this.value) {\n        this.value = visitor.visitArray(this.value);\n    }\n};\nValue.prototype.eval = function (context) {\n    if (this.value.length === 1) {\n        return this.value[0].eval(context);\n    } else {\n        return new Value(this.value.map(function (v) {\n            return v.eval(context);\n        }));\n    }\n};\nValue.prototype.genCSS = function (context, output) {\n    var i;\n    for (i = 0; i < this.value.length; i++) {\n        this.value[i].genCSS(context, output);\n        if (i + 1 < this.value.length) {\n            output.add((context && context.compress) ? ',' : ', ');\n        }\n    }\n};\nmodule.exports = Value;\n\n},{\"./node\":70}],82:[function(require,module,exports){\nvar Node = require(\"./node\");\n\nvar Variable = function (name, index, currentFileInfo) {\n    this.name = name;\n    this.index = index;\n    this.currentFileInfo = currentFileInfo || {};\n};\nVariable.prototype = new Node();\nVariable.prototype.type = \"Variable\";\nVariable.prototype.eval = function (context) {\n    var variable, name = this.name;\n\n    if (name.indexOf('@@') === 0) {\n        name = '@' + new Variable(name.slice(1), this.index, this.currentFileInfo).eval(context).value;\n    }\n\n    if (this.evaluating) {\n        throw { type: 'Name',\n                message: \"Recursive variable definition for \" + name,\n                filename: this.currentFileInfo.filename,\n                index: this.index };\n    }\n\n    this.evaluating = true;\n\n    variable = this.find(context.frames, function (frame) {\n        var v = frame.variable(name);\n        if (v) {\n            if (v.important) {\n                var importantScope = context.importantScope[context.importantScope.length - 1];\n                importantScope.important = v.important;\n            }\n            return v.value.eval(context);\n        }\n    });\n    if (variable) {\n        this.evaluating = false;\n        return variable;\n    } else {\n        throw { type: 'Name',\n                message: \"variable \" + name + \" is undefined\",\n                filename: this.currentFileInfo.filename,\n                index: this.index };\n    }\n};\nVariable.prototype.find = function (obj, fun) {\n    for (var i = 0, r; i < obj.length; i++) {\n        r = fun.call(obj, obj[i]);\n        if (r) { return r; }\n    }\n    return null;\n};\nmodule.exports = Variable;\n\n},{\"./node\":70}],83:[function(require,module,exports){\nmodule.exports = {\n    getLocation: function(index, inputStream) {\n        var n = index + 1,\n            line = null,\n            column = -1;\n\n        while (--n >= 0 && inputStream.charAt(n) !== '\\n') {\n            column++;\n        }\n\n        if (typeof index === 'number') {\n            line = (inputStream.slice(0, index).match(/\\n/g) || \"\").length;\n        }\n\n        return {\n            line: line,\n            column: column\n        };\n    }\n};\n\n},{}],84:[function(require,module,exports){\nvar tree = require(\"../tree\"),\n    Visitor = require(\"./visitor\"),\n    logger = require(\"../logger\");\n\n/*jshint loopfunc:true */\n\nvar ExtendFinderVisitor = function() {\n    this._visitor = new Visitor(this);\n    this.contexts = [];\n    this.allExtendsStack = [[]];\n};\n\nExtendFinderVisitor.prototype = {\n    run: function (root) {\n        root = this._visitor.visit(root);\n        root.allExtends = this.allExtendsStack[0];\n        return root;\n    },\n    visitRule: function (ruleNode, visitArgs) {\n        visitArgs.visitDeeper = false;\n    },\n    visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {\n        visitArgs.visitDeeper = false;\n    },\n    visitRuleset: function (rulesetNode, visitArgs) {\n        if (rulesetNode.root) {\n            return;\n        }\n\n        var i, j, extend, allSelectorsExtendList = [], extendList;\n\n        // get &:extend(.a); rules which apply to all selectors in this ruleset\n        var rules = rulesetNode.rules, ruleCnt = rules ? rules.length : 0;\n        for (i = 0; i < ruleCnt; i++) {\n            if (rulesetNode.rules[i] instanceof tree.Extend) {\n                allSelectorsExtendList.push(rules[i]);\n                rulesetNode.extendOnEveryPath = true;\n            }\n        }\n\n        // now find every selector and apply the extends that apply to all extends\n        // and the ones which apply to an individual extend\n        var paths = rulesetNode.paths;\n        for (i = 0; i < paths.length; i++) {\n            var selectorPath = paths[i],\n                selector = selectorPath[selectorPath.length - 1],\n                selExtendList = selector.extendList;\n\n            extendList = selExtendList ? selExtendList.slice(0).concat(allSelectorsExtendList)\n                                       : allSelectorsExtendList;\n\n            if (extendList) {\n                extendList = extendList.map(function(allSelectorsExtend) {\n                    return allSelectorsExtend.clone();\n                });\n            }\n\n            for (j = 0; j < extendList.length; j++) {\n                this.foundExtends = true;\n                extend = extendList[j];\n                extend.findSelfSelectors(selectorPath);\n                extend.ruleset = rulesetNode;\n                if (j === 0) { extend.firstExtendOnThisSelectorPath = true; }\n                this.allExtendsStack[this.allExtendsStack.length - 1].push(extend);\n            }\n        }\n\n        this.contexts.push(rulesetNode.selectors);\n    },\n    visitRulesetOut: function (rulesetNode) {\n        if (!rulesetNode.root) {\n            this.contexts.length = this.contexts.length - 1;\n        }\n    },\n    visitMedia: function (mediaNode, visitArgs) {\n        mediaNode.allExtends = [];\n        this.allExtendsStack.push(mediaNode.allExtends);\n    },\n    visitMediaOut: function (mediaNode) {\n        this.allExtendsStack.length = this.allExtendsStack.length - 1;\n    },\n    visitDirective: function (directiveNode, visitArgs) {\n        directiveNode.allExtends = [];\n        this.allExtendsStack.push(directiveNode.allExtends);\n    },\n    visitDirectiveOut: function (directiveNode) {\n        this.allExtendsStack.length = this.allExtendsStack.length - 1;\n    }\n};\n\nvar ProcessExtendsVisitor = function() {\n    this._visitor = new Visitor(this);\n};\n\nProcessExtendsVisitor.prototype = {\n    run: function(root) {\n        var extendFinder = new ExtendFinderVisitor();\n        this.extendIndices = {};\n        extendFinder.run(root);\n        if (!extendFinder.foundExtends) { return root; }\n        root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends));\n        this.allExtendsStack = [root.allExtends];\n        var newRoot = this._visitor.visit(root);\n        this.checkExtendsForNonMatched(root.allExtends);\n        return newRoot;\n    },\n    checkExtendsForNonMatched: function(extendList) {\n        var indices = this.extendIndices;\n        extendList.filter(function(extend) {\n            return !extend.hasFoundMatches && extend.parent_ids.length == 1;\n        }).forEach(function(extend) {\n                var selector = \"_unknown_\";\n                try {\n                    selector = extend.selector.toCSS({});\n                }\n                catch(_) {}\n\n                if (!indices[extend.index + ' ' + selector]) {\n                    indices[extend.index + ' ' + selector] = true;\n                    logger.warn(\"extend '\" + selector + \"' has no matches\");\n                }\n            });\n    },\n    doExtendChaining: function (extendsList, extendsListTarget, iterationCount) {\n        //\n        // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering\n        // and pasting the selector we would do normally, but we are also adding an extend with the same target selector\n        // this means this new extend can then go and alter other extends\n        //\n        // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors\n        // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already\n        // processed if we look at each selector at a time, as is done in visitRuleset\n\n        var extendIndex, targetExtendIndex, matches, extendsToAdd = [], newSelector, extendVisitor = this, selectorPath,\n            extend, targetExtend, newExtend;\n\n        iterationCount = iterationCount || 0;\n\n        //loop through comparing every extend with every target extend.\n        // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place\n        // e.g.  .a:extend(.b) {}  and .b:extend(.c) {} then the first extend extends the second one\n        // and the second is the target.\n        // the separation into two lists allows us to process a subset of chains with a bigger set, as is the\n        // case when processing media queries\n        for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) {\n            for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) {\n\n                extend = extendsList[extendIndex];\n                targetExtend = extendsListTarget[targetExtendIndex];\n\n                // look for circular references\n                if ( extend.parent_ids.indexOf( targetExtend.object_id ) >= 0 ) { continue; }\n\n                // find a match in the target extends self selector (the bit before :extend)\n                selectorPath = [targetExtend.selfSelectors[0]];\n                matches = extendVisitor.findMatch(extend, selectorPath);\n\n                if (matches.length) {\n                    extend.hasFoundMatches = true;\n\n                    // we found a match, so for each self selector..\n                    extend.selfSelectors.forEach(function(selfSelector) {\n                        var info = targetExtend.visibilityInfo();\n\n                        // process the extend as usual\n                        newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector, extend.isVisible());\n\n                        // but now we create a new extend from it\n                        newExtend = new(tree.Extend)(targetExtend.selector, targetExtend.option, 0, targetExtend.currentFileInfo, info);\n                        newExtend.selfSelectors = newSelector;\n\n                        // add the extend onto the list of extends for that selector\n                        newSelector[newSelector.length - 1].extendList = [newExtend];\n\n                        // record that we need to add it.\n                        extendsToAdd.push(newExtend);\n                        newExtend.ruleset = targetExtend.ruleset;\n\n                        //remember its parents for circular references\n                        newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids);\n\n                        // only process the selector once.. if we have :extend(.a,.b) then multiple\n                        // extends will look at the same selector path, so when extending\n                        // we know that any others will be duplicates in terms of what is added to the css\n                        if (targetExtend.firstExtendOnThisSelectorPath) {\n                            newExtend.firstExtendOnThisSelectorPath = true;\n                            targetExtend.ruleset.paths.push(newSelector);\n                        }\n                    });\n                }\n            }\n        }\n\n        if (extendsToAdd.length) {\n            // try to detect circular references to stop a stack overflow.\n            // may no longer be needed.\n            this.extendChainCount++;\n            if (iterationCount > 100) {\n                var selectorOne = \"{unable to calculate}\";\n                var selectorTwo = \"{unable to calculate}\";\n                try {\n                    selectorOne = extendsToAdd[0].selfSelectors[0].toCSS();\n                    selectorTwo = extendsToAdd[0].selector.toCSS();\n                }\n                catch(e) {}\n                throw { message: \"extend circular reference detected. One of the circular extends is currently:\" +\n                    selectorOne + \":extend(\" + selectorTwo + \")\"};\n            }\n\n            // now process the new extends on the existing rules so that we can handle a extending b extending c extending\n            // d extending e...\n            return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1));\n        } else {\n            return extendsToAdd;\n        }\n    },\n    visitRule: function (ruleNode, visitArgs) {\n        visitArgs.visitDeeper = false;\n    },\n    visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {\n        visitArgs.visitDeeper = false;\n    },\n    visitSelector: function (selectorNode, visitArgs) {\n        visitArgs.visitDeeper = false;\n    },\n    visitRuleset: function (rulesetNode, visitArgs) {\n        if (rulesetNode.root) {\n            return;\n        }\n        var matches, pathIndex, extendIndex, allExtends = this.allExtendsStack[this.allExtendsStack.length - 1],\n            selectorsToAdd = [], extendVisitor = this, selectorPath;\n\n        // look at each selector path in the ruleset, find any extend matches and then copy, find and replace\n\n        for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) {\n            for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) {\n                selectorPath = rulesetNode.paths[pathIndex];\n\n                // extending extends happens initially, before the main pass\n                if (rulesetNode.extendOnEveryPath) { continue; }\n                var extendList = selectorPath[selectorPath.length - 1].extendList;\n                if (extendList && extendList.length) { continue; }\n\n                matches = this.findMatch(allExtends[extendIndex], selectorPath);\n\n                if (matches.length) {\n                    allExtends[extendIndex].hasFoundMatches = true;\n\n                    allExtends[extendIndex].selfSelectors.forEach(function(selfSelector) {\n                        var extendedSelectors;\n                        extendedSelectors = extendVisitor.extendSelector(matches, selectorPath, selfSelector, allExtends[extendIndex].isVisible());\n                        selectorsToAdd.push(extendedSelectors);\n                    });\n                }\n            }\n        }\n        rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd);\n    },\n    findMatch: function (extend, haystackSelectorPath) {\n        //\n        // look through the haystack selector path to try and find the needle - extend.selector\n        // returns an array of selector matches that can then be replaced\n        //\n        var haystackSelectorIndex, hackstackSelector, hackstackElementIndex, haystackElement,\n            targetCombinator, i,\n            extendVisitor = this,\n            needleElements = extend.selector.elements,\n            potentialMatches = [], potentialMatch, matches = [];\n\n        // loop through the haystack elements\n        for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) {\n            hackstackSelector = haystackSelectorPath[haystackSelectorIndex];\n\n            for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) {\n\n                haystackElement = hackstackSelector.elements[hackstackElementIndex];\n\n                // if we allow elements before our match we can add a potential match every time. otherwise only at the first element.\n                if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) {\n                    potentialMatches.push({pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0,\n                        initialCombinator: haystackElement.combinator});\n                }\n\n                for (i = 0; i < potentialMatches.length; i++) {\n                    potentialMatch = potentialMatches[i];\n\n                    // selectors add \" \" onto the first element. When we use & it joins the selectors together, but if we don't\n                    // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to\n                    // work out what the resulting combinator will be\n                    targetCombinator = haystackElement.combinator.value;\n                    if (targetCombinator === '' && hackstackElementIndex === 0) {\n                        targetCombinator = ' ';\n                    }\n\n                    // if we don't match, null our match to indicate failure\n                    if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) ||\n                        (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) {\n                        potentialMatch = null;\n                    } else {\n                        potentialMatch.matched++;\n                    }\n\n                    // if we are still valid and have finished, test whether we have elements after and whether these are allowed\n                    if (potentialMatch) {\n                        potentialMatch.finished = potentialMatch.matched === needleElements.length;\n                        if (potentialMatch.finished &&\n                            (!extend.allowAfter &&\n                                (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length))) {\n                            potentialMatch = null;\n                        }\n                    }\n                    // if null we remove, if not, we are still valid, so either push as a valid match or continue\n                    if (potentialMatch) {\n                        if (potentialMatch.finished) {\n                            potentialMatch.length = needleElements.length;\n                            potentialMatch.endPathIndex = haystackSelectorIndex;\n                            potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match\n                            potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again\n                            matches.push(potentialMatch);\n                        }\n                    } else {\n                        potentialMatches.splice(i, 1);\n                        i--;\n                    }\n                }\n            }\n        }\n        return matches;\n    },\n    isElementValuesEqual: function(elementValue1, elementValue2) {\n        if (typeof elementValue1 === \"string\" || typeof elementValue2 === \"string\") {\n            return elementValue1 === elementValue2;\n        }\n        if (elementValue1 instanceof tree.Attribute) {\n            if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) {\n                return false;\n            }\n            if (!elementValue1.value || !elementValue2.value) {\n                if (elementValue1.value || elementValue2.value) {\n                    return false;\n                }\n                return true;\n            }\n            elementValue1 = elementValue1.value.value || elementValue1.value;\n            elementValue2 = elementValue2.value.value || elementValue2.value;\n            return elementValue1 === elementValue2;\n        }\n        elementValue1 = elementValue1.value;\n        elementValue2 = elementValue2.value;\n        if (elementValue1 instanceof tree.Selector) {\n            if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) {\n                return false;\n            }\n            for (var i = 0; i  < elementValue1.elements.length; i++) {\n                if (elementValue1.elements[i].combinator.value !== elementValue2.elements[i].combinator.value) {\n                    if (i !== 0 || (elementValue1.elements[i].combinator.value || ' ') !== (elementValue2.elements[i].combinator.value || ' ')) {\n                        return false;\n                    }\n                }\n                if (!this.isElementValuesEqual(elementValue1.elements[i].value, elementValue2.elements[i].value)) {\n                    return false;\n                }\n            }\n            return true;\n        }\n        return false;\n    },\n    extendSelector:function (matches, selectorPath, replacementSelector, isVisible) {\n\n        //for a set of matches, replace each match with the replacement selector\n\n        var currentSelectorPathIndex = 0,\n            currentSelectorPathElementIndex = 0,\n            path = [],\n            matchIndex,\n            selector,\n            firstElement,\n            match,\n            newElements;\n\n        for (matchIndex = 0; matchIndex < matches.length; matchIndex++) {\n            match = matches[matchIndex];\n            selector = selectorPath[match.pathIndex];\n            firstElement = new tree.Element(\n                match.initialCombinator,\n                replacementSelector.elements[0].value,\n                replacementSelector.elements[0].index,\n                replacementSelector.elements[0].currentFileInfo\n            );\n\n            if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) {\n                path[path.length - 1].elements = path[path.length - 1]\n                    .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));\n                currentSelectorPathElementIndex = 0;\n                currentSelectorPathIndex++;\n            }\n\n            newElements = selector.elements\n                .slice(currentSelectorPathElementIndex, match.index)\n                .concat([firstElement])\n                .concat(replacementSelector.elements.slice(1));\n\n            if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) {\n                path[path.length - 1].elements =\n                    path[path.length - 1].elements.concat(newElements);\n            } else {\n                path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex));\n\n                path.push(new tree.Selector(\n                    newElements\n                ));\n            }\n            currentSelectorPathIndex = match.endPathIndex;\n            currentSelectorPathElementIndex = match.endPathElementIndex;\n            if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) {\n                currentSelectorPathElementIndex = 0;\n                currentSelectorPathIndex++;\n            }\n        }\n\n        if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) {\n            path[path.length - 1].elements = path[path.length - 1]\n                .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));\n            currentSelectorPathIndex++;\n        }\n\n        path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length));\n        path = path.map(function (currentValue) {\n            // we can re-use elements here, because the visibility property matters only for selectors\n            var derived = currentValue.createDerived(currentValue.elements);\n            if (isVisible) {\n                derived.ensureVisibility();\n            } else {\n                derived.ensureInvisibility();\n            }\n            return derived;\n        });\n        return path;\n    },\n    visitMedia: function (mediaNode, visitArgs) {\n        var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);\n        newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends));\n        this.allExtendsStack.push(newAllExtends);\n    },\n    visitMediaOut: function (mediaNode) {\n        var lastIndex = this.allExtendsStack.length - 1;\n        this.allExtendsStack.length = lastIndex;\n    },\n    visitDirective: function (directiveNode, visitArgs) {\n        var newAllExtends = directiveNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);\n        newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, directiveNode.allExtends));\n        this.allExtendsStack.push(newAllExtends);\n    },\n    visitDirectiveOut: function (directiveNode) {\n        var lastIndex = this.allExtendsStack.length - 1;\n        this.allExtendsStack.length = lastIndex;\n    }\n};\n\nmodule.exports = ProcessExtendsVisitor;\n\n},{\"../logger\":33,\"../tree\":62,\"./visitor\":91}],85:[function(require,module,exports){\nfunction ImportSequencer(onSequencerEmpty) {\n    this.imports = [];\n    this.variableImports = [];\n    this._onSequencerEmpty = onSequencerEmpty;\n    this._currentDepth = 0;\n}\n\nImportSequencer.prototype.addImport = function(callback) {\n    var importSequencer = this,\n        importItem = {\n            callback: callback,\n            args: null,\n            isReady: false\n        };\n    this.imports.push(importItem);\n    return function() {\n        importItem.args = Array.prototype.slice.call(arguments, 0);\n        importItem.isReady = true;\n        importSequencer.tryRun();\n    };\n};\n\nImportSequencer.prototype.addVariableImport = function(callback) {\n    this.variableImports.push(callback);\n};\n\nImportSequencer.prototype.tryRun = function() {\n    this._currentDepth++;\n    try {\n        while (true) {\n            while (this.imports.length > 0) {\n                var importItem = this.imports[0];\n                if (!importItem.isReady) {\n                    return;\n                }\n                this.imports = this.imports.slice(1);\n                importItem.callback.apply(null, importItem.args);\n            }\n            if (this.variableImports.length === 0) {\n                break;\n            }\n            var variableImport = this.variableImports[0];\n            this.variableImports = this.variableImports.slice(1);\n            variableImport();\n        }\n    } finally {\n        this._currentDepth--;\n    }\n    if (this._currentDepth === 0 && this._onSequencerEmpty) {\n        this._onSequencerEmpty();\n    }\n};\n\nmodule.exports = ImportSequencer;\n\n},{}],86:[function(require,module,exports){\nvar contexts = require(\"../contexts\"),\n    Visitor = require(\"./visitor\"),\n    ImportSequencer = require(\"./import-sequencer\");\n\nvar ImportVisitor = function(importer, finish) {\n\n    this._visitor = new Visitor(this);\n    this._importer = importer;\n    this._finish = finish;\n    this.context = new contexts.Eval();\n    this.importCount = 0;\n    this.onceFileDetectionMap = {};\n    this.recursionDetector = {};\n    this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this));\n};\n\nImportVisitor.prototype = {\n    isReplacing: false,\n    run: function (root) {\n        try {\n            // process the contents\n            this._visitor.visit(root);\n        }\n        catch(e) {\n            this.error = e;\n        }\n\n        this.isFinished = true;\n        this._sequencer.tryRun();\n    },\n    _onSequencerEmpty: function() {\n        if (!this.isFinished) {\n            return;\n        }\n        this._finish(this.error);\n    },\n    visitImport: function (importNode, visitArgs) {\n        var inlineCSS = importNode.options.inline;\n\n        if (!importNode.css || inlineCSS) {\n\n            var context = new contexts.Eval(this.context, this.context.frames.slice(0));\n            var importParent = context.frames[0];\n\n            this.importCount++;\n            if (importNode.isVariableImport()) {\n                this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent));\n            } else {\n                this.processImportNode(importNode, context, importParent);\n            }\n        }\n        visitArgs.visitDeeper = false;\n    },\n    processImportNode: function(importNode, context, importParent) {\n        var evaldImportNode,\n            inlineCSS = importNode.options.inline;\n\n        try {\n            evaldImportNode = importNode.evalForImport(context);\n        } catch(e) {\n            if (!e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; }\n            // attempt to eval properly and treat as css\n            importNode.css = true;\n            // if that fails, this error will be thrown\n            importNode.error = e;\n        }\n\n        if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) {\n\n            if (evaldImportNode.options.multiple) {\n                context.importMultiple = true;\n            }\n\n            // try appending if we haven't determined if it is css or not\n            var tryAppendLessExtension = evaldImportNode.css === undefined;\n\n            for (var i = 0; i < importParent.rules.length; i++) {\n                if (importParent.rules[i] === importNode) {\n                    importParent.rules[i] = evaldImportNode;\n                    break;\n                }\n            }\n\n            var onImported = this.onImported.bind(this, evaldImportNode, context),\n                sequencedOnImported = this._sequencer.addImport(onImported);\n\n            this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.currentFileInfo,\n                evaldImportNode.options, sequencedOnImported);\n        } else {\n            this.importCount--;\n            if (this.isFinished) {\n                this._sequencer.tryRun();\n            }\n        }\n    },\n    onImported: function (importNode, context, e, root, importedAtRoot, fullPath) {\n        if (e) {\n            if (!e.filename) {\n                e.index = importNode.index; e.filename = importNode.currentFileInfo.filename;\n            }\n            this.error = e;\n        }\n\n        var importVisitor = this,\n            inlineCSS = importNode.options.inline,\n            isPlugin = importNode.options.plugin,\n            isOptional = importNode.options.optional,\n            duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector;\n\n        if (!context.importMultiple) {\n            if (duplicateImport) {\n                importNode.skip = true;\n            } else {\n                importNode.skip = function() {\n                    if (fullPath in importVisitor.onceFileDetectionMap) {\n                        return true;\n                    }\n                    importVisitor.onceFileDetectionMap[fullPath] = true;\n                    return false;\n                };\n            }\n        }\n\n        if (!fullPath && isOptional) {\n            importNode.skip = true;\n        }\n\n        if (root) {\n            importNode.root = root;\n            importNode.importedFilename = fullPath;\n\n            if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) {\n                importVisitor.recursionDetector[fullPath] = true;\n\n                var oldContext = this.context;\n                this.context = context;\n                try {\n                    this._visitor.visit(root);\n                } catch (e) {\n                    this.error = e;\n                }\n                this.context = oldContext;\n            }\n        }\n\n        importVisitor.importCount--;\n\n        if (importVisitor.isFinished) {\n            importVisitor._sequencer.tryRun();\n        }\n    },\n    visitRule: function (ruleNode, visitArgs) {\n        if (ruleNode.value.type === \"DetachedRuleset\") {\n            this.context.frames.unshift(ruleNode);\n        } else {\n            visitArgs.visitDeeper = false;\n        }\n    },\n    visitRuleOut : function(ruleNode) {\n        if (ruleNode.value.type === \"DetachedRuleset\") {\n            this.context.frames.shift();\n        }\n    },\n    visitDirective: function (directiveNode, visitArgs) {\n        this.context.frames.unshift(directiveNode);\n    },\n    visitDirectiveOut: function (directiveNode) {\n        this.context.frames.shift();\n    },\n    visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {\n        this.context.frames.unshift(mixinDefinitionNode);\n    },\n    visitMixinDefinitionOut: function (mixinDefinitionNode) {\n        this.context.frames.shift();\n    },\n    visitRuleset: function (rulesetNode, visitArgs) {\n        this.context.frames.unshift(rulesetNode);\n    },\n    visitRulesetOut: function (rulesetNode) {\n        this.context.frames.shift();\n    },\n    visitMedia: function (mediaNode, visitArgs) {\n        this.context.frames.unshift(mediaNode.rules[0]);\n    },\n    visitMediaOut: function (mediaNode) {\n        this.context.frames.shift();\n    }\n};\nmodule.exports = ImportVisitor;\n\n},{\"../contexts\":11,\"./import-sequencer\":85,\"./visitor\":91}],87:[function(require,module,exports){\nvar visitors = {\n    Visitor: require(\"./visitor\"),\n    ImportVisitor: require('./import-visitor'),\n    MarkVisibleSelectorsVisitor: require(\"./set-tree-visibility-visitor\"),\n    ExtendVisitor: require('./extend-visitor'),\n    JoinSelectorVisitor: require('./join-selector-visitor'),\n    ToCSSVisitor: require('./to-css-visitor')\n};\n\nmodule.exports = visitors;\n\n},{\"./extend-visitor\":84,\"./import-visitor\":86,\"./join-selector-visitor\":88,\"./set-tree-visibility-visitor\":89,\"./to-css-visitor\":90,\"./visitor\":91}],88:[function(require,module,exports){\nvar Visitor = require(\"./visitor\");\n\nvar JoinSelectorVisitor = function() {\n    this.contexts = [[]];\n    this._visitor = new Visitor(this);\n};\n\nJoinSelectorVisitor.prototype = {\n    run: function (root) {\n        return this._visitor.visit(root);\n    },\n    visitRule: function (ruleNode, visitArgs) {\n        visitArgs.visitDeeper = false;\n    },\n    visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {\n        visitArgs.visitDeeper = false;\n    },\n\n    visitRuleset: function (rulesetNode, visitArgs) {\n        var context = this.contexts[this.contexts.length - 1],\n            paths = [], selectors;\n\n        this.contexts.push(paths);\n\n        if (! rulesetNode.root) {\n            selectors = rulesetNode.selectors;\n            if (selectors) {\n                selectors = selectors.filter(function(selector) { return selector.getIsOutput(); });\n                rulesetNode.selectors = selectors.length ? selectors : (selectors = null);\n                if (selectors) { rulesetNode.joinSelectors(paths, context, selectors); }\n            }\n            if (!selectors) { rulesetNode.rules = null; }\n            rulesetNode.paths = paths;\n        }\n    },\n    visitRulesetOut: function (rulesetNode) {\n        this.contexts.length = this.contexts.length - 1;\n    },\n    visitMedia: function (mediaNode, visitArgs) {\n        var context = this.contexts[this.contexts.length - 1];\n        mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia);\n    },\n    visitDirective: function (directiveNode, visitArgs) {\n        var context = this.contexts[this.contexts.length - 1];\n        if (directiveNode.rules && directiveNode.rules.length) {\n            directiveNode.rules[0].root = (directiveNode.isRooted || context.length === 0 || null);\n        }\n    }\n};\n\nmodule.exports = JoinSelectorVisitor;\n\n},{\"./visitor\":91}],89:[function(require,module,exports){\nvar SetTreeVisibilityVisitor = function(visible) {\n    this.visible = visible;\n};\nSetTreeVisibilityVisitor.prototype.run = function(root) {\n    this.visit(root);\n};\nSetTreeVisibilityVisitor.prototype.visitArray = function(nodes) {\n    if (!nodes) {\n        return nodes;\n    }\n\n    var cnt = nodes.length, i;\n    for (i = 0; i < cnt; i++) {\n        this.visit(nodes[i]);\n    }\n    return nodes;\n};\nSetTreeVisibilityVisitor.prototype.visit = function(node) {\n    if (!node) {\n        return node;\n    }\n    if (node.constructor === Array) {\n        return this.visitArray(node);\n    }\n\n    if (!node.blocksVisibility || node.blocksVisibility()) {\n        return node;\n    }\n    if (this.visible) {\n        node.ensureVisibility();\n    } else {\n        node.ensureInvisibility();\n    }\n\n    node.accept(this);\n    return node;\n};\nmodule.exports = SetTreeVisibilityVisitor;\n},{}],90:[function(require,module,exports){\nvar tree = require(\"../tree\"),\n    Visitor = require(\"./visitor\");\n\nvar CSSVisitorUtils = function(context) {\n    this._visitor = new Visitor(this);\n    this._context = context;\n};\n\nCSSVisitorUtils.prototype = {\n    containsSilentNonBlockedChild: function(bodyRules) {\n        var rule;\n        if (bodyRules == null) {\n            return false;\n        }\n        for (var r = 0; r < bodyRules.length; r++) {\n            rule = bodyRules[r];\n            if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) {\n                //the directive contains something that was referenced (likely by extend)\n                //therefore it needs to be shown in output too\n                return true;\n            }\n        }\n        return false;\n    },\n\n    keepOnlyVisibleChilds: function(owner) {\n        if (owner == null || owner.rules == null) {\n            return ;\n        }\n\n        owner.rules = owner.rules.filter(function(thing) {\n                return thing.isVisible();\n            }\n        );\n    },\n\n    isEmpty: function(owner) {\n        if (owner == null || owner.rules == null) {\n            return true;\n        }\n        return owner.rules.length === 0;\n    },\n\n    hasVisibleSelector: function(rulesetNode) {\n        if (rulesetNode == null || rulesetNode.paths == null) {\n            return false;\n        }\n        return rulesetNode.paths.length > 0;\n    },\n\n    resolveVisibility: function (node, originalRules) {\n        if (!node.blocksVisibility()) {\n            if (this.isEmpty(node) && !this.containsSilentNonBlockedChild(originalRules)) {\n                return ;\n            }\n\n            return node;\n        }\n\n        var compiledRulesBody = node.rules[0];\n        this.keepOnlyVisibleChilds(compiledRulesBody);\n\n        if (this.isEmpty(compiledRulesBody)) {\n            return ;\n        }\n\n        node.ensureVisibility();\n        node.removeVisibilityBlock();\n\n        return node;\n    },\n\n    isVisibleRuleset: function(rulesetNode) {\n        if (rulesetNode.firstRoot) {\n            return true;\n        }\n\n        if (this.isEmpty(rulesetNode)) {\n            return false;\n        }\n\n        if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) {\n            return false;\n        }\n\n        return true;\n    }\n\n};\n\nvar ToCSSVisitor = function(context) {\n    this._visitor = new Visitor(this);\n    this._context = context;\n    this.utils = new CSSVisitorUtils(context);\n};\n\nToCSSVisitor.prototype = {\n    isReplacing: true,\n    run: function (root) {\n        return this._visitor.visit(root);\n    },\n\n    visitRule: function (ruleNode, visitArgs) {\n        if (ruleNode.blocksVisibility() || ruleNode.variable) {\n            return;\n        }\n        return ruleNode;\n    },\n\n    visitMixinDefinition: function (mixinNode, visitArgs) {\n        // mixin definitions do not get eval'd - this means they keep state\n        // so we have to clear that state here so it isn't used if toCSS is called twice\n        mixinNode.frames = [];\n    },\n\n    visitExtend: function (extendNode, visitArgs) {\n    },\n\n    visitComment: function (commentNode, visitArgs) {\n        if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) {\n            return;\n        }\n        return commentNode;\n    },\n\n    visitMedia: function(mediaNode, visitArgs) {\n        var originalRules = mediaNode.rules[0].rules;\n        mediaNode.accept(this._visitor);\n        visitArgs.visitDeeper = false;\n\n        return this.utils.resolveVisibility(mediaNode, originalRules);\n    },\n\n    visitImport: function (importNode, visitArgs) {\n        if (importNode.blocksVisibility()) {\n            return ;\n        }\n        return importNode;\n    },\n\n    visitDirective: function(directiveNode, visitArgs) {\n        if (directiveNode.rules && directiveNode.rules.length) {\n            return this.visitDirectiveWithBody(directiveNode, visitArgs);\n        } else {\n            return this.visitDirectiveWithoutBody(directiveNode, visitArgs);\n        }\n    },\n\n    visitDirectiveWithBody: function(directiveNode, visitArgs) {\n        //if there is only one nested ruleset and that one has no path, then it is\n        //just fake ruleset\n        function hasFakeRuleset(directiveNode) {\n            var bodyRules = directiveNode.rules;\n            return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0);\n        }\n        function getBodyRules(directiveNode) {\n            var nodeRules = directiveNode.rules;\n            if (hasFakeRuleset(directiveNode)) {\n                return nodeRules[0].rules;\n            }\n\n            return nodeRules;\n        }\n        //it is still true that it is only one ruleset in array\n        //this is last such moment\n        //process childs\n        var originalRules = getBodyRules(directiveNode);\n        directiveNode.accept(this._visitor);\n        visitArgs.visitDeeper = false;\n\n        if (!this.utils.isEmpty(directiveNode)) {\n            this._mergeRules(directiveNode.rules[0].rules);\n        }\n\n        return this.utils.resolveVisibility(directiveNode, originalRules);\n    },\n\n    visitDirectiveWithoutBody: function(directiveNode, visitArgs) {\n        if (directiveNode.blocksVisibility()) {\n            return;\n        }\n\n        if (directiveNode.name === \"@charset\") {\n            // Only output the debug info together with subsequent @charset definitions\n            // a comment (or @media statement) before the actual @charset directive would\n            // be considered illegal css as it has to be on the first line\n            if (this.charset) {\n                if (directiveNode.debugInfo) {\n                    var comment = new tree.Comment(\"/* \" + directiveNode.toCSS(this._context).replace(/\\n/g, \"\") + \" */\\n\");\n                    comment.debugInfo = directiveNode.debugInfo;\n                    return this._visitor.visit(comment);\n                }\n                return;\n            }\n            this.charset = true;\n        }\n\n        return directiveNode;\n    },\n\n    checkValidNodes: function(rules, isRoot) {\n        if (!rules) {\n            return;\n        }\n\n        for (var i = 0; i < rules.length; i++) {\n            var ruleNode = rules[i];\n            if (isRoot && ruleNode instanceof tree.Rule && !ruleNode.variable) {\n                throw { message: \"Properties must be inside selector blocks. They cannot be in the root\",\n                    index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename};\n            }\n            if (ruleNode instanceof tree.Call) {\n                throw { message: \"Function '\" + ruleNode.name + \"' is undefined\",\n                    index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename};\n            }\n            if (ruleNode.type && !ruleNode.allowRoot) {\n                throw { message: ruleNode.type + \" node returned by a function is not valid here\",\n                    index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename};\n            }\n        }\n    },\n\n    visitRuleset: function (rulesetNode, visitArgs) {\n        //at this point rulesets are nested into each other\n        var rule, rulesets = [];\n\n        this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot);\n\n        if (! rulesetNode.root) {\n            //remove invisible paths\n            this._compileRulesetPaths(rulesetNode);\n\n            // remove rulesets from this ruleset body and compile them separately\n            var nodeRules = rulesetNode.rules, nodeRuleCnt = nodeRules ? nodeRules.length : 0;\n            for (var i = 0; i < nodeRuleCnt; ) {\n                rule = nodeRules[i];\n                if (rule && rule.rules) {\n                    // visit because we are moving them out from being a child\n                    rulesets.push(this._visitor.visit(rule));\n                    nodeRules.splice(i, 1);\n                    nodeRuleCnt--;\n                    continue;\n                }\n                i++;\n            }\n            // accept the visitor to remove rules and refactor itself\n            // then we can decide nogw whether we want it or not\n            // compile body\n            if (nodeRuleCnt > 0) {\n                rulesetNode.accept(this._visitor);\n            } else {\n                rulesetNode.rules = null;\n            }\n            visitArgs.visitDeeper = false;\n\n        } else { //if (! rulesetNode.root) {\n            rulesetNode.accept(this._visitor);\n            visitArgs.visitDeeper = false;\n        }\n\n        if (rulesetNode.rules) {\n            this._mergeRules(rulesetNode.rules);\n            this._removeDuplicateRules(rulesetNode.rules);\n        }\n\n        //now decide whether we keep the ruleset\n        if (this.utils.isVisibleRuleset(rulesetNode)) {\n            rulesetNode.ensureVisibility();\n            rulesets.splice(0, 0, rulesetNode);\n        }\n\n        if (rulesets.length === 1) {\n            return rulesets[0];\n        }\n        return rulesets;\n    },\n\n    _compileRulesetPaths: function(rulesetNode) {\n        if (rulesetNode.paths) {\n            rulesetNode.paths = rulesetNode.paths\n                .filter(function(p) {\n                    var i;\n                    if (p[0].elements[0].combinator.value === ' ') {\n                        p[0].elements[0].combinator = new(tree.Combinator)('');\n                    }\n                    for (i = 0; i < p.length; i++) {\n                        if (p[i].isVisible() && p[i].getIsOutput()) {\n                            return true;\n                        }\n                    }\n                    return false;\n                });\n        }\n    },\n\n    _removeDuplicateRules: function(rules) {\n        if (!rules) { return; }\n\n        // remove duplicates\n        var ruleCache = {},\n            ruleList, rule, i;\n\n        for (i = rules.length - 1; i >= 0 ; i--) {\n            rule = rules[i];\n            if (rule instanceof tree.Rule) {\n                if (!ruleCache[rule.name]) {\n                    ruleCache[rule.name] = rule;\n                } else {\n                    ruleList = ruleCache[rule.name];\n                    if (ruleList instanceof tree.Rule) {\n                        ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)];\n                    }\n                    var ruleCSS = rule.toCSS(this._context);\n                    if (ruleList.indexOf(ruleCSS) !== -1) {\n                        rules.splice(i, 1);\n                    } else {\n                        ruleList.push(ruleCSS);\n                    }\n                }\n            }\n        }\n    },\n\n    _mergeRules: function (rules) {\n        if (!rules) { return; }\n\n        var groups = {},\n            parts,\n            rule,\n            key;\n\n        for (var i = 0; i < rules.length; i++) {\n            rule = rules[i];\n\n            if ((rule instanceof tree.Rule) && rule.merge) {\n                key = [rule.name,\n                    rule.important ? \"!\" : \"\"].join(\",\");\n\n                if (!groups[key]) {\n                    groups[key] = [];\n                } else {\n                    rules.splice(i--, 1);\n                }\n\n                groups[key].push(rule);\n            }\n        }\n\n        Object.keys(groups).map(function (k) {\n\n            function toExpression(values) {\n                return new (tree.Expression)(values.map(function (p) {\n                    return p.value;\n                }));\n            }\n\n            function toValue(values) {\n                return new (tree.Value)(values.map(function (p) {\n                    return p;\n                }));\n            }\n\n            parts = groups[k];\n\n            if (parts.length > 1) {\n                rule = parts[0];\n                var spacedGroups = [];\n                var lastSpacedGroup = [];\n                parts.map(function (p) {\n                    if (p.merge === \"+\") {\n                        if (lastSpacedGroup.length > 0) {\n                            spacedGroups.push(toExpression(lastSpacedGroup));\n                        }\n                        lastSpacedGroup = [];\n                    }\n                    lastSpacedGroup.push(p);\n                });\n                spacedGroups.push(toExpression(lastSpacedGroup));\n                rule.value = toValue(spacedGroups);\n            }\n        });\n    },\n\n    visitAnonymous: function(anonymousNode, visitArgs) {\n        if (anonymousNode.blocksVisibility()) {\n            return ;\n        }\n        anonymousNode.accept(this._visitor);\n        return anonymousNode;\n    }\n};\n\nmodule.exports = ToCSSVisitor;\n\n},{\"../tree\":62,\"./visitor\":91}],91:[function(require,module,exports){\nvar tree = require(\"../tree\");\n\nvar _visitArgs = { visitDeeper: true },\n    _hasIndexed = false;\n\nfunction _noop(node) {\n    return node;\n}\n\nfunction indexNodeTypes(parent, ticker) {\n    // add .typeIndex to tree node types for lookup table\n    var key, child;\n    for (key in parent) {\n        if (parent.hasOwnProperty(key)) {\n            child = parent[key];\n            switch (typeof child) {\n                case \"function\":\n                    // ignore bound functions directly on tree which do not have a prototype\n                    // or aren't nodes\n                    if (child.prototype && child.prototype.type) {\n                        child.prototype.typeIndex = ticker++;\n                    }\n                    break;\n                case \"object\":\n                    ticker = indexNodeTypes(child, ticker);\n                    break;\n            }\n        }\n    }\n    return ticker;\n}\n\nvar Visitor = function(implementation) {\n    this._implementation = implementation;\n    this._visitFnCache = [];\n\n    if (!_hasIndexed) {\n        indexNodeTypes(tree, 1);\n        _hasIndexed = true;\n    }\n};\n\nVisitor.prototype = {\n    visit: function(node) {\n        if (!node) {\n            return node;\n        }\n\n        var nodeTypeIndex = node.typeIndex;\n        if (!nodeTypeIndex) {\n            return node;\n        }\n\n        var visitFnCache = this._visitFnCache,\n            impl = this._implementation,\n            aryIndx = nodeTypeIndex << 1,\n            outAryIndex = aryIndx | 1,\n            func = visitFnCache[aryIndx],\n            funcOut = visitFnCache[outAryIndex],\n            visitArgs = _visitArgs,\n            fnName;\n\n        visitArgs.visitDeeper = true;\n\n        if (!func) {\n            fnName = \"visit\" + node.type;\n            func = impl[fnName] || _noop;\n            funcOut = impl[fnName + \"Out\"] || _noop;\n            visitFnCache[aryIndx] = func;\n            visitFnCache[outAryIndex] = funcOut;\n        }\n\n        if (func !== _noop) {\n            var newNode = func.call(impl, node, visitArgs);\n            if (impl.isReplacing) {\n                node = newNode;\n            }\n        }\n\n        if (visitArgs.visitDeeper && node && node.accept) {\n            node.accept(this);\n        }\n\n        if (funcOut != _noop) {\n            funcOut.call(impl, node);\n        }\n\n        return node;\n    },\n    visitArray: function(nodes, nonReplacing) {\n        if (!nodes) {\n            return nodes;\n        }\n\n        var cnt = nodes.length, i;\n\n        // Non-replacing\n        if (nonReplacing || !this._implementation.isReplacing) {\n            for (i = 0; i < cnt; i++) {\n                this.visit(nodes[i]);\n            }\n            return nodes;\n        }\n\n        // Replacing\n        var out = [];\n        for (i = 0; i < cnt; i++) {\n            var evald = this.visit(nodes[i]);\n            if (evald === undefined) { continue; }\n            if (!evald.splice) {\n                out.push(evald);\n            } else if (evald.length) {\n                this.flatten(evald, out);\n            }\n        }\n        return out;\n    },\n    flatten: function(arr, out) {\n        if (!out) {\n            out = [];\n        }\n\n        var cnt, i, item,\n            nestedCnt, j, nestedItem;\n\n        for (i = 0, cnt = arr.length; i < cnt; i++) {\n            item = arr[i];\n            if (item === undefined) {\n                continue;\n            }\n            if (!item.splice) {\n                out.push(item);\n                continue;\n            }\n\n            for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) {\n                nestedItem = item[j];\n                if (nestedItem === undefined) {\n                    continue;\n                }\n                if (!nestedItem.splice) {\n                    out.push(nestedItem);\n                } else if (nestedItem.length) {\n                    this.flatten(nestedItem, out);\n                }\n            }\n        }\n\n        return out;\n    }\n};\nmodule.exports = Visitor;\n\n},{\"../tree\":62}],92:[function(require,module,exports){\n\"use strict\";\n\n// rawAsap provides everything we need except exception management.\nvar rawAsap = require(\"./raw\");\n// RawTasks are recycled to reduce GC churn.\nvar freeTasks = [];\n// We queue errors to ensure they are thrown in right order (FIFO).\n// Array-as-queue is good enough here, since we are just dealing with exceptions.\nvar pendingErrors = [];\nvar requestErrorThrow = rawAsap.makeRequestCallFromTimer(throwFirstError);\n\nfunction throwFirstError() {\n    if (pendingErrors.length) {\n        throw pendingErrors.shift();\n    }\n}\n\n/**\n * Calls a task as soon as possible after returning, in its own event, with priority\n * over other events like animation, reflow, and repaint. An error thrown from an\n * event will not interrupt, nor even substantially slow down the processing of\n * other events, but will be rather postponed to a lower priority event.\n * @param {{call}} task A callable object, typically a function that takes no\n * arguments.\n */\nmodule.exports = asap;\nfunction asap(task) {\n    var rawTask;\n    if (freeTasks.length) {\n        rawTask = freeTasks.pop();\n    } else {\n        rawTask = new RawTask();\n    }\n    rawTask.task = task;\n    rawAsap(rawTask);\n}\n\n// We wrap tasks with recyclable task objects.  A task object implements\n// `call`, just like a function.\nfunction RawTask() {\n    this.task = null;\n}\n\n// The sole purpose of wrapping the task is to catch the exception and recycle\n// the task object after its single use.\nRawTask.prototype.call = function () {\n    try {\n        this.task.call();\n    } catch (error) {\n        if (asap.onerror) {\n            // This hook exists purely for testing purposes.\n            // Its name will be periodically randomized to break any code that\n            // depends on its existence.\n            asap.onerror(error);\n        } else {\n            // In a web browser, exceptions are not fatal. However, to avoid\n            // slowing down the queue of pending tasks, we rethrow the error in a\n            // lower priority turn.\n            pendingErrors.push(error);\n            requestErrorThrow();\n        }\n    } finally {\n        this.task = null;\n        freeTasks[freeTasks.length] = this;\n    }\n};\n\n},{\"./raw\":93}],93:[function(require,module,exports){\n(function (global){\n\"use strict\";\n\n// Use the fastest means possible to execute a task in its own turn, with\n// priority over other events including IO, animation, reflow, and redraw\n// events in browsers.\n//\n// An exception thrown by a task will permanently interrupt the processing of\n// subsequent tasks. The higher level `asap` function ensures that if an\n// exception is thrown by a task, that the task queue will continue flushing as\n// soon as possible, but if you use `rawAsap` directly, you are responsible to\n// either ensure that no exceptions are thrown from your task, or to manually\n// call `rawAsap.requestFlush` if an exception is thrown.\nmodule.exports = rawAsap;\nfunction rawAsap(task) {\n    if (!queue.length) {\n        requestFlush();\n        flushing = true;\n    }\n    // Equivalent to push, but avoids a function call.\n    queue[queue.length] = task;\n}\n\nvar queue = [];\n// Once a flush has been requested, no further calls to `requestFlush` are\n// necessary until the next `flush` completes.\nvar flushing = false;\n// `requestFlush` is an implementation-specific method that attempts to kick\n// off a `flush` event as quickly as possible. `flush` will attempt to exhaust\n// the event queue before yielding to the browser's own event loop.\nvar requestFlush;\n// The position of the next task to execute in the task queue. This is\n// preserved between calls to `flush` so that it can be resumed if\n// a task throws an exception.\nvar index = 0;\n// If a task schedules additional tasks recursively, the task queue can grow\n// unbounded. To prevent memory exhaustion, the task queue will periodically\n// truncate already-completed tasks.\nvar capacity = 1024;\n\n// The flush function processes all tasks that have been scheduled with\n// `rawAsap` unless and until one of those tasks throws an exception.\n// If a task throws an exception, `flush` ensures that its state will remain\n// consistent and will resume where it left off when called again.\n// However, `flush` does not make any arrangements to be called again if an\n// exception is thrown.\nfunction flush() {\n    while (index < queue.length) {\n        var currentIndex = index;\n        // Advance the index before calling the task. This ensures that we will\n        // begin flushing on the next task the task throws an error.\n        index = index + 1;\n        queue[currentIndex].call();\n        // Prevent leaking memory for long chains of recursive calls to `asap`.\n        // If we call `asap` within tasks scheduled by `asap`, the queue will\n        // grow, but to avoid an O(n) walk for every task we execute, we don't\n        // shift tasks off the queue after they have been executed.\n        // Instead, we periodically shift 1024 tasks off the queue.\n        if (index > capacity) {\n            // Manually shift all values starting at the index back to the\n            // beginning of the queue.\n            for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) {\n                queue[scan] = queue[scan + index];\n            }\n            queue.length -= index;\n            index = 0;\n        }\n    }\n    queue.length = 0;\n    index = 0;\n    flushing = false;\n}\n\n// `requestFlush` is implemented using a strategy based on data collected from\n// every available SauceLabs Selenium web driver worker at time of writing.\n// https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593\n\n// Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that\n// have WebKitMutationObserver but not un-prefixed MutationObserver.\n// Must use `global` instead of `window` to work in both frames and web\n// workers. `global` is a provision of Browserify, Mr, Mrs, or Mop.\nvar BrowserMutationObserver = global.MutationObserver || global.WebKitMutationObserver;\n\n// MutationObservers are desirable because they have high priority and work\n// reliably everywhere they are implemented.\n// They are implemented in all modern browsers.\n//\n// - Android 4-4.3\n// - Chrome 26-34\n// - Firefox 14-29\n// - Internet Explorer 11\n// - iPad Safari 6-7.1\n// - iPhone Safari 7-7.1\n// - Safari 6-7\nif (typeof BrowserMutationObserver === \"function\") {\n    requestFlush = makeRequestCallFromMutationObserver(flush);\n\n// MessageChannels are desirable because they give direct access to the HTML\n// task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera\n// 11-12, and in web workers in many engines.\n// Although message channels yield to any queued rendering and IO tasks, they\n// would be better than imposing the 4ms delay of timers.\n// However, they do not work reliably in Internet Explorer or Safari.\n\n// Internet Explorer 10 is the only browser that has setImmediate but does\n// not have MutationObservers.\n// Although setImmediate yields to the browser's renderer, it would be\n// preferrable to falling back to setTimeout since it does not have\n// the minimum 4ms penalty.\n// Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and\n// Desktop to a lesser extent) that renders both setImmediate and\n// MessageChannel useless for the purposes of ASAP.\n// https://github.com/kriskowal/q/issues/396\n\n// Timers are implemented universally.\n// We fall back to timers in workers in most engines, and in foreground\n// contexts in the following browsers.\n// However, note that even this simple case requires nuances to operate in a\n// broad spectrum of browsers.\n//\n// - Firefox 3-13\n// - Internet Explorer 6-9\n// - iPad Safari 4.3\n// - Lynx 2.8.7\n} else {\n    requestFlush = makeRequestCallFromTimer(flush);\n}\n\n// `requestFlush` requests that the high priority event queue be flushed as\n// soon as possible.\n// This is useful to prevent an error thrown in a task from stalling the event\n// queue if the exception handled by Node.js’s\n// `process.on(\"uncaughtException\")` or by a domain.\nrawAsap.requestFlush = requestFlush;\n\n// To request a high priority event, we induce a mutation observer by toggling\n// the text of a text node between \"1\" and \"-1\".\nfunction makeRequestCallFromMutationObserver(callback) {\n    var toggle = 1;\n    var observer = new BrowserMutationObserver(callback);\n    var node = document.createTextNode(\"\");\n    observer.observe(node, {characterData: true});\n    return function requestCall() {\n        toggle = -toggle;\n        node.data = toggle;\n    };\n}\n\n// The message channel technique was discovered by Malte Ubl and was the\n// original foundation for this library.\n// http://www.nonblocking.io/2011/06/windownexttick.html\n\n// Safari 6.0.5 (at least) intermittently fails to create message ports on a\n// page's first load. Thankfully, this version of Safari supports\n// MutationObservers, so we don't need to fall back in that case.\n\n// function makeRequestCallFromMessageChannel(callback) {\n//     var channel = new MessageChannel();\n//     channel.port1.onmessage = callback;\n//     return function requestCall() {\n//         channel.port2.postMessage(0);\n//     };\n// }\n\n// For reasons explained above, we are also unable to use `setImmediate`\n// under any circumstances.\n// Even if we were, there is another bug in Internet Explorer 10.\n// It is not sufficient to assign `setImmediate` to `requestFlush` because\n// `setImmediate` must be called *by name* and therefore must be wrapped in a\n// closure.\n// Never forget.\n\n// function makeRequestCallFromSetImmediate(callback) {\n//     return function requestCall() {\n//         setImmediate(callback);\n//     };\n// }\n\n// Safari 6.0 has a problem where timers will get lost while the user is\n// scrolling. This problem does not impact ASAP because Safari 6.0 supports\n// mutation observers, so that implementation is used instead.\n// However, if we ever elect to use timers in Safari, the prevalent work-around\n// is to add a scroll event listener that calls for a flush.\n\n// `setTimeout` does not call the passed callback if the delay is less than\n// approximately 7 in web workers in Firefox 8 through 18, and sometimes not\n// even then.\n\nfunction makeRequestCallFromTimer(callback) {\n    return function requestCall() {\n        // We dispatch a timeout with a specified delay of 0 for engines that\n        // can reliably accommodate that request. This will usually be snapped\n        // to a 4 milisecond delay, but once we're flushing, there's no delay\n        // between events.\n        var timeoutHandle = setTimeout(handleTimer, 0);\n        // However, since this timer gets frequently dropped in Firefox\n        // workers, we enlist an interval handle that will try to fire\n        // an event 20 times per second until it succeeds.\n        var intervalHandle = setInterval(handleTimer, 50);\n\n        function handleTimer() {\n            // Whichever timer succeeds will cancel both timers and\n            // execute the callback.\n            clearTimeout(timeoutHandle);\n            clearInterval(intervalHandle);\n            callback();\n        }\n    };\n}\n\n// This is for `asap.js` only.\n// Its name will be periodically randomized to break any code that depends on\n// its existence.\nrawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer;\n\n// ASAP was originally a nextTick shim included in Q. This was factored out\n// into this ASAP package. It was later adapted to RSVP which made further\n// amendments. These decisions, particularly to marginalize MessageChannel and\n// to capture the MutationObserver implementation in a closure, were integrated\n// back into ASAP proper.\n// https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],94:[function(require,module,exports){\n'use strict';\n\nvar asap = require('asap/raw');\n\nfunction noop() {}\n\n// States:\n//\n// 0 - pending\n// 1 - fulfilled with _value\n// 2 - rejected with _value\n// 3 - adopted the state of another promise, _value\n//\n// once the state is no longer pending (0) it is immutable\n\n// All `_` prefixed properties will be reduced to `_{random number}`\n// at build time to obfuscate them and discourage their use.\n// We don't use symbols or Object.defineProperty to fully hide them\n// because the performance isn't good enough.\n\n\n// to avoid using try/catch inside critical functions, we\n// extract them to here.\nvar LAST_ERROR = null;\nvar IS_ERROR = {};\nfunction getThen(obj) {\n  try {\n    return obj.then;\n  } catch (ex) {\n    LAST_ERROR = ex;\n    return IS_ERROR;\n  }\n}\n\nfunction tryCallOne(fn, a) {\n  try {\n    return fn(a);\n  } catch (ex) {\n    LAST_ERROR = ex;\n    return IS_ERROR;\n  }\n}\nfunction tryCallTwo(fn, a, b) {\n  try {\n    fn(a, b);\n  } catch (ex) {\n    LAST_ERROR = ex;\n    return IS_ERROR;\n  }\n}\n\nmodule.exports = Promise;\n\nfunction Promise(fn) {\n  if (typeof this !== 'object') {\n    throw new TypeError('Promises must be constructed via new');\n  }\n  if (typeof fn !== 'function') {\n    throw new TypeError('not a function');\n  }\n  this._45 = 0;\n  this._81 = 0;\n  this._65 = null;\n  this._54 = null;\n  if (fn === noop) return;\n  doResolve(fn, this);\n}\nPromise._10 = null;\nPromise._97 = null;\nPromise._61 = noop;\n\nPromise.prototype.then = function(onFulfilled, onRejected) {\n  if (this.constructor !== Promise) {\n    return safeThen(this, onFulfilled, onRejected);\n  }\n  var res = new Promise(noop);\n  handle(this, new Handler(onFulfilled, onRejected, res));\n  return res;\n};\n\nfunction safeThen(self, onFulfilled, onRejected) {\n  return new self.constructor(function (resolve, reject) {\n    var res = new Promise(noop);\n    res.then(resolve, reject);\n    handle(self, new Handler(onFulfilled, onRejected, res));\n  });\n};\nfunction handle(self, deferred) {\n  while (self._81 === 3) {\n    self = self._65;\n  }\n  if (Promise._10) {\n    Promise._10(self);\n  }\n  if (self._81 === 0) {\n    if (self._45 === 0) {\n      self._45 = 1;\n      self._54 = deferred;\n      return;\n    }\n    if (self._45 === 1) {\n      self._45 = 2;\n      self._54 = [self._54, deferred];\n      return;\n    }\n    self._54.push(deferred);\n    return;\n  }\n  handleResolved(self, deferred);\n}\n\nfunction handleResolved(self, deferred) {\n  asap(function() {\n    var cb = self._81 === 1 ? deferred.onFulfilled : deferred.onRejected;\n    if (cb === null) {\n      if (self._81 === 1) {\n        resolve(deferred.promise, self._65);\n      } else {\n        reject(deferred.promise, self._65);\n      }\n      return;\n    }\n    var ret = tryCallOne(cb, self._65);\n    if (ret === IS_ERROR) {\n      reject(deferred.promise, LAST_ERROR);\n    } else {\n      resolve(deferred.promise, ret);\n    }\n  });\n}\nfunction resolve(self, newValue) {\n  // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure\n  if (newValue === self) {\n    return reject(\n      self,\n      new TypeError('A promise cannot be resolved with itself.')\n    );\n  }\n  if (\n    newValue &&\n    (typeof newValue === 'object' || typeof newValue === 'function')\n  ) {\n    var then = getThen(newValue);\n    if (then === IS_ERROR) {\n      return reject(self, LAST_ERROR);\n    }\n    if (\n      then === self.then &&\n      newValue instanceof Promise\n    ) {\n      self._81 = 3;\n      self._65 = newValue;\n      finale(self);\n      return;\n    } else if (typeof then === 'function') {\n      doResolve(then.bind(newValue), self);\n      return;\n    }\n  }\n  self._81 = 1;\n  self._65 = newValue;\n  finale(self);\n}\n\nfunction reject(self, newValue) {\n  self._81 = 2;\n  self._65 = newValue;\n  if (Promise._97) {\n    Promise._97(self, newValue);\n  }\n  finale(self);\n}\nfunction finale(self) {\n  if (self._45 === 1) {\n    handle(self, self._54);\n    self._54 = null;\n  }\n  if (self._45 === 2) {\n    for (var i = 0; i < self._54.length; i++) {\n      handle(self, self._54[i]);\n    }\n    self._54 = null;\n  }\n}\n\nfunction Handler(onFulfilled, onRejected, promise){\n  this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;\n  this.onRejected = typeof onRejected === 'function' ? onRejected : null;\n  this.promise = promise;\n}\n\n/**\n * Take a potentially misbehaving resolver function and make sure\n * onFulfilled and onRejected are only called once.\n *\n * Makes no guarantees about asynchrony.\n */\nfunction doResolve(fn, promise) {\n  var done = false;\n  var res = tryCallTwo(fn, function (value) {\n    if (done) return;\n    done = true;\n    resolve(promise, value);\n  }, function (reason) {\n    if (done) return;\n    done = true;\n    reject(promise, reason);\n  })\n  if (!done && res === IS_ERROR) {\n    done = true;\n    reject(promise, LAST_ERROR);\n  }\n}\n\n},{\"asap/raw\":93}],95:[function(require,module,exports){\n'use strict';\n\n//This file contains the ES6 extensions to the core Promises/A+ API\n\nvar Promise = require('./core.js');\n\nmodule.exports = Promise;\n\n/* Static Functions */\n\nvar TRUE = valuePromise(true);\nvar FALSE = valuePromise(false);\nvar NULL = valuePromise(null);\nvar UNDEFINED = valuePromise(undefined);\nvar ZERO = valuePromise(0);\nvar EMPTYSTRING = valuePromise('');\n\nfunction valuePromise(value) {\n  var p = new Promise(Promise._61);\n  p._81 = 1;\n  p._65 = value;\n  return p;\n}\nPromise.resolve = function (value) {\n  if (value instanceof Promise) return value;\n\n  if (value === null) return NULL;\n  if (value === undefined) return UNDEFINED;\n  if (value === true) return TRUE;\n  if (value === false) return FALSE;\n  if (value === 0) return ZERO;\n  if (value === '') return EMPTYSTRING;\n\n  if (typeof value === 'object' || typeof value === 'function') {\n    try {\n      var then = value.then;\n      if (typeof then === 'function') {\n        return new Promise(then.bind(value));\n      }\n    } catch (ex) {\n      return new Promise(function (resolve, reject) {\n        reject(ex);\n      });\n    }\n  }\n  return valuePromise(value);\n};\n\nPromise.all = function (arr) {\n  var args = Array.prototype.slice.call(arr);\n\n  return new Promise(function (resolve, reject) {\n    if (args.length === 0) return resolve([]);\n    var remaining = args.length;\n    function res(i, val) {\n      if (val && (typeof val === 'object' || typeof val === 'function')) {\n        if (val instanceof Promise && val.then === Promise.prototype.then) {\n          while (val._81 === 3) {\n            val = val._65;\n          }\n          if (val._81 === 1) return res(i, val._65);\n          if (val._81 === 2) reject(val._65);\n          val.then(function (val) {\n            res(i, val);\n          }, reject);\n          return;\n        } else {\n          var then = val.then;\n          if (typeof then === 'function') {\n            var p = new Promise(then.bind(val));\n            p.then(function (val) {\n              res(i, val);\n            }, reject);\n            return;\n          }\n        }\n      }\n      args[i] = val;\n      if (--remaining === 0) {\n        resolve(args);\n      }\n    }\n    for (var i = 0; i < args.length; i++) {\n      res(i, args[i]);\n    }\n  });\n};\n\nPromise.reject = function (value) {\n  return new Promise(function (resolve, reject) {\n    reject(value);\n  });\n};\n\nPromise.race = function (values) {\n  return new Promise(function (resolve, reject) {\n    values.forEach(function(value){\n      Promise.resolve(value).then(resolve, reject);\n    });\n  });\n};\n\n/* Prototype Methods */\n\nPromise.prototype['catch'] = function (onRejected) {\n  return this.then(null, onRejected);\n};\n\n},{\"./core.js\":94}],96:[function(require,module,exports){\n// should work in any browser without browserify\n\nif (typeof Promise.prototype.done !== 'function') {\n  Promise.prototype.done = function (onFulfilled, onRejected) {\n    var self = arguments.length ? this.then.apply(this, arguments) : this\n    self.then(null, function (err) {\n      setTimeout(function () {\n        throw err\n      }, 0)\n    })\n  }\n}\n},{}],97:[function(require,module,exports){\n// not \"use strict\" so we can declare global \"Promise\"\n\nvar asap = require('asap');\n\nif (typeof Promise === 'undefined') {\n  Promise = require('./lib/core.js')\n  require('./lib/es6-extensions.js')\n}\n\nrequire('./polyfill-done.js');\n\n},{\"./lib/core.js\":94,\"./lib/es6-extensions.js\":95,\"./polyfill-done.js\":96,\"asap\":92}]},{},[2])(2)\n});\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(54)))\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2xlc3MvZGlzdC9sZXNzLmpzPzZkYTAiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjBEQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxhQUFhLFNBQTJELG1CQUFtQixnREFBZ0QsYUFBYSxLQUFLLE1BQU0sZ0NBQWdDLFNBQVMscUNBQXFDLFNBQVMsbUNBQW1DLE9BQU8sS0FBSyxPQUFPLGNBQWMsYUFBYSwwQkFBMEIsMEJBQTBCLGdCQUFnQixVQUFVLFVBQVUsMENBQTBDLDhCQUF3QixvQkFBb0IsOENBQThDLGtDQUFrQyxZQUFZLFlBQVksbUNBQW1DLGlCQUFpQixnQkFBZ0Isc0JBQXNCLG9CQUFvQiwwQ0FBMEMsWUFBWSxXQUFXLFlBQVksU0FBUyxHQUFHO0FBQ3h5QjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSwyQkFBMkI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLDJCQUEyQjtBQUNoRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLCtEQUErRDtBQUNsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxHQUFHO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLHNDQUFzQztBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxHQUFHO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNkJBQTZCO0FBQzdCOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxTQUFTO0FBQ3hCLHNFQUFzRSxPQUFPO0FBQzdFO0FBQ0E7QUFDQTtBQUNBLGVBQWUsbUNBQW1DO0FBQ2xEO0FBQ0E7QUFDQSxlQUFlLCtCQUErQjtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDJDQUEyQyxFQUFFO0FBQzdDO0FBQ0EscUJBQXFCOztBQUVyQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsbUJBQW1CLHdCQUF3QjtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQix3QkFBd0I7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLENBQUMsR0FBRztBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsc0JBQXNCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QyxTQUFTO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLGVBQWU7QUFDbEI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1Qjs7QUFFdkI7QUFDQSxtQkFBbUIsT0FBTztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSw0Q0FBNEM7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsOENBQThDLHVCQUF1QixFQUFFO0FBQ3ZFO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2QkFBNkIsc0JBQXNCOztBQUVuRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0Esc0JBQXNCLGVBQWU7O0FBRXJDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsMEJBQTBCLEVBQUUsVUFBVSxFQUFFO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsOEdBQThHO0FBQ2pIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLGVBQWUsUUFBUTtBQUNuRDtBQUNBO0FBQ0EsMEJBQTBCO0FBQzFCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMOztBQUVBLENBQUMsRUFBRSw2RUFBNkU7QUFDaEY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLENBQUMsRUFBRSw4Q0FBOEM7QUFDakQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkIsZ0JBQWdCO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLENBQUMsRUFBRSxlQUFlO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7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O0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDRDQUE0QztBQUMvQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLDRDQUE0QztBQUN0RTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsWUFBWTtBQUNmOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsWUFBWTtBQUNmOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsWUFBWTtBQUNmOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsWUFBWTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyx3QkFBd0IsRUFBRTtBQUNyRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsbUJBQW1CO0FBQ25CO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsc0JBQXNCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLENBQUMsRUFBRSw4Q0FBOEM7QUFDakQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsZ0NBQWdDLEVBQUU7QUFDbEM7QUFDQSxTQUFTO0FBQ1QsS0FBSztBQUNMO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixPQUFPO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQSxzREFBc0Q7QUFDdEQsd0NBQXdDO0FBQ3hDLHdDQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0Esc0RBQXNEO0FBQ3RELHdDQUF3QztBQUN4Qyx3Q0FBd0M7QUFDeEM7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLGdDQUFnQztBQUNuQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsWUFBWTtBQUNmO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDhCQUE4QjtBQUNqQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsWUFBWTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsU0FBUztBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULFVBQVUsS0FBSyxxREFBcUQ7QUFDcEU7O0FBRUE7O0FBRUEsQ0FBQyxHQUFHO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDZCQUE2QjtBQUNoQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkIsNENBQTRDO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBLGdFQUFnRTs7QUFFaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBLENBQUMsRUFBRSxtRUFBbUU7QUFDdEU7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsdUJBQXVCO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckIsbUJBQW1CLGFBQWE7QUFDaEM7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLGtCQUFrQjtBQUN4QyxLQUFLO0FBQ0wsc0JBQXNCO0FBQ3RCO0FBQ0EsbUJBQW1CLGFBQWE7QUFDaEM7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsMkNBQTJDO0FBQzlDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDJDQUEyQztBQUM5QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHVCQUF1QjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQSxDQUFDLEVBQUUsd0NBQXdDO0FBQzNDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxlQUFlLHNCQUFzQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLENBQUMsRUFBRSw0QkFBNEI7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXOztBQUVYO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsa0ZBQWtGO0FBQ3JGOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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QTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtQkFBbUIsU0FBUztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDZGQUE2RjtBQUNoRztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDhDQUE4QztBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxhQUFhO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGNBQWM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLENBQUMsR0FBRztBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CO0FBQ25CO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsMENBQTBDO0FBQzdDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLFlBQVk7QUFDZjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0Q0FBNEMsVUFBVTtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLFVBQVU7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBLENBQUMsRUFBRSxnREFBZ0Q7QUFDbkQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxzRUFBc0U7QUFDdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQkFBa0IsbUJBQW1CO0FBQ3JDLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrR0FBa0c7QUFDbEc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7O0FBRUE7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQyxFQUFFLHdDQUF3QztBQUMzQztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDRCQUE0QjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULG1CQUFtQixZQUFZO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCO0FBQ0EsMEJBQTBCLGNBQWM7QUFDeEM7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGVBQWU7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxlQUFlLGVBQWU7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZUFBZSxvQkFBb0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGVBQWUsb0JBQW9CO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0IsdUJBQXVCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQ0FBaUMsZ0NBQWdDO0FBQ2pFO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixRQUFROztBQUV6QixlQUFlLGtCQUFrQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxJQUFJO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsV0FBVzs7QUFFakM7QUFDQTs7QUFFQSxlQUFlLFNBQVM7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsK0JBQStCLDJCQUEyQjs7QUFFMUQ7QUFDQTtBQUNBLDJCQUEyQiwyQkFBMkI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyx3QkFBd0I7QUFDbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckIsb0NBQW9DLHNCQUFzQjtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxlQUFlLHVCQUF1QjtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx3QkFBd0I7QUFDeEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLG1CQUFtQixhQUFhO0FBQ2hDO0FBQ0EsOENBQThDLFVBQVU7QUFDeEQsd0JBQXdCLGlCQUFpQjs7QUFFekM7QUFDQTs7QUFFQTtBQUNBLHVCQUF1QixnQkFBZ0I7QUFDdkM7QUFDQTtBQUNBOztBQUVBLHlDQUF5QyxPQUFPO0FBQ2hEOztBQUVBO0FBQ0EsZUFBZSxzQkFBc0I7QUFDckM7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHlDQUF5Qyx5QkFBeUI7QUFDbEU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixzQkFBc0I7QUFDekM7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsdUJBQXVCLDBCQUEwQjtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDLE9BQU8sT0FBTztBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQiwwQkFBMEI7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixzQkFBc0I7QUFDekM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixnQ0FBZ0M7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQix3QkFBd0I7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUI7QUFDakI7QUFDQTs7QUFFQSxhQUFhO0FBQ2I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJCQUEyQix5QkFBeUI7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsb0JBQW9CO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CLHlCQUF5QjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLG9CQUFvQjtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CO0FBQ25COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZUFBZSxxQkFBcUI7QUFDcEM7QUFDQTs7QUFFQTtBQUNBOztBQUVBLENBQUMsRUFBRSxxS0FBcUs7QUFDeEs7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxtQkFBbUIsVUFBVTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxzREFBc0Qsd0JBQXdCLEVBQUU7QUFDaEYsZ0VBQWdFLDZCQUE2QixFQUFFOztBQUUvRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsMEJBQTBCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsMkJBQTJCO0FBQzlCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLFlBQVk7QUFDZjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQztBQUN0QyxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsNkJBQTZCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxlQUFlLDJCQUEyQjtBQUMxQztBQUNBOztBQUVBLGVBQWUsNkJBQTZCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCOztBQUUxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7O0FBRXBCLGVBQWUsMkJBQTJCO0FBQzFDO0FBQ0E7QUFDQTs7QUFFQSxlQUFlLDZCQUE2QjtBQUM1QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyQkFBMkIsV0FBVztBQUN0QztBQUNBO0FBQ0EsYUFBYTtBQUNiLDJCQUEyQixZQUFZO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLDBDQUEwQztBQUM3Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0RUFBNEUscUJBQXFCLEVBQUU7QUFDbkc7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLENBQUMsRUFBRSxZQUFZO0FBQ2Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsdUJBQXVCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLENBQUMsRUFBRSxZQUFZO0FBQ2Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsZ0JBQWdCO0FBQ3RDO0FBQ0EsZ0JBQWdCLFVBQVU7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLFlBQVk7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLENBQUMsR0FBRztBQUNKO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLDRCQUE0QjtBQUM1QjtBQUNBLG1CQUFtQixhQUFhO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGtCQUFrQjtBQUNyQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7O0FBRUEsdUJBQXVCLHVCQUF1QjtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4Qiw2Q0FBNkM7QUFDM0U7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QyxhQUFhO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLHVEQUF1RDtBQUN2RDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsaUNBQWlDLHNCQUFzQjtBQUN2RDtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsa0NBQWtDO0FBQy9ELHVDQUF1Qyw4Q0FBOEM7O0FBRXJGO0FBQ0E7O0FBRUE7QUFDQSxpRkFBaUYsVUFBVTs7QUFFM0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0Msb0JBQW9CO0FBQ3hELG9DQUFvQyxvQkFBb0I7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QjtBQUN2QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSw2QkFBNkIsaUNBQWlDO0FBQzlELCtCQUErQixzQ0FBc0M7QUFDckU7O0FBRUE7QUFDQSxvREFBb0QsVUFBVTtBQUM5RDtBQUNBLHNEQUFzRCxVQUFVOztBQUVoRTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdUNBQXVDLHFEQUFxRDtBQUM1Rjs7QUFFQSwyQ0FBMkMsMkRBQTJEOztBQUV0Rzs7QUFFQTtBQUNBO0FBQ0EsMkNBQTJDO0FBQzNDLHNFQUFzRTtBQUN0RTs7QUFFQSwyQkFBMkIsNkJBQTZCO0FBQ3hEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJGQUEyRjtBQUMzRix3REFBd0Q7QUFDeEQ7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkIsb0NBQW9DO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDRCQUE0Qiw2QkFBNkI7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSwyQ0FBMkM7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEdBQUc7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNULDhCQUE4Qiw0QkFBNEIsa0RBQWtEO0FBQzVHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsMkJBQTJCLCtCQUErQjtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQztBQUMzQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyxFQUFFLHdEQUF3RDtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSxpSkFBaUo7QUFDcEo7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlFQUFpRSwrQkFBK0IsRUFBRTtBQUNsRztBQUNBLGdDQUFnQyxzREFBc0Q7QUFDdEY7QUFDQSw2QkFBNkIsMEJBQTBCO0FBQ3ZEO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLGVBQWU7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxlQUFlLFNBQVM7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEdBQUc7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixzQkFBc0I7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsdUJBQXVCLGtCQUFrQjtBQUN6QztBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwyQkFBMkIsaUJBQWlCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7O0FBRUEsU0FBUyxPQUFPO0FBQ2hCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLGNBQWM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBLEtBQUs7O0FBRUw7QUFDQSxxQkFBcUIsUUFBUTs7QUFFN0I7QUFDQSwwQkFBMEI7QUFDMUI7O0FBRUEsa0NBQWtDLFNBQVM7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQSxxQkFBcUIsUUFBUTs7QUFFN0IsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQTs7QUFFQSx1QkFBdUIsa0JBQWtCO0FBQ3pDOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLDRCQUE0QjtBQUMvQjs7QUFFQSxrQkFBa0Isb0JBQW9CO0FBQ3RDOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLHVCQUF1QixTQUFTO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsU0FBUztBQUM1QjtBQUNBLHNDQUFzQyxVQUFVO0FBQ2hEO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxxQ0FBcUMsU0FBUztBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGdEQUFnRCxlQUFlO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsYUFBYTtBQUNoQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksTUFBTTtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsV0FBVztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGtCQUFrQjtBQUNsRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixvQkFBb0I7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLENBQUMscUlBQXFJO0FBQ3RJLENBQUMsR0FBRztBQUNKOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEscURBQXFELGNBQWM7QUFDbkU7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixxQkFBcUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsY0FBYztBQUNqQjs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixpQkFBaUI7QUFDcEM7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxDQUFDLEVBQUUsZUFBZTtBQUNsQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQSxDQUFDLEdBQUc7QUFDSjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxDQUFDLEVBQUUsa0ZBQWtGLEVBQUUsR0FBRztBQUMxRixDQUFDLEUiLCJmaWxlIjoiNC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qIVxuICogTGVzcyAtIExlYW5lciBDU1MgdjIuNy4xXG4gKiBodHRwOi8vbGVzc2Nzcy5vcmdcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMDktMjAxNiwgQWxleGlzIFNlbGxpZXIgPHNlbGZAY2xvdWRoZWFkLm5ldD5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUtMi4wIExpY2Vuc2UuXG4gKlxuICovXG5cbiAvKiogKiBAbGljZW5zZSBBcGFjaGUtMi4wXG4gKi9cblxuKGZ1bmN0aW9uKGYpe2lmKHR5cGVvZiBleHBvcnRzPT09XCJvYmplY3RcIiYmdHlwZW9mIG1vZHVsZSE9PVwidW5kZWZpbmVkXCIpe21vZHVsZS5leHBvcnRzPWYoKX1lbHNlIGlmKHR5cGVvZiBkZWZpbmU9PT1cImZ1bmN0aW9uXCImJmRlZmluZS5hbWQpe2RlZmluZShbXSxmKX1lbHNle3ZhciBnO2lmKHR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiKXtnPXdpbmRvd31lbHNlIGlmKHR5cGVvZiBnbG9iYWwhPT1cInVuZGVmaW5lZFwiKXtnPWdsb2JhbH1lbHNlIGlmKHR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIil7Zz1zZWxmfWVsc2V7Zz10aGlzfWcubGVzcyA9IGYoKX19KShmdW5jdGlvbigpe3ZhciBkZWZpbmUsbW9kdWxlLGV4cG9ydHM7cmV0dXJuIChmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pKHsxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBhZGREYXRhQXR0ciA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpLmFkZERhdGFBdHRyLFxuICAgIGJyb3dzZXIgPSByZXF1aXJlKFwiLi9icm93c2VyXCIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHdpbmRvdywgb3B0aW9ucykge1xuXG4gICAgLy8gdXNlIG9wdGlvbnMgZnJvbSB0aGUgY3VycmVudCBzY3JpcHQgdGFnIGRhdGEgYXR0cmlidWVzXG4gICAgYWRkRGF0YUF0dHIob3B0aW9ucywgYnJvd3Nlci5jdXJyZW50U2NyaXB0KHdpbmRvdykpO1xuXG4gICAgaWYgKG9wdGlvbnMuaXNGaWxlUHJvdG9jb2wgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBvcHRpb25zLmlzRmlsZVByb3RvY29sID0gL14oZmlsZXwoY2hyb21lfHNhZmFyaSkoLWV4dGVuc2lvbik/fHJlc291cmNlfHFyY3xhcHApOi8udGVzdCh3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wpO1xuICAgIH1cblxuICAgIC8vIExvYWQgc3R5bGVzIGFzeW5jaHJvbm91c2x5IChkZWZhdWx0OiBmYWxzZSlcbiAgICAvL1xuICAgIC8vIFRoaXMgaXMgc2V0IHRvIGBmYWxzZWAgYnkgZGVmYXVsdCwgc28gdGhhdCB0aGUgYm9keVxuICAgIC8vIGRvZXNuJ3Qgc3RhcnQgbG9hZGluZyBiZWZvcmUgdGhlIHN0eWxlc2hlZXRzIGFyZSBwYXJzZWQuXG4gICAgLy8gU2V0dGluZyB0aGlzIHRvIGB0cnVlYCBjYW4gcmVzdWx0IGluIGZsaWNrZXJpbmcuXG4gICAgLy9cbiAgICBvcHRpb25zLmFzeW5jID0gb3B0aW9ucy5hc3luYyB8fCBmYWxzZTtcbiAgICBvcHRpb25zLmZpbGVBc3luYyA9IG9wdGlvbnMuZmlsZUFzeW5jIHx8IGZhbHNlO1xuXG4gICAgLy8gSW50ZXJ2YWwgYmV0d2VlbiB3YXRjaCBwb2xsc1xuICAgIG9wdGlvbnMucG9sbCA9IG9wdGlvbnMucG9sbCB8fCAob3B0aW9ucy5pc0ZpbGVQcm90b2NvbCA/IDEwMDAgOiAxNTAwKTtcblxuICAgIG9wdGlvbnMuZW52ID0gb3B0aW9ucy5lbnYgfHwgKHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSA9PSAnMTI3LjAuMC4xJyB8fFxuICAgICAgICB3aW5kb3cubG9jYXRpb24uaG9zdG5hbWUgPT0gJzAuMC4wLjAnICAgfHxcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLmhvc3RuYW1lID09ICdsb2NhbGhvc3QnIHx8XG4gICAgICAgICh3aW5kb3cubG9jYXRpb24ucG9ydCAmJlxuICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLnBvcnQubGVuZ3RoID4gMCkgICAgICB8fFxuICAgICAgICBvcHRpb25zLmlzRmlsZVByb3RvY29sICAgICAgICAgICAgICAgICAgID8gJ2RldmVsb3BtZW50J1xuICAgICAgICA6ICdwcm9kdWN0aW9uJyk7XG5cbiAgICB2YXIgZHVtcExpbmVOdW1iZXJzID0gLyFkdW1wTGluZU51bWJlcnM6KGNvbW1lbnRzfG1lZGlhcXVlcnl8YWxsKS8uZXhlYyh3aW5kb3cubG9jYXRpb24uaGFzaCk7XG4gICAgaWYgKGR1bXBMaW5lTnVtYmVycykge1xuICAgICAgICBvcHRpb25zLmR1bXBMaW5lTnVtYmVycyA9IGR1bXBMaW5lTnVtYmVyc1sxXTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy51c2VGaWxlQ2FjaGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBvcHRpb25zLnVzZUZpbGVDYWNoZSA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMub25SZWFkeSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG9wdGlvbnMub25SZWFkeSA9IHRydWU7XG4gICAgfVxuXG59O1xuXG59LHtcIi4vYnJvd3NlclwiOjMsXCIuL3V0aWxzXCI6MTB9XSwyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbi8qKlxuICogS2lja3Mgb2ZmIGxlc3MgYW5kIGNvbXBpbGVzIGFueSBzdHlsZXNoZWV0c1xuICogdXNlZCBpbiB0aGUgYnJvd3NlciBkaXN0cmlidXRlZCB2ZXJzaW9uIG9mIGxlc3NcbiAqIHRvIGtpY2stc3RhcnQgbGVzcyB1c2luZyB0aGUgYnJvd3NlciBhcGlcbiAqL1xuLypnbG9iYWwgd2luZG93LCBkb2N1bWVudCAqL1xuXG4vLyBzaGltIFByb21pc2UgaWYgcmVxdWlyZWRcbnJlcXVpcmUoJ3Byb21pc2UvcG9seWZpbGwuanMnKTtcblxudmFyIG9wdGlvbnMgPSB3aW5kb3cubGVzcyB8fCB7fTtcbnJlcXVpcmUoXCIuL2FkZC1kZWZhdWx0LW9wdGlvbnNcIikod2luZG93LCBvcHRpb25zKTtcblxudmFyIGxlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL2luZGV4XCIpKHdpbmRvdywgb3B0aW9ucyk7XG5cbndpbmRvdy5sZXNzID0gbGVzcztcblxudmFyIGNzcywgaGVhZCwgc3R5bGU7XG5cbi8vIEFsd2F5cyByZXN0b3JlIHBhZ2UgdmlzaWJpbGl0eVxuZnVuY3Rpb24gcmVzb2x2ZU9yUmVqZWN0KGRhdGEpIHtcbiAgICBpZiAoZGF0YS5maWxlbmFtZSkge1xuICAgICAgICBjb25zb2xlLndhcm4oZGF0YSk7XG4gICAgfVxuICAgIGlmICghb3B0aW9ucy5hc3luYykge1xuICAgICAgICBoZWFkLnJlbW92ZUNoaWxkKHN0eWxlKTtcbiAgICB9XG59XG5cbmlmIChvcHRpb25zLm9uUmVhZHkpIHtcbiAgICBpZiAoLyF3YXRjaC8udGVzdCh3aW5kb3cubG9jYXRpb24uaGFzaCkpIHtcbiAgICAgICAgbGVzcy53YXRjaCgpO1xuICAgIH1cbiAgICAvLyBTaW11bGF0ZSBzeW5jaHJvbm91cyBzdHlsZXNoZWV0IGxvYWRpbmcgYnkgYmxvY2tpbmcgcGFnZSByZW5kZXJpbmdcbiAgICBpZiAoIW9wdGlvbnMuYXN5bmMpIHtcbiAgICAgICAgY3NzID0gJ2JvZHkgeyBkaXNwbGF5OiBub25lICFpbXBvcnRhbnQgfSc7XG4gICAgICAgIGhlYWQgPSBkb2N1bWVudC5oZWFkIHx8IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJylbMF07XG4gICAgICAgIHN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcblxuICAgICAgICBzdHlsZS50eXBlID0gJ3RleHQvY3NzJztcbiAgICAgICAgaWYgKHN0eWxlLnN0eWxlU2hlZXQpIHtcbiAgICAgICAgICAgIHN0eWxlLnN0eWxlU2hlZXQuY3NzVGV4dCA9IGNzcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0eWxlLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcykpO1xuICAgICAgICB9XG5cbiAgICAgICAgaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7XG4gICAgfVxuICAgIGxlc3MucmVnaXN0ZXJTdHlsZXNoZWV0c0ltbWVkaWF0ZWx5KCk7XG4gICAgbGVzcy5wYWdlTG9hZEZpbmlzaGVkID0gbGVzcy5yZWZyZXNoKGxlc3MuZW52ID09PSAnZGV2ZWxvcG1lbnQnKS50aGVuKHJlc29sdmVPclJlamVjdCwgcmVzb2x2ZU9yUmVqZWN0KTtcbn1cblxufSx7XCIuL2FkZC1kZWZhdWx0LW9wdGlvbnNcIjoxLFwiLi9pbmRleFwiOjgsXCJwcm9taXNlL3BvbHlmaWxsLmpzXCI6OTd9XSwzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciB1dGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpO1xubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgY3JlYXRlQ1NTOiBmdW5jdGlvbiAoZG9jdW1lbnQsIHN0eWxlcywgc2hlZXQpIHtcbiAgICAgICAgLy8gU3RyaXAgdGhlIHF1ZXJ5LXN0cmluZ1xuICAgICAgICB2YXIgaHJlZiA9IHNoZWV0LmhyZWYgfHwgJyc7XG5cbiAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gdGl0bGUgc2V0LCB1c2UgdGhlIGZpbGVuYW1lLCBtaW51cyB0aGUgZXh0ZW5zaW9uXG4gICAgICAgIHZhciBpZCA9ICdsZXNzOicgKyAoc2hlZXQudGl0bGUgfHwgdXRpbHMuZXh0cmFjdElkKGhyZWYpKTtcblxuICAgICAgICAvLyBJZiB0aGlzIGhhcyBhbHJlYWR5IGJlZW4gaW5zZXJ0ZWQgaW50byB0aGUgRE9NLCB3ZSBtYXkgbmVlZCB0byByZXBsYWNlIGl0XG4gICAgICAgIHZhciBvbGRTdHlsZU5vZGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCk7XG4gICAgICAgIHZhciBrZWVwT2xkU3R5bGVOb2RlID0gZmFsc2U7XG5cbiAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IHN0eWxlc2hlZXQgbm9kZSBmb3IgaW5zZXJ0aW9uIG9yIChpZiBuZWNlc3NhcnkpIHJlcGxhY2VtZW50XG4gICAgICAgIHZhciBzdHlsZU5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuICAgICAgICBzdHlsZU5vZGUuc2V0QXR0cmlidXRlKCd0eXBlJywgJ3RleHQvY3NzJyk7XG4gICAgICAgIGlmIChzaGVldC5tZWRpYSkge1xuICAgICAgICAgICAgc3R5bGVOb2RlLnNldEF0dHJpYnV0ZSgnbWVkaWEnLCBzaGVldC5tZWRpYSk7XG4gICAgICAgIH1cbiAgICAgICAgc3R5bGVOb2RlLmlkID0gaWQ7XG5cbiAgICAgICAgaWYgKCFzdHlsZU5vZGUuc3R5bGVTaGVldCkge1xuICAgICAgICAgICAgc3R5bGVOb2RlLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN0eWxlcykpO1xuXG4gICAgICAgICAgICAvLyBJZiBuZXcgY29udGVudHMgbWF0Y2ggY29udGVudHMgb2Ygb2xkU3R5bGVOb2RlLCBkb24ndCByZXBsYWNlIG9sZFN0eWxlTm9kZVxuICAgICAgICAgICAga2VlcE9sZFN0eWxlTm9kZSA9IChvbGRTdHlsZU5vZGUgIT09IG51bGwgJiYgb2xkU3R5bGVOb2RlLmNoaWxkTm9kZXMubGVuZ3RoID4gMCAmJiBzdHlsZU5vZGUuY2hpbGROb2Rlcy5sZW5ndGggPiAwICYmXG4gICAgICAgICAgICAgICAgb2xkU3R5bGVOb2RlLmZpcnN0Q2hpbGQubm9kZVZhbHVlID09PSBzdHlsZU5vZGUuZmlyc3RDaGlsZC5ub2RlVmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGhlYWQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdO1xuXG4gICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIG9sZFN0eWxlTm9kZSwganVzdCBhcHBlbmQ7IG90aGVyd2lzZSwgb25seSBhcHBlbmQgaWYgd2UgbmVlZFxuICAgICAgICAvLyB0byByZXBsYWNlIG9sZFN0eWxlTm9kZSB3aXRoIGFuIHVwZGF0ZWQgc3R5bGVzaGVldFxuICAgICAgICBpZiAob2xkU3R5bGVOb2RlID09PSBudWxsIHx8IGtlZXBPbGRTdHlsZU5vZGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICB2YXIgbmV4dEVsID0gc2hlZXQgJiYgc2hlZXQubmV4dFNpYmxpbmcgfHwgbnVsbDtcbiAgICAgICAgICAgIGlmIChuZXh0RWwpIHtcbiAgICAgICAgICAgICAgICBuZXh0RWwucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc3R5bGVOb2RlLCBuZXh0RWwpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBoZWFkLmFwcGVuZENoaWxkKHN0eWxlTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9sZFN0eWxlTm9kZSAmJiBrZWVwT2xkU3R5bGVOb2RlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgb2xkU3R5bGVOb2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQob2xkU3R5bGVOb2RlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZvciBJRS5cbiAgICAgICAgLy8gVGhpcyBuZWVkcyB0byBoYXBwZW4gKmFmdGVyKiB0aGUgc3R5bGUgZWxlbWVudCBpcyBhZGRlZCB0byB0aGUgRE9NLCBvdGhlcndpc2UgSUUgNyBhbmQgOCBtYXkgY3Jhc2guXG4gICAgICAgIC8vIFNlZSBodHRwOi8vc29jaWFsLm1zZG4ubWljcm9zb2Z0LmNvbS9Gb3J1bXMvZW4tVVMvN2UwODFiNjUtODc4YS00YzIyLThlNjgtYzEwZDM5YzJlZDMyL2ludGVybmV0LWV4cGxvcmVyLWNyYXNoZXMtYXBwZW5kaW5nLXN0eWxlLWVsZW1lbnQtdG8taGVhZFxuICAgICAgICBpZiAoc3R5bGVOb2RlLnN0eWxlU2hlZXQpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgc3R5bGVOb2RlLnN0eWxlU2hlZXQuY3NzVGV4dCA9IHN0eWxlcztcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZG4ndCByZWFzc2lnbiBzdHlsZVNoZWV0LmNzc1RleHQuXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcbiAgICBjdXJyZW50U2NyaXB0OiBmdW5jdGlvbih3aW5kb3cpIHtcbiAgICAgICAgdmFyIGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQuY3VycmVudFNjcmlwdCB8fCAoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB2YXIgc2NyaXB0cyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwic2NyaXB0XCIpO1xuICAgICAgICAgICAgcmV0dXJuIHNjcmlwdHNbc2NyaXB0cy5sZW5ndGggLSAxXTtcbiAgICAgICAgfSkoKTtcbiAgICB9XG59O1xuXG59LHtcIi4vdXRpbHNcIjoxMH1dLDQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuLy8gQ2FjaGUgc3lzdGVtIGlzIGEgYml0IG91dGRhdGVkIGFuZCBjb3VsZCBkbyB3aXRoIHdvcmtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih3aW5kb3csIG9wdGlvbnMsIGxvZ2dlcikge1xuICAgIHZhciBjYWNoZSA9IG51bGw7XG4gICAgaWYgKG9wdGlvbnMuZW52ICE9PSAnZGV2ZWxvcG1lbnQnKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjYWNoZSA9ICh0eXBlb2Ygd2luZG93LmxvY2FsU3RvcmFnZSA9PT0gJ3VuZGVmaW5lZCcpID8gbnVsbCA6IHdpbmRvdy5sb2NhbFN0b3JhZ2U7XG4gICAgICAgIH0gY2F0Y2ggKF8pIHt9XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHNldENTUzogZnVuY3Rpb24ocGF0aCwgbGFzdE1vZGlmaWVkLCBtb2RpZnlWYXJzLCBzdHlsZXMpIHtcbiAgICAgICAgICAgIGlmIChjYWNoZSkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdzYXZpbmcgJyArIHBhdGggKyAnIHRvIGNhY2hlLicpO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNhY2hlLnNldEl0ZW0ocGF0aCwgc3R5bGVzKTtcbiAgICAgICAgICAgICAgICAgICAgY2FjaGUuc2V0SXRlbShwYXRoICsgJzp0aW1lc3RhbXAnLCBsYXN0TW9kaWZpZWQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobW9kaWZ5VmFycykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuc2V0SXRlbShwYXRoICsgJzp2YXJzJywgSlNPTi5zdHJpbmdpZnkobW9kaWZ5VmFycykpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vVE9ETyAtIGNvdWxkIGRvIHdpdGggYWRkaW5nIG1vcmUgcm9idXN0IGVycm9yIGhhbmRsaW5nXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignZmFpbGVkIHRvIHNhdmUgXCInICsgcGF0aCArICdcIiB0byBsb2NhbCBzdG9yYWdlIGZvciBjYWNoaW5nLicpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZ2V0Q1NTOiBmdW5jdGlvbihwYXRoLCB3ZWJJbmZvLCBtb2RpZnlWYXJzKSB7XG4gICAgICAgICAgICB2YXIgY3NzICAgICAgID0gY2FjaGUgJiYgY2FjaGUuZ2V0SXRlbShwYXRoKSxcbiAgICAgICAgICAgICAgICB0aW1lc3RhbXAgPSBjYWNoZSAmJiBjYWNoZS5nZXRJdGVtKHBhdGggKyAnOnRpbWVzdGFtcCcpLFxuICAgICAgICAgICAgICAgIHZhcnMgICAgICA9IGNhY2hlICYmIGNhY2hlLmdldEl0ZW0ocGF0aCArICc6dmFycycpO1xuXG4gICAgICAgICAgICBtb2RpZnlWYXJzID0gbW9kaWZ5VmFycyB8fCB7fTtcblxuICAgICAgICAgICAgaWYgKHRpbWVzdGFtcCAmJiB3ZWJJbmZvLmxhc3RNb2RpZmllZCAmJlxuICAgICAgICAgICAgICAgIChuZXcgRGF0ZSh3ZWJJbmZvLmxhc3RNb2RpZmllZCkudmFsdWVPZigpID09PVxuICAgICAgICAgICAgICAgICAgICBuZXcgRGF0ZSh0aW1lc3RhbXApLnZhbHVlT2YoKSkgJiZcbiAgICAgICAgICAgICAgICAoIW1vZGlmeVZhcnMgJiYgIXZhcnMgfHwgSlNPTi5zdHJpbmdpZnkobW9kaWZ5VmFycykgPT09IHZhcnMpKSB7XG4gICAgICAgICAgICAgICAgLy8gVXNlIGxvY2FsIGNvcHlcbiAgICAgICAgICAgICAgICByZXR1cm4gY3NzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG5cbn0se31dLDU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIHV0aWxzID0gcmVxdWlyZShcIi4vdXRpbHNcIiksXG4gICAgYnJvd3NlciA9IHJlcXVpcmUoXCIuL2Jyb3dzZXJcIik7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24od2luZG93LCBsZXNzLCBvcHRpb25zKSB7XG5cbiAgICBmdW5jdGlvbiBlcnJvckhUTUwoZSwgcm9vdEhyZWYpIHtcbiAgICAgICAgdmFyIGlkID0gJ2xlc3MtZXJyb3ItbWVzc2FnZTonICsgdXRpbHMuZXh0cmFjdElkKHJvb3RIcmVmIHx8IFwiXCIpO1xuICAgICAgICB2YXIgdGVtcGxhdGUgPSAnPGxpPjxsYWJlbD57bGluZX08L2xhYmVsPjxwcmUgY2xhc3M9XCJ7Y2xhc3N9XCI+e2NvbnRlbnR9PC9wcmU+PC9saT4nO1xuICAgICAgICB2YXIgZWxlbSA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSwgdGltZXIsIGNvbnRlbnQsIGVycm9ycyA9IFtdO1xuICAgICAgICB2YXIgZmlsZW5hbWUgPSBlLmZpbGVuYW1lIHx8IHJvb3RIcmVmO1xuICAgICAgICB2YXIgZmlsZW5hbWVOb1BhdGggPSBmaWxlbmFtZS5tYXRjaCgvKFteXFwvXSsoXFw/LiopPykkLylbMV07XG5cbiAgICAgICAgZWxlbS5pZCAgICAgICAgPSBpZDtcbiAgICAgICAgZWxlbS5jbGFzc05hbWUgPSBcImxlc3MtZXJyb3ItbWVzc2FnZVwiO1xuXG4gICAgICAgIGNvbnRlbnQgPSAnPGgzPicgICsgKGUudHlwZSB8fCBcIlN5bnRheFwiKSArIFwiRXJyb3I6IFwiICsgKGUubWVzc2FnZSB8fCAnVGhlcmUgaXMgYW4gZXJyb3IgaW4geW91ciAubGVzcyBmaWxlJykgK1xuICAgICAgICAgICAgJzwvaDM+JyArICc8cD5pbiA8YSBocmVmPVwiJyArIGZpbGVuYW1lICAgKyAnXCI+JyArIGZpbGVuYW1lTm9QYXRoICsgXCI8L2E+IFwiO1xuXG4gICAgICAgIHZhciBlcnJvcmxpbmUgPSBmdW5jdGlvbiAoZSwgaSwgY2xhc3NuYW1lKSB7XG4gICAgICAgICAgICBpZiAoZS5leHRyYWN0W2ldICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaCh0ZW1wbGF0ZS5yZXBsYWNlKC9cXHtsaW5lXFx9LywgKHBhcnNlSW50KGUubGluZSwgMTApIHx8IDApICsgKGkgLSAxKSlcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xce2NsYXNzXFx9LywgY2xhc3NuYW1lKVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFx7Y29udGVudFxcfS8sIGUuZXh0cmFjdFtpXSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChlLmV4dHJhY3QpIHtcbiAgICAgICAgICAgIGVycm9ybGluZShlLCAwLCAnJyk7XG4gICAgICAgICAgICBlcnJvcmxpbmUoZSwgMSwgJ2xpbmUnKTtcbiAgICAgICAgICAgIGVycm9ybGluZShlLCAyLCAnJyk7XG4gICAgICAgICAgICBjb250ZW50ICs9ICdvbiBsaW5lICcgKyBlLmxpbmUgKyAnLCBjb2x1bW4gJyArIChlLmNvbHVtbiArIDEpICsgJzo8L3A+JyArXG4gICAgICAgICAgICAgICAgJzx1bD4nICsgZXJyb3JzLmpvaW4oJycpICsgJzwvdWw+JztcbiAgICAgICAgfVxuICAgICAgICBpZiAoZS5zdGFjayAmJiAoZS5leHRyYWN0IHx8IG9wdGlvbnMubG9nTGV2ZWwgPj0gNCkpIHtcbiAgICAgICAgICAgIGNvbnRlbnQgKz0gJzxici8+U3RhY2sgVHJhY2U8L2JyIC8+JyArIGUuc3RhY2suc3BsaXQoJ1xcbicpLnNsaWNlKDEpLmpvaW4oJzxici8+Jyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxlbS5pbm5lckhUTUwgPSBjb250ZW50O1xuXG4gICAgICAgIC8vIENTUyBmb3IgZXJyb3IgbWVzc2FnZXNcbiAgICAgICAgYnJvd3Nlci5jcmVhdGVDU1Mod2luZG93LmRvY3VtZW50LCBbXG4gICAgICAgICAgICAnLmxlc3MtZXJyb3ItbWVzc2FnZSB1bCwgLmxlc3MtZXJyb3ItbWVzc2FnZSBsaSB7JyxcbiAgICAgICAgICAgICdsaXN0LXN0eWxlLXR5cGU6IG5vbmU7JyxcbiAgICAgICAgICAgICdtYXJnaW4tcmlnaHQ6IDE1cHg7JyxcbiAgICAgICAgICAgICdwYWRkaW5nOiA0cHggMDsnLFxuICAgICAgICAgICAgJ21hcmdpbjogMDsnLFxuICAgICAgICAgICAgJ30nLFxuICAgICAgICAgICAgJy5sZXNzLWVycm9yLW1lc3NhZ2UgbGFiZWwgeycsXG4gICAgICAgICAgICAnZm9udC1zaXplOiAxMnB4OycsXG4gICAgICAgICAgICAnbWFyZ2luLXJpZ2h0OiAxNXB4OycsXG4gICAgICAgICAgICAncGFkZGluZzogNHB4IDA7JyxcbiAgICAgICAgICAgICdjb2xvcjogI2NjNzc3NzsnLFxuICAgICAgICAgICAgJ30nLFxuICAgICAgICAgICAgJy5sZXNzLWVycm9yLW1lc3NhZ2UgcHJlIHsnLFxuICAgICAgICAgICAgJ2NvbG9yOiAjZGQ2NjY2OycsXG4gICAgICAgICAgICAncGFkZGluZzogNHB4IDA7JyxcbiAgICAgICAgICAgICdtYXJnaW46IDA7JyxcbiAgICAgICAgICAgICdkaXNwbGF5OiBpbmxpbmUtYmxvY2s7JyxcbiAgICAgICAgICAgICd9JyxcbiAgICAgICAgICAgICcubGVzcy1lcnJvci1tZXNzYWdlIHByZS5saW5lIHsnLFxuICAgICAgICAgICAgJ2NvbG9yOiAjZmYwMDAwOycsXG4gICAgICAgICAgICAnfScsXG4gICAgICAgICAgICAnLmxlc3MtZXJyb3ItbWVzc2FnZSBoMyB7JyxcbiAgICAgICAgICAgICdmb250LXNpemU6IDIwcHg7JyxcbiAgICAgICAgICAgICdmb250LXdlaWdodDogYm9sZDsnLFxuICAgICAgICAgICAgJ3BhZGRpbmc6IDE1cHggMCA1cHggMDsnLFxuICAgICAgICAgICAgJ21hcmdpbjogMDsnLFxuICAgICAgICAgICAgJ30nLFxuICAgICAgICAgICAgJy5sZXNzLWVycm9yLW1lc3NhZ2UgYSB7JyxcbiAgICAgICAgICAgICdjb2xvcjogIzEwYScsXG4gICAgICAgICAgICAnfScsXG4gICAgICAgICAgICAnLmxlc3MtZXJyb3ItbWVzc2FnZSAuZXJyb3IgeycsXG4gICAgICAgICAgICAnY29sb3I6IHJlZDsnLFxuICAgICAgICAgICAgJ2ZvbnQtd2VpZ2h0OiBib2xkOycsXG4gICAgICAgICAgICAncGFkZGluZy1ib3R0b206IDJweDsnLFxuICAgICAgICAgICAgJ2JvcmRlci1ib3R0b206IDFweCBkYXNoZWQgcmVkOycsXG4gICAgICAgICAgICAnfSdcbiAgICAgICAgXS5qb2luKCdcXG4nKSwgeyB0aXRsZTogJ2Vycm9yLW1lc3NhZ2UnIH0pO1xuXG4gICAgICAgIGVsZW0uc3R5bGUuY3NzVGV4dCA9IFtcbiAgICAgICAgICAgIFwiZm9udC1mYW1pbHk6IEFyaWFsLCBzYW5zLXNlcmlmXCIsXG4gICAgICAgICAgICBcImJvcmRlcjogMXB4IHNvbGlkICNlMDBcIixcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvcjogI2VlZVwiLFxuICAgICAgICAgICAgXCJib3JkZXItcmFkaXVzOiA1cHhcIixcbiAgICAgICAgICAgIFwiLXdlYmtpdC1ib3JkZXItcmFkaXVzOiA1cHhcIixcbiAgICAgICAgICAgIFwiLW1vei1ib3JkZXItcmFkaXVzOiA1cHhcIixcbiAgICAgICAgICAgIFwiY29sb3I6ICNlMDBcIixcbiAgICAgICAgICAgIFwicGFkZGluZzogMTVweFwiLFxuICAgICAgICAgICAgXCJtYXJnaW4tYm90dG9tOiAxNXB4XCJcbiAgICAgICAgXS5qb2luKCc7Jyk7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuZW52ID09PSAnZGV2ZWxvcG1lbnQnKSB7XG4gICAgICAgICAgICB0aW1lciA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQsXG4gICAgICAgICAgICAgICAgICAgIGJvZHkgPSBkb2N1bWVudC5ib2R5O1xuICAgICAgICAgICAgICAgIGlmIChib2R5KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHkucmVwbGFjZUNoaWxkKGVsZW0sIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5Lmluc2VydEJlZm9yZShlbGVtLCBib2R5LmZpcnN0Q2hpbGQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGltZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIDEwKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlbW92ZUVycm9ySFRNTChwYXRoKSB7XG4gICAgICAgIHZhciBub2RlID0gd2luZG93LmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsZXNzLWVycm9yLW1lc3NhZ2U6JyArIHV0aWxzLmV4dHJhY3RJZChwYXRoKSk7XG4gICAgICAgIGlmIChub2RlKSB7XG4gICAgICAgICAgICBub2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZW1vdmVFcnJvckNvbnNvbGUocGF0aCkge1xuICAgICAgICAvL25vIGFjdGlvblxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlbW92ZUVycm9yKHBhdGgpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zLmVycm9yUmVwb3J0aW5nIHx8IG9wdGlvbnMuZXJyb3JSZXBvcnRpbmcgPT09IFwiaHRtbFwiKSB7XG4gICAgICAgICAgICByZW1vdmVFcnJvckhUTUwocGF0aCk7XG4gICAgICAgIH0gZWxzZSBpZiAob3B0aW9ucy5lcnJvclJlcG9ydGluZyA9PT0gXCJjb25zb2xlXCIpIHtcbiAgICAgICAgICAgIHJlbW92ZUVycm9yQ29uc29sZShwYXRoKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygb3B0aW9ucy5lcnJvclJlcG9ydGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgb3B0aW9ucy5lcnJvclJlcG9ydGluZyhcInJlbW92ZVwiLCBwYXRoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGVycm9yQ29uc29sZShlLCByb290SHJlZikge1xuICAgICAgICB2YXIgdGVtcGxhdGUgPSAne2xpbmV9IHtjb250ZW50fSc7XG4gICAgICAgIHZhciBmaWxlbmFtZSA9IGUuZmlsZW5hbWUgfHwgcm9vdEhyZWY7XG4gICAgICAgIHZhciBlcnJvcnMgPSBbXTtcbiAgICAgICAgdmFyIGNvbnRlbnQgPSAoZS50eXBlIHx8IFwiU3ludGF4XCIpICsgXCJFcnJvcjogXCIgKyAoZS5tZXNzYWdlIHx8ICdUaGVyZSBpcyBhbiBlcnJvciBpbiB5b3VyIC5sZXNzIGZpbGUnKSArXG4gICAgICAgICAgICBcIiBpbiBcIiArIGZpbGVuYW1lICsgXCIgXCI7XG5cbiAgICAgICAgdmFyIGVycm9ybGluZSA9IGZ1bmN0aW9uIChlLCBpLCBjbGFzc25hbWUpIHtcbiAgICAgICAgICAgIGlmIChlLmV4dHJhY3RbaV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGVycm9ycy5wdXNoKHRlbXBsYXRlLnJlcGxhY2UoL1xce2xpbmVcXH0vLCAocGFyc2VJbnQoZS5saW5lLCAxMCkgfHwgMCkgKyAoaSAtIDEpKVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFx7Y2xhc3NcXH0vLCBjbGFzc25hbWUpXG4gICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXHtjb250ZW50XFx9LywgZS5leHRyYWN0W2ldKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGUuZXh0cmFjdCkge1xuICAgICAgICAgICAgZXJyb3JsaW5lKGUsIDAsICcnKTtcbiAgICAgICAgICAgIGVycm9ybGluZShlLCAxLCAnbGluZScpO1xuICAgICAgICAgICAgZXJyb3JsaW5lKGUsIDIsICcnKTtcbiAgICAgICAgICAgIGNvbnRlbnQgKz0gJ29uIGxpbmUgJyArIGUubGluZSArICcsIGNvbHVtbiAnICsgKGUuY29sdW1uICsgMSkgKyAnOlxcbicgK1xuICAgICAgICAgICAgICAgIGVycm9ycy5qb2luKCdcXG4nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZS5zdGFjayAmJiAoZS5leHRyYWN0IHx8IG9wdGlvbnMubG9nTGV2ZWwgPj0gNCkpIHtcbiAgICAgICAgICAgIGNvbnRlbnQgKz0gJ1xcblN0YWNrIFRyYWNlXFxuJyArIGUuc3RhY2s7XG4gICAgICAgIH1cbiAgICAgICAgbGVzcy5sb2dnZXIuZXJyb3IoY29udGVudCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXJyb3IoZSwgcm9vdEhyZWYpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zLmVycm9yUmVwb3J0aW5nIHx8IG9wdGlvbnMuZXJyb3JSZXBvcnRpbmcgPT09IFwiaHRtbFwiKSB7XG4gICAgICAgICAgICBlcnJvckhUTUwoZSwgcm9vdEhyZWYpO1xuICAgICAgICB9IGVsc2UgaWYgKG9wdGlvbnMuZXJyb3JSZXBvcnRpbmcgPT09IFwiY29uc29sZVwiKSB7XG4gICAgICAgICAgICBlcnJvckNvbnNvbGUoZSwgcm9vdEhyZWYpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvcHRpb25zLmVycm9yUmVwb3J0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBvcHRpb25zLmVycm9yUmVwb3J0aW5nKFwiYWRkXCIsIGUsIHJvb3RIcmVmKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIGFkZDogZXJyb3IsXG4gICAgICAgIHJlbW92ZTogcmVtb3ZlRXJyb3JcbiAgICB9O1xufTtcblxufSx7XCIuL2Jyb3dzZXJcIjozLFwiLi91dGlsc1wiOjEwfV0sNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4vKmdsb2JhbCB3aW5kb3csIFhNTEh0dHBSZXF1ZXN0ICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ob3B0aW9ucywgbG9nZ2VyKSB7XG5cbiAgICB2YXIgQWJzdHJhY3RGaWxlTWFuYWdlciA9IHJlcXVpcmUoXCIuLi9sZXNzL2Vudmlyb25tZW50L2Fic3RyYWN0LWZpbGUtbWFuYWdlci5qc1wiKTtcblxuICAgIHZhciBmaWxlQ2FjaGUgPSB7fTtcblxuICAgIC8vVE9ET1MgLSBtb3ZlIGxvZyBzb21ld2hlcmUuIHBhdGhEaWZmIGFuZCBkb2luZyBzb21ldGhpbmcgc2ltaWxhciBpbiBub2RlLiB1c2UgcGF0aERpZmYgaW4gdGhlIG90aGVyIGJyb3dzZXIgZmlsZSBmb3IgdGhlIGluaXRpYWwgbG9hZFxuXG4gICAgZnVuY3Rpb24gZ2V0WE1MSHR0cFJlcXVlc3QoKSB7XG4gICAgICAgIGlmICh3aW5kb3cuWE1MSHR0cFJlcXVlc3QgJiYgKHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCAhPT0gXCJmaWxlOlwiIHx8ICEoXCJBY3RpdmVYT2JqZWN0XCIgaW4gd2luZG93KSkpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLypnbG9iYWwgQWN0aXZlWE9iamVjdCAqL1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQWN0aXZlWE9iamVjdChcIk1pY3Jvc29mdC5YTUxIVFRQXCIpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcImJyb3dzZXIgZG9lc24ndCBzdXBwb3J0IEFKQVguXCIpO1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIEZpbGVNYW5hZ2VyID0gZnVuY3Rpb24oKSB7XG4gICAgfTtcblxuICAgIEZpbGVNYW5hZ2VyLnByb3RvdHlwZSA9IG5ldyBBYnN0cmFjdEZpbGVNYW5hZ2VyKCk7XG5cbiAgICBGaWxlTWFuYWdlci5wcm90b3R5cGUuYWx3YXlzTWFrZVBhdGhzQWJzb2x1dGUgPSBmdW5jdGlvbiBhbHdheXNNYWtlUGF0aHNBYnNvbHV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbiAgICBGaWxlTWFuYWdlci5wcm90b3R5cGUuam9pbiA9IGZ1bmN0aW9uIGpvaW4oYmFzZVBhdGgsIGxhdGVyUGF0aCkge1xuICAgICAgICBpZiAoIWJhc2VQYXRoKSB7XG4gICAgICAgICAgICByZXR1cm4gbGF0ZXJQYXRoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmV4dHJhY3RVcmxQYXJ0cyhsYXRlclBhdGgsIGJhc2VQYXRoKS5wYXRoO1xuICAgIH07XG4gICAgRmlsZU1hbmFnZXIucHJvdG90eXBlLmRvWEhSID0gZnVuY3Rpb24gZG9YSFIodXJsLCB0eXBlLCBjYWxsYmFjaywgZXJyYmFjaykge1xuXG4gICAgICAgIHZhciB4aHIgPSBnZXRYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICB2YXIgYXN5bmMgPSBvcHRpb25zLmlzRmlsZVByb3RvY29sID8gb3B0aW9ucy5maWxlQXN5bmMgOiB0cnVlO1xuXG4gICAgICAgIGlmICh0eXBlb2YgeGhyLm92ZXJyaWRlTWltZVR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHhoci5vdmVycmlkZU1pbWVUeXBlKCd0ZXh0L2NzcycpO1xuICAgICAgICB9XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhcIlhIUjogR2V0dGluZyAnXCIgKyB1cmwgKyBcIidcIik7XG4gICAgICAgIHhoci5vcGVuKCdHRVQnLCB1cmwsIGFzeW5jKTtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0FjY2VwdCcsIHR5cGUgfHwgJ3RleHQveC1sZXNzLCB0ZXh0L2NzczsgcT0wLjksICovKjsgcT0wLjUnKTtcbiAgICAgICAgeGhyLnNlbmQobnVsbCk7XG5cbiAgICAgICAgZnVuY3Rpb24gaGFuZGxlUmVzcG9uc2UoeGhyLCBjYWxsYmFjaywgZXJyYmFjaykge1xuICAgICAgICAgICAgaWYgKHhoci5zdGF0dXMgPj0gMjAwICYmIHhoci5zdGF0dXMgPCAzMDApIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayh4aHIucmVzcG9uc2VUZXh0LFxuICAgICAgICAgICAgICAgICAgICB4aHIuZ2V0UmVzcG9uc2VIZWFkZXIoXCJMYXN0LU1vZGlmaWVkXCIpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGVycmJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBlcnJiYWNrKHhoci5zdGF0dXMsIHVybCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy5pc0ZpbGVQcm90b2NvbCAmJiAhb3B0aW9ucy5maWxlQXN5bmMpIHtcbiAgICAgICAgICAgIGlmICh4aHIuc3RhdHVzID09PSAwIHx8ICh4aHIuc3RhdHVzID49IDIwMCAmJiB4aHIuc3RhdHVzIDwgMzAwKSkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHhoci5yZXNwb25zZVRleHQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBlcnJiYWNrKHhoci5zdGF0dXMsIHVybCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoYXN5bmMpIHtcbiAgICAgICAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHhoci5yZWFkeVN0YXRlID09IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlUmVzcG9uc2UoeGhyLCBjYWxsYmFjaywgZXJyYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGhhbmRsZVJlc3BvbnNlKHhociwgY2FsbGJhY2ssIGVycmJhY2spO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBGaWxlTWFuYWdlci5wcm90b3R5cGUuc3VwcG9ydHMgPSBmdW5jdGlvbihmaWxlbmFtZSwgY3VycmVudERpcmVjdG9yeSwgb3B0aW9ucywgZW52aXJvbm1lbnQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIEZpbGVNYW5hZ2VyLnByb3RvdHlwZS5jbGVhckZpbGVDYWNoZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBmaWxlQ2FjaGUgPSB7fTtcbiAgICB9O1xuXG4gICAgRmlsZU1hbmFnZXIucHJvdG90eXBlLmxvYWRGaWxlID0gZnVuY3Rpb24gbG9hZEZpbGUoZmlsZW5hbWUsIGN1cnJlbnREaXJlY3RvcnksIG9wdGlvbnMsIGVudmlyb25tZW50LCBjYWxsYmFjaykge1xuICAgICAgICBpZiAoY3VycmVudERpcmVjdG9yeSAmJiAhdGhpcy5pc1BhdGhBYnNvbHV0ZShmaWxlbmFtZSkpIHtcbiAgICAgICAgICAgIGZpbGVuYW1lID0gY3VycmVudERpcmVjdG9yeSArIGZpbGVuYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICAgICAgLy8gc2hlZXQgbWF5IGJlIHNldCB0byB0aGUgc3R5bGVzaGVldCBmb3IgdGhlIGluaXRpYWwgbG9hZCBvciBhIGNvbGxlY3Rpb24gb2YgcHJvcGVydGllcyBpbmNsdWRpbmdcbiAgICAgICAgLy8gc29tZSBjb250ZXh0IHZhcmlhYmxlcyBmb3IgaW1wb3J0c1xuICAgICAgICB2YXIgaHJlZlBhcnRzID0gdGhpcy5leHRyYWN0VXJsUGFydHMoZmlsZW5hbWUsIHdpbmRvdy5sb2NhdGlvbi5ocmVmKTtcbiAgICAgICAgdmFyIGhyZWYgICAgICA9IGhyZWZQYXJ0cy51cmw7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMudXNlRmlsZUNhY2hlICYmIGZpbGVDYWNoZVtocmVmXSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgbGVzc1RleHQgPSBmaWxlQ2FjaGVbaHJlZl07XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgeyBjb250ZW50czogbGVzc1RleHQsIGZpbGVuYW1lOiBocmVmLCB3ZWJJbmZvOiB7IGxhc3RNb2RpZmllZDogbmV3IERhdGUoKSB9fSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soe2ZpbGVuYW1lOiBocmVmLCBtZXNzYWdlOiBcIkVycm9yIGxvYWRpbmcgZmlsZSBcIiArIGhyZWYgKyBcIiBlcnJvciB3YXMgXCIgKyBlLm1lc3NhZ2V9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZG9YSFIoaHJlZiwgb3B0aW9ucy5taW1lLCBmdW5jdGlvbiBkb1hIUkNhbGxiYWNrKGRhdGEsIGxhc3RNb2RpZmllZCkge1xuICAgICAgICAgICAgLy8gcGVyIGZpbGUgY2FjaGVcbiAgICAgICAgICAgIGZpbGVDYWNoZVtocmVmXSA9IGRhdGE7XG5cbiAgICAgICAgICAgIC8vIFVzZSByZW1vdGUgY29weSAocmUtcGFyc2UpXG4gICAgICAgICAgICBjYWxsYmFjayhudWxsLCB7IGNvbnRlbnRzOiBkYXRhLCBmaWxlbmFtZTogaHJlZiwgd2ViSW5mbzogeyBsYXN0TW9kaWZpZWQ6IGxhc3RNb2RpZmllZCB9fSk7XG4gICAgICAgIH0sIGZ1bmN0aW9uIGRvWEhSRXJyb3Ioc3RhdHVzLCB1cmwpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKHsgdHlwZTogJ0ZpbGUnLCBtZXNzYWdlOiBcIidcIiArIHVybCArIFwiJyB3YXNuJ3QgZm91bmQgKFwiICsgc3RhdHVzICsgXCIpXCIsIGhyZWY6IGhyZWYgfSk7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICByZXR1cm4gRmlsZU1hbmFnZXI7XG59O1xuXG59LHtcIi4uL2xlc3MvZW52aXJvbm1lbnQvYWJzdHJhY3QtZmlsZS1tYW5hZ2VyLmpzXCI6MTV9XSw3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG5cbiAgICB2YXIgZnVuY3Rpb25SZWdpc3RyeSA9IHJlcXVpcmUoXCIuLy4uL2xlc3MvZnVuY3Rpb25zL2Z1bmN0aW9uLXJlZ2lzdHJ5XCIpO1xuXG4gICAgZnVuY3Rpb24gaW1hZ2VTaXplKCkge1xuICAgICAgICB0aHJvdyB7XG4gICAgICAgICAgICB0eXBlOiBcIlJ1bnRpbWVcIixcbiAgICAgICAgICAgIG1lc3NhZ2U6IFwiSW1hZ2Ugc2l6ZSBmdW5jdGlvbnMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gYnJvd3NlciB2ZXJzaW9uIG9mIGxlc3NcIlxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBpbWFnZUZ1bmN0aW9ucyA9IHtcbiAgICAgICAgXCJpbWFnZS1zaXplXCI6IGZ1bmN0aW9uKGZpbGVQYXRoTm9kZSkge1xuICAgICAgICAgICAgaW1hZ2VTaXplKHRoaXMsIGZpbGVQYXRoTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH0sXG4gICAgICAgIFwiaW1hZ2Utd2lkdGhcIjogZnVuY3Rpb24oZmlsZVBhdGhOb2RlKSB7XG4gICAgICAgICAgICBpbWFnZVNpemUodGhpcywgZmlsZVBhdGhOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfSxcbiAgICAgICAgXCJpbWFnZS1oZWlnaHRcIjogZnVuY3Rpb24oZmlsZVBhdGhOb2RlKSB7XG4gICAgICAgICAgICBpbWFnZVNpemUodGhpcywgZmlsZVBhdGhOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvblJlZ2lzdHJ5LmFkZE11bHRpcGxlKGltYWdlRnVuY3Rpb25zKTtcbn07XG5cbn0se1wiLi8uLi9sZXNzL2Z1bmN0aW9ucy9mdW5jdGlvbi1yZWdpc3RyeVwiOjIyfV0sODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4vL1xuLy8gaW5kZXguanNcbi8vIFNob3VsZCBleHBvc2UgdGhlIGFkZGl0aW9uYWwgYnJvd3NlciBmdW5jdGlvbnMgb24gdG8gdGhlIGxlc3Mgb2JqZWN0XG4vL1xudmFyIGFkZERhdGFBdHRyID0gcmVxdWlyZShcIi4vdXRpbHNcIikuYWRkRGF0YUF0dHIsXG4gICAgYnJvd3NlciA9IHJlcXVpcmUoXCIuL2Jyb3dzZXJcIik7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24od2luZG93LCBvcHRpb25zKSB7XG4gICAgdmFyIGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuICAgIHZhciBsZXNzID0gcmVxdWlyZSgnLi4vbGVzcycpKCk7XG5cbiAgICAvL21vZHVsZS5leHBvcnRzID0gbGVzcztcbiAgICBsZXNzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHZhciBlbnZpcm9ubWVudCA9IGxlc3MuZW52aXJvbm1lbnQsXG4gICAgICAgIEZpbGVNYW5hZ2VyID0gcmVxdWlyZShcIi4vZmlsZS1tYW5hZ2VyXCIpKG9wdGlvbnMsIGxlc3MubG9nZ2VyKSxcbiAgICAgICAgZmlsZU1hbmFnZXIgPSBuZXcgRmlsZU1hbmFnZXIoKTtcbiAgICBlbnZpcm9ubWVudC5hZGRGaWxlTWFuYWdlcihmaWxlTWFuYWdlcik7XG4gICAgbGVzcy5GaWxlTWFuYWdlciA9IEZpbGVNYW5hZ2VyO1xuXG4gICAgcmVxdWlyZShcIi4vbG9nLWxpc3RlbmVyXCIpKGxlc3MsIG9wdGlvbnMpO1xuICAgIHZhciBlcnJvcnMgPSByZXF1aXJlKFwiLi9lcnJvci1yZXBvcnRpbmdcIikod2luZG93LCBsZXNzLCBvcHRpb25zKTtcbiAgICB2YXIgY2FjaGUgPSBsZXNzLmNhY2hlID0gb3B0aW9ucy5jYWNoZSB8fCByZXF1aXJlKFwiLi9jYWNoZVwiKSh3aW5kb3csIG9wdGlvbnMsIGxlc3MubG9nZ2VyKTtcbiAgICByZXF1aXJlKCcuL2ltYWdlLXNpemUnKShsZXNzLmVudmlyb25tZW50KTtcblxuICAgIC8vU2V0dXAgdXNlciBmdW5jdGlvbnNcbiAgICBpZiAob3B0aW9ucy5mdW5jdGlvbnMpIHtcbiAgICAgICAgbGVzcy5mdW5jdGlvbnMuZnVuY3Rpb25SZWdpc3RyeS5hZGRNdWx0aXBsZShvcHRpb25zLmZ1bmN0aW9ucyk7XG4gICAgfVxuXG4gICAgdmFyIHR5cGVQYXR0ZXJuID0gL150ZXh0XFwvKHgtKT9sZXNzJC87XG5cbiAgICBmdW5jdGlvbiBwb3N0UHJvY2Vzc0NTUyhzdHlsZXMpIHsgLy8gZGVwcmVjYXRlZCwgdXNlIGEgcGx1Z2luIGZvciBwb3N0cHJvY2Vzc3Rhc2tzXG4gICAgICAgIGlmIChvcHRpb25zLnBvc3RQcm9jZXNzb3IgJiYgdHlwZW9mIG9wdGlvbnMucG9zdFByb2Nlc3NvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgc3R5bGVzID0gb3B0aW9ucy5wb3N0UHJvY2Vzc29yLmNhbGwoc3R5bGVzLCBzdHlsZXMpIHx8IHN0eWxlcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3R5bGVzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsb25lKG9iaikge1xuICAgICAgICB2YXIgY2xvbmVkID0ge307XG4gICAgICAgIGZvciAodmFyIHByb3AgaW4gb2JqKSB7XG4gICAgICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KHByb3ApKSB7XG4gICAgICAgICAgICAgICAgY2xvbmVkW3Byb3BdID0gb2JqW3Byb3BdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjbG9uZWQ7XG4gICAgfVxuXG4gICAgLy8gb25seSByZWFsbHkgbmVlZGVkIGZvciBwaGFudG9tXG4gICAgZnVuY3Rpb24gYmluZChmdW5jLCB0aGlzQXJnKSB7XG4gICAgICAgIHZhciBjdXJyeUFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB2YXIgYXJncyA9IGN1cnJ5QXJncy5jb25jYXQoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7XG4gICAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzQXJnLCBhcmdzKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsb2FkU3R5bGVzKG1vZGlmeVZhcnMpIHtcbiAgICAgICAgdmFyIHN0eWxlcyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdzdHlsZScpLFxuICAgICAgICAgICAgc3R5bGU7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHN0eWxlID0gc3R5bGVzW2ldO1xuICAgICAgICAgICAgaWYgKHN0eWxlLnR5cGUubWF0Y2godHlwZVBhdHRlcm4pKSB7XG4gICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlT3B0aW9ucyA9IGNsb25lKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGluc3RhbmNlT3B0aW9ucy5tb2RpZnlWYXJzID0gbW9kaWZ5VmFycztcbiAgICAgICAgICAgICAgICB2YXIgbGVzc1RleHQgPSBzdHlsZS5pbm5lckhUTUwgfHwgJyc7XG4gICAgICAgICAgICAgICAgaW5zdGFuY2VPcHRpb25zLmZpbGVuYW1lID0gZG9jdW1lbnQubG9jYXRpb24uaHJlZi5yZXBsYWNlKC8jLiokLywgJycpO1xuXG4gICAgICAgICAgICAgICAgLypqc2hpbnQgbG9vcGZ1bmM6dHJ1ZSAqL1xuICAgICAgICAgICAgICAgIC8vIHVzZSBjbG9zdXJlIHRvIHN0b3JlIGN1cnJlbnQgc3R5bGVcbiAgICAgICAgICAgICAgICBsZXNzLnJlbmRlcihsZXNzVGV4dCwgaW5zdGFuY2VPcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICAgICAgYmluZChmdW5jdGlvbihzdHlsZSwgZSwgcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzLmFkZChlLCBcImlubGluZVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZS50eXBlID0gJ3RleHQvY3NzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0eWxlLnN0eWxlU2hlZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlLnN0eWxlU2hlZXQuY3NzVGV4dCA9IHJlc3VsdC5jc3M7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZS5pbm5lckhUTUwgPSByZXN1bHQuY3NzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgbnVsbCwgc3R5bGUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxvYWRTdHlsZVNoZWV0KHNoZWV0LCBjYWxsYmFjaywgcmVsb2FkLCByZW1haW5pbmcsIG1vZGlmeVZhcnMpIHtcblxuICAgICAgICB2YXIgaW5zdGFuY2VPcHRpb25zID0gY2xvbmUob3B0aW9ucyk7XG4gICAgICAgIGFkZERhdGFBdHRyKGluc3RhbmNlT3B0aW9ucywgc2hlZXQpO1xuICAgICAgICBpbnN0YW5jZU9wdGlvbnMubWltZSA9IHNoZWV0LnR5cGU7XG5cbiAgICAgICAgaWYgKG1vZGlmeVZhcnMpIHtcbiAgICAgICAgICAgIGluc3RhbmNlT3B0aW9ucy5tb2RpZnlWYXJzID0gbW9kaWZ5VmFycztcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGxvYWRJbml0aWFsRmlsZUNhbGxiYWNrKGxvYWRlZEZpbGUpIHtcblxuICAgICAgICAgICAgdmFyIGRhdGEgPSBsb2FkZWRGaWxlLmNvbnRlbnRzLFxuICAgICAgICAgICAgICAgIHBhdGggPSBsb2FkZWRGaWxlLmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgIHdlYkluZm8gPSBsb2FkZWRGaWxlLndlYkluZm87XG5cbiAgICAgICAgICAgIHZhciBuZXdGaWxlSW5mbyA9IHtcbiAgICAgICAgICAgICAgICBjdXJyZW50RGlyZWN0b3J5OiBmaWxlTWFuYWdlci5nZXRQYXRoKHBhdGgpLFxuICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBwYXRoLFxuICAgICAgICAgICAgICAgIHJvb3RGaWxlbmFtZTogcGF0aCxcbiAgICAgICAgICAgICAgICByZWxhdGl2ZVVybHM6IGluc3RhbmNlT3B0aW9ucy5yZWxhdGl2ZVVybHN9O1xuXG4gICAgICAgICAgICBuZXdGaWxlSW5mby5lbnRyeVBhdGggPSBuZXdGaWxlSW5mby5jdXJyZW50RGlyZWN0b3J5O1xuICAgICAgICAgICAgbmV3RmlsZUluZm8ucm9vdHBhdGggPSBpbnN0YW5jZU9wdGlvbnMucm9vdHBhdGggfHwgbmV3RmlsZUluZm8uY3VycmVudERpcmVjdG9yeTtcblxuICAgICAgICAgICAgaWYgKHdlYkluZm8pIHtcbiAgICAgICAgICAgICAgICB3ZWJJbmZvLnJlbWFpbmluZyA9IHJlbWFpbmluZztcblxuICAgICAgICAgICAgICAgIHZhciBjc3MgPSBjYWNoZS5nZXRDU1MocGF0aCwgd2ViSW5mbywgaW5zdGFuY2VPcHRpb25zLm1vZGlmeVZhcnMpO1xuICAgICAgICAgICAgICAgIGlmICghcmVsb2FkICYmIGNzcykge1xuICAgICAgICAgICAgICAgICAgICB3ZWJJbmZvLmxvY2FsID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgY3NzLCBkYXRhLCBzaGVldCwgd2ViSW5mbywgcGF0aCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy9UT0RPIGFkZCB0ZXN0cyBhcm91bmQgaG93IHRoaXMgYmVoYXZlcyB3aGVuIHJlbG9hZGluZ1xuICAgICAgICAgICAgZXJyb3JzLnJlbW92ZShwYXRoKTtcblxuICAgICAgICAgICAgaW5zdGFuY2VPcHRpb25zLnJvb3RGaWxlSW5mbyA9IG5ld0ZpbGVJbmZvO1xuICAgICAgICAgICAgbGVzcy5yZW5kZXIoZGF0YSwgaW5zdGFuY2VPcHRpb25zLCBmdW5jdGlvbihlLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBlLmhyZWYgPSBwYXRoO1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQuY3NzID0gcG9zdFByb2Nlc3NDU1MocmVzdWx0LmNzcyk7XG4gICAgICAgICAgICAgICAgICAgIGNhY2hlLnNldENTUyhzaGVldC5ocmVmLCB3ZWJJbmZvLmxhc3RNb2RpZmllZCwgaW5zdGFuY2VPcHRpb25zLm1vZGlmeVZhcnMsIHJlc3VsdC5jc3MpO1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCByZXN1bHQuY3NzLCBkYXRhLCBzaGVldCwgd2ViSW5mbywgcGF0aCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBmaWxlTWFuYWdlci5sb2FkRmlsZShzaGVldC5ocmVmLCBudWxsLCBpbnN0YW5jZU9wdGlvbnMsIGVudmlyb25tZW50LCBmdW5jdGlvbihlLCBsb2FkZWRGaWxlKSB7XG4gICAgICAgICAgICBpZiAoZSkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGUpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxvYWRJbml0aWFsRmlsZUNhbGxiYWNrKGxvYWRlZEZpbGUpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsb2FkU3R5bGVTaGVldHMoY2FsbGJhY2ssIHJlbG9hZCwgbW9kaWZ5VmFycykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlc3Muc2hlZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsb2FkU3R5bGVTaGVldChsZXNzLnNoZWV0c1tpXSwgY2FsbGJhY2ssIHJlbG9hZCwgbGVzcy5zaGVldHMubGVuZ3RoIC0gKGkgKyAxKSwgbW9kaWZ5VmFycyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbml0UnVubmluZ01vZGUoKSB7XG4gICAgICAgIGlmIChsZXNzLmVudiA9PT0gJ2RldmVsb3BtZW50Jykge1xuICAgICAgICAgICAgbGVzcy53YXRjaFRpbWVyID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChsZXNzLndhdGNoTW9kZSkge1xuICAgICAgICAgICAgICAgICAgICBmaWxlTWFuYWdlci5jbGVhckZpbGVDYWNoZSgpO1xuICAgICAgICAgICAgICAgICAgICBsb2FkU3R5bGVTaGVldHMoZnVuY3Rpb24gKGUsIGNzcywgXywgc2hlZXQsIHdlYkluZm8pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzLmFkZChlLCBlLmhyZWYgfHwgc2hlZXQuaHJlZik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyb3dzZXIuY3JlYXRlQ1NTKHdpbmRvdy5kb2N1bWVudCwgY3NzLCBzaGVldCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIG9wdGlvbnMucG9sbCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvL1xuICAgIC8vIFdhdGNoIG1vZGVcbiAgICAvL1xuICAgIGxlc3Mud2F0Y2ggICA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCFsZXNzLndhdGNoTW9kZSApIHtcbiAgICAgICAgICAgIGxlc3MuZW52ID0gJ2RldmVsb3BtZW50JztcbiAgICAgICAgICAgIGluaXRSdW5uaW5nTW9kZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud2F0Y2hNb2RlID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIGxlc3MudW53YXRjaCA9IGZ1bmN0aW9uICgpIHtjbGVhckludGVydmFsKGxlc3Mud2F0Y2hUaW1lcik7IHRoaXMud2F0Y2hNb2RlID0gZmFsc2U7IHJldHVybiBmYWxzZTsgfTtcblxuICAgIC8vXG4gICAgLy8gU3luY2hyb25vdXNseSBnZXQgYWxsIDxsaW5rPiB0YWdzIHdpdGggdGhlICdyZWwnIGF0dHJpYnV0ZSBzZXQgdG9cbiAgICAvLyBcInN0eWxlc2hlZXQvbGVzc1wiLlxuICAgIC8vXG4gICAgbGVzcy5yZWdpc3RlclN0eWxlc2hlZXRzSW1tZWRpYXRlbHkgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGxpbmtzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2xpbmsnKTtcbiAgICAgICAgbGVzcy5zaGVldHMgPSBbXTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAobGlua3NbaV0ucmVsID09PSAnc3R5bGVzaGVldC9sZXNzJyB8fCAobGlua3NbaV0ucmVsLm1hdGNoKC9zdHlsZXNoZWV0LykgJiZcbiAgICAgICAgICAgICAgICAobGlua3NbaV0udHlwZS5tYXRjaCh0eXBlUGF0dGVybikpKSkge1xuICAgICAgICAgICAgICAgIGxlc3Muc2hlZXRzLnB1c2gobGlua3NbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8vXG4gICAgLy8gQXN5bmNocm9ub3VzbHkgZ2V0IGFsbCA8bGluaz4gdGFncyB3aXRoIHRoZSAncmVsJyBhdHRyaWJ1dGUgc2V0IHRvXG4gICAgLy8gXCJzdHlsZXNoZWV0L2xlc3NcIiwgcmV0dXJuaW5nIGEgUHJvbWlzZS5cbiAgICAvL1xuICAgIGxlc3MucmVnaXN0ZXJTdHlsZXNoZWV0cyA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICBsZXNzLnJlZ2lzdGVyU3R5bGVzaGVldHNJbW1lZGlhdGVseSgpO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy9cbiAgICAvLyBXaXRoIHRoaXMgZnVuY3Rpb24sIGl0J3MgcG9zc2libGUgdG8gYWx0ZXIgdmFyaWFibGVzIGFuZCByZS1yZW5kZXJcbiAgICAvLyBDU1Mgd2l0aG91dCByZWxvYWRpbmcgbGVzcy1maWxlc1xuICAgIC8vXG4gICAgbGVzcy5tb2RpZnlWYXJzID0gZnVuY3Rpb24ocmVjb3JkKSB7XG4gICAgICAgIHJldHVybiBsZXNzLnJlZnJlc2godHJ1ZSwgcmVjb3JkLCBmYWxzZSk7XG4gICAgfTtcblxuICAgIGxlc3MucmVmcmVzaCA9IGZ1bmN0aW9uIChyZWxvYWQsIG1vZGlmeVZhcnMsIGNsZWFyRmlsZUNhY2hlKSB7XG4gICAgICAgIGlmICgocmVsb2FkIHx8IGNsZWFyRmlsZUNhY2hlKSAmJiBjbGVhckZpbGVDYWNoZSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGZpbGVNYW5hZ2VyLmNsZWFyRmlsZUNhY2hlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIHZhciBzdGFydFRpbWUsIGVuZFRpbWUsIHRvdGFsTWlsbGlzZWNvbmRzLCByZW1haW5pbmdTaGVldHM7XG4gICAgICAgICAgICBzdGFydFRpbWUgPSBlbmRUaW1lID0gbmV3IERhdGUoKTtcblxuICAgICAgICAgICAgLy8gU2V0IGNvdW50ZXIgZm9yIHJlbWFpbmluZyB1bnByb2Nlc3NlZCBzaGVldHNcbiAgICAgICAgICAgIHJlbWFpbmluZ1NoZWV0cyA9IGxlc3Muc2hlZXRzLmxlbmd0aDtcblxuICAgICAgICAgICAgaWYgKHJlbWFpbmluZ1NoZWV0cyA9PT0gMCkge1xuXG4gICAgICAgICAgICAgICAgZW5kVGltZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgICAgICAgdG90YWxNaWxsaXNlY29uZHMgPSBlbmRUaW1lIC0gc3RhcnRUaW1lO1xuICAgICAgICAgICAgICAgIGxlc3MubG9nZ2VyLmluZm8oXCJMZXNzIGhhcyBmaW5pc2hlZCBhbmQgbm8gc2hlZXRzIHdlcmUgbG9hZGVkLlwiKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lOiBzdGFydFRpbWUsXG4gICAgICAgICAgICAgICAgICAgIGVuZFRpbWU6IGVuZFRpbWUsXG4gICAgICAgICAgICAgICAgICAgIHRvdGFsTWlsbGlzZWNvbmRzOiB0b3RhbE1pbGxpc2Vjb25kcyxcbiAgICAgICAgICAgICAgICAgICAgc2hlZXRzOiBsZXNzLnNoZWV0cy5sZW5ndGhcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBSZWxpZXMgb24gbGVzcy5zaGVldHMgYXJyYXksIGNhbGxiYWNrIHNlZW1zIHRvIGJlIGd1YXJhbnRlZWQgdG8gYmUgY2FsbGVkIGZvciBldmVyeSBlbGVtZW50IG9mIHRoZSBhcnJheVxuICAgICAgICAgICAgICAgIGxvYWRTdHlsZVNoZWV0cyhmdW5jdGlvbiAoZSwgY3NzLCBfLCBzaGVldCwgd2ViSW5mbykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzLmFkZChlLCBlLmhyZWYgfHwgc2hlZXQuaHJlZik7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHdlYkluZm8ubG9jYWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlc3MubG9nZ2VyLmluZm8oXCJMb2FkaW5nIFwiICsgc2hlZXQuaHJlZiArIFwiIGZyb20gY2FjaGUuXCIpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGVzcy5sb2dnZXIuaW5mbyhcIlJlbmRlcmVkIFwiICsgc2hlZXQuaHJlZiArIFwiIHN1Y2Nlc3NmdWxseS5cIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJvd3Nlci5jcmVhdGVDU1Mod2luZG93LmRvY3VtZW50LCBjc3MsIHNoZWV0KTtcbiAgICAgICAgICAgICAgICAgICAgbGVzcy5sb2dnZXIuaW5mbyhcIkNTUyBmb3IgXCIgKyBzaGVldC5ocmVmICsgXCIgZ2VuZXJhdGVkIGluIFwiICsgKG5ldyBEYXRlKCkgLSBlbmRUaW1lKSArICdtcycpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIENvdW50IGNvbXBsZXRlZCBzaGVldFxuICAgICAgICAgICAgICAgICAgICByZW1haW5pbmdTaGVldHMtLTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgbGFzdCByZW1haW5pbmcgc2hlZXQgd2FzIHByb2Nlc3NlZCBhbmQgdGhlbiBjYWxsIHRoZSBwcm9taXNlXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZW1haW5pbmdTaGVldHMgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsTWlsbGlzZWNvbmRzID0gbmV3IERhdGUoKSAtIHN0YXJ0VGltZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlc3MubG9nZ2VyLmluZm8oXCJMZXNzIGhhcyBmaW5pc2hlZC4gQ1NTIGdlbmVyYXRlZCBpbiBcIiArIHRvdGFsTWlsbGlzZWNvbmRzICsgJ21zJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydFRpbWU6IHN0YXJ0VGltZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRUaW1lOiBlbmRUaW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsTWlsbGlzZWNvbmRzOiB0b3RhbE1pbGxpc2Vjb25kcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGVldHM6IGxlc3Muc2hlZXRzLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZW5kVGltZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgICAgICAgfSwgcmVsb2FkLCBtb2RpZnlWYXJzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbG9hZFN0eWxlcyhtb2RpZnlWYXJzKTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIGxlc3MucmVmcmVzaFN0eWxlcyA9IGxvYWRTdHlsZXM7XG4gICAgcmV0dXJuIGxlc3M7XG59O1xuXG59LHtcIi4uL2xlc3NcIjozMSxcIi4vYnJvd3NlclwiOjMsXCIuL2NhY2hlXCI6NCxcIi4vZXJyb3ItcmVwb3J0aW5nXCI6NSxcIi4vZmlsZS1tYW5hZ2VyXCI6NixcIi4vaW1hZ2Utc2l6ZVwiOjcsXCIuL2xvZy1saXN0ZW5lclwiOjksXCIuL3V0aWxzXCI6MTB9XSw5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24obGVzcywgb3B0aW9ucykge1xuXG4gICAgdmFyIGxvZ0xldmVsX2RlYnVnID0gNCxcbiAgICAgICAgbG9nTGV2ZWxfaW5mbyA9IDMsXG4gICAgICAgIGxvZ0xldmVsX3dhcm4gPSAyLFxuICAgICAgICBsb2dMZXZlbF9lcnJvciA9IDE7XG5cbiAgICAvLyBUaGUgYW1vdW50IG9mIGxvZ2dpbmcgaW4gdGhlIGphdmFzY3JpcHQgY29uc29sZS5cbiAgICAvLyAzIC0gRGVidWcsIGluZm9ybWF0aW9uIGFuZCBlcnJvcnNcbiAgICAvLyAyIC0gSW5mb3JtYXRpb24gYW5kIGVycm9yc1xuICAgIC8vIDEgLSBFcnJvcnNcbiAgICAvLyAwIC0gTm9uZVxuICAgIC8vIERlZmF1bHRzIHRvIDJcbiAgICBvcHRpb25zLmxvZ0xldmVsID0gdHlwZW9mIG9wdGlvbnMubG9nTGV2ZWwgIT09ICd1bmRlZmluZWQnID8gb3B0aW9ucy5sb2dMZXZlbCA6IChvcHRpb25zLmVudiA9PT0gJ2RldmVsb3BtZW50JyA/ICBsb2dMZXZlbF9pbmZvIDogbG9nTGV2ZWxfZXJyb3IpO1xuXG4gICAgaWYgKCFvcHRpb25zLmxvZ2dlcnMpIHtcbiAgICAgICAgb3B0aW9ucy5sb2dnZXJzID0gW3tcbiAgICAgICAgICAgIGRlYnVnOiBmdW5jdGlvbihtc2cpIHtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5sb2dMZXZlbCA+PSBsb2dMZXZlbF9kZWJ1Zykge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhtc2cpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpbmZvOiBmdW5jdGlvbihtc2cpIHtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5sb2dMZXZlbCA+PSBsb2dMZXZlbF9pbmZvKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKG1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHdhcm46IGZ1bmN0aW9uKG1zZykge1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmxvZ0xldmVsID49IGxvZ0xldmVsX3dhcm4pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKG1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbihtc2cpIHtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5sb2dMZXZlbCA+PSBsb2dMZXZlbF9lcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvcHRpb25zLmxvZ2dlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGVzcy5sb2dnZXIuYWRkTGlzdGVuZXIob3B0aW9ucy5sb2dnZXJzW2ldKTtcbiAgICB9XG59O1xuXG59LHt9XSwxMDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBleHRyYWN0SWQ6IGZ1bmN0aW9uKGhyZWYpIHtcbiAgICAgICAgcmV0dXJuIGhyZWYucmVwbGFjZSgvXlthLXotXSs6XFwvKz9bXlxcL10rLywgJycpICAvLyBSZW1vdmUgcHJvdG9jb2wgJiBkb21haW5cbiAgICAgICAgICAgIC5yZXBsYWNlKC9bXFw/XFwmXWxpdmVyZWxvYWQ9XFx3Ky8sICcnKSAgICAgICAgLy8gUmVtb3ZlIExpdmVSZWxvYWQgY2FjaGVidXN0ZXJcbiAgICAgICAgICAgIC5yZXBsYWNlKC9eXFwvLywgJycpICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlbW92ZSByb290IC9cbiAgICAgICAgICAgIC5yZXBsYWNlKC9cXC5bYS16QS1aXSskLywgJycpICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBzaW1wbGUgZXh0ZW5zaW9uXG4gICAgICAgICAgICAucmVwbGFjZSgvW15cXC5cXHctXSsvZywgJy0nKSAgICAgICAgICAgICAgICAgLy8gUmVwbGFjZSBpbGxlZ2FsIGNoYXJhY3RlcnNcbiAgICAgICAgICAgIC5yZXBsYWNlKC9cXC4vZywgJzonKTsgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlcGxhY2UgZG90cyB3aXRoIGNvbG9ucyhmb3IgdmFsaWQgaWQpXG4gICAgfSxcbiAgICBhZGREYXRhQXR0cjogZnVuY3Rpb24ob3B0aW9ucywgdGFnKSB7XG4gICAgICAgIGZvciAodmFyIG9wdCBpbiB0YWcuZGF0YXNldCkge1xuICAgICAgICAgICAgaWYgKHRhZy5kYXRhc2V0Lmhhc093blByb3BlcnR5KG9wdCkpIHtcbiAgICAgICAgICAgICAgICBpZiAob3B0ID09PSBcImVudlwiIHx8IG9wdCA9PT0gXCJkdW1wTGluZU51bWJlcnNcIiB8fCBvcHQgPT09IFwicm9vdHBhdGhcIiB8fCBvcHQgPT09IFwiZXJyb3JSZXBvcnRpbmdcIikge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zW29wdF0gPSB0YWcuZGF0YXNldFtvcHRdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zW29wdF0gPSBKU09OLnBhcnNlKHRhZy5kYXRhc2V0W29wdF0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhdGNoKF8pIHt9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufTtcblxufSx7fV0sMTE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIGNvbnRleHRzID0ge307XG5tb2R1bGUuZXhwb3J0cyA9IGNvbnRleHRzO1xuXG52YXIgY29weUZyb21PcmlnaW5hbCA9IGZ1bmN0aW9uIGNvcHlGcm9tT3JpZ2luYWwob3JpZ2luYWwsIGRlc3RpbmF0aW9uLCBwcm9wZXJ0aWVzVG9Db3B5KSB7XG4gICAgaWYgKCFvcmlnaW5hbCkgeyByZXR1cm47IH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcGVydGllc1RvQ29weS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAob3JpZ2luYWwuaGFzT3duUHJvcGVydHkocHJvcGVydGllc1RvQ29weVtpXSkpIHtcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uW3Byb3BlcnRpZXNUb0NvcHlbaV1dID0gb3JpZ2luYWxbcHJvcGVydGllc1RvQ29weVtpXV07XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG4vKlxuIHBhcnNlIGlzIHVzZWQgd2hpbHN0IHBhcnNpbmdcbiAqL1xudmFyIHBhcnNlQ29weVByb3BlcnRpZXMgPSBbXG4gICAgLy8gb3B0aW9uc1xuICAgICdwYXRocycsICAgICAgICAgICAgLy8gb3B0aW9uIC0gdW5tb2RpZmllZCAtIHBhdGhzIHRvIHNlYXJjaCBmb3IgaW1wb3J0cyBvblxuICAgICdyZWxhdGl2ZVVybHMnLCAgICAgLy8gb3B0aW9uIC0gd2hldGhlciB0byBhZGp1c3QgVVJMJ3MgdG8gYmUgcmVsYXRpdmVcbiAgICAncm9vdHBhdGgnLCAgICAgICAgIC8vIG9wdGlvbiAtIHJvb3RwYXRoIHRvIGFwcGVuZCB0byBVUkwnc1xuICAgICdzdHJpY3RJbXBvcnRzJywgICAgLy8gb3B0aW9uIC1cbiAgICAnaW5zZWN1cmUnLCAgICAgICAgIC8vIG9wdGlvbiAtIHdoZXRoZXIgdG8gYWxsb3cgaW1wb3J0cyBmcm9tIGluc2VjdXJlIHNzbCBob3N0c1xuICAgICdkdW1wTGluZU51bWJlcnMnLCAgLy8gb3B0aW9uIC0gd2hldGhlciB0byBkdW1wIGxpbmUgbnVtYmVyc1xuICAgICdjb21wcmVzcycsICAgICAgICAgLy8gb3B0aW9uIC0gd2hldGhlciB0byBjb21wcmVzc1xuICAgICdzeW5jSW1wb3J0JywgICAgICAgLy8gb3B0aW9uIC0gd2hldGhlciB0byBpbXBvcnQgc3luY2hyb25vdXNseVxuICAgICdjaHVua0lucHV0JywgICAgICAgLy8gb3B0aW9uIC0gd2hldGhlciB0byBjaHVuayBpbnB1dC4gbW9yZSBwZXJmb3JtYW50IGJ1dCBjYXVzZXMgcGFyc2UgaXNzdWVzLlxuICAgICdtaW1lJywgICAgICAgICAgICAgLy8gYnJvd3NlciBvbmx5IC0gbWltZSB0eXBlIGZvciBzaGVldCBpbXBvcnRcbiAgICAndXNlRmlsZUNhY2hlJywgICAgIC8vIGJyb3dzZXIgb25seSAtIHdoZXRoZXIgdG8gdXNlIHRoZSBwZXIgZmlsZSBzZXNzaW9uIGNhY2hlXG4gICAgLy8gY29udGV4dFxuICAgICdwcm9jZXNzSW1wb3J0cycsICAgLy8gb3B0aW9uICYgY29udGV4dCAtIHdoZXRoZXIgdG8gcHJvY2VzcyBpbXBvcnRzLiBpZiBmYWxzZSB0aGVuIGltcG9ydHMgd2lsbCBub3QgYmUgaW1wb3J0ZWQuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBVc2VkIGJ5IHRoZSBpbXBvcnQgbWFuYWdlciB0byBzdG9wIG11bHRpcGxlIGltcG9ydCB2aXNpdG9ycyBiZWluZyBjcmVhdGVkLlxuICAgICdwbHVnaW5NYW5hZ2VyJyAgICAgLy8gVXNlZCBhcyB0aGUgcGx1Z2luIG1hbmFnZXIgZm9yIHRoZSBzZXNzaW9uXG5dO1xuXG5jb250ZXh0cy5QYXJzZSA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICBjb3B5RnJvbU9yaWdpbmFsKG9wdGlvbnMsIHRoaXMsIHBhcnNlQ29weVByb3BlcnRpZXMpO1xuXG4gICAgaWYgKHR5cGVvZiB0aGlzLnBhdGhzID09PSBcInN0cmluZ1wiKSB7IHRoaXMucGF0aHMgPSBbdGhpcy5wYXRoc107IH1cbn07XG5cbnZhciBldmFsQ29weVByb3BlcnRpZXMgPSBbXG4gICAgJ3BhdGhzJywgICAgICAgICAgLy8gYWRkaXRpb25hbCBpbmNsdWRlIHBhdGhzXG4gICAgJ2NvbXByZXNzJywgICAgICAgLy8gd2hldGhlciB0byBjb21wcmVzc1xuICAgICdpZUNvbXBhdCcsICAgICAgIC8vIHdoZXRoZXIgdG8gZW5mb3JjZSBJRSBjb21wYXRpYmlsaXR5IChJRTggZGF0YS11cmkpXG4gICAgJ3N0cmljdE1hdGgnLCAgICAgLy8gd2hldGhlciBtYXRoIGhhcyB0byBiZSB3aXRoaW4gcGFyZW50aGVzaXNcbiAgICAnc3RyaWN0VW5pdHMnLCAgICAvLyB3aGV0aGVyIHVuaXRzIG5lZWQgdG8gZXZhbHVhdGUgY29ycmVjdGx5XG4gICAgJ3NvdXJjZU1hcCcsICAgICAgLy8gd2hldGhlciB0byBvdXRwdXQgYSBzb3VyY2UgbWFwXG4gICAgJ2ltcG9ydE11bHRpcGxlJywgLy8gd2hldGhlciB3ZSBhcmUgY3VycmVudGx5IGltcG9ydGluZyBtdWx0aXBsZSBjb3BpZXNcbiAgICAndXJsQXJncycsICAgICAgICAvLyB3aGV0aGVyIHRvIGFkZCBhcmdzIGludG8gdXJsIHRva2Vuc1xuICAgICdqYXZhc2NyaXB0RW5hYmxlZCcsLy8gb3B0aW9uIC0gd2hldGhlciBKYXZhU2NyaXB0IGlzIGVuYWJsZWQuIGlmIHVuZGVmaW5lZCwgZGVmYXVsdHMgdG8gdHJ1ZVxuICAgICdwbHVnaW5NYW5hZ2VyJywgIC8vIFVzZWQgYXMgdGhlIHBsdWdpbiBtYW5hZ2VyIGZvciB0aGUgc2Vzc2lvblxuICAgICdpbXBvcnRhbnRTY29wZScgIC8vIHVzZWQgdG8gYnViYmxlIHVwICFpbXBvcnRhbnQgc3RhdGVtZW50c1xuICAgIF07XG5cbmNvbnRleHRzLkV2YWwgPSBmdW5jdGlvbihvcHRpb25zLCBmcmFtZXMpIHtcbiAgICBjb3B5RnJvbU9yaWdpbmFsKG9wdGlvbnMsIHRoaXMsIGV2YWxDb3B5UHJvcGVydGllcyk7XG5cbiAgICBpZiAodHlwZW9mIHRoaXMucGF0aHMgPT09IFwic3RyaW5nXCIpIHsgdGhpcy5wYXRocyA9IFt0aGlzLnBhdGhzXTsgfVxuXG4gICAgdGhpcy5mcmFtZXMgPSBmcmFtZXMgfHwgW107XG4gICAgdGhpcy5pbXBvcnRhbnRTY29wZSA9IHRoaXMuaW1wb3J0YW50U2NvcGUgfHwgW107XG59O1xuXG5jb250ZXh0cy5FdmFsLnByb3RvdHlwZS5pblBhcmVudGhlc2lzID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy5wYXJlbnNTdGFjaykge1xuICAgICAgICB0aGlzLnBhcmVuc1N0YWNrID0gW107XG4gICAgfVxuICAgIHRoaXMucGFyZW5zU3RhY2sucHVzaCh0cnVlKTtcbn07XG5cbmNvbnRleHRzLkV2YWwucHJvdG90eXBlLm91dE9mUGFyZW50aGVzaXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5wYXJlbnNTdGFjay5wb3AoKTtcbn07XG5cbmNvbnRleHRzLkV2YWwucHJvdG90eXBlLmlzTWF0aE9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnN0cmljdE1hdGggPyAodGhpcy5wYXJlbnNTdGFjayAmJiB0aGlzLnBhcmVuc1N0YWNrLmxlbmd0aCkgOiB0cnVlO1xufTtcblxuY29udGV4dHMuRXZhbC5wcm90b3R5cGUuaXNQYXRoUmVsYXRpdmUgPSBmdW5jdGlvbiAocGF0aCkge1xuICAgIHJldHVybiAhL14oPzpbYS16LV0rOnxcXC98IykvaS50ZXN0KHBhdGgpO1xufTtcblxuY29udGV4dHMuRXZhbC5wcm90b3R5cGUubm9ybWFsaXplUGF0aCA9IGZ1bmN0aW9uKCBwYXRoICkge1xuICAgIHZhclxuICAgICAgc2VnbWVudHMgPSBwYXRoLnNwbGl0KFwiL1wiKS5yZXZlcnNlKCksXG4gICAgICBzZWdtZW50O1xuXG4gICAgcGF0aCA9IFtdO1xuICAgIHdoaWxlIChzZWdtZW50cy5sZW5ndGggIT09IDAgKSB7XG4gICAgICAgIHNlZ21lbnQgPSBzZWdtZW50cy5wb3AoKTtcbiAgICAgICAgc3dpdGNoKCBzZWdtZW50ICkge1xuICAgICAgICAgICAgY2FzZSBcIi5cIjpcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCIuLlwiOlxuICAgICAgICAgICAgICAgIGlmICgocGF0aC5sZW5ndGggPT09IDApIHx8IChwYXRoW3BhdGgubGVuZ3RoIC0gMV0gPT09IFwiLi5cIikpIHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aC5wdXNoKCBzZWdtZW50ICk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aC5wb3AoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHBhdGgucHVzaCggc2VnbWVudCApO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhdGguam9pbihcIi9cIik7XG59O1xuXG4vL3RvZG8gLSBkbyB0aGUgc2FtZSBmb3IgdGhlIHRvQ1NTID9cblxufSx7fV0sMTI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgJ2FsaWNlYmx1ZSc6JyNmMGY4ZmYnLFxuICAgICdhbnRpcXVld2hpdGUnOicjZmFlYmQ3JyxcbiAgICAnYXF1YSc6JyMwMGZmZmYnLFxuICAgICdhcXVhbWFyaW5lJzonIzdmZmZkNCcsXG4gICAgJ2F6dXJlJzonI2YwZmZmZicsXG4gICAgJ2JlaWdlJzonI2Y1ZjVkYycsXG4gICAgJ2Jpc3F1ZSc6JyNmZmU0YzQnLFxuICAgICdibGFjayc6JyMwMDAwMDAnLFxuICAgICdibGFuY2hlZGFsbW9uZCc6JyNmZmViY2QnLFxuICAgICdibHVlJzonIzAwMDBmZicsXG4gICAgJ2JsdWV2aW9sZXQnOicjOGEyYmUyJyxcbiAgICAnYnJvd24nOicjYTUyYTJhJyxcbiAgICAnYnVybHl3b29kJzonI2RlYjg4NycsXG4gICAgJ2NhZGV0Ymx1ZSc6JyM1ZjllYTAnLFxuICAgICdjaGFydHJldXNlJzonIzdmZmYwMCcsXG4gICAgJ2Nob2NvbGF0ZSc6JyNkMjY5MWUnLFxuICAgICdjb3JhbCc6JyNmZjdmNTAnLFxuICAgICdjb3JuZmxvd2VyYmx1ZSc6JyM2NDk1ZWQnLFxuICAgICdjb3Juc2lsayc6JyNmZmY4ZGMnLFxuICAgICdjcmltc29uJzonI2RjMTQzYycsXG4gICAgJ2N5YW4nOicjMDBmZmZmJyxcbiAgICAnZGFya2JsdWUnOicjMDAwMDhiJyxcbiAgICAnZGFya2N5YW4nOicjMDA4YjhiJyxcbiAgICAnZGFya2dvbGRlbnJvZCc6JyNiODg2MGInLFxuICAgICdkYXJrZ3JheSc6JyNhOWE5YTknLFxuICAgICdkYXJrZ3JleSc6JyNhOWE5YTknLFxuICAgICdkYXJrZ3JlZW4nOicjMDA2NDAwJyxcbiAgICAnZGFya2toYWtpJzonI2JkYjc2YicsXG4gICAgJ2RhcmttYWdlbnRhJzonIzhiMDA4YicsXG4gICAgJ2RhcmtvbGl2ZWdyZWVuJzonIzU1NmIyZicsXG4gICAgJ2RhcmtvcmFuZ2UnOicjZmY4YzAwJyxcbiAgICAnZGFya29yY2hpZCc6JyM5OTMyY2MnLFxuICAgICdkYXJrcmVkJzonIzhiMDAwMCcsXG4gICAgJ2RhcmtzYWxtb24nOicjZTk5NjdhJyxcbiAgICAnZGFya3NlYWdyZWVuJzonIzhmYmM4ZicsXG4gICAgJ2RhcmtzbGF0ZWJsdWUnOicjNDgzZDhiJyxcbiAgICAnZGFya3NsYXRlZ3JheSc6JyMyZjRmNGYnLFxuICAgICdkYXJrc2xhdGVncmV5JzonIzJmNGY0ZicsXG4gICAgJ2Rhcmt0dXJxdW9pc2UnOicjMDBjZWQxJyxcbiAgICAnZGFya3Zpb2xldCc6JyM5NDAwZDMnLFxuICAgICdkZWVwcGluayc6JyNmZjE0OTMnLFxuICAgICdkZWVwc2t5Ymx1ZSc6JyMwMGJmZmYnLFxuICAgICdkaW1ncmF5JzonIzY5Njk2OScsXG4gICAgJ2RpbWdyZXknOicjNjk2OTY5JyxcbiAgICAnZG9kZ2VyYmx1ZSc6JyMxZTkwZmYnLFxuICAgICdmaXJlYnJpY2snOicjYjIyMjIyJyxcbiAgICAnZmxvcmFsd2hpdGUnOicjZmZmYWYwJyxcbiAgICAnZm9yZXN0Z3JlZW4nOicjMjI4YjIyJyxcbiAgICAnZnVjaHNpYSc6JyNmZjAwZmYnLFxuICAgICdnYWluc2Jvcm8nOicjZGNkY2RjJyxcbiAgICAnZ2hvc3R3aGl0ZSc6JyNmOGY4ZmYnLFxuICAgICdnb2xkJzonI2ZmZDcwMCcsXG4gICAgJ2dvbGRlbnJvZCc6JyNkYWE1MjAnLFxuICAgICdncmF5JzonIzgwODA4MCcsXG4gICAgJ2dyZXknOicjODA4MDgwJyxcbiAgICAnZ3JlZW4nOicjMDA4MDAwJyxcbiAgICAnZ3JlZW55ZWxsb3cnOicjYWRmZjJmJyxcbiAgICAnaG9uZXlkZXcnOicjZjBmZmYwJyxcbiAgICAnaG90cGluayc6JyNmZjY5YjQnLFxuICAgICdpbmRpYW5yZWQnOicjY2Q1YzVjJyxcbiAgICAnaW5kaWdvJzonIzRiMDA4MicsXG4gICAgJ2l2b3J5JzonI2ZmZmZmMCcsXG4gICAgJ2toYWtpJzonI2YwZTY4YycsXG4gICAgJ2xhdmVuZGVyJzonI2U2ZTZmYScsXG4gICAgJ2xhdmVuZGVyYmx1c2gnOicjZmZmMGY1JyxcbiAgICAnbGF3bmdyZWVuJzonIzdjZmMwMCcsXG4gICAgJ2xlbW9uY2hpZmZvbic6JyNmZmZhY2QnLFxuICAgICdsaWdodGJsdWUnOicjYWRkOGU2JyxcbiAgICAnbGlnaHRjb3JhbCc6JyNmMDgwODAnLFxuICAgICdsaWdodGN5YW4nOicjZTBmZmZmJyxcbiAgICAnbGlnaHRnb2xkZW5yb2R5ZWxsb3cnOicjZmFmYWQyJyxcbiAgICAnbGlnaHRncmF5JzonI2QzZDNkMycsXG4gICAgJ2xpZ2h0Z3JleSc6JyNkM2QzZDMnLFxuICAgICdsaWdodGdyZWVuJzonIzkwZWU5MCcsXG4gICAgJ2xpZ2h0cGluayc6JyNmZmI2YzEnLFxuICAgICdsaWdodHNhbG1vbic6JyNmZmEwN2EnLFxuICAgICdsaWdodHNlYWdyZWVuJzonIzIwYjJhYScsXG4gICAgJ2xpZ2h0c2t5Ymx1ZSc6JyM4N2NlZmEnLFxuICAgICdsaWdodHNsYXRlZ3JheSc6JyM3Nzg4OTknLFxuICAgICdsaWdodHNsYXRlZ3JleSc6JyM3Nzg4OTknLFxuICAgICdsaWdodHN0ZWVsYmx1ZSc6JyNiMGM0ZGUnLFxuICAgICdsaWdodHllbGxvdyc6JyNmZmZmZTAnLFxuICAgICdsaW1lJzonIzAwZmYwMCcsXG4gICAgJ2xpbWVncmVlbic6JyMzMmNkMzInLFxuICAgICdsaW5lbic6JyNmYWYwZTYnLFxuICAgICdtYWdlbnRhJzonI2ZmMDBmZicsXG4gICAgJ21hcm9vbic6JyM4MDAwMDAnLFxuICAgICdtZWRpdW1hcXVhbWFyaW5lJzonIzY2Y2RhYScsXG4gICAgJ21lZGl1bWJsdWUnOicjMDAwMGNkJyxcbiAgICAnbWVkaXVtb3JjaGlkJzonI2JhNTVkMycsXG4gICAgJ21lZGl1bXB1cnBsZSc6JyM5MzcwZDgnLFxuICAgICdtZWRpdW1zZWFncmVlbic6JyMzY2IzNzEnLFxuICAgICdtZWRpdW1zbGF0ZWJsdWUnOicjN2I2OGVlJyxcbiAgICAnbWVkaXVtc3ByaW5nZ3JlZW4nOicjMDBmYTlhJyxcbiAgICAnbWVkaXVtdHVycXVvaXNlJzonIzQ4ZDFjYycsXG4gICAgJ21lZGl1bXZpb2xldHJlZCc6JyNjNzE1ODUnLFxuICAgICdtaWRuaWdodGJsdWUnOicjMTkxOTcwJyxcbiAgICAnbWludGNyZWFtJzonI2Y1ZmZmYScsXG4gICAgJ21pc3R5cm9zZSc6JyNmZmU0ZTEnLFxuICAgICdtb2NjYXNpbic6JyNmZmU0YjUnLFxuICAgICduYXZham93aGl0ZSc6JyNmZmRlYWQnLFxuICAgICduYXZ5JzonIzAwMDA4MCcsXG4gICAgJ29sZGxhY2UnOicjZmRmNWU2JyxcbiAgICAnb2xpdmUnOicjODA4MDAwJyxcbiAgICAnb2xpdmVkcmFiJzonIzZiOGUyMycsXG4gICAgJ29yYW5nZSc6JyNmZmE1MDAnLFxuICAgICdvcmFuZ2VyZWQnOicjZmY0NTAwJyxcbiAgICAnb3JjaGlkJzonI2RhNzBkNicsXG4gICAgJ3BhbGVnb2xkZW5yb2QnOicjZWVlOGFhJyxcbiAgICAncGFsZWdyZWVuJzonIzk4ZmI5OCcsXG4gICAgJ3BhbGV0dXJxdW9pc2UnOicjYWZlZWVlJyxcbiAgICAncGFsZXZpb2xldHJlZCc6JyNkODcwOTMnLFxuICAgICdwYXBheWF3aGlwJzonI2ZmZWZkNScsXG4gICAgJ3BlYWNocHVmZic6JyNmZmRhYjknLFxuICAgICdwZXJ1JzonI2NkODUzZicsXG4gICAgJ3BpbmsnOicjZmZjMGNiJyxcbiAgICAncGx1bSc6JyNkZGEwZGQnLFxuICAgICdwb3dkZXJibHVlJzonI2IwZTBlNicsXG4gICAgJ3B1cnBsZSc6JyM4MDAwODAnLFxuICAgICdyZWJlY2NhcHVycGxlJzonIzY2MzM5OScsXG4gICAgJ3JlZCc6JyNmZjAwMDAnLFxuICAgICdyb3N5YnJvd24nOicjYmM4ZjhmJyxcbiAgICAncm95YWxibHVlJzonIzQxNjllMScsXG4gICAgJ3NhZGRsZWJyb3duJzonIzhiNDUxMycsXG4gICAgJ3NhbG1vbic6JyNmYTgwNzInLFxuICAgICdzYW5keWJyb3duJzonI2Y0YTQ2MCcsXG4gICAgJ3NlYWdyZWVuJzonIzJlOGI1NycsXG4gICAgJ3NlYXNoZWxsJzonI2ZmZjVlZScsXG4gICAgJ3NpZW5uYSc6JyNhMDUyMmQnLFxuICAgICdzaWx2ZXInOicjYzBjMGMwJyxcbiAgICAnc2t5Ymx1ZSc6JyM4N2NlZWInLFxuICAgICdzbGF0ZWJsdWUnOicjNmE1YWNkJyxcbiAgICAnc2xhdGVncmF5JzonIzcwODA5MCcsXG4gICAgJ3NsYXRlZ3JleSc6JyM3MDgwOTAnLFxuICAgICdzbm93JzonI2ZmZmFmYScsXG4gICAgJ3NwcmluZ2dyZWVuJzonIzAwZmY3ZicsXG4gICAgJ3N0ZWVsYmx1ZSc6JyM0NjgyYjQnLFxuICAgICd0YW4nOicjZDJiNDhjJyxcbiAgICAndGVhbCc6JyMwMDgwODAnLFxuICAgICd0aGlzdGxlJzonI2Q4YmZkOCcsXG4gICAgJ3RvbWF0byc6JyNmZjYzNDcnLFxuICAgICd0dXJxdW9pc2UnOicjNDBlMGQwJyxcbiAgICAndmlvbGV0JzonI2VlODJlZScsXG4gICAgJ3doZWF0JzonI2Y1ZGViMycsXG4gICAgJ3doaXRlJzonI2ZmZmZmZicsXG4gICAgJ3doaXRlc21va2UnOicjZjVmNWY1JyxcbiAgICAneWVsbG93JzonI2ZmZmYwMCcsXG4gICAgJ3llbGxvd2dyZWVuJzonIzlhY2QzMidcbn07XG59LHt9XSwxMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBjb2xvcnM6IHJlcXVpcmUoXCIuL2NvbG9yc1wiKSxcbiAgICB1bml0Q29udmVyc2lvbnM6IHJlcXVpcmUoXCIuL3VuaXQtY29udmVyc2lvbnNcIilcbn07XG5cbn0se1wiLi9jb2xvcnNcIjoxMixcIi4vdW5pdC1jb252ZXJzaW9uc1wiOjE0fV0sMTQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgbGVuZ3RoOiB7XG4gICAgICAgICdtJzogMSxcbiAgICAgICAgJ2NtJzogMC4wMSxcbiAgICAgICAgJ21tJzogMC4wMDEsXG4gICAgICAgICdpbic6IDAuMDI1NCxcbiAgICAgICAgJ3B4JzogMC4wMjU0IC8gOTYsXG4gICAgICAgICdwdCc6IDAuMDI1NCAvIDcyLFxuICAgICAgICAncGMnOiAwLjAyNTQgLyA3MiAqIDEyXG4gICAgfSxcbiAgICBkdXJhdGlvbjoge1xuICAgICAgICAncyc6IDEsXG4gICAgICAgICdtcyc6IDAuMDAxXG4gICAgfSxcbiAgICBhbmdsZToge1xuICAgICAgICAncmFkJzogMSAvICgyICogTWF0aC5QSSksXG4gICAgICAgICdkZWcnOiAxIC8gMzYwLFxuICAgICAgICAnZ3JhZCc6IDEgLyA0MDAsXG4gICAgICAgICd0dXJuJzogMVxuICAgIH1cbn07XG59LHt9XSwxNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgYWJzdHJhY3RGaWxlTWFuYWdlciA9IGZ1bmN0aW9uKCkge1xufTtcblxuYWJzdHJhY3RGaWxlTWFuYWdlci5wcm90b3R5cGUuZ2V0UGF0aCA9IGZ1bmN0aW9uIChmaWxlbmFtZSkge1xuICAgIHZhciBqID0gZmlsZW5hbWUubGFzdEluZGV4T2YoJz8nKTtcbiAgICBpZiAoaiA+IDApIHtcbiAgICAgICAgZmlsZW5hbWUgPSBmaWxlbmFtZS5zbGljZSgwLCBqKTtcbiAgICB9XG4gICAgaiA9IGZpbGVuYW1lLmxhc3RJbmRleE9mKCcvJyk7XG4gICAgaWYgKGogPCAwKSB7XG4gICAgICAgIGogPSBmaWxlbmFtZS5sYXN0SW5kZXhPZignXFxcXCcpO1xuICAgIH1cbiAgICBpZiAoaiA8IDApIHtcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgfVxuICAgIHJldHVybiBmaWxlbmFtZS5zbGljZSgwLCBqICsgMSk7XG59O1xuXG5hYnN0cmFjdEZpbGVNYW5hZ2VyLnByb3RvdHlwZS50cnlBcHBlbmRFeHRlbnNpb24gPSBmdW5jdGlvbihwYXRoLCBleHQpIHtcbiAgICByZXR1cm4gLyhcXC5bYS16XSokKXwoW1xcPztdLiopJC8udGVzdChwYXRoKSA/IHBhdGggOiBwYXRoICsgZXh0O1xufTtcblxuYWJzdHJhY3RGaWxlTWFuYWdlci5wcm90b3R5cGUudHJ5QXBwZW5kTGVzc0V4dGVuc2lvbiA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgICByZXR1cm4gdGhpcy50cnlBcHBlbmRFeHRlbnNpb24ocGF0aCwgJy5sZXNzJyk7XG59O1xuXG5hYnN0cmFjdEZpbGVNYW5hZ2VyLnByb3RvdHlwZS5zdXBwb3J0c1N5bmMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5hYnN0cmFjdEZpbGVNYW5hZ2VyLnByb3RvdHlwZS5hbHdheXNNYWtlUGF0aHNBYnNvbHV0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBmYWxzZTtcbn07XG5cbmFic3RyYWN0RmlsZU1hbmFnZXIucHJvdG90eXBlLmlzUGF0aEFic29sdXRlID0gZnVuY3Rpb24oZmlsZW5hbWUpIHtcbiAgICByZXR1cm4gKC9eKD86W2Etei1dKzp8XFwvfFxcXFx8IykvaSkudGVzdChmaWxlbmFtZSk7XG59O1xuXG5hYnN0cmFjdEZpbGVNYW5hZ2VyLnByb3RvdHlwZS5qb2luID0gZnVuY3Rpb24oYmFzZVBhdGgsIGxhdGVyUGF0aCkge1xuICAgIGlmICghYmFzZVBhdGgpIHtcbiAgICAgICAgcmV0dXJuIGxhdGVyUGF0aDtcbiAgICB9XG4gICAgcmV0dXJuIGJhc2VQYXRoICsgbGF0ZXJQYXRoO1xufTtcbmFic3RyYWN0RmlsZU1hbmFnZXIucHJvdG90eXBlLnBhdGhEaWZmID0gZnVuY3Rpb24gcGF0aERpZmYodXJsLCBiYXNlVXJsKSB7XG4gICAgLy8gZGlmZiBiZXR3ZWVuIHR3byBwYXRocyB0byBjcmVhdGUgYSByZWxhdGl2ZSBwYXRoXG5cbiAgICB2YXIgdXJsUGFydHMgPSB0aGlzLmV4dHJhY3RVcmxQYXJ0cyh1cmwpLFxuICAgICAgICBiYXNlVXJsUGFydHMgPSB0aGlzLmV4dHJhY3RVcmxQYXJ0cyhiYXNlVXJsKSxcbiAgICAgICAgaSwgbWF4LCB1cmxEaXJlY3RvcmllcywgYmFzZVVybERpcmVjdG9yaWVzLCBkaWZmID0gXCJcIjtcbiAgICBpZiAodXJsUGFydHMuaG9zdFBhcnQgIT09IGJhc2VVcmxQYXJ0cy5ob3N0UGFydCkge1xuICAgICAgICByZXR1cm4gXCJcIjtcbiAgICB9XG4gICAgbWF4ID0gTWF0aC5tYXgoYmFzZVVybFBhcnRzLmRpcmVjdG9yaWVzLmxlbmd0aCwgdXJsUGFydHMuZGlyZWN0b3JpZXMubGVuZ3RoKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbWF4OyBpKyspIHtcbiAgICAgICAgaWYgKGJhc2VVcmxQYXJ0cy5kaXJlY3Rvcmllc1tpXSAhPT0gdXJsUGFydHMuZGlyZWN0b3JpZXNbaV0pIHsgYnJlYWs7IH1cbiAgICB9XG4gICAgYmFzZVVybERpcmVjdG9yaWVzID0gYmFzZVVybFBhcnRzLmRpcmVjdG9yaWVzLnNsaWNlKGkpO1xuICAgIHVybERpcmVjdG9yaWVzID0gdXJsUGFydHMuZGlyZWN0b3JpZXMuc2xpY2UoaSk7XG4gICAgZm9yIChpID0gMDsgaSA8IGJhc2VVcmxEaXJlY3Rvcmllcy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgZGlmZiArPSBcIi4uL1wiO1xuICAgIH1cbiAgICBmb3IgKGkgPSAwOyBpIDwgdXJsRGlyZWN0b3JpZXMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGRpZmYgKz0gdXJsRGlyZWN0b3JpZXNbaV0gKyBcIi9cIjtcbiAgICB9XG4gICAgcmV0dXJuIGRpZmY7XG59O1xuLy8gaGVscGVyIGZ1bmN0aW9uLCBub3QgcGFydCBvZiBBUElcbmFic3RyYWN0RmlsZU1hbmFnZXIucHJvdG90eXBlLmV4dHJhY3RVcmxQYXJ0cyA9IGZ1bmN0aW9uIGV4dHJhY3RVcmxQYXJ0cyh1cmwsIGJhc2VVcmwpIHtcbiAgICAvLyB1cmxQYXJ0c1sxXSA9IHByb3RvY29sOi8vaG9zdG5hbWUvIE9SIC9cbiAgICAvLyB1cmxQYXJ0c1syXSA9IC8gaWYgcGF0aCByZWxhdGl2ZSB0byBob3N0IGJhc2VcbiAgICAvLyB1cmxQYXJ0c1szXSA9IGRpcmVjdG9yaWVzXG4gICAgLy8gdXJsUGFydHNbNF0gPSBmaWxlbmFtZVxuICAgIC8vIHVybFBhcnRzWzVdID0gcGFyYW1ldGVyc1xuXG4gICAgdmFyIHVybFBhcnRzUmVnZXggPSAvXigoPzpbYS16LV0rOik/XFwvezJ9KD86W15cXC9cXD8jXSpcXC8pfChbXFwvXFxcXF0pKT8oKD86W15cXC9cXFxcXFw/I10qW1xcL1xcXFxdKSopKFteXFwvXFxcXFxcPyNdKikoWyNcXD9dLiopPyQvaSxcbiAgICAgICAgdXJsUGFydHMgPSB1cmwubWF0Y2godXJsUGFydHNSZWdleCksXG4gICAgICAgIHJldHVybmVyID0ge30sIGRpcmVjdG9yaWVzID0gW10sIGksIGJhc2VVcmxQYXJ0cztcblxuICAgIGlmICghdXJsUGFydHMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ291bGQgbm90IHBhcnNlIHNoZWV0IGhyZWYgLSAnXCIgKyB1cmwgKyBcIidcIik7XG4gICAgfVxuXG4gICAgLy8gU3R5bGVzaGVldHMgaW4gSUUgZG9uJ3QgYWx3YXlzIHJldHVybiB0aGUgZnVsbCBwYXRoXG4gICAgaWYgKGJhc2VVcmwgJiYgKCF1cmxQYXJ0c1sxXSB8fCB1cmxQYXJ0c1syXSkpIHtcbiAgICAgICAgYmFzZVVybFBhcnRzID0gYmFzZVVybC5tYXRjaCh1cmxQYXJ0c1JlZ2V4KTtcbiAgICAgICAgaWYgKCFiYXNlVXJsUGFydHMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCBwYXJzZSBwYWdlIHVybCAtICdcIiArIGJhc2VVcmwgKyBcIidcIik7XG4gICAgICAgIH1cbiAgICAgICAgdXJsUGFydHNbMV0gPSB1cmxQYXJ0c1sxXSB8fCBiYXNlVXJsUGFydHNbMV0gfHwgXCJcIjtcbiAgICAgICAgaWYgKCF1cmxQYXJ0c1syXSkge1xuICAgICAgICAgICAgdXJsUGFydHNbM10gPSBiYXNlVXJsUGFydHNbM10gKyB1cmxQYXJ0c1szXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICh1cmxQYXJ0c1szXSkge1xuICAgICAgICBkaXJlY3RvcmllcyA9IHVybFBhcnRzWzNdLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpLnNwbGl0KFwiL1wiKTtcblxuICAgICAgICAvLyBleHRyYWN0IG91dCAuIGJlZm9yZSAuLiBzbyAuLiBkb2Vzbid0IGFic29yYiBhIG5vbi1kaXJlY3RvcnlcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGRpcmVjdG9yaWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoZGlyZWN0b3JpZXNbaV0gPT09IFwiLlwiKSB7XG4gICAgICAgICAgICAgICAgZGlyZWN0b3JpZXMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBkaXJlY3Rvcmllcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGRpcmVjdG9yaWVzW2ldID09PSBcIi4uXCIgJiYgaSA+IDApIHtcbiAgICAgICAgICAgICAgICBkaXJlY3Rvcmllcy5zcGxpY2UoaSAtIDEsIDIpO1xuICAgICAgICAgICAgICAgIGkgLT0gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybmVyLmhvc3RQYXJ0ID0gdXJsUGFydHNbMV07XG4gICAgcmV0dXJuZXIuZGlyZWN0b3JpZXMgPSBkaXJlY3RvcmllcztcbiAgICByZXR1cm5lci5wYXRoID0gKHVybFBhcnRzWzFdIHx8IFwiXCIpICsgZGlyZWN0b3JpZXMuam9pbihcIi9cIik7XG4gICAgcmV0dXJuZXIuZmlsZVVybCA9IHJldHVybmVyLnBhdGggKyAodXJsUGFydHNbNF0gfHwgXCJcIik7XG4gICAgcmV0dXJuZXIudXJsID0gcmV0dXJuZXIuZmlsZVVybCArICh1cmxQYXJ0c1s1XSB8fCBcIlwiKTtcbiAgICByZXR1cm4gcmV0dXJuZXI7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGFic3RyYWN0RmlsZU1hbmFnZXI7XG5cbn0se31dLDE2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBsb2dnZXIgPSByZXF1aXJlKFwiLi4vbG9nZ2VyXCIpO1xudmFyIGVudmlyb25tZW50ID0gZnVuY3Rpb24oZXh0ZXJuYWxFbnZpcm9ubWVudCwgZmlsZU1hbmFnZXJzKSB7XG4gICAgdGhpcy5maWxlTWFuYWdlcnMgPSBmaWxlTWFuYWdlcnMgfHwgW107XG4gICAgZXh0ZXJuYWxFbnZpcm9ubWVudCA9IGV4dGVybmFsRW52aXJvbm1lbnQgfHwge307XG5cbiAgICB2YXIgb3B0aW9uYWxGdW5jdGlvbnMgPSBbXCJlbmNvZGVCYXNlNjRcIiwgXCJtaW1lTG9va3VwXCIsIFwiY2hhcnNldExvb2t1cFwiLCBcImdldFNvdXJjZU1hcEdlbmVyYXRvclwiXSxcbiAgICAgICAgcmVxdWlyZWRGdW5jdGlvbnMgPSBbXSxcbiAgICAgICAgZnVuY3Rpb25zID0gcmVxdWlyZWRGdW5jdGlvbnMuY29uY2F0KG9wdGlvbmFsRnVuY3Rpb25zKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZnVuY3Rpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBwcm9wTmFtZSA9IGZ1bmN0aW9uc1tpXSxcbiAgICAgICAgICAgIGVudmlyb25tZW50RnVuYyA9IGV4dGVybmFsRW52aXJvbm1lbnRbcHJvcE5hbWVdO1xuICAgICAgICBpZiAoZW52aXJvbm1lbnRGdW5jKSB7XG4gICAgICAgICAgICB0aGlzW3Byb3BOYW1lXSA9IGVudmlyb25tZW50RnVuYy5iaW5kKGV4dGVybmFsRW52aXJvbm1lbnQpO1xuICAgICAgICB9IGVsc2UgaWYgKGkgPCByZXF1aXJlZEZ1bmN0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMud2FybihcIm1pc3NpbmcgcmVxdWlyZWQgZnVuY3Rpb24gaW4gZW52aXJvbm1lbnQgLSBcIiArIHByb3BOYW1lKTtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbmVudmlyb25tZW50LnByb3RvdHlwZS5nZXRGaWxlTWFuYWdlciA9IGZ1bmN0aW9uIChmaWxlbmFtZSwgY3VycmVudERpcmVjdG9yeSwgb3B0aW9ucywgZW52aXJvbm1lbnQsIGlzU3luYykge1xuXG4gICAgaWYgKCFmaWxlbmFtZSkge1xuICAgICAgICBsb2dnZXIud2FybihcImdldEZpbGVNYW5hZ2VyIGNhbGxlZCB3aXRoIG5vIGZpbGVuYW1lLi4gUGxlYXNlIHJlcG9ydCB0aGlzIGlzc3VlLiBjb250aW51aW5nLlwiKTtcbiAgICB9XG4gICAgaWYgKGN1cnJlbnREaXJlY3RvcnkgPT0gbnVsbCkge1xuICAgICAgICBsb2dnZXIud2FybihcImdldEZpbGVNYW5hZ2VyIGNhbGxlZCB3aXRoIG51bGwgZGlyZWN0b3J5Li4gUGxlYXNlIHJlcG9ydCB0aGlzIGlzc3VlLiBjb250aW51aW5nLlwiKTtcbiAgICB9XG5cbiAgICB2YXIgZmlsZU1hbmFnZXJzID0gdGhpcy5maWxlTWFuYWdlcnM7XG4gICAgaWYgKG9wdGlvbnMucGx1Z2luTWFuYWdlcikge1xuICAgICAgICBmaWxlTWFuYWdlcnMgPSBbXS5jb25jYXQoZmlsZU1hbmFnZXJzKS5jb25jYXQob3B0aW9ucy5wbHVnaW5NYW5hZ2VyLmdldEZpbGVNYW5hZ2VycygpKTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IGZpbGVNYW5hZ2Vycy5sZW5ndGggLSAxOyBpID49IDAgOyBpLS0pIHtcbiAgICAgICAgdmFyIGZpbGVNYW5hZ2VyID0gZmlsZU1hbmFnZXJzW2ldO1xuICAgICAgICBpZiAoZmlsZU1hbmFnZXJbaXNTeW5jID8gXCJzdXBwb3J0c1N5bmNcIiA6IFwic3VwcG9ydHNcIl0oZmlsZW5hbWUsIGN1cnJlbnREaXJlY3RvcnksIG9wdGlvbnMsIGVudmlyb25tZW50KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZpbGVNYW5hZ2VyO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcblxuZW52aXJvbm1lbnQucHJvdG90eXBlLmFkZEZpbGVNYW5hZ2VyID0gZnVuY3Rpb24gKGZpbGVNYW5hZ2VyKSB7XG4gICAgdGhpcy5maWxlTWFuYWdlcnMucHVzaChmaWxlTWFuYWdlcik7XG59O1xuXG5lbnZpcm9ubWVudC5wcm90b3R5cGUuY2xlYXJGaWxlTWFuYWdlcnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5maWxlTWFuYWdlcnMgPSBbXTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZW52aXJvbm1lbnQ7XG5cbn0se1wiLi4vbG9nZ2VyXCI6MzN9XSwxNzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgQ29sb3IgPSByZXF1aXJlKFwiLi4vdHJlZS9jb2xvclwiKSxcbiAgICBmdW5jdGlvblJlZ2lzdHJ5ID0gcmVxdWlyZShcIi4vZnVuY3Rpb24tcmVnaXN0cnlcIik7XG5cbi8vIENvbG9yIEJsZW5kaW5nXG4vLyByZWY6IGh0dHA6Ly93d3cudzMub3JnL1RSL2NvbXBvc2l0aW5nLTFcblxuZnVuY3Rpb24gY29sb3JCbGVuZChtb2RlLCBjb2xvcjEsIGNvbG9yMikge1xuICAgIHZhciBhYiA9IGNvbG9yMS5hbHBoYSwgY2IsIC8vIGJhY2tkcm9wXG4gICAgICAgIGFzID0gY29sb3IyLmFscGhhLCBjcywgLy8gc291cmNlXG4gICAgICAgIGFyLCBjciwgciA9IFtdOyAgICAgICAgLy8gcmVzdWx0XG5cbiAgICBhciA9IGFzICsgYWIgKiAoMSAtIGFzKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDM7IGkrKykge1xuICAgICAgICBjYiA9IGNvbG9yMS5yZ2JbaV0gLyAyNTU7XG4gICAgICAgIGNzID0gY29sb3IyLnJnYltpXSAvIDI1NTtcbiAgICAgICAgY3IgPSBtb2RlKGNiLCBjcyk7XG4gICAgICAgIGlmIChhcikge1xuICAgICAgICAgICAgY3IgPSAoYXMgKiBjcyArIGFiICogKGNiIC1cbiAgICAgICAgICAgICAgICAgIGFzICogKGNiICsgY3MgLSBjcikpKSAvIGFyO1xuICAgICAgICB9XG4gICAgICAgIHJbaV0gPSBjciAqIDI1NTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IENvbG9yKHIsIGFyKTtcbn1cblxudmFyIGNvbG9yQmxlbmRNb2RlRnVuY3Rpb25zID0ge1xuICAgIG11bHRpcGx5OiBmdW5jdGlvbihjYiwgY3MpIHtcbiAgICAgICAgcmV0dXJuIGNiICogY3M7XG4gICAgfSxcbiAgICBzY3JlZW46IGZ1bmN0aW9uKGNiLCBjcykge1xuICAgICAgICByZXR1cm4gY2IgKyBjcyAtIGNiICogY3M7XG4gICAgfSxcbiAgICBvdmVybGF5OiBmdW5jdGlvbihjYiwgY3MpIHtcbiAgICAgICAgY2IgKj0gMjtcbiAgICAgICAgcmV0dXJuIChjYiA8PSAxKSA/XG4gICAgICAgICAgICBjb2xvckJsZW5kTW9kZUZ1bmN0aW9ucy5tdWx0aXBseShjYiwgY3MpIDpcbiAgICAgICAgICAgIGNvbG9yQmxlbmRNb2RlRnVuY3Rpb25zLnNjcmVlbihjYiAtIDEsIGNzKTtcbiAgICB9LFxuICAgIHNvZnRsaWdodDogZnVuY3Rpb24oY2IsIGNzKSB7XG4gICAgICAgIHZhciBkID0gMSwgZSA9IGNiO1xuICAgICAgICBpZiAoY3MgPiAwLjUpIHtcbiAgICAgICAgICAgIGUgPSAxO1xuICAgICAgICAgICAgZCA9IChjYiA+IDAuMjUpID8gTWF0aC5zcXJ0KGNiKVxuICAgICAgICAgICAgICAgIDogKCgxNiAqIGNiIC0gMTIpICogY2IgKyA0KSAqIGNiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYiAtICgxIC0gMiAqIGNzKSAqIGUgKiAoZCAtIGNiKTtcbiAgICB9LFxuICAgIGhhcmRsaWdodDogZnVuY3Rpb24oY2IsIGNzKSB7XG4gICAgICAgIHJldHVybiBjb2xvckJsZW5kTW9kZUZ1bmN0aW9ucy5vdmVybGF5KGNzLCBjYik7XG4gICAgfSxcbiAgICBkaWZmZXJlbmNlOiBmdW5jdGlvbihjYiwgY3MpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguYWJzKGNiIC0gY3MpO1xuICAgIH0sXG4gICAgZXhjbHVzaW9uOiBmdW5jdGlvbihjYiwgY3MpIHtcbiAgICAgICAgcmV0dXJuIGNiICsgY3MgLSAyICogY2IgKiBjcztcbiAgICB9LFxuXG4gICAgLy8gbm9uLXczYyBmdW5jdGlvbnM6XG4gICAgYXZlcmFnZTogZnVuY3Rpb24oY2IsIGNzKSB7XG4gICAgICAgIHJldHVybiAoY2IgKyBjcykgLyAyO1xuICAgIH0sXG4gICAgbmVnYXRpb246IGZ1bmN0aW9uKGNiLCBjcykge1xuICAgICAgICByZXR1cm4gMSAtIE1hdGguYWJzKGNiICsgY3MgLSAxKTtcbiAgICB9XG59O1xuXG5mb3IgKHZhciBmIGluIGNvbG9yQmxlbmRNb2RlRnVuY3Rpb25zKSB7XG4gICAgaWYgKGNvbG9yQmxlbmRNb2RlRnVuY3Rpb25zLmhhc093blByb3BlcnR5KGYpKSB7XG4gICAgICAgIGNvbG9yQmxlbmRbZl0gPSBjb2xvckJsZW5kLmJpbmQobnVsbCwgY29sb3JCbGVuZE1vZGVGdW5jdGlvbnNbZl0pO1xuICAgIH1cbn1cblxuZnVuY3Rpb25SZWdpc3RyeS5hZGRNdWx0aXBsZShjb2xvckJsZW5kKTtcblxufSx7XCIuLi90cmVlL2NvbG9yXCI6NTAsXCIuL2Z1bmN0aW9uLXJlZ2lzdHJ5XCI6MjJ9XSwxODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgRGltZW5zaW9uID0gcmVxdWlyZShcIi4uL3RyZWUvZGltZW5zaW9uXCIpLFxuICAgIENvbG9yID0gcmVxdWlyZShcIi4uL3RyZWUvY29sb3JcIiksXG4gICAgUXVvdGVkID0gcmVxdWlyZShcIi4uL3RyZWUvcXVvdGVkXCIpLFxuICAgIEFub255bW91cyA9IHJlcXVpcmUoXCIuLi90cmVlL2Fub255bW91c1wiKSxcbiAgICBmdW5jdGlvblJlZ2lzdHJ5ID0gcmVxdWlyZShcIi4vZnVuY3Rpb24tcmVnaXN0cnlcIiksXG4gICAgY29sb3JGdW5jdGlvbnM7XG5cbmZ1bmN0aW9uIGNsYW1wKHZhbCkge1xuICAgIHJldHVybiBNYXRoLm1pbigxLCBNYXRoLm1heCgwLCB2YWwpKTtcbn1cbmZ1bmN0aW9uIGhzbGEoY29sb3IpIHtcbiAgICByZXR1cm4gY29sb3JGdW5jdGlvbnMuaHNsYShjb2xvci5oLCBjb2xvci5zLCBjb2xvci5sLCBjb2xvci5hKTtcbn1cbmZ1bmN0aW9uIG51bWJlcihuKSB7XG4gICAgaWYgKG4gaW5zdGFuY2VvZiBEaW1lbnNpb24pIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlRmxvYXQobi51bml0LmlzKCclJykgPyBuLnZhbHVlIC8gMTAwIDogbi52YWx1ZSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgbiA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIG47XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cge1xuICAgICAgICAgICAgdHlwZTogXCJBcmd1bWVudFwiLFxuICAgICAgICAgICAgbWVzc2FnZTogXCJjb2xvciBmdW5jdGlvbnMgdGFrZSBudW1iZXJzIGFzIHBhcmFtZXRlcnNcIlxuICAgICAgICB9O1xuICAgIH1cbn1cbmZ1bmN0aW9uIHNjYWxlZChuLCBzaXplKSB7XG4gICAgaWYgKG4gaW5zdGFuY2VvZiBEaW1lbnNpb24gJiYgbi51bml0LmlzKCclJykpIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlRmxvYXQobi52YWx1ZSAqIHNpemUgLyAxMDApO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudW1iZXIobik7XG4gICAgfVxufVxuY29sb3JGdW5jdGlvbnMgPSB7XG4gICAgcmdiOiBmdW5jdGlvbiAociwgZywgYikge1xuICAgICAgICByZXR1cm4gY29sb3JGdW5jdGlvbnMucmdiYShyLCBnLCBiLCAxLjApO1xuICAgIH0sXG4gICAgcmdiYTogZnVuY3Rpb24gKHIsIGcsIGIsIGEpIHtcbiAgICAgICAgdmFyIHJnYiA9IFtyLCBnLCBiXS5tYXAoZnVuY3Rpb24gKGMpIHsgcmV0dXJuIHNjYWxlZChjLCAyNTUpOyB9KTtcbiAgICAgICAgYSA9IG51bWJlcihhKTtcbiAgICAgICAgcmV0dXJuIG5ldyBDb2xvcihyZ2IsIGEpO1xuICAgIH0sXG4gICAgaHNsOiBmdW5jdGlvbiAoaCwgcywgbCkge1xuICAgICAgICByZXR1cm4gY29sb3JGdW5jdGlvbnMuaHNsYShoLCBzLCBsLCAxLjApO1xuICAgIH0sXG4gICAgaHNsYTogZnVuY3Rpb24gKGgsIHMsIGwsIGEpIHtcblxuICAgICAgICB2YXIgbTEsIG0yO1xuXG4gICAgICAgIGZ1bmN0aW9uIGh1ZShoKSB7XG4gICAgICAgICAgICBoID0gaCA8IDAgPyBoICsgMSA6IChoID4gMSA/IGggLSAxIDogaCk7XG4gICAgICAgICAgICBpZiAoaCAqIDYgPCAxKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG0xICsgKG0yIC0gbTEpICogaCAqIDY7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChoICogMiA8IDEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbTI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChoICogMyA8IDIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbTEgKyAobTIgLSBtMSkgKiAoMiAvIDMgLSBoKSAqIDY7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbTE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBoID0gKG51bWJlcihoKSAlIDM2MCkgLyAzNjA7XG4gICAgICAgIHMgPSBjbGFtcChudW1iZXIocykpOyBsID0gY2xhbXAobnVtYmVyKGwpKTsgYSA9IGNsYW1wKG51bWJlcihhKSk7XG5cbiAgICAgICAgbTIgPSBsIDw9IDAuNSA/IGwgKiAocyArIDEpIDogbCArIHMgLSBsICogcztcbiAgICAgICAgbTEgPSBsICogMiAtIG0yO1xuXG4gICAgICAgIHJldHVybiBjb2xvckZ1bmN0aW9ucy5yZ2JhKGh1ZShoICsgMSAvIDMpICogMjU1LFxuICAgICAgICAgICAgaHVlKGgpICAgICAgICogMjU1LFxuICAgICAgICAgICAgaHVlKGggLSAxIC8gMykgKiAyNTUsXG4gICAgICAgICAgICBhKTtcbiAgICB9LFxuXG4gICAgaHN2OiBmdW5jdGlvbihoLCBzLCB2KSB7XG4gICAgICAgIHJldHVybiBjb2xvckZ1bmN0aW9ucy5oc3ZhKGgsIHMsIHYsIDEuMCk7XG4gICAgfSxcblxuICAgIGhzdmE6IGZ1bmN0aW9uKGgsIHMsIHYsIGEpIHtcbiAgICAgICAgaCA9ICgobnVtYmVyKGgpICUgMzYwKSAvIDM2MCkgKiAzNjA7XG4gICAgICAgIHMgPSBudW1iZXIocyk7IHYgPSBudW1iZXIodik7IGEgPSBudW1iZXIoYSk7XG5cbiAgICAgICAgdmFyIGksIGY7XG4gICAgICAgIGkgPSBNYXRoLmZsb29yKChoIC8gNjApICUgNik7XG4gICAgICAgIGYgPSAoaCAvIDYwKSAtIGk7XG5cbiAgICAgICAgdmFyIHZzID0gW3YsXG4gICAgICAgICAgICB2ICogKDEgLSBzKSxcbiAgICAgICAgICAgIHYgKiAoMSAtIGYgKiBzKSxcbiAgICAgICAgICAgIHYgKiAoMSAtICgxIC0gZikgKiBzKV07XG4gICAgICAgIHZhciBwZXJtID0gW1swLCAzLCAxXSxcbiAgICAgICAgICAgIFsyLCAwLCAxXSxcbiAgICAgICAgICAgIFsxLCAwLCAzXSxcbiAgICAgICAgICAgIFsxLCAyLCAwXSxcbiAgICAgICAgICAgIFszLCAxLCAwXSxcbiAgICAgICAgICAgIFswLCAxLCAyXV07XG5cbiAgICAgICAgcmV0dXJuIGNvbG9yRnVuY3Rpb25zLnJnYmEodnNbcGVybVtpXVswXV0gKiAyNTUsXG4gICAgICAgICAgICB2c1twZXJtW2ldWzFdXSAqIDI1NSxcbiAgICAgICAgICAgIHZzW3Blcm1baV1bMl1dICogMjU1LFxuICAgICAgICAgICAgYSk7XG4gICAgfSxcblxuICAgIGh1ZTogZnVuY3Rpb24gKGNvbG9yKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGltZW5zaW9uKGNvbG9yLnRvSFNMKCkuaCk7XG4gICAgfSxcbiAgICBzYXR1cmF0aW9uOiBmdW5jdGlvbiAoY29sb3IpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEaW1lbnNpb24oY29sb3IudG9IU0woKS5zICogMTAwLCAnJScpO1xuICAgIH0sXG4gICAgbGlnaHRuZXNzOiBmdW5jdGlvbiAoY29sb3IpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEaW1lbnNpb24oY29sb3IudG9IU0woKS5sICogMTAwLCAnJScpO1xuICAgIH0sXG4gICAgaHN2aHVlOiBmdW5jdGlvbihjb2xvcikge1xuICAgICAgICByZXR1cm4gbmV3IERpbWVuc2lvbihjb2xvci50b0hTVigpLmgpO1xuICAgIH0sXG4gICAgaHN2c2F0dXJhdGlvbjogZnVuY3Rpb24gKGNvbG9yKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGltZW5zaW9uKGNvbG9yLnRvSFNWKCkucyAqIDEwMCwgJyUnKTtcbiAgICB9LFxuICAgIGhzdnZhbHVlOiBmdW5jdGlvbiAoY29sb3IpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEaW1lbnNpb24oY29sb3IudG9IU1YoKS52ICogMTAwLCAnJScpO1xuICAgIH0sXG4gICAgcmVkOiBmdW5jdGlvbiAoY29sb3IpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEaW1lbnNpb24oY29sb3IucmdiWzBdKTtcbiAgICB9LFxuICAgIGdyZWVuOiBmdW5jdGlvbiAoY29sb3IpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEaW1lbnNpb24oY29sb3IucmdiWzFdKTtcbiAgICB9LFxuICAgIGJsdWU6IGZ1bmN0aW9uIChjb2xvcikge1xuICAgICAgICByZXR1cm4gbmV3IERpbWVuc2lvbihjb2xvci5yZ2JbMl0pO1xuICAgIH0sXG4gICAgYWxwaGE6IGZ1bmN0aW9uIChjb2xvcikge1xuICAgICAgICByZXR1cm4gbmV3IERpbWVuc2lvbihjb2xvci50b0hTTCgpLmEpO1xuICAgIH0sXG4gICAgbHVtYTogZnVuY3Rpb24gKGNvbG9yKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGltZW5zaW9uKGNvbG9yLmx1bWEoKSAqIGNvbG9yLmFscGhhICogMTAwLCAnJScpO1xuICAgIH0sXG4gICAgbHVtaW5hbmNlOiBmdW5jdGlvbiAoY29sb3IpIHtcbiAgICAgICAgdmFyIGx1bWluYW5jZSA9XG4gICAgICAgICAgICAoMC4yMTI2ICogY29sb3IucmdiWzBdIC8gMjU1KSArXG4gICAgICAgICAgICAgICAgKDAuNzE1MiAqIGNvbG9yLnJnYlsxXSAvIDI1NSkgK1xuICAgICAgICAgICAgICAgICgwLjA3MjIgKiBjb2xvci5yZ2JbMl0gLyAyNTUpO1xuXG4gICAgICAgIHJldHVybiBuZXcgRGltZW5zaW9uKGx1bWluYW5jZSAqIGNvbG9yLmFscGhhICogMTAwLCAnJScpO1xuICAgIH0sXG4gICAgc2F0dXJhdGU6IGZ1bmN0aW9uIChjb2xvciwgYW1vdW50LCBtZXRob2QpIHtcbiAgICAgICAgLy8gZmlsdGVyOiBzYXR1cmF0ZSgzLjIpO1xuICAgICAgICAvLyBzaG91bGQgYmUga2VwdCBhcyBpcywgc28gY2hlY2sgZm9yIGNvbG9yXG4gICAgICAgIGlmICghY29sb3IucmdiKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaHNsID0gY29sb3IudG9IU0woKTtcblxuICAgICAgICBpZiAodHlwZW9mIG1ldGhvZCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtZXRob2QudmFsdWUgPT09IFwicmVsYXRpdmVcIikge1xuICAgICAgICAgICAgaHNsLnMgKz0gIGhzbC5zICogYW1vdW50LnZhbHVlIC8gMTAwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaHNsLnMgKz0gYW1vdW50LnZhbHVlIC8gMTAwO1xuICAgICAgICB9XG4gICAgICAgIGhzbC5zID0gY2xhbXAoaHNsLnMpO1xuICAgICAgICByZXR1cm4gaHNsYShoc2wpO1xuICAgIH0sXG4gICAgZGVzYXR1cmF0ZTogZnVuY3Rpb24gKGNvbG9yLCBhbW91bnQsIG1ldGhvZCkge1xuICAgICAgICB2YXIgaHNsID0gY29sb3IudG9IU0woKTtcblxuICAgICAgICBpZiAodHlwZW9mIG1ldGhvZCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtZXRob2QudmFsdWUgPT09IFwicmVsYXRpdmVcIikge1xuICAgICAgICAgICAgaHNsLnMgLT0gIGhzbC5zICogYW1vdW50LnZhbHVlIC8gMTAwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaHNsLnMgLT0gYW1vdW50LnZhbHVlIC8gMTAwO1xuICAgICAgICB9XG4gICAgICAgIGhzbC5zID0gY2xhbXAoaHNsLnMpO1xuICAgICAgICByZXR1cm4gaHNsYShoc2wpO1xuICAgIH0sXG4gICAgbGlnaHRlbjogZnVuY3Rpb24gKGNvbG9yLCBhbW91bnQsIG1ldGhvZCkge1xuICAgICAgICB2YXIgaHNsID0gY29sb3IudG9IU0woKTtcblxuICAgICAgICBpZiAodHlwZW9mIG1ldGhvZCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtZXRob2QudmFsdWUgPT09IFwicmVsYXRpdmVcIikge1xuICAgICAgICAgICAgaHNsLmwgKz0gIGhzbC5sICogYW1vdW50LnZhbHVlIC8gMTAwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaHNsLmwgKz0gYW1vdW50LnZhbHVlIC8gMTAwO1xuICAgICAgICB9XG4gICAgICAgIGhzbC5sID0gY2xhbXAoaHNsLmwpO1xuICAgICAgICByZXR1cm4gaHNsYShoc2wpO1xuICAgIH0sXG4gICAgZGFya2VuOiBmdW5jdGlvbiAoY29sb3IsIGFtb3VudCwgbWV0aG9kKSB7XG4gICAgICAgIHZhciBoc2wgPSBjb2xvci50b0hTTCgpO1xuXG4gICAgICAgIGlmICh0eXBlb2YgbWV0aG9kICE9PSBcInVuZGVmaW5lZFwiICYmIG1ldGhvZC52YWx1ZSA9PT0gXCJyZWxhdGl2ZVwiKSB7XG4gICAgICAgICAgICBoc2wubCAtPSAgaHNsLmwgKiBhbW91bnQudmFsdWUgLyAxMDA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBoc2wubCAtPSBhbW91bnQudmFsdWUgLyAxMDA7XG4gICAgICAgIH1cbiAgICAgICAgaHNsLmwgPSBjbGFtcChoc2wubCk7XG4gICAgICAgIHJldHVybiBoc2xhKGhzbCk7XG4gICAgfSxcbiAgICBmYWRlaW46IGZ1bmN0aW9uIChjb2xvciwgYW1vdW50LCBtZXRob2QpIHtcbiAgICAgICAgdmFyIGhzbCA9IGNvbG9yLnRvSFNMKCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBtZXRob2QgIT09IFwidW5kZWZpbmVkXCIgJiYgbWV0aG9kLnZhbHVlID09PSBcInJlbGF0aXZlXCIpIHtcbiAgICAgICAgICAgIGhzbC5hICs9ICBoc2wuYSAqIGFtb3VudC52YWx1ZSAvIDEwMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGhzbC5hICs9IGFtb3VudC52YWx1ZSAvIDEwMDtcbiAgICAgICAgfVxuICAgICAgICBoc2wuYSA9IGNsYW1wKGhzbC5hKTtcbiAgICAgICAgcmV0dXJuIGhzbGEoaHNsKTtcbiAgICB9LFxuICAgIGZhZGVvdXQ6IGZ1bmN0aW9uIChjb2xvciwgYW1vdW50LCBtZXRob2QpIHtcbiAgICAgICAgdmFyIGhzbCA9IGNvbG9yLnRvSFNMKCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBtZXRob2QgIT09IFwidW5kZWZpbmVkXCIgJiYgbWV0aG9kLnZhbHVlID09PSBcInJlbGF0aXZlXCIpIHtcbiAgICAgICAgICAgIGhzbC5hIC09ICBoc2wuYSAqIGFtb3VudC52YWx1ZSAvIDEwMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGhzbC5hIC09IGFtb3VudC52YWx1ZSAvIDEwMDtcbiAgICAgICAgfVxuICAgICAgICBoc2wuYSA9IGNsYW1wKGhzbC5hKTtcbiAgICAgICAgcmV0dXJuIGhzbGEoaHNsKTtcbiAgICB9LFxuICAgIGZhZGU6IGZ1bmN0aW9uIChjb2xvciwgYW1vdW50KSB7XG4gICAgICAgIHZhciBoc2wgPSBjb2xvci50b0hTTCgpO1xuXG4gICAgICAgIGhzbC5hID0gYW1vdW50LnZhbHVlIC8gMTAwO1xuICAgICAgICBoc2wuYSA9IGNsYW1wKGhzbC5hKTtcbiAgICAgICAgcmV0dXJuIGhzbGEoaHNsKTtcbiAgICB9LFxuICAgIHNwaW46IGZ1bmN0aW9uIChjb2xvciwgYW1vdW50KSB7XG4gICAgICAgIHZhciBoc2wgPSBjb2xvci50b0hTTCgpO1xuICAgICAgICB2YXIgaHVlID0gKGhzbC5oICsgYW1vdW50LnZhbHVlKSAlIDM2MDtcblxuICAgICAgICBoc2wuaCA9IGh1ZSA8IDAgPyAzNjAgKyBodWUgOiBodWU7XG5cbiAgICAgICAgcmV0dXJuIGhzbGEoaHNsKTtcbiAgICB9LFxuICAgIC8vXG4gICAgLy8gQ29weXJpZ2h0IChjKSAyMDA2LTIwMDkgSGFtcHRvbiBDYXRsaW4sIE5hdGFsaWUgV2VpemVuYmF1bSwgYW5kIENocmlzIEVwcHN0ZWluXG4gICAgLy8gaHR0cDovL3Nhc3MtbGFuZy5jb21cbiAgICAvL1xuICAgIG1peDogZnVuY3Rpb24gKGNvbG9yMSwgY29sb3IyLCB3ZWlnaHQpIHtcbiAgICAgICAgaWYgKCFjb2xvcjEudG9IU0wgfHwgIWNvbG9yMi50b0hTTCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coY29sb3IyLnR5cGUpO1xuICAgICAgICAgICAgY29uc29sZS5kaXIoY29sb3IyKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXdlaWdodCkge1xuICAgICAgICAgICAgd2VpZ2h0ID0gbmV3IERpbWVuc2lvbig1MCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHAgPSB3ZWlnaHQudmFsdWUgLyAxMDAuMDtcbiAgICAgICAgdmFyIHcgPSBwICogMiAtIDE7XG4gICAgICAgIHZhciBhID0gY29sb3IxLnRvSFNMKCkuYSAtIGNvbG9yMi50b0hTTCgpLmE7XG5cbiAgICAgICAgdmFyIHcxID0gKCgodyAqIGEgPT0gLTEpID8gdyA6ICh3ICsgYSkgLyAoMSArIHcgKiBhKSkgKyAxKSAvIDIuMDtcbiAgICAgICAgdmFyIHcyID0gMSAtIHcxO1xuXG4gICAgICAgIHZhciByZ2IgPSBbY29sb3IxLnJnYlswXSAqIHcxICsgY29sb3IyLnJnYlswXSAqIHcyLFxuICAgICAgICAgICAgY29sb3IxLnJnYlsxXSAqIHcxICsgY29sb3IyLnJnYlsxXSAqIHcyLFxuICAgICAgICAgICAgY29sb3IxLnJnYlsyXSAqIHcxICsgY29sb3IyLnJnYlsyXSAqIHcyXTtcblxuICAgICAgICB2YXIgYWxwaGEgPSBjb2xvcjEuYWxwaGEgKiBwICsgY29sb3IyLmFscGhhICogKDEgLSBwKTtcblxuICAgICAgICByZXR1cm4gbmV3IENvbG9yKHJnYiwgYWxwaGEpO1xuICAgIH0sXG4gICAgZ3JleXNjYWxlOiBmdW5jdGlvbiAoY29sb3IpIHtcbiAgICAgICAgcmV0dXJuIGNvbG9yRnVuY3Rpb25zLmRlc2F0dXJhdGUoY29sb3IsIG5ldyBEaW1lbnNpb24oMTAwKSk7XG4gICAgfSxcbiAgICBjb250cmFzdDogZnVuY3Rpb24gKGNvbG9yLCBjb2xvcjEsIGNvbG9yMiwgdGhyZXNob2xkKSB7XG4gICAgICAgIC8vIFJldHVybiB3aGljaCBvZiBgY29sb3IxYCBhbmQgYGNvbG9yMmAgaGFzIHRoZSBncmVhdGVzdCBjb250cmFzdCB3aXRoIGBjb2xvcmBcbiAgICAgICAgLy8gYWNjb3JkaW5nIHRvIHRoZSBzdGFuZGFyZCBXQ0FHIGNvbnRyYXN0IHJhdGlvIGNhbGN1bGF0aW9uLlxuICAgICAgICAvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9XQ0FHMjAvI2NvbnRyYXN0LXJhdGlvZGVmXG4gICAgICAgIC8vIFRoZSB0aHJlc2hvbGQgcGFyYW0gaXMgbm8gbG9uZ2VyIHVzZWQsIGluIGxpbmUgd2l0aCBTQVNTLlxuICAgICAgICAvLyBmaWx0ZXI6IGNvbnRyYXN0KDMuMik7XG4gICAgICAgIC8vIHNob3VsZCBiZSBrZXB0IGFzIGlzLCBzbyBjaGVjayBmb3IgY29sb3JcbiAgICAgICAgaWYgKCFjb2xvci5yZ2IpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgY29sb3IxID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY29sb3IxID0gY29sb3JGdW5jdGlvbnMucmdiYSgwLCAwLCAwLCAxLjApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgY29sb3IyID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY29sb3IyID0gY29sb3JGdW5jdGlvbnMucmdiYSgyNTUsIDI1NSwgMjU1LCAxLjApO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjb250cmFzdDEsIGNvbnRyYXN0MjtcbiAgICAgICAgdmFyIGx1bWEgPSBjb2xvci5sdW1hKCk7XG4gICAgICAgIHZhciBsdW1hMSA9IGNvbG9yMS5sdW1hKCk7XG4gICAgICAgIHZhciBsdW1hMiA9IGNvbG9yMi5sdW1hKCk7XG4gICAgICAgIC8vIENhbGN1bGF0ZSBjb250cmFzdCByYXRpb3MgZm9yIGVhY2ggY29sb3JcbiAgICAgICAgaWYgKGx1bWEgPiBsdW1hMSkge1xuICAgICAgICAgICAgY29udHJhc3QxID0gKGx1bWEgKyAwLjA1KSAvIChsdW1hMSArIDAuMDUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udHJhc3QxID0gKGx1bWExICsgMC4wNSkgLyAobHVtYSArIDAuMDUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsdW1hID4gbHVtYTIpIHtcbiAgICAgICAgICAgIGNvbnRyYXN0MiA9IChsdW1hICsgMC4wNSkgLyAobHVtYTIgKyAwLjA1KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnRyYXN0MiA9IChsdW1hMiArIDAuMDUpIC8gKGx1bWEgKyAwLjA1KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udHJhc3QxID4gY29udHJhc3QyKSB7XG4gICAgICAgICAgICByZXR1cm4gY29sb3IxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGNvbG9yMjtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgYXJnYjogZnVuY3Rpb24gKGNvbG9yKSB7XG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzKGNvbG9yLnRvQVJHQigpKTtcbiAgICB9LFxuICAgIGNvbG9yOiBmdW5jdGlvbihjKSB7XG4gICAgICAgIGlmICgoYyBpbnN0YW5jZW9mIFF1b3RlZCkgJiZcbiAgICAgICAgICAgICgvXiMoW2EtZjAtOV17Nn18W2EtZjAtOV17M30pJC9pLnRlc3QoYy52YWx1ZSkpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IENvbG9yKGMudmFsdWUuc2xpY2UoMSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoYyBpbnN0YW5jZW9mIENvbG9yKSB8fCAoYyA9IENvbG9yLmZyb21LZXl3b3JkKGMudmFsdWUpKSkge1xuICAgICAgICAgICAgYy52YWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHJldHVybiBjO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IHtcbiAgICAgICAgICAgIHR5cGU6ICAgIFwiQXJndW1lbnRcIixcbiAgICAgICAgICAgIG1lc3NhZ2U6IFwiYXJndW1lbnQgbXVzdCBiZSBhIGNvbG9yIGtleXdvcmQgb3IgMy82IGRpZ2l0IGhleCBlLmcuICNGRkZcIlxuICAgICAgICB9O1xuICAgIH0sXG4gICAgdGludDogZnVuY3Rpb24oY29sb3IsIGFtb3VudCkge1xuICAgICAgICByZXR1cm4gY29sb3JGdW5jdGlvbnMubWl4KGNvbG9yRnVuY3Rpb25zLnJnYigyNTUsIDI1NSwgMjU1KSwgY29sb3IsIGFtb3VudCk7XG4gICAgfSxcbiAgICBzaGFkZTogZnVuY3Rpb24oY29sb3IsIGFtb3VudCkge1xuICAgICAgICByZXR1cm4gY29sb3JGdW5jdGlvbnMubWl4KGNvbG9yRnVuY3Rpb25zLnJnYigwLCAwLCAwKSwgY29sb3IsIGFtb3VudCk7XG4gICAgfVxufTtcbmZ1bmN0aW9uUmVnaXN0cnkuYWRkTXVsdGlwbGUoY29sb3JGdW5jdGlvbnMpO1xuXG59LHtcIi4uL3RyZWUvYW5vbnltb3VzXCI6NDYsXCIuLi90cmVlL2NvbG9yXCI6NTAsXCIuLi90cmVlL2RpbWVuc2lvblwiOjU2LFwiLi4vdHJlZS9xdW90ZWRcIjo3MyxcIi4vZnVuY3Rpb24tcmVnaXN0cnlcIjoyMn1dLDE5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZW52aXJvbm1lbnQpIHtcbiAgICB2YXIgUXVvdGVkID0gcmVxdWlyZShcIi4uL3RyZWUvcXVvdGVkXCIpLFxuICAgICAgICBVUkwgPSByZXF1aXJlKFwiLi4vdHJlZS91cmxcIiksXG4gICAgICAgIGZ1bmN0aW9uUmVnaXN0cnkgPSByZXF1aXJlKFwiLi9mdW5jdGlvbi1yZWdpc3RyeVwiKSxcbiAgICAgICAgZmFsbGJhY2sgPSBmdW5jdGlvbihmdW5jdGlvblRoaXMsIG5vZGUpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVVJMKG5vZGUsIGZ1bmN0aW9uVGhpcy5pbmRleCwgZnVuY3Rpb25UaGlzLmN1cnJlbnRGaWxlSW5mbykuZXZhbChmdW5jdGlvblRoaXMuY29udGV4dCk7XG4gICAgICAgIH0sXG4gICAgICAgIGxvZ2dlciA9IHJlcXVpcmUoJy4uL2xvZ2dlcicpO1xuXG4gICAgZnVuY3Rpb25SZWdpc3RyeS5hZGQoXCJkYXRhLXVyaVwiLCBmdW5jdGlvbihtaW1ldHlwZU5vZGUsIGZpbGVQYXRoTm9kZSkge1xuXG4gICAgICAgIGlmICghZmlsZVBhdGhOb2RlKSB7XG4gICAgICAgICAgICBmaWxlUGF0aE5vZGUgPSBtaW1ldHlwZU5vZGU7XG4gICAgICAgICAgICBtaW1ldHlwZU5vZGUgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG1pbWV0eXBlID0gbWltZXR5cGVOb2RlICYmIG1pbWV0eXBlTm9kZS52YWx1ZTtcbiAgICAgICAgdmFyIGZpbGVQYXRoID0gZmlsZVBhdGhOb2RlLnZhbHVlO1xuICAgICAgICB2YXIgY3VycmVudEZpbGVJbmZvID0gdGhpcy5jdXJyZW50RmlsZUluZm87XG4gICAgICAgIHZhciBjdXJyZW50RGlyZWN0b3J5ID0gY3VycmVudEZpbGVJbmZvLnJlbGF0aXZlVXJscyA/XG4gICAgICAgICAgICBjdXJyZW50RmlsZUluZm8uY3VycmVudERpcmVjdG9yeSA6IGN1cnJlbnRGaWxlSW5mby5lbnRyeVBhdGg7XG5cbiAgICAgICAgdmFyIGZyYWdtZW50U3RhcnQgPSBmaWxlUGF0aC5pbmRleE9mKCcjJyk7XG4gICAgICAgIHZhciBmcmFnbWVudCA9ICcnO1xuICAgICAgICBpZiAoZnJhZ21lbnRTdGFydCAhPT0gLTEpIHtcbiAgICAgICAgICAgIGZyYWdtZW50ID0gZmlsZVBhdGguc2xpY2UoZnJhZ21lbnRTdGFydCk7XG4gICAgICAgICAgICBmaWxlUGF0aCA9IGZpbGVQYXRoLnNsaWNlKDAsIGZyYWdtZW50U3RhcnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGZpbGVNYW5hZ2VyID0gZW52aXJvbm1lbnQuZ2V0RmlsZU1hbmFnZXIoZmlsZVBhdGgsIGN1cnJlbnREaXJlY3RvcnksIHRoaXMuY29udGV4dCwgZW52aXJvbm1lbnQsIHRydWUpO1xuXG4gICAgICAgIGlmICghZmlsZU1hbmFnZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxsYmFjayh0aGlzLCBmaWxlUGF0aE5vZGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHVzZUJhc2U2NCA9IGZhbHNlO1xuXG4gICAgICAgIC8vIGRldGVjdCB0aGUgbWltZXR5cGUgaWYgbm90IGdpdmVuXG4gICAgICAgIGlmICghbWltZXR5cGVOb2RlKSB7XG5cbiAgICAgICAgICAgIG1pbWV0eXBlID0gZW52aXJvbm1lbnQubWltZUxvb2t1cChmaWxlUGF0aCk7XG5cbiAgICAgICAgICAgIGlmIChtaW1ldHlwZSA9PT0gXCJpbWFnZS9zdmcreG1sXCIpIHtcbiAgICAgICAgICAgICAgICB1c2VCYXNlNjQgPSBmYWxzZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gdXNlIGJhc2UgNjQgdW5sZXNzIGl0J3MgYW4gQVNDSUkgb3IgVVRGLTggZm9ybWF0XG4gICAgICAgICAgICAgICAgdmFyIGNoYXJzZXQgPSBlbnZpcm9ubWVudC5jaGFyc2V0TG9va3VwKG1pbWV0eXBlKTtcbiAgICAgICAgICAgICAgICB1c2VCYXNlNjQgPSBbJ1VTLUFTQ0lJJywgJ1VURi04J10uaW5kZXhPZihjaGFyc2V0KSA8IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodXNlQmFzZTY0KSB7IG1pbWV0eXBlICs9ICc7YmFzZTY0JzsgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdXNlQmFzZTY0ID0gLztiYXNlNjQkLy50ZXN0KG1pbWV0eXBlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBmaWxlU3luYyA9IGZpbGVNYW5hZ2VyLmxvYWRGaWxlU3luYyhmaWxlUGF0aCwgY3VycmVudERpcmVjdG9yeSwgdGhpcy5jb250ZXh0LCBlbnZpcm9ubWVudCk7XG4gICAgICAgIGlmICghZmlsZVN5bmMuY29udGVudHMpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKFwiU2tpcHBlZCBkYXRhLXVyaSBlbWJlZGRpbmcgb2YgXCIgKyBmaWxlUGF0aCArIFwiIGJlY2F1c2UgZmlsZSBub3QgZm91bmRcIik7XG4gICAgICAgICAgICByZXR1cm4gZmFsbGJhY2sodGhpcywgZmlsZVBhdGhOb2RlIHx8IG1pbWV0eXBlTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGJ1ZiA9IGZpbGVTeW5jLmNvbnRlbnRzO1xuICAgICAgICBpZiAodXNlQmFzZTY0ICYmICFlbnZpcm9ubWVudC5lbmNvZGVCYXNlNjQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxsYmFjayh0aGlzLCBmaWxlUGF0aE5vZGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnVmID0gdXNlQmFzZTY0ID8gZW52aXJvbm1lbnQuZW5jb2RlQmFzZTY0KGJ1ZikgOiBlbmNvZGVVUklDb21wb25lbnQoYnVmKTtcblxuICAgICAgICB2YXIgdXJpID0gXCJkYXRhOlwiICsgbWltZXR5cGUgKyAnLCcgKyBidWYgKyBmcmFnbWVudDtcblxuICAgICAgICAvLyBJRTggY2Fubm90IGhhbmRsZSBhIGRhdGEtdXJpIGxhcmdlciB0aGFuIDMyLDc2OCBjaGFyYWN0ZXJzLiBJZiB0aGlzIGlzIGV4Y2VlZGVkXG4gICAgICAgIC8vIGFuZCB0aGUgLS1pZUNvbXBhdCBmbGFnIGlzIGVuYWJsZWQsIHJldHVybiBhIG5vcm1hbCB1cmwoKSBpbnN0ZWFkLlxuICAgICAgICB2YXIgREFUQV9VUklfTUFYID0gMzI3Njg7XG4gICAgICAgIGlmICh1cmkubGVuZ3RoID49IERBVEFfVVJJX01BWCkge1xuXG4gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LmllQ29tcGF0ICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKFwiU2tpcHBlZCBkYXRhLXVyaSBlbWJlZGRpbmcgb2YgXCIgKyBmaWxlUGF0aCArIFwiIGJlY2F1c2UgaXRzIHNpemUgKFwiICsgdXJpLmxlbmd0aCArXG4gICAgICAgICAgICAgICAgICAgIFwiIGNoYXJhY3RlcnMpIGV4Y2VlZHMgSUU4LXNhZmUgXCIgKyBEQVRBX1VSSV9NQVggKyBcIiBjaGFyYWN0ZXJzIVwiKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxsYmFjayh0aGlzLCBmaWxlUGF0aE5vZGUgfHwgbWltZXR5cGVOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgVVJMKG5ldyBRdW90ZWQoJ1wiJyArIHVyaSArICdcIicsIHVyaSwgZmFsc2UsIHRoaXMuaW5kZXgsIHRoaXMuY3VycmVudEZpbGVJbmZvKSwgdGhpcy5pbmRleCwgdGhpcy5jdXJyZW50RmlsZUluZm8pO1xuICAgIH0pO1xufTtcblxufSx7XCIuLi9sb2dnZXJcIjozMyxcIi4uL3RyZWUvcXVvdGVkXCI6NzMsXCIuLi90cmVlL3VybFwiOjgwLFwiLi9mdW5jdGlvbi1yZWdpc3RyeVwiOjIyfV0sMjA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIEtleXdvcmQgPSByZXF1aXJlKFwiLi4vdHJlZS9rZXl3b3JkXCIpLFxuICAgIGZ1bmN0aW9uUmVnaXN0cnkgPSByZXF1aXJlKFwiLi9mdW5jdGlvbi1yZWdpc3RyeVwiKTtcblxudmFyIGRlZmF1bHRGdW5jID0ge1xuICAgIGV2YWw6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHYgPSB0aGlzLnZhbHVlXywgZSA9IHRoaXMuZXJyb3JfO1xuICAgICAgICBpZiAoZSkge1xuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodiAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdiA/IEtleXdvcmQuVHJ1ZSA6IEtleXdvcmQuRmFsc2U7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIHZhbHVlOiBmdW5jdGlvbiAodikge1xuICAgICAgICB0aGlzLnZhbHVlXyA9IHY7XG4gICAgfSxcbiAgICBlcnJvcjogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdGhpcy5lcnJvcl8gPSBlO1xuICAgIH0sXG4gICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy52YWx1ZV8gPSB0aGlzLmVycm9yXyA9IG51bGw7XG4gICAgfVxufTtcblxuZnVuY3Rpb25SZWdpc3RyeS5hZGQoXCJkZWZhdWx0XCIsIGRlZmF1bHRGdW5jLmV2YWwuYmluZChkZWZhdWx0RnVuYykpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlZmF1bHRGdW5jO1xuXG59LHtcIi4uL3RyZWUva2V5d29yZFwiOjY1LFwiLi9mdW5jdGlvbi1yZWdpc3RyeVwiOjIyfV0sMjE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIEV4cHJlc3Npb24gPSByZXF1aXJlKFwiLi4vdHJlZS9leHByZXNzaW9uXCIpO1xuXG52YXIgZnVuY3Rpb25DYWxsZXIgPSBmdW5jdGlvbihuYW1lLCBjb250ZXh0LCBpbmRleCwgY3VycmVudEZpbGVJbmZvKSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIHRoaXMuaW5kZXggPSBpbmRleDtcbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIHRoaXMuY3VycmVudEZpbGVJbmZvID0gY3VycmVudEZpbGVJbmZvO1xuXG4gICAgdGhpcy5mdW5jID0gY29udGV4dC5mcmFtZXNbMF0uZnVuY3Rpb25SZWdpc3RyeS5nZXQodGhpcy5uYW1lKTtcbn07XG5mdW5jdGlvbkNhbGxlci5wcm90b3R5cGUuaXNWYWxpZCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBCb29sZWFuKHRoaXMuZnVuYyk7XG59O1xuZnVuY3Rpb25DYWxsZXIucHJvdG90eXBlLmNhbGwgPSBmdW5jdGlvbihhcmdzKSB7XG5cbiAgICAvLyBUaGlzIGNvZGUgaXMgdGVycmlibGUgYW5kIHNob3VsZCBiZSByZXBsYWNlZCBhcyBwZXIgdGhpcyBpc3N1ZS4uLlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9sZXNzL2xlc3MuanMvaXNzdWVzLzI0NzdcbiAgICBpZiAoQXJyYXkuaXNBcnJheShhcmdzKSkge1xuICAgICAgICBhcmdzID0gYXJncy5maWx0ZXIoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgIGlmIChpdGVtLnR5cGUgPT09IFwiQ29tbWVudFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5tYXAoZnVuY3Rpb24oaXRlbSkge1xuICAgICAgICAgICAgaWYgKGl0ZW0udHlwZSA9PT0gXCJFeHByZXNzaW9uXCIpIHtcbiAgICAgICAgICAgICAgICB2YXIgc3ViTm9kZXMgPSBpdGVtLnZhbHVlLmZpbHRlcihmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS50eXBlID09PSBcIkNvbW1lbnRcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChzdWJOb2Rlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN1Yk5vZGVzWzBdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRXhwcmVzc2lvbihzdWJOb2Rlcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGl0ZW07XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmZ1bmMuYXBwbHkodGhpcywgYXJncyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uQ2FsbGVyO1xuXG59LHtcIi4uL3RyZWUvZXhwcmVzc2lvblwiOjU5fV0sMjI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuZnVuY3Rpb24gbWFrZVJlZ2lzdHJ5KCBiYXNlICkge1xuICAgIHJldHVybiB7XG4gICAgICAgIF9kYXRhOiB7fSxcbiAgICAgICAgYWRkOiBmdW5jdGlvbihuYW1lLCBmdW5jKSB7XG4gICAgICAgICAgICAvLyBwcmVjYXV0aW9uYXJ5IGNhc2UgY29udmVyc2lvbiwgYXMgbGF0ZXIgcXVlcnlpbmcgb2ZcbiAgICAgICAgICAgIC8vIHRoZSByZWdpc3RyeSBieSBmdW5jdGlvbi1jYWxsZXIgdXNlcyBsb3dlciBjYXNlIGFzIHdlbGwuXG4gICAgICAgICAgICBuYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5fZGF0YS5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICAgICAgICAgIC8vVE9ETyB3YXJuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9kYXRhW25hbWVdID0gZnVuYztcbiAgICAgICAgfSxcbiAgICAgICAgYWRkTXVsdGlwbGU6IGZ1bmN0aW9uKGZ1bmN0aW9ucykge1xuICAgICAgICAgICAgT2JqZWN0LmtleXMoZnVuY3Rpb25zKS5mb3JFYWNoKFxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGQobmFtZSwgZnVuY3Rpb25zW25hbWVdKTtcbiAgICAgICAgICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgICB9LFxuICAgICAgICBnZXQ6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kYXRhW25hbWVdIHx8ICggYmFzZSAmJiBiYXNlLmdldCggbmFtZSApKTtcbiAgICAgICAgfSxcbiAgICAgICAgaW5oZXJpdCA6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIG1ha2VSZWdpc3RyeSggdGhpcyApO1xuICAgICAgICB9XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYWtlUmVnaXN0cnkoIG51bGwgKTtcbn0se31dLDIzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZW52aXJvbm1lbnQpIHtcbiAgICB2YXIgZnVuY3Rpb25zID0ge1xuICAgICAgICBmdW5jdGlvblJlZ2lzdHJ5OiByZXF1aXJlKFwiLi9mdW5jdGlvbi1yZWdpc3RyeVwiKSxcbiAgICAgICAgZnVuY3Rpb25DYWxsZXI6IHJlcXVpcmUoXCIuL2Z1bmN0aW9uLWNhbGxlclwiKVxuICAgIH07XG5cbiAgICAvL3JlZ2lzdGVyIGZ1bmN0aW9uc1xuICAgIHJlcXVpcmUoXCIuL2RlZmF1bHRcIik7XG4gICAgcmVxdWlyZShcIi4vY29sb3JcIik7XG4gICAgcmVxdWlyZShcIi4vY29sb3ItYmxlbmRpbmdcIik7XG4gICAgcmVxdWlyZShcIi4vZGF0YS11cmlcIikoZW52aXJvbm1lbnQpO1xuICAgIHJlcXVpcmUoXCIuL21hdGhcIik7XG4gICAgcmVxdWlyZShcIi4vbnVtYmVyXCIpO1xuICAgIHJlcXVpcmUoXCIuL3N0cmluZ1wiKTtcbiAgICByZXF1aXJlKFwiLi9zdmdcIikoZW52aXJvbm1lbnQpO1xuICAgIHJlcXVpcmUoXCIuL3R5cGVzXCIpO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9ucztcbn07XG5cbn0se1wiLi9jb2xvclwiOjE4LFwiLi9jb2xvci1ibGVuZGluZ1wiOjE3LFwiLi9kYXRhLXVyaVwiOjE5LFwiLi9kZWZhdWx0XCI6MjAsXCIuL2Z1bmN0aW9uLWNhbGxlclwiOjIxLFwiLi9mdW5jdGlvbi1yZWdpc3RyeVwiOjIyLFwiLi9tYXRoXCI6MjUsXCIuL251bWJlclwiOjI2LFwiLi9zdHJpbmdcIjoyNyxcIi4vc3ZnXCI6MjgsXCIuL3R5cGVzXCI6Mjl9XSwyNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgRGltZW5zaW9uID0gcmVxdWlyZShcIi4uL3RyZWUvZGltZW5zaW9uXCIpO1xuXG52YXIgTWF0aEhlbHBlciA9IGZ1bmN0aW9uKCkge1xufTtcbk1hdGhIZWxwZXIuX21hdGggPSBmdW5jdGlvbiAoZm4sIHVuaXQsIG4pIHtcbiAgICBpZiAoIShuIGluc3RhbmNlb2YgRGltZW5zaW9uKSkge1xuICAgICAgICB0aHJvdyB7IHR5cGU6IFwiQXJndW1lbnRcIiwgbWVzc2FnZTogXCJhcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyXCIgfTtcbiAgICB9XG4gICAgaWYgKHVuaXQgPT0gbnVsbCkge1xuICAgICAgICB1bml0ID0gbi51bml0O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIG4gPSBuLnVuaWZ5KCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgRGltZW5zaW9uKGZuKHBhcnNlRmxvYXQobi52YWx1ZSkpLCB1bml0KTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IE1hdGhIZWxwZXI7XG59LHtcIi4uL3RyZWUvZGltZW5zaW9uXCI6NTZ9XSwyNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgZnVuY3Rpb25SZWdpc3RyeSA9IHJlcXVpcmUoXCIuL2Z1bmN0aW9uLXJlZ2lzdHJ5XCIpLFxuICAgIG1hdGhIZWxwZXIgPSByZXF1aXJlKFwiLi9tYXRoLWhlbHBlci5qc1wiKTtcblxudmFyIG1hdGhGdW5jdGlvbnMgPSB7XG4gICAgLy8gbmFtZSwgIHVuaXRcbiAgICBjZWlsOiAgbnVsbCxcbiAgICBmbG9vcjogbnVsbCxcbiAgICBzcXJ0OiAgbnVsbCxcbiAgICBhYnM6ICAgbnVsbCxcbiAgICB0YW46ICAgXCJcIixcbiAgICBzaW46ICAgXCJcIixcbiAgICBjb3M6ICAgXCJcIixcbiAgICBhdGFuOiAgXCJyYWRcIixcbiAgICBhc2luOiAgXCJyYWRcIixcbiAgICBhY29zOiAgXCJyYWRcIlxufTtcblxuZm9yICh2YXIgZiBpbiBtYXRoRnVuY3Rpb25zKSB7XG4gICAgaWYgKG1hdGhGdW5jdGlvbnMuaGFzT3duUHJvcGVydHkoZikpIHtcbiAgICAgICAgbWF0aEZ1bmN0aW9uc1tmXSA9IG1hdGhIZWxwZXIuX21hdGguYmluZChudWxsLCBNYXRoW2ZdLCBtYXRoRnVuY3Rpb25zW2ZdKTtcbiAgICB9XG59XG5cbm1hdGhGdW5jdGlvbnMucm91bmQgPSBmdW5jdGlvbiAobiwgZikge1xuICAgIHZhciBmcmFjdGlvbiA9IHR5cGVvZiBmID09PSBcInVuZGVmaW5lZFwiID8gMCA6IGYudmFsdWU7XG4gICAgcmV0dXJuIG1hdGhIZWxwZXIuX21hdGgoZnVuY3Rpb24obnVtKSB7IHJldHVybiBudW0udG9GaXhlZChmcmFjdGlvbik7IH0sIG51bGwsIG4pO1xufTtcblxuZnVuY3Rpb25SZWdpc3RyeS5hZGRNdWx0aXBsZShtYXRoRnVuY3Rpb25zKTtcblxufSx7XCIuL2Z1bmN0aW9uLXJlZ2lzdHJ5XCI6MjIsXCIuL21hdGgtaGVscGVyLmpzXCI6MjR9XSwyNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgRGltZW5zaW9uID0gcmVxdWlyZShcIi4uL3RyZWUvZGltZW5zaW9uXCIpLFxuICAgIEFub255bW91cyA9IHJlcXVpcmUoXCIuLi90cmVlL2Fub255bW91c1wiKSxcbiAgICBmdW5jdGlvblJlZ2lzdHJ5ID0gcmVxdWlyZShcIi4vZnVuY3Rpb24tcmVnaXN0cnlcIiksXG4gICAgbWF0aEhlbHBlciA9IHJlcXVpcmUoXCIuL21hdGgtaGVscGVyLmpzXCIpO1xuXG52YXIgbWluTWF4ID0gZnVuY3Rpb24gKGlzTWluLCBhcmdzKSB7XG4gICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MpO1xuICAgIHN3aXRjaChhcmdzLmxlbmd0aCkge1xuICAgICAgICBjYXNlIDA6IHRocm93IHsgdHlwZTogXCJBcmd1bWVudFwiLCBtZXNzYWdlOiBcIm9uZSBvciBtb3JlIGFyZ3VtZW50cyByZXF1aXJlZFwiIH07XG4gICAgfVxuICAgIHZhciBpLCBqLCBjdXJyZW50LCBjdXJyZW50VW5pZmllZCwgcmVmZXJlbmNlVW5pZmllZCwgdW5pdCwgdW5pdFN0YXRpYywgdW5pdENsb25lLFxuICAgICAgICBvcmRlciAgPSBbXSwgLy8gZWxlbXMgb25seSBjb250YWlucyBvcmlnaW5hbCBhcmd1bWVudCB2YWx1ZXMuXG4gICAgICAgIHZhbHVlcyA9IHt9OyAvLyBrZXkgaXMgdGhlIHVuaXQudG9TdHJpbmcoKSBmb3IgdW5pZmllZCBEaW1lbnNpb24gdmFsdWVzLFxuICAgIC8vIHZhbHVlIGlzIHRoZSBpbmRleCBpbnRvIHRoZSBvcmRlciBhcnJheS5cbiAgICBmb3IgKGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjdXJyZW50ID0gYXJnc1tpXTtcbiAgICAgICAgaWYgKCEoY3VycmVudCBpbnN0YW5jZW9mIERpbWVuc2lvbikpIHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGFyZ3NbaV0udmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoYXJncywgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJnc1tpXS52YWx1ZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudFVuaWZpZWQgPSBjdXJyZW50LnVuaXQudG9TdHJpbmcoKSA9PT0gXCJcIiAmJiB1bml0Q2xvbmUgIT09IHVuZGVmaW5lZCA/IG5ldyBEaW1lbnNpb24oY3VycmVudC52YWx1ZSwgdW5pdENsb25lKS51bmlmeSgpIDogY3VycmVudC51bmlmeSgpO1xuICAgICAgICB1bml0ID0gY3VycmVudFVuaWZpZWQudW5pdC50b1N0cmluZygpID09PSBcIlwiICYmIHVuaXRTdGF0aWMgIT09IHVuZGVmaW5lZCA/IHVuaXRTdGF0aWMgOiBjdXJyZW50VW5pZmllZC51bml0LnRvU3RyaW5nKCk7XG4gICAgICAgIHVuaXRTdGF0aWMgPSB1bml0ICE9PSBcIlwiICYmIHVuaXRTdGF0aWMgPT09IHVuZGVmaW5lZCB8fCB1bml0ICE9PSBcIlwiICYmIG9yZGVyWzBdLnVuaWZ5KCkudW5pdC50b1N0cmluZygpID09PSBcIlwiID8gdW5pdCA6IHVuaXRTdGF0aWM7XG4gICAgICAgIHVuaXRDbG9uZSA9IHVuaXQgIT09IFwiXCIgJiYgdW5pdENsb25lID09PSB1bmRlZmluZWQgPyBjdXJyZW50LnVuaXQudG9TdHJpbmcoKSA6IHVuaXRDbG9uZTtcbiAgICAgICAgaiA9IHZhbHVlc1tcIlwiXSAhPT0gdW5kZWZpbmVkICYmIHVuaXQgIT09IFwiXCIgJiYgdW5pdCA9PT0gdW5pdFN0YXRpYyA/IHZhbHVlc1tcIlwiXSA6IHZhbHVlc1t1bml0XTtcbiAgICAgICAgaWYgKGogPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKHVuaXRTdGF0aWMgIT09IHVuZGVmaW5lZCAmJiB1bml0ICE9PSB1bml0U3RhdGljKSB7XG4gICAgICAgICAgICAgICAgdGhyb3d7IHR5cGU6IFwiQXJndW1lbnRcIiwgbWVzc2FnZTogXCJpbmNvbXBhdGlibGUgdHlwZXNcIiB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFsdWVzW3VuaXRdID0gb3JkZXIubGVuZ3RoO1xuICAgICAgICAgICAgb3JkZXIucHVzaChjdXJyZW50KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHJlZmVyZW5jZVVuaWZpZWQgPSBvcmRlcltqXS51bml0LnRvU3RyaW5nKCkgPT09IFwiXCIgJiYgdW5pdENsb25lICE9PSB1bmRlZmluZWQgPyBuZXcgRGltZW5zaW9uKG9yZGVyW2pdLnZhbHVlLCB1bml0Q2xvbmUpLnVuaWZ5KCkgOiBvcmRlcltqXS51bmlmeSgpO1xuICAgICAgICBpZiAoIGlzTWluICYmIGN1cnJlbnRVbmlmaWVkLnZhbHVlIDwgcmVmZXJlbmNlVW5pZmllZC52YWx1ZSB8fFxuICAgICAgICAgICAgIWlzTWluICYmIGN1cnJlbnRVbmlmaWVkLnZhbHVlID4gcmVmZXJlbmNlVW5pZmllZC52YWx1ZSkge1xuICAgICAgICAgICAgb3JkZXJbal0gPSBjdXJyZW50O1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChvcmRlci5sZW5ndGggPT0gMSkge1xuICAgICAgICByZXR1cm4gb3JkZXJbMF07XG4gICAgfVxuICAgIGFyZ3MgPSBvcmRlci5tYXAoZnVuY3Rpb24gKGEpIHsgcmV0dXJuIGEudG9DU1ModGhpcy5jb250ZXh0KTsgfSkuam9pbih0aGlzLmNvbnRleHQuY29tcHJlc3MgPyBcIixcIiA6IFwiLCBcIik7XG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXMoKGlzTWluID8gXCJtaW5cIiA6IFwibWF4XCIpICsgXCIoXCIgKyBhcmdzICsgXCIpXCIpO1xufTtcbmZ1bmN0aW9uUmVnaXN0cnkuYWRkTXVsdGlwbGUoe1xuICAgIG1pbjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbWluTWF4KHRydWUsIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBtYXg6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG1pbk1heChmYWxzZSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIGNvbnZlcnQ6IGZ1bmN0aW9uICh2YWwsIHVuaXQpIHtcbiAgICAgICAgcmV0dXJuIHZhbC5jb252ZXJ0VG8odW5pdC52YWx1ZSk7XG4gICAgfSxcbiAgICBwaTogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IERpbWVuc2lvbihNYXRoLlBJKTtcbiAgICB9LFxuICAgIG1vZDogZnVuY3Rpb24oYSwgYikge1xuICAgICAgICByZXR1cm4gbmV3IERpbWVuc2lvbihhLnZhbHVlICUgYi52YWx1ZSwgYS51bml0KTtcbiAgICB9LFxuICAgIHBvdzogZnVuY3Rpb24oeCwgeSkge1xuICAgICAgICBpZiAodHlwZW9mIHggPT09IFwibnVtYmVyXCIgJiYgdHlwZW9mIHkgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIHggPSBuZXcgRGltZW5zaW9uKHgpO1xuICAgICAgICAgICAgeSA9IG5ldyBEaW1lbnNpb24oeSk7XG4gICAgICAgIH0gZWxzZSBpZiAoISh4IGluc3RhbmNlb2YgRGltZW5zaW9uKSB8fCAhKHkgaW5zdGFuY2VvZiBEaW1lbnNpb24pKSB7XG4gICAgICAgICAgICB0aHJvdyB7IHR5cGU6IFwiQXJndW1lbnRcIiwgbWVzc2FnZTogXCJhcmd1bWVudHMgbXVzdCBiZSBudW1iZXJzXCIgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgRGltZW5zaW9uKE1hdGgucG93KHgudmFsdWUsIHkudmFsdWUpLCB4LnVuaXQpO1xuICAgIH0sXG4gICAgcGVyY2VudGFnZTogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IG1hdGhIZWxwZXIuX21hdGgoZnVuY3Rpb24obnVtKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVtICogMTAwO1xuICAgICAgICB9LCAnJScsIG4pO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxufSk7XG5cbn0se1wiLi4vdHJlZS9hbm9ueW1vdXNcIjo0NixcIi4uL3RyZWUvZGltZW5zaW9uXCI6NTYsXCIuL2Z1bmN0aW9uLXJlZ2lzdHJ5XCI6MjIsXCIuL21hdGgtaGVscGVyLmpzXCI6MjR9XSwyNzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgUXVvdGVkID0gcmVxdWlyZShcIi4uL3RyZWUvcXVvdGVkXCIpLFxuICAgIEFub255bW91cyA9IHJlcXVpcmUoXCIuLi90cmVlL2Fub255bW91c1wiKSxcbiAgICBKYXZhU2NyaXB0ID0gcmVxdWlyZShcIi4uL3RyZWUvamF2YXNjcmlwdFwiKSxcbiAgICBmdW5jdGlvblJlZ2lzdHJ5ID0gcmVxdWlyZShcIi4vZnVuY3Rpb24tcmVnaXN0cnlcIik7XG5cbmZ1bmN0aW9uUmVnaXN0cnkuYWRkTXVsdGlwbGUoe1xuICAgIGU6IGZ1bmN0aW9uIChzdHIpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXMoc3RyIGluc3RhbmNlb2YgSmF2YVNjcmlwdCA/IHN0ci5ldmFsdWF0ZWQgOiBzdHIudmFsdWUpO1xuICAgIH0sXG4gICAgZXNjYXBlOiBmdW5jdGlvbiAoc3RyKSB7XG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzKFxuICAgICAgICAgICAgZW5jb2RlVVJJKHN0ci52YWx1ZSkucmVwbGFjZSgvPS9nLCBcIiUzRFwiKS5yZXBsYWNlKC86L2csIFwiJTNBXCIpLnJlcGxhY2UoLyMvZywgXCIlMjNcIikucmVwbGFjZSgvOy9nLCBcIiUzQlwiKVxuICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXCgvZywgXCIlMjhcIikucmVwbGFjZSgvXFwpL2csIFwiJTI5XCIpKTtcbiAgICB9LFxuICAgIHJlcGxhY2U6IGZ1bmN0aW9uIChzdHJpbmcsIHBhdHRlcm4sIHJlcGxhY2VtZW50LCBmbGFncykge1xuICAgICAgICB2YXIgcmVzdWx0ID0gc3RyaW5nLnZhbHVlO1xuICAgICAgICByZXBsYWNlbWVudCA9IChyZXBsYWNlbWVudC50eXBlID09PSBcIlF1b3RlZFwiKSA/XG4gICAgICAgICAgICByZXBsYWNlbWVudC52YWx1ZSA6IHJlcGxhY2VtZW50LnRvQ1NTKCk7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdC5yZXBsYWNlKG5ldyBSZWdFeHAocGF0dGVybi52YWx1ZSwgZmxhZ3MgPyBmbGFncy52YWx1ZSA6ICcnKSwgcmVwbGFjZW1lbnQpO1xuICAgICAgICByZXR1cm4gbmV3IFF1b3RlZChzdHJpbmcucXVvdGUgfHwgJycsIHJlc3VsdCwgc3RyaW5nLmVzY2FwZWQpO1xuICAgIH0sXG4gICAgJyUnOiBmdW5jdGlvbiAoc3RyaW5nIC8qIGFyZywgYXJnLCAuLi4qLykge1xuICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSksXG4gICAgICAgICAgICByZXN1bHQgPSBzdHJpbmcudmFsdWU7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAvKmpzaGludCBsb29wZnVuYzp0cnVlICovXG4gICAgICAgICAgICByZXN1bHQgPSByZXN1bHQucmVwbGFjZSgvJVtzZGFdL2ksIGZ1bmN0aW9uKHRva2VuKSB7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gKChhcmdzW2ldLnR5cGUgPT09IFwiUXVvdGVkXCIpICYmXG4gICAgICAgICAgICAgICAgICAgIHRva2VuLm1hdGNoKC9zL2kpKSA/IGFyZ3NbaV0udmFsdWUgOiBhcmdzW2ldLnRvQ1NTKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRva2VuLm1hdGNoKC9bQS1aXSQvKSA/IGVuY29kZVVSSUNvbXBvbmVudCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdC5yZXBsYWNlKC8lJS9nLCAnJScpO1xuICAgICAgICByZXR1cm4gbmV3IFF1b3RlZChzdHJpbmcucXVvdGUgfHwgJycsIHJlc3VsdCwgc3RyaW5nLmVzY2FwZWQpO1xuICAgIH1cbn0pO1xuXG59LHtcIi4uL3RyZWUvYW5vbnltb3VzXCI6NDYsXCIuLi90cmVlL2phdmFzY3JpcHRcIjo2MyxcIi4uL3RyZWUvcXVvdGVkXCI6NzMsXCIuL2Z1bmN0aW9uLXJlZ2lzdHJ5XCI6MjJ9XSwyODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVudmlyb25tZW50KSB7XG4gICAgdmFyIERpbWVuc2lvbiA9IHJlcXVpcmUoXCIuLi90cmVlL2RpbWVuc2lvblwiKSxcbiAgICAgICAgQ29sb3IgPSByZXF1aXJlKFwiLi4vdHJlZS9jb2xvclwiKSxcbiAgICAgICAgRXhwcmVzc2lvbiA9IHJlcXVpcmUoXCIuLi90cmVlL2V4cHJlc3Npb25cIiksXG4gICAgICAgIFF1b3RlZCA9IHJlcXVpcmUoXCIuLi90cmVlL3F1b3RlZFwiKSxcbiAgICAgICAgVVJMID0gcmVxdWlyZShcIi4uL3RyZWUvdXJsXCIpLFxuICAgICAgICBmdW5jdGlvblJlZ2lzdHJ5ID0gcmVxdWlyZShcIi4vZnVuY3Rpb24tcmVnaXN0cnlcIik7XG5cbiAgICBmdW5jdGlvblJlZ2lzdHJ5LmFkZChcInN2Zy1ncmFkaWVudFwiLCBmdW5jdGlvbihkaXJlY3Rpb24pIHtcblxuICAgICAgICB2YXIgc3RvcHMsXG4gICAgICAgICAgICBncmFkaWVudERpcmVjdGlvblN2ZyxcbiAgICAgICAgICAgIGdyYWRpZW50VHlwZSA9IFwibGluZWFyXCIsXG4gICAgICAgICAgICByZWN0YW5nbGVEaW1lbnNpb24gPSAneD1cIjBcIiB5PVwiMFwiIHdpZHRoPVwiMVwiIGhlaWdodD1cIjFcIicsXG4gICAgICAgICAgICByZW5kZXJFbnYgPSB7Y29tcHJlc3M6IGZhbHNlfSxcbiAgICAgICAgICAgIHJldHVybmVyLFxuICAgICAgICAgICAgZGlyZWN0aW9uVmFsdWUgPSBkaXJlY3Rpb24udG9DU1MocmVuZGVyRW52KSxcblx0XHRcdGksIGNvbG9yLCBwb3NpdGlvbiwgcG9zaXRpb25WYWx1ZSwgYWxwaGE7XG5cbiAgICAgICAgZnVuY3Rpb24gdGhyb3dBcmd1bWVudERlc2NyaXB0b3IoKSB7XG4gICAgICAgICAgICB0aHJvdyB7IHR5cGU6IFwiQXJndW1lbnRcIixcblx0XHRcdFx0XHRtZXNzYWdlOiBcInN2Zy1ncmFkaWVudCBleHBlY3RzIGRpcmVjdGlvbiwgc3RhcnRfY29sb3IgW3N0YXJ0X3Bvc2l0aW9uXSwgW2NvbG9yIHBvc2l0aW9uLF0uLi4sXCIgK1xuXHRcdFx0XHRcdFx0XHRcIiBlbmRfY29sb3IgW2VuZF9wb3NpdGlvbl0gb3IgZGlyZWN0aW9uLCBjb2xvciBsaXN0XCIgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDIpIHtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHNbMV0udmFsdWUubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgICAgIHRocm93QXJndW1lbnREZXNjcmlwdG9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdG9wcyA9IGFyZ3VtZW50c1sxXS52YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMykge1xuICAgICAgICAgICAgdGhyb3dBcmd1bWVudERlc2NyaXB0b3IoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0b3BzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAoZGlyZWN0aW9uVmFsdWUpIHtcbiAgICAgICAgICAgIGNhc2UgXCJ0byBib3R0b21cIjpcbiAgICAgICAgICAgICAgICBncmFkaWVudERpcmVjdGlvblN2ZyA9ICd4MT1cIjAlXCIgeTE9XCIwJVwiIHgyPVwiMCVcIiB5Mj1cIjEwMCVcIic7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwidG8gcmlnaHRcIjpcbiAgICAgICAgICAgICAgICBncmFkaWVudERpcmVjdGlvblN2ZyA9ICd4MT1cIjAlXCIgeTE9XCIwJVwiIHgyPVwiMTAwJVwiIHkyPVwiMCVcIic7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwidG8gYm90dG9tIHJpZ2h0XCI6XG4gICAgICAgICAgICAgICAgZ3JhZGllbnREaXJlY3Rpb25TdmcgPSAneDE9XCIwJVwiIHkxPVwiMCVcIiB4Mj1cIjEwMCVcIiB5Mj1cIjEwMCVcIic7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwidG8gdG9wIHJpZ2h0XCI6XG4gICAgICAgICAgICAgICAgZ3JhZGllbnREaXJlY3Rpb25TdmcgPSAneDE9XCIwJVwiIHkxPVwiMTAwJVwiIHgyPVwiMTAwJVwiIHkyPVwiMCVcIic7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiZWxsaXBzZVwiOlxuICAgICAgICAgICAgY2FzZSBcImVsbGlwc2UgYXQgY2VudGVyXCI6XG4gICAgICAgICAgICAgICAgZ3JhZGllbnRUeXBlID0gXCJyYWRpYWxcIjtcbiAgICAgICAgICAgICAgICBncmFkaWVudERpcmVjdGlvblN2ZyA9ICdjeD1cIjUwJVwiIGN5PVwiNTAlXCIgcj1cIjc1JVwiJztcbiAgICAgICAgICAgICAgICByZWN0YW5nbGVEaW1lbnNpb24gPSAneD1cIi01MFwiIHk9XCItNTBcIiB3aWR0aD1cIjEwMVwiIGhlaWdodD1cIjEwMVwiJztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgeyB0eXBlOiBcIkFyZ3VtZW50XCIsIG1lc3NhZ2U6IFwic3ZnLWdyYWRpZW50IGRpcmVjdGlvbiBtdXN0IGJlICd0byBib3R0b20nLCAndG8gcmlnaHQnLFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCIgJ3RvIGJvdHRvbSByaWdodCcsICd0byB0b3AgcmlnaHQnIG9yICdlbGxpcHNlIGF0IGNlbnRlcidcIiB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybmVyID0gJzw/eG1sIHZlcnNpb249XCIxLjBcIiA/PicgK1xuICAgICAgICAgICAgJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZlcnNpb249XCIxLjFcIiB3aWR0aD1cIjEwMCVcIiBoZWlnaHQ9XCIxMDAlXCIgdmlld0JveD1cIjAgMCAxIDFcIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPVwibm9uZVwiPicgK1xuICAgICAgICAgICAgJzwnICsgZ3JhZGllbnRUeXBlICsgJ0dyYWRpZW50IGlkPVwiZ3JhZGllbnRcIiBncmFkaWVudFVuaXRzPVwidXNlclNwYWNlT25Vc2VcIiAnICsgZ3JhZGllbnREaXJlY3Rpb25TdmcgKyAnPic7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHN0b3BzLmxlbmd0aDsgaSs9IDEpIHtcbiAgICAgICAgICAgIGlmIChzdG9wc1tpXSBpbnN0YW5jZW9mIEV4cHJlc3Npb24pIHtcbiAgICAgICAgICAgICAgICBjb2xvciA9IHN0b3BzW2ldLnZhbHVlWzBdO1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gc3RvcHNbaV0udmFsdWVbMV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbG9yID0gc3RvcHNbaV07XG4gICAgICAgICAgICAgICAgcG9zaXRpb24gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghKGNvbG9yIGluc3RhbmNlb2YgQ29sb3IpIHx8ICghKChpID09PSAwIHx8IGkgKyAxID09PSBzdG9wcy5sZW5ndGgpICYmIHBvc2l0aW9uID09PSB1bmRlZmluZWQpICYmICEocG9zaXRpb24gaW5zdGFuY2VvZiBEaW1lbnNpb24pKSkge1xuICAgICAgICAgICAgICAgIHRocm93QXJndW1lbnREZXNjcmlwdG9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwb3NpdGlvblZhbHVlID0gcG9zaXRpb24gPyBwb3NpdGlvbi50b0NTUyhyZW5kZXJFbnYpIDogaSA9PT0gMCA/IFwiMCVcIiA6IFwiMTAwJVwiO1xuICAgICAgICAgICAgYWxwaGEgPSBjb2xvci5hbHBoYTtcbiAgICAgICAgICAgIHJldHVybmVyICs9ICc8c3RvcCBvZmZzZXQ9XCInICsgcG9zaXRpb25WYWx1ZSArICdcIiBzdG9wLWNvbG9yPVwiJyArIGNvbG9yLnRvUkdCKCkgKyAnXCInICsgKGFscGhhIDwgMSA/ICcgc3RvcC1vcGFjaXR5PVwiJyArIGFscGhhICsgJ1wiJyA6ICcnKSArICcvPic7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuZXIgKz0gJzwvJyArIGdyYWRpZW50VHlwZSArICdHcmFkaWVudD4nICtcbiAgICAgICAgICAgICc8cmVjdCAnICsgcmVjdGFuZ2xlRGltZW5zaW9uICsgJyBmaWxsPVwidXJsKCNncmFkaWVudClcIiAvPjwvc3ZnPic7XG5cbiAgICAgICAgcmV0dXJuZXIgPSBlbmNvZGVVUklDb21wb25lbnQocmV0dXJuZXIpO1xuXG4gICAgICAgIHJldHVybmVyID0gXCJkYXRhOmltYWdlL3N2Zyt4bWwsXCIgKyByZXR1cm5lcjtcbiAgICAgICAgcmV0dXJuIG5ldyBVUkwobmV3IFF1b3RlZChcIidcIiArIHJldHVybmVyICsgXCInXCIsIHJldHVybmVyLCBmYWxzZSwgdGhpcy5pbmRleCwgdGhpcy5jdXJyZW50RmlsZUluZm8pLCB0aGlzLmluZGV4LCB0aGlzLmN1cnJlbnRGaWxlSW5mbyk7XG4gICAgfSk7XG59O1xuXG59LHtcIi4uL3RyZWUvY29sb3JcIjo1MCxcIi4uL3RyZWUvZGltZW5zaW9uXCI6NTYsXCIuLi90cmVlL2V4cHJlc3Npb25cIjo1OSxcIi4uL3RyZWUvcXVvdGVkXCI6NzMsXCIuLi90cmVlL3VybFwiOjgwLFwiLi9mdW5jdGlvbi1yZWdpc3RyeVwiOjIyfV0sMjk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIEtleXdvcmQgPSByZXF1aXJlKFwiLi4vdHJlZS9rZXl3b3JkXCIpLFxuICAgIERldGFjaGVkUnVsZXNldCA9IHJlcXVpcmUoXCIuLi90cmVlL2RldGFjaGVkLXJ1bGVzZXRcIiksXG4gICAgRGltZW5zaW9uID0gcmVxdWlyZShcIi4uL3RyZWUvZGltZW5zaW9uXCIpLFxuICAgIENvbG9yID0gcmVxdWlyZShcIi4uL3RyZWUvY29sb3JcIiksXG4gICAgUXVvdGVkID0gcmVxdWlyZShcIi4uL3RyZWUvcXVvdGVkXCIpLFxuICAgIEFub255bW91cyA9IHJlcXVpcmUoXCIuLi90cmVlL2Fub255bW91c1wiKSxcbiAgICBVUkwgPSByZXF1aXJlKFwiLi4vdHJlZS91cmxcIiksXG4gICAgT3BlcmF0aW9uID0gcmVxdWlyZShcIi4uL3RyZWUvb3BlcmF0aW9uXCIpLFxuICAgIGZ1bmN0aW9uUmVnaXN0cnkgPSByZXF1aXJlKFwiLi9mdW5jdGlvbi1yZWdpc3RyeVwiKTtcblxudmFyIGlzYSA9IGZ1bmN0aW9uIChuLCBUeXBlKSB7XG4gICAgICAgIHJldHVybiAobiBpbnN0YW5jZW9mIFR5cGUpID8gS2V5d29yZC5UcnVlIDogS2V5d29yZC5GYWxzZTtcbiAgICB9LFxuICAgIGlzdW5pdCA9IGZ1bmN0aW9uIChuLCB1bml0KSB7XG4gICAgICAgIGlmICh1bml0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IHsgdHlwZTogXCJBcmd1bWVudFwiLCBtZXNzYWdlOiBcIm1pc3NpbmcgdGhlIHJlcXVpcmVkIHNlY29uZCBhcmd1bWVudCB0byBpc3VuaXQuXCIgfTtcbiAgICAgICAgfVxuICAgICAgICB1bml0ID0gdHlwZW9mIHVuaXQudmFsdWUgPT09IFwic3RyaW5nXCIgPyB1bml0LnZhbHVlIDogdW5pdDtcbiAgICAgICAgaWYgKHR5cGVvZiB1bml0ICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyB7IHR5cGU6IFwiQXJndW1lbnRcIiwgbWVzc2FnZTogXCJTZWNvbmQgYXJndW1lbnQgdG8gaXN1bml0IHNob3VsZCBiZSBhIHVuaXQgb3IgYSBzdHJpbmcuXCIgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKG4gaW5zdGFuY2VvZiBEaW1lbnNpb24pICYmIG4udW5pdC5pcyh1bml0KSA/IEtleXdvcmQuVHJ1ZSA6IEtleXdvcmQuRmFsc2U7XG4gICAgfSxcbiAgICBnZXRJdGVtc0Zyb21Ob2RlID0gZnVuY3Rpb24obm9kZSkge1xuICAgICAgICAvLyBoYW5kbGUgbm9uLWFycmF5IHZhbHVlcyBhcyBhbiBhcnJheSBvZiBsZW5ndGggMVxuICAgICAgICAvLyByZXR1cm4gJ3VuZGVmaW5lZCcgaWYgaW5kZXggaXMgaW52YWxpZFxuICAgICAgICB2YXIgaXRlbXMgPSBBcnJheS5pc0FycmF5KG5vZGUudmFsdWUpID9cbiAgICAgICAgICAgIG5vZGUudmFsdWUgOiBBcnJheShub2RlKTtcblxuICAgICAgICByZXR1cm4gaXRlbXM7XG4gICAgfTtcbmZ1bmN0aW9uUmVnaXN0cnkuYWRkTXVsdGlwbGUoe1xuICAgIGlzcnVsZXNldDogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgcmV0dXJuIGlzYShuLCBEZXRhY2hlZFJ1bGVzZXQpO1xuICAgIH0sXG4gICAgaXNjb2xvcjogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgcmV0dXJuIGlzYShuLCBDb2xvcik7XG4gICAgfSxcbiAgICBpc251bWJlcjogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgcmV0dXJuIGlzYShuLCBEaW1lbnNpb24pO1xuICAgIH0sXG4gICAgaXNzdHJpbmc6IGZ1bmN0aW9uIChuKSB7XG4gICAgICAgIHJldHVybiBpc2EobiwgUXVvdGVkKTtcbiAgICB9LFxuICAgIGlza2V5d29yZDogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgcmV0dXJuIGlzYShuLCBLZXl3b3JkKTtcbiAgICB9LFxuICAgIGlzdXJsOiBmdW5jdGlvbiAobikge1xuICAgICAgICByZXR1cm4gaXNhKG4sIFVSTCk7XG4gICAgfSxcbiAgICBpc3BpeGVsOiBmdW5jdGlvbiAobikge1xuICAgICAgICByZXR1cm4gaXN1bml0KG4sICdweCcpO1xuICAgIH0sXG4gICAgaXNwZXJjZW50YWdlOiBmdW5jdGlvbiAobikge1xuICAgICAgICByZXR1cm4gaXN1bml0KG4sICclJyk7XG4gICAgfSxcbiAgICBpc2VtOiBmdW5jdGlvbiAobikge1xuICAgICAgICByZXR1cm4gaXN1bml0KG4sICdlbScpO1xuICAgIH0sXG4gICAgaXN1bml0OiBpc3VuaXQsXG4gICAgdW5pdDogZnVuY3Rpb24gKHZhbCwgdW5pdCkge1xuICAgICAgICBpZiAoISh2YWwgaW5zdGFuY2VvZiBEaW1lbnNpb24pKSB7XG4gICAgICAgICAgICB0aHJvdyB7IHR5cGU6IFwiQXJndW1lbnRcIixcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBcInRoZSBmaXJzdCBhcmd1bWVudCB0byB1bml0IG11c3QgYmUgYSBudW1iZXJcIiArXG4gICAgICAgICAgICAgICAgICAgICh2YWwgaW5zdGFuY2VvZiBPcGVyYXRpb24gPyBcIi4gSGF2ZSB5b3UgZm9yZ290dGVuIHBhcmVudGhlc2lzP1wiIDogXCJcIikgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodW5pdCkge1xuICAgICAgICAgICAgaWYgKHVuaXQgaW5zdGFuY2VvZiBLZXl3b3JkKSB7XG4gICAgICAgICAgICAgICAgdW5pdCA9IHVuaXQudmFsdWU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHVuaXQgPSB1bml0LnRvQ1NTKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1bml0ID0gXCJcIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IERpbWVuc2lvbih2YWwudmFsdWUsIHVuaXQpO1xuICAgIH0sXG4gICAgXCJnZXQtdW5pdFwiOiBmdW5jdGlvbiAobikge1xuICAgICAgICByZXR1cm4gbmV3IEFub255bW91cyhuLnVuaXQpO1xuICAgIH0sXG4gICAgZXh0cmFjdDogZnVuY3Rpb24odmFsdWVzLCBpbmRleCkge1xuICAgICAgICBpbmRleCA9IGluZGV4LnZhbHVlIC0gMTsgLy8gKDEtYmFzZWQgaW5kZXgpXG5cbiAgICAgICAgcmV0dXJuIGdldEl0ZW1zRnJvbU5vZGUodmFsdWVzKVtpbmRleF07XG4gICAgfSxcbiAgICBsZW5ndGg6IGZ1bmN0aW9uKHZhbHVlcykge1xuICAgICAgICByZXR1cm4gbmV3IERpbWVuc2lvbihnZXRJdGVtc0Zyb21Ob2RlKHZhbHVlcykubGVuZ3RoKTtcbiAgICB9XG59KTtcblxufSx7XCIuLi90cmVlL2Fub255bW91c1wiOjQ2LFwiLi4vdHJlZS9jb2xvclwiOjUwLFwiLi4vdHJlZS9kZXRhY2hlZC1ydWxlc2V0XCI6NTUsXCIuLi90cmVlL2RpbWVuc2lvblwiOjU2LFwiLi4vdHJlZS9rZXl3b3JkXCI6NjUsXCIuLi90cmVlL29wZXJhdGlvblwiOjcxLFwiLi4vdHJlZS9xdW90ZWRcIjo3MyxcIi4uL3RyZWUvdXJsXCI6ODAsXCIuL2Z1bmN0aW9uLXJlZ2lzdHJ5XCI6MjJ9XSwzMDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgY29udGV4dHMgPSByZXF1aXJlKFwiLi9jb250ZXh0c1wiKSxcbiAgICBQYXJzZXIgPSByZXF1aXJlKCcuL3BhcnNlci9wYXJzZXInKSxcbiAgICBGdW5jdGlvbkltcG9ydGVyID0gcmVxdWlyZSgnLi9wbHVnaW5zL2Z1bmN0aW9uLWltcG9ydGVyJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZW52aXJvbm1lbnQpIHtcblxuICAgIC8vIEZpbGVJbmZvID0ge1xuICAgIC8vICAncmVsYXRpdmVVcmxzJyAtIG9wdGlvbiAtIHdoZXRoZXIgdG8gYWRqdXN0IFVSTCdzIHRvIGJlIHJlbGF0aXZlXG4gICAgLy8gICdmaWxlbmFtZScgLSBmdWxsIHJlc29sdmVkIGZpbGVuYW1lIG9mIGN1cnJlbnQgZmlsZVxuICAgIC8vICAncm9vdHBhdGgnIC0gcGF0aCB0byBhcHBlbmQgdG8gbm9ybWFsIFVSTHMgZm9yIHRoaXMgbm9kZVxuICAgIC8vICAnY3VycmVudERpcmVjdG9yeScgLSBwYXRoIHRvIHRoZSBjdXJyZW50IGZpbGUsIGFic29sdXRlXG4gICAgLy8gICdyb290RmlsZW5hbWUnIC0gZmlsZW5hbWUgb2YgdGhlIGJhc2UgZmlsZVxuICAgIC8vICAnZW50cnlQYXRoJyAtIGFic29sdXRlIHBhdGggdG8gdGhlIGVudHJ5IGZpbGVcbiAgICAvLyAgJ3JlZmVyZW5jZScgLSB3aGV0aGVyIHRoZSBmaWxlIHNob3VsZCBub3QgYmUgb3V0cHV0IGFuZCBvbmx5IG91dHB1dCBwYXJ0cyB0aGF0IGFyZSByZWZlcmVuY2VkXG5cbiAgICB2YXIgSW1wb3J0TWFuYWdlciA9IGZ1bmN0aW9uKGNvbnRleHQsIHJvb3RGaWxlSW5mbykge1xuICAgICAgICB0aGlzLnJvb3RGaWxlbmFtZSA9IHJvb3RGaWxlSW5mby5maWxlbmFtZTtcbiAgICAgICAgdGhpcy5wYXRocyA9IGNvbnRleHQucGF0aHMgfHwgW107ICAvLyBTZWFyY2ggcGF0aHMsIHdoZW4gaW1wb3J0aW5nXG4gICAgICAgIHRoaXMuY29udGVudHMgPSB7fTsgICAgICAgICAgICAgLy8gbWFwIC0gZmlsZW5hbWUgdG8gY29udGVudHMgb2YgYWxsIHRoZSBmaWxlc1xuICAgICAgICB0aGlzLmNvbnRlbnRzSWdub3JlZENoYXJzID0ge307IC8vIG1hcCAtIGZpbGVuYW1lIHRvIGxpbmVzIGF0IHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBmaWxlIHRvIGlnbm9yZVxuICAgICAgICB0aGlzLm1pbWUgPSBjb250ZXh0Lm1pbWU7XG4gICAgICAgIHRoaXMuZXJyb3IgPSBudWxsO1xuICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICAvLyBEZXByZWNhdGVkPyBVbnVzZWQgb3V0c2lkZSBvZiBoZXJlLCBjb3VsZCBiZSB1c2VmdWwuXG4gICAgICAgIHRoaXMucXVldWUgPSBbXTsgICAgICAgIC8vIEZpbGVzIHdoaWNoIGhhdmVuJ3QgYmVlbiBpbXBvcnRlZCB5ZXRcbiAgICAgICAgdGhpcy5maWxlcyA9IHt9OyAgICAgICAgLy8gSG9sZHMgdGhlIGltcG9ydGVkIHBhcnNlIHRyZWVzLlxuICAgIH07XG4gICAgLyoqXG4gICAgICogQWRkIGFuIGltcG9ydCB0byBiZSBpbXBvcnRlZFxuICAgICAqIEBwYXJhbSBwYXRoIC0gdGhlIHJhdyBwYXRoXG4gICAgICogQHBhcmFtIHRyeUFwcGVuZExlc3NFeHRlbnNpb24gLSB3aGV0aGVyIHRvIHRyeSBhcHBlbmRpbmcgdGhlIGxlc3MgZXh0ZW5zaW9uIChpZiB0aGUgcGF0aCBoYXMgbm8gZXh0ZW5zaW9uKVxuICAgICAqIEBwYXJhbSBjdXJyZW50RmlsZUluZm8gLSB0aGUgY3VycmVudCBmaWxlIGluZm8gKHVzZWQgZm9yIGluc3RhbmNlIHRvIHdvcmsgb3V0IHJlbGF0aXZlIHBhdGhzKVxuICAgICAqIEBwYXJhbSBpbXBvcnRPcHRpb25zIC0gaW1wb3J0IG9wdGlvbnNcbiAgICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBjYWxsYmFjayBmb3Igd2hlbiBpdCBpcyBpbXBvcnRlZFxuICAgICAqL1xuICAgIEltcG9ydE1hbmFnZXIucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAocGF0aCwgdHJ5QXBwZW5kTGVzc0V4dGVuc2lvbiwgY3VycmVudEZpbGVJbmZvLCBpbXBvcnRPcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgaW1wb3J0TWFuYWdlciA9IHRoaXM7XG4gICAgICAgIHRoaXMucXVldWUucHVzaChwYXRoKTtcblxuICAgICAgICB2YXIgZmlsZVBhcnNlZEZ1bmMgPSBmdW5jdGlvbiAoZSwgcm9vdCwgZnVsbFBhdGgpIHtcbiAgICAgICAgICAgIGltcG9ydE1hbmFnZXIucXVldWUuc3BsaWNlKGltcG9ydE1hbmFnZXIucXVldWUuaW5kZXhPZihwYXRoKSwgMSk7IC8vIFJlbW92ZSB0aGUgcGF0aCBmcm9tIHRoZSBxdWV1ZVxuXG4gICAgICAgICAgICB2YXIgaW1wb3J0ZWRFcXVhbHNSb290ID0gZnVsbFBhdGggPT09IGltcG9ydE1hbmFnZXIucm9vdEZpbGVuYW1lO1xuICAgICAgICAgICAgaWYgKGltcG9ydE9wdGlvbnMub3B0aW9uYWwgJiYgZSkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHtydWxlczpbXX0sIGZhbHNlLCBudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGltcG9ydE1hbmFnZXIuZmlsZXNbZnVsbFBhdGhdID0gcm9vdDtcbiAgICAgICAgICAgICAgICBpZiAoZSAmJiAhaW1wb3J0TWFuYWdlci5lcnJvcikgeyBpbXBvcnRNYW5hZ2VyLmVycm9yID0gZTsgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGUsIHJvb3QsIGltcG9ydGVkRXF1YWxzUm9vdCwgZnVsbFBhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHZhciBuZXdGaWxlSW5mbyA9IHtcbiAgICAgICAgICAgIHJlbGF0aXZlVXJsczogdGhpcy5jb250ZXh0LnJlbGF0aXZlVXJscyxcbiAgICAgICAgICAgIGVudHJ5UGF0aDogY3VycmVudEZpbGVJbmZvLmVudHJ5UGF0aCxcbiAgICAgICAgICAgIHJvb3RwYXRoOiBjdXJyZW50RmlsZUluZm8ucm9vdHBhdGgsXG4gICAgICAgICAgICByb290RmlsZW5hbWU6IGN1cnJlbnRGaWxlSW5mby5yb290RmlsZW5hbWVcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgZmlsZU1hbmFnZXIgPSBlbnZpcm9ubWVudC5nZXRGaWxlTWFuYWdlcihwYXRoLCBjdXJyZW50RmlsZUluZm8uY3VycmVudERpcmVjdG9yeSwgdGhpcy5jb250ZXh0LCBlbnZpcm9ubWVudCk7XG5cbiAgICAgICAgaWYgKCFmaWxlTWFuYWdlcikge1xuICAgICAgICAgICAgZmlsZVBhcnNlZEZ1bmMoeyBtZXNzYWdlOiBcIkNvdWxkIG5vdCBmaW5kIGEgZmlsZS1tYW5hZ2VyIGZvciBcIiArIHBhdGggfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHJ5QXBwZW5kTGVzc0V4dGVuc2lvbikge1xuICAgICAgICAgICAgcGF0aCA9IGZpbGVNYW5hZ2VyLnRyeUFwcGVuZEV4dGVuc2lvbihwYXRoLCBpbXBvcnRPcHRpb25zLnBsdWdpbiA/IFwiLmpzXCIgOiBcIi5sZXNzXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGxvYWRGaWxlQ2FsbGJhY2sgPSBmdW5jdGlvbihsb2FkZWRGaWxlKSB7XG4gICAgICAgICAgICB2YXIgcmVzb2x2ZWRGaWxlbmFtZSA9IGxvYWRlZEZpbGUuZmlsZW5hbWUsXG4gICAgICAgICAgICAgICAgY29udGVudHMgPSBsb2FkZWRGaWxlLmNvbnRlbnRzLnJlcGxhY2UoL15cXHVGRUZGLywgJycpO1xuXG4gICAgICAgICAgICAvLyBQYXNzIG9uIGFuIHVwZGF0ZWQgcm9vdHBhdGggaWYgcGF0aCBvZiBpbXBvcnRlZCBmaWxlIGlzIHJlbGF0aXZlIGFuZCBmaWxlXG4gICAgICAgICAgICAvLyBpcyBpbiBhIChzdWJ8c3VwKSBkaXJlY3RvcnlcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBFeGFtcGxlczpcbiAgICAgICAgICAgIC8vIC0gSWYgcGF0aCBvZiBpbXBvcnRlZCBmaWxlIGlzICdtb2R1bGUvbmF2L25hdi5sZXNzJyBhbmQgcm9vdHBhdGggaXMgJ2xlc3MvJyxcbiAgICAgICAgICAgIC8vICAgdGhlbiByb290cGF0aCBzaG91bGQgYmVjb21lICdsZXNzL21vZHVsZS9uYXYvJ1xuICAgICAgICAgICAgLy8gLSBJZiBwYXRoIG9mIGltcG9ydGVkIGZpbGUgaXMgJy4uL21peGlucy5sZXNzJyBhbmQgcm9vdHBhdGggaXMgJ2xlc3MvJyxcbiAgICAgICAgICAgIC8vICAgdGhlbiByb290cGF0aCBzaG91bGQgYmVjb21lICdsZXNzLy4uLydcbiAgICAgICAgICAgIG5ld0ZpbGVJbmZvLmN1cnJlbnREaXJlY3RvcnkgPSBmaWxlTWFuYWdlci5nZXRQYXRoKHJlc29sdmVkRmlsZW5hbWUpO1xuICAgICAgICAgICAgaWYgKG5ld0ZpbGVJbmZvLnJlbGF0aXZlVXJscykge1xuICAgICAgICAgICAgICAgIG5ld0ZpbGVJbmZvLnJvb3RwYXRoID0gZmlsZU1hbmFnZXIuam9pbihcbiAgICAgICAgICAgICAgICAgICAgKGltcG9ydE1hbmFnZXIuY29udGV4dC5yb290cGF0aCB8fCBcIlwiKSxcbiAgICAgICAgICAgICAgICAgICAgZmlsZU1hbmFnZXIucGF0aERpZmYobmV3RmlsZUluZm8uY3VycmVudERpcmVjdG9yeSwgbmV3RmlsZUluZm8uZW50cnlQYXRoKSk7XG5cbiAgICAgICAgICAgICAgICBpZiAoIWZpbGVNYW5hZ2VyLmlzUGF0aEFic29sdXRlKG5ld0ZpbGVJbmZvLnJvb3RwYXRoKSAmJiBmaWxlTWFuYWdlci5hbHdheXNNYWtlUGF0aHNBYnNvbHV0ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld0ZpbGVJbmZvLnJvb3RwYXRoID0gZmlsZU1hbmFnZXIuam9pbihuZXdGaWxlSW5mby5lbnRyeVBhdGgsIG5ld0ZpbGVJbmZvLnJvb3RwYXRoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBuZXdGaWxlSW5mby5maWxlbmFtZSA9IHJlc29sdmVkRmlsZW5hbWU7XG5cbiAgICAgICAgICAgIHZhciBuZXdFbnYgPSBuZXcgY29udGV4dHMuUGFyc2UoaW1wb3J0TWFuYWdlci5jb250ZXh0KTtcblxuICAgICAgICAgICAgbmV3RW52LnByb2Nlc3NJbXBvcnRzID0gZmFsc2U7XG4gICAgICAgICAgICBpbXBvcnRNYW5hZ2VyLmNvbnRlbnRzW3Jlc29sdmVkRmlsZW5hbWVdID0gY29udGVudHM7XG5cbiAgICAgICAgICAgIGlmIChjdXJyZW50RmlsZUluZm8ucmVmZXJlbmNlIHx8IGltcG9ydE9wdGlvbnMucmVmZXJlbmNlKSB7XG4gICAgICAgICAgICAgICAgbmV3RmlsZUluZm8ucmVmZXJlbmNlID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGltcG9ydE9wdGlvbnMucGx1Z2luKSB7XG4gICAgICAgICAgICAgICAgbmV3IEZ1bmN0aW9uSW1wb3J0ZXIobmV3RW52LCBuZXdGaWxlSW5mbykuZXZhbChjb250ZW50cywgZnVuY3Rpb24gKGUsIHJvb3QpIHtcbiAgICAgICAgICAgICAgICAgICAgZmlsZVBhcnNlZEZ1bmMoZSwgcm9vdCwgcmVzb2x2ZWRGaWxlbmFtZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGltcG9ydE9wdGlvbnMuaW5saW5lKSB7XG4gICAgICAgICAgICAgICAgZmlsZVBhcnNlZEZ1bmMobnVsbCwgY29udGVudHMsIHJlc29sdmVkRmlsZW5hbWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBuZXcgUGFyc2VyKG5ld0VudiwgaW1wb3J0TWFuYWdlciwgbmV3RmlsZUluZm8pLnBhcnNlKGNvbnRlbnRzLCBmdW5jdGlvbiAoZSwgcm9vdCkge1xuICAgICAgICAgICAgICAgICAgICBmaWxlUGFyc2VkRnVuYyhlLCByb290LCByZXNvbHZlZEZpbGVuYW1lKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgcHJvbWlzZSA9IGZpbGVNYW5hZ2VyLmxvYWRGaWxlKHBhdGgsIGN1cnJlbnRGaWxlSW5mby5jdXJyZW50RGlyZWN0b3J5LCB0aGlzLmNvbnRleHQsIGVudmlyb25tZW50LFxuICAgICAgICAgICAgZnVuY3Rpb24oZXJyLCBsb2FkZWRGaWxlKSB7XG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgZmlsZVBhcnNlZEZ1bmMoZXJyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbG9hZEZpbGVDYWxsYmFjayhsb2FkZWRGaWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChwcm9taXNlKSB7XG4gICAgICAgICAgICBwcm9taXNlLnRoZW4obG9hZEZpbGVDYWxsYmFjaywgZmlsZVBhcnNlZEZ1bmMpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gSW1wb3J0TWFuYWdlcjtcbn07XG5cbn0se1wiLi9jb250ZXh0c1wiOjExLFwiLi9wYXJzZXIvcGFyc2VyXCI6MzgsXCIuL3BsdWdpbnMvZnVuY3Rpb24taW1wb3J0ZXJcIjo0MH1dLDMxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZW52aXJvbm1lbnQsIGZpbGVNYW5hZ2Vycykge1xuICAgIHZhciBTb3VyY2VNYXBPdXRwdXQsIFNvdXJjZU1hcEJ1aWxkZXIsIFBhcnNlVHJlZSwgSW1wb3J0TWFuYWdlciwgRW52aXJvbm1lbnQ7XG5cbiAgICB2YXIgbGVzcyA9IHtcbiAgICAgICAgdmVyc2lvbjogWzIsIDcsIDFdLFxuICAgICAgICBkYXRhOiByZXF1aXJlKCcuL2RhdGEnKSxcbiAgICAgICAgdHJlZTogcmVxdWlyZSgnLi90cmVlJyksXG4gICAgICAgIEVudmlyb25tZW50OiAoRW52aXJvbm1lbnQgPSByZXF1aXJlKFwiLi9lbnZpcm9ubWVudC9lbnZpcm9ubWVudFwiKSksXG4gICAgICAgIEFic3RyYWN0RmlsZU1hbmFnZXI6IHJlcXVpcmUoXCIuL2Vudmlyb25tZW50L2Fic3RyYWN0LWZpbGUtbWFuYWdlclwiKSxcbiAgICAgICAgZW52aXJvbm1lbnQ6IChlbnZpcm9ubWVudCA9IG5ldyBFbnZpcm9ubWVudChlbnZpcm9ubWVudCwgZmlsZU1hbmFnZXJzKSksXG4gICAgICAgIHZpc2l0b3JzOiByZXF1aXJlKCcuL3Zpc2l0b3JzJyksXG4gICAgICAgIFBhcnNlcjogcmVxdWlyZSgnLi9wYXJzZXIvcGFyc2VyJyksXG4gICAgICAgIGZ1bmN0aW9uczogcmVxdWlyZSgnLi9mdW5jdGlvbnMnKShlbnZpcm9ubWVudCksXG4gICAgICAgIGNvbnRleHRzOiByZXF1aXJlKFwiLi9jb250ZXh0c1wiKSxcbiAgICAgICAgU291cmNlTWFwT3V0cHV0OiAoU291cmNlTWFwT3V0cHV0ID0gcmVxdWlyZSgnLi9zb3VyY2UtbWFwLW91dHB1dCcpKGVudmlyb25tZW50KSksXG4gICAgICAgIFNvdXJjZU1hcEJ1aWxkZXI6IChTb3VyY2VNYXBCdWlsZGVyID0gcmVxdWlyZSgnLi9zb3VyY2UtbWFwLWJ1aWxkZXInKShTb3VyY2VNYXBPdXRwdXQsIGVudmlyb25tZW50KSksXG4gICAgICAgIFBhcnNlVHJlZTogKFBhcnNlVHJlZSA9IHJlcXVpcmUoJy4vcGFyc2UtdHJlZScpKFNvdXJjZU1hcEJ1aWxkZXIpKSxcbiAgICAgICAgSW1wb3J0TWFuYWdlcjogKEltcG9ydE1hbmFnZXIgPSByZXF1aXJlKCcuL2ltcG9ydC1tYW5hZ2VyJykoZW52aXJvbm1lbnQpKSxcbiAgICAgICAgcmVuZGVyOiByZXF1aXJlKFwiLi9yZW5kZXJcIikoZW52aXJvbm1lbnQsIFBhcnNlVHJlZSwgSW1wb3J0TWFuYWdlciksXG4gICAgICAgIHBhcnNlOiByZXF1aXJlKFwiLi9wYXJzZVwiKShlbnZpcm9ubWVudCwgUGFyc2VUcmVlLCBJbXBvcnRNYW5hZ2VyKSxcbiAgICAgICAgTGVzc0Vycm9yOiByZXF1aXJlKCcuL2xlc3MtZXJyb3InKSxcbiAgICAgICAgdHJhbnNmb3JtVHJlZTogcmVxdWlyZSgnLi90cmFuc2Zvcm0tdHJlZScpLFxuICAgICAgICB1dGlsczogcmVxdWlyZSgnLi91dGlscycpLFxuICAgICAgICBQbHVnaW5NYW5hZ2VyOiByZXF1aXJlKCcuL3BsdWdpbi1tYW5hZ2VyJyksXG4gICAgICAgIGxvZ2dlcjogcmVxdWlyZSgnLi9sb2dnZXInKVxuICAgIH07XG5cbiAgICByZXR1cm4gbGVzcztcbn07XG5cbn0se1wiLi9jb250ZXh0c1wiOjExLFwiLi9kYXRhXCI6MTMsXCIuL2Vudmlyb25tZW50L2Fic3RyYWN0LWZpbGUtbWFuYWdlclwiOjE1LFwiLi9lbnZpcm9ubWVudC9lbnZpcm9ubWVudFwiOjE2LFwiLi9mdW5jdGlvbnNcIjoyMyxcIi4vaW1wb3J0LW1hbmFnZXJcIjozMCxcIi4vbGVzcy1lcnJvclwiOjMyLFwiLi9sb2dnZXJcIjozMyxcIi4vcGFyc2VcIjozNSxcIi4vcGFyc2UtdHJlZVwiOjM0LFwiLi9wYXJzZXIvcGFyc2VyXCI6MzgsXCIuL3BsdWdpbi1tYW5hZ2VyXCI6MzksXCIuL3JlbmRlclwiOjQxLFwiLi9zb3VyY2UtbWFwLWJ1aWxkZXJcIjo0MixcIi4vc291cmNlLW1hcC1vdXRwdXRcIjo0MyxcIi4vdHJhbnNmb3JtLXRyZWVcIjo0NCxcIi4vdHJlZVwiOjYyLFwiLi91dGlsc1wiOjgzLFwiLi92aXNpdG9yc1wiOjg3fV0sMzI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIHV0aWxzID0gcmVxdWlyZShcIi4vdXRpbHNcIik7XG5cbnZhciBMZXNzRXJyb3IgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIExlc3NFcnJvcihlLCBpbXBvcnRNYW5hZ2VyLCBjdXJyZW50RmlsZW5hbWUpIHtcblxuICAgIEVycm9yLmNhbGwodGhpcyk7XG5cbiAgICB2YXIgZmlsZW5hbWUgPSBlLmZpbGVuYW1lIHx8IGN1cnJlbnRGaWxlbmFtZTtcblxuICAgIGlmIChpbXBvcnRNYW5hZ2VyICYmIGZpbGVuYW1lKSB7XG4gICAgICAgIHZhciBpbnB1dCA9IGltcG9ydE1hbmFnZXIuY29udGVudHNbZmlsZW5hbWVdLFxuICAgICAgICAgICAgbG9jID0gdXRpbHMuZ2V0TG9jYXRpb24oZS5pbmRleCwgaW5wdXQpLFxuICAgICAgICAgICAgbGluZSA9IGxvYy5saW5lLFxuICAgICAgICAgICAgY29sICA9IGxvYy5jb2x1bW4sXG4gICAgICAgICAgICBjYWxsTGluZSA9IGUuY2FsbCAmJiB1dGlscy5nZXRMb2NhdGlvbihlLmNhbGwsIGlucHV0KS5saW5lLFxuICAgICAgICAgICAgbGluZXMgPSBpbnB1dC5zcGxpdCgnXFxuJyk7XG5cbiAgICAgICAgdGhpcy50eXBlID0gZS50eXBlIHx8ICdTeW50YXgnO1xuICAgICAgICB0aGlzLmZpbGVuYW1lID0gZmlsZW5hbWU7XG4gICAgICAgIHRoaXMuaW5kZXggPSBlLmluZGV4O1xuICAgICAgICB0aGlzLmxpbmUgPSB0eXBlb2YgbGluZSA9PT0gJ251bWJlcicgPyBsaW5lICsgMSA6IG51bGw7XG4gICAgICAgIHRoaXMuY2FsbExpbmUgPSBjYWxsTGluZSArIDE7XG4gICAgICAgIHRoaXMuY2FsbEV4dHJhY3QgPSBsaW5lc1tjYWxsTGluZV07XG4gICAgICAgIHRoaXMuY29sdW1uID0gY29sO1xuICAgICAgICB0aGlzLmV4dHJhY3QgPSBbXG4gICAgICAgICAgICBsaW5lc1tsaW5lIC0gMV0sXG4gICAgICAgICAgICBsaW5lc1tsaW5lXSxcbiAgICAgICAgICAgIGxpbmVzW2xpbmUgKyAxXVxuICAgICAgICBdO1xuICAgIH1cbiAgICB0aGlzLm1lc3NhZ2UgPSBlLm1lc3NhZ2U7XG4gICAgdGhpcy5zdGFjayA9IGUuc3RhY2s7XG59O1xuXG5pZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdmFyIEYgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICBGLnByb3RvdHlwZSA9IEVycm9yLnByb3RvdHlwZTtcbiAgICBMZXNzRXJyb3IucHJvdG90eXBlID0gbmV3IEYoKTtcbn0gZWxzZSB7XG4gICAgTGVzc0Vycm9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKTtcbn1cblxuTGVzc0Vycm9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExlc3NFcnJvcjtcblxufSx7XCIuL3V0aWxzXCI6ODN9XSwzMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBlcnJvcjogZnVuY3Rpb24obXNnKSB7XG4gICAgICAgIHRoaXMuX2ZpcmVFdmVudChcImVycm9yXCIsIG1zZyk7XG4gICAgfSxcbiAgICB3YXJuOiBmdW5jdGlvbihtc2cpIHtcbiAgICAgICAgdGhpcy5fZmlyZUV2ZW50KFwid2FyblwiLCBtc2cpO1xuICAgIH0sXG4gICAgaW5mbzogZnVuY3Rpb24obXNnKSB7XG4gICAgICAgIHRoaXMuX2ZpcmVFdmVudChcImluZm9cIiwgbXNnKTtcbiAgICB9LFxuICAgIGRlYnVnOiBmdW5jdGlvbihtc2cpIHtcbiAgICAgICAgdGhpcy5fZmlyZUV2ZW50KFwiZGVidWdcIiwgbXNnKTtcbiAgICB9LFxuICAgIGFkZExpc3RlbmVyOiBmdW5jdGlvbihsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9saXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG4gICAgfSxcbiAgICByZW1vdmVMaXN0ZW5lcjogZnVuY3Rpb24obGlzdGVuZXIpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLl9saXN0ZW5lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbaV0gPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIF9maXJlRXZlbnQ6IGZ1bmN0aW9uKHR5cGUsIG1zZykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX2xpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGxvZ0Z1bmN0aW9uID0gdGhpcy5fbGlzdGVuZXJzW2ldW3R5cGVdO1xuICAgICAgICAgICAgaWYgKGxvZ0Z1bmN0aW9uKSB7XG4gICAgICAgICAgICAgICAgbG9nRnVuY3Rpb24obXNnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG4gICAgX2xpc3RlbmVyczogW11cbn07XG5cbn0se31dLDM0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBMZXNzRXJyb3IgPSByZXF1aXJlKCcuL2xlc3MtZXJyb3InKSxcbiAgICB0cmFuc2Zvcm1UcmVlID0gcmVxdWlyZShcIi4vdHJhbnNmb3JtLXRyZWVcIiksXG4gICAgbG9nZ2VyID0gcmVxdWlyZShcIi4vbG9nZ2VyXCIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKFNvdXJjZU1hcEJ1aWxkZXIpIHtcbiAgICB2YXIgUGFyc2VUcmVlID0gZnVuY3Rpb24ocm9vdCwgaW1wb3J0cykge1xuICAgICAgICB0aGlzLnJvb3QgPSByb290O1xuICAgICAgICB0aGlzLmltcG9ydHMgPSBpbXBvcnRzO1xuICAgIH07XG5cbiAgICBQYXJzZVRyZWUucHJvdG90eXBlLnRvQ1NTID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICB2YXIgZXZhbGRSb290LCByZXN1bHQgPSB7fSwgc291cmNlTWFwQnVpbGRlcjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGV2YWxkUm9vdCA9IHRyYW5zZm9ybVRyZWUodGhpcy5yb290LCBvcHRpb25zKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IExlc3NFcnJvcihlLCB0aGlzLmltcG9ydHMpO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZhciBjb21wcmVzcyA9IEJvb2xlYW4ob3B0aW9ucy5jb21wcmVzcyk7XG4gICAgICAgICAgICBpZiAoY29tcHJlc3MpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIud2FybihcIlRoZSBjb21wcmVzcyBvcHRpb24gaGFzIGJlZW4gZGVwcmVjYXRlZC4gV2UgcmVjb21tZW5kIHlvdSB1c2UgYSBkZWRpY2F0ZWQgY3NzIG1pbmlmaWVyLCBmb3IgaW5zdGFuY2Ugc2VlIGxlc3MtcGx1Z2luLWNsZWFuLWNzcy5cIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciB0b0NTU09wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgY29tcHJlc3M6IGNvbXByZXNzLFxuICAgICAgICAgICAgICAgIGR1bXBMaW5lTnVtYmVyczogb3B0aW9ucy5kdW1wTGluZU51bWJlcnMsXG4gICAgICAgICAgICAgICAgc3RyaWN0VW5pdHM6IEJvb2xlYW4ob3B0aW9ucy5zdHJpY3RVbml0cyksXG4gICAgICAgICAgICAgICAgbnVtUHJlY2lzaW9uOiA4fTtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuc291cmNlTWFwKSB7XG4gICAgICAgICAgICAgICAgc291cmNlTWFwQnVpbGRlciA9IG5ldyBTb3VyY2VNYXBCdWlsZGVyKG9wdGlvbnMuc291cmNlTWFwKTtcbiAgICAgICAgICAgICAgICByZXN1bHQuY3NzID0gc291cmNlTWFwQnVpbGRlci50b0NTUyhldmFsZFJvb3QsIHRvQ1NTT3B0aW9ucywgdGhpcy5pbXBvcnRzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LmNzcyA9IGV2YWxkUm9vdC50b0NTUyh0b0NTU09wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgTGVzc0Vycm9yKGUsIHRoaXMuaW1wb3J0cyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy5wbHVnaW5NYW5hZ2VyKSB7XG4gICAgICAgICAgICB2YXIgcG9zdFByb2Nlc3NvcnMgPSBvcHRpb25zLnBsdWdpbk1hbmFnZXIuZ2V0UG9zdFByb2Nlc3NvcnMoKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9zdFByb2Nlc3NvcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICByZXN1bHQuY3NzID0gcG9zdFByb2Nlc3NvcnNbaV0ucHJvY2VzcyhyZXN1bHQuY3NzLCB7IHNvdXJjZU1hcDogc291cmNlTWFwQnVpbGRlciwgb3B0aW9uczogb3B0aW9ucywgaW1wb3J0czogdGhpcy5pbXBvcnRzIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLnNvdXJjZU1hcCkge1xuICAgICAgICAgICAgcmVzdWx0Lm1hcCA9IHNvdXJjZU1hcEJ1aWxkZXIuZ2V0RXh0ZXJuYWxTb3VyY2VNYXAoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlc3VsdC5pbXBvcnRzID0gW107XG4gICAgICAgIGZvciAodmFyIGZpbGUgaW4gdGhpcy5pbXBvcnRzLmZpbGVzKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pbXBvcnRzLmZpbGVzLmhhc093blByb3BlcnR5KGZpbGUpICYmIGZpbGUgIT09IHRoaXMuaW1wb3J0cy5yb290RmlsZW5hbWUpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQuaW1wb3J0cy5wdXNoKGZpbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgICByZXR1cm4gUGFyc2VUcmVlO1xufTtcblxufSx7XCIuL2xlc3MtZXJyb3JcIjozMixcIi4vbG9nZ2VyXCI6MzMsXCIuL3RyYW5zZm9ybS10cmVlXCI6NDR9XSwzNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgUHJvbWlzZUNvbnN0cnVjdG9yLFxuICAgIGNvbnRleHRzID0gcmVxdWlyZShcIi4vY29udGV4dHNcIiksXG4gICAgUGFyc2VyID0gcmVxdWlyZSgnLi9wYXJzZXIvcGFyc2VyJyksXG4gICAgUGx1Z2luTWFuYWdlciA9IHJlcXVpcmUoJy4vcGx1Z2luLW1hbmFnZXInKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbnZpcm9ubWVudCwgUGFyc2VUcmVlLCBJbXBvcnRNYW5hZ2VyKSB7XG4gICAgdmFyIHBhcnNlID0gZnVuY3Rpb24gKGlucHV0LCBvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gb3B0aW9ucztcbiAgICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGlmICghUHJvbWlzZUNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgUHJvbWlzZUNvbnN0cnVjdG9yID0gdHlwZW9mIFByb21pc2UgPT09ICd1bmRlZmluZWQnID8gcmVxdWlyZSgncHJvbWlzZScpIDogUHJvbWlzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZUNvbnN0cnVjdG9yKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgICAgICBwYXJzZS5jYWxsKHNlbGYsIGlucHV0LCBvcHRpb25zLCBmdW5jdGlvbihlcnIsIG91dHB1dCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUob3V0cHV0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgY29udGV4dCxcbiAgICAgICAgICAgICAgICByb290RmlsZUluZm8sXG4gICAgICAgICAgICAgICAgcGx1Z2luTWFuYWdlciA9IG5ldyBQbHVnaW5NYW5hZ2VyKHRoaXMpO1xuXG4gICAgICAgICAgICBwbHVnaW5NYW5hZ2VyLmFkZFBsdWdpbnMob3B0aW9ucy5wbHVnaW5zKTtcbiAgICAgICAgICAgIG9wdGlvbnMucGx1Z2luTWFuYWdlciA9IHBsdWdpbk1hbmFnZXI7XG5cbiAgICAgICAgICAgIGNvbnRleHQgPSBuZXcgY29udGV4dHMuUGFyc2Uob3B0aW9ucyk7XG5cbiAgICAgICAgICAgIGlmIChvcHRpb25zLnJvb3RGaWxlSW5mbykge1xuICAgICAgICAgICAgICAgIHJvb3RGaWxlSW5mbyA9IG9wdGlvbnMucm9vdEZpbGVJbmZvO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgZmlsZW5hbWUgPSBvcHRpb25zLmZpbGVuYW1lIHx8IFwiaW5wdXRcIjtcbiAgICAgICAgICAgICAgICB2YXIgZW50cnlQYXRoID0gZmlsZW5hbWUucmVwbGFjZSgvW15cXC9cXFxcXSokLywgXCJcIik7XG4gICAgICAgICAgICAgICAgcm9vdEZpbGVJbmZvID0ge1xuICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZTogZmlsZW5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHJlbGF0aXZlVXJsczogY29udGV4dC5yZWxhdGl2ZVVybHMsXG4gICAgICAgICAgICAgICAgICAgIHJvb3RwYXRoOiBjb250ZXh0LnJvb3RwYXRoIHx8IFwiXCIsXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnREaXJlY3Rvcnk6IGVudHJ5UGF0aCxcbiAgICAgICAgICAgICAgICAgICAgZW50cnlQYXRoOiBlbnRyeVBhdGgsXG4gICAgICAgICAgICAgICAgICAgIHJvb3RGaWxlbmFtZTogZmlsZW5hbWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIC8vIGFkZCBpbiBhIG1pc3NpbmcgdHJhaWxpbmcgc2xhc2hcbiAgICAgICAgICAgICAgICBpZiAocm9vdEZpbGVJbmZvLnJvb3RwYXRoICYmIHJvb3RGaWxlSW5mby5yb290cGF0aC5zbGljZSgtMSkgIT09IFwiL1wiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJvb3RGaWxlSW5mby5yb290cGF0aCArPSBcIi9cIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBpbXBvcnRzID0gbmV3IEltcG9ydE1hbmFnZXIoY29udGV4dCwgcm9vdEZpbGVJbmZvKTtcblxuICAgICAgICAgICAgbmV3IFBhcnNlcihjb250ZXh0LCBpbXBvcnRzLCByb290RmlsZUluZm8pXG4gICAgICAgICAgICAgICAgLnBhcnNlKGlucHV0LCBmdW5jdGlvbiAoZSwgcm9vdCkge1xuICAgICAgICAgICAgICAgIGlmIChlKSB7IHJldHVybiBjYWxsYmFjayhlKTsgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHJvb3QsIGltcG9ydHMsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfSwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBwYXJzZTtcbn07XG5cbn0se1wiLi9jb250ZXh0c1wiOjExLFwiLi9wYXJzZXIvcGFyc2VyXCI6MzgsXCIuL3BsdWdpbi1tYW5hZ2VyXCI6MzksXCJwcm9taXNlXCI6dW5kZWZpbmVkfV0sMzY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuLy8gU3BsaXQgdGhlIGlucHV0IGludG8gY2h1bmtzLlxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaW5wdXQsIGZhaWwpIHtcbiAgICB2YXIgbGVuID0gaW5wdXQubGVuZ3RoLCBsZXZlbCA9IDAsIHBhcmVuTGV2ZWwgPSAwLFxuICAgICAgICBsYXN0T3BlbmluZywgbGFzdE9wZW5pbmdQYXJlbiwgbGFzdE11bHRpQ29tbWVudCwgbGFzdE11bHRpQ29tbWVudEVuZEJyYWNlLFxuICAgICAgICBjaHVua3MgPSBbXSwgZW1pdEZyb20gPSAwLFxuICAgICAgICBjaHVua2VyQ3VycmVudEluZGV4LCBjdXJyZW50Q2h1bmtTdGFydEluZGV4LCBjYywgY2MyLCBtYXRjaGVkO1xuXG4gICAgZnVuY3Rpb24gZW1pdENodW5rKGZvcmNlKSB7XG4gICAgICAgIHZhciBsZW4gPSBjaHVua2VyQ3VycmVudEluZGV4IC0gZW1pdEZyb207XG4gICAgICAgIGlmICgoKGxlbiA8IDUxMikgJiYgIWZvcmNlKSB8fCAhbGVuKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY2h1bmtzLnB1c2goaW5wdXQuc2xpY2UoZW1pdEZyb20sIGNodW5rZXJDdXJyZW50SW5kZXggKyAxKSk7XG4gICAgICAgIGVtaXRGcm9tID0gY2h1bmtlckN1cnJlbnRJbmRleCArIDE7XG4gICAgfVxuXG4gICAgZm9yIChjaHVua2VyQ3VycmVudEluZGV4ID0gMDsgY2h1bmtlckN1cnJlbnRJbmRleCA8IGxlbjsgY2h1bmtlckN1cnJlbnRJbmRleCsrKSB7XG4gICAgICAgIGNjID0gaW5wdXQuY2hhckNvZGVBdChjaHVua2VyQ3VycmVudEluZGV4KTtcbiAgICAgICAgaWYgKCgoY2MgPj0gOTcpICYmIChjYyA8PSAxMjIpKSB8fCAoY2MgPCAzNCkpIHtcbiAgICAgICAgICAgIC8vIGEteiBvciB3aGl0ZXNwYWNlXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAoY2MpIHtcbiAgICAgICAgICAgIGNhc2UgNDA6ICAgICAgICAgICAgICAgICAgICAgICAgLy8gKFxuICAgICAgICAgICAgICAgIHBhcmVuTGV2ZWwrKztcbiAgICAgICAgICAgICAgICBsYXN0T3BlbmluZ1BhcmVuID0gY2h1bmtlckN1cnJlbnRJbmRleDtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIGNhc2UgNDE6ICAgICAgICAgICAgICAgICAgICAgICAgLy8gKVxuICAgICAgICAgICAgICAgIGlmICgtLXBhcmVuTGV2ZWwgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWlsKFwibWlzc2luZyBvcGVuaW5nIGAoYFwiLCBjaHVua2VyQ3VycmVudEluZGV4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICBjYXNlIDU5OiAgICAgICAgICAgICAgICAgICAgICAgIC8vIDtcbiAgICAgICAgICAgICAgICBpZiAoIXBhcmVuTGV2ZWwpIHsgZW1pdENodW5rKCk7IH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIGNhc2UgMTIzOiAgICAgICAgICAgICAgICAgICAgICAgLy8ge1xuICAgICAgICAgICAgICAgIGxldmVsKys7XG4gICAgICAgICAgICAgICAgbGFzdE9wZW5pbmcgPSBjaHVua2VyQ3VycmVudEluZGV4O1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgY2FzZSAxMjU6ICAgICAgICAgICAgICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAgICAgaWYgKC0tbGV2ZWwgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWlsKFwibWlzc2luZyBvcGVuaW5nIGB7YFwiLCBjaHVua2VyQ3VycmVudEluZGV4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFsZXZlbCAmJiAhcGFyZW5MZXZlbCkgeyBlbWl0Q2h1bmsoKTsgfVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgY2FzZSA5MjogICAgICAgICAgICAgICAgICAgICAgICAvLyBcXFxuICAgICAgICAgICAgICAgIGlmIChjaHVua2VyQ3VycmVudEluZGV4IDwgbGVuIC0gMSkgeyBjaHVua2VyQ3VycmVudEluZGV4Kys7IGNvbnRpbnVlOyB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhaWwoXCJ1bmVzY2FwZWQgYFxcXFxgXCIsIGNodW5rZXJDdXJyZW50SW5kZXgpO1xuICAgICAgICAgICAgY2FzZSAzNDpcbiAgICAgICAgICAgIGNhc2UgMzk6XG4gICAgICAgICAgICBjYXNlIDk2OiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFwiLCAnIGFuZCBgXG4gICAgICAgICAgICAgICAgbWF0Y2hlZCA9IDA7XG4gICAgICAgICAgICAgICAgY3VycmVudENodW5rU3RhcnRJbmRleCA9IGNodW5rZXJDdXJyZW50SW5kZXg7XG4gICAgICAgICAgICAgICAgZm9yIChjaHVua2VyQ3VycmVudEluZGV4ID0gY2h1bmtlckN1cnJlbnRJbmRleCArIDE7IGNodW5rZXJDdXJyZW50SW5kZXggPCBsZW47IGNodW5rZXJDdXJyZW50SW5kZXgrKykge1xuICAgICAgICAgICAgICAgICAgICBjYzIgPSBpbnB1dC5jaGFyQ29kZUF0KGNodW5rZXJDdXJyZW50SW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2MyID4gOTYpIHsgY29udGludWU7IH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNjMiA9PSBjYykgeyBtYXRjaGVkID0gMTsgYnJlYWs7IH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNjMiA9PSA5MikgeyAgICAgICAgLy8gXFxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaHVua2VyQ3VycmVudEluZGV4ID09IGxlbiAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFpbChcInVuZXNjYXBlZCBgXFxcXGBcIiwgY2h1bmtlckN1cnJlbnRJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjaHVua2VyQ3VycmVudEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoZWQpIHsgY29udGludWU7IH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZmFpbChcInVubWF0Y2hlZCBgXCIgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGNjKSArIFwiYFwiLCBjdXJyZW50Q2h1bmtTdGFydEluZGV4KTtcbiAgICAgICAgICAgIGNhc2UgNDc6ICAgICAgICAgICAgICAgICAgICAgICAgLy8gLywgY2hlY2sgZm9yIGNvbW1lbnRcbiAgICAgICAgICAgICAgICBpZiAocGFyZW5MZXZlbCB8fCAoY2h1bmtlckN1cnJlbnRJbmRleCA9PSBsZW4gLSAxKSkgeyBjb250aW51ZTsgfVxuICAgICAgICAgICAgICAgIGNjMiA9IGlucHV0LmNoYXJDb2RlQXQoY2h1bmtlckN1cnJlbnRJbmRleCArIDEpO1xuICAgICAgICAgICAgICAgIGlmIChjYzIgPT0gNDcpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gLy8sIGZpbmQgbG5mZWVkXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY2h1bmtlckN1cnJlbnRJbmRleCA9IGNodW5rZXJDdXJyZW50SW5kZXggKyAyOyBjaHVua2VyQ3VycmVudEluZGV4IDwgbGVuOyBjaHVua2VyQ3VycmVudEluZGV4KyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNjMiA9IGlucHV0LmNoYXJDb2RlQXQoY2h1bmtlckN1cnJlbnRJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGNjMiA8PSAxMykgJiYgKChjYzIgPT0gMTApIHx8IChjYzIgPT0gMTMpKSkgeyBicmVhazsgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjYzIgPT0gNDIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gLyosIGZpbmQgKi9cbiAgICAgICAgICAgICAgICAgICAgbGFzdE11bHRpQ29tbWVudCA9IGN1cnJlbnRDaHVua1N0YXJ0SW5kZXggPSBjaHVua2VyQ3VycmVudEluZGV4O1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNodW5rZXJDdXJyZW50SW5kZXggPSBjaHVua2VyQ3VycmVudEluZGV4ICsgMjsgY2h1bmtlckN1cnJlbnRJbmRleCA8IGxlbiAtIDE7IGNodW5rZXJDdXJyZW50SW5kZXgrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2MyID0gaW5wdXQuY2hhckNvZGVBdChjaHVua2VyQ3VycmVudEluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYzIgPT0gMTI1KSB7IGxhc3RNdWx0aUNvbW1lbnRFbmRCcmFjZSA9IGNodW5rZXJDdXJyZW50SW5kZXg7IH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYzIgIT0gNDIpIHsgY29udGludWU7IH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KGNodW5rZXJDdXJyZW50SW5kZXggKyAxKSA9PSA0NykgeyBicmVhazsgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChjaHVua2VyQ3VycmVudEluZGV4ID09IGxlbiAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWlsKFwibWlzc2luZyBjbG9zaW5nIGAqL2BcIiwgY3VycmVudENodW5rU3RhcnRJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2h1bmtlckN1cnJlbnRJbmRleCsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIGNhc2UgNDI6ICAgICAgICAgICAgICAgICAgICAgICAvLyAqLCBjaGVjayBmb3IgdW5tYXRjaGVkICovXG4gICAgICAgICAgICAgICAgaWYgKChjaHVua2VyQ3VycmVudEluZGV4IDwgbGVuIC0gMSkgJiYgKGlucHV0LmNoYXJDb2RlQXQoY2h1bmtlckN1cnJlbnRJbmRleCArIDEpID09IDQ3KSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFpbChcInVubWF0Y2hlZCBgLypgXCIsIGNodW5rZXJDdXJyZW50SW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChsZXZlbCAhPT0gMCkge1xuICAgICAgICBpZiAoKGxhc3RNdWx0aUNvbW1lbnQgPiBsYXN0T3BlbmluZykgJiYgKGxhc3RNdWx0aUNvbW1lbnRFbmRCcmFjZSA+IGxhc3RNdWx0aUNvbW1lbnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFpbChcIm1pc3NpbmcgY2xvc2luZyBgfWAgb3IgYCovYFwiLCBsYXN0T3BlbmluZyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFpbChcIm1pc3NpbmcgY2xvc2luZyBgfWBcIiwgbGFzdE9wZW5pbmcpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChwYXJlbkxldmVsICE9PSAwKSB7XG4gICAgICAgIHJldHVybiBmYWlsKFwibWlzc2luZyBjbG9zaW5nIGApYFwiLCBsYXN0T3BlbmluZ1BhcmVuKTtcbiAgICB9XG5cbiAgICBlbWl0Q2h1bmsodHJ1ZSk7XG4gICAgcmV0dXJuIGNodW5rcztcbn07XG5cbn0se31dLDM3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBjaHVua2VyID0gcmVxdWlyZSgnLi9jaHVua2VyJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGlucHV0LCAgICAgICAvLyBMZVNTIGlucHV0IHN0cmluZ1xuICAgICAgICBqLCAgICAgICAgICAgLy8gY3VycmVudCBjaHVua1xuICAgICAgICBzYXZlU3RhY2sgPSBbXSwgICAvLyBob2xkcyBzdGF0ZSBmb3IgYmFja3RyYWNraW5nXG4gICAgICAgIGZ1cnRoZXN0LCAgICAvLyBmdXJ0aGVzdCBpbmRleCB0aGUgcGFyc2VyIGhhcyBnb25lIHRvXG4gICAgICAgIGZ1cnRoZXN0UG9zc2libGVFcnJvck1lc3NhZ2UsLy8gaWYgdGhpcyBpcyBmdXJ0aGVzdCB3ZSBnb3QgdG8sIHRoaXMgaXMgdGhlIHByb2JhYmx5IGNhdXNlXG4gICAgICAgIGNodW5rcywgICAgICAvLyBjaHVua2lmaWVkIGlucHV0XG4gICAgICAgIGN1cnJlbnQsICAgICAvLyBjdXJyZW50IGNodW5rXG4gICAgICAgIGN1cnJlbnRQb3MsICAvLyBpbmRleCBvZiBjdXJyZW50IGNodW5rLCBpbiBgaW5wdXRgXG4gICAgICAgIHBhcnNlcklucHV0ID0ge307XG5cbiAgICB2YXIgQ0hBUkNPREVfU1BBQ0UgPSAzMixcbiAgICAgICAgQ0hBUkNPREVfVEFCID0gOSxcbiAgICAgICAgQ0hBUkNPREVfTEYgPSAxMCxcbiAgICAgICAgQ0hBUkNPREVfQ1IgPSAxMyxcbiAgICAgICAgQ0hBUkNPREVfUExVUyA9IDQzLFxuICAgICAgICBDSEFSQ09ERV9DT01NQSA9IDQ0LFxuICAgICAgICBDSEFSQ09ERV9GT1JXQVJEX1NMQVNIID0gNDcsXG4gICAgICAgIENIQVJDT0RFXzkgPSA1NztcblxuICAgIGZ1bmN0aW9uIHNraXBXaGl0ZXNwYWNlKGxlbmd0aCkge1xuICAgICAgICB2YXIgb2xkaSA9IHBhcnNlcklucHV0LmksIG9sZGogPSBqLFxuICAgICAgICAgICAgY3VyciA9IHBhcnNlcklucHV0LmkgLSBjdXJyZW50UG9zLFxuICAgICAgICAgICAgZW5kSW5kZXggPSBwYXJzZXJJbnB1dC5pICsgY3VycmVudC5sZW5ndGggLSBjdXJyLFxuICAgICAgICAgICAgbWVtID0gKHBhcnNlcklucHV0LmkgKz0gbGVuZ3RoKSxcbiAgICAgICAgICAgIGlucCA9IGlucHV0LFxuICAgICAgICAgICAgYywgbmV4dENoYXIsIGNvbW1lbnQ7XG5cbiAgICAgICAgZm9yICg7IHBhcnNlcklucHV0LmkgPCBlbmRJbmRleDsgcGFyc2VySW5wdXQuaSsrKSB7XG4gICAgICAgICAgICBjID0gaW5wLmNoYXJDb2RlQXQocGFyc2VySW5wdXQuaSk7XG5cbiAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC5hdXRvQ29tbWVudEFic29yYiAmJiBjID09PSBDSEFSQ09ERV9GT1JXQVJEX1NMQVNIKSB7XG4gICAgICAgICAgICAgICAgbmV4dENoYXIgPSBpbnAuY2hhckF0KHBhcnNlcklucHV0LmkgKyAxKTtcbiAgICAgICAgICAgICAgICBpZiAobmV4dENoYXIgPT09ICcvJykge1xuICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0ge2luZGV4OiBwYXJzZXJJbnB1dC5pLCBpc0xpbmVDb21tZW50OiB0cnVlfTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5leHROZXdMaW5lID0gaW5wLmluZGV4T2YoXCJcXG5cIiwgcGFyc2VySW5wdXQuaSArIDIpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobmV4dE5ld0xpbmUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXh0TmV3TGluZSA9IGVuZEluZGV4O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LmkgPSBuZXh0TmV3TGluZTtcbiAgICAgICAgICAgICAgICAgICAgY29tbWVudC50ZXh0ID0gaW5wLnN1YnN0cihjb21tZW50LmluZGV4LCBwYXJzZXJJbnB1dC5pIC0gY29tbWVudC5pbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LmNvbW1lbnRTdG9yZS5wdXNoKGNvbW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5leHRDaGFyID09PSAnKicpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5leHRTdGFyU2xhc2ggPSBpbnAuaW5kZXhPZihcIiovXCIsIHBhcnNlcklucHV0LmkgKyAyKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRTdGFyU2xhc2ggPj0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleDogcGFyc2VySW5wdXQuaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OiBpbnAuc3Vic3RyKHBhcnNlcklucHV0LmksIG5leHRTdGFyU2xhc2ggKyAyIC0gcGFyc2VySW5wdXQuaSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNMaW5lQ29tbWVudDogZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5pICs9IGNvbW1lbnQudGV4dC5sZW5ndGggLSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuY29tbWVudFN0b3JlLnB1c2goY29tbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKChjICE9PSBDSEFSQ09ERV9TUEFDRSkgJiYgKGMgIT09IENIQVJDT0RFX0xGKSAmJiAoYyAhPT0gQ0hBUkNPREVfVEFCKSAmJiAoYyAhPT0gQ0hBUkNPREVfQ1IpKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50ID0gY3VycmVudC5zbGljZShsZW5ndGggKyBwYXJzZXJJbnB1dC5pIC0gbWVtICsgY3Vycik7XG4gICAgICAgIGN1cnJlbnRQb3MgPSBwYXJzZXJJbnB1dC5pO1xuXG4gICAgICAgIGlmICghY3VycmVudC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChqIDwgY2h1bmtzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50ID0gY2h1bmtzWysral07XG4gICAgICAgICAgICAgICAgc2tpcFdoaXRlc3BhY2UoMCk7IC8vIHNraXAgc3BhY2UgYXQgdGhlIGJlZ2lubmluZyBvZiBhIGNodW5rXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7IC8vIHRoaW5ncyBjaGFuZ2VkXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwYXJzZXJJbnB1dC5maW5pc2hlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb2xkaSAhPT0gcGFyc2VySW5wdXQuaSB8fCBvbGRqICE9PSBqO1xuICAgIH1cblxuICAgIHBhcnNlcklucHV0LnNhdmUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgY3VycmVudFBvcyA9IHBhcnNlcklucHV0Lmk7XG4gICAgICAgIHNhdmVTdGFjay5wdXNoKCB7IGN1cnJlbnQ6IGN1cnJlbnQsIGk6IHBhcnNlcklucHV0LmksIGo6IGogfSk7XG4gICAgfTtcbiAgICBwYXJzZXJJbnB1dC5yZXN0b3JlID0gZnVuY3Rpb24ocG9zc2libGVFcnJvck1lc3NhZ2UpIHtcblxuICAgICAgICBpZiAocGFyc2VySW5wdXQuaSA+IGZ1cnRoZXN0IHx8IChwYXJzZXJJbnB1dC5pID09PSBmdXJ0aGVzdCAmJiBwb3NzaWJsZUVycm9yTWVzc2FnZSAmJiAhZnVydGhlc3RQb3NzaWJsZUVycm9yTWVzc2FnZSkpIHtcbiAgICAgICAgICAgIGZ1cnRoZXN0ID0gcGFyc2VySW5wdXQuaTtcbiAgICAgICAgICAgIGZ1cnRoZXN0UG9zc2libGVFcnJvck1lc3NhZ2UgPSBwb3NzaWJsZUVycm9yTWVzc2FnZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc3RhdGUgPSBzYXZlU3RhY2sucG9wKCk7XG4gICAgICAgIGN1cnJlbnQgPSBzdGF0ZS5jdXJyZW50O1xuICAgICAgICBjdXJyZW50UG9zID0gcGFyc2VySW5wdXQuaSA9IHN0YXRlLmk7XG4gICAgICAgIGogPSBzdGF0ZS5qO1xuICAgIH07XG4gICAgcGFyc2VySW5wdXQuZm9yZ2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHNhdmVTdGFjay5wb3AoKTtcbiAgICB9O1xuICAgIHBhcnNlcklucHV0LmlzV2hpdGVzcGFjZSA9IGZ1bmN0aW9uIChvZmZzZXQpIHtcbiAgICAgICAgdmFyIHBvcyA9IHBhcnNlcklucHV0LmkgKyAob2Zmc2V0IHx8IDApLFxuICAgICAgICAgICAgY29kZSA9IGlucHV0LmNoYXJDb2RlQXQocG9zKTtcbiAgICAgICAgcmV0dXJuIChjb2RlID09PSBDSEFSQ09ERV9TUEFDRSB8fCBjb2RlID09PSBDSEFSQ09ERV9DUiB8fCBjb2RlID09PSBDSEFSQ09ERV9UQUIgfHwgY29kZSA9PT0gQ0hBUkNPREVfTEYpO1xuICAgIH07XG5cbiAgICAvLyBTcGVjaWFsaXphdGlvbiBvZiAkKHRvaylcbiAgICBwYXJzZXJJbnB1dC4kcmUgPSBmdW5jdGlvbih0b2spIHtcbiAgICAgICAgaWYgKHBhcnNlcklucHV0LmkgPiBjdXJyZW50UG9zKSB7XG4gICAgICAgICAgICBjdXJyZW50ID0gY3VycmVudC5zbGljZShwYXJzZXJJbnB1dC5pIC0gY3VycmVudFBvcyk7XG4gICAgICAgICAgICBjdXJyZW50UG9zID0gcGFyc2VySW5wdXQuaTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBtID0gdG9rLmV4ZWMoY3VycmVudCk7XG4gICAgICAgIGlmICghbSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBza2lwV2hpdGVzcGFjZShtWzBdLmxlbmd0aCk7XG4gICAgICAgIGlmICh0eXBlb2YgbSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgcmV0dXJuIG07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbS5sZW5ndGggPT09IDEgPyBtWzBdIDogbTtcbiAgICB9O1xuXG4gICAgcGFyc2VySW5wdXQuJGNoYXIgPSBmdW5jdGlvbih0b2spIHtcbiAgICAgICAgaWYgKGlucHV0LmNoYXJBdChwYXJzZXJJbnB1dC5pKSAhPT0gdG9rKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBza2lwV2hpdGVzcGFjZSgxKTtcbiAgICAgICAgcmV0dXJuIHRvaztcbiAgICB9O1xuXG4gICAgcGFyc2VySW5wdXQuJHN0ciA9IGZ1bmN0aW9uKHRvaykge1xuICAgICAgICB2YXIgdG9rTGVuZ3RoID0gdG9rLmxlbmd0aDtcblxuICAgICAgICAvLyBodHRwczovL2pzcGVyZi5jb20vc3RyaW5nLXN0YXJ0c3dpdGgvMjFcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0b2tMZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGlucHV0LmNoYXJBdChwYXJzZXJJbnB1dC5pICsgaSkgIT09IHRvay5jaGFyQXQoaSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHNraXBXaGl0ZXNwYWNlKHRva0xlbmd0aCk7XG4gICAgICAgIHJldHVybiB0b2s7XG4gICAgfTtcblxuICAgIHBhcnNlcklucHV0LiRxdW90ZWQgPSBmdW5jdGlvbigpIHtcblxuICAgICAgICB2YXIgc3RhcnRDaGFyID0gaW5wdXQuY2hhckF0KHBhcnNlcklucHV0LmkpO1xuICAgICAgICBpZiAoc3RhcnRDaGFyICE9PSBcIidcIiAmJiBzdGFydENoYXIgIT09ICdcIicpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbGVuZ3RoID0gaW5wdXQubGVuZ3RoLFxuICAgICAgICAgICAgY3VycmVudFBvc2l0aW9uID0gcGFyc2VySW5wdXQuaTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSArIGN1cnJlbnRQb3NpdGlvbiA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgbmV4dENoYXIgPSBpbnB1dC5jaGFyQXQoaSArIGN1cnJlbnRQb3NpdGlvbik7XG4gICAgICAgICAgICBzd2l0Y2gobmV4dENoYXIpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwiXFxcXFwiOlxuICAgICAgICAgICAgICAgICAgICBpKys7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJcXHJcIjpcbiAgICAgICAgICAgICAgICBjYXNlIFwiXFxuXCI6XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2Ugc3RhcnRDaGFyOlxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyID0gaW5wdXQuc3Vic3RyKGN1cnJlbnRQb3NpdGlvbiwgaSArIDEpO1xuICAgICAgICAgICAgICAgICAgICBza2lwV2hpdGVzcGFjZShpICsgMSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHI7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgcGFyc2VySW5wdXQuYXV0b0NvbW1lbnRBYnNvcmIgPSB0cnVlO1xuICAgIHBhcnNlcklucHV0LmNvbW1lbnRTdG9yZSA9IFtdO1xuICAgIHBhcnNlcklucHV0LmZpbmlzaGVkID0gZmFsc2U7XG5cbiAgICAvLyBTYW1lIGFzICQoKSwgYnV0IGRvbid0IGNoYW5nZSB0aGUgc3RhdGUgb2YgdGhlIHBhcnNlcixcbiAgICAvLyBqdXN0IHJldHVybiB0aGUgbWF0Y2guXG4gICAgcGFyc2VySW5wdXQucGVlayA9IGZ1bmN0aW9uKHRvaykge1xuICAgICAgICBpZiAodHlwZW9mIHRvayA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIC8vIGh0dHBzOi8vanNwZXJmLmNvbS9zdHJpbmctc3RhcnRzd2l0aC8yMVxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0b2subGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQuY2hhckF0KHBhcnNlcklucHV0LmkgKyBpKSAhPT0gdG9rLmNoYXJBdChpKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdG9rLnRlc3QoY3VycmVudCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gU3BlY2lhbGl6YXRpb24gb2YgcGVlaygpXG4gICAgLy8gVE9ETyByZW1vdmUgb3IgY2hhbmdlIHNvbWUgY3VycmVudENoYXIgY2FsbHMgdG8gcGVla0NoYXJcbiAgICBwYXJzZXJJbnB1dC5wZWVrQ2hhciA9IGZ1bmN0aW9uKHRvaykge1xuICAgICAgICByZXR1cm4gaW5wdXQuY2hhckF0KHBhcnNlcklucHV0LmkpID09PSB0b2s7XG4gICAgfTtcblxuICAgIHBhcnNlcklucHV0LmN1cnJlbnRDaGFyID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBpbnB1dC5jaGFyQXQocGFyc2VySW5wdXQuaSk7XG4gICAgfTtcblxuICAgIHBhcnNlcklucHV0LmdldElucHV0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBpbnB1dDtcbiAgICB9O1xuXG4gICAgcGFyc2VySW5wdXQucGVla05vdE51bWVyaWMgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGMgPSBpbnB1dC5jaGFyQ29kZUF0KHBhcnNlcklucHV0LmkpO1xuICAgICAgICAvL0lzIHRoZSBmaXJzdCBjaGFyIG9mIHRoZSBkaW1lbnNpb24gMC05LCAnLicsICcrJyBvciAnLSdcbiAgICAgICAgcmV0dXJuIChjID4gQ0hBUkNPREVfOSB8fCBjIDwgQ0hBUkNPREVfUExVUykgfHwgYyA9PT0gQ0hBUkNPREVfRk9SV0FSRF9TTEFTSCB8fCBjID09PSBDSEFSQ09ERV9DT01NQTtcbiAgICB9O1xuXG4gICAgcGFyc2VySW5wdXQuc3RhcnQgPSBmdW5jdGlvbihzdHIsIGNodW5rSW5wdXQsIGZhaWxGdW5jdGlvbikge1xuICAgICAgICBpbnB1dCA9IHN0cjtcbiAgICAgICAgcGFyc2VySW5wdXQuaSA9IGogPSBjdXJyZW50UG9zID0gZnVydGhlc3QgPSAwO1xuXG4gICAgICAgIC8vIGNodW5raW5nIGFwcGFyZW50bHkgbWFrZXMgdGhpbmdzIHF1aWNrZXIgKGJ1dCBteSB0ZXN0cyBpbmRpY2F0ZVxuICAgICAgICAvLyBpdCBtaWdodCBhY3R1YWxseSBtYWtlIHRoaW5ncyBzbG93ZXIgaW4gbm9kZSBhdCBsZWFzdClcbiAgICAgICAgLy8gYW5kIGl0IGlzIGEgbm9uLXBlcmZlY3QgcGFyc2UgLSBpdCBjYW4ndCByZWNvZ25pc2VcbiAgICAgICAgLy8gdW5xdW90ZWQgdXJscywgbWVhbmluZyBpdCBjYW4ndCBkaXN0aW5ndWlzaCBjb21tZW50c1xuICAgICAgICAvLyBtZWFuaW5nIGNvbW1lbnRzIHdpdGggcXVvdGVzIG9yIHt9KCkgaW4gdGhlbSBnZXQgJ2NvdW50ZWQnXG4gICAgICAgIC8vIGFuZCB0aGVuIGxlYWQgdG8gcGFyc2UgZXJyb3JzLlxuICAgICAgICAvLyBJbiBhZGRpdGlvbiBpZiB0aGUgY2h1bmtpbmcgY2h1bmtzIGluIHRoZSB3cm9uZyBwbGFjZSB3ZSBtaWdodFxuICAgICAgICAvLyBub3QgYmUgYWJsZSB0byBwYXJzZSBhIHBhcnNlciBzdGF0ZW1lbnQgaW4gb25lIGdvXG4gICAgICAgIC8vIHRoaXMgaXMgb2ZmaWNpYWxseSBkZXByZWNhdGVkIGJ1dCBjYW4gYmUgc3dpdGNoZWQgb24gdmlhIGFuIG9wdGlvblxuICAgICAgICAvLyBpbiB0aGUgY2FzZSBpdCBjYXVzZXMgdG9vIG11Y2ggcGVyZm9ybWFuY2UgaXNzdWVzLlxuICAgICAgICBpZiAoY2h1bmtJbnB1dCkge1xuICAgICAgICAgICAgY2h1bmtzID0gY2h1bmtlcihzdHIsIGZhaWxGdW5jdGlvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjaHVua3MgPSBbc3RyXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGN1cnJlbnQgPSBjaHVua3NbMF07XG5cbiAgICAgICAgc2tpcFdoaXRlc3BhY2UoMCk7XG4gICAgfTtcblxuICAgIHBhcnNlcklucHV0LmVuZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbWVzc2FnZSxcbiAgICAgICAgICAgIGlzRmluaXNoZWQgPSBwYXJzZXJJbnB1dC5pID49IGlucHV0Lmxlbmd0aDtcblxuICAgICAgICBpZiAocGFyc2VySW5wdXQuaSA8IGZ1cnRoZXN0KSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gZnVydGhlc3RQb3NzaWJsZUVycm9yTWVzc2FnZTtcbiAgICAgICAgICAgIHBhcnNlcklucHV0LmkgPSBmdXJ0aGVzdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaXNGaW5pc2hlZDogaXNGaW5pc2hlZCxcbiAgICAgICAgICAgIGZ1cnRoZXN0OiBwYXJzZXJJbnB1dC5pLFxuICAgICAgICAgICAgZnVydGhlc3RQb3NzaWJsZUVycm9yTWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgICAgIGZ1cnRoZXN0UmVhY2hlZEVuZDogcGFyc2VySW5wdXQuaSA+PSBpbnB1dC5sZW5ndGggLSAxLFxuICAgICAgICAgICAgZnVydGhlc3RDaGFyOiBpbnB1dFtwYXJzZXJJbnB1dC5pXVxuICAgICAgICB9O1xuICAgIH07XG5cbiAgICByZXR1cm4gcGFyc2VySW5wdXQ7XG59O1xuXG59LHtcIi4vY2h1bmtlclwiOjM2fV0sMzg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIExlc3NFcnJvciA9IHJlcXVpcmUoJy4uL2xlc3MtZXJyb3InKSxcbiAgICB0cmVlID0gcmVxdWlyZShcIi4uL3RyZWVcIiksXG4gICAgdmlzaXRvcnMgPSByZXF1aXJlKFwiLi4vdmlzaXRvcnNcIiksXG4gICAgZ2V0UGFyc2VySW5wdXQgPSByZXF1aXJlKFwiLi9wYXJzZXItaW5wdXRcIiksXG4gICAgdXRpbHMgPSByZXF1aXJlKFwiLi4vdXRpbHNcIik7XG5cbi8vXG4vLyBsZXNzLmpzIC0gcGFyc2VyXG4vL1xuLy8gICAgQSByZWxhdGl2ZWx5IHN0cmFpZ2h0LWZvcndhcmQgcHJlZGljdGl2ZSBwYXJzZXIuXG4vLyAgICBUaGVyZSBpcyBubyB0b2tlbml6YXRpb24vbGV4aW5nIHN0YWdlLCB0aGUgaW5wdXQgaXMgcGFyc2VkXG4vLyAgICBpbiBvbmUgc3dlZXAuXG4vL1xuLy8gICAgVG8gbWFrZSB0aGUgcGFyc2VyIGZhc3QgZW5vdWdoIHRvIHJ1biBpbiB0aGUgYnJvd3Nlciwgc2V2ZXJhbFxuLy8gICAgb3B0aW1pemF0aW9uIGhhZCB0byBiZSBtYWRlOlxuLy9cbi8vICAgIC0gTWF0Y2hpbmcgYW5kIHNsaWNpbmcgb24gYSBodWdlIGlucHV0IGlzIG9mdGVuIGNhdXNlIG9mIHNsb3dkb3ducy5cbi8vICAgICAgVGhlIHNvbHV0aW9uIGlzIHRvIGNodW5raWZ5IHRoZSBpbnB1dCBpbnRvIHNtYWxsZXIgc3RyaW5ncy5cbi8vICAgICAgVGhlIGNodW5rcyBhcmUgc3RvcmVkIGluIHRoZSBgY2h1bmtzYCB2YXIsXG4vLyAgICAgIGBqYCBob2xkcyB0aGUgY3VycmVudCBjaHVuayBpbmRleCwgYW5kIGBjdXJyZW50UG9zYCBob2xkc1xuLy8gICAgICB0aGUgaW5kZXggb2YgdGhlIGN1cnJlbnQgY2h1bmsgaW4gcmVsYXRpb24gdG8gYGlucHV0YC5cbi8vICAgICAgVGhpcyBnaXZlcyB1cyBhbiBhbG1vc3QgNHggc3BlZWQtdXAuXG4vL1xuLy8gICAgLSBJbiBtYW55IGNhc2VzLCB3ZSBkb24ndCBuZWVkIHRvIG1hdGNoIGluZGl2aWR1YWwgdG9rZW5zO1xuLy8gICAgICBmb3IgZXhhbXBsZSwgaWYgYSB2YWx1ZSBkb2Vzbid0IGhvbGQgYW55IHZhcmlhYmxlcywgb3BlcmF0aW9uc1xuLy8gICAgICBvciBkeW5hbWljIHJlZmVyZW5jZXMsIHRoZSBwYXJzZXIgY2FuIGVmZmVjdGl2ZWx5ICdza2lwJyBpdCxcbi8vICAgICAgdHJlYXRpbmcgaXQgYXMgYSBsaXRlcmFsLlxuLy8gICAgICBBbiBleGFtcGxlIHdvdWxkIGJlICcxcHggc29saWQgIzAwMCcgLSB3aGljaCBldmFsdWF0ZXMgdG8gaXRzZWxmLFxuLy8gICAgICB3ZSBkb24ndCBuZWVkIHRvIGtub3cgd2hhdCB0aGUgaW5kaXZpZHVhbCBjb21wb25lbnRzIGFyZS5cbi8vICAgICAgVGhlIGRyYXdiYWNrLCBvZiBjb3Vyc2UgaXMgdGhhdCB5b3UgZG9uJ3QgZ2V0IHRoZSBiZW5lZml0cyBvZlxuLy8gICAgICBzeW50YXgtY2hlY2tpbmcgb24gdGhlIENTUy4gVGhpcyBnaXZlcyB1cyBhIDUwJSBzcGVlZC11cCBpbiB0aGUgcGFyc2VyLFxuLy8gICAgICBhbmQgYSBzbWFsbGVyIHNwZWVkLXVwIGluIHRoZSBjb2RlLWdlbi5cbi8vXG4vL1xuLy8gICAgVG9rZW4gbWF0Y2hpbmcgaXMgZG9uZSB3aXRoIHRoZSBgJGAgZnVuY3Rpb24sIHdoaWNoIGVpdGhlciB0YWtlc1xuLy8gICAgYSB0ZXJtaW5hbCBzdHJpbmcgb3IgcmVnZXhwLCBvciBhIG5vbi10ZXJtaW5hbCBmdW5jdGlvbiB0byBjYWxsLlxuLy8gICAgSXQgYWxzbyB0YWtlcyBjYXJlIG9mIG1vdmluZyBhbGwgdGhlIGluZGljZXMgZm9yd2FyZHMuXG4vL2Bcbi8vXG52YXIgUGFyc2VyID0gZnVuY3Rpb24gUGFyc2VyKGNvbnRleHQsIGltcG9ydHMsIGZpbGVJbmZvKSB7XG4gICAgdmFyIHBhcnNlcnMsXG4gICAgICAgIHBhcnNlcklucHV0ID0gZ2V0UGFyc2VySW5wdXQoKTtcblxuICAgIGZ1bmN0aW9uIGVycm9yKG1zZywgdHlwZSkge1xuICAgICAgICB0aHJvdyBuZXcgTGVzc0Vycm9yKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGluZGV4OiBwYXJzZXJJbnB1dC5pLFxuICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBmaWxlSW5mby5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICB0eXBlOiB0eXBlIHx8ICdTeW50YXgnLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG1zZ1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGltcG9ydHNcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBleHBlY3QoYXJnLCBtc2csIGluZGV4KSB7XG4gICAgICAgIC8vIHNvbWUgb2xkZXIgYnJvd3NlcnMgcmV0dXJuIHR5cGVvZiAnZnVuY3Rpb24nIGZvciBSZWdFeHBcbiAgICAgICAgdmFyIHJlc3VsdCA9IChhcmcgaW5zdGFuY2VvZiBGdW5jdGlvbikgPyBhcmcuY2FsbChwYXJzZXJzKSA6IHBhcnNlcklucHV0LiRyZShhcmcpO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGVycm9yKG1zZyB8fCAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgPyBcImV4cGVjdGVkICdcIiArIGFyZyArIFwiJyBnb3QgJ1wiICsgcGFyc2VySW5wdXQuY3VycmVudENoYXIoKSArIFwiJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogXCJ1bmV4cGVjdGVkIHRva2VuXCIpKTtcbiAgICB9XG5cbiAgICAvLyBTcGVjaWFsaXphdGlvbiBvZiBleHBlY3QoKVxuICAgIGZ1bmN0aW9uIGV4cGVjdENoYXIoYXJnLCBtc2cpIHtcbiAgICAgICAgaWYgKHBhcnNlcklucHV0LiRjaGFyKGFyZykpIHtcbiAgICAgICAgICAgIHJldHVybiBhcmc7XG4gICAgICAgIH1cbiAgICAgICAgZXJyb3IobXNnIHx8IFwiZXhwZWN0ZWQgJ1wiICsgYXJnICsgXCInIGdvdCAnXCIgKyBwYXJzZXJJbnB1dC5jdXJyZW50Q2hhcigpICsgXCInXCIpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldERlYnVnSW5mbyhpbmRleCkge1xuICAgICAgICB2YXIgZmlsZW5hbWUgPSBmaWxlSW5mby5maWxlbmFtZTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbGluZU51bWJlcjogdXRpbHMuZ2V0TG9jYXRpb24oaW5kZXgsIHBhcnNlcklucHV0LmdldElucHV0KCkpLmxpbmUgKyAxLFxuICAgICAgICAgICAgZmlsZU5hbWU6IGZpbGVuYW1lXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy9cbiAgICAvLyBUaGUgUGFyc2VyXG4gICAgLy9cbiAgICByZXR1cm4ge1xuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFBhcnNlIGFuIGlucHV0IHN0cmluZyBpbnRvIGFuIGFic3RyYWN0IHN5bnRheCB0cmVlLFxuICAgICAgICAvLyBAcGFyYW0gc3RyIEEgc3RyaW5nIGNvbnRhaW5pbmcgJ2xlc3MnIG1hcmt1cFxuICAgICAgICAvLyBAcGFyYW0gY2FsbGJhY2sgY2FsbCBgY2FsbGJhY2tgIHdoZW4gZG9uZS5cbiAgICAgICAgLy8gQHBhcmFtIFthZGRpdGlvbmFsRGF0YV0gQW4gb3B0aW9uYWwgbWFwIHdoaWNoIGNhbiBjb250YWlucyB2YXJzIC0gYSBtYXAgKGtleSwgdmFsdWUpIG9mIHZhcmlhYmxlcyB0byBhcHBseVxuICAgICAgICAvL1xuICAgICAgICBwYXJzZTogZnVuY3Rpb24gKHN0ciwgY2FsbGJhY2ssIGFkZGl0aW9uYWxEYXRhKSB7XG4gICAgICAgICAgICB2YXIgcm9vdCwgZXJyb3IgPSBudWxsLCBnbG9iYWxWYXJzLCBtb2RpZnlWYXJzLCBpZ25vcmVkLCBwcmVUZXh0ID0gXCJcIjtcblxuICAgICAgICAgICAgZ2xvYmFsVmFycyA9IChhZGRpdGlvbmFsRGF0YSAmJiBhZGRpdGlvbmFsRGF0YS5nbG9iYWxWYXJzKSA/IFBhcnNlci5zZXJpYWxpemVWYXJzKGFkZGl0aW9uYWxEYXRhLmdsb2JhbFZhcnMpICsgJ1xcbicgOiAnJztcbiAgICAgICAgICAgIG1vZGlmeVZhcnMgPSAoYWRkaXRpb25hbERhdGEgJiYgYWRkaXRpb25hbERhdGEubW9kaWZ5VmFycykgPyAnXFxuJyArIFBhcnNlci5zZXJpYWxpemVWYXJzKGFkZGl0aW9uYWxEYXRhLm1vZGlmeVZhcnMpIDogJyc7XG5cbiAgICAgICAgICAgIGlmIChjb250ZXh0LnBsdWdpbk1hbmFnZXIpIHtcbiAgICAgICAgICAgICAgICB2YXIgcHJlUHJvY2Vzc29ycyA9IGNvbnRleHQucGx1Z2luTWFuYWdlci5nZXRQcmVQcm9jZXNzb3JzKCk7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcmVQcm9jZXNzb3JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0ciA9IHByZVByb2Nlc3NvcnNbaV0ucHJvY2VzcyhzdHIsIHsgY29udGV4dDogY29udGV4dCwgaW1wb3J0czogaW1wb3J0cywgZmlsZUluZm86IGZpbGVJbmZvIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGdsb2JhbFZhcnMgfHwgKGFkZGl0aW9uYWxEYXRhICYmIGFkZGl0aW9uYWxEYXRhLmJhbm5lcikpIHtcbiAgICAgICAgICAgICAgICBwcmVUZXh0ID0gKChhZGRpdGlvbmFsRGF0YSAmJiBhZGRpdGlvbmFsRGF0YS5iYW5uZXIpID8gYWRkaXRpb25hbERhdGEuYmFubmVyIDogXCJcIikgKyBnbG9iYWxWYXJzO1xuICAgICAgICAgICAgICAgIGlnbm9yZWQgPSBpbXBvcnRzLmNvbnRlbnRzSWdub3JlZENoYXJzO1xuICAgICAgICAgICAgICAgIGlnbm9yZWRbZmlsZUluZm8uZmlsZW5hbWVdID0gaWdub3JlZFtmaWxlSW5mby5maWxlbmFtZV0gfHwgMDtcbiAgICAgICAgICAgICAgICBpZ25vcmVkW2ZpbGVJbmZvLmZpbGVuYW1lXSArPSBwcmVUZXh0Lmxlbmd0aDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoL1xcclxcbj8vZywgJ1xcbicpO1xuICAgICAgICAgICAgLy8gUmVtb3ZlIHBvdGVudGlhbCBVVEYgQnl0ZSBPcmRlciBNYXJrXG4gICAgICAgICAgICBzdHIgPSBwcmVUZXh0ICsgc3RyLnJlcGxhY2UoL15cXHVGRUZGLywgJycpICsgbW9kaWZ5VmFycztcbiAgICAgICAgICAgIGltcG9ydHMuY29udGVudHNbZmlsZUluZm8uZmlsZW5hbWVdID0gc3RyO1xuXG4gICAgICAgICAgICAvLyBTdGFydCB3aXRoIHRoZSBwcmltYXJ5IHJ1bGUuXG4gICAgICAgICAgICAvLyBUaGUgd2hvbGUgc3ludGF4IHRyZWUgaXMgaGVsZCB1bmRlciBhIFJ1bGVzZXQgbm9kZSxcbiAgICAgICAgICAgIC8vIHdpdGggdGhlIGByb290YCBwcm9wZXJ0eSBzZXQgdG8gdHJ1ZSwgc28gbm8gYHt9YCBhcmVcbiAgICAgICAgICAgIC8vIG91dHB1dC4gVGhlIGNhbGxiYWNrIGlzIGNhbGxlZCB3aGVuIHRoZSBpbnB1dCBpcyBwYXJzZWQuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LnN0YXJ0KHN0ciwgY29udGV4dC5jaHVua0lucHV0LCBmdW5jdGlvbiBmYWlsKG1zZywgaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IExlc3NFcnJvcih7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleDogaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnUGFyc2UnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogbXNnLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWU6IGZpbGVJbmZvLmZpbGVuYW1lXG4gICAgICAgICAgICAgICAgICAgIH0sIGltcG9ydHMpO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgcm9vdCA9IG5ldyh0cmVlLlJ1bGVzZXQpKG51bGwsIHRoaXMucGFyc2Vycy5wcmltYXJ5KCkpO1xuICAgICAgICAgICAgICAgIHJvb3Qucm9vdCA9IHRydWU7XG4gICAgICAgICAgICAgICAgcm9vdC5maXJzdFJvb3QgPSB0cnVlO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgTGVzc0Vycm9yKGUsIGltcG9ydHMsIGZpbGVJbmZvLmZpbGVuYW1lKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIGBpYCBpcyBzbWFsbGVyIHRoYW4gdGhlIGBpbnB1dC5sZW5ndGggLSAxYCxcbiAgICAgICAgICAgIC8vIGl0IG1lYW5zIHRoZSBwYXJzZXIgd2Fzbid0IGFibGUgdG8gcGFyc2UgdGhlIHdob2xlXG4gICAgICAgICAgICAvLyBzdHJpbmcsIHNvIHdlJ3ZlIGdvdCBhIHBhcnNpbmcgZXJyb3IuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gV2UgdHJ5IHRvIGV4dHJhY3QgYSBcXG4gZGVsaW1pdGVkIHN0cmluZyxcbiAgICAgICAgICAgIC8vIHNob3dpbmcgdGhlIGxpbmUgd2hlcmUgdGhlIHBhcnNlIGVycm9yIG9jY3VycmVkLlxuICAgICAgICAgICAgLy8gV2Ugc3BsaXQgaXQgdXAgaW50byB0d28gcGFydHMgKHRoZSBwYXJ0IHdoaWNoIHBhcnNlZCxcbiAgICAgICAgICAgIC8vIGFuZCB0aGUgcGFydCB3aGljaCBkaWRuJ3QpLCBzbyB3ZSBjYW4gY29sb3IgdGhlbSBkaWZmZXJlbnRseS5cbiAgICAgICAgICAgIHZhciBlbmRJbmZvID0gcGFyc2VySW5wdXQuZW5kKCk7XG4gICAgICAgICAgICBpZiAoIWVuZEluZm8uaXNGaW5pc2hlZCkge1xuXG4gICAgICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBlbmRJbmZvLmZ1cnRoZXN0UG9zc2libGVFcnJvck1lc3NhZ2U7XG5cbiAgICAgICAgICAgICAgICBpZiAoIW1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IFwiVW5yZWNvZ25pc2VkIGlucHV0XCI7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlbmRJbmZvLmZ1cnRoZXN0Q2hhciA9PT0gJ30nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlICs9IFwiLiBQb3NzaWJseSBtaXNzaW5nIG9wZW5pbmcgJ3snXCI7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZW5kSW5mby5mdXJ0aGVzdENoYXIgPT09ICcpJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSArPSBcIi4gUG9zc2libHkgbWlzc2luZyBvcGVuaW5nICcoJ1wiO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVuZEluZm8uZnVydGhlc3RSZWFjaGVkRW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlICs9IFwiLiBQb3NzaWJseSBtaXNzaW5nIHNvbWV0aGluZ1wiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcgTGVzc0Vycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJQYXJzZVwiLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICBpbmRleDogZW5kSW5mby5mdXJ0aGVzdCxcbiAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWU6IGZpbGVJbmZvLmZpbGVuYW1lXG4gICAgICAgICAgICAgICAgfSwgaW1wb3J0cyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBmaW5pc2ggPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIGUgPSBlcnJvciB8fCBlIHx8IGltcG9ydHMuZXJyb3I7XG5cbiAgICAgICAgICAgICAgICBpZiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIShlIGluc3RhbmNlb2YgTGVzc0Vycm9yKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZSA9IG5ldyBMZXNzRXJyb3IoZSwgaW1wb3J0cywgZmlsZUluZm8uZmlsZW5hbWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHJvb3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmIChjb250ZXh0LnByb2Nlc3NJbXBvcnRzICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIG5ldyB2aXNpdG9ycy5JbXBvcnRWaXNpdG9yKGltcG9ydHMsIGZpbmlzaClcbiAgICAgICAgICAgICAgICAgICAgLnJ1bihyb290KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZpbmlzaCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEhlcmUgaW4sIHRoZSBwYXJzaW5nIHJ1bGVzL2Z1bmN0aW9uc1xuICAgICAgICAvL1xuICAgICAgICAvLyBUaGUgYmFzaWMgc3RydWN0dXJlIG9mIHRoZSBzeW50YXggdHJlZSBnZW5lcmF0ZWQgaXMgYXMgZm9sbG93czpcbiAgICAgICAgLy9cbiAgICAgICAgLy8gICBSdWxlc2V0IC0+ICBSdWxlIC0+IFZhbHVlIC0+IEV4cHJlc3Npb24gLT4gRW50aXR5XG4gICAgICAgIC8vXG4gICAgICAgIC8vIEhlcmUncyBzb21lIExlc3MgY29kZTpcbiAgICAgICAgLy9cbiAgICAgICAgLy8gICAgLmNsYXNzIHtcbiAgICAgICAgLy8gICAgICBjb2xvcjogI2ZmZjtcbiAgICAgICAgLy8gICAgICBib3JkZXI6IDFweCBzb2xpZCAjMDAwO1xuICAgICAgICAvLyAgICAgIHdpZHRoOiBAdyArIDRweDtcbiAgICAgICAgLy8gICAgICA+IC5jaGlsZCB7Li4ufVxuICAgICAgICAvLyAgICB9XG4gICAgICAgIC8vXG4gICAgICAgIC8vIEFuZCBoZXJlJ3Mgd2hhdCB0aGUgcGFyc2UgdHJlZSBtaWdodCBsb29rIGxpa2U6XG4gICAgICAgIC8vXG4gICAgICAgIC8vICAgICBSdWxlc2V0IChTZWxlY3RvciAnLmNsYXNzJywgW1xuICAgICAgICAvLyAgICAgICAgIFJ1bGUgKFwiY29sb3JcIiwgIFZhbHVlIChbRXhwcmVzc2lvbiBbQ29sb3IgI2ZmZl1dKSlcbiAgICAgICAgLy8gICAgICAgICBSdWxlIChcImJvcmRlclwiLCBWYWx1ZSAoW0V4cHJlc3Npb24gW0RpbWVuc2lvbiAxcHhdW0tleXdvcmQgXCJzb2xpZFwiXVtDb2xvciAjMDAwXV0pKVxuICAgICAgICAvLyAgICAgICAgIFJ1bGUgKFwid2lkdGhcIiwgIFZhbHVlIChbRXhwcmVzc2lvbiBbT3BlcmF0aW9uIFwiICsgXCIgW1ZhcmlhYmxlIFwiQHdcIl1bRGltZW5zaW9uIDRweF1dXSkpXG4gICAgICAgIC8vICAgICAgICAgUnVsZXNldCAoU2VsZWN0b3IgW0VsZW1lbnQgJz4nLCAnLmNoaWxkJ10sIFsuLi5dKVxuICAgICAgICAvLyAgICAgXSlcbiAgICAgICAgLy9cbiAgICAgICAgLy8gIEluIGdlbmVyYWwsIG1vc3QgcnVsZXMgd2lsbCB0cnkgdG8gcGFyc2UgYSB0b2tlbiB3aXRoIHRoZSBgJHJlKClgIGZ1bmN0aW9uLCBhbmQgaWYgdGhlIHJldHVyblxuICAgICAgICAvLyAgdmFsdWUgaXMgdHJ1bHksIHdpbGwgcmV0dXJuIGEgbmV3IG5vZGUsIG9mIHRoZSByZWxldmFudCB0eXBlLiBTb21ldGltZXMsIHdlIG5lZWQgdG8gY2hlY2tcbiAgICAgICAgLy8gIGZpcnN0LCBiZWZvcmUgcGFyc2luZywgdGhhdCdzIHdoZW4gd2UgdXNlIGBwZWVrKClgLlxuICAgICAgICAvL1xuICAgICAgICBwYXJzZXJzOiBwYXJzZXJzID0ge1xuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIFRoZSBgcHJpbWFyeWAgcnVsZSBpcyB0aGUgKmVudHJ5KiBhbmQgKmV4aXQqIHBvaW50IG9mIHRoZSBwYXJzZXIuXG4gICAgICAgICAgICAvLyBUaGUgcnVsZXMgaGVyZSBjYW4gYXBwZWFyIGF0IGFueSBsZXZlbCBvZiB0aGUgcGFyc2UgdHJlZS5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBUaGUgcmVjdXJzaXZlIG5hdHVyZSBvZiB0aGUgZ3JhbW1hciBpcyBhbiBpbnRlcnBsYXkgYmV0d2VlbiB0aGUgYGJsb2NrYFxuICAgICAgICAgICAgLy8gcnVsZSwgd2hpY2ggcmVwcmVzZW50cyBgeyAuLi4gfWAsIHRoZSBgcnVsZXNldGAgcnVsZSwgYW5kIHRoaXMgYHByaW1hcnlgIHJ1bGUsXG4gICAgICAgICAgICAvLyBhcyByZXByZXNlbnRlZCBieSB0aGlzIHNpbXBsaWZpZWQgZ3JhbW1hcjpcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyAgICAgcHJpbWFyeSAg4oaSICAocnVsZXNldCB8IHJ1bGUpK1xuICAgICAgICAgICAgLy8gICAgIHJ1bGVzZXQgIOKGkiAgc2VsZWN0b3IrIGJsb2NrXG4gICAgICAgICAgICAvLyAgICAgYmxvY2sgICAg4oaSICAneycgcHJpbWFyeSAnfSdcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBPbmx5IGF0IG9uZSBwb2ludCBpcyB0aGUgcHJpbWFyeSBydWxlIG5vdCBjYWxsZWQgZnJvbSB0aGVcbiAgICAgICAgICAgIC8vIGJsb2NrIHJ1bGU6IGF0IHRoZSByb290IGxldmVsLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIHByaW1hcnk6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgbWl4aW4gPSB0aGlzLm1peGluLCByb290ID0gW10sIG5vZGU7XG5cbiAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IHRoaXMuY29tbWVudCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFub2RlKSB7IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICAgICAgICByb290LnB1c2gobm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gYWx3YXlzIHByb2Nlc3MgY29tbWVudHMgYmVmb3JlIGRlY2lkaW5nIGlmIGZpbmlzaGVkXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC5maW5pc2hlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LnBlZWsoJ30nKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBub2RlID0gdGhpcy5leHRlbmRSdWxlKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByb290ID0gcm9vdC5jb25jYXQobm9kZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIG5vZGUgPSBtaXhpbi5kZWZpbml0aW9uKCkgfHwgdGhpcy5ydWxlKCkgfHwgdGhpcy5ydWxlc2V0KCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1peGluLmNhbGwoKSB8fCB0aGlzLnJ1bGVzZXRDYWxsKCkgfHwgdGhpcy5lbnRpdGllcy5jYWxsKCkgfHwgdGhpcy5kaXJlY3RpdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJvb3QucHVzaChub2RlKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmb3VuZFNlbWlDb2xvbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHBhcnNlcklucHV0LiRjaGFyKFwiO1wiKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kU2VtaUNvbG9uID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZm91bmRTZW1pQ29sb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiByb290O1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLy8gY29tbWVudHMgYXJlIGNvbGxlY3RlZCBieSB0aGUgbWFpbiBwYXJzaW5nIG1lY2hhbmlzbSBhbmQgdGhlbiBhc3NpZ25lZCB0byBub2Rlc1xuICAgICAgICAgICAgLy8gd2hlcmUgdGhlIGN1cnJlbnQgc3RydWN0dXJlIGFsbG93cyBpdFxuICAgICAgICAgICAgY29tbWVudDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC5jb21tZW50U3RvcmUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjb21tZW50ID0gcGFyc2VySW5wdXQuY29tbWVudFN0b3JlLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcodHJlZS5Db21tZW50KShjb21tZW50LnRleHQsIGNvbW1lbnQuaXNMaW5lQ29tbWVudCwgY29tbWVudC5pbmRleCwgZmlsZUluZm8pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBFbnRpdGllcyBhcmUgdG9rZW5zIHdoaWNoIGNhbiBiZSBmb3VuZCBpbnNpZGUgYW4gRXhwcmVzc2lvblxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIGVudGl0aWVzOiB7XG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyBBIHN0cmluZywgd2hpY2ggc3VwcG9ydHMgZXNjYXBpbmcgXCIgYW5kICdcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vICAgICBcIm1pbGt5IHdheVwiICdoZVxcJ3MgdGhlIG9uZSEnXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICBxdW90ZWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ciwgaW5kZXggPSBwYXJzZXJJbnB1dC5pLCBpc0VzY2FwZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5zYXZlKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC4kY2hhcihcIn5cIikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzRXNjYXBlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgc3RyID0gcGFyc2VySW5wdXQuJHF1b3RlZCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXN0cikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQucmVzdG9yZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LmZvcmdldCgpO1xuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcodHJlZS5RdW90ZWQpKHN0ci5jaGFyQXQoMCksIHN0ci5zdWJzdHIoMSwgc3RyLmxlbmd0aCAtIDIpLCBpc0VzY2FwZWQsIGluZGV4LCBmaWxlSW5mbyk7XG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gQSBjYXRjaC1hbGwgd29yZCwgc3VjaCBhczpcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vICAgICBibGFjayBib3JkZXItY29sbGFwc2VcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIGtleXdvcmQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGsgPSBwYXJzZXJJbnB1dC4kY2hhcihcIiVcIikgfHwgcGFyc2VySW5wdXQuJHJlKC9eW19BLVphLXotXVtfQS1aYS16MC05LV0qLyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJlZS5Db2xvci5mcm9tS2V5d29yZChrKSB8fCBuZXcodHJlZS5LZXl3b3JkKShrKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIEEgZnVuY3Rpb24gY2FsbFxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gICAgIHJnYigyNTUsIDAsIDI1NSlcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIFdlIGFsc28gdHJ5IHRvIGNhdGNoIElFJ3MgYGFscGhhKClgLCBidXQgbGV0IHRoZSBgYWxwaGFgIHBhcnNlclxuICAgICAgICAgICAgICAgIC8vIGRlYWwgd2l0aCB0aGUgZGV0YWlscy5cbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIFRoZSBhcmd1bWVudHMgYXJlIHBhcnNlZCB3aXRoIHRoZSBgZW50aXRpZXMuYXJndW1lbnRzYCBwYXJzZXIuXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICBjYWxsOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBuYW1lLCBuYW1lTEMsIGFyZ3MsIGFscGhhLCBpbmRleCA9IHBhcnNlcklucHV0Lmk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gaHR0cDovL2pzcGVyZi5jb20vY2FzZS1pbnNlbnNpdGl2ZS1yZWdleC12cy1zdHJ0b2xvd2VyLXRoZW4tcmVnZXgvMThcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LnBlZWsoL151cmxcXCgvaSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LnNhdmUoKTtcblxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gcGFyc2VySW5wdXQuJHJlKC9eKFtcXHctXSt8JXxwcm9naWQ6W1xcd1xcLl0rKVxcKC8pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIW5hbWUpIHsgcGFyc2VySW5wdXQuZm9yZ2V0KCk7IHJldHVybjsgfVxuXG4gICAgICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lWzFdO1xuICAgICAgICAgICAgICAgICAgICBuYW1lTEMgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVMQyA9PT0gJ2FscGhhJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYWxwaGEgPSBwYXJzZXJzLmFscGhhKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWxwaGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5mb3JnZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWxwaGE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBhcmdzID0gdGhpcy5hcmd1bWVudHMoKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoISBwYXJzZXJJbnB1dC4kY2hhcignKScpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5yZXN0b3JlKFwiQ291bGQgbm90IHBhcnNlIGNhbGwgYXJndW1lbnRzIG9yIG1pc3NpbmcgJyknXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuZm9yZ2V0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcodHJlZS5DYWxsKShuYW1lLCBhcmdzLCBpbmRleCwgZmlsZUluZm8pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYXJndW1lbnRzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhcmdzU2VtaUNvbG9uID0gW10sIGFyZ3NDb21tYSA9IFtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbnMgPSBbXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzU2VtaUNvbG9uU2VwYXJhdGVkLCB2YWx1ZSwgYXJnO1xuXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LnNhdmUoKTtcblxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmcgPSBwYXJzZXJzLmRldGFjaGVkUnVsZXNldCgpIHx8IHRoaXMuYXNzaWdubWVudCgpIHx8IHBhcnNlcnMuZXhwcmVzc2lvbigpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFyZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGFyZztcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZy52YWx1ZSAmJiBhcmcudmFsdWUubGVuZ3RoID09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGFyZy52YWx1ZVswXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbnMucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NDb21tYS5wdXNoKHZhbHVlKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LiRjaGFyKCcsJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LiRjaGFyKCc7JykgfHwgaXNTZW1pQ29sb25TZXBhcmF0ZWQpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzU2VtaUNvbG9uU2VwYXJhdGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChleHByZXNzaW9ucy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbmV3KHRyZWUuVmFsdWUpKGV4cHJlc3Npb25zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1NlbWlDb2xvbi5wdXNoKHZhbHVlKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb25zID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5mb3JnZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlzU2VtaUNvbG9uU2VwYXJhdGVkID8gYXJnc1NlbWlDb2xvbiA6IGFyZ3NDb21tYTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxpdGVyYWw6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGltZW5zaW9uKCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29sb3IoKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5xdW90ZWQoKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51bmljb2RlRGVzY3JpcHRvcigpO1xuICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICAvLyBBc3NpZ25tZW50cyBhcmUgYXJndW1lbnQgZW50aXRpZXMgZm9yIGNhbGxzLlxuICAgICAgICAgICAgICAgIC8vIFRoZXkgYXJlIHByZXNlbnQgaW4gaWUgZmlsdGVyIHByb3BlcnRpZXMgYXMgc2hvd24gYmVsb3cuXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyAgICAgZmlsdGVyOiBwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuQWxwaGEoICpvcGFjaXR5PTUwKiApXG4gICAgICAgICAgICAgICAgLy9cblxuICAgICAgICAgICAgICAgIGFzc2lnbm1lbnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGtleSwgdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LnNhdmUoKTtcbiAgICAgICAgICAgICAgICAgICAga2V5ID0gcGFyc2VySW5wdXQuJHJlKC9eXFx3Kyg/PVxccz89KS9pKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LnJlc3RvcmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIXBhcnNlcklucHV0LiRjaGFyKCc9JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LnJlc3RvcmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhcnNlcnMuZW50aXR5KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuZm9yZ2V0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3KHRyZWUuQXNzaWdubWVudCkoa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5yZXN0b3JlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyBQYXJzZSB1cmwoKSB0b2tlbnNcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIFdlIHVzZSBhIHNwZWNpZmljIHJ1bGUgZm9yIHVybHMsIGJlY2F1c2UgdGhleSBkb24ndCByZWFsbHkgYmVoYXZlIGxpa2VcbiAgICAgICAgICAgICAgICAvLyBzdGFuZGFyZCBmdW5jdGlvbiBjYWxscy4gVGhlIGRpZmZlcmVuY2UgaXMgdGhhdCB0aGUgYXJndW1lbnQgZG9lc24ndCBoYXZlXG4gICAgICAgICAgICAgICAgLy8gdG8gYmUgZW5jbG9zZWQgd2l0aGluIGEgc3RyaW5nLCBzbyBpdCBjYW4ndCBiZSBwYXJzZWQgYXMgYW4gRXhwcmVzc2lvbi5cbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIHVybDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWUsIGluZGV4ID0gcGFyc2VySW5wdXQuaTtcblxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5hdXRvQ29tbWVudEFic29yYiA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICghcGFyc2VySW5wdXQuJHN0cihcInVybChcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LmF1dG9Db21tZW50QWJzb3JiID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5xdW90ZWQoKSB8fCB0aGlzLnZhcmlhYmxlKCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC4kcmUoL14oPzooPzpcXFxcW1xcKFxcKSdcIl0pfFteXFwoXFwpJ1wiXSkrLykgfHwgXCJcIjtcblxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5hdXRvQ29tbWVudEFic29yYiA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0Q2hhcignKScpO1xuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcodHJlZS5VUkwpKCh2YWx1ZS52YWx1ZSAhPSBudWxsIHx8IHZhbHVlIGluc3RhbmNlb2YgdHJlZS5WYXJpYWJsZSkgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIDogbmV3KHRyZWUuQW5vbnltb3VzKSh2YWx1ZSksIGluZGV4LCBmaWxlSW5mbyk7XG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gQSBWYXJpYWJsZSBlbnRpdHksIHN1Y2ggYXMgYEBmaW5rYCwgaW5cbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vICAgICB3aWR0aDogQGZpbmsgKyAycHhcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIFdlIHVzZSBhIGRpZmZlcmVudCBwYXJzZXIgZm9yIHZhcmlhYmxlIGRlZmluaXRpb25zLFxuICAgICAgICAgICAgICAgIC8vIHNlZSBgcGFyc2Vycy52YXJpYWJsZWAuXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICB2YXJpYWJsZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZSwgaW5kZXggPSBwYXJzZXJJbnB1dC5pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC5jdXJyZW50Q2hhcigpID09PSAnQCcgJiYgKG5hbWUgPSBwYXJzZXJJbnB1dC4kcmUoL15AQD9bXFx3LV0rLykpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3KHRyZWUuVmFyaWFibGUpKG5hbWUsIGluZGV4LCBmaWxlSW5mbyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgLy8gQSB2YXJpYWJsZSBlbnRpdHkgdXNpbmcgdGhlIHByb3RlY3RpdmUge30gZS5nLiBAe3Zhcn1cbiAgICAgICAgICAgICAgICB2YXJpYWJsZUN1cmx5OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJseSwgaW5kZXggPSBwYXJzZXJJbnB1dC5pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC5jdXJyZW50Q2hhcigpID09PSAnQCcgJiYgKGN1cmx5ID0gcGFyc2VySW5wdXQuJHJlKC9eQFxceyhbXFx3LV0rKVxcfS8pKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyh0cmVlLlZhcmlhYmxlKShcIkBcIiArIGN1cmx5WzFdLCBpbmRleCwgZmlsZUluZm8pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gQSBIZXhhZGVjaW1hbCBjb2xvclxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gICAgICM0RjNDMkZcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIGByZ2JgIGFuZCBgaHNsYCBjb2xvcnMgYXJlIHBhcnNlZCB0aHJvdWdoIHRoZSBgZW50aXRpZXMuY2FsbGAgcGFyc2VyLlxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgY29sb3I6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJnYjtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocGFyc2VySW5wdXQuY3VycmVudENoYXIoKSA9PT0gJyMnICYmIChyZ2IgPSBwYXJzZXJJbnB1dC4kcmUoL14jKFtBLUZhLWYwLTldezZ9fFtBLUZhLWYwLTldezN9KS8pKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RyaXAgY29sb25zLCBicmFja2V0cywgd2hpdGVzcGFjZXMgYW5kIG90aGVyIGNoYXJhY3RlcnMgdGhhdCBzaG91bGQgbm90XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWZpbml0ZWx5IGJlIHBhcnQgb2YgY29sb3Igc3RyaW5nXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29sb3JDYW5kaWRhdGVTdHJpbmcgPSByZ2IuaW5wdXQubWF0Y2goL14jKFtcXHddKykuKi8pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29sb3JDYW5kaWRhdGVTdHJpbmcgPSBjb2xvckNhbmRpZGF0ZVN0cmluZ1sxXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY29sb3JDYW5kaWRhdGVTdHJpbmcubWF0Y2goL15bQS1GYS1mMC05XSskLykpIHsgLy8gdmVyaWZ5IGlmIGNhbmRpZGF0ZSBjb25zaXN0cyBvbmx5IG9mIGFsbG93ZWQgSEVYIGNoYXJhY3RlcnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcihcIkludmFsaWQgSEVYIGNvbG9yIGNvZGVcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3KHRyZWUuQ29sb3IpKHJnYlsxXSwgdW5kZWZpbmVkLCAnIycgKyBjb2xvckNhbmRpZGF0ZVN0cmluZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgY29sb3JLZXl3b3JkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LnNhdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGF1dG9Db21tZW50QWJzb3JiID0gcGFyc2VySW5wdXQuYXV0b0NvbW1lbnRBYnNvcmI7XG4gICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LmF1dG9Db21tZW50QWJzb3JiID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHZhciBrID0gcGFyc2VySW5wdXQuJHJlKC9eW19BLVphLXotXVtfQS1aYS16MC05LV0rLyk7XG4gICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LmF1dG9Db21tZW50QWJzb3JiID0gYXV0b0NvbW1lbnRBYnNvcmI7XG4gICAgICAgICAgICAgICAgICAgIGlmICghaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuZm9yZ2V0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQucmVzdG9yZSgpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgY29sb3IgPSB0cmVlLkNvbG9yLmZyb21LZXl3b3JkKGspO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29sb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LiRzdHIoayk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29sb3I7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyBBIERpbWVuc2lvbiwgdGhhdCBpcywgYSBudW1iZXIgYW5kIGEgdW5pdFxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gICAgIDAuNWVtIDk1JVxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgZGltZW5zaW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC5wZWVrTm90TnVtZXJpYygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSBwYXJzZXJJbnB1dC4kcmUoL14oWystXT9cXGQqXFwuP1xcZCspKCV8W2Etel9dKyk/L2kpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcodHJlZS5EaW1lbnNpb24pKHZhbHVlWzFdLCB2YWx1ZVsyXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyBBIHVuaWNvZGUgZGVzY3JpcHRvciwgYXMgaXMgdXNlZCBpbiB1bmljb2RlLXJhbmdlXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyBVKzA/PyAgb3IgVSswMEExLTAwQTlcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIHVuaWNvZGVEZXNjcmlwdG9yOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB1ZDtcblxuICAgICAgICAgICAgICAgICAgICB1ZCA9IHBhcnNlcklucHV0LiRyZSgvXlVcXCtbMC05YS1mQS1GP10rKFxcLVswLTlhLWZBLUY/XSspPy8pO1xuICAgICAgICAgICAgICAgICAgICBpZiAodWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcodHJlZS5Vbmljb2RlRGVzY3JpcHRvcikodWRbMF0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gSmF2YVNjcmlwdCBjb2RlIHRvIGJlIGV2YWx1YXRlZFxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gICAgIGB3aW5kb3cubG9jYXRpb24uaHJlZmBcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIGphdmFzY3JpcHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGpzLCBpbmRleCA9IHBhcnNlcklucHV0Lmk7XG5cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuc2F2ZSgpO1xuXG4gICAgICAgICAgICAgICAgICAgIHZhciBlc2NhcGUgPSBwYXJzZXJJbnB1dC4kY2hhcihcIn5cIik7XG4gICAgICAgICAgICAgICAgICAgIHZhciBqc1F1b3RlID0gcGFyc2VySW5wdXQuJGNoYXIoXCJgXCIpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICghanNRdW90ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQucmVzdG9yZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAganMgPSBwYXJzZXJJbnB1dC4kcmUoL15bXmBdKmAvKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGpzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5mb3JnZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcodHJlZS5KYXZhU2NyaXB0KShqcy5zdWJzdHIoMCwganMubGVuZ3RoIC0gMSksIEJvb2xlYW4oZXNjYXBlKSwgaW5kZXgsIGZpbGVJbmZvKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5yZXN0b3JlKFwiaW52YWxpZCBqYXZhc2NyaXB0IGRlZmluaXRpb25cIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIFRoZSB2YXJpYWJsZSBwYXJ0IG9mIGEgdmFyaWFibGUgZGVmaW5pdGlvbi4gVXNlZCBpbiB0aGUgYHJ1bGVgIHBhcnNlclxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vICAgICBAZmluazpcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICB2YXJpYWJsZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBuYW1lO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LmN1cnJlbnRDaGFyKCkgPT09ICdAJyAmJiAobmFtZSA9IHBhcnNlcklucHV0LiRyZSgvXihAW1xcdy1dKylcXHMqOi8pKSkgeyByZXR1cm4gbmFtZVsxXTsgfVxuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIFRoZSB2YXJpYWJsZSBwYXJ0IG9mIGEgdmFyaWFibGUgZGVmaW5pdGlvbi4gVXNlZCBpbiB0aGUgYHJ1bGVgIHBhcnNlclxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vICAgICBAZmluaygpO1xuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIHJ1bGVzZXRDYWxsOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIG5hbWU7XG5cbiAgICAgICAgICAgICAgICBpZiAocGFyc2VySW5wdXQuY3VycmVudENoYXIoKSA9PT0gJ0AnICYmIChuYW1lID0gcGFyc2VySW5wdXQuJHJlKC9eKEBbXFx3LV0rKVxcKFxccypcXClcXHMqOy8pKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHRyZWUuUnVsZXNldENhbGwobmFtZVsxXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIGV4dGVuZCBzeW50YXggLSB1c2VkIHRvIGV4dGVuZCBzZWxlY3RvcnNcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBleHRlbmQ6IGZ1bmN0aW9uKGlzUnVsZSkge1xuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50cywgZSwgaW5kZXggPSBwYXJzZXJJbnB1dC5pLCBvcHRpb24sIGV4dGVuZExpc3QsIGV4dGVuZDtcblxuICAgICAgICAgICAgICAgIGlmICghcGFyc2VySW5wdXQuJHN0cihpc1J1bGUgPyBcIiY6ZXh0ZW5kKFwiIDogXCI6ZXh0ZW5kKFwiKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb24gPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50cyA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlICghIChvcHRpb24gPSBwYXJzZXJJbnB1dC4kcmUoL14oYWxsKSg/PVxccyooXFwpfCwpKS8pKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZSA9IHRoaXMuZWxlbWVudCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50cyA9IFsgZSBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgb3B0aW9uID0gb3B0aW9uICYmIG9wdGlvblsxXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFlbGVtZW50cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IoXCJNaXNzaW5nIHRhcmdldCBzZWxlY3RvciBmb3IgOmV4dGVuZCgpLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBleHRlbmQgPSBuZXcodHJlZS5FeHRlbmQpKG5ldyh0cmVlLlNlbGVjdG9yKShlbGVtZW50cyksIG9wdGlvbiwgaW5kZXgsIGZpbGVJbmZvKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4dGVuZExpc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuZExpc3QucHVzaChleHRlbmQpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kTGlzdCA9IFsgZXh0ZW5kIF07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IHdoaWxlIChwYXJzZXJJbnB1dC4kY2hhcihcIixcIikpO1xuXG4gICAgICAgICAgICAgICAgZXhwZWN0KC9eXFwpLyk7XG5cbiAgICAgICAgICAgICAgICBpZiAoaXNSdWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdCgvXjsvKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gZXh0ZW5kTGlzdDtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBleHRlbmRSdWxlIC0gdXNlZCBpbiBhIHJ1bGUgdG8gZXh0ZW5kIGFsbCB0aGUgcGFyZW50IHNlbGVjdG9yc1xuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIGV4dGVuZFJ1bGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmV4dGVuZCh0cnVlKTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBNaXhpbnNcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBtaXhpbjoge1xuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gQSBNaXhpbiBjYWxsLCB3aXRoIGFuIG9wdGlvbmFsIGFyZ3VtZW50IGxpc3RcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vICAgICAjbWl4aW5zID4gLnNxdWFyZSgjZmZmKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgLnJvdW5kZWQoNHB4LCBibGFjayk7XG4gICAgICAgICAgICAgICAgLy8gICAgIC5idXR0b247XG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyBUaGUgYHdoaWxlYCBsb29wIGlzIHRoZXJlIGJlY2F1c2UgbWl4aW5zIGNhbiBiZVxuICAgICAgICAgICAgICAgIC8vIG5hbWVzcGFjZWQsIGJ1dCB3ZSBvbmx5IHN1cHBvcnQgdGhlIGNoaWxkIGFuZCBkZXNjZW5kYW50XG4gICAgICAgICAgICAgICAgLy8gc2VsZWN0b3IgZm9yIG5vdy5cbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIGNhbGw6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHMgPSBwYXJzZXJJbnB1dC5jdXJyZW50Q2hhcigpLCBpbXBvcnRhbnQgPSBmYWxzZSwgaW5kZXggPSBwYXJzZXJJbnB1dC5pLCBlbGVtSW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50cywgZWxlbSwgZSwgYywgYXJncztcblxuICAgICAgICAgICAgICAgICAgICBpZiAocyAhPT0gJy4nICYmIHMgIT09ICcjJykgeyByZXR1cm47IH1cblxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5zYXZlKCk7IC8vIHN0b3AgdXMgYWJzb3JiaW5nIHBhcnQgb2YgYW4gaW52YWxpZCBzZWxlY3RvclxuXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtSW5kZXggPSBwYXJzZXJJbnB1dC5pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZSA9IHBhcnNlcklucHV0LiRyZSgvXlsjLl0oPzpbXFx3LV18XFxcXCg/OltBLUZhLWYwLTldezEsNn0gP3xbXkEtRmEtZjAtOV0pKSsvKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbSA9IG5ldyh0cmVlLkVsZW1lbnQpKGMsIGUsIGVsZW1JbmRleCwgZmlsZUluZm8pO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMucHVzaChlbGVtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMgPSBbIGVsZW0gXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGMgPSBwYXJzZXJJbnB1dC4kY2hhcignPicpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyc2VySW5wdXQuJGNoYXIoJygnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3MgPSB0aGlzLmFyZ3ModHJ1ZSkuYXJncztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RDaGFyKCcpJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZXJzLmltcG9ydGFudCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wb3J0YW50ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlcnMuZW5kKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5mb3JnZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3KHRyZWUubWl4aW4uQ2FsbCkoZWxlbWVudHMsIGFyZ3MsIGluZGV4LCBmaWxlSW5mbywgaW1wb3J0YW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LnJlc3RvcmUoKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGFyZ3M6IGZ1bmN0aW9uIChpc0NhbGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVudGl0aWVzID0gcGFyc2Vycy5lbnRpdGllcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybmVyID0geyBhcmdzOm51bGwsIHZhcmlhZGljOiBmYWxzZSB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbnMgPSBbXSwgYXJnc1NlbWlDb2xvbiA9IFtdLCBhcmdzQ29tbWEgPSBbXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzU2VtaUNvbG9uU2VwYXJhdGVkLCBleHByZXNzaW9uQ29udGFpbnNOYW1lZCwgbmFtZSwgbmFtZUxvb3AsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSwgYXJnLCBleHBhbmQ7XG5cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuc2F2ZSgpO1xuXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNDYWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnID0gcGFyc2Vycy5kZXRhY2hlZFJ1bGVzZXQoKSB8fCBwYXJzZXJzLmV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuY29tbWVudFN0b3JlLmxlbmd0aCA9IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LiRzdHIoXCIuLi5cIikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuZXIudmFyaWFkaWMgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyc2VySW5wdXQuJGNoYXIoXCI7XCIpICYmICFpc1NlbWlDb2xvblNlcGFyYXRlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNTZW1pQ29sb25TZXBhcmF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpc1NlbWlDb2xvblNlcGFyYXRlZCA/IGFyZ3NTZW1pQ29sb24gOiBhcmdzQ29tbWEpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucHVzaCh7IHZhcmlhZGljOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnID0gZW50aXRpZXMudmFyaWFibGUoKSB8fCBlbnRpdGllcy5saXRlcmFsKCkgfHwgZW50aXRpZXMua2V5d29yZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFyZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lTG9vcCA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJnLnRocm93QXdheUNvbW1lbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnLnRocm93QXdheUNvbW1lbnRzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGFyZztcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWwgPSBudWxsO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNDYWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmFyaWFibGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJnLnZhbHVlICYmIGFyZy52YWx1ZS5sZW5ndGggPT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWwgPSBhcmcudmFsdWVbMF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWwgPSBhcmc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWwgJiYgdmFsIGluc3RhbmNlb2YgdHJlZS5WYXJpYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC4kY2hhcignOicpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChleHByZXNzaW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNTZW1pQ29sb25TZXBhcmF0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcihcIkNhbm5vdCBtaXggOyBhbmQgLCBhcyBkZWxpbWl0ZXIgdHlwZXNcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uQ29udGFpbnNOYW1lZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhcnNlcnMuZGV0YWNoZWRSdWxlc2V0KCkgfHwgcGFyc2Vycy5leHByZXNzaW9uKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ2FsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yKFwiY291bGQgbm90IHVuZGVyc3RhbmQgdmFsdWUgZm9yIG5hbWVkIGFyZ3VtZW50XCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5yZXN0b3JlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuZXIuYXJncyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXR1cm5lcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lTG9vcCA9IChuYW1lID0gdmFsLm5hbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFyc2VySW5wdXQuJHN0cihcIi4uLlwiKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzQ2FsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuZXIudmFyaWFkaWMgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LiRjaGFyKFwiO1wiKSAmJiAhaXNTZW1pQ29sb25TZXBhcmF0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1NlbWlDb2xvblNlcGFyYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaXNTZW1pQ29sb25TZXBhcmF0ZWQgPyBhcmdzU2VtaUNvbG9uIDogYXJnc0NvbW1hKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wdXNoKHsgbmFtZTogYXJnLm5hbWUsIHZhcmlhZGljOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNDYWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lTG9vcCA9IHZhbC5uYW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9ucy5wdXNoKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgYXJnc0NvbW1hLnB1c2goeyBuYW1lOm5hbWVMb29wLCB2YWx1ZTp2YWx1ZSwgZXhwYW5kOmV4cGFuZCB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LiRjaGFyKCcsJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LiRjaGFyKCc7JykgfHwgaXNTZW1pQ29sb25TZXBhcmF0ZWQpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChleHByZXNzaW9uQ29udGFpbnNOYW1lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcihcIkNhbm5vdCBtaXggOyBhbmQgLCBhcyBkZWxpbWl0ZXIgdHlwZXNcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNTZW1pQ29sb25TZXBhcmF0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV4cHJlc3Npb25zLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBuZXcodHJlZS5WYWx1ZSkoZXhwcmVzc2lvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzU2VtaUNvbG9uLnB1c2goeyBuYW1lOm5hbWUsIHZhbHVlOnZhbHVlLCBleHBhbmQ6ZXhwYW5kIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbnMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uQ29udGFpbnNOYW1lZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuZm9yZ2V0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybmVyLmFyZ3MgPSBpc1NlbWlDb2xvblNlcGFyYXRlZCA/IGFyZ3NTZW1pQ29sb24gOiBhcmdzQ29tbWE7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXR1cm5lcjtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gQSBNaXhpbiBkZWZpbml0aW9uLCB3aXRoIGEgbGlzdCBvZiBwYXJhbWV0ZXJzXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyAgICAgLnJvdW5kZWQgKEByYWRpdXM6IDJweCwgQGNvbG9yKSB7XG4gICAgICAgICAgICAgICAgLy8gICAgICAgIC4uLlxuICAgICAgICAgICAgICAgIC8vICAgICB9XG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyBVbnRpbCB3ZSBoYXZlIGEgZmluZXIgZ3JhaW5lZCBzdGF0ZS1tYWNoaW5lLCB3ZSBoYXZlIHRvXG4gICAgICAgICAgICAgICAgLy8gZG8gYSBsb29rLWFoZWFkLCB0byBtYWtlIHN1cmUgd2UgZG9uJ3QgaGF2ZSBhIG1peGluIGNhbGwuXG4gICAgICAgICAgICAgICAgLy8gU2VlIHRoZSBgcnVsZWAgZnVuY3Rpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyBXZSBzdGFydCBieSBtYXRjaGluZyBgLnJvdW5kZWQgKGAsIGFuZCB0aGVuIHByb2NlZWQgb24gdG9cbiAgICAgICAgICAgICAgICAvLyB0aGUgYXJndW1lbnQgbGlzdCwgd2hpY2ggaGFzIG9wdGlvbmFsIGRlZmF1bHQgdmFsdWVzLlxuICAgICAgICAgICAgICAgIC8vIFdlIHN0b3JlIHRoZSBwYXJhbWV0ZXJzIGluIGBwYXJhbXNgLCB3aXRoIGEgYHZhbHVlYCBrZXksXG4gICAgICAgICAgICAgICAgLy8gaWYgdGhlcmUgaXMgYSB2YWx1ZSwgc3VjaCBhcyBpbiB0aGUgY2FzZSBvZiBgQHJhZGl1c2AuXG4gICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAvLyBPbmNlIHdlJ3ZlIGdvdCBvdXIgcGFyYW1zIGxpc3QsIGFuZCBhIGNsb3NpbmcgYClgLCB3ZSBwYXJzZVxuICAgICAgICAgICAgICAgIC8vIHRoZSBgey4uLn1gIGJsb2NrLlxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgZGVmaW5pdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZSwgcGFyYW1zID0gW10sIG1hdGNoLCBydWxlc2V0LCBjb25kLCB2YXJpYWRpYyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoKHBhcnNlcklucHV0LmN1cnJlbnRDaGFyKCkgIT09ICcuJyAmJiBwYXJzZXJJbnB1dC5jdXJyZW50Q2hhcigpICE9PSAnIycpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5wZWVrKC9eW157XSpcXH0vKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuc2F2ZSgpO1xuXG4gICAgICAgICAgICAgICAgICAgIG1hdGNoID0gcGFyc2VySW5wdXQuJHJlKC9eKFsjLl0oPzpbXFx3LV18XFxcXCg/OltBLUZhLWYwLTldezEsNn0gP3xbXkEtRmEtZjAtOV0pKSspXFxzKlxcKC8pO1xuICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBtYXRjaFsxXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFyZ0luZm8gPSB0aGlzLmFyZ3MoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0gYXJnSW5mby5hcmdzO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFkaWMgPSBhcmdJbmZvLnZhcmlhZGljO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAubWl4aW5jYWxsKFwiQHthfVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvb2tzIGEgYml0IGxpa2UgYSBtaXhpbiBkZWZpbml0aW9uLi5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFsc29cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC5taXhpbmNhbGwoQGE6IHtydWxlOiBzZXQ7fSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzbyB3ZSBoYXZlIHRvIGJlIG5pY2UgYW5kIHJlc3RvcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcGFyc2VySW5wdXQuJGNoYXIoJyknKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LnJlc3RvcmUoXCJNaXNzaW5nIGNsb3NpbmcgJyknXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuY29tbWVudFN0b3JlLmxlbmd0aCA9IDA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC4kc3RyKFwid2hlblwiKSkgeyAvLyBHdWFyZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmQgPSBleHBlY3QocGFyc2Vycy5jb25kaXRpb25zLCAnZXhwZWN0ZWQgY29uZGl0aW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGVzZXQgPSBwYXJzZXJzLmJsb2NrKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChydWxlc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuZm9yZ2V0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyh0cmVlLm1peGluLkRlZmluaXRpb24pKG5hbWUsIHBhcmFtcywgcnVsZXNldCwgY29uZCwgdmFyaWFkaWMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5yZXN0b3JlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5mb3JnZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBFbnRpdGllcyBhcmUgdGhlIHNtYWxsZXN0IHJlY29nbml6ZWQgdG9rZW4sXG4gICAgICAgICAgICAvLyBhbmQgY2FuIGJlIGZvdW5kIGluc2lkZSBhIHJ1bGUncyB2YWx1ZS5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBlbnRpdHk6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZW50aXRpZXMgPSB0aGlzLmVudGl0aWVzO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tbWVudCgpIHx8IGVudGl0aWVzLmxpdGVyYWwoKSB8fCBlbnRpdGllcy52YXJpYWJsZSgpIHx8IGVudGl0aWVzLnVybCgpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgIGVudGl0aWVzLmNhbGwoKSAgICB8fCBlbnRpdGllcy5rZXl3b3JkKCkgIHx8IGVudGl0aWVzLmphdmFzY3JpcHQoKTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBBIFJ1bGUgdGVybWluYXRvci4gTm90ZSB0aGF0IHdlIHVzZSBgcGVlaygpYCB0byBjaGVjayBmb3IgJ30nLFxuICAgICAgICAgICAgLy8gYmVjYXVzZSB0aGUgYGJsb2NrYCBydWxlIHdpbGwgYmUgZXhwZWN0aW5nIGl0LCBidXQgd2Ugc3RpbGwgbmVlZCB0byBtYWtlIHN1cmVcbiAgICAgICAgICAgIC8vIGl0J3MgdGhlcmUsIGlmICc7JyB3YXMgb21pdHRlZC5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBlbmQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VySW5wdXQuJGNoYXIoJzsnKSB8fCBwYXJzZXJJbnB1dC5wZWVrKCd9Jyk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gSUUncyBhbHBoYSBmdW5jdGlvblxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vICAgICBhbHBoYShvcGFjaXR5PTg4KVxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIGFscGhhOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlO1xuXG4gICAgICAgICAgICAgICAgLy8gaHR0cDovL2pzcGVyZi5jb20vY2FzZS1pbnNlbnNpdGl2ZS1yZWdleC12cy1zdHJ0b2xvd2VyLXRoZW4tcmVnZXgvMThcbiAgICAgICAgICAgICAgICBpZiAoISBwYXJzZXJJbnB1dC4kcmUoL15vcGFjaXR5PS9pKSkgeyByZXR1cm47IH1cbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhcnNlcklucHV0LiRyZSgvXlxcZCsvKTtcbiAgICAgICAgICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gZXhwZWN0KHRoaXMuZW50aXRpZXMudmFyaWFibGUsIFwiQ291bGQgbm90IHBhcnNlIGFscGhhXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBleHBlY3RDaGFyKCcpJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyh0cmVlLkFscGhhKSh2YWx1ZSk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gQSBTZWxlY3RvciBFbGVtZW50XG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gICAgIGRpdlxuICAgICAgICAgICAgLy8gICAgICsgaDFcbiAgICAgICAgICAgIC8vICAgICAjc29ja3NcbiAgICAgICAgICAgIC8vICAgICBpbnB1dFt0eXBlPVwidGV4dFwiXVxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEVsZW1lbnRzIGFyZSB0aGUgYnVpbGRpbmcgYmxvY2tzIGZvciBTZWxlY3RvcnMsXG4gICAgICAgICAgICAvLyB0aGV5IGFyZSBtYWRlIG91dCBvZiBhIGBDb21iaW5hdG9yYCAoc2VlIGNvbWJpbmF0b3IgcnVsZSksXG4gICAgICAgICAgICAvLyBhbmQgYW4gZWxlbWVudCBuYW1lLCBzdWNoIGFzIGEgdGFnIGEgY2xhc3MsIG9yIGAqYC5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBlbGVtZW50OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGUsIGMsIHYsIGluZGV4ID0gcGFyc2VySW5wdXQuaTtcblxuICAgICAgICAgICAgICAgIGMgPSB0aGlzLmNvbWJpbmF0b3IoKTtcblxuICAgICAgICAgICAgICAgIGUgPSBwYXJzZXJJbnB1dC4kcmUoL14oPzpcXGQrXFwuXFxkK3xcXGQrKSUvKSB8fFxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC4kcmUoL14oPzpbLiNdP3w6KikoPzpbXFx3LV18W15cXHgwMC1cXHg5Zl18XFxcXCg/OltBLUZhLWYwLTldezEsNn0gP3xbXkEtRmEtZjAtOV0pKSsvKSB8fFxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC4kY2hhcignKicpIHx8IHBhcnNlcklucHV0LiRjaGFyKCcmJykgfHwgdGhpcy5hdHRyaWJ1dGUoKSB8fFxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC4kcmUoL15cXChbXiYoKUBdK1xcKS8pIHx8ICBwYXJzZXJJbnB1dC4kcmUoL15bXFwuIzpdKD89QCkvKSB8fFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVudGl0aWVzLnZhcmlhYmxlQ3VybHkoKTtcblxuICAgICAgICAgICAgICAgIGlmICghIGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuc2F2ZSgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocGFyc2VySW5wdXQuJGNoYXIoJygnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCh2ID0gdGhpcy5zZWxlY3RvcigpKSAmJiBwYXJzZXJJbnB1dC4kY2hhcignKScpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZSA9IG5ldyh0cmVlLlBhcmVuKSh2KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5mb3JnZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQucmVzdG9yZShcIk1pc3NpbmcgY2xvc2luZyAnKSdcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5mb3JnZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChlKSB7IHJldHVybiBuZXcodHJlZS5FbGVtZW50KShjLCBlLCBpbmRleCwgZmlsZUluZm8pOyB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gQ29tYmluYXRvcnMgY29tYmluZSBlbGVtZW50cyB0b2dldGhlciwgaW4gYSBTZWxlY3Rvci5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBCZWNhdXNlIG91ciBwYXJzZXIgaXNuJ3Qgd2hpdGUtc3BhY2Ugc2Vuc2l0aXZlLCBzcGVjaWFsIGNhcmVcbiAgICAgICAgICAgIC8vIGhhcyB0byBiZSB0YWtlbiwgd2hlbiBwYXJzaW5nIHRoZSBkZXNjZW5kYW50IGNvbWJpbmF0b3IsIGAgYCxcbiAgICAgICAgICAgIC8vIGFzIGl0J3MgYW4gZW1wdHkgc3BhY2UuIFdlIGhhdmUgdG8gY2hlY2sgdGhlIHByZXZpb3VzIGNoYXJhY3RlclxuICAgICAgICAgICAgLy8gaW4gdGhlIGlucHV0LCB0byBzZWUgaWYgaXQncyBhIGAgYCBjaGFyYWN0ZXIuIE1vcmUgaW5mbyBvbiBob3dcbiAgICAgICAgICAgIC8vIHdlIGRlYWwgd2l0aCB0aGlzIGluICpjb21iaW5hdG9yLmpzKi5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBjb21iaW5hdG9yOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGMgPSBwYXJzZXJJbnB1dC5jdXJyZW50Q2hhcigpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGMgPT09ICcvJykge1xuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5zYXZlKCk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzbGFzaGVkQ29tYmluYXRvciA9IHBhcnNlcklucHV0LiRyZSgvXlxcL1thLXpdK1xcLy9pKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNsYXNoZWRDb21iaW5hdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5mb3JnZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcodHJlZS5Db21iaW5hdG9yKShzbGFzaGVkQ29tYmluYXRvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQucmVzdG9yZSgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChjID09PSAnPicgfHwgYyA9PT0gJysnIHx8IGMgPT09ICd+JyB8fCBjID09PSAnfCcgfHwgYyA9PT0gJ14nKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LmkrKztcbiAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT09ICdeJyAmJiBwYXJzZXJJbnB1dC5jdXJyZW50Q2hhcigpID09PSAnXicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGMgPSAnXl4nO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuaSsrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChwYXJzZXJJbnB1dC5pc1doaXRlc3BhY2UoKSkgeyBwYXJzZXJJbnB1dC5pKys7IH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyh0cmVlLkNvbWJpbmF0b3IpKGMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFyc2VySW5wdXQuaXNXaGl0ZXNwYWNlKC0xKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3KHRyZWUuQ29tYmluYXRvcikoXCIgXCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcodHJlZS5Db21iaW5hdG9yKShudWxsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEEgQ1NTIHNlbGVjdG9yIChzZWUgc2VsZWN0b3IgYmVsb3cpXG4gICAgICAgICAgICAvLyB3aXRoIGxlc3MgZXh0ZW5zaW9ucyBlLmcuIHRoZSBhYmlsaXR5IHRvIGV4dGVuZCBhbmQgZ3VhcmRcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBsZXNzU2VsZWN0b3I6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3Rvcih0cnVlKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gQSBDU1MgU2VsZWN0b3JcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyAgICAgLmNsYXNzID4gZGl2ICsgaDFcbiAgICAgICAgICAgIC8vICAgICBsaSBhOmhvdmVyXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gU2VsZWN0b3JzIGFyZSBtYWRlIG91dCBvZiBvbmUgb3IgbW9yZSBFbGVtZW50cywgc2VlIGFib3ZlLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIHNlbGVjdG9yOiBmdW5jdGlvbiAoaXNMZXNzKSB7XG4gICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gcGFyc2VySW5wdXQuaSwgZWxlbWVudHMsIGV4dGVuZExpc3QsIGMsIGUsIGFsbEV4dGVuZHMsIHdoZW4sIGNvbmRpdGlvbjtcblxuICAgICAgICAgICAgICAgIHdoaWxlICgoaXNMZXNzICYmIChleHRlbmRMaXN0ID0gdGhpcy5leHRlbmQoKSkpIHx8IChpc0xlc3MgJiYgKHdoZW4gPSBwYXJzZXJJbnB1dC4kc3RyKFwid2hlblwiKSkpIHx8IChlID0gdGhpcy5lbGVtZW50KCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh3aGVuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25kaXRpb24gPSBleHBlY3QodGhpcy5jb25kaXRpb25zLCAnZXhwZWN0ZWQgY29uZGl0aW9uJyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY29uZGl0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcihcIkNTUyBndWFyZCBjYW4gb25seSBiZSB1c2VkIGF0IHRoZSBlbmQgb2Ygc2VsZWN0b3JcIik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXh0ZW5kTGlzdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFsbEV4dGVuZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxFeHRlbmRzID0gYWxsRXh0ZW5kcy5jb25jYXQoZXh0ZW5kTGlzdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbEV4dGVuZHMgPSBleHRlbmRMaXN0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFsbEV4dGVuZHMpIHsgZXJyb3IoXCJFeHRlbmQgY2FuIG9ubHkgYmUgdXNlZCBhdCB0aGUgZW5kIG9mIHNlbGVjdG9yXCIpOyB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjID0gcGFyc2VySW5wdXQuY3VycmVudENoYXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzID0gWyBlIF07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PT0gJ3snIHx8IGMgPT09ICd9JyB8fCBjID09PSAnOycgfHwgYyA9PT0gJywnIHx8IGMgPT09ICcpJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudHMpIHsgcmV0dXJuIG5ldyh0cmVlLlNlbGVjdG9yKShlbGVtZW50cywgYWxsRXh0ZW5kcywgY29uZGl0aW9uLCBpbmRleCwgZmlsZUluZm8pOyB9XG4gICAgICAgICAgICAgICAgaWYgKGFsbEV4dGVuZHMpIHsgZXJyb3IoXCJFeHRlbmQgbXVzdCBiZSB1c2VkIHRvIGV4dGVuZCBhIHNlbGVjdG9yLCBpdCBjYW5ub3QgYmUgdXNlZCBvbiBpdHMgb3duXCIpOyB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXR0cmlidXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEgcGFyc2VySW5wdXQuJGNoYXIoJ1snKSkgeyByZXR1cm47IH1cblxuICAgICAgICAgICAgICAgIHZhciBlbnRpdGllcyA9IHRoaXMuZW50aXRpZXMsXG4gICAgICAgICAgICAgICAgICAgIGtleSwgdmFsLCBvcDtcblxuICAgICAgICAgICAgICAgIGlmICghKGtleSA9IGVudGl0aWVzLnZhcmlhYmxlQ3VybHkoKSkpIHtcbiAgICAgICAgICAgICAgICAgICAga2V5ID0gZXhwZWN0KC9eKD86W19BLVphLXowLTktXFwqXSpcXHwpPyg/OltfQS1aYS16MC05LV18XFxcXC4pKy8pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG9wID0gcGFyc2VySW5wdXQuJHJlKC9eW3x+KiReXT89Lyk7XG4gICAgICAgICAgICAgICAgaWYgKG9wKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbCA9IGVudGl0aWVzLnF1b3RlZCgpIHx8IHBhcnNlcklucHV0LiRyZSgvXlswLTldKyUvKSB8fCBwYXJzZXJJbnB1dC4kcmUoL15bXFx3LV0rLykgfHwgZW50aXRpZXMudmFyaWFibGVDdXJseSgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGV4cGVjdENoYXIoJ10nKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcodHJlZS5BdHRyaWJ1dGUpKGtleSwgb3AsIHZhbCk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gVGhlIGBibG9ja2AgcnVsZSBpcyB1c2VkIGJ5IGBydWxlc2V0YCBhbmQgYG1peGluLmRlZmluaXRpb25gLlxuICAgICAgICAgICAgLy8gSXQncyBhIHdyYXBwZXIgYXJvdW5kIHRoZSBgcHJpbWFyeWAgcnVsZSwgd2l0aCBhZGRlZCBge31gLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIGJsb2NrOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbnRlbnQ7XG4gICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LiRjaGFyKCd7JykgJiYgKGNvbnRlbnQgPSB0aGlzLnByaW1hcnkoKSkgJiYgcGFyc2VySW5wdXQuJGNoYXIoJ30nKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udGVudDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBibG9ja1J1bGVzZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHZhciBibG9jayA9IHRoaXMuYmxvY2soKTtcblxuICAgICAgICAgICAgICAgIGlmIChibG9jaykge1xuICAgICAgICAgICAgICAgICAgICBibG9jayA9IG5ldyB0cmVlLlJ1bGVzZXQobnVsbCwgYmxvY2spO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYmxvY2s7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICBkZXRhY2hlZFJ1bGVzZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHZhciBibG9ja1J1bGVzZXQgPSB0aGlzLmJsb2NrUnVsZXNldCgpO1xuICAgICAgICAgICAgICAgIGlmIChibG9ja1J1bGVzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB0cmVlLkRldGFjaGVkUnVsZXNldChibG9ja1J1bGVzZXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBkaXYsIC5jbGFzcywgYm9keSA+IHAgey4uLn1cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBydWxlc2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlbGVjdG9ycywgcywgcnVsZXMsIGRlYnVnSW5mbztcblxuICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LnNhdmUoKTtcblxuICAgICAgICAgICAgICAgIGlmIChjb250ZXh0LmR1bXBMaW5lTnVtYmVycykge1xuICAgICAgICAgICAgICAgICAgICBkZWJ1Z0luZm8gPSBnZXREZWJ1Z0luZm8ocGFyc2VySW5wdXQuaSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgcyA9IHRoaXMubGVzc1NlbGVjdG9yKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdG9ycykge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3JzLnB1c2gocyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcnMgPSBbIHMgXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5jb21tZW50U3RvcmUubGVuZ3RoID0gMDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHMuY29uZGl0aW9uICYmIHNlbGVjdG9ycy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcihcIkd1YXJkcyBhcmUgb25seSBjdXJyZW50bHkgYWxsb3dlZCBvbiBhIHNpbmdsZSBzZWxlY3Rvci5cIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCEgcGFyc2VySW5wdXQuJGNoYXIoJywnKSkgeyBicmVhazsgfVxuICAgICAgICAgICAgICAgICAgICBpZiAocy5jb25kaXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yKFwiR3VhcmRzIGFyZSBvbmx5IGN1cnJlbnRseSBhbGxvd2VkIG9uIGEgc2luZ2xlIHNlbGVjdG9yLlwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5jb21tZW50U3RvcmUubGVuZ3RoID0gMDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3JzICYmIChydWxlcyA9IHRoaXMuYmxvY2soKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuZm9yZ2V0KCk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBydWxlc2V0ID0gbmV3KHRyZWUuUnVsZXNldCkoc2VsZWN0b3JzLCBydWxlcywgY29udGV4dC5zdHJpY3RJbXBvcnRzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRleHQuZHVtcExpbmVOdW1iZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBydWxlc2V0LmRlYnVnSW5mbyA9IGRlYnVnSW5mbztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcnVsZXNldDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5yZXN0b3JlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJ1bGU6IGZ1bmN0aW9uICh0cnlBbm9ueW1vdXMpIHtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZSwgdmFsdWUsIHN0YXJ0T2ZSdWxlID0gcGFyc2VySW5wdXQuaSwgYyA9IHBhcnNlcklucHV0LmN1cnJlbnRDaGFyKCksIGltcG9ydGFudCwgbWVyZ2UsIGlzVmFyaWFibGU7XG5cbiAgICAgICAgICAgICAgICBpZiAoYyA9PT0gJy4nIHx8IGMgPT09ICcjJyB8fCBjID09PSAnJicgfHwgYyA9PT0gJzonKSB7IHJldHVybjsgfVxuXG4gICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuc2F2ZSgpO1xuXG4gICAgICAgICAgICAgICAgbmFtZSA9IHRoaXMudmFyaWFibGUoKSB8fCB0aGlzLnJ1bGVQcm9wZXJ0eSgpO1xuICAgICAgICAgICAgICAgIGlmIChuYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGlzVmFyaWFibGUgPSB0eXBlb2YgbmFtZSA9PT0gXCJzdHJpbmdcIjtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNWYXJpYWJsZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmRldGFjaGVkUnVsZXNldCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuY29tbWVudFN0b3JlLmxlbmd0aCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGEgbmFtZSByZXR1cm5lZCBieSB0aGlzLnJ1bGVQcm9wZXJ0eSgpIGlzIGFsd2F5cyBhbiBhcnJheSBvZiB0aGUgZm9ybTpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFtzdHJpbmctMSwgLi4uLCBzdHJpbmctbiwgXCJcIl0gb3IgW3N0cmluZy0xLCAuLi4sIHN0cmluZy1uLCBcIitcIl1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdoZXJlIGVhY2ggaXRlbSBpcyBhIHRyZWUuS2V5d29yZCBvciB0cmVlLlZhcmlhYmxlXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXJnZSA9ICFpc1ZhcmlhYmxlICYmIG5hbWUubGVuZ3RoID4gMSAmJiBuYW1lLnBvcCgpLnZhbHVlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBwcmVmZXIgdG8gdHJ5IHRvIHBhcnNlIGZpcnN0IGlmIGl0cyBhIHZhcmlhYmxlIG9yIHdlIGFyZSBjb21wcmVzc2luZ1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IGFsd2F5cyBmYWxsYmFjayBvbiB0aGUgb3RoZXIgb25lXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJ5VmFsdWVGaXJzdCA9ICF0cnlBbm9ueW1vdXMgJiYgKGNvbnRleHQuY29tcHJlc3MgfHwgaXNWYXJpYWJsZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cnlWYWx1ZUZpcnN0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLnZhbHVlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmFub255bW91c1ZhbHVlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LmZvcmdldCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbm9ueW1vdXMgdmFsdWVzIGFic29yYiB0aGUgZW5kICc7JyB3aGljaCBpcyByZXF1aXJlZCBmb3IgdGhlbSB0byB3b3JrXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgKHRyZWUuUnVsZSkobmFtZSwgdmFsdWUsIGZhbHNlLCBtZXJnZSwgc3RhcnRPZlJ1bGUsIGZpbGVJbmZvKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRyeVZhbHVlRmlyc3QgJiYgIXZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLnZhbHVlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGltcG9ydGFudCA9IHRoaXMuaW1wb3J0YW50KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgJiYgdGhpcy5lbmQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuZm9yZ2V0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3ICh0cmVlLlJ1bGUpKG5hbWUsIHZhbHVlLCBpbXBvcnRhbnQsIG1lcmdlLCBzdGFydE9mUnVsZSwgZmlsZUluZm8pO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQucmVzdG9yZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlICYmICF0cnlBbm9ueW1vdXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5ydWxlKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuZm9yZ2V0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFub255bW91c1ZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIG1hdGNoID0gcGFyc2VySW5wdXQuJHJlKC9eKFteQCtcXC8nXCIqYCg7e30tXSopOy8pO1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3KHRyZWUuQW5vbnltb3VzKShtYXRjaFsxXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEFuIEBpbXBvcnQgZGlyZWN0aXZlXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gICAgIEBpbXBvcnQgXCJsaWJcIjtcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBEZXBlbmRpbmcgb24gb3VyIGVudmlyb25tZW50LCBpbXBvcnRpbmcgaXMgZG9uZSBkaWZmZXJlbnRseTpcbiAgICAgICAgICAgIC8vIEluIHRoZSBicm93c2VyLCBpdCdzIGFuIFhIUiByZXF1ZXN0LCBpbiBOb2RlLCBpdCB3b3VsZCBiZSBhXG4gICAgICAgICAgICAvLyBmaWxlLXN5c3RlbSBvcGVyYXRpb24uIFRoZSBmdW5jdGlvbiB1c2VkIGZvciBpbXBvcnRpbmcgaXNcbiAgICAgICAgICAgIC8vIHN0b3JlZCBpbiBgaW1wb3J0YCwgd2hpY2ggd2UgcGFzcyB0byB0aGUgSW1wb3J0IGNvbnN0cnVjdG9yLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIFwiaW1wb3J0XCI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgcGF0aCwgZmVhdHVyZXMsIGluZGV4ID0gcGFyc2VySW5wdXQuaTtcblxuICAgICAgICAgICAgICAgIHZhciBkaXIgPSBwYXJzZXJJbnB1dC4kcmUoL15AaW1wb3J0P1xccysvKTtcblxuICAgICAgICAgICAgICAgIGlmIChkaXIpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9wdGlvbnMgPSAoZGlyID8gdGhpcy5pbXBvcnRPcHRpb25zKCkgOiBudWxsKSB8fCB7fTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoKHBhdGggPSB0aGlzLmVudGl0aWVzLnF1b3RlZCgpIHx8IHRoaXMuZW50aXRpZXMudXJsKCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcyA9IHRoaXMubWVkaWFGZWF0dXJlcygpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXBhcnNlcklucHV0LiRjaGFyKCc7JykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5pID0gaW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IoXCJtaXNzaW5nIHNlbWktY29sb24gb3IgdW5yZWNvZ25pc2VkIG1lZGlhIGZlYXR1cmVzIG9uIGltcG9ydFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzID0gZmVhdHVyZXMgJiYgbmV3KHRyZWUuVmFsdWUpKGZlYXR1cmVzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcodHJlZS5JbXBvcnQpKHBhdGgsIGZlYXR1cmVzLCBvcHRpb25zLCBpbmRleCwgZmlsZUluZm8pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuaSA9IGluZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IoXCJtYWxmb3JtZWQgaW1wb3J0IHN0YXRlbWVudFwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIGltcG9ydE9wdGlvbnM6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHZhciBvLCBvcHRpb25zID0ge30sIG9wdGlvbk5hbWUsIHZhbHVlO1xuXG4gICAgICAgICAgICAgICAgLy8gbGlzdCBvZiBvcHRpb25zLCBzdXJyb3VuZGVkIGJ5IHBhcmVuc1xuICAgICAgICAgICAgICAgIGlmICghIHBhcnNlcklucHV0LiRjaGFyKCcoJykpIHsgcmV0dXJuIG51bGw7IH1cbiAgICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgICAgIG8gPSB0aGlzLmltcG9ydE9wdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobykge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uTmFtZSA9IG87XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2gob3B0aW9uTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJjc3NcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uTmFtZSA9IFwibGVzc1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwib25jZVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25OYW1lID0gXCJtdWx0aXBsZVwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnNbb3B0aW9uTmFtZV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIHBhcnNlcklucHV0LiRjaGFyKCcsJykpIHsgYnJlYWs7IH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gd2hpbGUgKG8pO1xuICAgICAgICAgICAgICAgIGV4cGVjdENoYXIoJyknKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucztcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIGltcG9ydE9wdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgdmFyIG9wdCA9IHBhcnNlcklucHV0LiRyZSgvXihsZXNzfGNzc3xtdWx0aXBsZXxvbmNlfGlubGluZXxyZWZlcmVuY2V8b3B0aW9uYWwpLyk7XG4gICAgICAgICAgICAgICAgaWYgKG9wdCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3B0WzFdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIG1lZGlhRmVhdHVyZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBlbnRpdGllcyA9IHRoaXMuZW50aXRpZXMsIG5vZGVzID0gW10sIGUsIHA7XG4gICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuc2F2ZSgpO1xuICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgZSA9IGVudGl0aWVzLmtleXdvcmQoKSB8fCBlbnRpdGllcy52YXJpYWJsZSgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXMucHVzaChlKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJzZXJJbnB1dC4kY2hhcignKCcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwID0gdGhpcy5wcm9wZXJ0eSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZSA9IHRoaXMudmFsdWUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC4kY2hhcignKScpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHAgJiYgZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2Rlcy5wdXNoKG5ldyh0cmVlLlBhcmVuKShuZXcodHJlZS5SdWxlKShwLCBlLCBudWxsLCBudWxsLCBwYXJzZXJJbnB1dC5pLCBmaWxlSW5mbywgdHJ1ZSkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXMucHVzaChuZXcodHJlZS5QYXJlbikoZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yKFwiYmFkbHkgZm9ybWVkIG1lZGlhIGZlYXR1cmUgZGVmaW5pdGlvblwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yKFwiTWlzc2luZyBjbG9zaW5nICcpJ1wiLCBcIlBhcnNlXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSB3aGlsZSAoZSk7XG5cbiAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5mb3JnZXQoKTtcbiAgICAgICAgICAgICAgICBpZiAobm9kZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3KHRyZWUuRXhwcmVzc2lvbikobm9kZXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIG1lZGlhRmVhdHVyZXM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZW50aXRpZXMgPSB0aGlzLmVudGl0aWVzLCBmZWF0dXJlcyA9IFtdLCBlO1xuICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgZSA9IHRoaXMubWVkaWFGZWF0dXJlKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcy5wdXNoKGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEgcGFyc2VySW5wdXQuJGNoYXIoJywnKSkgeyBicmVhazsgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZSA9IGVudGl0aWVzLnZhcmlhYmxlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzLnB1c2goZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEgcGFyc2VySW5wdXQuJGNoYXIoJywnKSkgeyBicmVhazsgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSB3aGlsZSAoZSk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gZmVhdHVyZXMubGVuZ3RoID4gMCA/IGZlYXR1cmVzIDogbnVsbDtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIG1lZGlhOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGZlYXR1cmVzLCBydWxlcywgbWVkaWEsIGRlYnVnSW5mbywgaW5kZXggPSBwYXJzZXJJbnB1dC5pO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNvbnRleHQuZHVtcExpbmVOdW1iZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlYnVnSW5mbyA9IGdldERlYnVnSW5mbyhpbmRleCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuc2F2ZSgpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LiRzdHIoXCJAbWVkaWFcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXMgPSB0aGlzLm1lZGlhRmVhdHVyZXMoKTtcblxuICAgICAgICAgICAgICAgICAgICBydWxlcyA9IHRoaXMuYmxvY2soKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoIXJ1bGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcihcIm1lZGlhIGRlZmluaXRpb25zIHJlcXVpcmUgYmxvY2sgc3RhdGVtZW50cyBhZnRlciBhbnkgZmVhdHVyZXNcIik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5mb3JnZXQoKTtcblxuICAgICAgICAgICAgICAgICAgICBtZWRpYSA9IG5ldyh0cmVlLk1lZGlhKShydWxlcywgZmVhdHVyZXMsIGluZGV4LCBmaWxlSW5mbyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZXh0LmR1bXBMaW5lTnVtYmVycykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWEuZGVidWdJbmZvID0gZGVidWdJbmZvO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1lZGlhO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LnJlc3RvcmUoKTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBBIEBwbHVnaW4gZGlyZWN0aXZlLCB1c2VkIHRvIGltcG9ydCBjb21waWxlciBleHRlbnNpb25zIGR5bmFtaWNhbGx5LlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vICAgICBAcGx1Z2luIFwibGliXCI7XG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gRGVwZW5kaW5nIG9uIG91ciBlbnZpcm9ubWVudCwgaW1wb3J0aW5nIGlzIGRvbmUgZGlmZmVyZW50bHk6XG4gICAgICAgICAgICAvLyBJbiB0aGUgYnJvd3NlciwgaXQncyBhbiBYSFIgcmVxdWVzdCwgaW4gTm9kZSwgaXQgd291bGQgYmUgYVxuICAgICAgICAgICAgLy8gZmlsZS1zeXN0ZW0gb3BlcmF0aW9uLiBUaGUgZnVuY3Rpb24gdXNlZCBmb3IgaW1wb3J0aW5nIGlzXG4gICAgICAgICAgICAvLyBzdG9yZWQgaW4gYGltcG9ydGAsIHdoaWNoIHdlIHBhc3MgdG8gdGhlIEltcG9ydCBjb25zdHJ1Y3Rvci5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBwbHVnaW46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgcGF0aCxcbiAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBwYXJzZXJJbnB1dC5pLFxuICAgICAgICAgICAgICAgICAgICBkaXIgICA9IHBhcnNlcklucHV0LiRyZSgvXkBwbHVnaW4/XFxzKy8pO1xuXG4gICAgICAgICAgICAgICAgaWYgKGRpcikge1xuICAgICAgICAgICAgICAgICAgICB2YXIgb3B0aW9ucyA9IHsgcGx1Z2luIDogdHJ1ZSB9O1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICgocGF0aCA9IHRoaXMuZW50aXRpZXMucXVvdGVkKCkgfHwgdGhpcy5lbnRpdGllcy51cmwoKSkpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFwYXJzZXJJbnB1dC4kY2hhcignOycpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuaSA9IGluZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yKFwibWlzc2luZyBzZW1pLWNvbG9uIG9uIHBsdWdpblwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyh0cmVlLkltcG9ydCkocGF0aCwgbnVsbCwgb3B0aW9ucywgaW5kZXgsIGZpbGVJbmZvKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LmkgPSBpbmRleDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yKFwibWFsZm9ybWVkIHBsdWdpbiBzdGF0ZW1lbnRcIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gQSBDU1MgRGlyZWN0aXZlXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gICAgIEBjaGFyc2V0IFwidXRmLThcIjtcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBkaXJlY3RpdmU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBwYXJzZXJJbnB1dC5pLCBuYW1lLCB2YWx1ZSwgcnVsZXMsIG5vblZlbmRvclNwZWNpZmljTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgaGFzSWRlbnRpZmllciwgaGFzRXhwcmVzc2lvbiwgaGFzVW5rbm93biwgaGFzQmxvY2sgPSB0cnVlLCBpc1Jvb3RlZCA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICBpZiAocGFyc2VySW5wdXQuY3VycmVudENoYXIoKSAhPT0gJ0AnKSB7IHJldHVybjsgfVxuXG4gICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzWydpbXBvcnQnXSgpIHx8IHRoaXMucGx1Z2luKCkgfHwgdGhpcy5tZWRpYSgpO1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuc2F2ZSgpO1xuXG4gICAgICAgICAgICAgICAgbmFtZSA9IHBhcnNlcklucHV0LiRyZSgvXkBbYS16LV0rLyk7XG5cbiAgICAgICAgICAgICAgICBpZiAoIW5hbWUpIHsgcmV0dXJuOyB9XG5cbiAgICAgICAgICAgICAgICBub25WZW5kb3JTcGVjaWZpY05hbWUgPSBuYW1lO1xuICAgICAgICAgICAgICAgIGlmIChuYW1lLmNoYXJBdCgxKSA9PSAnLScgJiYgbmFtZS5pbmRleE9mKCctJywgMikgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIG5vblZlbmRvclNwZWNpZmljTmFtZSA9IFwiQFwiICsgbmFtZS5zbGljZShuYW1lLmluZGV4T2YoJy0nLCAyKSArIDEpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHN3aXRjaChub25WZW5kb3JTcGVjaWZpY05hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIkBjaGFyc2V0XCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBoYXNJZGVudGlmaWVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc0Jsb2NrID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIkBuYW1lc3BhY2VcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc0V4cHJlc3Npb24gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgaGFzQmxvY2sgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiQGtleWZyYW1lc1wiOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiQGNvdW50ZXItc3R5bGVcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc0lkZW50aWZpZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJAZG9jdW1lbnRcIjpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIkBzdXBwb3J0c1wiOlxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzVW5rbm93biA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc1Jvb3RlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICBoYXNVbmtub3duID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LmNvbW1lbnRTdG9yZS5sZW5ndGggPSAwO1xuXG4gICAgICAgICAgICAgICAgaWYgKGhhc0lkZW50aWZpZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmVudGl0eSgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcihcImV4cGVjdGVkIFwiICsgbmFtZSArIFwiIGlkZW50aWZpZXJcIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGhhc0V4cHJlc3Npb24pIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IoXCJleHBlY3RlZCBcIiArIG5hbWUgKyBcIiBleHByZXNzaW9uXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChoYXNVbmtub3duKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gKHBhcnNlcklucHV0LiRyZSgvXlteeztdKy8pIHx8ICcnKS50cmltKCk7XG4gICAgICAgICAgICAgICAgICAgIGhhc0Jsb2NrID0gKHBhcnNlcklucHV0LmN1cnJlbnRDaGFyKCkgPT0gJ3snKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IG5ldyh0cmVlLkFub255bW91cykodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGhhc0Jsb2NrKSB7XG4gICAgICAgICAgICAgICAgICAgIHJ1bGVzID0gdGhpcy5ibG9ja1J1bGVzZXQoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAocnVsZXMgfHwgKCFoYXNCbG9jayAmJiB2YWx1ZSAmJiBwYXJzZXJJbnB1dC4kY2hhcignOycpKSkge1xuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5mb3JnZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyAodHJlZS5EaXJlY3RpdmUpKG5hbWUsIHZhbHVlLCBydWxlcywgaW5kZXgsIGZpbGVJbmZvLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5kdW1wTGluZU51bWJlcnMgPyBnZXREZWJ1Z0luZm8oaW5kZXgpIDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzUm9vdGVkXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcGFyc2VySW5wdXQucmVzdG9yZShcImRpcmVjdGl2ZSBvcHRpb25zIG5vdCByZWNvZ25pc2VkXCIpO1xuICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEEgVmFsdWUgaXMgYSBjb21tYS1kZWxpbWl0ZWQgbGlzdCBvZiBFeHByZXNzaW9uc1xuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vICAgICBmb250LWZhbWlseTogQmFza2VydmlsbGUsIEdlb3JnaWEsIHNlcmlmO1xuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEluIGEgUnVsZSwgYSBWYWx1ZSByZXByZXNlbnRzIGV2ZXJ5dGhpbmcgYWZ0ZXIgdGhlIGA6YCxcbiAgICAgICAgICAgIC8vIGFuZCBiZWZvcmUgdGhlIGA7YC5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBlLCBleHByZXNzaW9ucyA9IFtdO1xuXG4gICAgICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgICAgICBlID0gdGhpcy5leHByZXNzaW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9ucy5wdXNoKGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEgcGFyc2VySW5wdXQuJGNoYXIoJywnKSkgeyBicmVhazsgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSB3aGlsZSAoZSk7XG5cbiAgICAgICAgICAgICAgICBpZiAoZXhwcmVzc2lvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3KHRyZWUuVmFsdWUpKGV4cHJlc3Npb25zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaW1wb3J0YW50OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LmN1cnJlbnRDaGFyKCkgPT09ICchJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VySW5wdXQuJHJlKC9eISAqaW1wb3J0YW50Lyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN1YjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBhLCBlO1xuXG4gICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuc2F2ZSgpO1xuICAgICAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC4kY2hhcignKCcpKSB7XG4gICAgICAgICAgICAgICAgICAgIGEgPSB0aGlzLmFkZGl0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhICYmIHBhcnNlcklucHV0LiRjaGFyKCcpJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LmZvcmdldCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZSA9IG5ldyh0cmVlLkV4cHJlc3Npb24pKFthXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlLnBhcmVucyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5yZXN0b3JlKFwiRXhwZWN0ZWQgJyknXCIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LnJlc3RvcmUoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBtdWx0aXBsaWNhdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBtLCBhLCBvcCwgb3BlcmF0aW9uLCBpc1NwYWNlZDtcbiAgICAgICAgICAgICAgICBtID0gdGhpcy5vcGVyYW5kKCk7XG4gICAgICAgICAgICAgICAgaWYgKG0pIHtcbiAgICAgICAgICAgICAgICAgICAgaXNTcGFjZWQgPSBwYXJzZXJJbnB1dC5pc1doaXRlc3BhY2UoLTEpO1xuICAgICAgICAgICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LnBlZWsoL15cXC9bKlxcL10vKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5zYXZlKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIG9wID0gcGFyc2VySW5wdXQuJGNoYXIoJy8nKSB8fCBwYXJzZXJJbnB1dC4kY2hhcignKicpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9wKSB7IHBhcnNlcklucHV0LmZvcmdldCgpOyBicmVhazsgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBhID0gdGhpcy5vcGVyYW5kKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYSkgeyBwYXJzZXJJbnB1dC5yZXN0b3JlKCk7IGJyZWFrOyB9XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5mb3JnZXQoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgbS5wYXJlbnNJbk9wID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGEucGFyZW5zSW5PcCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24gPSBuZXcodHJlZS5PcGVyYXRpb24pKG9wLCBbb3BlcmF0aW9uIHx8IG0sIGFdLCBpc1NwYWNlZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc1NwYWNlZCA9IHBhcnNlcklucHV0LmlzV2hpdGVzcGFjZSgtMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9wZXJhdGlvbiB8fCBtO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhZGRpdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBtLCBhLCBvcCwgb3BlcmF0aW9uLCBpc1NwYWNlZDtcbiAgICAgICAgICAgICAgICBtID0gdGhpcy5tdWx0aXBsaWNhdGlvbigpO1xuICAgICAgICAgICAgICAgIGlmIChtKSB7XG4gICAgICAgICAgICAgICAgICAgIGlzU3BhY2VkID0gcGFyc2VySW5wdXQuaXNXaGl0ZXNwYWNlKC0xKTtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wID0gcGFyc2VySW5wdXQuJHJlKC9eWy0rXVxccysvKSB8fCAoIWlzU3BhY2VkICYmIChwYXJzZXJJbnB1dC4kY2hhcignKycpIHx8IHBhcnNlcklucHV0LiRjaGFyKCctJykpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghb3ApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGEgPSB0aGlzLm11bHRpcGxpY2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgbS5wYXJlbnNJbk9wID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGEucGFyZW5zSW5PcCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24gPSBuZXcodHJlZS5PcGVyYXRpb24pKG9wLCBbb3BlcmF0aW9uIHx8IG0sIGFdLCBpc1NwYWNlZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc1NwYWNlZCA9IHBhcnNlcklucHV0LmlzV2hpdGVzcGFjZSgtMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9wZXJhdGlvbiB8fCBtO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb25kaXRpb25zOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGEsIGIsIGluZGV4ID0gcGFyc2VySW5wdXQuaSwgY29uZGl0aW9uO1xuXG4gICAgICAgICAgICAgICAgYSA9IHRoaXMuY29uZGl0aW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKGEpIHtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcGFyc2VySW5wdXQucGVlaygvXixcXHMqKG5vdFxccyopP1xcKC8pIHx8ICFwYXJzZXJJbnB1dC4kY2hhcignLCcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBiID0gdGhpcy5jb25kaXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uID0gbmV3KHRyZWUuQ29uZGl0aW9uKSgnb3InLCBjb25kaXRpb24gfHwgYSwgYiwgaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb25kaXRpb24gfHwgYTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29uZGl0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlc3VsdCwgbG9naWNhbCwgbmV4dDtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBvcigpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlcklucHV0LiRzdHIoXCJvclwiKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXN1bHQgPSB0aGlzLmNvbmRpdGlvbkFuZCh0aGlzKTtcbiAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsb2dpY2FsID0gb3IoKTtcbiAgICAgICAgICAgICAgICBpZiAobG9naWNhbCkge1xuICAgICAgICAgICAgICAgICAgICBuZXh0ID0gdGhpcy5jb25kaXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyh0cmVlLkNvbmRpdGlvbikobG9naWNhbCwgcmVzdWx0LCBuZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb25kaXRpb25BbmQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0LCBsb2dpY2FsLCBuZXh0O1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGluc2lkZUNvbmRpdGlvbihtZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWUubmVnYXRlZENvbmRpdGlvbigpIHx8IG1lLnBhcmVudGhlc2lzQ29uZGl0aW9uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGFuZCgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlcklucHV0LiRzdHIoXCJhbmRcIik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gaW5zaWRlQ29uZGl0aW9uKHRoaXMpO1xuICAgICAgICAgICAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxvZ2ljYWwgPSBhbmQoKTtcbiAgICAgICAgICAgICAgICBpZiAobG9naWNhbCkge1xuICAgICAgICAgICAgICAgICAgICBuZXh0ID0gdGhpcy5jb25kaXRpb25BbmQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyh0cmVlLkNvbmRpdGlvbikobG9naWNhbCwgcmVzdWx0LCBuZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBuZWdhdGVkQ29uZGl0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHBhcnNlcklucHV0LiRzdHIoXCJub3RcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHRoaXMucGFyZW50aGVzaXNDb25kaXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0Lm5lZ2F0ZSA9ICFyZXN1bHQubmVnYXRlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBhcmVudGhlc2lzQ29uZGl0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gdHJ5Q29uZGl0aW9uRm9sbG93ZWRCeVBhcmVudGhlc2lzKG1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBib2R5O1xuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5zYXZlKCk7XG4gICAgICAgICAgICAgICAgICAgIGJvZHkgPSBtZS5jb25kaXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFib2R5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5yZXN0b3JlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghcGFyc2VySW5wdXQuJGNoYXIoJyknKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQucmVzdG9yZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5mb3JnZXQoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJvZHk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIGJvZHk7XG4gICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuc2F2ZSgpO1xuICAgICAgICAgICAgICAgIGlmICghcGFyc2VySW5wdXQuJHN0cihcIihcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQucmVzdG9yZSgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBib2R5ID0gdHJ5Q29uZGl0aW9uRm9sbG93ZWRCeVBhcmVudGhlc2lzKHRoaXMpO1xuICAgICAgICAgICAgICAgIGlmIChib2R5KSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcnNlcklucHV0LmZvcmdldCgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYm9keTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBib2R5ID0gdGhpcy5hdG9taWNDb25kaXRpb24oKTtcbiAgICAgICAgICAgICAgICBpZiAoIWJvZHkpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQucmVzdG9yZSgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXBhcnNlcklucHV0LiRjaGFyKCcpJykpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQucmVzdG9yZShcImV4cGVjdGVkICcpJyBnb3QgJ1wiICsgcGFyc2VySW5wdXQuY3VycmVudENoYXIoKSArIFwiJ1wiKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuZm9yZ2V0KCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJvZHk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXRvbWljQ29uZGl0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVudGl0aWVzID0gdGhpcy5lbnRpdGllcywgaW5kZXggPSBwYXJzZXJJbnB1dC5pLCBhLCBiLCBjLCBvcDtcblxuICAgICAgICAgICAgICAgIGEgPSB0aGlzLmFkZGl0aW9uKCkgfHwgZW50aXRpZXMua2V5d29yZCgpIHx8IGVudGl0aWVzLnF1b3RlZCgpO1xuICAgICAgICAgICAgICAgIGlmIChhKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC4kY2hhcignPicpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyc2VySW5wdXQuJGNoYXIoJz0nKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wID0gXCI+PVwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcCA9ICc+JztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC4kY2hhcignPCcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyc2VySW5wdXQuJGNoYXIoJz0nKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wID0gXCI8PVwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcCA9ICc8JztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZXJJbnB1dC4kY2hhcignPScpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyc2VySW5wdXQuJGNoYXIoJz4nKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wID0gXCI9PlwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJzZXJJbnB1dC4kY2hhcignPCcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3AgPSAnPTwnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcCA9ICc9JztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAob3ApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGIgPSB0aGlzLmFkZGl0aW9uKCkgfHwgZW50aXRpZXMua2V5d29yZCgpIHx8IGVudGl0aWVzLnF1b3RlZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjID0gbmV3KHRyZWUuQ29uZGl0aW9uKShvcCwgYSwgYiwgaW5kZXgsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IoJ2V4cGVjdGVkIGV4cHJlc3Npb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGMgPSBuZXcodHJlZS5Db25kaXRpb24pKCc9JywgYSwgbmV3KHRyZWUuS2V5d29yZCkoJ3RydWUnKSwgaW5kZXgsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gQW4gb3BlcmFuZCBpcyBhbnl0aGluZyB0aGF0IGNhbiBiZSBwYXJ0IG9mIGFuIG9wZXJhdGlvbixcbiAgICAgICAgICAgIC8vIHN1Y2ggYXMgYSBDb2xvciwgb3IgYSBWYXJpYWJsZVxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIG9wZXJhbmQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZW50aXRpZXMgPSB0aGlzLmVudGl0aWVzLCBuZWdhdGU7XG5cbiAgICAgICAgICAgICAgICBpZiAocGFyc2VySW5wdXQucGVlaygvXi1bQFxcKF0vKSkge1xuICAgICAgICAgICAgICAgICAgICBuZWdhdGUgPSBwYXJzZXJJbnB1dC4kY2hhcignLScpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHZhciBvID0gdGhpcy5zdWIoKSB8fCBlbnRpdGllcy5kaW1lbnNpb24oKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgZW50aXRpZXMuY29sb3IoKSB8fCBlbnRpdGllcy52YXJpYWJsZSgpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBlbnRpdGllcy5jYWxsKCkgfHwgZW50aXRpZXMuY29sb3JLZXl3b3JkKCk7XG5cbiAgICAgICAgICAgICAgICBpZiAobmVnYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIG8ucGFyZW5zSW5PcCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIG8gPSBuZXcodHJlZS5OZWdhdGl2ZSkobyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIG87XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gRXhwcmVzc2lvbnMgZWl0aGVyIHJlcHJlc2VudCBtYXRoZW1hdGljYWwgb3BlcmF0aW9ucyxcbiAgICAgICAgICAgIC8vIG9yIHdoaXRlLXNwYWNlIGRlbGltaXRlZCBFbnRpdGllcy5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyAgICAgMXB4IHNvbGlkIGJsYWNrXG4gICAgICAgICAgICAvLyAgICAgQHZhciAqIDJcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBleHByZXNzaW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVudGl0aWVzID0gW10sIGUsIGRlbGltO1xuXG4gICAgICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgICAgICBlID0gdGhpcy5jb21tZW50KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbnRpdGllcy5wdXNoKGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZSA9IHRoaXMuYWRkaXRpb24oKSB8fCB0aGlzLmVudGl0eSgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZW50aXRpZXMucHVzaChlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9wZXJhdGlvbnMgZG8gbm90IGFsbG93IGtleXdvcmQgXCIvXCIgZGltZW5zaW9uIChlLmcuIHNtYWxsLzIwcHgpIHNvIHdlIHN1cHBvcnQgdGhhdCBoZXJlXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXBhcnNlcklucHV0LnBlZWsoL15cXC9bXFwvKl0vKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGltID0gcGFyc2VySW5wdXQuJGNoYXIoJy8nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVsaW0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50aXRpZXMucHVzaChuZXcodHJlZS5Bbm9ueW1vdXMpKGRlbGltKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSB3aGlsZSAoZSk7XG4gICAgICAgICAgICAgICAgaWYgKGVudGl0aWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyh0cmVlLkV4cHJlc3Npb24pKGVudGl0aWVzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcHJvcGVydHk6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IHBhcnNlcklucHV0LiRyZSgvXihcXCo/LT9bX2EtekEtWjAtOS1dKylcXHMqOi8pO1xuICAgICAgICAgICAgICAgIGlmIChuYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuYW1lWzFdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBydWxlUHJvcGVydHk6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IFtdLCBpbmRleCA9IFtdLCBzLCBrO1xuXG4gICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuc2F2ZSgpO1xuXG4gICAgICAgICAgICAgICAgdmFyIHNpbXBsZVByb3BlcnR5ID0gcGFyc2VySW5wdXQuJHJlKC9eKFtfYS16QS1aMC05LV0rKVxccyo6Lyk7XG4gICAgICAgICAgICAgICAgaWYgKHNpbXBsZVByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWUgPSBbbmV3KHRyZWUuS2V5d29yZCkoc2ltcGxlUHJvcGVydHlbMV0pXTtcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuZm9yZ2V0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuYW1lO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG1hdGNoKHJlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gcGFyc2VySW5wdXQuaSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rID0gcGFyc2VySW5wdXQuJHJlKHJlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNodW5rKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbmRleC5wdXNoKGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hbWUucHVzaChjaHVua1sxXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBtYXRjaCgvXihcXCo/KS8pO1xuICAgICAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghbWF0Y2goL14oKD86W1xcdy1dKyl8KD86QFxce1tcXHctXStcXH0pKS8pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICgobmFtZS5sZW5ndGggPiAxKSAmJiBtYXRjaCgvXigoPzpcXCtffFxcKyk/KVxccyo6LykpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VySW5wdXQuZm9yZ2V0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gYXQgbGFzdCwgd2UgaGF2ZSB0aGUgY29tcGxldGUgbWF0Y2ggbm93LiBtb3ZlIGZvcndhcmQsXG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgbmFtZSBwYXJ0aWNsZXMgdG8gdHJlZSBvYmplY3RzIGFuZCByZXR1cm46XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lWzBdID09PSAnJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXguc2hpZnQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGsgPSAwOyBrIDwgbmFtZS5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcyA9IG5hbWVba107XG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lW2tdID0gKHMuY2hhckF0KDApICE9PSAnQCcpID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcodHJlZS5LZXl3b3JkKShzKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3KHRyZWUuVmFyaWFibGUpKCdAJyArIHMuc2xpY2UoMiwgLTEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleFtrXSwgZmlsZUluZm8pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYXJzZXJJbnB1dC5yZXN0b3JlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcblBhcnNlci5zZXJpYWxpemVWYXJzID0gZnVuY3Rpb24odmFycykge1xuICAgIHZhciBzID0gJyc7XG5cbiAgICBmb3IgKHZhciBuYW1lIGluIHZhcnMpIHtcbiAgICAgICAgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKHZhcnMsIG5hbWUpKSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSB2YXJzW25hbWVdO1xuICAgICAgICAgICAgcyArPSAoKG5hbWVbMF0gPT09ICdAJykgPyAnJyA6ICdAJykgKyBuYW1lICsgJzogJyArIHZhbHVlICtcbiAgICAgICAgICAgICAgICAoKFN0cmluZyh2YWx1ZSkuc2xpY2UoLTEpID09PSAnOycpID8gJycgOiAnOycpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHM7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBhcnNlcjtcblxufSx7XCIuLi9sZXNzLWVycm9yXCI6MzIsXCIuLi90cmVlXCI6NjIsXCIuLi91dGlsc1wiOjgzLFwiLi4vdmlzaXRvcnNcIjo4NyxcIi4vcGFyc2VyLWlucHV0XCI6Mzd9XSwzOTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4vKipcbiAqIFBsdWdpbiBNYW5hZ2VyXG4gKi9cbnZhciBQbHVnaW5NYW5hZ2VyID0gZnVuY3Rpb24obGVzcykge1xuICAgIHRoaXMubGVzcyA9IGxlc3M7XG4gICAgdGhpcy52aXNpdG9ycyA9IFtdO1xuICAgIHRoaXMucHJlUHJvY2Vzc29ycyA9IFtdO1xuICAgIHRoaXMucG9zdFByb2Nlc3NvcnMgPSBbXTtcbiAgICB0aGlzLmluc3RhbGxlZFBsdWdpbnMgPSBbXTtcbiAgICB0aGlzLmZpbGVNYW5hZ2VycyA9IFtdO1xufTtcbi8qKlxuICogQWRkcyBhbGwgdGhlIHBsdWdpbnMgaW4gdGhlIGFycmF5XG4gKiBAcGFyYW0ge0FycmF5fSBwbHVnaW5zXG4gKi9cblBsdWdpbk1hbmFnZXIucHJvdG90eXBlLmFkZFBsdWdpbnMgPSBmdW5jdGlvbihwbHVnaW5zKSB7XG4gICAgaWYgKHBsdWdpbnMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwbHVnaW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLmFkZFBsdWdpbihwbHVnaW5zW2ldKTtcbiAgICAgICAgfVxuICAgIH1cbn07XG4vKipcbiAqXG4gKiBAcGFyYW0gcGx1Z2luXG4gKi9cblBsdWdpbk1hbmFnZXIucHJvdG90eXBlLmFkZFBsdWdpbiA9IGZ1bmN0aW9uKHBsdWdpbikge1xuICAgIHRoaXMuaW5zdGFsbGVkUGx1Z2lucy5wdXNoKHBsdWdpbik7XG4gICAgcGx1Z2luLmluc3RhbGwodGhpcy5sZXNzLCB0aGlzKTtcbn07XG4vKipcbiAqIEFkZHMgYSB2aXNpdG9yLiBUaGUgdmlzaXRvciBvYmplY3QgaGFzIG9wdGlvbnMgb24gaXRzZWxmIHRvIGRldGVybWluZVxuICogd2hlbiBpdCBzaG91bGQgcnVuLlxuICogQHBhcmFtIHZpc2l0b3JcbiAqL1xuUGx1Z2luTWFuYWdlci5wcm90b3R5cGUuYWRkVmlzaXRvciA9IGZ1bmN0aW9uKHZpc2l0b3IpIHtcbiAgICB0aGlzLnZpc2l0b3JzLnB1c2godmlzaXRvcik7XG59O1xuLyoqXG4gKiBBZGRzIGEgcHJlIHByb2Nlc3NvciBvYmplY3RcbiAqIEBwYXJhbSB7b2JqZWN0fSBwcmVQcm9jZXNzb3JcbiAqIEBwYXJhbSB7bnVtYmVyfSBwcmlvcml0eSAtIGd1aWRlbGluZXMgMSA9IGJlZm9yZSBpbXBvcnQsIDEwMDAgPSBpbXBvcnQsIDIwMDAgPSBhZnRlciBpbXBvcnRcbiAqL1xuUGx1Z2luTWFuYWdlci5wcm90b3R5cGUuYWRkUHJlUHJvY2Vzc29yID0gZnVuY3Rpb24ocHJlUHJvY2Vzc29yLCBwcmlvcml0eSkge1xuICAgIHZhciBpbmRleFRvSW5zZXJ0QXQ7XG4gICAgZm9yIChpbmRleFRvSW5zZXJ0QXQgPSAwOyBpbmRleFRvSW5zZXJ0QXQgPCB0aGlzLnByZVByb2Nlc3NvcnMubGVuZ3RoOyBpbmRleFRvSW5zZXJ0QXQrKykge1xuICAgICAgICBpZiAodGhpcy5wcmVQcm9jZXNzb3JzW2luZGV4VG9JbnNlcnRBdF0ucHJpb3JpdHkgPj0gcHJpb3JpdHkpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIHRoaXMucHJlUHJvY2Vzc29ycy5zcGxpY2UoaW5kZXhUb0luc2VydEF0LCAwLCB7cHJlUHJvY2Vzc29yOiBwcmVQcm9jZXNzb3IsIHByaW9yaXR5OiBwcmlvcml0eX0pO1xufTtcbi8qKlxuICogQWRkcyBhIHBvc3QgcHJvY2Vzc29yIG9iamVjdFxuICogQHBhcmFtIHtvYmplY3R9IHBvc3RQcm9jZXNzb3JcbiAqIEBwYXJhbSB7bnVtYmVyfSBwcmlvcml0eSAtIGd1aWRlbGluZXMgMSA9IGJlZm9yZSBjb21wcmVzc2lvbiwgMTAwMCA9IGNvbXByZXNzaW9uLCAyMDAwID0gYWZ0ZXIgY29tcHJlc3Npb25cbiAqL1xuUGx1Z2luTWFuYWdlci5wcm90b3R5cGUuYWRkUG9zdFByb2Nlc3NvciA9IGZ1bmN0aW9uKHBvc3RQcm9jZXNzb3IsIHByaW9yaXR5KSB7XG4gICAgdmFyIGluZGV4VG9JbnNlcnRBdDtcbiAgICBmb3IgKGluZGV4VG9JbnNlcnRBdCA9IDA7IGluZGV4VG9JbnNlcnRBdCA8IHRoaXMucG9zdFByb2Nlc3NvcnMubGVuZ3RoOyBpbmRleFRvSW5zZXJ0QXQrKykge1xuICAgICAgICBpZiAodGhpcy5wb3N0UHJvY2Vzc29yc1tpbmRleFRvSW5zZXJ0QXRdLnByaW9yaXR5ID49IHByaW9yaXR5KSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnBvc3RQcm9jZXNzb3JzLnNwbGljZShpbmRleFRvSW5zZXJ0QXQsIDAsIHtwb3N0UHJvY2Vzc29yOiBwb3N0UHJvY2Vzc29yLCBwcmlvcml0eTogcHJpb3JpdHl9KTtcbn07XG4vKipcbiAqXG4gKiBAcGFyYW0gbWFuYWdlclxuICovXG5QbHVnaW5NYW5hZ2VyLnByb3RvdHlwZS5hZGRGaWxlTWFuYWdlciA9IGZ1bmN0aW9uKG1hbmFnZXIpIHtcbiAgICB0aGlzLmZpbGVNYW5hZ2Vycy5wdXNoKG1hbmFnZXIpO1xufTtcbi8qKlxuICpcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqIEBwcml2YXRlXG4gKi9cblBsdWdpbk1hbmFnZXIucHJvdG90eXBlLmdldFByZVByb2Nlc3NvcnMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgcHJlUHJvY2Vzc29ycyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wcmVQcm9jZXNzb3JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHByZVByb2Nlc3NvcnMucHVzaCh0aGlzLnByZVByb2Nlc3NvcnNbaV0ucHJlUHJvY2Vzc29yKTtcbiAgICB9XG4gICAgcmV0dXJuIHByZVByb2Nlc3NvcnM7XG59O1xuLyoqXG4gKlxuICogQHJldHVybnMge0FycmF5fVxuICogQHByaXZhdGVcbiAqL1xuUGx1Z2luTWFuYWdlci5wcm90b3R5cGUuZ2V0UG9zdFByb2Nlc3NvcnMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgcG9zdFByb2Nlc3NvcnMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucG9zdFByb2Nlc3NvcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcG9zdFByb2Nlc3NvcnMucHVzaCh0aGlzLnBvc3RQcm9jZXNzb3JzW2ldLnBvc3RQcm9jZXNzb3IpO1xuICAgIH1cbiAgICByZXR1cm4gcG9zdFByb2Nlc3NvcnM7XG59O1xuLyoqXG4gKlxuICogQHJldHVybnMge0FycmF5fVxuICogQHByaXZhdGVcbiAqL1xuUGx1Z2luTWFuYWdlci5wcm90b3R5cGUuZ2V0VmlzaXRvcnMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy52aXNpdG9ycztcbn07XG4vKipcbiAqXG4gKiBAcmV0dXJucyB7QXJyYXl9XG4gKiBAcHJpdmF0ZVxuICovXG5QbHVnaW5NYW5hZ2VyLnByb3RvdHlwZS5nZXRGaWxlTWFuYWdlcnMgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5maWxlTWFuYWdlcnM7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBQbHVnaW5NYW5hZ2VyO1xuXG59LHt9XSw0MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgTGVzc0Vycm9yID0gcmVxdWlyZSgnLi4vbGVzcy1lcnJvcicpLFxuICAgIHRyZWUgPSByZXF1aXJlKFwiLi4vdHJlZVwiKTtcblxudmFyIEZ1bmN0aW9uSW1wb3J0ZXIgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIEZ1bmN0aW9uSW1wb3J0ZXIoY29udGV4dCwgZmlsZUluZm8pIHtcbiAgICB0aGlzLmZpbGVJbmZvID0gZmlsZUluZm87XG59O1xuXG5GdW5jdGlvbkltcG9ydGVyLnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24oY29udGVudHMsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGxvYWRlZCA9IHt9LFxuICAgICAgICBsb2FkZXIsXG4gICAgICAgIHJlZ2lzdHJ5O1xuXG4gICAgcmVnaXN0cnkgPSB7XG4gICAgICAgIGFkZDogZnVuY3Rpb24obmFtZSwgZnVuYykge1xuICAgICAgICAgICAgbG9hZGVkW25hbWVdID0gZnVuYztcbiAgICAgICAgfSxcbiAgICAgICAgYWRkTXVsdGlwbGU6IGZ1bmN0aW9uKGZ1bmN0aW9ucykge1xuICAgICAgICAgICAgT2JqZWN0LmtleXMoZnVuY3Rpb25zKS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgICAgICAgICBsb2FkZWRbbmFtZV0gPSBmdW5jdGlvbnNbbmFtZV07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgICBsb2FkZXIgPSBuZXcgRnVuY3Rpb24oXCJmdW5jdGlvbnNcIiwgXCJ0cmVlXCIsIFwiZmlsZUluZm9cIiwgY29udGVudHMpO1xuICAgICAgICBsb2FkZXIocmVnaXN0cnksIHRyZWUsIHRoaXMuZmlsZUluZm8pO1xuICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBjYWxsYmFjayhuZXcgTGVzc0Vycm9yKHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IFwiUGx1Z2luIGV2YWx1YXRpb24gZXJyb3I6ICdcIiArIGUubmFtZSArICc6ICcgKyBlLm1lc3NhZ2UucmVwbGFjZSgvW1wiXS9nLCBcIidcIikgKyBcIidcIiAsXG4gICAgICAgICAgICBmaWxlbmFtZTogdGhpcy5maWxlSW5mby5maWxlbmFtZVxuICAgICAgICB9KSwgbnVsbCApO1xuICAgIH1cblxuICAgIGNhbGxiYWNrKG51bGwsIHsgZnVuY3Rpb25zOiBsb2FkZWQgfSk7XG59O1xuXG59LHtcIi4uL2xlc3MtZXJyb3JcIjozMixcIi4uL3RyZWVcIjo2Mn1dLDQxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBQcm9taXNlQ29uc3RydWN0b3I7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZW52aXJvbm1lbnQsIFBhcnNlVHJlZSwgSW1wb3J0TWFuYWdlcikge1xuICAgIHZhciByZW5kZXIgPSBmdW5jdGlvbiAoaW5wdXQsIG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FsbGJhY2sgPSBvcHRpb25zO1xuICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFjYWxsYmFjaykge1xuICAgICAgICAgICAgaWYgKCFQcm9taXNlQ29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgICBQcm9taXNlQ29uc3RydWN0b3IgPSB0eXBlb2YgUHJvbWlzZSA9PT0gJ3VuZGVmaW5lZCcgPyByZXF1aXJlKCdwcm9taXNlJykgOiBQcm9taXNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlQ29uc3RydWN0b3IoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgICAgIHJlbmRlci5jYWxsKHNlbGYsIGlucHV0LCBvcHRpb25zLCBmdW5jdGlvbihlcnIsIG91dHB1dCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUob3V0cHV0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnBhcnNlKGlucHV0LCBvcHRpb25zLCBmdW5jdGlvbihlcnIsIHJvb3QsIGltcG9ydHMsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyKSB7IHJldHVybiBjYWxsYmFjayhlcnIpOyB9XG5cbiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0O1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJzZVRyZWUgPSBuZXcgUGFyc2VUcmVlKHJvb3QsIGltcG9ydHMpO1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBwYXJzZVRyZWUudG9DU1Mob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHsgcmV0dXJuIGNhbGxiYWNrKGVycik7IH1cblxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHJlc3VsdCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gcmVuZGVyO1xufTtcblxufSx7XCJwcm9taXNlXCI6dW5kZWZpbmVkfV0sNDI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoU291cmNlTWFwT3V0cHV0LCBlbnZpcm9ubWVudCkge1xuXG4gICAgdmFyIFNvdXJjZU1hcEJ1aWxkZXIgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIH07XG5cbiAgICBTb3VyY2VNYXBCdWlsZGVyLnByb3RvdHlwZS50b0NTUyA9IGZ1bmN0aW9uKHJvb3ROb2RlLCBvcHRpb25zLCBpbXBvcnRzKSB7XG4gICAgICAgIHZhciBzb3VyY2VNYXBPdXRwdXQgPSBuZXcgU291cmNlTWFwT3V0cHV0KFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbnRlbnRzSWdub3JlZENoYXJzTWFwOiBpbXBvcnRzLmNvbnRlbnRzSWdub3JlZENoYXJzLFxuICAgICAgICAgICAgICAgIHJvb3ROb2RlOiByb290Tm9kZSxcbiAgICAgICAgICAgICAgICBjb250ZW50c01hcDogaW1wb3J0cy5jb250ZW50cyxcbiAgICAgICAgICAgICAgICBzb3VyY2VNYXBGaWxlbmFtZTogdGhpcy5vcHRpb25zLnNvdXJjZU1hcEZpbGVuYW1lLFxuICAgICAgICAgICAgICAgIHNvdXJjZU1hcFVSTDogdGhpcy5vcHRpb25zLnNvdXJjZU1hcFVSTCxcbiAgICAgICAgICAgICAgICBvdXRwdXRGaWxlbmFtZTogdGhpcy5vcHRpb25zLnNvdXJjZU1hcE91dHB1dEZpbGVuYW1lLFxuICAgICAgICAgICAgICAgIHNvdXJjZU1hcEJhc2VwYXRoOiB0aGlzLm9wdGlvbnMuc291cmNlTWFwQmFzZXBhdGgsXG4gICAgICAgICAgICAgICAgc291cmNlTWFwUm9vdHBhdGg6IHRoaXMub3B0aW9ucy5zb3VyY2VNYXBSb290cGF0aCxcbiAgICAgICAgICAgICAgICBvdXRwdXRTb3VyY2VGaWxlczogdGhpcy5vcHRpb25zLm91dHB1dFNvdXJjZUZpbGVzLFxuICAgICAgICAgICAgICAgIHNvdXJjZU1hcEdlbmVyYXRvcjogdGhpcy5vcHRpb25zLnNvdXJjZU1hcEdlbmVyYXRvcixcbiAgICAgICAgICAgICAgICBzb3VyY2VNYXBGaWxlSW5saW5lOiB0aGlzLm9wdGlvbnMuc291cmNlTWFwRmlsZUlubGluZVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIGNzcyA9IHNvdXJjZU1hcE91dHB1dC50b0NTUyhvcHRpb25zKTtcbiAgICAgICAgdGhpcy5zb3VyY2VNYXAgPSBzb3VyY2VNYXBPdXRwdXQuc291cmNlTWFwO1xuICAgICAgICB0aGlzLnNvdXJjZU1hcFVSTCA9IHNvdXJjZU1hcE91dHB1dC5zb3VyY2VNYXBVUkw7XG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc291cmNlTWFwSW5wdXRGaWxlbmFtZSkge1xuICAgICAgICAgICAgdGhpcy5zb3VyY2VNYXBJbnB1dEZpbGVuYW1lID0gc291cmNlTWFwT3V0cHV0Lm5vcm1hbGl6ZUZpbGVuYW1lKHRoaXMub3B0aW9ucy5zb3VyY2VNYXBJbnB1dEZpbGVuYW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY3NzICsgdGhpcy5nZXRDU1NBcHBlbmRhZ2UoKTtcbiAgICB9O1xuXG4gICAgU291cmNlTWFwQnVpbGRlci5wcm90b3R5cGUuZ2V0Q1NTQXBwZW5kYWdlID0gZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgdmFyIHNvdXJjZU1hcFVSTCA9IHRoaXMuc291cmNlTWFwVVJMO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNvdXJjZU1hcEZpbGVJbmxpbmUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNvdXJjZU1hcCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzb3VyY2VNYXBVUkwgPSBcImRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsXCIgKyBlbnZpcm9ubWVudC5lbmNvZGVCYXNlNjQodGhpcy5zb3VyY2VNYXApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNvdXJjZU1hcFVSTCkge1xuICAgICAgICAgICAgcmV0dXJuIFwiLyojIHNvdXJjZU1hcHBpbmdVUkw9XCIgKyBzb3VyY2VNYXBVUkwgKyBcIiAqL1wiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBcIlwiO1xuICAgIH07XG5cbiAgICBTb3VyY2VNYXBCdWlsZGVyLnByb3RvdHlwZS5nZXRFeHRlcm5hbFNvdXJjZU1hcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zb3VyY2VNYXA7XG4gICAgfTtcbiAgICBTb3VyY2VNYXBCdWlsZGVyLnByb3RvdHlwZS5zZXRFeHRlcm5hbFNvdXJjZU1hcCA9IGZ1bmN0aW9uKHNvdXJjZU1hcCkge1xuICAgICAgICB0aGlzLnNvdXJjZU1hcCA9IHNvdXJjZU1hcDtcbiAgICB9O1xuXG4gICAgU291cmNlTWFwQnVpbGRlci5wcm90b3R5cGUuaXNJbmxpbmUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5zb3VyY2VNYXBGaWxlSW5saW5lO1xuICAgIH07XG4gICAgU291cmNlTWFwQnVpbGRlci5wcm90b3R5cGUuZ2V0U291cmNlTWFwVVJMID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNvdXJjZU1hcFVSTDtcbiAgICB9O1xuICAgIFNvdXJjZU1hcEJ1aWxkZXIucHJvdG90eXBlLmdldE91dHB1dEZpbGVuYW1lID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuc291cmNlTWFwT3V0cHV0RmlsZW5hbWU7XG4gICAgfTtcbiAgICBTb3VyY2VNYXBCdWlsZGVyLnByb3RvdHlwZS5nZXRJbnB1dEZpbGVuYW1lID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNvdXJjZU1hcElucHV0RmlsZW5hbWU7XG4gICAgfTtcblxuICAgIHJldHVybiBTb3VyY2VNYXBCdWlsZGVyO1xufTtcblxufSx7fV0sNDM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZW52aXJvbm1lbnQpIHtcblxuICAgIHZhciBTb3VyY2VNYXBPdXRwdXQgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICB0aGlzLl9jc3MgPSBbXTtcbiAgICAgICAgdGhpcy5fcm9vdE5vZGUgPSBvcHRpb25zLnJvb3ROb2RlO1xuICAgICAgICB0aGlzLl9jb250ZW50c01hcCA9IG9wdGlvbnMuY29udGVudHNNYXA7XG4gICAgICAgIHRoaXMuX2NvbnRlbnRzSWdub3JlZENoYXJzTWFwID0gb3B0aW9ucy5jb250ZW50c0lnbm9yZWRDaGFyc01hcDtcbiAgICAgICAgaWYgKG9wdGlvbnMuc291cmNlTWFwRmlsZW5hbWUpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZU1hcEZpbGVuYW1lID0gb3B0aW9ucy5zb3VyY2VNYXBGaWxlbmFtZS5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fb3V0cHV0RmlsZW5hbWUgPSBvcHRpb25zLm91dHB1dEZpbGVuYW1lO1xuICAgICAgICB0aGlzLnNvdXJjZU1hcFVSTCA9IG9wdGlvbnMuc291cmNlTWFwVVJMO1xuICAgICAgICBpZiAob3B0aW9ucy5zb3VyY2VNYXBCYXNlcGF0aCkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlTWFwQmFzZXBhdGggPSBvcHRpb25zLnNvdXJjZU1hcEJhc2VwYXRoLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0aW9ucy5zb3VyY2VNYXBSb290cGF0aCkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlTWFwUm9vdHBhdGggPSBvcHRpb25zLnNvdXJjZU1hcFJvb3RwYXRoLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zb3VyY2VNYXBSb290cGF0aC5jaGFyQXQodGhpcy5fc291cmNlTWFwUm9vdHBhdGgubGVuZ3RoIC0gMSkgIT09ICcvJykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NvdXJjZU1hcFJvb3RwYXRoICs9ICcvJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZU1hcFJvb3RwYXRoID0gXCJcIjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9vdXRwdXRTb3VyY2VGaWxlcyA9IG9wdGlvbnMub3V0cHV0U291cmNlRmlsZXM7XG4gICAgICAgIHRoaXMuX3NvdXJjZU1hcEdlbmVyYXRvckNvbnN0cnVjdG9yID0gZW52aXJvbm1lbnQuZ2V0U291cmNlTWFwR2VuZXJhdG9yKCk7XG5cbiAgICAgICAgdGhpcy5fbGluZU51bWJlciA9IDA7XG4gICAgICAgIHRoaXMuX2NvbHVtbiA9IDA7XG4gICAgfTtcblxuICAgIFNvdXJjZU1hcE91dHB1dC5wcm90b3R5cGUubm9ybWFsaXplRmlsZW5hbWUgPSBmdW5jdGlvbihmaWxlbmFtZSkge1xuICAgICAgICBmaWxlbmFtZSA9IGZpbGVuYW1lLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcblxuICAgICAgICBpZiAodGhpcy5fc291cmNlTWFwQmFzZXBhdGggJiYgZmlsZW5hbWUuaW5kZXhPZih0aGlzLl9zb3VyY2VNYXBCYXNlcGF0aCkgPT09IDApIHtcbiAgICAgICAgICAgIGZpbGVuYW1lID0gZmlsZW5hbWUuc3Vic3RyaW5nKHRoaXMuX3NvdXJjZU1hcEJhc2VwYXRoLmxlbmd0aCk7XG4gICAgICAgICAgICBpZiAoZmlsZW5hbWUuY2hhckF0KDApID09PSAnXFxcXCcgfHwgZmlsZW5hbWUuY2hhckF0KDApID09PSAnLycpIHtcbiAgICAgICAgICAgICAgICBmaWxlbmFtZSA9IGZpbGVuYW1lLnN1YnN0cmluZygxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKHRoaXMuX3NvdXJjZU1hcFJvb3RwYXRoIHx8IFwiXCIpICsgZmlsZW5hbWU7XG4gICAgfTtcblxuICAgIFNvdXJjZU1hcE91dHB1dC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24oY2h1bmssIGZpbGVJbmZvLCBpbmRleCwgbWFwTGluZXMpIHtcblxuICAgICAgICAvL2lnbm9yZSBhZGRpbmcgZW1wdHkgc3RyaW5nc1xuICAgICAgICBpZiAoIWNodW5rKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbGluZXMsXG4gICAgICAgICAgICBzb3VyY2VMaW5lcyxcbiAgICAgICAgICAgIGNvbHVtbnMsXG4gICAgICAgICAgICBzb3VyY2VDb2x1bW5zLFxuICAgICAgICAgICAgaTtcblxuICAgICAgICBpZiAoZmlsZUluZm8pIHtcbiAgICAgICAgICAgIHZhciBpbnB1dFNvdXJjZSA9IHRoaXMuX2NvbnRlbnRzTWFwW2ZpbGVJbmZvLmZpbGVuYW1lXTtcblxuICAgICAgICAgICAgLy8gcmVtb3ZlIHZhcnMvYmFubmVyIGFkZGVkIHRvIHRoZSB0b3Agb2YgdGhlIGZpbGVcbiAgICAgICAgICAgIGlmICh0aGlzLl9jb250ZW50c0lnbm9yZWRDaGFyc01hcFtmaWxlSW5mby5maWxlbmFtZV0pIHtcbiAgICAgICAgICAgICAgICAvLyBhZGp1c3QgdGhlIGluZGV4XG4gICAgICAgICAgICAgICAgaW5kZXggLT0gdGhpcy5fY29udGVudHNJZ25vcmVkQ2hhcnNNYXBbZmlsZUluZm8uZmlsZW5hbWVdO1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCA8IDApIHsgaW5kZXggPSAwOyB9XG4gICAgICAgICAgICAgICAgLy8gYWRqdXN0IHRoZSBzb3VyY2VcbiAgICAgICAgICAgICAgICBpbnB1dFNvdXJjZSA9IGlucHV0U291cmNlLnNsaWNlKHRoaXMuX2NvbnRlbnRzSWdub3JlZENoYXJzTWFwW2ZpbGVJbmZvLmZpbGVuYW1lXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbnB1dFNvdXJjZSA9IGlucHV0U291cmNlLnN1YnN0cmluZygwLCBpbmRleCk7XG4gICAgICAgICAgICBzb3VyY2VMaW5lcyA9IGlucHV0U291cmNlLnNwbGl0KFwiXFxuXCIpO1xuICAgICAgICAgICAgc291cmNlQ29sdW1ucyA9IHNvdXJjZUxpbmVzW3NvdXJjZUxpbmVzLmxlbmd0aCAtIDFdO1xuICAgICAgICB9XG5cbiAgICAgICAgbGluZXMgPSBjaHVuay5zcGxpdChcIlxcblwiKTtcbiAgICAgICAgY29sdW1ucyA9IGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdO1xuXG4gICAgICAgIGlmIChmaWxlSW5mbykge1xuICAgICAgICAgICAgaWYgKCFtYXBMaW5lcykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NvdXJjZU1hcEdlbmVyYXRvci5hZGRNYXBwaW5nKHsgZ2VuZXJhdGVkOiB7IGxpbmU6IHRoaXMuX2xpbmVOdW1iZXIgKyAxLCBjb2x1bW46IHRoaXMuX2NvbHVtbn0sXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsOiB7IGxpbmU6IHNvdXJjZUxpbmVzLmxlbmd0aCwgY29sdW1uOiBzb3VyY2VDb2x1bW5zLmxlbmd0aH0sXG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZTogdGhpcy5ub3JtYWxpemVGaWxlbmFtZShmaWxlSW5mby5maWxlbmFtZSl9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NvdXJjZU1hcEdlbmVyYXRvci5hZGRNYXBwaW5nKHsgZ2VuZXJhdGVkOiB7IGxpbmU6IHRoaXMuX2xpbmVOdW1iZXIgKyBpICsgMSwgY29sdW1uOiBpID09PSAwID8gdGhpcy5fY29sdW1uIDogMH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbDogeyBsaW5lOiBzb3VyY2VMaW5lcy5sZW5ndGggKyBpLCBjb2x1bW46IGkgPT09IDAgPyBzb3VyY2VDb2x1bW5zLmxlbmd0aCA6IDB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlOiB0aGlzLm5vcm1hbGl6ZUZpbGVuYW1lKGZpbGVJbmZvLmZpbGVuYW1lKX0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsaW5lcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHRoaXMuX2NvbHVtbiArPSBjb2x1bW5zLmxlbmd0aDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2xpbmVOdW1iZXIgKz0gbGluZXMubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgIHRoaXMuX2NvbHVtbiA9IGNvbHVtbnMubGVuZ3RoO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fY3NzLnB1c2goY2h1bmspO1xuICAgIH07XG5cbiAgICBTb3VyY2VNYXBPdXRwdXQucHJvdG90eXBlLmlzRW1wdHkgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nzcy5sZW5ndGggPT09IDA7XG4gICAgfTtcblxuICAgIFNvdXJjZU1hcE91dHB1dC5wcm90b3R5cGUudG9DU1MgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgICAgIHRoaXMuX3NvdXJjZU1hcEdlbmVyYXRvciA9IG5ldyB0aGlzLl9zb3VyY2VNYXBHZW5lcmF0b3JDb25zdHJ1Y3Rvcih7IGZpbGU6IHRoaXMuX291dHB1dEZpbGVuYW1lLCBzb3VyY2VSb290OiBudWxsIH0pO1xuXG4gICAgICAgIGlmICh0aGlzLl9vdXRwdXRTb3VyY2VGaWxlcykge1xuICAgICAgICAgICAgZm9yICh2YXIgZmlsZW5hbWUgaW4gdGhpcy5fY29udGVudHNNYXApIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fY29udGVudHNNYXAuaGFzT3duUHJvcGVydHkoZmlsZW5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzb3VyY2UgPSB0aGlzLl9jb250ZW50c01hcFtmaWxlbmFtZV07XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jb250ZW50c0lnbm9yZWRDaGFyc01hcFtmaWxlbmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZSA9IHNvdXJjZS5zbGljZSh0aGlzLl9jb250ZW50c0lnbm9yZWRDaGFyc01hcFtmaWxlbmFtZV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NvdXJjZU1hcEdlbmVyYXRvci5zZXRTb3VyY2VDb250ZW50KHRoaXMubm9ybWFsaXplRmlsZW5hbWUoZmlsZW5hbWUpLCBzb3VyY2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3Jvb3ROb2RlLmdlbkNTUyhjb250ZXh0LCB0aGlzKTtcblxuICAgICAgICBpZiAodGhpcy5fY3NzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHZhciBzb3VyY2VNYXBVUkwsXG4gICAgICAgICAgICAgICAgc291cmNlTWFwQ29udGVudCA9IEpTT04uc3RyaW5naWZ5KHRoaXMuX3NvdXJjZU1hcEdlbmVyYXRvci50b0pTT04oKSk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnNvdXJjZU1hcFVSTCkge1xuICAgICAgICAgICAgICAgIHNvdXJjZU1hcFVSTCA9IHRoaXMuc291cmNlTWFwVVJMO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9zb3VyY2VNYXBGaWxlbmFtZSkge1xuICAgICAgICAgICAgICAgIHNvdXJjZU1hcFVSTCA9IHRoaXMuX3NvdXJjZU1hcEZpbGVuYW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zb3VyY2VNYXBVUkwgPSBzb3VyY2VNYXBVUkw7XG5cbiAgICAgICAgICAgIHRoaXMuc291cmNlTWFwID0gc291cmNlTWFwQ29udGVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLl9jc3Muam9pbignJyk7XG4gICAgfTtcblxuICAgIHJldHVybiBTb3VyY2VNYXBPdXRwdXQ7XG59O1xuXG59LHt9XSw0NDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgY29udGV4dHMgPSByZXF1aXJlKFwiLi9jb250ZXh0c1wiKSxcbiAgICB2aXNpdG9yID0gcmVxdWlyZShcIi4vdmlzaXRvcnNcIiksXG4gICAgdHJlZSA9IHJlcXVpcmUoXCIuL3RyZWVcIik7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ocm9vdCwgb3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgIHZhciBldmFsZFJvb3QsXG4gICAgICAgIHZhcmlhYmxlcyA9IG9wdGlvbnMudmFyaWFibGVzLFxuICAgICAgICBldmFsRW52ID0gbmV3IGNvbnRleHRzLkV2YWwob3B0aW9ucyk7XG5cbiAgICAvL1xuICAgIC8vIEFsbG93cyBzZXR0aW5nIHZhcmlhYmxlcyB3aXRoIGEgaGFzaCwgc286XG4gICAgLy9cbiAgICAvLyAgIGB7IGNvbG9yOiBuZXcgdHJlZS5Db2xvcignI2YwMScpIH1gIHdpbGwgYmVjb21lOlxuICAgIC8vXG4gICAgLy8gICBuZXcgdHJlZS5SdWxlKCdAY29sb3InLFxuICAgIC8vICAgICBuZXcgdHJlZS5WYWx1ZShbXG4gICAgLy8gICAgICAgbmV3IHRyZWUuRXhwcmVzc2lvbihbXG4gICAgLy8gICAgICAgICBuZXcgdHJlZS5Db2xvcignI2YwMScpXG4gICAgLy8gICAgICAgXSlcbiAgICAvLyAgICAgXSlcbiAgICAvLyAgIClcbiAgICAvL1xuICAgIGlmICh0eXBlb2YgdmFyaWFibGVzID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheSh2YXJpYWJsZXMpKSB7XG4gICAgICAgIHZhcmlhYmxlcyA9IE9iamVjdC5rZXlzKHZhcmlhYmxlcykubWFwKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSB2YXJpYWJsZXNba107XG5cbiAgICAgICAgICAgIGlmICghICh2YWx1ZSBpbnN0YW5jZW9mIHRyZWUuVmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEgKHZhbHVlIGluc3RhbmNlb2YgdHJlZS5FeHByZXNzaW9uKSkge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IG5ldyB0cmVlLkV4cHJlc3Npb24oW3ZhbHVlXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhbHVlID0gbmV3IHRyZWUuVmFsdWUoW3ZhbHVlXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmV3IHRyZWUuUnVsZSgnQCcgKyBrLCB2YWx1ZSwgZmFsc2UsIG51bGwsIDApO1xuICAgICAgICB9KTtcbiAgICAgICAgZXZhbEVudi5mcmFtZXMgPSBbbmV3IHRyZWUuUnVsZXNldChudWxsLCB2YXJpYWJsZXMpXTtcbiAgICB9XG5cbiAgICB2YXIgcHJlRXZhbFZpc2l0b3JzID0gW10sXG4gICAgICAgIHZpc2l0b3JzID0gW1xuICAgICAgICAgICAgbmV3IHZpc2l0b3IuSm9pblNlbGVjdG9yVmlzaXRvcigpLFxuICAgICAgICAgICAgbmV3IHZpc2l0b3IuTWFya1Zpc2libGVTZWxlY3RvcnNWaXNpdG9yKHRydWUpLFxuICAgICAgICAgICAgbmV3IHZpc2l0b3IuRXh0ZW5kVmlzaXRvcigpLFxuICAgICAgICAgICAgbmV3IHZpc2l0b3IuVG9DU1NWaXNpdG9yKHtjb21wcmVzczogQm9vbGVhbihvcHRpb25zLmNvbXByZXNzKX0pXG4gICAgICAgIF0sIGk7XG5cbiAgICBpZiAob3B0aW9ucy5wbHVnaW5NYW5hZ2VyKSB7XG4gICAgICAgIHZhciBwbHVnaW5WaXNpdG9ycyA9IG9wdGlvbnMucGx1Z2luTWFuYWdlci5nZXRWaXNpdG9ycygpO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcGx1Z2luVmlzaXRvcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBwbHVnaW5WaXNpdG9yID0gcGx1Z2luVmlzaXRvcnNbaV07XG4gICAgICAgICAgICBpZiAocGx1Z2luVmlzaXRvci5pc1ByZUV2YWxWaXNpdG9yKSB7XG4gICAgICAgICAgICAgICAgcHJlRXZhbFZpc2l0b3JzLnB1c2gocGx1Z2luVmlzaXRvcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChwbHVnaW5WaXNpdG9yLmlzUHJlVmlzaXRvcikge1xuICAgICAgICAgICAgICAgICAgICB2aXNpdG9ycy5zcGxpY2UoMCwgMCwgcGx1Z2luVmlzaXRvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmlzaXRvcnMucHVzaChwbHVnaW5WaXNpdG9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgcHJlRXZhbFZpc2l0b3JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHByZUV2YWxWaXNpdG9yc1tpXS5ydW4ocm9vdCk7XG4gICAgfVxuXG4gICAgZXZhbGRSb290ID0gcm9vdC5ldmFsKGV2YWxFbnYpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IHZpc2l0b3JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZpc2l0b3JzW2ldLnJ1bihldmFsZFJvb3QpO1xuICAgIH1cblxuICAgIHJldHVybiBldmFsZFJvb3Q7XG59O1xuXG59LHtcIi4vY29udGV4dHNcIjoxMSxcIi4vdHJlZVwiOjYyLFwiLi92aXNpdG9yc1wiOjg3fV0sNDU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIE5vZGUgPSByZXF1aXJlKFwiLi9ub2RlXCIpO1xuXG52YXIgQWxwaGEgPSBmdW5jdGlvbiAodmFsKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbDtcbn07XG5BbHBoYS5wcm90b3R5cGUgPSBuZXcgTm9kZSgpO1xuQWxwaGEucHJvdG90eXBlLnR5cGUgPSBcIkFscGhhXCI7XG5cbkFscGhhLnByb3RvdHlwZS5hY2NlcHQgPSBmdW5jdGlvbiAodmlzaXRvcikge1xuICAgIHRoaXMudmFsdWUgPSB2aXNpdG9yLnZpc2l0KHRoaXMudmFsdWUpO1xufTtcbkFscGhhLnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICBpZiAodGhpcy52YWx1ZS5ldmFsKSB7IHJldHVybiBuZXcgQWxwaGEodGhpcy52YWx1ZS5ldmFsKGNvbnRleHQpKTsgfVxuICAgIHJldHVybiB0aGlzO1xufTtcbkFscGhhLnByb3RvdHlwZS5nZW5DU1MgPSBmdW5jdGlvbiAoY29udGV4dCwgb3V0cHV0KSB7XG4gICAgb3V0cHV0LmFkZChcImFscGhhKG9wYWNpdHk9XCIpO1xuXG4gICAgaWYgKHRoaXMudmFsdWUuZ2VuQ1NTKSB7XG4gICAgICAgIHRoaXMudmFsdWUuZ2VuQ1NTKGNvbnRleHQsIG91dHB1dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0LmFkZCh0aGlzLnZhbHVlKTtcbiAgICB9XG5cbiAgICBvdXRwdXQuYWRkKFwiKVwiKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQWxwaGE7XG5cbn0se1wiLi9ub2RlXCI6NzB9XSw0NjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgTm9kZSA9IHJlcXVpcmUoXCIuL25vZGVcIik7XG5cbnZhciBBbm9ueW1vdXMgPSBmdW5jdGlvbiAodmFsdWUsIGluZGV4LCBjdXJyZW50RmlsZUluZm8sIG1hcExpbmVzLCBydWxlc2V0TGlrZSwgdmlzaWJpbGl0eUluZm8pIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy5pbmRleCA9IGluZGV4O1xuICAgIHRoaXMubWFwTGluZXMgPSBtYXBMaW5lcztcbiAgICB0aGlzLmN1cnJlbnRGaWxlSW5mbyA9IGN1cnJlbnRGaWxlSW5mbztcbiAgICB0aGlzLnJ1bGVzZXRMaWtlID0gKHR5cGVvZiBydWxlc2V0TGlrZSA9PT0gJ3VuZGVmaW5lZCcpID8gZmFsc2UgOiBydWxlc2V0TGlrZTtcbiAgICB0aGlzLmFsbG93Um9vdCA9IHRydWU7XG4gICAgdGhpcy5jb3B5VmlzaWJpbGl0eUluZm8odmlzaWJpbGl0eUluZm8pO1xufTtcbkFub255bW91cy5wcm90b3R5cGUgPSBuZXcgTm9kZSgpO1xuQW5vbnltb3VzLnByb3RvdHlwZS50eXBlID0gXCJBbm9ueW1vdXNcIjtcbkFub255bW91cy5wcm90b3R5cGUuZXZhbCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbmV3IEFub255bW91cyh0aGlzLnZhbHVlLCB0aGlzLmluZGV4LCB0aGlzLmN1cnJlbnRGaWxlSW5mbywgdGhpcy5tYXBMaW5lcywgdGhpcy5ydWxlc2V0TGlrZSwgdGhpcy52aXNpYmlsaXR5SW5mbygpKTtcbn07XG5Bbm9ueW1vdXMucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgICByZXR1cm4gb3RoZXIudG9DU1MgJiYgdGhpcy50b0NTUygpID09PSBvdGhlci50b0NTUygpID8gMCA6IHVuZGVmaW5lZDtcbn07XG5Bbm9ueW1vdXMucHJvdG90eXBlLmlzUnVsZXNldExpa2UgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5ydWxlc2V0TGlrZTtcbn07XG5Bbm9ueW1vdXMucHJvdG90eXBlLmdlbkNTUyA9IGZ1bmN0aW9uIChjb250ZXh0LCBvdXRwdXQpIHtcbiAgICBvdXRwdXQuYWRkKHRoaXMudmFsdWUsIHRoaXMuY3VycmVudEZpbGVJbmZvLCB0aGlzLmluZGV4LCB0aGlzLm1hcExpbmVzKTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IEFub255bW91cztcblxufSx7XCIuL25vZGVcIjo3MH1dLDQ3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBOb2RlID0gcmVxdWlyZShcIi4vbm9kZVwiKTtcblxudmFyIEFzc2lnbm1lbnQgPSBmdW5jdGlvbiAoa2V5LCB2YWwpIHtcbiAgICB0aGlzLmtleSA9IGtleTtcbiAgICB0aGlzLnZhbHVlID0gdmFsO1xufTtcblxuQXNzaWdubWVudC5wcm90b3R5cGUgPSBuZXcgTm9kZSgpO1xuQXNzaWdubWVudC5wcm90b3R5cGUudHlwZSA9IFwiQXNzaWdubWVudFwiO1xuQXNzaWdubWVudC5wcm90b3R5cGUuYWNjZXB0ID0gZnVuY3Rpb24gKHZpc2l0b3IpIHtcbiAgICB0aGlzLnZhbHVlID0gdmlzaXRvci52aXNpdCh0aGlzLnZhbHVlKTtcbn07XG5Bc3NpZ25tZW50LnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICBpZiAodGhpcy52YWx1ZS5ldmFsKSB7XG4gICAgICAgIHJldHVybiBuZXcgQXNzaWdubWVudCh0aGlzLmtleSwgdGhpcy52YWx1ZS5ldmFsKGNvbnRleHQpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuQXNzaWdubWVudC5wcm90b3R5cGUuZ2VuQ1NTID0gZnVuY3Rpb24gKGNvbnRleHQsIG91dHB1dCkge1xuICAgIG91dHB1dC5hZGQodGhpcy5rZXkgKyAnPScpO1xuICAgIGlmICh0aGlzLnZhbHVlLmdlbkNTUykge1xuICAgICAgICB0aGlzLnZhbHVlLmdlbkNTUyhjb250ZXh0LCBvdXRwdXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIG91dHB1dC5hZGQodGhpcy52YWx1ZSk7XG4gICAgfVxufTtcbm1vZHVsZS5leHBvcnRzID0gQXNzaWdubWVudDtcblxufSx7XCIuL25vZGVcIjo3MH1dLDQ4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBOb2RlID0gcmVxdWlyZShcIi4vbm9kZVwiKTtcblxudmFyIEF0dHJpYnV0ZSA9IGZ1bmN0aW9uIChrZXksIG9wLCB2YWx1ZSkge1xuICAgIHRoaXMua2V5ID0ga2V5O1xuICAgIHRoaXMub3AgPSBvcDtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG59O1xuQXR0cmlidXRlLnByb3RvdHlwZSA9IG5ldyBOb2RlKCk7XG5BdHRyaWJ1dGUucHJvdG90eXBlLnR5cGUgPSBcIkF0dHJpYnV0ZVwiO1xuQXR0cmlidXRlLnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZSh0aGlzLmtleS5ldmFsID8gdGhpcy5rZXkuZXZhbChjb250ZXh0KSA6IHRoaXMua2V5LFxuICAgICAgICB0aGlzLm9wLCAodGhpcy52YWx1ZSAmJiB0aGlzLnZhbHVlLmV2YWwpID8gdGhpcy52YWx1ZS5ldmFsKGNvbnRleHQpIDogdGhpcy52YWx1ZSk7XG59O1xuQXR0cmlidXRlLnByb3RvdHlwZS5nZW5DU1MgPSBmdW5jdGlvbiAoY29udGV4dCwgb3V0cHV0KSB7XG4gICAgb3V0cHV0LmFkZCh0aGlzLnRvQ1NTKGNvbnRleHQpKTtcbn07XG5BdHRyaWJ1dGUucHJvdG90eXBlLnRvQ1NTID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLmtleS50b0NTUyA/IHRoaXMua2V5LnRvQ1NTKGNvbnRleHQpIDogdGhpcy5rZXk7XG5cbiAgICBpZiAodGhpcy5vcCkge1xuICAgICAgICB2YWx1ZSArPSB0aGlzLm9wO1xuICAgICAgICB2YWx1ZSArPSAodGhpcy52YWx1ZS50b0NTUyA/IHRoaXMudmFsdWUudG9DU1MoY29udGV4dCkgOiB0aGlzLnZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gJ1snICsgdmFsdWUgKyAnXSc7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBBdHRyaWJ1dGU7XG5cbn0se1wiLi9ub2RlXCI6NzB9XSw0OTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgTm9kZSA9IHJlcXVpcmUoXCIuL25vZGVcIiksXG4gICAgRnVuY3Rpb25DYWxsZXIgPSByZXF1aXJlKFwiLi4vZnVuY3Rpb25zL2Z1bmN0aW9uLWNhbGxlclwiKTtcbi8vXG4vLyBBIGZ1bmN0aW9uIGNhbGwgbm9kZS5cbi8vXG52YXIgQ2FsbCA9IGZ1bmN0aW9uIChuYW1lLCBhcmdzLCBpbmRleCwgY3VycmVudEZpbGVJbmZvKSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLmFyZ3MgPSBhcmdzO1xuICAgIHRoaXMuaW5kZXggPSBpbmRleDtcbiAgICB0aGlzLmN1cnJlbnRGaWxlSW5mbyA9IGN1cnJlbnRGaWxlSW5mbztcbn07XG5DYWxsLnByb3RvdHlwZSA9IG5ldyBOb2RlKCk7XG5DYWxsLnByb3RvdHlwZS50eXBlID0gXCJDYWxsXCI7XG5DYWxsLnByb3RvdHlwZS5hY2NlcHQgPSBmdW5jdGlvbiAodmlzaXRvcikge1xuICAgIGlmICh0aGlzLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5hcmdzID0gdmlzaXRvci52aXNpdEFycmF5KHRoaXMuYXJncyk7XG4gICAgfVxufTtcbi8vXG4vLyBXaGVuIGV2YWx1YXRpbmcgYSBmdW5jdGlvbiBjYWxsLFxuLy8gd2UgZWl0aGVyIGZpbmQgdGhlIGZ1bmN0aW9uIGluIHRoZSBmdW5jdGlvblJlZ2lzdHJ5LFxuLy8gaW4gd2hpY2ggY2FzZSB3ZSBjYWxsIGl0LCBwYXNzaW5nIHRoZSAgZXZhbHVhdGVkIGFyZ3VtZW50cyxcbi8vIGlmIHRoaXMgcmV0dXJucyBudWxsIG9yIHdlIGNhbm5vdCBmaW5kIHRoZSBmdW5jdGlvbiwgd2Vcbi8vIHNpbXBseSBwcmludCBpdCBvdXQgYXMgaXQgYXBwZWFyZWQgb3JpZ2luYWxseSBbMl0uXG4vL1xuLy8gVGhlIHJlYXNvbiB3aHkgd2UgZXZhbHVhdGUgdGhlIGFyZ3VtZW50cywgaXMgaW4gdGhlIGNhc2Ugd2hlcmVcbi8vIHdlIHRyeSB0byBwYXNzIGEgdmFyaWFibGUgdG8gYSBmdW5jdGlvbiwgbGlrZTogYHNhdHVyYXRlKEBjb2xvcilgLlxuLy8gVGhlIGZ1bmN0aW9uIHNob3VsZCByZWNlaXZlIHRoZSB2YWx1ZSwgbm90IHRoZSB2YXJpYWJsZS5cbi8vXG5DYWxsLnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgYXJncyA9IHRoaXMuYXJncy5tYXAoZnVuY3Rpb24gKGEpIHsgcmV0dXJuIGEuZXZhbChjb250ZXh0KTsgfSksXG4gICAgICAgIHJlc3VsdCwgZnVuY0NhbGxlciA9IG5ldyBGdW5jdGlvbkNhbGxlcih0aGlzLm5hbWUsIGNvbnRleHQsIHRoaXMuaW5kZXgsIHRoaXMuY3VycmVudEZpbGVJbmZvKTtcblxuICAgIGlmIChmdW5jQ2FsbGVyLmlzVmFsaWQoKSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmVzdWx0ID0gZnVuY0NhbGxlci5jYWxsKGFyZ3MpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0aHJvdyB7IHR5cGU6IGUudHlwZSB8fCBcIlJ1bnRpbWVcIixcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogXCJlcnJvciBldmFsdWF0aW5nIGZ1bmN0aW9uIGBcIiArIHRoaXMubmFtZSArIFwiYFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGUubWVzc2FnZSA/ICc6ICcgKyBlLm1lc3NhZ2UgOiAnJyksXG4gICAgICAgICAgICAgICAgICAgIGluZGV4OiB0aGlzLmluZGV4LCBmaWxlbmFtZTogdGhpcy5jdXJyZW50RmlsZUluZm8uZmlsZW5hbWUgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmVzdWx0LmluZGV4ID0gdGhpcy5pbmRleDtcbiAgICAgICAgICAgIHJlc3VsdC5jdXJyZW50RmlsZUluZm8gPSB0aGlzLmN1cnJlbnRGaWxlSW5mbztcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IENhbGwodGhpcy5uYW1lLCBhcmdzLCB0aGlzLmluZGV4LCB0aGlzLmN1cnJlbnRGaWxlSW5mbyk7XG59O1xuQ2FsbC5wcm90b3R5cGUuZ2VuQ1NTID0gZnVuY3Rpb24gKGNvbnRleHQsIG91dHB1dCkge1xuICAgIG91dHB1dC5hZGQodGhpcy5uYW1lICsgXCIoXCIsIHRoaXMuY3VycmVudEZpbGVJbmZvLCB0aGlzLmluZGV4KTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5hcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMuYXJnc1tpXS5nZW5DU1MoY29udGV4dCwgb3V0cHV0KTtcbiAgICAgICAgaWYgKGkgKyAxIDwgdGhpcy5hcmdzLmxlbmd0aCkge1xuICAgICAgICAgICAgb3V0cHV0LmFkZChcIiwgXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb3V0cHV0LmFkZChcIilcIik7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBDYWxsO1xuXG59LHtcIi4uL2Z1bmN0aW9ucy9mdW5jdGlvbi1jYWxsZXJcIjoyMSxcIi4vbm9kZVwiOjcwfV0sNTA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIE5vZGUgPSByZXF1aXJlKFwiLi9ub2RlXCIpLFxuICAgIGNvbG9ycyA9IHJlcXVpcmUoXCIuLi9kYXRhL2NvbG9yc1wiKTtcblxuLy9cbi8vIFJHQiBDb2xvcnMgLSAjZmYwMDE0LCAjZWVlXG4vL1xudmFyIENvbG9yID0gZnVuY3Rpb24gKHJnYiwgYSwgb3JpZ2luYWxGb3JtKSB7XG4gICAgLy9cbiAgICAvLyBUaGUgZW5kIGdvYWwgaGVyZSwgaXMgdG8gcGFyc2UgdGhlIGFyZ3VtZW50c1xuICAgIC8vIGludG8gYW4gaW50ZWdlciB0cmlwbGV0LCBzdWNoIGFzIGAxMjgsIDI1NSwgMGBcbiAgICAvL1xuICAgIC8vIFRoaXMgZmFjaWxpdGF0ZXMgb3BlcmF0aW9ucyBhbmQgY29udmVyc2lvbnMuXG4gICAgLy9cbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZ2IpKSB7XG4gICAgICAgIHRoaXMucmdiID0gcmdiO1xuICAgIH0gZWxzZSBpZiAocmdiLmxlbmd0aCA9PSA2KSB7XG4gICAgICAgIHRoaXMucmdiID0gcmdiLm1hdGNoKC8uezJ9L2cpLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KGMsIDE2KTtcbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZ2IgPSByZ2Iuc3BsaXQoJycpLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KGMgKyBjLCAxNik7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLmFscGhhID0gdHlwZW9mIGEgPT09ICdudW1iZXInID8gYSA6IDE7XG4gICAgaWYgKHR5cGVvZiBvcmlnaW5hbEZvcm0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBvcmlnaW5hbEZvcm07XG4gICAgfVxufTtcblxuQ29sb3IucHJvdG90eXBlID0gbmV3IE5vZGUoKTtcbkNvbG9yLnByb3RvdHlwZS50eXBlID0gXCJDb2xvclwiO1xuXG5mdW5jdGlvbiBjbGFtcCh2LCBtYXgpIHtcbiAgICByZXR1cm4gTWF0aC5taW4oTWF0aC5tYXgodiwgMCksIG1heCk7XG59XG5cbmZ1bmN0aW9uIHRvSGV4KHYpIHtcbiAgICByZXR1cm4gJyMnICsgdi5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgYyA9IGNsYW1wKE1hdGgucm91bmQoYyksIDI1NSk7XG4gICAgICAgIHJldHVybiAoYyA8IDE2ID8gJzAnIDogJycpICsgYy50b1N0cmluZygxNik7XG4gICAgfSkuam9pbignJyk7XG59XG5cbkNvbG9yLnByb3RvdHlwZS5sdW1hID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciByID0gdGhpcy5yZ2JbMF0gLyAyNTUsXG4gICAgICAgIGcgPSB0aGlzLnJnYlsxXSAvIDI1NSxcbiAgICAgICAgYiA9IHRoaXMucmdiWzJdIC8gMjU1O1xuXG4gICAgciA9IChyIDw9IDAuMDM5MjgpID8gciAvIDEyLjkyIDogTWF0aC5wb3coKChyICsgMC4wNTUpIC8gMS4wNTUpLCAyLjQpO1xuICAgIGcgPSAoZyA8PSAwLjAzOTI4KSA/IGcgLyAxMi45MiA6IE1hdGgucG93KCgoZyArIDAuMDU1KSAvIDEuMDU1KSwgMi40KTtcbiAgICBiID0gKGIgPD0gMC4wMzkyOCkgPyBiIC8gMTIuOTIgOiBNYXRoLnBvdygoKGIgKyAwLjA1NSkgLyAxLjA1NSksIDIuNCk7XG5cbiAgICByZXR1cm4gMC4yMTI2ICogciArIDAuNzE1MiAqIGcgKyAwLjA3MjIgKiBiO1xufTtcbkNvbG9yLnByb3RvdHlwZS5nZW5DU1MgPSBmdW5jdGlvbiAoY29udGV4dCwgb3V0cHV0KSB7XG4gICAgb3V0cHV0LmFkZCh0aGlzLnRvQ1NTKGNvbnRleHQpKTtcbn07XG5Db2xvci5wcm90b3R5cGUudG9DU1MgPSBmdW5jdGlvbiAoY29udGV4dCwgZG9Ob3RDb21wcmVzcykge1xuICAgIHZhciBjb21wcmVzcyA9IGNvbnRleHQgJiYgY29udGV4dC5jb21wcmVzcyAmJiAhZG9Ob3RDb21wcmVzcywgY29sb3IsIGFscGhhO1xuXG4gICAgLy8gYHZhbHVlYCBpcyBzZXQgaWYgdGhpcyBjb2xvciB3YXMgb3JpZ2luYWxseVxuICAgIC8vIGNvbnZlcnRlZCBmcm9tIGEgbmFtZWQgY29sb3Igc3RyaW5nIHNvIHdlIG5lZWRcbiAgICAvLyB0byByZXNwZWN0IHRoaXMgYW5kIHRyeSB0byBvdXRwdXQgbmFtZWQgY29sb3IgdG9vLlxuICAgIGlmICh0aGlzLnZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICAgIH1cblxuICAgIC8vIElmIHdlIGhhdmUgc29tZSB0cmFuc3BhcmVuY3ksIHRoZSBvbmx5IHdheSB0byByZXByZXNlbnQgaXRcbiAgICAvLyBpcyB2aWEgYHJnYmFgLiBPdGhlcndpc2UsIHdlIHVzZSB0aGUgaGV4IHJlcHJlc2VudGF0aW9uLFxuICAgIC8vIHdoaWNoIGhhcyBiZXR0ZXIgY29tcGF0aWJpbGl0eSB3aXRoIG9sZGVyIGJyb3dzZXJzLlxuICAgIC8vIFZhbHVlcyBhcmUgY2FwcGVkIGJldHdlZW4gYDBgIGFuZCBgMjU1YCwgcm91bmRlZCBhbmQgemVyby1wYWRkZWQuXG4gICAgYWxwaGEgPSB0aGlzLmZyb3VuZChjb250ZXh0LCB0aGlzLmFscGhhKTtcbiAgICBpZiAoYWxwaGEgPCAxKSB7XG4gICAgICAgIHJldHVybiBcInJnYmEoXCIgKyB0aGlzLnJnYi5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgIHJldHVybiBjbGFtcChNYXRoLnJvdW5kKGMpLCAyNTUpO1xuICAgICAgICB9KS5jb25jYXQoY2xhbXAoYWxwaGEsIDEpKVxuICAgICAgICAgICAgLmpvaW4oJywnICsgKGNvbXByZXNzID8gJycgOiAnICcpKSArIFwiKVwiO1xuICAgIH1cblxuICAgIGNvbG9yID0gdGhpcy50b1JHQigpO1xuXG4gICAgaWYgKGNvbXByZXNzKSB7XG4gICAgICAgIHZhciBzcGxpdGNvbG9yID0gY29sb3Iuc3BsaXQoJycpO1xuXG4gICAgICAgIC8vIENvbnZlcnQgY29sb3IgdG8gc2hvcnQgZm9ybWF0XG4gICAgICAgIGlmIChzcGxpdGNvbG9yWzFdID09PSBzcGxpdGNvbG9yWzJdICYmIHNwbGl0Y29sb3JbM10gPT09IHNwbGl0Y29sb3JbNF0gJiYgc3BsaXRjb2xvcls1XSA9PT0gc3BsaXRjb2xvcls2XSkge1xuICAgICAgICAgICAgY29sb3IgPSAnIycgKyBzcGxpdGNvbG9yWzFdICsgc3BsaXRjb2xvclszXSArIHNwbGl0Y29sb3JbNV07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY29sb3I7XG59O1xuXG4vL1xuLy8gT3BlcmF0aW9ucyBoYXZlIHRvIGJlIGRvbmUgcGVyLWNoYW5uZWwsIGlmIG5vdCxcbi8vIGNoYW5uZWxzIHdpbGwgc3BpbGwgb250byBlYWNoIG90aGVyLiBPbmNlIHdlIGhhdmVcbi8vIG91ciByZXN1bHQsIGluIHRoZSBmb3JtIG9mIGFuIGludGVnZXIgdHJpcGxldCxcbi8vIHdlIGNyZWF0ZSBhIG5ldyBDb2xvciBub2RlIHRvIGhvbGQgdGhlIHJlc3VsdC5cbi8vXG5Db2xvci5wcm90b3R5cGUub3BlcmF0ZSA9IGZ1bmN0aW9uIChjb250ZXh0LCBvcCwgb3RoZXIpIHtcbiAgICB2YXIgcmdiID0gW107XG4gICAgdmFyIGFscGhhID0gdGhpcy5hbHBoYSAqICgxIC0gb3RoZXIuYWxwaGEpICsgb3RoZXIuYWxwaGE7XG4gICAgZm9yICh2YXIgYyA9IDA7IGMgPCAzOyBjKyspIHtcbiAgICAgICAgcmdiW2NdID0gdGhpcy5fb3BlcmF0ZShjb250ZXh0LCBvcCwgdGhpcy5yZ2JbY10sIG90aGVyLnJnYltjXSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQ29sb3IocmdiLCBhbHBoYSk7XG59O1xuQ29sb3IucHJvdG90eXBlLnRvUkdCID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0b0hleCh0aGlzLnJnYik7XG59O1xuQ29sb3IucHJvdG90eXBlLnRvSFNMID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciByID0gdGhpcy5yZ2JbMF0gLyAyNTUsXG4gICAgICAgIGcgPSB0aGlzLnJnYlsxXSAvIDI1NSxcbiAgICAgICAgYiA9IHRoaXMucmdiWzJdIC8gMjU1LFxuICAgICAgICBhID0gdGhpcy5hbHBoYTtcblxuICAgIHZhciBtYXggPSBNYXRoLm1heChyLCBnLCBiKSwgbWluID0gTWF0aC5taW4ociwgZywgYik7XG4gICAgdmFyIGgsIHMsIGwgPSAobWF4ICsgbWluKSAvIDIsIGQgPSBtYXggLSBtaW47XG5cbiAgICBpZiAobWF4ID09PSBtaW4pIHtcbiAgICAgICAgaCA9IHMgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHMgPSBsID4gMC41ID8gZCAvICgyIC0gbWF4IC0gbWluKSA6IGQgLyAobWF4ICsgbWluKTtcblxuICAgICAgICBzd2l0Y2ggKG1heCkge1xuICAgICAgICAgICAgY2FzZSByOiBoID0gKGcgLSBiKSAvIGQgKyAoZyA8IGIgPyA2IDogMCk7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBnOiBoID0gKGIgLSByKSAvIGQgKyAyOyAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBiOiBoID0gKHIgLSBnKSAvIGQgKyA0OyAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGggLz0gNjtcbiAgICB9XG4gICAgcmV0dXJuIHsgaDogaCAqIDM2MCwgczogcywgbDogbCwgYTogYSB9O1xufTtcbi8vQWRhcHRlZCBmcm9tIGh0dHA6Ly9tamlqYWNrc29uLmNvbS8yMDA4LzAyL3JnYi10by1oc2wtYW5kLXJnYi10by1oc3YtY29sb3ItbW9kZWwtY29udmVyc2lvbi1hbGdvcml0aG1zLWluLWphdmFzY3JpcHRcbkNvbG9yLnByb3RvdHlwZS50b0hTViA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgciA9IHRoaXMucmdiWzBdIC8gMjU1LFxuICAgICAgICBnID0gdGhpcy5yZ2JbMV0gLyAyNTUsXG4gICAgICAgIGIgPSB0aGlzLnJnYlsyXSAvIDI1NSxcbiAgICAgICAgYSA9IHRoaXMuYWxwaGE7XG5cbiAgICB2YXIgbWF4ID0gTWF0aC5tYXgociwgZywgYiksIG1pbiA9IE1hdGgubWluKHIsIGcsIGIpO1xuICAgIHZhciBoLCBzLCB2ID0gbWF4O1xuXG4gICAgdmFyIGQgPSBtYXggLSBtaW47XG4gICAgaWYgKG1heCA9PT0gMCkge1xuICAgICAgICBzID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBzID0gZCAvIG1heDtcbiAgICB9XG5cbiAgICBpZiAobWF4ID09PSBtaW4pIHtcbiAgICAgICAgaCA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgc3dpdGNoKG1heCkge1xuICAgICAgICAgICAgY2FzZSByOiBoID0gKGcgLSBiKSAvIGQgKyAoZyA8IGIgPyA2IDogMCk7IGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBnOiBoID0gKGIgLSByKSAvIGQgKyAyOyBicmVhaztcbiAgICAgICAgICAgIGNhc2UgYjogaCA9IChyIC0gZykgLyBkICsgNDsgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaCAvPSA2O1xuICAgIH1cbiAgICByZXR1cm4geyBoOiBoICogMzYwLCBzOiBzLCB2OiB2LCBhOiBhIH07XG59O1xuQ29sb3IucHJvdG90eXBlLnRvQVJHQiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdG9IZXgoW3RoaXMuYWxwaGEgKiAyNTVdLmNvbmNhdCh0aGlzLnJnYikpO1xufTtcbkNvbG9yLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gKHgpIHtcbiAgICByZXR1cm4gKHgucmdiICYmXG4gICAgICAgIHgucmdiWzBdID09PSB0aGlzLnJnYlswXSAmJlxuICAgICAgICB4LnJnYlsxXSA9PT0gdGhpcy5yZ2JbMV0gJiZcbiAgICAgICAgeC5yZ2JbMl0gPT09IHRoaXMucmdiWzJdICYmXG4gICAgICAgIHguYWxwaGEgID09PSB0aGlzLmFscGhhKSA/IDAgOiB1bmRlZmluZWQ7XG59O1xuXG5Db2xvci5mcm9tS2V5d29yZCA9IGZ1bmN0aW9uKGtleXdvcmQpIHtcbiAgICB2YXIgYywga2V5ID0ga2V5d29yZC50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChjb2xvcnMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICBjID0gbmV3IENvbG9yKGNvbG9yc1trZXldLnNsaWNlKDEpKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoa2V5ID09PSBcInRyYW5zcGFyZW50XCIpIHtcbiAgICAgICAgYyA9IG5ldyBDb2xvcihbMCwgMCwgMF0sIDApO1xuICAgIH1cblxuICAgIGlmIChjKSB7XG4gICAgICAgIGMudmFsdWUgPSBrZXl3b3JkO1xuICAgICAgICByZXR1cm4gYztcbiAgICB9XG59O1xubW9kdWxlLmV4cG9ydHMgPSBDb2xvcjtcblxufSx7XCIuLi9kYXRhL2NvbG9yc1wiOjEyLFwiLi9ub2RlXCI6NzB9XSw1MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgTm9kZSA9IHJlcXVpcmUoXCIuL25vZGVcIik7XG5cbnZhciBDb21iaW5hdG9yID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09PSAnICcpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9ICcgJztcbiAgICAgICAgdGhpcy5lbXB0eU9yV2hpdGVzcGFjZSA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlID8gdmFsdWUudHJpbSgpIDogXCJcIjtcbiAgICAgICAgdGhpcy5lbXB0eU9yV2hpdGVzcGFjZSA9IHRoaXMudmFsdWUgPT09IFwiXCI7XG4gICAgfVxufTtcbkNvbWJpbmF0b3IucHJvdG90eXBlID0gbmV3IE5vZGUoKTtcbkNvbWJpbmF0b3IucHJvdG90eXBlLnR5cGUgPSBcIkNvbWJpbmF0b3JcIjtcbnZhciBfbm9TcGFjZUNvbWJpbmF0b3JzID0ge1xuICAgICcnOiB0cnVlLFxuICAgICcgJzogdHJ1ZSxcbiAgICAnfCc6IHRydWVcbn07XG5Db21iaW5hdG9yLnByb3RvdHlwZS5nZW5DU1MgPSBmdW5jdGlvbiAoY29udGV4dCwgb3V0cHV0KSB7XG4gICAgdmFyIHNwYWNlT3JFbXB0eSA9IChjb250ZXh0LmNvbXByZXNzIHx8IF9ub1NwYWNlQ29tYmluYXRvcnNbdGhpcy52YWx1ZV0pID8gJycgOiAnICc7XG4gICAgb3V0cHV0LmFkZChzcGFjZU9yRW1wdHkgKyB0aGlzLnZhbHVlICsgc3BhY2VPckVtcHR5KTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IENvbWJpbmF0b3I7XG5cbn0se1wiLi9ub2RlXCI6NzB9XSw1MjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgTm9kZSA9IHJlcXVpcmUoXCIuL25vZGVcIiksXG4gICAgZ2V0RGVidWdJbmZvID0gcmVxdWlyZShcIi4vZGVidWctaW5mb1wiKTtcblxudmFyIENvbW1lbnQgPSBmdW5jdGlvbiAodmFsdWUsIGlzTGluZUNvbW1lbnQsIGluZGV4LCBjdXJyZW50RmlsZUluZm8pIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy5pc0xpbmVDb21tZW50ID0gaXNMaW5lQ29tbWVudDtcbiAgICB0aGlzLmN1cnJlbnRGaWxlSW5mbyA9IGN1cnJlbnRGaWxlSW5mbztcbiAgICB0aGlzLmFsbG93Um9vdCA9IHRydWU7XG59O1xuQ29tbWVudC5wcm90b3R5cGUgPSBuZXcgTm9kZSgpO1xuQ29tbWVudC5wcm90b3R5cGUudHlwZSA9IFwiQ29tbWVudFwiO1xuQ29tbWVudC5wcm90b3R5cGUuZ2VuQ1NTID0gZnVuY3Rpb24gKGNvbnRleHQsIG91dHB1dCkge1xuICAgIGlmICh0aGlzLmRlYnVnSW5mbykge1xuICAgICAgICBvdXRwdXQuYWRkKGdldERlYnVnSW5mbyhjb250ZXh0LCB0aGlzKSwgdGhpcy5jdXJyZW50RmlsZUluZm8sIHRoaXMuaW5kZXgpO1xuICAgIH1cbiAgICBvdXRwdXQuYWRkKHRoaXMudmFsdWUpO1xufTtcbkNvbW1lbnQucHJvdG90eXBlLmlzU2lsZW50ID0gZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBpc0NvbXByZXNzZWQgPSBjb250ZXh0LmNvbXByZXNzICYmIHRoaXMudmFsdWVbMl0gIT09IFwiIVwiO1xuICAgIHJldHVybiB0aGlzLmlzTGluZUNvbW1lbnQgfHwgaXNDb21wcmVzc2VkO1xufTtcbm1vZHVsZS5leHBvcnRzID0gQ29tbWVudDtcblxufSx7XCIuL2RlYnVnLWluZm9cIjo1NCxcIi4vbm9kZVwiOjcwfV0sNTM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIE5vZGUgPSByZXF1aXJlKFwiLi9ub2RlXCIpO1xuXG52YXIgQ29uZGl0aW9uID0gZnVuY3Rpb24gKG9wLCBsLCByLCBpLCBuZWdhdGUpIHtcbiAgICB0aGlzLm9wID0gb3AudHJpbSgpO1xuICAgIHRoaXMubHZhbHVlID0gbDtcbiAgICB0aGlzLnJ2YWx1ZSA9IHI7XG4gICAgdGhpcy5pbmRleCA9IGk7XG4gICAgdGhpcy5uZWdhdGUgPSBuZWdhdGU7XG59O1xuQ29uZGl0aW9uLnByb3RvdHlwZSA9IG5ldyBOb2RlKCk7XG5Db25kaXRpb24ucHJvdG90eXBlLnR5cGUgPSBcIkNvbmRpdGlvblwiO1xuQ29uZGl0aW9uLnByb3RvdHlwZS5hY2NlcHQgPSBmdW5jdGlvbiAodmlzaXRvcikge1xuICAgIHRoaXMubHZhbHVlID0gdmlzaXRvci52aXNpdCh0aGlzLmx2YWx1ZSk7XG4gICAgdGhpcy5ydmFsdWUgPSB2aXNpdG9yLnZpc2l0KHRoaXMucnZhbHVlKTtcbn07XG5Db25kaXRpb24ucHJvdG90eXBlLmV2YWwgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHZhciByZXN1bHQgPSAoZnVuY3Rpb24gKG9wLCBhLCBiKSB7XG4gICAgICAgIHN3aXRjaCAob3ApIHtcbiAgICAgICAgICAgIGNhc2UgJ2FuZCc6IHJldHVybiBhICYmIGI7XG4gICAgICAgICAgICBjYXNlICdvcic6ICByZXR1cm4gYSB8fCBiO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKE5vZGUuY29tcGFyZShhLCBiKSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIC0xOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9wID09PSAnPCcgfHwgb3AgPT09ICc9PCcgfHwgb3AgPT09ICc8PSc7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvcCA9PT0gJz0nIHx8IG9wID09PSAnPj0nIHx8IG9wID09PSAnPTwnIHx8IG9wID09PSAnPD0nO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3AgPT09ICc+JyB8fCBvcCA9PT0gJz49JztcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KSh0aGlzLm9wLCB0aGlzLmx2YWx1ZS5ldmFsKGNvbnRleHQpLCB0aGlzLnJ2YWx1ZS5ldmFsKGNvbnRleHQpKTtcblxuICAgIHJldHVybiB0aGlzLm5lZ2F0ZSA/ICFyZXN1bHQgOiByZXN1bHQ7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBDb25kaXRpb247XG5cbn0se1wiLi9ub2RlXCI6NzB9XSw1NDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgZGVidWdJbmZvID0gZnVuY3Rpb24oY29udGV4dCwgY3R4LCBsaW5lU2VwYXJhdG9yKSB7XG4gICAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgaWYgKGNvbnRleHQuZHVtcExpbmVOdW1iZXJzICYmICFjb250ZXh0LmNvbXByZXNzKSB7XG4gICAgICAgIHN3aXRjaChjb250ZXh0LmR1bXBMaW5lTnVtYmVycykge1xuICAgICAgICAgICAgY2FzZSAnY29tbWVudHMnOlxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRlYnVnSW5mby5hc0NvbW1lbnQoY3R4KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21lZGlhcXVlcnknOlxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRlYnVnSW5mby5hc01lZGlhUXVlcnkoY3R4KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2FsbCc6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gZGVidWdJbmZvLmFzQ29tbWVudChjdHgpICsgKGxpbmVTZXBhcmF0b3IgfHwgXCJcIikgKyBkZWJ1Z0luZm8uYXNNZWRpYVF1ZXJ5KGN0eCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbmRlYnVnSW5mby5hc0NvbW1lbnQgPSBmdW5jdGlvbihjdHgpIHtcbiAgICByZXR1cm4gJy8qIGxpbmUgJyArIGN0eC5kZWJ1Z0luZm8ubGluZU51bWJlciArICcsICcgKyBjdHguZGVidWdJbmZvLmZpbGVOYW1lICsgJyAqL1xcbic7XG59O1xuXG5kZWJ1Z0luZm8uYXNNZWRpYVF1ZXJ5ID0gZnVuY3Rpb24oY3R4KSB7XG4gICAgdmFyIGZpbGVuYW1lV2l0aFByb3RvY29sID0gY3R4LmRlYnVnSW5mby5maWxlTmFtZTtcbiAgICBpZiAoIS9eW2Etel0rOlxcL1xcLy9pLnRlc3QoZmlsZW5hbWVXaXRoUHJvdG9jb2wpKSB7XG4gICAgICAgIGZpbGVuYW1lV2l0aFByb3RvY29sID0gJ2ZpbGU6Ly8nICsgZmlsZW5hbWVXaXRoUHJvdG9jb2w7XG4gICAgfVxuICAgIHJldHVybiAnQG1lZGlhIC1zYXNzLWRlYnVnLWluZm97ZmlsZW5hbWV7Zm9udC1mYW1pbHk6JyArXG4gICAgICAgIGZpbGVuYW1lV2l0aFByb3RvY29sLnJlcGxhY2UoLyhbLjpcXC9cXFxcXSkvZywgZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICAgIGlmIChhID09ICdcXFxcJykge1xuICAgICAgICAgICAgICAgIGEgPSAnXFwvJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAnXFxcXCcgKyBhO1xuICAgICAgICB9KSArXG4gICAgICAgICd9bGluZXtmb250LWZhbWlseTpcXFxcMDAwMDMnICsgY3R4LmRlYnVnSW5mby5saW5lTnVtYmVyICsgJ319XFxuJztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZGVidWdJbmZvO1xuXG59LHt9XSw1NTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgTm9kZSA9IHJlcXVpcmUoXCIuL25vZGVcIiksXG4gICAgY29udGV4dHMgPSByZXF1aXJlKFwiLi4vY29udGV4dHNcIik7XG5cbnZhciBEZXRhY2hlZFJ1bGVzZXQgPSBmdW5jdGlvbiAocnVsZXNldCwgZnJhbWVzKSB7XG4gICAgdGhpcy5ydWxlc2V0ID0gcnVsZXNldDtcbiAgICB0aGlzLmZyYW1lcyA9IGZyYW1lcztcbn07XG5EZXRhY2hlZFJ1bGVzZXQucHJvdG90eXBlID0gbmV3IE5vZGUoKTtcbkRldGFjaGVkUnVsZXNldC5wcm90b3R5cGUudHlwZSA9IFwiRGV0YWNoZWRSdWxlc2V0XCI7XG5EZXRhY2hlZFJ1bGVzZXQucHJvdG90eXBlLmV2YWxGaXJzdCA9IHRydWU7XG5EZXRhY2hlZFJ1bGVzZXQucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uICh2aXNpdG9yKSB7XG4gICAgdGhpcy5ydWxlc2V0ID0gdmlzaXRvci52aXNpdCh0aGlzLnJ1bGVzZXQpO1xufTtcbkRldGFjaGVkUnVsZXNldC5wcm90b3R5cGUuZXZhbCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgdmFyIGZyYW1lcyA9IHRoaXMuZnJhbWVzIHx8IGNvbnRleHQuZnJhbWVzLnNsaWNlKDApO1xuICAgIHJldHVybiBuZXcgRGV0YWNoZWRSdWxlc2V0KHRoaXMucnVsZXNldCwgZnJhbWVzKTtcbn07XG5EZXRhY2hlZFJ1bGVzZXQucHJvdG90eXBlLmNhbGxFdmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICByZXR1cm4gdGhpcy5ydWxlc2V0LmV2YWwodGhpcy5mcmFtZXMgPyBuZXcgY29udGV4dHMuRXZhbChjb250ZXh0LCB0aGlzLmZyYW1lcy5jb25jYXQoY29udGV4dC5mcmFtZXMpKSA6IGNvbnRleHQpO1xufTtcbm1vZHVsZS5leHBvcnRzID0gRGV0YWNoZWRSdWxlc2V0O1xuXG59LHtcIi4uL2NvbnRleHRzXCI6MTEsXCIuL25vZGVcIjo3MH1dLDU2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBOb2RlID0gcmVxdWlyZShcIi4vbm9kZVwiKSxcbiAgICB1bml0Q29udmVyc2lvbnMgPSByZXF1aXJlKFwiLi4vZGF0YS91bml0LWNvbnZlcnNpb25zXCIpLFxuICAgIFVuaXQgPSByZXF1aXJlKFwiLi91bml0XCIpLFxuICAgIENvbG9yID0gcmVxdWlyZShcIi4vY29sb3JcIik7XG5cbi8vXG4vLyBBIG51bWJlciB3aXRoIGEgdW5pdFxuLy9cbnZhciBEaW1lbnNpb24gPSBmdW5jdGlvbiAodmFsdWUsIHVuaXQpIHtcbiAgICB0aGlzLnZhbHVlID0gcGFyc2VGbG9hdCh2YWx1ZSk7XG4gICAgdGhpcy51bml0ID0gKHVuaXQgJiYgdW5pdCBpbnN0YW5jZW9mIFVuaXQpID8gdW5pdCA6XG4gICAgICBuZXcgVW5pdCh1bml0ID8gW3VuaXRdIDogdW5kZWZpbmVkKTtcbn07XG5cbkRpbWVuc2lvbi5wcm90b3R5cGUgPSBuZXcgTm9kZSgpO1xuRGltZW5zaW9uLnByb3RvdHlwZS50eXBlID0gXCJEaW1lbnNpb25cIjtcbkRpbWVuc2lvbi5wcm90b3R5cGUuYWNjZXB0ID0gZnVuY3Rpb24gKHZpc2l0b3IpIHtcbiAgICB0aGlzLnVuaXQgPSB2aXNpdG9yLnZpc2l0KHRoaXMudW5pdCk7XG59O1xuRGltZW5zaW9uLnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICByZXR1cm4gdGhpcztcbn07XG5EaW1lbnNpb24ucHJvdG90eXBlLnRvQ29sb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG5ldyBDb2xvcihbdGhpcy52YWx1ZSwgdGhpcy52YWx1ZSwgdGhpcy52YWx1ZV0pO1xufTtcbkRpbWVuc2lvbi5wcm90b3R5cGUuZ2VuQ1NTID0gZnVuY3Rpb24gKGNvbnRleHQsIG91dHB1dCkge1xuICAgIGlmICgoY29udGV4dCAmJiBjb250ZXh0LnN0cmljdFVuaXRzKSAmJiAhdGhpcy51bml0LmlzU2luZ3VsYXIoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNdWx0aXBsZSB1bml0cyBpbiBkaW1lbnNpb24uIENvcnJlY3QgdGhlIHVuaXRzIG9yIHVzZSB0aGUgdW5pdCBmdW5jdGlvbi4gQmFkIHVuaXQ6IFwiICsgdGhpcy51bml0LnRvU3RyaW5nKCkpO1xuICAgIH1cblxuICAgIHZhciB2YWx1ZSA9IHRoaXMuZnJvdW5kKGNvbnRleHQsIHRoaXMudmFsdWUpLFxuICAgICAgICBzdHJWYWx1ZSA9IFN0cmluZyh2YWx1ZSk7XG5cbiAgICBpZiAodmFsdWUgIT09IDAgJiYgdmFsdWUgPCAwLjAwMDAwMSAmJiB2YWx1ZSA+IC0wLjAwMDAwMSkge1xuICAgICAgICAvLyB3b3VsZCBiZSBvdXRwdXQgMWUtNiBldGMuXG4gICAgICAgIHN0clZhbHVlID0gdmFsdWUudG9GaXhlZCgyMCkucmVwbGFjZSgvMCskLywgXCJcIik7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgJiYgY29udGV4dC5jb21wcmVzcykge1xuICAgICAgICAvLyBaZXJvIHZhbHVlcyBkb2Vzbid0IG5lZWQgYSB1bml0XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gMCAmJiB0aGlzLnVuaXQuaXNMZW5ndGgoKSkge1xuICAgICAgICAgICAgb3V0cHV0LmFkZChzdHJWYWx1ZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGbG9hdCB2YWx1ZXMgZG9lc24ndCBuZWVkIGEgbGVhZGluZyB6ZXJvXG4gICAgICAgIGlmICh2YWx1ZSA+IDAgJiYgdmFsdWUgPCAxKSB7XG4gICAgICAgICAgICBzdHJWYWx1ZSA9IChzdHJWYWx1ZSkuc3Vic3RyKDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb3V0cHV0LmFkZChzdHJWYWx1ZSk7XG4gICAgdGhpcy51bml0LmdlbkNTUyhjb250ZXh0LCBvdXRwdXQpO1xufTtcblxuLy8gSW4gYW4gb3BlcmF0aW9uIGJldHdlZW4gdHdvIERpbWVuc2lvbnMsXG4vLyB3ZSBkZWZhdWx0IHRvIHRoZSBmaXJzdCBEaW1lbnNpb24ncyB1bml0LFxuLy8gc28gYDFweCArIDJgIHdpbGwgeWllbGQgYDNweGAuXG5EaW1lbnNpb24ucHJvdG90eXBlLm9wZXJhdGUgPSBmdW5jdGlvbiAoY29udGV4dCwgb3AsIG90aGVyKSB7XG4gICAgLypqc2hpbnQgbm9lbXB0eTpmYWxzZSAqL1xuICAgIHZhciB2YWx1ZSA9IHRoaXMuX29wZXJhdGUoY29udGV4dCwgb3AsIHRoaXMudmFsdWUsIG90aGVyLnZhbHVlKSxcbiAgICAgICAgdW5pdCA9IHRoaXMudW5pdC5jbG9uZSgpO1xuXG4gICAgaWYgKG9wID09PSAnKycgfHwgb3AgPT09ICctJykge1xuICAgICAgICBpZiAodW5pdC5udW1lcmF0b3IubGVuZ3RoID09PSAwICYmIHVuaXQuZGVub21pbmF0b3IubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB1bml0ID0gb3RoZXIudW5pdC5jbG9uZSgpO1xuICAgICAgICAgICAgaWYgKHRoaXMudW5pdC5iYWNrdXBVbml0KSB7XG4gICAgICAgICAgICAgICAgdW5pdC5iYWNrdXBVbml0ID0gdGhpcy51bml0LmJhY2t1cFVuaXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAob3RoZXIudW5pdC5udW1lcmF0b3IubGVuZ3RoID09PSAwICYmIHVuaXQuZGVub21pbmF0b3IubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBkbyBub3RoaW5nXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBvdGhlciA9IG90aGVyLmNvbnZlcnRUbyh0aGlzLnVuaXQudXNlZFVuaXRzKCkpO1xuXG4gICAgICAgICAgICBpZiAoY29udGV4dC5zdHJpY3RVbml0cyAmJiBvdGhlci51bml0LnRvU3RyaW5nKCkgIT09IHVuaXQudG9TdHJpbmcoKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkluY29tcGF0aWJsZSB1bml0cy4gQ2hhbmdlIHRoZSB1bml0cyBvciB1c2UgdGhlIHVuaXQgZnVuY3Rpb24uIEJhZCB1bml0czogJ1wiICsgdW5pdC50b1N0cmluZygpICtcbiAgICAgICAgICAgICAgICAgICAgXCInIGFuZCAnXCIgKyBvdGhlci51bml0LnRvU3RyaW5nKCkgKyBcIicuXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YWx1ZSA9IHRoaXMuX29wZXJhdGUoY29udGV4dCwgb3AsIHRoaXMudmFsdWUsIG90aGVyLnZhbHVlKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAob3AgPT09ICcqJykge1xuICAgICAgICB1bml0Lm51bWVyYXRvciA9IHVuaXQubnVtZXJhdG9yLmNvbmNhdChvdGhlci51bml0Lm51bWVyYXRvcikuc29ydCgpO1xuICAgICAgICB1bml0LmRlbm9taW5hdG9yID0gdW5pdC5kZW5vbWluYXRvci5jb25jYXQob3RoZXIudW5pdC5kZW5vbWluYXRvcikuc29ydCgpO1xuICAgICAgICB1bml0LmNhbmNlbCgpO1xuICAgIH0gZWxzZSBpZiAob3AgPT09ICcvJykge1xuICAgICAgICB1bml0Lm51bWVyYXRvciA9IHVuaXQubnVtZXJhdG9yLmNvbmNhdChvdGhlci51bml0LmRlbm9taW5hdG9yKS5zb3J0KCk7XG4gICAgICAgIHVuaXQuZGVub21pbmF0b3IgPSB1bml0LmRlbm9taW5hdG9yLmNvbmNhdChvdGhlci51bml0Lm51bWVyYXRvcikuc29ydCgpO1xuICAgICAgICB1bml0LmNhbmNlbCgpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IERpbWVuc2lvbih2YWx1ZSwgdW5pdCk7XG59O1xuRGltZW5zaW9uLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gICAgdmFyIGEsIGI7XG5cbiAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIERpbWVuc2lvbikpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy51bml0LmlzRW1wdHkoKSB8fCBvdGhlci51bml0LmlzRW1wdHkoKSkge1xuICAgICAgICBhID0gdGhpcztcbiAgICAgICAgYiA9IG90aGVyO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGEgPSB0aGlzLnVuaWZ5KCk7XG4gICAgICAgIGIgPSBvdGhlci51bmlmeSgpO1xuICAgICAgICBpZiAoYS51bml0LmNvbXBhcmUoYi51bml0KSAhPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBOb2RlLm51bWVyaWNDb21wYXJlKGEudmFsdWUsIGIudmFsdWUpO1xufTtcbkRpbWVuc2lvbi5wcm90b3R5cGUudW5pZnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udmVydFRvKHsgbGVuZ3RoOiAncHgnLCBkdXJhdGlvbjogJ3MnLCBhbmdsZTogJ3JhZCcgfSk7XG59O1xuRGltZW5zaW9uLnByb3RvdHlwZS5jb252ZXJ0VG8gPSBmdW5jdGlvbiAoY29udmVyc2lvbnMpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLnZhbHVlLCB1bml0ID0gdGhpcy51bml0LmNsb25lKCksXG4gICAgICAgIGksIGdyb3VwTmFtZSwgZ3JvdXAsIHRhcmdldFVuaXQsIGRlcml2ZWRDb252ZXJzaW9ucyA9IHt9LCBhcHBseVVuaXQ7XG5cbiAgICBpZiAodHlwZW9mIGNvbnZlcnNpb25zID09PSAnc3RyaW5nJykge1xuICAgICAgICBmb3IgKGkgaW4gdW5pdENvbnZlcnNpb25zKSB7XG4gICAgICAgICAgICBpZiAodW5pdENvbnZlcnNpb25zW2ldLmhhc093blByb3BlcnR5KGNvbnZlcnNpb25zKSkge1xuICAgICAgICAgICAgICAgIGRlcml2ZWRDb252ZXJzaW9ucyA9IHt9O1xuICAgICAgICAgICAgICAgIGRlcml2ZWRDb252ZXJzaW9uc1tpXSA9IGNvbnZlcnNpb25zO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnZlcnNpb25zID0gZGVyaXZlZENvbnZlcnNpb25zO1xuICAgIH1cbiAgICBhcHBseVVuaXQgPSBmdW5jdGlvbiAoYXRvbWljVW5pdCwgZGVub21pbmF0b3IpIHtcbiAgICAgICAgLyoganNoaW50IGxvb3BmdW5jOnRydWUgKi9cbiAgICAgICAgaWYgKGdyb3VwLmhhc093blByb3BlcnR5KGF0b21pY1VuaXQpKSB7XG4gICAgICAgICAgICBpZiAoZGVub21pbmF0b3IpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlIC8gKGdyb3VwW2F0b21pY1VuaXRdIC8gZ3JvdXBbdGFyZ2V0VW5pdF0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlICogKGdyb3VwW2F0b21pY1VuaXRdIC8gZ3JvdXBbdGFyZ2V0VW5pdF0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0VW5pdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhdG9taWNVbml0O1xuICAgIH07XG5cbiAgICBmb3IgKGdyb3VwTmFtZSBpbiBjb252ZXJzaW9ucykge1xuICAgICAgICBpZiAoY29udmVyc2lvbnMuaGFzT3duUHJvcGVydHkoZ3JvdXBOYW1lKSkge1xuICAgICAgICAgICAgdGFyZ2V0VW5pdCA9IGNvbnZlcnNpb25zW2dyb3VwTmFtZV07XG4gICAgICAgICAgICBncm91cCA9IHVuaXRDb252ZXJzaW9uc1tncm91cE5hbWVdO1xuXG4gICAgICAgICAgICB1bml0Lm1hcChhcHBseVVuaXQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdW5pdC5jYW5jZWwoKTtcblxuICAgIHJldHVybiBuZXcgRGltZW5zaW9uKHZhbHVlLCB1bml0KTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IERpbWVuc2lvbjtcblxufSx7XCIuLi9kYXRhL3VuaXQtY29udmVyc2lvbnNcIjoxNCxcIi4vY29sb3JcIjo1MCxcIi4vbm9kZVwiOjcwLFwiLi91bml0XCI6Nzl9XSw1NzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgTm9kZSA9IHJlcXVpcmUoXCIuL25vZGVcIiksXG4gICAgU2VsZWN0b3IgPSByZXF1aXJlKFwiLi9zZWxlY3RvclwiKSxcbiAgICBSdWxlc2V0ID0gcmVxdWlyZShcIi4vcnVsZXNldFwiKTtcblxudmFyIERpcmVjdGl2ZSA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSwgcnVsZXMsIGluZGV4LCBjdXJyZW50RmlsZUluZm8sIGRlYnVnSW5mbywgaXNSb290ZWQsIHZpc2liaWxpdHlJbmZvKSB7XG4gICAgdmFyIGk7XG5cbiAgICB0aGlzLm5hbWUgID0gbmFtZTtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgaWYgKHJ1bGVzKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJ1bGVzKSkge1xuICAgICAgICAgICAgdGhpcy5ydWxlcyA9IHJ1bGVzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5ydWxlcyA9IFtydWxlc107XG4gICAgICAgICAgICB0aGlzLnJ1bGVzWzBdLnNlbGVjdG9ycyA9IChuZXcgU2VsZWN0b3IoW10sIG51bGwsIG51bGwsIHRoaXMuaW5kZXgsIGN1cnJlbnRGaWxlSW5mbykpLmNyZWF0ZUVtcHR5U2VsZWN0b3JzKCk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXMucnVsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMucnVsZXNbaV0uYWxsb3dJbXBvcnRzID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy5jdXJyZW50RmlsZUluZm8gPSBjdXJyZW50RmlsZUluZm87XG4gICAgdGhpcy5kZWJ1Z0luZm8gPSBkZWJ1Z0luZm87XG4gICAgdGhpcy5pc1Jvb3RlZCA9IGlzUm9vdGVkIHx8IGZhbHNlO1xuICAgIHRoaXMuY29weVZpc2liaWxpdHlJbmZvKHZpc2liaWxpdHlJbmZvKTtcbiAgICB0aGlzLmFsbG93Um9vdCA9IHRydWU7XG59O1xuXG5EaXJlY3RpdmUucHJvdG90eXBlID0gbmV3IE5vZGUoKTtcbkRpcmVjdGl2ZS5wcm90b3R5cGUudHlwZSA9IFwiRGlyZWN0aXZlXCI7XG5EaXJlY3RpdmUucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uICh2aXNpdG9yKSB7XG4gICAgdmFyIHZhbHVlID0gdGhpcy52YWx1ZSwgcnVsZXMgPSB0aGlzLnJ1bGVzO1xuICAgIGlmIChydWxlcykge1xuICAgICAgICB0aGlzLnJ1bGVzID0gdmlzaXRvci52aXNpdEFycmF5KHJ1bGVzKTtcbiAgICB9XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2aXNpdG9yLnZpc2l0KHZhbHVlKTtcbiAgICB9XG59O1xuRGlyZWN0aXZlLnByb3RvdHlwZS5pc1J1bGVzZXRMaWtlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMucnVsZXMgfHwgIXRoaXMuaXNDaGFyc2V0KCk7XG59O1xuRGlyZWN0aXZlLnByb3RvdHlwZS5pc0NoYXJzZXQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXCJAY2hhcnNldFwiID09PSB0aGlzLm5hbWU7XG59O1xuRGlyZWN0aXZlLnByb3RvdHlwZS5nZW5DU1MgPSBmdW5jdGlvbiAoY29udGV4dCwgb3V0cHV0KSB7XG4gICAgdmFyIHZhbHVlID0gdGhpcy52YWx1ZSwgcnVsZXMgPSB0aGlzLnJ1bGVzO1xuICAgIG91dHB1dC5hZGQodGhpcy5uYW1lLCB0aGlzLmN1cnJlbnRGaWxlSW5mbywgdGhpcy5pbmRleCk7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIG91dHB1dC5hZGQoJyAnKTtcbiAgICAgICAgdmFsdWUuZ2VuQ1NTKGNvbnRleHQsIG91dHB1dCk7XG4gICAgfVxuICAgIGlmIChydWxlcykge1xuICAgICAgICB0aGlzLm91dHB1dFJ1bGVzZXQoY29udGV4dCwgb3V0cHV0LCBydWxlcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0LmFkZCgnOycpO1xuICAgIH1cbn07XG5EaXJlY3RpdmUucHJvdG90eXBlLmV2YWwgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHZhciBtZWRpYVBhdGhCYWNrdXAsIG1lZGlhQmxvY2tzQmFja3VwLCB2YWx1ZSA9IHRoaXMudmFsdWUsIHJ1bGVzID0gdGhpcy5ydWxlcztcblxuICAgIC8vbWVkaWEgc3RvcmVkIGluc2lkZSBvdGhlciBkaXJlY3RpdmUgc2hvdWxkIG5vdCBidWJibGUgb3ZlciBpdFxuICAgIC8vYmFja3B1cCBtZWRpYSBidWJibGluZyBpbmZvcm1hdGlvblxuICAgIG1lZGlhUGF0aEJhY2t1cCA9IGNvbnRleHQubWVkaWFQYXRoO1xuICAgIG1lZGlhQmxvY2tzQmFja3VwID0gY29udGV4dC5tZWRpYUJsb2NrcztcbiAgICAvL2RlbGV0ZWQgbWVkaWEgYnViYmxpbmcgaW5mb3JtYXRpb25cbiAgICBjb250ZXh0Lm1lZGlhUGF0aCA9IFtdO1xuICAgIGNvbnRleHQubWVkaWFCbG9ja3MgPSBbXTtcblxuICAgIGlmICh2YWx1ZSkge1xuICAgICAgICB2YWx1ZSA9IHZhbHVlLmV2YWwoY29udGV4dCk7XG4gICAgfVxuICAgIGlmIChydWxlcykge1xuICAgICAgICAvLyBhc3N1bWluZyB0aGF0IHRoZXJlIGlzIG9ubHkgb25lIHJ1bGUgYXQgdGhpcyBwb2ludCAtIHRoYXQgaXMgaG93IHBhcnNlciBjb25zdHJ1Y3RzIHRoZSBydWxlXG4gICAgICAgIHJ1bGVzID0gW3J1bGVzWzBdLmV2YWwoY29udGV4dCldO1xuICAgICAgICBydWxlc1swXS5yb290ID0gdHJ1ZTtcbiAgICB9XG4gICAgLy9yZXN0b3JlIG1lZGlhIGJ1YmJsaW5nIGluZm9ybWF0aW9uXG4gICAgY29udGV4dC5tZWRpYVBhdGggPSBtZWRpYVBhdGhCYWNrdXA7XG4gICAgY29udGV4dC5tZWRpYUJsb2NrcyA9IG1lZGlhQmxvY2tzQmFja3VwO1xuXG4gICAgcmV0dXJuIG5ldyBEaXJlY3RpdmUodGhpcy5uYW1lLCB2YWx1ZSwgcnVsZXMsXG4gICAgICAgIHRoaXMuaW5kZXgsIHRoaXMuY3VycmVudEZpbGVJbmZvLCB0aGlzLmRlYnVnSW5mbywgdGhpcy5pc1Jvb3RlZCwgdGhpcy52aXNpYmlsaXR5SW5mbygpKTtcbn07XG5EaXJlY3RpdmUucHJvdG90eXBlLnZhcmlhYmxlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICBpZiAodGhpcy5ydWxlcykge1xuICAgICAgICAvLyBhc3N1bWluZyB0aGF0IHRoZXJlIGlzIG9ubHkgb25lIHJ1bGUgYXQgdGhpcyBwb2ludCAtIHRoYXQgaXMgaG93IHBhcnNlciBjb25zdHJ1Y3RzIHRoZSBydWxlXG4gICAgICAgIHJldHVybiBSdWxlc2V0LnByb3RvdHlwZS52YXJpYWJsZS5jYWxsKHRoaXMucnVsZXNbMF0sIG5hbWUpO1xuICAgIH1cbn07XG5EaXJlY3RpdmUucHJvdG90eXBlLmZpbmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMucnVsZXMpIHtcbiAgICAgICAgLy8gYXNzdW1pbmcgdGhhdCB0aGVyZSBpcyBvbmx5IG9uZSBydWxlIGF0IHRoaXMgcG9pbnQgLSB0aGF0IGlzIGhvdyBwYXJzZXIgY29uc3RydWN0cyB0aGUgcnVsZVxuICAgICAgICByZXR1cm4gUnVsZXNldC5wcm90b3R5cGUuZmluZC5hcHBseSh0aGlzLnJ1bGVzWzBdLCBhcmd1bWVudHMpO1xuICAgIH1cbn07XG5EaXJlY3RpdmUucHJvdG90eXBlLnJ1bGVzZXRzID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnJ1bGVzKSB7XG4gICAgICAgIC8vIGFzc3VtaW5nIHRoYXQgdGhlcmUgaXMgb25seSBvbmUgcnVsZSBhdCB0aGlzIHBvaW50IC0gdGhhdCBpcyBob3cgcGFyc2VyIGNvbnN0cnVjdHMgdGhlIHJ1bGVcbiAgICAgICAgcmV0dXJuIFJ1bGVzZXQucHJvdG90eXBlLnJ1bGVzZXRzLmFwcGx5KHRoaXMucnVsZXNbMF0pO1xuICAgIH1cbn07XG5EaXJlY3RpdmUucHJvdG90eXBlLm91dHB1dFJ1bGVzZXQgPSBmdW5jdGlvbiAoY29udGV4dCwgb3V0cHV0LCBydWxlcykge1xuICAgIHZhciBydWxlQ250ID0gcnVsZXMubGVuZ3RoLCBpO1xuICAgIGNvbnRleHQudGFiTGV2ZWwgPSAoY29udGV4dC50YWJMZXZlbCB8IDApICsgMTtcblxuICAgIC8vIENvbXByZXNzZWRcbiAgICBpZiAoY29udGV4dC5jb21wcmVzcykge1xuICAgICAgICBvdXRwdXQuYWRkKCd7Jyk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBydWxlQ250OyBpKyspIHtcbiAgICAgICAgICAgIHJ1bGVzW2ldLmdlbkNTUyhjb250ZXh0LCBvdXRwdXQpO1xuICAgICAgICB9XG4gICAgICAgIG91dHB1dC5hZGQoJ30nKTtcbiAgICAgICAgY29udGV4dC50YWJMZXZlbC0tO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gTm9uLWNvbXByZXNzZWRcbiAgICB2YXIgdGFiU2V0U3RyID0gJ1xcbicgKyBBcnJheShjb250ZXh0LnRhYkxldmVsKS5qb2luKFwiICBcIiksIHRhYlJ1bGVTdHIgPSB0YWJTZXRTdHIgKyBcIiAgXCI7XG4gICAgaWYgKCFydWxlQ250KSB7XG4gICAgICAgIG91dHB1dC5hZGQoXCIge1wiICsgdGFiU2V0U3RyICsgJ30nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQuYWRkKFwiIHtcIiArIHRhYlJ1bGVTdHIpO1xuICAgICAgICBydWxlc1swXS5nZW5DU1MoY29udGV4dCwgb3V0cHV0KTtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IHJ1bGVDbnQ7IGkrKykge1xuICAgICAgICAgICAgb3V0cHV0LmFkZCh0YWJSdWxlU3RyKTtcbiAgICAgICAgICAgIHJ1bGVzW2ldLmdlbkNTUyhjb250ZXh0LCBvdXRwdXQpO1xuICAgICAgICB9XG4gICAgICAgIG91dHB1dC5hZGQodGFiU2V0U3RyICsgJ30nKTtcbiAgICB9XG5cbiAgICBjb250ZXh0LnRhYkxldmVsLS07XG59O1xubW9kdWxlLmV4cG9ydHMgPSBEaXJlY3RpdmU7XG5cbn0se1wiLi9ub2RlXCI6NzAsXCIuL3J1bGVzZXRcIjo3NixcIi4vc2VsZWN0b3JcIjo3N31dLDU4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBOb2RlID0gcmVxdWlyZShcIi4vbm9kZVwiKSxcbiAgICBQYXJlbiA9IHJlcXVpcmUoXCIuL3BhcmVuXCIpLFxuICAgIENvbWJpbmF0b3IgPSByZXF1aXJlKFwiLi9jb21iaW5hdG9yXCIpO1xuXG52YXIgRWxlbWVudCA9IGZ1bmN0aW9uIChjb21iaW5hdG9yLCB2YWx1ZSwgaW5kZXgsIGN1cnJlbnRGaWxlSW5mbywgaW5mbykge1xuICAgIHRoaXMuY29tYmluYXRvciA9IGNvbWJpbmF0b3IgaW5zdGFuY2VvZiBDb21iaW5hdG9yID9cbiAgICAgICAgICAgICAgICAgICAgICBjb21iaW5hdG9yIDogbmV3IENvbWJpbmF0b3IoY29tYmluYXRvcik7XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWUudHJpbSgpO1xuICAgIH0gZWxzZSBpZiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBcIlwiO1xuICAgIH1cbiAgICB0aGlzLmluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy5jdXJyZW50RmlsZUluZm8gPSBjdXJyZW50RmlsZUluZm87XG4gICAgdGhpcy5jb3B5VmlzaWJpbGl0eUluZm8oaW5mbyk7XG59O1xuRWxlbWVudC5wcm90b3R5cGUgPSBuZXcgTm9kZSgpO1xuRWxlbWVudC5wcm90b3R5cGUudHlwZSA9IFwiRWxlbWVudFwiO1xuRWxlbWVudC5wcm90b3R5cGUuYWNjZXB0ID0gZnVuY3Rpb24gKHZpc2l0b3IpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLnZhbHVlO1xuICAgIHRoaXMuY29tYmluYXRvciA9IHZpc2l0b3IudmlzaXQodGhpcy5jb21iaW5hdG9yKTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2aXNpdG9yLnZpc2l0KHZhbHVlKTtcbiAgICB9XG59O1xuRWxlbWVudC5wcm90b3R5cGUuZXZhbCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBFbGVtZW50KHRoaXMuY29tYmluYXRvcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZS5ldmFsID8gdGhpcy52YWx1ZS5ldmFsKGNvbnRleHQpIDogdGhpcy52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmRleCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50RmlsZUluZm8sIHRoaXMudmlzaWJpbGl0eUluZm8oKSk7XG59O1xuRWxlbWVudC5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG5ldyBFbGVtZW50KHRoaXMuY29tYmluYXRvcixcbiAgICAgICAgdGhpcy52YWx1ZSxcbiAgICAgICAgdGhpcy5pbmRleCxcbiAgICAgICAgdGhpcy5jdXJyZW50RmlsZUluZm8sIHRoaXMudmlzaWJpbGl0eUluZm8oKSk7XG59O1xuRWxlbWVudC5wcm90b3R5cGUuZ2VuQ1NTID0gZnVuY3Rpb24gKGNvbnRleHQsIG91dHB1dCkge1xuICAgIG91dHB1dC5hZGQodGhpcy50b0NTUyhjb250ZXh0KSwgdGhpcy5jdXJyZW50RmlsZUluZm8sIHRoaXMuaW5kZXgpO1xufTtcbkVsZW1lbnQucHJvdG90eXBlLnRvQ1NTID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICBjb250ZXh0ID0gY29udGV4dCB8fCB7fTtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLnZhbHVlLCBmaXJzdFNlbGVjdG9yID0gY29udGV4dC5maXJzdFNlbGVjdG9yO1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFBhcmVuKSB7XG4gICAgICAgIC8vIHNlbGVjdG9yIGluIHBhcmVucyBzaG91bGQgbm90IGJlIGFmZmVjdGVkIGJ5IG91dGVyIHNlbGVjdG9yXG4gICAgICAgIC8vIGZsYWdzIChicmVha3Mgb25seSBpbnRlcnBvbGF0ZWQgc2VsZWN0b3JzIC0gc2VlICMxOTczKVxuICAgICAgICBjb250ZXh0LmZpcnN0U2VsZWN0b3IgPSB0cnVlO1xuICAgIH1cbiAgICB2YWx1ZSA9IHZhbHVlLnRvQ1NTID8gdmFsdWUudG9DU1MoY29udGV4dCkgOiB2YWx1ZTtcbiAgICBjb250ZXh0LmZpcnN0U2VsZWN0b3IgPSBmaXJzdFNlbGVjdG9yO1xuICAgIGlmICh2YWx1ZSA9PT0gJycgJiYgdGhpcy5jb21iaW5hdG9yLnZhbHVlLmNoYXJBdCgwKSA9PT0gJyYnKSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21iaW5hdG9yLnRvQ1NTKGNvbnRleHQpICsgdmFsdWU7XG4gICAgfVxufTtcbm1vZHVsZS5leHBvcnRzID0gRWxlbWVudDtcblxufSx7XCIuL2NvbWJpbmF0b3JcIjo1MSxcIi4vbm9kZVwiOjcwLFwiLi9wYXJlblwiOjcyfV0sNTk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIE5vZGUgPSByZXF1aXJlKFwiLi9ub2RlXCIpLFxuICAgIFBhcmVuID0gcmVxdWlyZShcIi4vcGFyZW5cIiksXG4gICAgQ29tbWVudCA9IHJlcXVpcmUoXCIuL2NvbW1lbnRcIik7XG5cbnZhciBFeHByZXNzaW9uID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXhwcmVzc2lvbiByZXF1aXJlcyBhbiBhcnJheSBwYXJhbWV0ZXJcIik7XG4gICAgfVxufTtcbkV4cHJlc3Npb24ucHJvdG90eXBlID0gbmV3IE5vZGUoKTtcbkV4cHJlc3Npb24ucHJvdG90eXBlLnR5cGUgPSBcIkV4cHJlc3Npb25cIjtcbkV4cHJlc3Npb24ucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uICh2aXNpdG9yKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZpc2l0b3IudmlzaXRBcnJheSh0aGlzLnZhbHVlKTtcbn07XG5FeHByZXNzaW9uLnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgcmV0dXJuVmFsdWUsXG4gICAgICAgIGluUGFyZW50aGVzaXMgPSB0aGlzLnBhcmVucyAmJiAhdGhpcy5wYXJlbnNJbk9wLFxuICAgICAgICBkb3VibGVQYXJlbiA9IGZhbHNlO1xuICAgIGlmIChpblBhcmVudGhlc2lzKSB7XG4gICAgICAgIGNvbnRleHQuaW5QYXJlbnRoZXNpcygpO1xuICAgIH1cbiAgICBpZiAodGhpcy52YWx1ZS5sZW5ndGggPiAxKSB7XG4gICAgICAgIHJldHVyblZhbHVlID0gbmV3IEV4cHJlc3Npb24odGhpcy52YWx1ZS5tYXAoZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBlLmV2YWwoY29udGV4dCk7XG4gICAgICAgIH0pKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMudmFsdWUubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGlmICh0aGlzLnZhbHVlWzBdLnBhcmVucyAmJiAhdGhpcy52YWx1ZVswXS5wYXJlbnNJbk9wKSB7XG4gICAgICAgICAgICBkb3VibGVQYXJlbiA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnZhbHVlWzBdLmV2YWwoY29udGV4dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzO1xuICAgIH1cbiAgICBpZiAoaW5QYXJlbnRoZXNpcykge1xuICAgICAgICBjb250ZXh0Lm91dE9mUGFyZW50aGVzaXMoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucGFyZW5zICYmIHRoaXMucGFyZW5zSW5PcCAmJiAhKGNvbnRleHQuaXNNYXRoT24oKSkgJiYgIWRvdWJsZVBhcmVuKSB7XG4gICAgICAgIHJldHVyblZhbHVlID0gbmV3IFBhcmVuKHJldHVyblZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldHVyblZhbHVlO1xufTtcbkV4cHJlc3Npb24ucHJvdG90eXBlLmdlbkNTUyA9IGZ1bmN0aW9uIChjb250ZXh0LCBvdXRwdXQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy52YWx1ZVtpXS5nZW5DU1MoY29udGV4dCwgb3V0cHV0KTtcbiAgICAgICAgaWYgKGkgKyAxIDwgdGhpcy52YWx1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIG91dHB1dC5hZGQoXCIgXCIpO1xuICAgICAgICB9XG4gICAgfVxufTtcbkV4cHJlc3Npb24ucHJvdG90eXBlLnRocm93QXdheUNvbW1lbnRzID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMudmFsdWUgPSB0aGlzLnZhbHVlLmZpbHRlcihmdW5jdGlvbih2KSB7XG4gICAgICAgIHJldHVybiAhKHYgaW5zdGFuY2VvZiBDb21tZW50KTtcbiAgICB9KTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IEV4cHJlc3Npb247XG5cbn0se1wiLi9jb21tZW50XCI6NTIsXCIuL25vZGVcIjo3MCxcIi4vcGFyZW5cIjo3Mn1dLDYwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBOb2RlID0gcmVxdWlyZShcIi4vbm9kZVwiKSxcbiAgICBTZWxlY3RvciA9IHJlcXVpcmUoXCIuL3NlbGVjdG9yXCIpO1xuXG52YXIgRXh0ZW5kID0gZnVuY3Rpb24gRXh0ZW5kKHNlbGVjdG9yLCBvcHRpb24sIGluZGV4LCBjdXJyZW50RmlsZUluZm8sIHZpc2liaWxpdHlJbmZvKSB7XG4gICAgdGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yO1xuICAgIHRoaXMub3B0aW9uID0gb3B0aW9uO1xuICAgIHRoaXMuaW5kZXggPSBpbmRleDtcbiAgICB0aGlzLm9iamVjdF9pZCA9IEV4dGVuZC5uZXh0X2lkKys7XG4gICAgdGhpcy5wYXJlbnRfaWRzID0gW3RoaXMub2JqZWN0X2lkXTtcbiAgICB0aGlzLmN1cnJlbnRGaWxlSW5mbyA9IGN1cnJlbnRGaWxlSW5mbyB8fCB7fTtcbiAgICB0aGlzLmNvcHlWaXNpYmlsaXR5SW5mbyh2aXNpYmlsaXR5SW5mbyk7XG4gICAgdGhpcy5hbGxvd1Jvb3QgPSB0cnVlO1xuXG4gICAgc3dpdGNoKG9wdGlvbikge1xuICAgICAgICBjYXNlIFwiYWxsXCI6XG4gICAgICAgICAgICB0aGlzLmFsbG93QmVmb3JlID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuYWxsb3dBZnRlciA9IHRydWU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRoaXMuYWxsb3dCZWZvcmUgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuYWxsb3dBZnRlciA9IGZhbHNlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgfVxufTtcbkV4dGVuZC5uZXh0X2lkID0gMDtcblxuRXh0ZW5kLnByb3RvdHlwZSA9IG5ldyBOb2RlKCk7XG5FeHRlbmQucHJvdG90eXBlLnR5cGUgPSBcIkV4dGVuZFwiO1xuRXh0ZW5kLnByb3RvdHlwZS5hY2NlcHQgPSBmdW5jdGlvbiAodmlzaXRvcikge1xuICAgIHRoaXMuc2VsZWN0b3IgPSB2aXNpdG9yLnZpc2l0KHRoaXMuc2VsZWN0b3IpO1xufTtcbkV4dGVuZC5wcm90b3R5cGUuZXZhbCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBFeHRlbmQodGhpcy5zZWxlY3Rvci5ldmFsKGNvbnRleHQpLCB0aGlzLm9wdGlvbiwgdGhpcy5pbmRleCwgdGhpcy5jdXJyZW50RmlsZUluZm8sIHRoaXMudmlzaWJpbGl0eUluZm8oKSk7XG59O1xuRXh0ZW5kLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBFeHRlbmQodGhpcy5zZWxlY3RvciwgdGhpcy5vcHRpb24sIHRoaXMuaW5kZXgsIHRoaXMuY3VycmVudEZpbGVJbmZvLCB0aGlzLnZpc2liaWxpdHlJbmZvKCkpO1xufTtcbi8vaXQgY29uY2F0ZW5hdGVzIChqb2lucykgYWxsIHNlbGVjdG9ycyBpbiBzZWxlY3RvciBhcnJheVxuRXh0ZW5kLnByb3RvdHlwZS5maW5kU2VsZlNlbGVjdG9ycyA9IGZ1bmN0aW9uIChzZWxlY3RvcnMpIHtcbiAgICB2YXIgc2VsZkVsZW1lbnRzID0gW10sXG4gICAgICAgIGksXG4gICAgICAgIHNlbGVjdG9yRWxlbWVudHM7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgc2VsZWN0b3JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHNlbGVjdG9yRWxlbWVudHMgPSBzZWxlY3RvcnNbaV0uZWxlbWVudHM7XG4gICAgICAgIC8vIGR1cGxpY2F0ZSB0aGUgbG9naWMgaW4gZ2VuQ1NTIGZ1bmN0aW9uIGluc2lkZSB0aGUgc2VsZWN0b3Igbm9kZS5cbiAgICAgICAgLy8gZnV0dXJlIFRPRE8gLSBtb3ZlIGJvdGggbG9naWNzIGludG8gdGhlIHNlbGVjdG9yIGpvaW5lciB2aXNpdG9yXG4gICAgICAgIGlmIChpID4gMCAmJiBzZWxlY3RvckVsZW1lbnRzLmxlbmd0aCAmJiBzZWxlY3RvckVsZW1lbnRzWzBdLmNvbWJpbmF0b3IudmFsdWUgPT09IFwiXCIpIHtcbiAgICAgICAgICAgIHNlbGVjdG9yRWxlbWVudHNbMF0uY29tYmluYXRvci52YWx1ZSA9ICcgJztcbiAgICAgICAgfVxuICAgICAgICBzZWxmRWxlbWVudHMgPSBzZWxmRWxlbWVudHMuY29uY2F0KHNlbGVjdG9yc1tpXS5lbGVtZW50cyk7XG4gICAgfVxuXG4gICAgdGhpcy5zZWxmU2VsZWN0b3JzID0gW25ldyBTZWxlY3RvcihzZWxmRWxlbWVudHMpXTtcbiAgICB0aGlzLnNlbGZTZWxlY3RvcnNbMF0uY29weVZpc2liaWxpdHlJbmZvKHRoaXMudmlzaWJpbGl0eUluZm8oKSk7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBFeHRlbmQ7XG5cbn0se1wiLi9ub2RlXCI6NzAsXCIuL3NlbGVjdG9yXCI6Nzd9XSw2MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgTm9kZSA9IHJlcXVpcmUoXCIuL25vZGVcIiksXG4gICAgTWVkaWEgPSByZXF1aXJlKFwiLi9tZWRpYVwiKSxcbiAgICBVUkwgPSByZXF1aXJlKFwiLi91cmxcIiksXG4gICAgUXVvdGVkID0gcmVxdWlyZShcIi4vcXVvdGVkXCIpLFxuICAgIFJ1bGVzZXQgPSByZXF1aXJlKFwiLi9ydWxlc2V0XCIpLFxuICAgIEFub255bW91cyA9IHJlcXVpcmUoXCIuL2Fub255bW91c1wiKTtcblxuLy9cbi8vIENTUyBAaW1wb3J0IG5vZGVcbi8vXG4vLyBUaGUgZ2VuZXJhbCBzdHJhdGVneSBoZXJlIGlzIHRoYXQgd2UgZG9uJ3Qgd2FudCB0byB3YWl0XG4vLyBmb3IgdGhlIHBhcnNpbmcgdG8gYmUgY29tcGxldGVkLCBiZWZvcmUgd2Ugc3RhcnQgaW1wb3J0aW5nXG4vLyB0aGUgZmlsZS4gVGhhdCdzIGJlY2F1c2UgaW4gdGhlIGNvbnRleHQgb2YgYSBicm93c2VyLFxuLy8gbW9zdCBvZiB0aGUgdGltZSB3aWxsIGJlIHNwZW50IHdhaXRpbmcgZm9yIHRoZSBzZXJ2ZXIgdG8gcmVzcG9uZC5cbi8vXG4vLyBPbiBjcmVhdGlvbiwgd2UgcHVzaCB0aGUgaW1wb3J0IHBhdGggdG8gb3VyIGltcG9ydCBxdWV1ZSwgdGhvdWdoXG4vLyBgaW1wb3J0LHB1c2hgLCB3ZSBhbHNvIHBhc3MgaXQgYSBjYWxsYmFjaywgd2hpY2ggaXQnbGwgY2FsbCBvbmNlXG4vLyB0aGUgZmlsZSBoYXMgYmVlbiBmZXRjaGVkLCBhbmQgcGFyc2VkLlxuLy9cbnZhciBJbXBvcnQgPSBmdW5jdGlvbiAocGF0aCwgZmVhdHVyZXMsIG9wdGlvbnMsIGluZGV4LCBjdXJyZW50RmlsZUluZm8sIHZpc2liaWxpdHlJbmZvKSB7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLmluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy5wYXRoID0gcGF0aDtcbiAgICB0aGlzLmZlYXR1cmVzID0gZmVhdHVyZXM7XG4gICAgdGhpcy5jdXJyZW50RmlsZUluZm8gPSBjdXJyZW50RmlsZUluZm87XG4gICAgdGhpcy5hbGxvd1Jvb3QgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5sZXNzICE9PSB1bmRlZmluZWQgfHwgdGhpcy5vcHRpb25zLmlubGluZSkge1xuICAgICAgICB0aGlzLmNzcyA9ICF0aGlzLm9wdGlvbnMubGVzcyB8fCB0aGlzLm9wdGlvbnMuaW5saW5lO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBwYXRoVmFsdWUgPSB0aGlzLmdldFBhdGgoKTtcbiAgICAgICAgaWYgKHBhdGhWYWx1ZSAmJiAvWyNcXC5cXCZcXD9cXC9dY3NzKFtcXD87XS4qKT8kLy50ZXN0KHBhdGhWYWx1ZSkpIHtcbiAgICAgICAgICAgIHRoaXMuY3NzID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmNvcHlWaXNpYmlsaXR5SW5mbyh2aXNpYmlsaXR5SW5mbyk7XG59O1xuXG4vL1xuLy8gVGhlIGFjdHVhbCBpbXBvcnQgbm9kZSBkb2Vzbid0IHJldHVybiBhbnl0aGluZywgd2hlbiBjb252ZXJ0ZWQgdG8gQ1NTLlxuLy8gVGhlIHJlYXNvbiBpcyB0aGF0IGl0J3MgdXNlZCBhdCB0aGUgZXZhbHVhdGlvbiBzdGFnZSwgc28gdGhhdCB0aGUgcnVsZXNcbi8vIGl0IGltcG9ydHMgY2FuIGJlIHRyZWF0ZWQgbGlrZSBhbnkgb3RoZXIgcnVsZXMuXG4vL1xuLy8gSW4gYGV2YWxgLCB3ZSBtYWtlIHN1cmUgYWxsIEltcG9ydCBub2RlcyBnZXQgZXZhbHVhdGVkLCByZWN1cnNpdmVseSwgc29cbi8vIHdlIGVuZCB1cCB3aXRoIGEgZmxhdCBzdHJ1Y3R1cmUsIHdoaWNoIGNhbiBlYXNpbHkgYmUgaW1wb3J0ZWQgaW4gdGhlIHBhcmVudFxuLy8gcnVsZXNldC5cbi8vXG5JbXBvcnQucHJvdG90eXBlID0gbmV3IE5vZGUoKTtcbkltcG9ydC5wcm90b3R5cGUudHlwZSA9IFwiSW1wb3J0XCI7XG5JbXBvcnQucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uICh2aXNpdG9yKSB7XG4gICAgaWYgKHRoaXMuZmVhdHVyZXMpIHtcbiAgICAgICAgdGhpcy5mZWF0dXJlcyA9IHZpc2l0b3IudmlzaXQodGhpcy5mZWF0dXJlcyk7XG4gICAgfVxuICAgIHRoaXMucGF0aCA9IHZpc2l0b3IudmlzaXQodGhpcy5wYXRoKTtcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5wbHVnaW4gJiYgIXRoaXMub3B0aW9ucy5pbmxpbmUgJiYgdGhpcy5yb290KSB7XG4gICAgICAgIHRoaXMucm9vdCA9IHZpc2l0b3IudmlzaXQodGhpcy5yb290KTtcbiAgICB9XG59O1xuSW1wb3J0LnByb3RvdHlwZS5nZW5DU1MgPSBmdW5jdGlvbiAoY29udGV4dCwgb3V0cHV0KSB7XG4gICAgaWYgKHRoaXMuY3NzICYmIHRoaXMucGF0aC5jdXJyZW50RmlsZUluZm8ucmVmZXJlbmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgb3V0cHV0LmFkZChcIkBpbXBvcnQgXCIsIHRoaXMuY3VycmVudEZpbGVJbmZvLCB0aGlzLmluZGV4KTtcbiAgICAgICAgdGhpcy5wYXRoLmdlbkNTUyhjb250ZXh0LCBvdXRwdXQpO1xuICAgICAgICBpZiAodGhpcy5mZWF0dXJlcykge1xuICAgICAgICAgICAgb3V0cHV0LmFkZChcIiBcIik7XG4gICAgICAgICAgICB0aGlzLmZlYXR1cmVzLmdlbkNTUyhjb250ZXh0LCBvdXRwdXQpO1xuICAgICAgICB9XG4gICAgICAgIG91dHB1dC5hZGQoJzsnKTtcbiAgICB9XG59O1xuSW1wb3J0LnByb3RvdHlwZS5nZXRQYXRoID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAodGhpcy5wYXRoIGluc3RhbmNlb2YgVVJMKSA/XG4gICAgICAgIHRoaXMucGF0aC52YWx1ZS52YWx1ZSA6IHRoaXMucGF0aC52YWx1ZTtcbn07XG5JbXBvcnQucHJvdG90eXBlLmlzVmFyaWFibGVJbXBvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHBhdGggPSB0aGlzLnBhdGg7XG4gICAgaWYgKHBhdGggaW5zdGFuY2VvZiBVUkwpIHtcbiAgICAgICAgcGF0aCA9IHBhdGgudmFsdWU7XG4gICAgfVxuICAgIGlmIChwYXRoIGluc3RhbmNlb2YgUXVvdGVkKSB7XG4gICAgICAgIHJldHVybiBwYXRoLmNvbnRhaW5zVmFyaWFibGVzKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG59O1xuSW1wb3J0LnByb3RvdHlwZS5ldmFsRm9ySW1wb3J0ID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgcGF0aCA9IHRoaXMucGF0aDtcblxuICAgIGlmIChwYXRoIGluc3RhbmNlb2YgVVJMKSB7XG4gICAgICAgIHBhdGggPSBwYXRoLnZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgSW1wb3J0KHBhdGguZXZhbChjb250ZXh0KSwgdGhpcy5mZWF0dXJlcywgdGhpcy5vcHRpb25zLCB0aGlzLmluZGV4LCB0aGlzLmN1cnJlbnRGaWxlSW5mbywgdGhpcy52aXNpYmlsaXR5SW5mbygpKTtcbn07XG5JbXBvcnQucHJvdG90eXBlLmV2YWxQYXRoID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgcGF0aCA9IHRoaXMucGF0aC5ldmFsKGNvbnRleHQpO1xuICAgIHZhciByb290cGF0aCA9IHRoaXMuY3VycmVudEZpbGVJbmZvICYmIHRoaXMuY3VycmVudEZpbGVJbmZvLnJvb3RwYXRoO1xuXG4gICAgaWYgKCEocGF0aCBpbnN0YW5jZW9mIFVSTCkpIHtcbiAgICAgICAgaWYgKHJvb3RwYXRoKSB7XG4gICAgICAgICAgICB2YXIgcGF0aFZhbHVlID0gcGF0aC52YWx1ZTtcbiAgICAgICAgICAgIC8vIEFkZCB0aGUgYmFzZSBwYXRoIGlmIHRoZSBpbXBvcnQgaXMgcmVsYXRpdmVcbiAgICAgICAgICAgIGlmIChwYXRoVmFsdWUgJiYgY29udGV4dC5pc1BhdGhSZWxhdGl2ZShwYXRoVmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgcGF0aC52YWx1ZSA9IHJvb3RwYXRoICsgcGF0aFZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHBhdGgudmFsdWUgPSBjb250ZXh0Lm5vcm1hbGl6ZVBhdGgocGF0aC52YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhdGg7XG59O1xuSW1wb3J0LnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgcmVzdWx0ID0gdGhpcy5kb0V2YWwoY29udGV4dCk7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5yZWZlcmVuY2UgfHwgdGhpcy5ibG9ja3NWaXNpYmlsaXR5KCkpIHtcbiAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGggfHwgcmVzdWx0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmVzdWx0LmZvckVhY2goZnVuY3Rpb24gKG5vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZS5hZGRWaXNpYmlsaXR5QmxvY2soKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVzdWx0LmFkZFZpc2liaWxpdHlCbG9jaygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59O1xuSW1wb3J0LnByb3RvdHlwZS5kb0V2YWwgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHZhciBydWxlc2V0LCByZWdpc3RyeSxcbiAgICAgICAgZmVhdHVyZXMgPSB0aGlzLmZlYXR1cmVzICYmIHRoaXMuZmVhdHVyZXMuZXZhbChjb250ZXh0KTtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMucGx1Z2luKSB7XG4gICAgICAgIHJlZ2lzdHJ5ID0gY29udGV4dC5mcmFtZXNbMF0gJiYgY29udGV4dC5mcmFtZXNbMF0uZnVuY3Rpb25SZWdpc3RyeTtcbiAgICAgICAgaWYgKCByZWdpc3RyeSAmJiB0aGlzLnJvb3QgJiYgdGhpcy5yb290LmZ1bmN0aW9ucyApIHtcbiAgICAgICAgICAgIHJlZ2lzdHJ5LmFkZE11bHRpcGxlKCB0aGlzLnJvb3QuZnVuY3Rpb25zICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnNraXApIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnNraXAgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhpcy5za2lwID0gdGhpcy5za2lwKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc2tpcCkge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICh0aGlzLm9wdGlvbnMuaW5saW5lKSB7XG4gICAgICAgIHZhciBjb250ZW50cyA9IG5ldyBBbm9ueW1vdXModGhpcy5yb290LCAwLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZmlsZW5hbWU6IHRoaXMuaW1wb3J0ZWRGaWxlbmFtZSxcbiAgICAgICAgICAgICAgcmVmZXJlbmNlOiB0aGlzLnBhdGguY3VycmVudEZpbGVJbmZvICYmIHRoaXMucGF0aC5jdXJyZW50RmlsZUluZm8ucmVmZXJlbmNlXG4gICAgICAgICAgfSwgdHJ1ZSwgdHJ1ZSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZmVhdHVyZXMgPyBuZXcgTWVkaWEoW2NvbnRlbnRzXSwgdGhpcy5mZWF0dXJlcy52YWx1ZSkgOiBbY29udGVudHNdO1xuICAgIH0gZWxzZSBpZiAodGhpcy5jc3MpIHtcbiAgICAgICAgdmFyIG5ld0ltcG9ydCA9IG5ldyBJbXBvcnQodGhpcy5ldmFsUGF0aChjb250ZXh0KSwgZmVhdHVyZXMsIHRoaXMub3B0aW9ucywgdGhpcy5pbmRleCk7XG4gICAgICAgIGlmICghbmV3SW1wb3J0LmNzcyAmJiB0aGlzLmVycm9yKSB7XG4gICAgICAgICAgICB0aHJvdyB0aGlzLmVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXdJbXBvcnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcnVsZXNldCA9IG5ldyBSdWxlc2V0KG51bGwsIHRoaXMucm9vdC5ydWxlcy5zbGljZSgwKSk7XG4gICAgICAgIHJ1bGVzZXQuZXZhbEltcG9ydHMoY29udGV4dCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZmVhdHVyZXMgPyBuZXcgTWVkaWEocnVsZXNldC5ydWxlcywgdGhpcy5mZWF0dXJlcy52YWx1ZSkgOiBydWxlc2V0LnJ1bGVzO1xuICAgIH1cbn07XG5tb2R1bGUuZXhwb3J0cyA9IEltcG9ydDtcblxufSx7XCIuL2Fub255bW91c1wiOjQ2LFwiLi9tZWRpYVwiOjY2LFwiLi9ub2RlXCI6NzAsXCIuL3F1b3RlZFwiOjczLFwiLi9ydWxlc2V0XCI6NzYsXCIuL3VybFwiOjgwfV0sNjI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIHRyZWUgPSB7fTtcblxudHJlZS5Ob2RlID0gcmVxdWlyZSgnLi9ub2RlJyk7XG50cmVlLkFscGhhID0gcmVxdWlyZSgnLi9hbHBoYScpO1xudHJlZS5Db2xvciA9IHJlcXVpcmUoJy4vY29sb3InKTtcbnRyZWUuRGlyZWN0aXZlID0gcmVxdWlyZSgnLi9kaXJlY3RpdmUnKTtcbnRyZWUuRGV0YWNoZWRSdWxlc2V0ID0gcmVxdWlyZSgnLi9kZXRhY2hlZC1ydWxlc2V0Jyk7XG50cmVlLk9wZXJhdGlvbiA9IHJlcXVpcmUoJy4vb3BlcmF0aW9uJyk7XG50cmVlLkRpbWVuc2lvbiA9IHJlcXVpcmUoJy4vZGltZW5zaW9uJyk7XG50cmVlLlVuaXQgPSByZXF1aXJlKCcuL3VuaXQnKTtcbnRyZWUuS2V5d29yZCA9IHJlcXVpcmUoJy4va2V5d29yZCcpO1xudHJlZS5WYXJpYWJsZSA9IHJlcXVpcmUoJy4vdmFyaWFibGUnKTtcbnRyZWUuUnVsZXNldCA9IHJlcXVpcmUoJy4vcnVsZXNldCcpO1xudHJlZS5FbGVtZW50ID0gcmVxdWlyZSgnLi9lbGVtZW50Jyk7XG50cmVlLkF0dHJpYnV0ZSA9IHJlcXVpcmUoJy4vYXR0cmlidXRlJyk7XG50cmVlLkNvbWJpbmF0b3IgPSByZXF1aXJlKCcuL2NvbWJpbmF0b3InKTtcbnRyZWUuU2VsZWN0b3IgPSByZXF1aXJlKCcuL3NlbGVjdG9yJyk7XG50cmVlLlF1b3RlZCA9IHJlcXVpcmUoJy4vcXVvdGVkJyk7XG50cmVlLkV4cHJlc3Npb24gPSByZXF1aXJlKCcuL2V4cHJlc3Npb24nKTtcbnRyZWUuUnVsZSA9IHJlcXVpcmUoJy4vcnVsZScpO1xudHJlZS5DYWxsID0gcmVxdWlyZSgnLi9jYWxsJyk7XG50cmVlLlVSTCA9IHJlcXVpcmUoJy4vdXJsJyk7XG50cmVlLkltcG9ydCA9IHJlcXVpcmUoJy4vaW1wb3J0Jyk7XG50cmVlLm1peGluID0ge1xuICAgIENhbGw6IHJlcXVpcmUoJy4vbWl4aW4tY2FsbCcpLFxuICAgIERlZmluaXRpb246IHJlcXVpcmUoJy4vbWl4aW4tZGVmaW5pdGlvbicpXG59O1xudHJlZS5Db21tZW50ID0gcmVxdWlyZSgnLi9jb21tZW50Jyk7XG50cmVlLkFub255bW91cyA9IHJlcXVpcmUoJy4vYW5vbnltb3VzJyk7XG50cmVlLlZhbHVlID0gcmVxdWlyZSgnLi92YWx1ZScpO1xudHJlZS5KYXZhU2NyaXB0ID0gcmVxdWlyZSgnLi9qYXZhc2NyaXB0Jyk7XG50cmVlLkFzc2lnbm1lbnQgPSByZXF1aXJlKCcuL2Fzc2lnbm1lbnQnKTtcbnRyZWUuQ29uZGl0aW9uID0gcmVxdWlyZSgnLi9jb25kaXRpb24nKTtcbnRyZWUuUGFyZW4gPSByZXF1aXJlKCcuL3BhcmVuJyk7XG50cmVlLk1lZGlhID0gcmVxdWlyZSgnLi9tZWRpYScpO1xudHJlZS5Vbmljb2RlRGVzY3JpcHRvciA9IHJlcXVpcmUoJy4vdW5pY29kZS1kZXNjcmlwdG9yJyk7XG50cmVlLk5lZ2F0aXZlID0gcmVxdWlyZSgnLi9uZWdhdGl2ZScpO1xudHJlZS5FeHRlbmQgPSByZXF1aXJlKCcuL2V4dGVuZCcpO1xudHJlZS5SdWxlc2V0Q2FsbCA9IHJlcXVpcmUoJy4vcnVsZXNldC1jYWxsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gdHJlZTtcblxufSx7XCIuL2FscGhhXCI6NDUsXCIuL2Fub255bW91c1wiOjQ2LFwiLi9hc3NpZ25tZW50XCI6NDcsXCIuL2F0dHJpYnV0ZVwiOjQ4LFwiLi9jYWxsXCI6NDksXCIuL2NvbG9yXCI6NTAsXCIuL2NvbWJpbmF0b3JcIjo1MSxcIi4vY29tbWVudFwiOjUyLFwiLi9jb25kaXRpb25cIjo1MyxcIi4vZGV0YWNoZWQtcnVsZXNldFwiOjU1LFwiLi9kaW1lbnNpb25cIjo1NixcIi4vZGlyZWN0aXZlXCI6NTcsXCIuL2VsZW1lbnRcIjo1OCxcIi4vZXhwcmVzc2lvblwiOjU5LFwiLi9leHRlbmRcIjo2MCxcIi4vaW1wb3J0XCI6NjEsXCIuL2phdmFzY3JpcHRcIjo2MyxcIi4va2V5d29yZFwiOjY1LFwiLi9tZWRpYVwiOjY2LFwiLi9taXhpbi1jYWxsXCI6NjcsXCIuL21peGluLWRlZmluaXRpb25cIjo2OCxcIi4vbmVnYXRpdmVcIjo2OSxcIi4vbm9kZVwiOjcwLFwiLi9vcGVyYXRpb25cIjo3MSxcIi4vcGFyZW5cIjo3MixcIi4vcXVvdGVkXCI6NzMsXCIuL3J1bGVcIjo3NCxcIi4vcnVsZXNldFwiOjc2LFwiLi9ydWxlc2V0LWNhbGxcIjo3NSxcIi4vc2VsZWN0b3JcIjo3NyxcIi4vdW5pY29kZS1kZXNjcmlwdG9yXCI6NzgsXCIuL3VuaXRcIjo3OSxcIi4vdXJsXCI6ODAsXCIuL3ZhbHVlXCI6ODEsXCIuL3ZhcmlhYmxlXCI6ODJ9XSw2MzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgSnNFdmFsTm9kZSA9IHJlcXVpcmUoXCIuL2pzLWV2YWwtbm9kZVwiKSxcbiAgICBEaW1lbnNpb24gPSByZXF1aXJlKFwiLi9kaW1lbnNpb25cIiksXG4gICAgUXVvdGVkID0gcmVxdWlyZShcIi4vcXVvdGVkXCIpLFxuICAgIEFub255bW91cyA9IHJlcXVpcmUoXCIuL2Fub255bW91c1wiKTtcblxudmFyIEphdmFTY3JpcHQgPSBmdW5jdGlvbiAoc3RyaW5nLCBlc2NhcGVkLCBpbmRleCwgY3VycmVudEZpbGVJbmZvKSB7XG4gICAgdGhpcy5lc2NhcGVkID0gZXNjYXBlZDtcbiAgICB0aGlzLmV4cHJlc3Npb24gPSBzdHJpbmc7XG4gICAgdGhpcy5pbmRleCA9IGluZGV4O1xuICAgIHRoaXMuY3VycmVudEZpbGVJbmZvID0gY3VycmVudEZpbGVJbmZvO1xufTtcbkphdmFTY3JpcHQucHJvdG90eXBlID0gbmV3IEpzRXZhbE5vZGUoKTtcbkphdmFTY3JpcHQucHJvdG90eXBlLnR5cGUgPSBcIkphdmFTY3JpcHRcIjtcbkphdmFTY3JpcHQucHJvdG90eXBlLmV2YWwgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIHJlc3VsdCA9IHRoaXMuZXZhbHVhdGVKYXZhU2NyaXB0KHRoaXMuZXhwcmVzc2lvbiwgY29udGV4dCk7XG5cbiAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEaW1lbnNpb24ocmVzdWx0KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBuZXcgUXVvdGVkKCdcIicgKyByZXN1bHQgKyAnXCInLCByZXN1bHQsIHRoaXMuZXNjYXBlZCwgdGhpcy5pbmRleCk7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXMocmVzdWx0LmpvaW4oJywgJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzKHJlc3VsdCk7XG4gICAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBKYXZhU2NyaXB0O1xuXG59LHtcIi4vYW5vbnltb3VzXCI6NDYsXCIuL2RpbWVuc2lvblwiOjU2LFwiLi9qcy1ldmFsLW5vZGVcIjo2NCxcIi4vcXVvdGVkXCI6NzN9XSw2NDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgTm9kZSA9IHJlcXVpcmUoXCIuL25vZGVcIiksXG4gICAgVmFyaWFibGUgPSByZXF1aXJlKFwiLi92YXJpYWJsZVwiKTtcblxudmFyIEpzRXZhbE5vZGUgPSBmdW5jdGlvbigpIHtcbn07XG5Kc0V2YWxOb2RlLnByb3RvdHlwZSA9IG5ldyBOb2RlKCk7XG5cbkpzRXZhbE5vZGUucHJvdG90eXBlLmV2YWx1YXRlSmF2YVNjcmlwdCA9IGZ1bmN0aW9uIChleHByZXNzaW9uLCBjb250ZXh0KSB7XG4gICAgdmFyIHJlc3VsdCxcbiAgICAgICAgdGhhdCA9IHRoaXMsXG4gICAgICAgIGV2YWxDb250ZXh0ID0ge307XG5cbiAgICBpZiAoY29udGV4dC5qYXZhc2NyaXB0RW5hYmxlZCAhPT0gdW5kZWZpbmVkICYmICFjb250ZXh0LmphdmFzY3JpcHRFbmFibGVkKSB7XG4gICAgICAgIHRocm93IHsgbWVzc2FnZTogXCJZb3UgYXJlIHVzaW5nIEphdmFTY3JpcHQsIHdoaWNoIGhhcyBiZWVuIGRpc2FibGVkLlwiLFxuICAgICAgICAgICAgZmlsZW5hbWU6IHRoaXMuY3VycmVudEZpbGVJbmZvLmZpbGVuYW1lLFxuICAgICAgICAgICAgaW5kZXg6IHRoaXMuaW5kZXggfTtcbiAgICB9XG5cbiAgICBleHByZXNzaW9uID0gZXhwcmVzc2lvbi5yZXBsYWNlKC9AXFx7KFtcXHctXSspXFx9L2csIGZ1bmN0aW9uIChfLCBuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGF0LmpzaWZ5KG5ldyBWYXJpYWJsZSgnQCcgKyBuYW1lLCB0aGF0LmluZGV4LCB0aGF0LmN1cnJlbnRGaWxlSW5mbykuZXZhbChjb250ZXh0KSk7XG4gICAgfSk7XG5cbiAgICB0cnkge1xuICAgICAgICBleHByZXNzaW9uID0gbmV3IEZ1bmN0aW9uKCdyZXR1cm4gKCcgKyBleHByZXNzaW9uICsgJyknKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IHsgbWVzc2FnZTogXCJKYXZhU2NyaXB0IGV2YWx1YXRpb24gZXJyb3I6IFwiICsgZS5tZXNzYWdlICsgXCIgZnJvbSBgXCIgKyBleHByZXNzaW9uICsgXCJgXCIgLFxuICAgICAgICAgICAgZmlsZW5hbWU6IHRoaXMuY3VycmVudEZpbGVJbmZvLmZpbGVuYW1lLFxuICAgICAgICAgICAgaW5kZXg6IHRoaXMuaW5kZXggfTtcbiAgICB9XG5cbiAgICB2YXIgdmFyaWFibGVzID0gY29udGV4dC5mcmFtZXNbMF0udmFyaWFibGVzKCk7XG4gICAgZm9yICh2YXIgayBpbiB2YXJpYWJsZXMpIHtcbiAgICAgICAgaWYgKHZhcmlhYmxlcy5oYXNPd25Qcm9wZXJ0eShrKSkge1xuICAgICAgICAgICAgLypqc2hpbnQgbG9vcGZ1bmM6dHJ1ZSAqL1xuICAgICAgICAgICAgZXZhbENvbnRleHRbay5zbGljZSgxKV0gPSB7XG4gICAgICAgICAgICAgICAgdmFsdWU6IHZhcmlhYmxlc1trXS52YWx1ZSxcbiAgICAgICAgICAgICAgICB0b0pTOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlLmV2YWwoY29udGV4dCkudG9DU1MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgcmVzdWx0ID0gZXhwcmVzc2lvbi5jYWxsKGV2YWxDb250ZXh0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IHsgbWVzc2FnZTogXCJKYXZhU2NyaXB0IGV2YWx1YXRpb24gZXJyb3I6ICdcIiArIGUubmFtZSArICc6ICcgKyBlLm1lc3NhZ2UucmVwbGFjZSgvW1wiXS9nLCBcIidcIikgKyBcIidcIiAsXG4gICAgICAgICAgICBmaWxlbmFtZTogdGhpcy5jdXJyZW50RmlsZUluZm8uZmlsZW5hbWUsXG4gICAgICAgICAgICBpbmRleDogdGhpcy5pbmRleCB9O1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufTtcbkpzRXZhbE5vZGUucHJvdG90eXBlLmpzaWZ5ID0gZnVuY3Rpb24gKG9iaikge1xuICAgIGlmIChBcnJheS5pc0FycmF5KG9iai52YWx1ZSkgJiYgKG9iai52YWx1ZS5sZW5ndGggPiAxKSkge1xuICAgICAgICByZXR1cm4gJ1snICsgb2JqLnZhbHVlLm1hcChmdW5jdGlvbiAodikgeyByZXR1cm4gdi50b0NTUygpOyB9KS5qb2luKCcsICcpICsgJ10nO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBvYmoudG9DU1MoKTtcbiAgICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEpzRXZhbE5vZGU7XG5cbn0se1wiLi9ub2RlXCI6NzAsXCIuL3ZhcmlhYmxlXCI6ODJ9XSw2NTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgTm9kZSA9IHJlcXVpcmUoXCIuL25vZGVcIik7XG5cbnZhciBLZXl3b3JkID0gZnVuY3Rpb24gKHZhbHVlKSB7IHRoaXMudmFsdWUgPSB2YWx1ZTsgfTtcbktleXdvcmQucHJvdG90eXBlID0gbmV3IE5vZGUoKTtcbktleXdvcmQucHJvdG90eXBlLnR5cGUgPSBcIktleXdvcmRcIjtcbktleXdvcmQucHJvdG90eXBlLmdlbkNTUyA9IGZ1bmN0aW9uIChjb250ZXh0LCBvdXRwdXQpIHtcbiAgICBpZiAodGhpcy52YWx1ZSA9PT0gJyUnKSB7IHRocm93IHsgdHlwZTogXCJTeW50YXhcIiwgbWVzc2FnZTogXCJJbnZhbGlkICUgd2l0aG91dCBudW1iZXJcIiB9OyB9XG4gICAgb3V0cHV0LmFkZCh0aGlzLnZhbHVlKTtcbn07XG5cbktleXdvcmQuVHJ1ZSA9IG5ldyBLZXl3b3JkKCd0cnVlJyk7XG5LZXl3b3JkLkZhbHNlID0gbmV3IEtleXdvcmQoJ2ZhbHNlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gS2V5d29yZDtcblxufSx7XCIuL25vZGVcIjo3MH1dLDY2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBSdWxlc2V0ID0gcmVxdWlyZShcIi4vcnVsZXNldFwiKSxcbiAgICBWYWx1ZSA9IHJlcXVpcmUoXCIuL3ZhbHVlXCIpLFxuICAgIFNlbGVjdG9yID0gcmVxdWlyZShcIi4vc2VsZWN0b3JcIiksXG4gICAgQW5vbnltb3VzID0gcmVxdWlyZShcIi4vYW5vbnltb3VzXCIpLFxuICAgIEV4cHJlc3Npb24gPSByZXF1aXJlKFwiLi9leHByZXNzaW9uXCIpLFxuICAgIERpcmVjdGl2ZSA9IHJlcXVpcmUoXCIuL2RpcmVjdGl2ZVwiKTtcblxudmFyIE1lZGlhID0gZnVuY3Rpb24gKHZhbHVlLCBmZWF0dXJlcywgaW5kZXgsIGN1cnJlbnRGaWxlSW5mbywgdmlzaWJpbGl0eUluZm8pIHtcbiAgICB0aGlzLmluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy5jdXJyZW50RmlsZUluZm8gPSBjdXJyZW50RmlsZUluZm87XG5cbiAgICB2YXIgc2VsZWN0b3JzID0gKG5ldyBTZWxlY3RvcihbXSwgbnVsbCwgbnVsbCwgdGhpcy5pbmRleCwgdGhpcy5jdXJyZW50RmlsZUluZm8pKS5jcmVhdGVFbXB0eVNlbGVjdG9ycygpO1xuXG4gICAgdGhpcy5mZWF0dXJlcyA9IG5ldyBWYWx1ZShmZWF0dXJlcyk7XG4gICAgdGhpcy5ydWxlcyA9IFtuZXcgUnVsZXNldChzZWxlY3RvcnMsIHZhbHVlKV07XG4gICAgdGhpcy5ydWxlc1swXS5hbGxvd0ltcG9ydHMgPSB0cnVlO1xuICAgIHRoaXMuY29weVZpc2liaWxpdHlJbmZvKHZpc2liaWxpdHlJbmZvKTtcbiAgICB0aGlzLmFsbG93Um9vdCA9IHRydWU7XG59O1xuTWVkaWEucHJvdG90eXBlID0gbmV3IERpcmVjdGl2ZSgpO1xuTWVkaWEucHJvdG90eXBlLnR5cGUgPSBcIk1lZGlhXCI7XG5NZWRpYS5wcm90b3R5cGUuaXNSdWxlc2V0TGlrZSA9IHRydWU7XG5NZWRpYS5wcm90b3R5cGUuYWNjZXB0ID0gZnVuY3Rpb24gKHZpc2l0b3IpIHtcbiAgICBpZiAodGhpcy5mZWF0dXJlcykge1xuICAgICAgICB0aGlzLmZlYXR1cmVzID0gdmlzaXRvci52aXNpdCh0aGlzLmZlYXR1cmVzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucnVsZXMpIHtcbiAgICAgICAgdGhpcy5ydWxlcyA9IHZpc2l0b3IudmlzaXRBcnJheSh0aGlzLnJ1bGVzKTtcbiAgICB9XG59O1xuTWVkaWEucHJvdG90eXBlLmdlbkNTUyA9IGZ1bmN0aW9uIChjb250ZXh0LCBvdXRwdXQpIHtcbiAgICBvdXRwdXQuYWRkKCdAbWVkaWEgJywgdGhpcy5jdXJyZW50RmlsZUluZm8sIHRoaXMuaW5kZXgpO1xuICAgIHRoaXMuZmVhdHVyZXMuZ2VuQ1NTKGNvbnRleHQsIG91dHB1dCk7XG4gICAgdGhpcy5vdXRwdXRSdWxlc2V0KGNvbnRleHQsIG91dHB1dCwgdGhpcy5ydWxlcyk7XG59O1xuTWVkaWEucHJvdG90eXBlLmV2YWwgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIGlmICghY29udGV4dC5tZWRpYUJsb2Nrcykge1xuICAgICAgICBjb250ZXh0Lm1lZGlhQmxvY2tzID0gW107XG4gICAgICAgIGNvbnRleHQubWVkaWFQYXRoID0gW107XG4gICAgfVxuXG4gICAgdmFyIG1lZGlhID0gbmV3IE1lZGlhKG51bGwsIFtdLCB0aGlzLmluZGV4LCB0aGlzLmN1cnJlbnRGaWxlSW5mbywgdGhpcy52aXNpYmlsaXR5SW5mbygpKTtcbiAgICBpZiAodGhpcy5kZWJ1Z0luZm8pIHtcbiAgICAgICAgdGhpcy5ydWxlc1swXS5kZWJ1Z0luZm8gPSB0aGlzLmRlYnVnSW5mbztcbiAgICAgICAgbWVkaWEuZGVidWdJbmZvID0gdGhpcy5kZWJ1Z0luZm87XG4gICAgfVxuICAgIHZhciBzdHJpY3RNYXRoQnlwYXNzID0gZmFsc2U7XG4gICAgaWYgKCFjb250ZXh0LnN0cmljdE1hdGgpIHtcbiAgICAgICAgc3RyaWN0TWF0aEJ5cGFzcyA9IHRydWU7XG4gICAgICAgIGNvbnRleHQuc3RyaWN0TWF0aCA9IHRydWU7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIG1lZGlhLmZlYXR1cmVzID0gdGhpcy5mZWF0dXJlcy5ldmFsKGNvbnRleHQpO1xuICAgIH1cbiAgICBmaW5hbGx5IHtcbiAgICAgICAgaWYgKHN0cmljdE1hdGhCeXBhc3MpIHtcbiAgICAgICAgICAgIGNvbnRleHQuc3RyaWN0TWF0aCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29udGV4dC5tZWRpYVBhdGgucHVzaChtZWRpYSk7XG4gICAgY29udGV4dC5tZWRpYUJsb2Nrcy5wdXNoKG1lZGlhKTtcblxuICAgIHRoaXMucnVsZXNbMF0uZnVuY3Rpb25SZWdpc3RyeSA9IGNvbnRleHQuZnJhbWVzWzBdLmZ1bmN0aW9uUmVnaXN0cnkuaW5oZXJpdCgpO1xuICAgIGNvbnRleHQuZnJhbWVzLnVuc2hpZnQodGhpcy5ydWxlc1swXSk7XG4gICAgbWVkaWEucnVsZXMgPSBbdGhpcy5ydWxlc1swXS5ldmFsKGNvbnRleHQpXTtcbiAgICBjb250ZXh0LmZyYW1lcy5zaGlmdCgpO1xuXG4gICAgY29udGV4dC5tZWRpYVBhdGgucG9wKCk7XG5cbiAgICByZXR1cm4gY29udGV4dC5tZWRpYVBhdGgubGVuZ3RoID09PSAwID8gbWVkaWEuZXZhbFRvcChjb250ZXh0KSA6XG4gICAgICAgICAgICAgICAgbWVkaWEuZXZhbE5lc3RlZChjb250ZXh0KTtcbn07XG5NZWRpYS5wcm90b3R5cGUuZXZhbFRvcCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgdmFyIHJlc3VsdCA9IHRoaXM7XG5cbiAgICAvLyBSZW5kZXIgYWxsIGRlcGVuZGVudCBNZWRpYSBibG9ja3MuXG4gICAgaWYgKGNvbnRleHQubWVkaWFCbG9ja3MubGVuZ3RoID4gMSkge1xuICAgICAgICB2YXIgc2VsZWN0b3JzID0gKG5ldyBTZWxlY3RvcihbXSwgbnVsbCwgbnVsbCwgdGhpcy5pbmRleCwgdGhpcy5jdXJyZW50RmlsZUluZm8pKS5jcmVhdGVFbXB0eVNlbGVjdG9ycygpO1xuICAgICAgICByZXN1bHQgPSBuZXcgUnVsZXNldChzZWxlY3RvcnMsIGNvbnRleHQubWVkaWFCbG9ja3MpO1xuICAgICAgICByZXN1bHQubXVsdGlNZWRpYSA9IHRydWU7XG4gICAgICAgIHJlc3VsdC5jb3B5VmlzaWJpbGl0eUluZm8odGhpcy52aXNpYmlsaXR5SW5mbygpKTtcbiAgICB9XG5cbiAgICBkZWxldGUgY29udGV4dC5tZWRpYUJsb2NrcztcbiAgICBkZWxldGUgY29udGV4dC5tZWRpYVBhdGg7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufTtcbk1lZGlhLnByb3RvdHlwZS5ldmFsTmVzdGVkID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgaSwgdmFsdWUsXG4gICAgICAgIHBhdGggPSBjb250ZXh0Lm1lZGlhUGF0aC5jb25jYXQoW3RoaXNdKTtcblxuICAgIC8vIEV4dHJhY3QgdGhlIG1lZGlhLXF1ZXJ5IGNvbmRpdGlvbnMgc2VwYXJhdGVkIHdpdGggYCxgIChPUikuXG4gICAgZm9yIChpID0gMDsgaSA8IHBhdGgubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFsdWUgPSBwYXRoW2ldLmZlYXR1cmVzIGluc3RhbmNlb2YgVmFsdWUgP1xuICAgICAgICAgICAgICAgICAgICBwYXRoW2ldLmZlYXR1cmVzLnZhbHVlIDogcGF0aFtpXS5mZWF0dXJlcztcbiAgICAgICAgcGF0aFtpXSA9IEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbdmFsdWVdO1xuICAgIH1cblxuICAgIC8vIFRyYWNlIGFsbCBwZXJtdXRhdGlvbnMgdG8gZ2VuZXJhdGUgdGhlIHJlc3VsdGluZyBtZWRpYS1xdWVyeS5cbiAgICAvL1xuICAgIC8vIChhLCBiIGFuZCBjKSB3aXRoIG5lc3RlZCAoZCwgZSkgLT5cbiAgICAvLyAgICBhIGFuZCBkXG4gICAgLy8gICAgYSBhbmQgZVxuICAgIC8vICAgIGIgYW5kIGMgYW5kIGRcbiAgICAvLyAgICBiIGFuZCBjIGFuZCBlXG4gICAgdGhpcy5mZWF0dXJlcyA9IG5ldyBWYWx1ZSh0aGlzLnBlcm11dGUocGF0aCkubWFwKGZ1bmN0aW9uIChwYXRoKSB7XG4gICAgICAgIHBhdGggPSBwYXRoLm1hcChmdW5jdGlvbiAoZnJhZ21lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBmcmFnbWVudC50b0NTUyA/IGZyYWdtZW50IDogbmV3IEFub255bW91cyhmcmFnbWVudCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGZvciAoaSA9IHBhdGgubGVuZ3RoIC0gMTsgaSA+IDA7IGktLSkge1xuICAgICAgICAgICAgcGF0aC5zcGxpY2UoaSwgMCwgbmV3IEFub255bW91cyhcImFuZFwiKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IEV4cHJlc3Npb24ocGF0aCk7XG4gICAgfSkpO1xuXG4gICAgLy8gRmFrZSBhIHRyZWUtbm9kZSB0aGF0IGRvZXNuJ3Qgb3V0cHV0IGFueXRoaW5nLlxuICAgIHJldHVybiBuZXcgUnVsZXNldChbXSwgW10pO1xufTtcbk1lZGlhLnByb3RvdHlwZS5wZXJtdXRlID0gZnVuY3Rpb24gKGFycikge1xuICAgIGlmIChhcnIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9IGVsc2UgaWYgKGFyci5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIGFyclswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICAgIHZhciByZXN0ID0gdGhpcy5wZXJtdXRlKGFyci5zbGljZSgxKSk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBhcnJbMF0ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChbYXJyWzBdW2pdXS5jb25jYXQocmVzdFtpXSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxufTtcbk1lZGlhLnByb3RvdHlwZS5idWJibGVTZWxlY3RvcnMgPSBmdW5jdGlvbiAoc2VsZWN0b3JzKSB7XG4gICAgaWYgKCFzZWxlY3RvcnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnJ1bGVzID0gW25ldyBSdWxlc2V0KHNlbGVjdG9ycy5zbGljZSgwKSwgW3RoaXMucnVsZXNbMF1dKV07XG59O1xubW9kdWxlLmV4cG9ydHMgPSBNZWRpYTtcblxufSx7XCIuL2Fub255bW91c1wiOjQ2LFwiLi9kaXJlY3RpdmVcIjo1NyxcIi4vZXhwcmVzc2lvblwiOjU5LFwiLi9ydWxlc2V0XCI6NzYsXCIuL3NlbGVjdG9yXCI6NzcsXCIuL3ZhbHVlXCI6ODF9XSw2NzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgTm9kZSA9IHJlcXVpcmUoXCIuL25vZGVcIiksXG4gICAgU2VsZWN0b3IgPSByZXF1aXJlKFwiLi9zZWxlY3RvclwiKSxcbiAgICBNaXhpbkRlZmluaXRpb24gPSByZXF1aXJlKFwiLi9taXhpbi1kZWZpbml0aW9uXCIpLFxuICAgIGRlZmF1bHRGdW5jID0gcmVxdWlyZShcIi4uL2Z1bmN0aW9ucy9kZWZhdWx0XCIpO1xuXG52YXIgTWl4aW5DYWxsID0gZnVuY3Rpb24gKGVsZW1lbnRzLCBhcmdzLCBpbmRleCwgY3VycmVudEZpbGVJbmZvLCBpbXBvcnRhbnQpIHtcbiAgICB0aGlzLnNlbGVjdG9yID0gbmV3IFNlbGVjdG9yKGVsZW1lbnRzKTtcbiAgICB0aGlzLmFyZ3VtZW50cyA9IGFyZ3MgfHwgW107XG4gICAgdGhpcy5pbmRleCA9IGluZGV4O1xuICAgIHRoaXMuY3VycmVudEZpbGVJbmZvID0gY3VycmVudEZpbGVJbmZvO1xuICAgIHRoaXMuaW1wb3J0YW50ID0gaW1wb3J0YW50O1xuICAgIHRoaXMuYWxsb3dSb290ID0gdHJ1ZTtcbn07XG5NaXhpbkNhbGwucHJvdG90eXBlID0gbmV3IE5vZGUoKTtcbk1peGluQ2FsbC5wcm90b3R5cGUudHlwZSA9IFwiTWl4aW5DYWxsXCI7XG5NaXhpbkNhbGwucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uICh2aXNpdG9yKSB7XG4gICAgaWYgKHRoaXMuc2VsZWN0b3IpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RvciA9IHZpc2l0b3IudmlzaXQodGhpcy5zZWxlY3Rvcik7XG4gICAgfVxuICAgIGlmICh0aGlzLmFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5hcmd1bWVudHMgPSB2aXNpdG9yLnZpc2l0QXJyYXkodGhpcy5hcmd1bWVudHMpO1xuICAgIH1cbn07XG5NaXhpbkNhbGwucHJvdG90eXBlLmV2YWwgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHZhciBtaXhpbnMsIG1peGluLCBtaXhpblBhdGgsIGFyZ3MgPSBbXSwgYXJnLCBhcmdWYWx1ZSxcbiAgICAgICAgcnVsZXMgPSBbXSwgbWF0Y2ggPSBmYWxzZSwgaSwgbSwgZiwgaXNSZWN1cnNpdmUsIGlzT25lRm91bmQsXG4gICAgICAgIGNhbmRpZGF0ZXMgPSBbXSwgY2FuZGlkYXRlLCBjb25kaXRpb25SZXN1bHQgPSBbXSwgZGVmYXVsdFJlc3VsdCwgZGVmRmFsc2VFaXRoZXJDYXNlID0gLTEsXG4gICAgICAgIGRlZk5vbmUgPSAwLCBkZWZUcnVlID0gMSwgZGVmRmFsc2UgPSAyLCBjb3VudCwgb3JpZ2luYWxSdWxlc2V0LCBub0FyZ3VtZW50c0ZpbHRlcjtcblxuICAgIGZ1bmN0aW9uIGNhbGNEZWZHcm91cChtaXhpbiwgbWl4aW5QYXRoKSB7XG4gICAgICAgIHZhciBmLCBwLCBuYW1lc3BhY2U7XG5cbiAgICAgICAgZm9yIChmID0gMDsgZiA8IDI7IGYrKykge1xuICAgICAgICAgICAgY29uZGl0aW9uUmVzdWx0W2ZdID0gdHJ1ZTtcbiAgICAgICAgICAgIGRlZmF1bHRGdW5jLnZhbHVlKGYpO1xuICAgICAgICAgICAgZm9yIChwID0gMDsgcCA8IG1peGluUGF0aC5sZW5ndGggJiYgY29uZGl0aW9uUmVzdWx0W2ZdOyBwKyspIHtcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2UgPSBtaXhpblBhdGhbcF07XG4gICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZS5tYXRjaENvbmRpdGlvbikge1xuICAgICAgICAgICAgICAgICAgICBjb25kaXRpb25SZXN1bHRbZl0gPSBjb25kaXRpb25SZXN1bHRbZl0gJiYgbmFtZXNwYWNlLm1hdGNoQ29uZGl0aW9uKG51bGwsIGNvbnRleHQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtaXhpbi5tYXRjaENvbmRpdGlvbikge1xuICAgICAgICAgICAgICAgIGNvbmRpdGlvblJlc3VsdFtmXSA9IGNvbmRpdGlvblJlc3VsdFtmXSAmJiBtaXhpbi5tYXRjaENvbmRpdGlvbihhcmdzLCBjb250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoY29uZGl0aW9uUmVzdWx0WzBdIHx8IGNvbmRpdGlvblJlc3VsdFsxXSkge1xuICAgICAgICAgICAgaWYgKGNvbmRpdGlvblJlc3VsdFswXSAhPSBjb25kaXRpb25SZXN1bHRbMV0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29uZGl0aW9uUmVzdWx0WzFdID9cbiAgICAgICAgICAgICAgICAgICAgZGVmVHJ1ZSA6IGRlZkZhbHNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gZGVmTm9uZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmRmFsc2VFaXRoZXJDYXNlO1xuICAgIH1cblxuICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLmFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBhcmcgPSB0aGlzLmFyZ3VtZW50c1tpXTtcbiAgICAgICAgYXJnVmFsdWUgPSBhcmcudmFsdWUuZXZhbChjb250ZXh0KTtcbiAgICAgICAgaWYgKGFyZy5leHBhbmQgJiYgQXJyYXkuaXNBcnJheShhcmdWYWx1ZS52YWx1ZSkpIHtcbiAgICAgICAgICAgIGFyZ1ZhbHVlID0gYXJnVmFsdWUudmFsdWU7XG4gICAgICAgICAgICBmb3IgKG0gPSAwOyBtIDwgYXJnVmFsdWUubGVuZ3RoOyBtKyspIHtcbiAgICAgICAgICAgICAgICBhcmdzLnB1c2goe3ZhbHVlOiBhcmdWYWx1ZVttXX0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYXJncy5wdXNoKHtuYW1lOiBhcmcubmFtZSwgdmFsdWU6IGFyZ1ZhbHVlfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBub0FyZ3VtZW50c0ZpbHRlciA9IGZ1bmN0aW9uKHJ1bGUpIHtyZXR1cm4gcnVsZS5tYXRjaEFyZ3MobnVsbCwgY29udGV4dCk7fTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBjb250ZXh0LmZyYW1lcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoKG1peGlucyA9IGNvbnRleHQuZnJhbWVzW2ldLmZpbmQodGhpcy5zZWxlY3RvciwgbnVsbCwgbm9Bcmd1bWVudHNGaWx0ZXIpKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBpc09uZUZvdW5kID0gdHJ1ZTtcblxuICAgICAgICAgICAgLy8gVG8gbWFrZSBgZGVmYXVsdCgpYCBmdW5jdGlvbiBpbmRlcGVuZGVudCBvZiBkZWZpbml0aW9uIG9yZGVyIHdlIGhhdmUgdHdvIFwic3VicGFzc2VzXCIgaGVyZS5cbiAgICAgICAgICAgIC8vIEF0IGZpcnN0IHdlIGV2YWx1YXRlIGVhY2ggZ3VhcmQgKnR3aWNlKiAod2l0aCBgZGVmYXVsdCgpID09IHRydWVgIGFuZCBgZGVmYXVsdCgpID09IGZhbHNlYCksXG4gICAgICAgICAgICAvLyBhbmQgYnVpbGQgY2FuZGlkYXRlIGxpc3Qgd2l0aCBjb3JyZXNwb25kaW5nIGZsYWdzLiBUaGVuLCB3aGVuIHdlIGtub3cgYWxsIHBvc3NpYmxlIG1hdGNoZXMsXG4gICAgICAgICAgICAvLyB3ZSBtYWtlIGEgZmluYWwgZGVjaXNpb24uXG5cbiAgICAgICAgICAgIGZvciAobSA9IDA7IG0gPCBtaXhpbnMubGVuZ3RoOyBtKyspIHtcbiAgICAgICAgICAgICAgICBtaXhpbiA9IG1peGluc1ttXS5ydWxlO1xuICAgICAgICAgICAgICAgIG1peGluUGF0aCA9IG1peGluc1ttXS5wYXRoO1xuICAgICAgICAgICAgICAgIGlzUmVjdXJzaXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZm9yIChmID0gMDsgZiA8IGNvbnRleHQuZnJhbWVzLmxlbmd0aDsgZisrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgoIShtaXhpbiBpbnN0YW5jZW9mIE1peGluRGVmaW5pdGlvbikpICYmIG1peGluID09PSAoY29udGV4dC5mcmFtZXNbZl0ub3JpZ2luYWxSdWxlc2V0IHx8IGNvbnRleHQuZnJhbWVzW2ZdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNSZWN1cnNpdmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGlzUmVjdXJzaXZlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChtaXhpbi5tYXRjaEFyZ3MoYXJncywgY29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FuZGlkYXRlID0ge21peGluOiBtaXhpbiwgZ3JvdXA6IGNhbGNEZWZHcm91cChtaXhpbiwgbWl4aW5QYXRoKX07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZS5ncm91cCAhPT0gZGVmRmFsc2VFaXRoZXJDYXNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYW5kaWRhdGVzLnB1c2goY2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIG1hdGNoID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGRlZmF1bHRGdW5jLnJlc2V0KCk7XG5cbiAgICAgICAgICAgIGNvdW50ID0gWzAsIDAsIDBdO1xuICAgICAgICAgICAgZm9yIChtID0gMDsgbSA8IGNhbmRpZGF0ZXMubGVuZ3RoOyBtKyspIHtcbiAgICAgICAgICAgICAgICBjb3VudFtjYW5kaWRhdGVzW21dLmdyb3VwXSsrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoY291bnRbZGVmTm9uZV0gPiAwKSB7XG4gICAgICAgICAgICAgICAgZGVmYXVsdFJlc3VsdCA9IGRlZkZhbHNlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0ID0gZGVmVHJ1ZTtcbiAgICAgICAgICAgICAgICBpZiAoKGNvdW50W2RlZlRydWVdICsgY291bnRbZGVmRmFsc2VdKSA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgeyB0eXBlOiAnUnVudGltZScsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiAnQW1iaWd1b3VzIHVzZSBvZiBgZGVmYXVsdCgpYCBmb3VuZCB3aGVuIG1hdGNoaW5nIGZvciBgJyArIHRoaXMuZm9ybWF0KGFyZ3MpICsgJ2AnLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXg6IHRoaXMuaW5kZXgsIGZpbGVuYW1lOiB0aGlzLmN1cnJlbnRGaWxlSW5mby5maWxlbmFtZSB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChtID0gMDsgbSA8IGNhbmRpZGF0ZXMubGVuZ3RoOyBtKyspIHtcbiAgICAgICAgICAgICAgICBjYW5kaWRhdGUgPSBjYW5kaWRhdGVzW21dLmdyb3VwO1xuICAgICAgICAgICAgICAgIGlmICgoY2FuZGlkYXRlID09PSBkZWZOb25lKSB8fCAoY2FuZGlkYXRlID09PSBkZWZhdWx0UmVzdWx0KSkge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWl4aW4gPSBjYW5kaWRhdGVzW21dLm1peGluO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEobWl4aW4gaW5zdGFuY2VvZiBNaXhpbkRlZmluaXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxSdWxlc2V0ID0gbWl4aW4ub3JpZ2luYWxSdWxlc2V0IHx8IG1peGluO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1peGluID0gbmV3IE1peGluRGVmaW5pdGlvbihcIlwiLCBbXSwgbWl4aW4ucnVsZXMsIG51bGwsIGZhbHNlLCBudWxsLCBvcmlnaW5hbFJ1bGVzZXQudmlzaWJpbGl0eUluZm8oKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWl4aW4ub3JpZ2luYWxSdWxlc2V0ID0gb3JpZ2luYWxSdWxlc2V0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld1J1bGVzID0gbWl4aW4uZXZhbENhbGwoY29udGV4dCwgYXJncywgdGhpcy5pbXBvcnRhbnQpLnJ1bGVzO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2V0VmlzaWJpbGl0eVRvUmVwbGFjZW1lbnQobmV3UnVsZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkocnVsZXMsIG5ld1J1bGVzKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgeyBtZXNzYWdlOiBlLm1lc3NhZ2UsIGluZGV4OiB0aGlzLmluZGV4LCBmaWxlbmFtZTogdGhpcy5jdXJyZW50RmlsZUluZm8uZmlsZW5hbWUsIHN0YWNrOiBlLnN0YWNrIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBydWxlcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNPbmVGb3VuZCkge1xuICAgICAgICB0aHJvdyB7IHR5cGU6ICAgICdSdW50aW1lJyxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdObyBtYXRjaGluZyBkZWZpbml0aW9uIHdhcyBmb3VuZCBmb3IgYCcgKyB0aGlzLmZvcm1hdChhcmdzKSArICdgJyxcbiAgICAgICAgICAgIGluZGV4OiAgIHRoaXMuaW5kZXgsIGZpbGVuYW1lOiB0aGlzLmN1cnJlbnRGaWxlSW5mby5maWxlbmFtZSB9O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IHsgdHlwZTogICAgJ05hbWUnLFxuICAgICAgICAgICAgbWVzc2FnZTogdGhpcy5zZWxlY3Rvci50b0NTUygpLnRyaW0oKSArIFwiIGlzIHVuZGVmaW5lZFwiLFxuICAgICAgICAgICAgaW5kZXg6ICAgdGhpcy5pbmRleCwgZmlsZW5hbWU6IHRoaXMuY3VycmVudEZpbGVJbmZvLmZpbGVuYW1lIH07XG4gICAgfVxufTtcblxuTWl4aW5DYWxsLnByb3RvdHlwZS5fc2V0VmlzaWJpbGl0eVRvUmVwbGFjZW1lbnQgPSBmdW5jdGlvbiAocmVwbGFjZW1lbnQpIHtcbiAgICB2YXIgaSwgcnVsZTtcbiAgICBpZiAodGhpcy5ibG9ja3NWaXNpYmlsaXR5KCkpIHtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHJlcGxhY2VtZW50Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBydWxlID0gcmVwbGFjZW1lbnRbaV07XG4gICAgICAgICAgICBydWxlLmFkZFZpc2liaWxpdHlCbG9jaygpO1xuICAgICAgICB9XG4gICAgfVxufTtcbk1peGluQ2FsbC5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rvci50b0NTUygpLnRyaW0oKSArICcoJyArXG4gICAgICAgIChhcmdzID8gYXJncy5tYXAoZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICAgIHZhciBhcmdWYWx1ZSA9IFwiXCI7XG4gICAgICAgICAgICBpZiAoYS5uYW1lKSB7XG4gICAgICAgICAgICAgICAgYXJnVmFsdWUgKz0gYS5uYW1lICsgXCI6XCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYS52YWx1ZS50b0NTUykge1xuICAgICAgICAgICAgICAgIGFyZ1ZhbHVlICs9IGEudmFsdWUudG9DU1MoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXJnVmFsdWUgKz0gXCI/Pz9cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhcmdWYWx1ZTtcbiAgICAgICAgfSkuam9pbignLCAnKSA6IFwiXCIpICsgXCIpXCI7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBNaXhpbkNhbGw7XG5cbn0se1wiLi4vZnVuY3Rpb25zL2RlZmF1bHRcIjoyMCxcIi4vbWl4aW4tZGVmaW5pdGlvblwiOjY4LFwiLi9ub2RlXCI6NzAsXCIuL3NlbGVjdG9yXCI6Nzd9XSw2ODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgU2VsZWN0b3IgPSByZXF1aXJlKFwiLi9zZWxlY3RvclwiKSxcbiAgICBFbGVtZW50ID0gcmVxdWlyZShcIi4vZWxlbWVudFwiKSxcbiAgICBSdWxlc2V0ID0gcmVxdWlyZShcIi4vcnVsZXNldFwiKSxcbiAgICBSdWxlID0gcmVxdWlyZShcIi4vcnVsZVwiKSxcbiAgICBFeHByZXNzaW9uID0gcmVxdWlyZShcIi4vZXhwcmVzc2lvblwiKSxcbiAgICBjb250ZXh0cyA9IHJlcXVpcmUoXCIuLi9jb250ZXh0c1wiKTtcblxudmFyIERlZmluaXRpb24gPSBmdW5jdGlvbiAobmFtZSwgcGFyYW1zLCBydWxlcywgY29uZGl0aW9uLCB2YXJpYWRpYywgZnJhbWVzLCB2aXNpYmlsaXR5SW5mbykge1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5zZWxlY3RvcnMgPSBbbmV3IFNlbGVjdG9yKFtuZXcgRWxlbWVudChudWxsLCBuYW1lLCB0aGlzLmluZGV4LCB0aGlzLmN1cnJlbnRGaWxlSW5mbyldKV07XG4gICAgdGhpcy5wYXJhbXMgPSBwYXJhbXM7XG4gICAgdGhpcy5jb25kaXRpb24gPSBjb25kaXRpb247XG4gICAgdGhpcy52YXJpYWRpYyA9IHZhcmlhZGljO1xuICAgIHRoaXMuYXJpdHkgPSBwYXJhbXMubGVuZ3RoO1xuICAgIHRoaXMucnVsZXMgPSBydWxlcztcbiAgICB0aGlzLl9sb29rdXBzID0ge307XG4gICAgdmFyIG9wdGlvbmFsUGFyYW1ldGVycyA9IFtdO1xuICAgIHRoaXMucmVxdWlyZWQgPSBwYXJhbXMucmVkdWNlKGZ1bmN0aW9uIChjb3VudCwgcCkge1xuICAgICAgICBpZiAoIXAubmFtZSB8fCAocC5uYW1lICYmICFwLnZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNvdW50ICsgMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG9wdGlvbmFsUGFyYW1ldGVycy5wdXNoKHAubmFtZSk7XG4gICAgICAgICAgICByZXR1cm4gY291bnQ7XG4gICAgICAgIH1cbiAgICB9LCAwKTtcbiAgICB0aGlzLm9wdGlvbmFsUGFyYW1ldGVycyA9IG9wdGlvbmFsUGFyYW1ldGVycztcbiAgICB0aGlzLmZyYW1lcyA9IGZyYW1lcztcbiAgICB0aGlzLmNvcHlWaXNpYmlsaXR5SW5mbyh2aXNpYmlsaXR5SW5mbyk7XG4gICAgdGhpcy5hbGxvd1Jvb3QgPSB0cnVlO1xufTtcbkRlZmluaXRpb24ucHJvdG90eXBlID0gbmV3IFJ1bGVzZXQoKTtcbkRlZmluaXRpb24ucHJvdG90eXBlLnR5cGUgPSBcIk1peGluRGVmaW5pdGlvblwiO1xuRGVmaW5pdGlvbi5wcm90b3R5cGUuZXZhbEZpcnN0ID0gdHJ1ZTtcbkRlZmluaXRpb24ucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uICh2aXNpdG9yKSB7XG4gICAgaWYgKHRoaXMucGFyYW1zICYmIHRoaXMucGFyYW1zLmxlbmd0aCkge1xuICAgICAgICB0aGlzLnBhcmFtcyA9IHZpc2l0b3IudmlzaXRBcnJheSh0aGlzLnBhcmFtcyk7XG4gICAgfVxuICAgIHRoaXMucnVsZXMgPSB2aXNpdG9yLnZpc2l0QXJyYXkodGhpcy5ydWxlcyk7XG4gICAgaWYgKHRoaXMuY29uZGl0aW9uKSB7XG4gICAgICAgIHRoaXMuY29uZGl0aW9uID0gdmlzaXRvci52aXNpdCh0aGlzLmNvbmRpdGlvbik7XG4gICAgfVxufTtcbkRlZmluaXRpb24ucHJvdG90eXBlLmV2YWxQYXJhbXMgPSBmdW5jdGlvbiAoY29udGV4dCwgbWl4aW5FbnYsIGFyZ3MsIGV2YWxkQXJndW1lbnRzKSB7XG4gICAgLypqc2hpbnQgYm9zczp0cnVlICovXG4gICAgdmFyIGZyYW1lID0gbmV3IFJ1bGVzZXQobnVsbCwgbnVsbCksXG4gICAgICAgIHZhcmFyZ3MsIGFyZyxcbiAgICAgICAgcGFyYW1zID0gdGhpcy5wYXJhbXMuc2xpY2UoMCksXG4gICAgICAgIGksIGosIHZhbCwgbmFtZSwgaXNOYW1lZEZvdW5kLCBhcmdJbmRleCwgYXJnc0xlbmd0aCA9IDA7XG5cbiAgICBpZiAobWl4aW5FbnYuZnJhbWVzICYmIG1peGluRW52LmZyYW1lc1swXSAmJiBtaXhpbkVudi5mcmFtZXNbMF0uZnVuY3Rpb25SZWdpc3RyeSkge1xuICAgICAgICBmcmFtZS5mdW5jdGlvblJlZ2lzdHJ5ID0gbWl4aW5FbnYuZnJhbWVzWzBdLmZ1bmN0aW9uUmVnaXN0cnkuaW5oZXJpdCgpO1xuICAgIH1cbiAgICBtaXhpbkVudiA9IG5ldyBjb250ZXh0cy5FdmFsKG1peGluRW52LCBbZnJhbWVdLmNvbmNhdChtaXhpbkVudi5mcmFtZXMpKTtcblxuICAgIGlmIChhcmdzKSB7XG4gICAgICAgIGFyZ3MgPSBhcmdzLnNsaWNlKDApO1xuICAgICAgICBhcmdzTGVuZ3RoID0gYXJncy5sZW5ndGg7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGFyZ3NMZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnID0gYXJnc1tpXTtcbiAgICAgICAgICAgIGlmIChuYW1lID0gKGFyZyAmJiBhcmcubmFtZSkpIHtcbiAgICAgICAgICAgICAgICBpc05hbWVkRm91bmQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgcGFyYW1zLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghZXZhbGRBcmd1bWVudHNbal0gJiYgbmFtZSA9PT0gcGFyYW1zW2pdLm5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2YWxkQXJndW1lbnRzW2pdID0gYXJnLnZhbHVlLmV2YWwoY29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5wcmVwZW5kUnVsZShuZXcgUnVsZShuYW1lLCBhcmcudmFsdWUuZXZhbChjb250ZXh0KSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNOYW1lZEZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChpc05hbWVkRm91bmQpIHtcbiAgICAgICAgICAgICAgICAgICAgYXJncy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgeyB0eXBlOiAnUnVudGltZScsIG1lc3NhZ2U6IFwiTmFtZWQgYXJndW1lbnQgZm9yIFwiICsgdGhpcy5uYW1lICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcgJyArIGFyZ3NbaV0ubmFtZSArICcgbm90IGZvdW5kJyB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBhcmdJbmRleCA9IDA7XG4gICAgZm9yIChpID0gMDsgaSA8IHBhcmFtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoZXZhbGRBcmd1bWVudHNbaV0pIHsgY29udGludWU7IH1cblxuICAgICAgICBhcmcgPSBhcmdzICYmIGFyZ3NbYXJnSW5kZXhdO1xuXG4gICAgICAgIGlmIChuYW1lID0gcGFyYW1zW2ldLm5hbWUpIHtcbiAgICAgICAgICAgIGlmIChwYXJhbXNbaV0udmFyaWFkaWMpIHtcbiAgICAgICAgICAgICAgICB2YXJhcmdzID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChqID0gYXJnSW5kZXg7IGogPCBhcmdzTGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyYXJncy5wdXNoKGFyZ3Nbal0udmFsdWUuZXZhbChjb250ZXh0KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZyYW1lLnByZXBlbmRSdWxlKG5ldyBSdWxlKG5hbWUsIG5ldyBFeHByZXNzaW9uKHZhcmFyZ3MpLmV2YWwoY29udGV4dCkpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsID0gYXJnICYmIGFyZy52YWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAodmFsKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbCA9IHZhbC5ldmFsKGNvbnRleHQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFyYW1zW2ldLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbCA9IHBhcmFtc1tpXS52YWx1ZS5ldmFsKG1peGluRW52KTtcbiAgICAgICAgICAgICAgICAgICAgZnJhbWUucmVzZXRDYWNoZSgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IHsgdHlwZTogJ1J1bnRpbWUnLCBtZXNzYWdlOiBcIndyb25nIG51bWJlciBvZiBhcmd1bWVudHMgZm9yIFwiICsgdGhpcy5uYW1lICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcgKCcgKyBhcmdzTGVuZ3RoICsgJyBmb3IgJyArIHRoaXMuYXJpdHkgKyAnKScgfTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBmcmFtZS5wcmVwZW5kUnVsZShuZXcgUnVsZShuYW1lLCB2YWwpKTtcbiAgICAgICAgICAgICAgICBldmFsZEFyZ3VtZW50c1tpXSA9IHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJhbXNbaV0udmFyaWFkaWMgJiYgYXJncykge1xuICAgICAgICAgICAgZm9yIChqID0gYXJnSW5kZXg7IGogPCBhcmdzTGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICBldmFsZEFyZ3VtZW50c1tqXSA9IGFyZ3Nbal0udmFsdWUuZXZhbChjb250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBhcmdJbmRleCsrO1xuICAgIH1cblxuICAgIHJldHVybiBmcmFtZTtcbn07XG5EZWZpbml0aW9uLnByb3RvdHlwZS5tYWtlSW1wb3J0YW50ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHJ1bGVzID0gIXRoaXMucnVsZXMgPyB0aGlzLnJ1bGVzIDogdGhpcy5ydWxlcy5tYXAoZnVuY3Rpb24gKHIpIHtcbiAgICAgICAgaWYgKHIubWFrZUltcG9ydGFudCkge1xuICAgICAgICAgICAgcmV0dXJuIHIubWFrZUltcG9ydGFudCh0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiByO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgdmFyIHJlc3VsdCA9IG5ldyBEZWZpbml0aW9uKHRoaXMubmFtZSwgdGhpcy5wYXJhbXMsIHJ1bGVzLCB0aGlzLmNvbmRpdGlvbiwgdGhpcy52YXJpYWRpYywgdGhpcy5mcmFtZXMpO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuRGVmaW5pdGlvbi5wcm90b3R5cGUuZXZhbCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBEZWZpbml0aW9uKHRoaXMubmFtZSwgdGhpcy5wYXJhbXMsIHRoaXMucnVsZXMsIHRoaXMuY29uZGl0aW9uLCB0aGlzLnZhcmlhZGljLCB0aGlzLmZyYW1lcyB8fCBjb250ZXh0LmZyYW1lcy5zbGljZSgwKSk7XG59O1xuRGVmaW5pdGlvbi5wcm90b3R5cGUuZXZhbENhbGwgPSBmdW5jdGlvbiAoY29udGV4dCwgYXJncywgaW1wb3J0YW50KSB7XG4gICAgdmFyIF9hcmd1bWVudHMgPSBbXSxcbiAgICAgICAgbWl4aW5GcmFtZXMgPSB0aGlzLmZyYW1lcyA/IHRoaXMuZnJhbWVzLmNvbmNhdChjb250ZXh0LmZyYW1lcykgOiBjb250ZXh0LmZyYW1lcyxcbiAgICAgICAgZnJhbWUgPSB0aGlzLmV2YWxQYXJhbXMoY29udGV4dCwgbmV3IGNvbnRleHRzLkV2YWwoY29udGV4dCwgbWl4aW5GcmFtZXMpLCBhcmdzLCBfYXJndW1lbnRzKSxcbiAgICAgICAgcnVsZXMsIHJ1bGVzZXQ7XG5cbiAgICBmcmFtZS5wcmVwZW5kUnVsZShuZXcgUnVsZSgnQGFyZ3VtZW50cycsIG5ldyBFeHByZXNzaW9uKF9hcmd1bWVudHMpLmV2YWwoY29udGV4dCkpKTtcblxuICAgIHJ1bGVzID0gdGhpcy5ydWxlcy5zbGljZSgwKTtcblxuICAgIHJ1bGVzZXQgPSBuZXcgUnVsZXNldChudWxsLCBydWxlcyk7XG4gICAgcnVsZXNldC5vcmlnaW5hbFJ1bGVzZXQgPSB0aGlzO1xuICAgIHJ1bGVzZXQgPSBydWxlc2V0LmV2YWwobmV3IGNvbnRleHRzLkV2YWwoY29udGV4dCwgW3RoaXMsIGZyYW1lXS5jb25jYXQobWl4aW5GcmFtZXMpKSk7XG4gICAgaWYgKGltcG9ydGFudCkge1xuICAgICAgICBydWxlc2V0ID0gcnVsZXNldC5tYWtlSW1wb3J0YW50KCk7XG4gICAgfVxuICAgIHJldHVybiBydWxlc2V0O1xufTtcbkRlZmluaXRpb24ucHJvdG90eXBlLm1hdGNoQ29uZGl0aW9uID0gZnVuY3Rpb24gKGFyZ3MsIGNvbnRleHQpIHtcbiAgICBpZiAodGhpcy5jb25kaXRpb24gJiYgIXRoaXMuY29uZGl0aW9uLmV2YWwoXG4gICAgICAgIG5ldyBjb250ZXh0cy5FdmFsKGNvbnRleHQsXG4gICAgICAgICAgICBbdGhpcy5ldmFsUGFyYW1zKGNvbnRleHQsIC8qIHRoZSBwYXJhbWV0ZXIgdmFyaWFibGVzKi9cbiAgICAgICAgICAgICAgICBuZXcgY29udGV4dHMuRXZhbChjb250ZXh0LCB0aGlzLmZyYW1lcyA/IHRoaXMuZnJhbWVzLmNvbmNhdChjb250ZXh0LmZyYW1lcykgOiBjb250ZXh0LmZyYW1lcyksIGFyZ3MsIFtdKV1cbiAgICAgICAgICAgIC5jb25jYXQodGhpcy5mcmFtZXMgfHwgW10pIC8vIHRoZSBwYXJlbnQgbmFtZXNwYWNlL21peGluIGZyYW1lc1xuICAgICAgICAgICAgLmNvbmNhdChjb250ZXh0LmZyYW1lcykpKSkgeyAvLyB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBmcmFtZXNcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5EZWZpbml0aW9uLnByb3RvdHlwZS5tYXRjaEFyZ3MgPSBmdW5jdGlvbiAoYXJncywgY29udGV4dCkge1xuICAgIHZhciBhbGxBcmdzQ250ID0gKGFyZ3MgJiYgYXJncy5sZW5ndGgpIHx8IDAsIGxlbiwgb3B0aW9uYWxQYXJhbWV0ZXJzID0gdGhpcy5vcHRpb25hbFBhcmFtZXRlcnM7XG4gICAgdmFyIHJlcXVpcmVkQXJnc0NudCA9ICFhcmdzID8gMCA6IGFyZ3MucmVkdWNlKGZ1bmN0aW9uIChjb3VudCwgcCkge1xuICAgICAgICBpZiAob3B0aW9uYWxQYXJhbWV0ZXJzLmluZGV4T2YocC5uYW1lKSA8IDApIHtcbiAgICAgICAgICAgIHJldHVybiBjb3VudCArIDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gY291bnQ7XG4gICAgICAgIH1cbiAgICB9LCAwKTtcblxuICAgIGlmICghIHRoaXMudmFyaWFkaWMpIHtcbiAgICAgICAgaWYgKHJlcXVpcmVkQXJnc0NudCA8IHRoaXMucmVxdWlyZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYWxsQXJnc0NudCA+IHRoaXMucGFyYW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHJlcXVpcmVkQXJnc0NudCA8ICh0aGlzLnJlcXVpcmVkIC0gMSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIGNoZWNrIHBhdHRlcm5zXG4gICAgbGVuID0gTWF0aC5taW4ocmVxdWlyZWRBcmdzQ250LCB0aGlzLmFyaXR5KTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgaWYgKCF0aGlzLnBhcmFtc1tpXS5uYW1lICYmICF0aGlzLnBhcmFtc1tpXS52YXJpYWRpYykge1xuICAgICAgICAgICAgaWYgKGFyZ3NbaV0udmFsdWUuZXZhbChjb250ZXh0KS50b0NTUygpICE9IHRoaXMucGFyYW1zW2ldLnZhbHVlLmV2YWwoY29udGV4dCkudG9DU1MoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IERlZmluaXRpb247XG5cbn0se1wiLi4vY29udGV4dHNcIjoxMSxcIi4vZWxlbWVudFwiOjU4LFwiLi9leHByZXNzaW9uXCI6NTksXCIuL3J1bGVcIjo3NCxcIi4vcnVsZXNldFwiOjc2LFwiLi9zZWxlY3RvclwiOjc3fV0sNjk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIE5vZGUgPSByZXF1aXJlKFwiLi9ub2RlXCIpLFxuICAgIE9wZXJhdGlvbiA9IHJlcXVpcmUoXCIuL29wZXJhdGlvblwiKSxcbiAgICBEaW1lbnNpb24gPSByZXF1aXJlKFwiLi9kaW1lbnNpb25cIik7XG5cbnZhciBOZWdhdGl2ZSA9IGZ1bmN0aW9uIChub2RlKSB7XG4gICAgdGhpcy52YWx1ZSA9IG5vZGU7XG59O1xuTmVnYXRpdmUucHJvdG90eXBlID0gbmV3IE5vZGUoKTtcbk5lZ2F0aXZlLnByb3RvdHlwZS50eXBlID0gXCJOZWdhdGl2ZVwiO1xuTmVnYXRpdmUucHJvdG90eXBlLmdlbkNTUyA9IGZ1bmN0aW9uIChjb250ZXh0LCBvdXRwdXQpIHtcbiAgICBvdXRwdXQuYWRkKCctJyk7XG4gICAgdGhpcy52YWx1ZS5nZW5DU1MoY29udGV4dCwgb3V0cHV0KTtcbn07XG5OZWdhdGl2ZS5wcm90b3R5cGUuZXZhbCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgaWYgKGNvbnRleHQuaXNNYXRoT24oKSkge1xuICAgICAgICByZXR1cm4gKG5ldyBPcGVyYXRpb24oJyonLCBbbmV3IERpbWVuc2lvbigtMSksIHRoaXMudmFsdWVdKSkuZXZhbChjb250ZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBOZWdhdGl2ZSh0aGlzLnZhbHVlLmV2YWwoY29udGV4dCkpO1xufTtcbm1vZHVsZS5leHBvcnRzID0gTmVnYXRpdmU7XG5cbn0se1wiLi9kaW1lbnNpb25cIjo1NixcIi4vbm9kZVwiOjcwLFwiLi9vcGVyYXRpb25cIjo3MX1dLDcwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBOb2RlID0gZnVuY3Rpb24oKSB7XG59O1xuTm9kZS5wcm90b3R5cGUudG9DU1MgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHZhciBzdHJzID0gW107XG4gICAgdGhpcy5nZW5DU1MoY29udGV4dCwge1xuICAgICAgICBhZGQ6IGZ1bmN0aW9uKGNodW5rLCBmaWxlSW5mbywgaW5kZXgpIHtcbiAgICAgICAgICAgIHN0cnMucHVzaChjaHVuayk7XG4gICAgICAgIH0sXG4gICAgICAgIGlzRW1wdHk6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBzdHJzLmxlbmd0aCA9PT0gMDtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBzdHJzLmpvaW4oJycpO1xufTtcbk5vZGUucHJvdG90eXBlLmdlbkNTUyA9IGZ1bmN0aW9uIChjb250ZXh0LCBvdXRwdXQpIHtcbiAgICBvdXRwdXQuYWRkKHRoaXMudmFsdWUpO1xufTtcbk5vZGUucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uICh2aXNpdG9yKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZpc2l0b3IudmlzaXQodGhpcy52YWx1ZSk7XG59O1xuTm9kZS5wcm90b3R5cGUuZXZhbCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH07XG5Ob2RlLnByb3RvdHlwZS5fb3BlcmF0ZSA9IGZ1bmN0aW9uIChjb250ZXh0LCBvcCwgYSwgYikge1xuICAgIHN3aXRjaCAob3ApIHtcbiAgICAgICAgY2FzZSAnKyc6IHJldHVybiBhICsgYjtcbiAgICAgICAgY2FzZSAnLSc6IHJldHVybiBhIC0gYjtcbiAgICAgICAgY2FzZSAnKic6IHJldHVybiBhICogYjtcbiAgICAgICAgY2FzZSAnLyc6IHJldHVybiBhIC8gYjtcbiAgICB9XG59O1xuTm9kZS5wcm90b3R5cGUuZnJvdW5kID0gZnVuY3Rpb24oY29udGV4dCwgdmFsdWUpIHtcbiAgICB2YXIgcHJlY2lzaW9uID0gY29udGV4dCAmJiBjb250ZXh0Lm51bVByZWNpc2lvbjtcbiAgICAvL2FkZCBcImVwc2lsb25cIiB0byBlbnN1cmUgbnVtYmVycyBsaWtlIDEuMDAwMDAwMDA1IChyZXByZXNlbnRlZCBhcyAxLjAwMDAwMDAwNDk5OS4uLi4pIGFyZSBwcm9wZXJseSByb3VuZGVkLi4uXG4gICAgcmV0dXJuIChwcmVjaXNpb24gPT0gbnVsbCkgPyB2YWx1ZSA6IE51bWJlcigodmFsdWUgKyAyZS0xNikudG9GaXhlZChwcmVjaXNpb24pKTtcbn07XG5Ob2RlLmNvbXBhcmUgPSBmdW5jdGlvbiAoYSwgYikge1xuICAgIC8qIHJldHVybnM6XG4gICAgIC0xOiBhIDwgYlxuICAgICAwOiBhID0gYlxuICAgICAxOiBhID4gYlxuICAgICBhbmQgKmFueSogb3RoZXIgdmFsdWUgZm9yIGEgIT0gYiAoZS5nLiB1bmRlZmluZWQsIE5hTiwgLTIgZXRjLikgKi9cblxuICAgIGlmICgoYS5jb21wYXJlKSAmJlxuICAgICAgICAvLyBmb3IgXCJzeW1tZXRyaWMgcmVzdWx0c1wiIGZvcmNlIHRvQ1NTLWJhc2VkIGNvbXBhcmlzb25cbiAgICAgICAgLy8gb2YgUXVvdGVkIG9yIEFub255bW91cyBpZiBlaXRoZXIgdmFsdWUgaXMgb25lIG9mIHRob3NlXG4gICAgICAgICEoYi50eXBlID09PSBcIlF1b3RlZFwiIHx8IGIudHlwZSA9PT0gXCJBbm9ueW1vdXNcIikpIHtcbiAgICAgICAgcmV0dXJuIGEuY29tcGFyZShiKTtcbiAgICB9IGVsc2UgaWYgKGIuY29tcGFyZSkge1xuICAgICAgICByZXR1cm4gLWIuY29tcGFyZShhKTtcbiAgICB9IGVsc2UgaWYgKGEudHlwZSAhPT0gYi50eXBlKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgYSA9IGEudmFsdWU7XG4gICAgYiA9IGIudmFsdWU7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGEpKSB7XG4gICAgICAgIHJldHVybiBhID09PSBiID8gMCA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKE5vZGUuY29tcGFyZShhW2ldLCBiW2ldKSAhPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gMDtcbn07XG5cbk5vZGUubnVtZXJpY0NvbXBhcmUgPSBmdW5jdGlvbiAoYSwgYikge1xuICAgIHJldHVybiBhICA8ICBiID8gLTFcbiAgICAgICAgOiBhID09PSBiID8gIDBcbiAgICAgICAgOiBhICA+ICBiID8gIDEgOiB1bmRlZmluZWQ7XG59O1xuLy8gUmV0dXJucyB0cnVlIGlmIHRoaXMgbm9kZSByZXByZXNlbnRzIHJvb3Qgb2YgYXN0IGltcG9ydGVkIGJ5IHJlZmVyZW5jZVxuTm9kZS5wcm90b3R5cGUuYmxvY2tzVmlzaWJpbGl0eSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy52aXNpYmlsaXR5QmxvY2tzID09IG51bGwpIHtcbiAgICAgICAgdGhpcy52aXNpYmlsaXR5QmxvY2tzID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudmlzaWJpbGl0eUJsb2NrcyAhPT0gMDtcbn07XG5Ob2RlLnByb3RvdHlwZS5hZGRWaXNpYmlsaXR5QmxvY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMudmlzaWJpbGl0eUJsb2NrcyA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMudmlzaWJpbGl0eUJsb2NrcyA9IDA7XG4gICAgfVxuICAgIHRoaXMudmlzaWJpbGl0eUJsb2NrcyA9IHRoaXMudmlzaWJpbGl0eUJsb2NrcyArIDE7XG59O1xuTm9kZS5wcm90b3R5cGUucmVtb3ZlVmlzaWJpbGl0eUJsb2NrID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnZpc2liaWxpdHlCbG9ja3MgPT0gbnVsbCkge1xuICAgICAgICB0aGlzLnZpc2liaWxpdHlCbG9ja3MgPSAwO1xuICAgIH1cbiAgICB0aGlzLnZpc2liaWxpdHlCbG9ja3MgPSB0aGlzLnZpc2liaWxpdHlCbG9ja3MgLSAxO1xufTtcbi8vVHVybnMgb24gbm9kZSB2aXNpYmlsaXR5IC0gaWYgY2FsbGVkIG5vZGUgd2lsbCBiZSBzaG93biBpbiBvdXRwdXQgcmVnYXJkbGVzc1xuLy9vZiB3aGV0aGVyIGl0IGNvbWVzIGZyb20gaW1wb3J0IGJ5IHJlZmVyZW5jZSBvciBub3Rcbk5vZGUucHJvdG90eXBlLmVuc3VyZVZpc2liaWxpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5ub2RlVmlzaWJsZSA9IHRydWU7XG59O1xuLy9UdXJucyBvZmYgbm9kZSB2aXNpYmlsaXR5IC0gaWYgY2FsbGVkIG5vZGUgd2lsbCBOT1QgYmUgc2hvd24gaW4gb3V0cHV0IHJlZ2FyZGxlc3Ncbi8vb2Ygd2hldGhlciBpdCBjb21lcyBmcm9tIGltcG9ydCBieSByZWZlcmVuY2Ugb3Igbm90XG5Ob2RlLnByb3RvdHlwZS5lbnN1cmVJbnZpc2liaWxpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5ub2RlVmlzaWJsZSA9IGZhbHNlO1xufTtcbi8vIHJldHVybiB2YWx1ZXM6XG4vLyBmYWxzZSAtIHRoZSBub2RlIG11c3Qgbm90IGJlIHZpc2libGVcbi8vIHRydWUgLSB0aGUgbm9kZSBtdXN0IGJlIHZpc2libGVcbi8vIHVuZGVmaW5lZCBvciBudWxsIC0gdGhlIG5vZGUgaGFzIHRoZSBzYW1lIHZpc2liaWxpdHkgYXMgaXRzIHBhcmVudFxuTm9kZS5wcm90b3R5cGUuaXNWaXNpYmxlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm5vZGVWaXNpYmxlO1xufTtcbk5vZGUucHJvdG90eXBlLnZpc2liaWxpdHlJbmZvID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdmlzaWJpbGl0eUJsb2NrczogdGhpcy52aXNpYmlsaXR5QmxvY2tzLFxuICAgICAgICBub2RlVmlzaWJsZTogdGhpcy5ub2RlVmlzaWJsZVxuICAgIH07XG59O1xuTm9kZS5wcm90b3R5cGUuY29weVZpc2liaWxpdHlJbmZvID0gZnVuY3Rpb24oaW5mbykge1xuICAgIGlmICghaW5mbykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudmlzaWJpbGl0eUJsb2NrcyA9IGluZm8udmlzaWJpbGl0eUJsb2NrcztcbiAgICB0aGlzLm5vZGVWaXNpYmxlID0gaW5mby5ub2RlVmlzaWJsZTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IE5vZGU7XG5cbn0se31dLDcxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBOb2RlID0gcmVxdWlyZShcIi4vbm9kZVwiKSxcbiAgICBDb2xvciA9IHJlcXVpcmUoXCIuL2NvbG9yXCIpLFxuICAgIERpbWVuc2lvbiA9IHJlcXVpcmUoXCIuL2RpbWVuc2lvblwiKTtcblxudmFyIE9wZXJhdGlvbiA9IGZ1bmN0aW9uIChvcCwgb3BlcmFuZHMsIGlzU3BhY2VkKSB7XG4gICAgdGhpcy5vcCA9IG9wLnRyaW0oKTtcbiAgICB0aGlzLm9wZXJhbmRzID0gb3BlcmFuZHM7XG4gICAgdGhpcy5pc1NwYWNlZCA9IGlzU3BhY2VkO1xufTtcbk9wZXJhdGlvbi5wcm90b3R5cGUgPSBuZXcgTm9kZSgpO1xuT3BlcmF0aW9uLnByb3RvdHlwZS50eXBlID0gXCJPcGVyYXRpb25cIjtcbk9wZXJhdGlvbi5wcm90b3R5cGUuYWNjZXB0ID0gZnVuY3Rpb24gKHZpc2l0b3IpIHtcbiAgICB0aGlzLm9wZXJhbmRzID0gdmlzaXRvci52aXNpdCh0aGlzLm9wZXJhbmRzKTtcbn07XG5PcGVyYXRpb24ucHJvdG90eXBlLmV2YWwgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHZhciBhID0gdGhpcy5vcGVyYW5kc1swXS5ldmFsKGNvbnRleHQpLFxuICAgICAgICBiID0gdGhpcy5vcGVyYW5kc1sxXS5ldmFsKGNvbnRleHQpO1xuXG4gICAgaWYgKGNvbnRleHQuaXNNYXRoT24oKSkge1xuICAgICAgICBpZiAoYSBpbnN0YW5jZW9mIERpbWVuc2lvbiAmJiBiIGluc3RhbmNlb2YgQ29sb3IpIHtcbiAgICAgICAgICAgIGEgPSBhLnRvQ29sb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYiBpbnN0YW5jZW9mIERpbWVuc2lvbiAmJiBhIGluc3RhbmNlb2YgQ29sb3IpIHtcbiAgICAgICAgICAgIGIgPSBiLnRvQ29sb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWEub3BlcmF0ZSkge1xuICAgICAgICAgICAgdGhyb3cgeyB0eXBlOiBcIk9wZXJhdGlvblwiLFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBcIk9wZXJhdGlvbiBvbiBhbiBpbnZhbGlkIHR5cGVcIiB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGEub3BlcmF0ZShjb250ZXh0LCB0aGlzLm9wLCBiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IE9wZXJhdGlvbih0aGlzLm9wLCBbYSwgYl0sIHRoaXMuaXNTcGFjZWQpO1xuICAgIH1cbn07XG5PcGVyYXRpb24ucHJvdG90eXBlLmdlbkNTUyA9IGZ1bmN0aW9uIChjb250ZXh0LCBvdXRwdXQpIHtcbiAgICB0aGlzLm9wZXJhbmRzWzBdLmdlbkNTUyhjb250ZXh0LCBvdXRwdXQpO1xuICAgIGlmICh0aGlzLmlzU3BhY2VkKSB7XG4gICAgICAgIG91dHB1dC5hZGQoXCIgXCIpO1xuICAgIH1cbiAgICBvdXRwdXQuYWRkKHRoaXMub3ApO1xuICAgIGlmICh0aGlzLmlzU3BhY2VkKSB7XG4gICAgICAgIG91dHB1dC5hZGQoXCIgXCIpO1xuICAgIH1cbiAgICB0aGlzLm9wZXJhbmRzWzFdLmdlbkNTUyhjb250ZXh0LCBvdXRwdXQpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBPcGVyYXRpb247XG5cbn0se1wiLi9jb2xvclwiOjUwLFwiLi9kaW1lbnNpb25cIjo1NixcIi4vbm9kZVwiOjcwfV0sNzI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIE5vZGUgPSByZXF1aXJlKFwiLi9ub2RlXCIpO1xuXG52YXIgUGFyZW4gPSBmdW5jdGlvbiAobm9kZSkge1xuICAgIHRoaXMudmFsdWUgPSBub2RlO1xufTtcblBhcmVuLnByb3RvdHlwZSA9IG5ldyBOb2RlKCk7XG5QYXJlbi5wcm90b3R5cGUudHlwZSA9IFwiUGFyZW5cIjtcblBhcmVuLnByb3RvdHlwZS5nZW5DU1MgPSBmdW5jdGlvbiAoY29udGV4dCwgb3V0cHV0KSB7XG4gICAgb3V0cHV0LmFkZCgnKCcpO1xuICAgIHRoaXMudmFsdWUuZ2VuQ1NTKGNvbnRleHQsIG91dHB1dCk7XG4gICAgb3V0cHV0LmFkZCgnKScpO1xufTtcblBhcmVuLnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IFBhcmVuKHRoaXMudmFsdWUuZXZhbChjb250ZXh0KSk7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBQYXJlbjtcblxufSx7XCIuL25vZGVcIjo3MH1dLDczOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBOb2RlID0gcmVxdWlyZShcIi4vbm9kZVwiKSxcbiAgICBKc0V2YWxOb2RlID0gcmVxdWlyZShcIi4vanMtZXZhbC1ub2RlXCIpLFxuICAgIFZhcmlhYmxlID0gcmVxdWlyZShcIi4vdmFyaWFibGVcIik7XG5cbnZhciBRdW90ZWQgPSBmdW5jdGlvbiAoc3RyLCBjb250ZW50LCBlc2NhcGVkLCBpbmRleCwgY3VycmVudEZpbGVJbmZvKSB7XG4gICAgdGhpcy5lc2NhcGVkID0gKGVzY2FwZWQgPT0gbnVsbCkgPyB0cnVlIDogZXNjYXBlZDtcbiAgICB0aGlzLnZhbHVlID0gY29udGVudCB8fCAnJztcbiAgICB0aGlzLnF1b3RlID0gc3RyLmNoYXJBdCgwKTtcbiAgICB0aGlzLmluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy5jdXJyZW50RmlsZUluZm8gPSBjdXJyZW50RmlsZUluZm87XG59O1xuUXVvdGVkLnByb3RvdHlwZSA9IG5ldyBKc0V2YWxOb2RlKCk7XG5RdW90ZWQucHJvdG90eXBlLnR5cGUgPSBcIlF1b3RlZFwiO1xuUXVvdGVkLnByb3RvdHlwZS5nZW5DU1MgPSBmdW5jdGlvbiAoY29udGV4dCwgb3V0cHV0KSB7XG4gICAgaWYgKCF0aGlzLmVzY2FwZWQpIHtcbiAgICAgICAgb3V0cHV0LmFkZCh0aGlzLnF1b3RlLCB0aGlzLmN1cnJlbnRGaWxlSW5mbywgdGhpcy5pbmRleCk7XG4gICAgfVxuICAgIG91dHB1dC5hZGQodGhpcy52YWx1ZSk7XG4gICAgaWYgKCF0aGlzLmVzY2FwZWQpIHtcbiAgICAgICAgb3V0cHV0LmFkZCh0aGlzLnF1b3RlKTtcbiAgICB9XG59O1xuUXVvdGVkLnByb3RvdHlwZS5jb250YWluc1ZhcmlhYmxlcyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnZhbHVlLm1hdGNoKC8oYChbXmBdKylgKXxAXFx7KFtcXHctXSspXFx9Lyk7XG59O1xuUXVvdGVkLnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgdGhhdCA9IHRoaXMsIHZhbHVlID0gdGhpcy52YWx1ZTtcbiAgICB2YXIgamF2YXNjcmlwdFJlcGxhY2VtZW50ID0gZnVuY3Rpb24gKF8sIGV4cCkge1xuICAgICAgICByZXR1cm4gU3RyaW5nKHRoYXQuZXZhbHVhdGVKYXZhU2NyaXB0KGV4cCwgY29udGV4dCkpO1xuICAgIH07XG4gICAgdmFyIGludGVycG9sYXRpb25SZXBsYWNlbWVudCA9IGZ1bmN0aW9uIChfLCBuYW1lKSB7XG4gICAgICAgIHZhciB2ID0gbmV3IFZhcmlhYmxlKCdAJyArIG5hbWUsIHRoYXQuaW5kZXgsIHRoYXQuY3VycmVudEZpbGVJbmZvKS5ldmFsKGNvbnRleHQsIHRydWUpO1xuICAgICAgICByZXR1cm4gKHYgaW5zdGFuY2VvZiBRdW90ZWQpID8gdi52YWx1ZSA6IHYudG9DU1MoKTtcbiAgICB9O1xuICAgIGZ1bmN0aW9uIGl0ZXJhdGl2ZVJlcGxhY2UodmFsdWUsIHJlZ2V4cCwgcmVwbGFjZW1lbnRGbmMpIHtcbiAgICAgICAgdmFyIGV2YWx1YXRlZFZhbHVlID0gdmFsdWU7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIHZhbHVlID0gZXZhbHVhdGVkVmFsdWU7XG4gICAgICAgICAgICBldmFsdWF0ZWRWYWx1ZSA9IHZhbHVlLnJlcGxhY2UocmVnZXhwLCByZXBsYWNlbWVudEZuYyk7XG4gICAgICAgIH0gd2hpbGUgKHZhbHVlICE9PSBldmFsdWF0ZWRWYWx1ZSk7XG4gICAgICAgIHJldHVybiBldmFsdWF0ZWRWYWx1ZTtcbiAgICB9XG4gICAgdmFsdWUgPSBpdGVyYXRpdmVSZXBsYWNlKHZhbHVlLCAvYChbXmBdKylgL2csIGphdmFzY3JpcHRSZXBsYWNlbWVudCk7XG4gICAgdmFsdWUgPSBpdGVyYXRpdmVSZXBsYWNlKHZhbHVlLCAvQFxceyhbXFx3LV0rKVxcfS9nLCBpbnRlcnBvbGF0aW9uUmVwbGFjZW1lbnQpO1xuICAgIHJldHVybiBuZXcgUXVvdGVkKHRoaXMucXVvdGUgKyB2YWx1ZSArIHRoaXMucXVvdGUsIHZhbHVlLCB0aGlzLmVzY2FwZWQsIHRoaXMuaW5kZXgsIHRoaXMuY3VycmVudEZpbGVJbmZvKTtcbn07XG5RdW90ZWQucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgICAvLyB3aGVuIGNvbXBhcmluZyBxdW90ZWQgc3RyaW5ncyBhbGxvdyB0aGUgcXVvdGUgdG8gZGlmZmVyXG4gICAgaWYgKG90aGVyLnR5cGUgPT09IFwiUXVvdGVkXCIgJiYgIXRoaXMuZXNjYXBlZCAmJiAhb3RoZXIuZXNjYXBlZCkge1xuICAgICAgICByZXR1cm4gTm9kZS5udW1lcmljQ29tcGFyZSh0aGlzLnZhbHVlLCBvdGhlci52YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG90aGVyLnRvQ1NTICYmIHRoaXMudG9DU1MoKSA9PT0gb3RoZXIudG9DU1MoKSA/IDAgOiB1bmRlZmluZWQ7XG4gICAgfVxufTtcbm1vZHVsZS5leHBvcnRzID0gUXVvdGVkO1xuXG59LHtcIi4vanMtZXZhbC1ub2RlXCI6NjQsXCIuL25vZGVcIjo3MCxcIi4vdmFyaWFibGVcIjo4Mn1dLDc0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBOb2RlID0gcmVxdWlyZShcIi4vbm9kZVwiKSxcbiAgICBWYWx1ZSA9IHJlcXVpcmUoXCIuL3ZhbHVlXCIpLFxuICAgIEtleXdvcmQgPSByZXF1aXJlKFwiLi9rZXl3b3JkXCIpO1xuXG52YXIgUnVsZSA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSwgaW1wb3J0YW50LCBtZXJnZSwgaW5kZXgsIGN1cnJlbnRGaWxlSW5mbywgaW5saW5lLCB2YXJpYWJsZSkge1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy52YWx1ZSA9ICh2YWx1ZSBpbnN0YW5jZW9mIE5vZGUpID8gdmFsdWUgOiBuZXcgVmFsdWUoW3ZhbHVlXSk7IC8vdmFsdWUgaW5zdGFuY2VvZiB0cmVlLlZhbHVlIHx8IHZhbHVlIGluc3RhbmNlb2YgdHJlZS5SdWxlc2V0ID8/XG4gICAgdGhpcy5pbXBvcnRhbnQgPSBpbXBvcnRhbnQgPyAnICcgKyBpbXBvcnRhbnQudHJpbSgpIDogJyc7XG4gICAgdGhpcy5tZXJnZSA9IG1lcmdlO1xuICAgIHRoaXMuaW5kZXggPSBpbmRleDtcbiAgICB0aGlzLmN1cnJlbnRGaWxlSW5mbyA9IGN1cnJlbnRGaWxlSW5mbztcbiAgICB0aGlzLmlubGluZSA9IGlubGluZSB8fCBmYWxzZTtcbiAgICB0aGlzLnZhcmlhYmxlID0gKHZhcmlhYmxlICE9PSB1bmRlZmluZWQpID8gdmFyaWFibGVcbiAgICAgICAgOiAobmFtZS5jaGFyQXQgJiYgKG5hbWUuY2hhckF0KDApID09PSAnQCcpKTtcbiAgICB0aGlzLmFsbG93Um9vdCA9IHRydWU7XG59O1xuXG5mdW5jdGlvbiBldmFsTmFtZShjb250ZXh0LCBuYW1lKSB7XG4gICAgdmFyIHZhbHVlID0gXCJcIiwgaSwgbiA9IG5hbWUubGVuZ3RoLFxuICAgICAgICBvdXRwdXQgPSB7YWRkOiBmdW5jdGlvbiAocykge3ZhbHVlICs9IHM7fX07XG4gICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykge1xuICAgICAgICBuYW1lW2ldLmV2YWwoY29udGV4dCkuZ2VuQ1NTKGNvbnRleHQsIG91dHB1dCk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn1cblxuUnVsZS5wcm90b3R5cGUgPSBuZXcgTm9kZSgpO1xuUnVsZS5wcm90b3R5cGUudHlwZSA9IFwiUnVsZVwiO1xuUnVsZS5wcm90b3R5cGUuZ2VuQ1NTID0gZnVuY3Rpb24gKGNvbnRleHQsIG91dHB1dCkge1xuICAgIG91dHB1dC5hZGQodGhpcy5uYW1lICsgKGNvbnRleHQuY29tcHJlc3MgPyAnOicgOiAnOiAnKSwgdGhpcy5jdXJyZW50RmlsZUluZm8sIHRoaXMuaW5kZXgpO1xuICAgIHRyeSB7XG4gICAgICAgIHRoaXMudmFsdWUuZ2VuQ1NTKGNvbnRleHQsIG91dHB1dCk7XG4gICAgfVxuICAgIGNhdGNoKGUpIHtcbiAgICAgICAgZS5pbmRleCA9IHRoaXMuaW5kZXg7XG4gICAgICAgIGUuZmlsZW5hbWUgPSB0aGlzLmN1cnJlbnRGaWxlSW5mby5maWxlbmFtZTtcbiAgICAgICAgdGhyb3cgZTtcbiAgICB9XG4gICAgb3V0cHV0LmFkZCh0aGlzLmltcG9ydGFudCArICgodGhpcy5pbmxpbmUgfHwgKGNvbnRleHQubGFzdFJ1bGUgJiYgY29udGV4dC5jb21wcmVzcykpID8gXCJcIiA6IFwiO1wiKSwgdGhpcy5jdXJyZW50RmlsZUluZm8sIHRoaXMuaW5kZXgpO1xufTtcblJ1bGUucHJvdG90eXBlLmV2YWwgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHZhciBzdHJpY3RNYXRoQnlwYXNzID0gZmFsc2UsIG5hbWUgPSB0aGlzLm5hbWUsIGV2YWxkVmFsdWUsIHZhcmlhYmxlID0gdGhpcy52YXJpYWJsZTtcbiAgICBpZiAodHlwZW9mIG5hbWUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgLy8gZXhwYW5kICdwcmltaXRpdmUnIG5hbWUgZGlyZWN0bHkgdG8gZ2V0XG4gICAgICAgIC8vIHRoaW5ncyBmYXN0ZXIgKH4xMCUgZm9yIGJlbmNobWFyay5sZXNzKTpcbiAgICAgICAgbmFtZSA9IChuYW1lLmxlbmd0aCA9PT0gMSkgJiYgKG5hbWVbMF0gaW5zdGFuY2VvZiBLZXl3b3JkKSA/XG4gICAgICAgICAgICAgICAgbmFtZVswXS52YWx1ZSA6IGV2YWxOYW1lKGNvbnRleHQsIG5hbWUpO1xuICAgICAgICB2YXJpYWJsZSA9IGZhbHNlOyAvLyBuZXZlciB0cmVhdCBleHBhbmRlZCBpbnRlcnBvbGF0aW9uIGFzIG5ldyB2YXJpYWJsZSBuYW1lXG4gICAgfVxuICAgIGlmIChuYW1lID09PSBcImZvbnRcIiAmJiAhY29udGV4dC5zdHJpY3RNYXRoKSB7XG4gICAgICAgIHN0cmljdE1hdGhCeXBhc3MgPSB0cnVlO1xuICAgICAgICBjb250ZXh0LnN0cmljdE1hdGggPSB0cnVlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBjb250ZXh0LmltcG9ydGFudFNjb3BlLnB1c2goe30pO1xuICAgICAgICBldmFsZFZhbHVlID0gdGhpcy52YWx1ZS5ldmFsKGNvbnRleHQpO1xuXG4gICAgICAgIGlmICghdGhpcy52YXJpYWJsZSAmJiBldmFsZFZhbHVlLnR5cGUgPT09IFwiRGV0YWNoZWRSdWxlc2V0XCIpIHtcbiAgICAgICAgICAgIHRocm93IHsgbWVzc2FnZTogXCJSdWxlc2V0cyBjYW5ub3QgYmUgZXZhbHVhdGVkIG9uIGEgcHJvcGVydHkuXCIsXG4gICAgICAgICAgICAgICAgICAgIGluZGV4OiB0aGlzLmluZGV4LCBmaWxlbmFtZTogdGhpcy5jdXJyZW50RmlsZUluZm8uZmlsZW5hbWUgfTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaW1wb3J0YW50ID0gdGhpcy5pbXBvcnRhbnQsXG4gICAgICAgICAgICBpbXBvcnRhbnRSZXN1bHQgPSBjb250ZXh0LmltcG9ydGFudFNjb3BlLnBvcCgpO1xuICAgICAgICBpZiAoIWltcG9ydGFudCAmJiBpbXBvcnRhbnRSZXN1bHQuaW1wb3J0YW50KSB7XG4gICAgICAgICAgICBpbXBvcnRhbnQgPSBpbXBvcnRhbnRSZXN1bHQuaW1wb3J0YW50O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBSdWxlKG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGV2YWxkVmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGltcG9ydGFudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tZXJnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmRleCwgdGhpcy5jdXJyZW50RmlsZUluZm8sIHRoaXMuaW5saW5lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUpO1xuICAgIH1cbiAgICBjYXRjaChlKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZS5pbmRleCAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIGUuaW5kZXggPSB0aGlzLmluZGV4O1xuICAgICAgICAgICAgZS5maWxlbmFtZSA9IHRoaXMuY3VycmVudEZpbGVJbmZvLmZpbGVuYW1lO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGU7XG4gICAgfVxuICAgIGZpbmFsbHkge1xuICAgICAgICBpZiAoc3RyaWN0TWF0aEJ5cGFzcykge1xuICAgICAgICAgICAgY29udGV4dC5zdHJpY3RNYXRoID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG59O1xuUnVsZS5wcm90b3R5cGUubWFrZUltcG9ydGFudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbmV3IFJ1bGUodGhpcy5uYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBcIiFpbXBvcnRhbnRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tZXJnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmRleCwgdGhpcy5jdXJyZW50RmlsZUluZm8sIHRoaXMuaW5saW5lKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUnVsZTtcbn0se1wiLi9rZXl3b3JkXCI6NjUsXCIuL25vZGVcIjo3MCxcIi4vdmFsdWVcIjo4MX1dLDc1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBOb2RlID0gcmVxdWlyZShcIi4vbm9kZVwiKSxcbiAgICBWYXJpYWJsZSA9IHJlcXVpcmUoXCIuL3ZhcmlhYmxlXCIpO1xuXG52YXIgUnVsZXNldENhbGwgPSBmdW5jdGlvbiAodmFyaWFibGUpIHtcbiAgICB0aGlzLnZhcmlhYmxlID0gdmFyaWFibGU7XG4gICAgdGhpcy5hbGxvd1Jvb3QgPSB0cnVlO1xufTtcblJ1bGVzZXRDYWxsLnByb3RvdHlwZSA9IG5ldyBOb2RlKCk7XG5SdWxlc2V0Q2FsbC5wcm90b3R5cGUudHlwZSA9IFwiUnVsZXNldENhbGxcIjtcblJ1bGVzZXRDYWxsLnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgZGV0YWNoZWRSdWxlc2V0ID0gbmV3IFZhcmlhYmxlKHRoaXMudmFyaWFibGUpLmV2YWwoY29udGV4dCk7XG4gICAgcmV0dXJuIGRldGFjaGVkUnVsZXNldC5jYWxsRXZhbChjb250ZXh0KTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IFJ1bGVzZXRDYWxsO1xuXG59LHtcIi4vbm9kZVwiOjcwLFwiLi92YXJpYWJsZVwiOjgyfV0sNzY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIE5vZGUgPSByZXF1aXJlKFwiLi9ub2RlXCIpLFxuICAgIFJ1bGUgPSByZXF1aXJlKFwiLi9ydWxlXCIpLFxuICAgIFNlbGVjdG9yID0gcmVxdWlyZShcIi4vc2VsZWN0b3JcIiksXG4gICAgRWxlbWVudCA9IHJlcXVpcmUoXCIuL2VsZW1lbnRcIiksXG4gICAgUGFyZW4gPSByZXF1aXJlKFwiLi9wYXJlblwiKSxcbiAgICBjb250ZXh0cyA9IHJlcXVpcmUoXCIuLi9jb250ZXh0c1wiKSxcbiAgICBnbG9iYWxGdW5jdGlvblJlZ2lzdHJ5ID0gcmVxdWlyZShcIi4uL2Z1bmN0aW9ucy9mdW5jdGlvbi1yZWdpc3RyeVwiKSxcbiAgICBkZWZhdWx0RnVuYyA9IHJlcXVpcmUoXCIuLi9mdW5jdGlvbnMvZGVmYXVsdFwiKSxcbiAgICBnZXREZWJ1Z0luZm8gPSByZXF1aXJlKFwiLi9kZWJ1Zy1pbmZvXCIpO1xuXG52YXIgUnVsZXNldCA9IGZ1bmN0aW9uIChzZWxlY3RvcnMsIHJ1bGVzLCBzdHJpY3RJbXBvcnRzLCB2aXNpYmlsaXR5SW5mbykge1xuICAgIHRoaXMuc2VsZWN0b3JzID0gc2VsZWN0b3JzO1xuICAgIHRoaXMucnVsZXMgPSBydWxlcztcbiAgICB0aGlzLl9sb29rdXBzID0ge307XG4gICAgdGhpcy5zdHJpY3RJbXBvcnRzID0gc3RyaWN0SW1wb3J0cztcbiAgICB0aGlzLmNvcHlWaXNpYmlsaXR5SW5mbyh2aXNpYmlsaXR5SW5mbyk7XG4gICAgdGhpcy5hbGxvd1Jvb3QgPSB0cnVlO1xufTtcblJ1bGVzZXQucHJvdG90eXBlID0gbmV3IE5vZGUoKTtcblJ1bGVzZXQucHJvdG90eXBlLnR5cGUgPSBcIlJ1bGVzZXRcIjtcblJ1bGVzZXQucHJvdG90eXBlLmlzUnVsZXNldCA9IHRydWU7XG5SdWxlc2V0LnByb3RvdHlwZS5pc1J1bGVzZXRMaWtlID0gdHJ1ZTtcblJ1bGVzZXQucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uICh2aXNpdG9yKSB7XG4gICAgaWYgKHRoaXMucGF0aHMpIHtcbiAgICAgICAgdGhpcy5wYXRocyA9IHZpc2l0b3IudmlzaXRBcnJheSh0aGlzLnBhdGhzLCB0cnVlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc2VsZWN0b3JzKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0b3JzID0gdmlzaXRvci52aXNpdEFycmF5KHRoaXMuc2VsZWN0b3JzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucnVsZXMgJiYgdGhpcy5ydWxlcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5ydWxlcyA9IHZpc2l0b3IudmlzaXRBcnJheSh0aGlzLnJ1bGVzKTtcbiAgICB9XG59O1xuUnVsZXNldC5wcm90b3R5cGUuZXZhbCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgdmFyIHRoaXNTZWxlY3RvcnMgPSB0aGlzLnNlbGVjdG9ycywgc2VsZWN0b3JzLFxuICAgICAgICBzZWxDbnQsIHNlbGVjdG9yLCBpLCBoYXNPbmVQYXNzaW5nU2VsZWN0b3IgPSBmYWxzZTtcblxuICAgIGlmICh0aGlzU2VsZWN0b3JzICYmIChzZWxDbnQgPSB0aGlzU2VsZWN0b3JzLmxlbmd0aCkpIHtcbiAgICAgICAgc2VsZWN0b3JzID0gW107XG4gICAgICAgIGRlZmF1bHRGdW5jLmVycm9yKHtcbiAgICAgICAgICAgIHR5cGU6IFwiU3ludGF4XCIsXG4gICAgICAgICAgICBtZXNzYWdlOiBcIml0IGlzIGN1cnJlbnRseSBvbmx5IGFsbG93ZWQgaW4gcGFyYW1ldHJpYyBtaXhpbiBndWFyZHMsXCJcbiAgICAgICAgfSk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBzZWxDbnQ7IGkrKykge1xuICAgICAgICAgICAgc2VsZWN0b3IgPSB0aGlzU2VsZWN0b3JzW2ldLmV2YWwoY29udGV4dCk7XG4gICAgICAgICAgICBzZWxlY3RvcnMucHVzaChzZWxlY3Rvcik7XG4gICAgICAgICAgICBpZiAoc2VsZWN0b3IuZXZhbGRDb25kaXRpb24pIHtcbiAgICAgICAgICAgICAgICBoYXNPbmVQYXNzaW5nU2VsZWN0b3IgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGRlZmF1bHRGdW5jLnJlc2V0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaGFzT25lUGFzc2luZ1NlbGVjdG9yID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgcnVsZXMgPSB0aGlzLnJ1bGVzID8gdGhpcy5ydWxlcy5zbGljZSgwKSA6IG51bGwsXG4gICAgICAgIHJ1bGVzZXQgPSBuZXcgUnVsZXNldChzZWxlY3RvcnMsIHJ1bGVzLCB0aGlzLnN0cmljdEltcG9ydHMsIHRoaXMudmlzaWJpbGl0eUluZm8oKSksXG4gICAgICAgIHJ1bGUsIHN1YlJ1bGU7XG5cbiAgICBydWxlc2V0Lm9yaWdpbmFsUnVsZXNldCA9IHRoaXM7XG4gICAgcnVsZXNldC5yb290ID0gdGhpcy5yb290O1xuICAgIHJ1bGVzZXQuZmlyc3RSb290ID0gdGhpcy5maXJzdFJvb3Q7XG4gICAgcnVsZXNldC5hbGxvd0ltcG9ydHMgPSB0aGlzLmFsbG93SW1wb3J0cztcblxuICAgIGlmICh0aGlzLmRlYnVnSW5mbykge1xuICAgICAgICBydWxlc2V0LmRlYnVnSW5mbyA9IHRoaXMuZGVidWdJbmZvO1xuICAgIH1cblxuICAgIGlmICghaGFzT25lUGFzc2luZ1NlbGVjdG9yKSB7XG4gICAgICAgIHJ1bGVzLmxlbmd0aCA9IDA7XG4gICAgfVxuXG4gICAgLy8gaW5oZXJpdCBhIGZ1bmN0aW9uIHJlZ2lzdHJ5IGZyb20gdGhlIGZyYW1lcyBzdGFjayB3aGVuIHBvc3NpYmxlO1xuICAgIC8vIG90aGVyd2lzZSBmcm9tIHRoZSBnbG9iYWwgcmVnaXN0cnlcbiAgICBydWxlc2V0LmZ1bmN0aW9uUmVnaXN0cnkgPSAoZnVuY3Rpb24gKGZyYW1lcykge1xuICAgICAgICB2YXIgaSA9IDAsXG4gICAgICAgICAgICBuID0gZnJhbWVzLmxlbmd0aCxcbiAgICAgICAgICAgIGZvdW5kO1xuICAgICAgICBmb3IgKCA7IGkgIT09IG4gOyArK2kgKSB7XG4gICAgICAgICAgICBmb3VuZCA9IGZyYW1lc1sgaSBdLmZ1bmN0aW9uUmVnaXN0cnk7XG4gICAgICAgICAgICBpZiAoIGZvdW5kICkgeyByZXR1cm4gZm91bmQ7IH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZ2xvYmFsRnVuY3Rpb25SZWdpc3RyeTtcbiAgICB9KGNvbnRleHQuZnJhbWVzKSkuaW5oZXJpdCgpO1xuXG4gICAgLy8gcHVzaCB0aGUgY3VycmVudCBydWxlc2V0IHRvIHRoZSBmcmFtZXMgc3RhY2tcbiAgICB2YXIgY3R4RnJhbWVzID0gY29udGV4dC5mcmFtZXM7XG4gICAgY3R4RnJhbWVzLnVuc2hpZnQocnVsZXNldCk7XG5cbiAgICAvLyBjdXJycmVudCBzZWxlY3RvcnNcbiAgICB2YXIgY3R4U2VsZWN0b3JzID0gY29udGV4dC5zZWxlY3RvcnM7XG4gICAgaWYgKCFjdHhTZWxlY3RvcnMpIHtcbiAgICAgICAgY29udGV4dC5zZWxlY3RvcnMgPSBjdHhTZWxlY3RvcnMgPSBbXTtcbiAgICB9XG4gICAgY3R4U2VsZWN0b3JzLnVuc2hpZnQodGhpcy5zZWxlY3RvcnMpO1xuXG4gICAgLy8gRXZhbHVhdGUgaW1wb3J0c1xuICAgIGlmIChydWxlc2V0LnJvb3QgfHwgcnVsZXNldC5hbGxvd0ltcG9ydHMgfHwgIXJ1bGVzZXQuc3RyaWN0SW1wb3J0cykge1xuICAgICAgICBydWxlc2V0LmV2YWxJbXBvcnRzKGNvbnRleHQpO1xuICAgIH1cblxuICAgIC8vIFN0b3JlIHRoZSBmcmFtZXMgYXJvdW5kIG1peGluIGRlZmluaXRpb25zLFxuICAgIC8vIHNvIHRoZXkgY2FuIGJlIGV2YWx1YXRlZCBsaWtlIGNsb3N1cmVzIHdoZW4gdGhlIHRpbWUgY29tZXMuXG4gICAgdmFyIHJzUnVsZXMgPSBydWxlc2V0LnJ1bGVzLCByc1J1bGVDbnQgPSByc1J1bGVzID8gcnNSdWxlcy5sZW5ndGggOiAwO1xuICAgIGZvciAoaSA9IDA7IGkgPCByc1J1bGVDbnQ7IGkrKykge1xuICAgICAgICBpZiAocnNSdWxlc1tpXS5ldmFsRmlyc3QpIHtcbiAgICAgICAgICAgIHJzUnVsZXNbaV0gPSByc1J1bGVzW2ldLmV2YWwoY29udGV4dCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgbWVkaWFCbG9ja0NvdW50ID0gKGNvbnRleHQubWVkaWFCbG9ja3MgJiYgY29udGV4dC5tZWRpYUJsb2Nrcy5sZW5ndGgpIHx8IDA7XG5cbiAgICAvLyBFdmFsdWF0ZSBtaXhpbiBjYWxscy5cbiAgICBmb3IgKGkgPSAwOyBpIDwgcnNSdWxlQ250OyBpKyspIHtcbiAgICAgICAgaWYgKHJzUnVsZXNbaV0udHlwZSA9PT0gXCJNaXhpbkNhbGxcIikge1xuICAgICAgICAgICAgLypqc2hpbnQgbG9vcGZ1bmM6dHJ1ZSAqL1xuICAgICAgICAgICAgcnVsZXMgPSByc1J1bGVzW2ldLmV2YWwoY29udGV4dCkuZmlsdGVyKGZ1bmN0aW9uKHIpIHtcbiAgICAgICAgICAgICAgICBpZiAoKHIgaW5zdGFuY2VvZiBSdWxlKSAmJiByLnZhcmlhYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdCBwb2xsdXRlIHRoZSBzY29wZSBpZiB0aGUgdmFyaWFibGUgaXNcbiAgICAgICAgICAgICAgICAgICAgLy8gYWxyZWFkeSB0aGVyZS4gY29uc2lkZXIgcmV0dXJuaW5nIGZhbHNlIGhlcmVcbiAgICAgICAgICAgICAgICAgICAgLy8gYnV0IHdlIG5lZWQgYSB3YXkgdG8gXCJyZXR1cm5cIiB2YXJpYWJsZSBmcm9tIG1peGluc1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gIShydWxlc2V0LnZhcmlhYmxlKHIubmFtZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcnNSdWxlcy5zcGxpY2UuYXBwbHkocnNSdWxlcywgW2ksIDFdLmNvbmNhdChydWxlcykpO1xuICAgICAgICAgICAgcnNSdWxlQ250ICs9IHJ1bGVzLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICBpICs9IHJ1bGVzLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICBydWxlc2V0LnJlc2V0Q2FjaGUoKTtcbiAgICAgICAgfSBlbHNlIGlmIChyc1J1bGVzW2ldLnR5cGUgPT09IFwiUnVsZXNldENhbGxcIikge1xuICAgICAgICAgICAgLypqc2hpbnQgbG9vcGZ1bmM6dHJ1ZSAqL1xuICAgICAgICAgICAgcnVsZXMgPSByc1J1bGVzW2ldLmV2YWwoY29udGV4dCkucnVsZXMuZmlsdGVyKGZ1bmN0aW9uKHIpIHtcbiAgICAgICAgICAgICAgICBpZiAoKHIgaW5zdGFuY2VvZiBSdWxlKSAmJiByLnZhcmlhYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGRvIG5vdCBwb2xsdXRlIHRoZSBzY29wZSBhdCBhbGxcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcnNSdWxlcy5zcGxpY2UuYXBwbHkocnNSdWxlcywgW2ksIDFdLmNvbmNhdChydWxlcykpO1xuICAgICAgICAgICAgcnNSdWxlQ250ICs9IHJ1bGVzLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICBpICs9IHJ1bGVzLmxlbmd0aCAtIDE7XG4gICAgICAgICAgICBydWxlc2V0LnJlc2V0Q2FjaGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEV2YWx1YXRlIGV2ZXJ5dGhpbmcgZWxzZVxuICAgIGZvciAoaSA9IDA7IGkgPCByc1J1bGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJ1bGUgPSByc1J1bGVzW2ldO1xuICAgICAgICBpZiAoIXJ1bGUuZXZhbEZpcnN0KSB7XG4gICAgICAgICAgICByc1J1bGVzW2ldID0gcnVsZSA9IHJ1bGUuZXZhbCA/IHJ1bGUuZXZhbChjb250ZXh0KSA6IHJ1bGU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBFdmFsdWF0ZSBldmVyeXRoaW5nIGVsc2VcbiAgICBmb3IgKGkgPSAwOyBpIDwgcnNSdWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBydWxlID0gcnNSdWxlc1tpXTtcbiAgICAgICAgLy8gZm9yIHJ1bGVzZXRzLCBjaGVjayBpZiBpdCBpcyBhIGNzcyBndWFyZCBhbmQgY2FuIGJlIHJlbW92ZWRcbiAgICAgICAgaWYgKHJ1bGUgaW5zdGFuY2VvZiBSdWxlc2V0ICYmIHJ1bGUuc2VsZWN0b3JzICYmIHJ1bGUuc2VsZWN0b3JzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgLy8gY2hlY2sgaWYgaXQgY2FuIGJlIGZvbGRlZCBpbiAoZS5nLiAmIHdoZXJlKVxuICAgICAgICAgICAgaWYgKHJ1bGUuc2VsZWN0b3JzWzBdLmlzSnVzdFBhcmVudFNlbGVjdG9yKCkpIHtcbiAgICAgICAgICAgICAgICByc1J1bGVzLnNwbGljZShpLS0sIDEpO1xuXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBydWxlLnJ1bGVzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIHN1YlJ1bGUgPSBydWxlLnJ1bGVzW2pdO1xuICAgICAgICAgICAgICAgICAgICBzdWJSdWxlLmNvcHlWaXNpYmlsaXR5SW5mbyhydWxlLnZpc2liaWxpdHlJbmZvKCkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIShzdWJSdWxlIGluc3RhbmNlb2YgUnVsZSkgfHwgIXN1YlJ1bGUudmFyaWFibGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJzUnVsZXMuc3BsaWNlKCsraSwgMCwgc3ViUnVsZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBQb3AgdGhlIHN0YWNrXG4gICAgY3R4RnJhbWVzLnNoaWZ0KCk7XG4gICAgY3R4U2VsZWN0b3JzLnNoaWZ0KCk7XG5cbiAgICBpZiAoY29udGV4dC5tZWRpYUJsb2Nrcykge1xuICAgICAgICBmb3IgKGkgPSBtZWRpYUJsb2NrQ291bnQ7IGkgPCBjb250ZXh0Lm1lZGlhQmxvY2tzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb250ZXh0Lm1lZGlhQmxvY2tzW2ldLmJ1YmJsZVNlbGVjdG9ycyhzZWxlY3RvcnMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJ1bGVzZXQ7XG59O1xuUnVsZXNldC5wcm90b3R5cGUuZXZhbEltcG9ydHMgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIHJ1bGVzID0gdGhpcy5ydWxlcywgaSwgaW1wb3J0UnVsZXM7XG4gICAgaWYgKCFydWxlcykgeyByZXR1cm47IH1cblxuICAgIGZvciAoaSA9IDA7IGkgPCBydWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAocnVsZXNbaV0udHlwZSA9PT0gXCJJbXBvcnRcIikge1xuICAgICAgICAgICAgaW1wb3J0UnVsZXMgPSBydWxlc1tpXS5ldmFsKGNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKGltcG9ydFJ1bGVzICYmIChpbXBvcnRSdWxlcy5sZW5ndGggfHwgaW1wb3J0UnVsZXMubGVuZ3RoID09PSAwKSkge1xuICAgICAgICAgICAgICAgIHJ1bGVzLnNwbGljZS5hcHBseShydWxlcywgW2ksIDFdLmNvbmNhdChpbXBvcnRSdWxlcykpO1xuICAgICAgICAgICAgICAgIGkrPSBpbXBvcnRSdWxlcy5sZW5ndGggLSAxO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBydWxlcy5zcGxpY2UoaSwgMSwgaW1wb3J0UnVsZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5yZXNldENhY2hlKCk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuUnVsZXNldC5wcm90b3R5cGUubWFrZUltcG9ydGFudCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciByZXN1bHQgPSBuZXcgUnVsZXNldCh0aGlzLnNlbGVjdG9ycywgdGhpcy5ydWxlcy5tYXAoZnVuY3Rpb24gKHIpIHtcbiAgICAgICAgaWYgKHIubWFrZUltcG9ydGFudCkge1xuICAgICAgICAgICAgcmV0dXJuIHIubWFrZUltcG9ydGFudCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHI7XG4gICAgICAgIH1cbiAgICB9KSwgdGhpcy5zdHJpY3RJbXBvcnRzLCB0aGlzLnZpc2liaWxpdHlJbmZvKCkpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn07XG5SdWxlc2V0LnByb3RvdHlwZS5tYXRjaEFyZ3MgPSBmdW5jdGlvbiAoYXJncykge1xuICAgIHJldHVybiAhYXJncyB8fCBhcmdzLmxlbmd0aCA9PT0gMDtcbn07XG4vLyBsZXRzIHlvdSBjYWxsIGEgY3NzIHNlbGVjdG9yIHdpdGggYSBndWFyZFxuUnVsZXNldC5wcm90b3R5cGUubWF0Y2hDb25kaXRpb24gPSBmdW5jdGlvbiAoYXJncywgY29udGV4dCkge1xuICAgIHZhciBsYXN0U2VsZWN0b3IgPSB0aGlzLnNlbGVjdG9yc1t0aGlzLnNlbGVjdG9ycy5sZW5ndGggLSAxXTtcbiAgICBpZiAoIWxhc3RTZWxlY3Rvci5ldmFsZENvbmRpdGlvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChsYXN0U2VsZWN0b3IuY29uZGl0aW9uICYmXG4gICAgICAgICFsYXN0U2VsZWN0b3IuY29uZGl0aW9uLmV2YWwoXG4gICAgICAgICAgICBuZXcgY29udGV4dHMuRXZhbChjb250ZXh0LFxuICAgICAgICAgICAgICAgIGNvbnRleHQuZnJhbWVzKSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5SdWxlc2V0LnByb3RvdHlwZS5yZXNldENhY2hlID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuX3J1bGVzZXRzID0gbnVsbDtcbiAgICB0aGlzLl92YXJpYWJsZXMgPSBudWxsO1xuICAgIHRoaXMuX2xvb2t1cHMgPSB7fTtcbn07XG5SdWxlc2V0LnByb3RvdHlwZS52YXJpYWJsZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLl92YXJpYWJsZXMpIHtcbiAgICAgICAgdGhpcy5fdmFyaWFibGVzID0gIXRoaXMucnVsZXMgPyB7fSA6IHRoaXMucnVsZXMucmVkdWNlKGZ1bmN0aW9uIChoYXNoLCByKSB7XG4gICAgICAgICAgICBpZiAociBpbnN0YW5jZW9mIFJ1bGUgJiYgci52YXJpYWJsZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIGhhc2hbci5uYW1lXSA9IHI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyB3aGVuIGV2YWx1YXRpbmcgdmFyaWFibGVzIGluIGFuIGltcG9ydCBzdGF0ZW1lbnQsIGltcG9ydHMgaGF2ZSBub3QgYmVlbiBldmFsJ2RcbiAgICAgICAgICAgIC8vIHNvIHdlIG5lZWQgdG8gZ28gaW5zaWRlIGltcG9ydCBzdGF0ZW1lbnRzLlxuICAgICAgICAgICAgLy8gZ3VhcmQgYWdhaW5zdCByb290IGJlaW5nIGEgc3RyaW5nIChpbiB0aGUgY2FzZSBvZiBpbmxpbmVkIGxlc3MpXG4gICAgICAgICAgICBpZiAoci50eXBlID09PSBcIkltcG9ydFwiICYmIHIucm9vdCAmJiByLnJvb3QudmFyaWFibGVzKSB7XG4gICAgICAgICAgICAgICAgdmFyIHZhcnMgPSByLnJvb3QudmFyaWFibGVzKCk7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgbmFtZSBpbiB2YXJzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YXJzLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoYXNoW25hbWVdID0gdmFyc1tuYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBoYXNoO1xuICAgICAgICB9LCB7fSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl92YXJpYWJsZXM7XG59O1xuUnVsZXNldC5wcm90b3R5cGUudmFyaWFibGUgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHJldHVybiB0aGlzLnZhcmlhYmxlcygpW25hbWVdO1xufTtcblJ1bGVzZXQucHJvdG90eXBlLnJ1bGVzZXRzID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy5ydWxlcykgeyByZXR1cm4gW107IH1cblxuICAgIHZhciBmaWx0UnVsZXMgPSBbXSwgcnVsZXMgPSB0aGlzLnJ1bGVzLCBjbnQgPSBydWxlcy5sZW5ndGgsXG4gICAgICAgIGksIHJ1bGU7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgY250OyBpKyspIHtcbiAgICAgICAgcnVsZSA9IHJ1bGVzW2ldO1xuICAgICAgICBpZiAocnVsZS5pc1J1bGVzZXQpIHtcbiAgICAgICAgICAgIGZpbHRSdWxlcy5wdXNoKHJ1bGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpbHRSdWxlcztcbn07XG5SdWxlc2V0LnByb3RvdHlwZS5wcmVwZW5kUnVsZSA9IGZ1bmN0aW9uIChydWxlKSB7XG4gICAgdmFyIHJ1bGVzID0gdGhpcy5ydWxlcztcbiAgICBpZiAocnVsZXMpIHtcbiAgICAgICAgcnVsZXMudW5zaGlmdChydWxlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnJ1bGVzID0gWyBydWxlIF07XG4gICAgfVxufTtcblJ1bGVzZXQucHJvdG90eXBlLmZpbmQgPSBmdW5jdGlvbiAoc2VsZWN0b3IsIHNlbGYsIGZpbHRlcikge1xuICAgIHNlbGYgPSBzZWxmIHx8IHRoaXM7XG4gICAgdmFyIHJ1bGVzID0gW10sIG1hdGNoLCBmb3VuZE1peGlucyxcbiAgICAgICAga2V5ID0gc2VsZWN0b3IudG9DU1MoKTtcblxuICAgIGlmIChrZXkgaW4gdGhpcy5fbG9va3VwcykgeyByZXR1cm4gdGhpcy5fbG9va3Vwc1trZXldOyB9XG5cbiAgICB0aGlzLnJ1bGVzZXRzKCkuZm9yRWFjaChmdW5jdGlvbiAocnVsZSkge1xuICAgICAgICBpZiAocnVsZSAhPT0gc2VsZikge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBydWxlLnNlbGVjdG9ycy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgIG1hdGNoID0gc2VsZWN0b3IubWF0Y2gocnVsZS5zZWxlY3RvcnNbal0pO1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IuZWxlbWVudHMubGVuZ3RoID4gbWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlsdGVyIHx8IGZpbHRlcihydWxlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kTWl4aW5zID0gcnVsZS5maW5kKG5ldyBTZWxlY3RvcihzZWxlY3Rvci5lbGVtZW50cy5zbGljZShtYXRjaCkpLCBzZWxmLCBmaWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZm91bmRNaXhpbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRNaXhpbnNbaV0ucGF0aC5wdXNoKHJ1bGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShydWxlcywgZm91bmRNaXhpbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcnVsZXMucHVzaCh7IHJ1bGU6IHJ1bGUsIHBhdGg6IFtdfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5fbG9va3Vwc1trZXldID0gcnVsZXM7XG4gICAgcmV0dXJuIHJ1bGVzO1xufTtcblJ1bGVzZXQucHJvdG90eXBlLmdlbkNTUyA9IGZ1bmN0aW9uIChjb250ZXh0LCBvdXRwdXQpIHtcbiAgICB2YXIgaSwgaixcbiAgICAgICAgY2hhcnNldFJ1bGVOb2RlcyA9IFtdLFxuICAgICAgICBydWxlTm9kZXMgPSBbXSxcbiAgICAgICAgZGVidWdJbmZvLCAgICAgLy8gTGluZSBudW1iZXIgZGVidWdnaW5nXG4gICAgICAgIHJ1bGUsXG4gICAgICAgIHBhdGg7XG5cbiAgICBjb250ZXh0LnRhYkxldmVsID0gKGNvbnRleHQudGFiTGV2ZWwgfHwgMCk7XG5cbiAgICBpZiAoIXRoaXMucm9vdCkge1xuICAgICAgICBjb250ZXh0LnRhYkxldmVsKys7XG4gICAgfVxuXG4gICAgdmFyIHRhYlJ1bGVTdHIgPSBjb250ZXh0LmNvbXByZXNzID8gJycgOiBBcnJheShjb250ZXh0LnRhYkxldmVsICsgMSkuam9pbihcIiAgXCIpLFxuICAgICAgICB0YWJTZXRTdHIgPSBjb250ZXh0LmNvbXByZXNzID8gJycgOiBBcnJheShjb250ZXh0LnRhYkxldmVsKS5qb2luKFwiICBcIiksXG4gICAgICAgIHNlcDtcblxuICAgIGZ1bmN0aW9uIGlzUnVsZXNldExpa2VOb2RlKHJ1bGUpIHtcbiAgICAgICAgLy8gaWYgaXQgaGFzIG5lc3RlZCBydWxlcywgdGhlbiBpdCBzaG91bGQgYmUgdHJlYXRlZCBsaWtlIGEgcnVsZXNldFxuICAgICAgICAvLyBtZWRpYXMgYW5kIGNvbW1lbnRzIGRvIG5vdCBoYXZlIG5lc3RlZCBydWxlcywgYnV0IHNob3VsZCBiZSB0cmVhdGVkIGxpa2UgcnVsZXNldHMgYW55d2F5XG4gICAgICAgIC8vIHNvbWUgZGlyZWN0aXZlcyBhbmQgYW5vbnltb3VzIG5vZGVzIGFyZSBydWxlc2V0IGxpa2UsIG90aGVycyBhcmUgbm90XG4gICAgICAgIGlmICh0eXBlb2YgcnVsZS5pc1J1bGVzZXRMaWtlID09PSBcImJvb2xlYW5cIikge1xuICAgICAgICAgICAgcmV0dXJuIHJ1bGUuaXNSdWxlc2V0TGlrZTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgcnVsZS5pc1J1bGVzZXRMaWtlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBydWxlLmlzUnVsZXNldExpa2UoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vYW55dGhpbmcgZWxzZSBpcyBhc3N1bWVkIHRvIGJlIGEgcnVsZVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIGNoYXJzZXROb2RlSW5kZXggPSAwO1xuICAgIHZhciBpbXBvcnROb2RlSW5kZXggPSAwO1xuICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLnJ1bGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJ1bGUgPSB0aGlzLnJ1bGVzW2ldO1xuICAgICAgICBpZiAocnVsZS50eXBlID09PSBcIkNvbW1lbnRcIikge1xuICAgICAgICAgICAgaWYgKGltcG9ydE5vZGVJbmRleCA9PT0gaSkge1xuICAgICAgICAgICAgICAgIGltcG9ydE5vZGVJbmRleCsrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcnVsZU5vZGVzLnB1c2gocnVsZSk7XG4gICAgICAgIH0gZWxzZSBpZiAocnVsZS5pc0NoYXJzZXQgJiYgcnVsZS5pc0NoYXJzZXQoKSkge1xuICAgICAgICAgICAgcnVsZU5vZGVzLnNwbGljZShjaGFyc2V0Tm9kZUluZGV4LCAwLCBydWxlKTtcbiAgICAgICAgICAgIGNoYXJzZXROb2RlSW5kZXgrKztcbiAgICAgICAgICAgIGltcG9ydE5vZGVJbmRleCsrO1xuICAgICAgICB9IGVsc2UgaWYgKHJ1bGUudHlwZSA9PT0gXCJJbXBvcnRcIikge1xuICAgICAgICAgICAgcnVsZU5vZGVzLnNwbGljZShpbXBvcnROb2RlSW5kZXgsIDAsIHJ1bGUpO1xuICAgICAgICAgICAgaW1wb3J0Tm9kZUluZGV4Kys7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBydWxlTm9kZXMucHVzaChydWxlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBydWxlTm9kZXMgPSBjaGFyc2V0UnVsZU5vZGVzLmNvbmNhdChydWxlTm9kZXMpO1xuXG4gICAgLy8gSWYgdGhpcyBpcyB0aGUgcm9vdCBub2RlLCB3ZSBkb24ndCByZW5kZXJcbiAgICAvLyBhIHNlbGVjdG9yLCBvciB7fS5cbiAgICBpZiAoIXRoaXMucm9vdCkge1xuICAgICAgICBkZWJ1Z0luZm8gPSBnZXREZWJ1Z0luZm8oY29udGV4dCwgdGhpcywgdGFiU2V0U3RyKTtcblxuICAgICAgICBpZiAoZGVidWdJbmZvKSB7XG4gICAgICAgICAgICBvdXRwdXQuYWRkKGRlYnVnSW5mbyk7XG4gICAgICAgICAgICBvdXRwdXQuYWRkKHRhYlNldFN0cik7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcGF0aHMgPSB0aGlzLnBhdGhzLCBwYXRoQ250ID0gcGF0aHMubGVuZ3RoLFxuICAgICAgICAgICAgcGF0aFN1YkNudDtcblxuICAgICAgICBzZXAgPSBjb250ZXh0LmNvbXByZXNzID8gJywnIDogKCcsXFxuJyArIHRhYlNldFN0cik7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBhdGhDbnQ7IGkrKykge1xuICAgICAgICAgICAgcGF0aCA9IHBhdGhzW2ldO1xuICAgICAgICAgICAgaWYgKCEocGF0aFN1YkNudCA9IHBhdGgubGVuZ3RoKSkgeyBjb250aW51ZTsgfVxuICAgICAgICAgICAgaWYgKGkgPiAwKSB7IG91dHB1dC5hZGQoc2VwKTsgfVxuXG4gICAgICAgICAgICBjb250ZXh0LmZpcnN0U2VsZWN0b3IgPSB0cnVlO1xuICAgICAgICAgICAgcGF0aFswXS5nZW5DU1MoY29udGV4dCwgb3V0cHV0KTtcblxuICAgICAgICAgICAgY29udGV4dC5maXJzdFNlbGVjdG9yID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKGogPSAxOyBqIDwgcGF0aFN1YkNudDsgaisrKSB7XG4gICAgICAgICAgICAgICAgcGF0aFtqXS5nZW5DU1MoY29udGV4dCwgb3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIG91dHB1dC5hZGQoKGNvbnRleHQuY29tcHJlc3MgPyAneycgOiAnIHtcXG4nKSArIHRhYlJ1bGVTdHIpO1xuICAgIH1cblxuICAgIC8vIENvbXBpbGUgcnVsZXMgYW5kIHJ1bGVzZXRzXG4gICAgZm9yIChpID0gMDsgaSA8IHJ1bGVOb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBydWxlID0gcnVsZU5vZGVzW2ldO1xuXG4gICAgICAgIGlmIChpICsgMSA9PT0gcnVsZU5vZGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgY29udGV4dC5sYXN0UnVsZSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY3VycmVudExhc3RSdWxlID0gY29udGV4dC5sYXN0UnVsZTtcbiAgICAgICAgaWYgKGlzUnVsZXNldExpa2VOb2RlKHJ1bGUpKSB7XG4gICAgICAgICAgICBjb250ZXh0Lmxhc3RSdWxlID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocnVsZS5nZW5DU1MpIHtcbiAgICAgICAgICAgIHJ1bGUuZ2VuQ1NTKGNvbnRleHQsIG91dHB1dCk7XG4gICAgICAgIH0gZWxzZSBpZiAocnVsZS52YWx1ZSkge1xuICAgICAgICAgICAgb3V0cHV0LmFkZChydWxlLnZhbHVlLnRvU3RyaW5nKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29udGV4dC5sYXN0UnVsZSA9IGN1cnJlbnRMYXN0UnVsZTtcblxuICAgICAgICBpZiAoIWNvbnRleHQubGFzdFJ1bGUpIHtcbiAgICAgICAgICAgIG91dHB1dC5hZGQoY29udGV4dC5jb21wcmVzcyA/ICcnIDogKCdcXG4nICsgdGFiUnVsZVN0cikpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udGV4dC5sYXN0UnVsZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnJvb3QpIHtcbiAgICAgICAgb3V0cHV0LmFkZCgoY29udGV4dC5jb21wcmVzcyA/ICd9JyA6ICdcXG4nICsgdGFiU2V0U3RyICsgJ30nKSk7XG4gICAgICAgIGNvbnRleHQudGFiTGV2ZWwtLTtcbiAgICB9XG5cbiAgICBpZiAoIW91dHB1dC5pc0VtcHR5KCkgJiYgIWNvbnRleHQuY29tcHJlc3MgJiYgdGhpcy5maXJzdFJvb3QpIHtcbiAgICAgICAgb3V0cHV0LmFkZCgnXFxuJyk7XG4gICAgfVxufTtcblxuUnVsZXNldC5wcm90b3R5cGUuam9pblNlbGVjdG9ycyA9IGZ1bmN0aW9uIChwYXRocywgY29udGV4dCwgc2VsZWN0b3JzKSB7XG4gICAgZm9yICh2YXIgcyA9IDA7IHMgPCBzZWxlY3RvcnMubGVuZ3RoOyBzKyspIHtcbiAgICAgICAgdGhpcy5qb2luU2VsZWN0b3IocGF0aHMsIGNvbnRleHQsIHNlbGVjdG9yc1tzXSk7XG4gICAgfVxufTtcblxuUnVsZXNldC5wcm90b3R5cGUuam9pblNlbGVjdG9yID0gZnVuY3Rpb24gKHBhdGhzLCBjb250ZXh0LCBzZWxlY3Rvcikge1xuXG4gICAgZnVuY3Rpb24gY3JlYXRlUGFyZW50aGVzaXMoZWxlbWVudHNUb1Bhaywgb3JpZ2luYWxFbGVtZW50KSB7XG4gICAgICAgIHZhciByZXBsYWNlbWVudFBhcmVuLCBqO1xuICAgICAgICBpZiAoZWxlbWVudHNUb1Bhay5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJlcGxhY2VtZW50UGFyZW4gPSBuZXcgUGFyZW4oZWxlbWVudHNUb1Bha1swXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgaW5zaWRlUGFyZW50ID0gW107XG4gICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgZWxlbWVudHNUb1Bhay5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgIGluc2lkZVBhcmVudC5wdXNoKG5ldyBFbGVtZW50KG51bGwsIGVsZW1lbnRzVG9QYWtbal0sIG9yaWdpbmFsRWxlbWVudC5pbmRleCwgb3JpZ2luYWxFbGVtZW50LmN1cnJlbnRGaWxlSW5mbykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVwbGFjZW1lbnRQYXJlbiA9IG5ldyBQYXJlbihuZXcgU2VsZWN0b3IoaW5zaWRlUGFyZW50KSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcGxhY2VtZW50UGFyZW47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlU2VsZWN0b3IoY29udGFpbmVkRWxlbWVudCwgb3JpZ2luYWxFbGVtZW50KSB7XG4gICAgICAgIHZhciBlbGVtZW50LCBzZWxlY3RvcjtcbiAgICAgICAgZWxlbWVudCA9IG5ldyBFbGVtZW50KG51bGwsIGNvbnRhaW5lZEVsZW1lbnQsIG9yaWdpbmFsRWxlbWVudC5pbmRleCwgb3JpZ2luYWxFbGVtZW50LmN1cnJlbnRGaWxlSW5mbyk7XG4gICAgICAgIHNlbGVjdG9yID0gbmV3IFNlbGVjdG9yKFtlbGVtZW50XSk7XG4gICAgICAgIHJldHVybiBzZWxlY3RvcjtcbiAgICB9XG5cbiAgICAvLyBqb2lucyBzZWxlY3RvciBwYXRoIGZyb20gYGJlZ2lubmluZ1BhdGhgIHdpdGggc2VsZWN0b3IgcGF0aCBpbiBgYWRkUGF0aGBcbiAgICAvLyBgcmVwbGFjZWRFbGVtZW50YCBjb250YWlucyBlbGVtZW50IHRoYXQgaXMgYmVpbmcgcmVwbGFjZWQgYnkgYGFkZFBhdGhgXG4gICAgLy8gcmV0dXJucyBjb25jYXRlbmF0ZWQgcGF0aFxuICAgIGZ1bmN0aW9uIGFkZFJlcGxhY2VtZW50SW50b1BhdGgoYmVnaW5uaW5nUGF0aCwgYWRkUGF0aCwgcmVwbGFjZWRFbGVtZW50LCBvcmlnaW5hbFNlbGVjdG9yKSB7XG4gICAgICAgIHZhciBuZXdTZWxlY3RvclBhdGgsIGxhc3RTZWxlY3RvciwgbmV3Sm9pbmVkU2VsZWN0b3I7XG4gICAgICAgIC8vIG91ciBuZXcgc2VsZWN0b3IgcGF0aFxuICAgICAgICBuZXdTZWxlY3RvclBhdGggPSBbXTtcblxuICAgICAgICAvL2NvbnN0cnVjdCB0aGUgam9pbmVkIHNlbGVjdG9yIC0gaWYgJiBpcyB0aGUgZmlyc3QgdGhpbmcgdGhpcyB3aWxsIGJlIGVtcHR5LFxuICAgICAgICAvLyBpZiBub3QgbmV3Sm9pbmVkU2VsZWN0b3Igd2lsbCBiZSB0aGUgbGFzdCBzZXQgb2YgZWxlbWVudHMgaW4gdGhlIHNlbGVjdG9yXG4gICAgICAgIGlmIChiZWdpbm5pbmdQYXRoLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIG5ld1NlbGVjdG9yUGF0aCA9IGJlZ2lubmluZ1BhdGguc2xpY2UoMCk7XG4gICAgICAgICAgICBsYXN0U2VsZWN0b3IgPSBuZXdTZWxlY3RvclBhdGgucG9wKCk7XG4gICAgICAgICAgICBuZXdKb2luZWRTZWxlY3RvciA9IG9yaWdpbmFsU2VsZWN0b3IuY3JlYXRlRGVyaXZlZChsYXN0U2VsZWN0b3IuZWxlbWVudHMuc2xpY2UoMCkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbmV3Sm9pbmVkU2VsZWN0b3IgPSBvcmlnaW5hbFNlbGVjdG9yLmNyZWF0ZURlcml2ZWQoW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFkZFBhdGgubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgLy8gL2RlZXAvIGlzIGEgY29tYmluYXRvciB0aGF0IGlzIHZhbGlkIHdpdGhvdXQgYW55dGhpbmcgaW4gZnJvbnQgb2YgaXRcbiAgICAgICAgICAgIC8vIHNvIGlmIHRoZSAmIGRvZXMgbm90IGhhdmUgYSBjb21iaW5hdG9yIHRoYXQgaXMgXCJcIiBvciBcIiBcIiB0aGVuXG4gICAgICAgICAgICAvLyBhbmQgdGhlcmUgaXMgYSBjb21iaW5hdG9yIG9uIHRoZSBwYXJlbnQsIHRoZW4gZ3JhYiB0aGF0LlxuICAgICAgICAgICAgLy8gdGhpcyBhbHNvIGFsbG93cyArIGEgeyAmIC5iIHsgLmEgJiB7IC4uLiB0aG91Z2ggbm90IHN1cmUgd2h5IHlvdSB3b3VsZCB3YW50IHRvIGRvIHRoYXRcbiAgICAgICAgICAgIHZhciBjb21iaW5hdG9yID0gcmVwbGFjZWRFbGVtZW50LmNvbWJpbmF0b3IsIHBhcmVudEVsID0gYWRkUGF0aFswXS5lbGVtZW50c1swXTtcbiAgICAgICAgICAgIGlmIChjb21iaW5hdG9yLmVtcHR5T3JXaGl0ZXNwYWNlICYmICFwYXJlbnRFbC5jb21iaW5hdG9yLmVtcHR5T3JXaGl0ZXNwYWNlKSB7XG4gICAgICAgICAgICAgICAgY29tYmluYXRvciA9IHBhcmVudEVsLmNvbWJpbmF0b3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBqb2luIHRoZSBlbGVtZW50cyBzbyBmYXIgd2l0aCB0aGUgZmlyc3QgcGFydCBvZiB0aGUgcGFyZW50XG4gICAgICAgICAgICBuZXdKb2luZWRTZWxlY3Rvci5lbGVtZW50cy5wdXNoKG5ldyBFbGVtZW50KGNvbWJpbmF0b3IsIHBhcmVudEVsLnZhbHVlLCByZXBsYWNlZEVsZW1lbnQuaW5kZXgsIHJlcGxhY2VkRWxlbWVudC5jdXJyZW50RmlsZUluZm8pKTtcbiAgICAgICAgICAgIG5ld0pvaW5lZFNlbGVjdG9yLmVsZW1lbnRzID0gbmV3Sm9pbmVkU2VsZWN0b3IuZWxlbWVudHMuY29uY2F0KGFkZFBhdGhbMF0uZWxlbWVudHMuc2xpY2UoMSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gbm93IGFkZCB0aGUgam9pbmVkIHNlbGVjdG9yIC0gYnV0IG9ubHkgaWYgaXQgaXMgbm90IGVtcHR5XG4gICAgICAgIGlmIChuZXdKb2luZWRTZWxlY3Rvci5lbGVtZW50cy5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgIG5ld1NlbGVjdG9yUGF0aC5wdXNoKG5ld0pvaW5lZFNlbGVjdG9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vcHV0IHRvZ2V0aGVyIHRoZSBwYXJlbnQgc2VsZWN0b3JzIGFmdGVyIHRoZSBqb2luIChlLmcuIHRoZSByZXN0IG9mIHRoZSBwYXJlbnQpXG4gICAgICAgIGlmIChhZGRQYXRoLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIHZhciByZXN0T2ZQYXRoID0gYWRkUGF0aC5zbGljZSgxKTtcbiAgICAgICAgICAgIHJlc3RPZlBhdGggPSByZXN0T2ZQYXRoLm1hcChmdW5jdGlvbiAoc2VsZWN0b3IpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0b3IuY3JlYXRlRGVyaXZlZChzZWxlY3Rvci5lbGVtZW50cywgW10pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBuZXdTZWxlY3RvclBhdGggPSBuZXdTZWxlY3RvclBhdGguY29uY2F0KHJlc3RPZlBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXdTZWxlY3RvclBhdGg7XG4gICAgfVxuXG4gICAgLy8gam9pbnMgc2VsZWN0b3IgcGF0aCBmcm9tIGBiZWdpbm5pbmdQYXRoYCB3aXRoIGV2ZXJ5IHNlbGVjdG9yIHBhdGggaW4gYGFkZFBhdGhzYCBhcnJheVxuICAgIC8vIGByZXBsYWNlZEVsZW1lbnRgIGNvbnRhaW5zIGVsZW1lbnQgdGhhdCBpcyBiZWluZyByZXBsYWNlZCBieSBgYWRkUGF0aGBcbiAgICAvLyByZXR1cm5zIGFycmF5IHdpdGggYWxsIGNvbmNhdGVuYXRlZCBwYXRoc1xuICAgIGZ1bmN0aW9uIGFkZEFsbFJlcGxhY2VtZW50c0ludG9QYXRoKCBiZWdpbm5pbmdQYXRoLCBhZGRQYXRocywgcmVwbGFjZWRFbGVtZW50LCBvcmlnaW5hbFNlbGVjdG9yLCByZXN1bHQpIHtcbiAgICAgICAgdmFyIGo7XG4gICAgICAgIGZvciAoaiA9IDA7IGogPCBiZWdpbm5pbmdQYXRoLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICB2YXIgbmV3U2VsZWN0b3JQYXRoID0gYWRkUmVwbGFjZW1lbnRJbnRvUGF0aChiZWdpbm5pbmdQYXRoW2pdLCBhZGRQYXRocywgcmVwbGFjZWRFbGVtZW50LCBvcmlnaW5hbFNlbGVjdG9yKTtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKG5ld1NlbGVjdG9yUGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtZXJnZUVsZW1lbnRzT25Ub1NlbGVjdG9ycyhlbGVtZW50cywgc2VsZWN0b3JzKSB7XG4gICAgICAgIHZhciBpLCBzZWw7XG5cbiAgICAgICAgaWYgKGVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VsZWN0b3JzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgc2VsZWN0b3JzLnB1c2goWyBuZXcgU2VsZWN0b3IoZWxlbWVudHMpIF0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHNlbGVjdG9ycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgc2VsID0gc2VsZWN0b3JzW2ldO1xuXG4gICAgICAgICAgICAvLyBpZiB0aGUgcHJldmlvdXMgdGhpbmcgaW4gc2VsIGlzIGEgcGFyZW50IHRoaXMgbmVlZHMgdG8gam9pbiBvbiB0byBpdFxuICAgICAgICAgICAgaWYgKHNlbC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgc2VsW3NlbC5sZW5ndGggLSAxXSA9IHNlbFtzZWwubGVuZ3RoIC0gMV0uY3JlYXRlRGVyaXZlZChzZWxbc2VsLmxlbmd0aCAtIDFdLmVsZW1lbnRzLmNvbmNhdChlbGVtZW50cykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2VsLnB1c2gobmV3IFNlbGVjdG9yKGVsZW1lbnRzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyByZXBsYWNlIGFsbCBwYXJlbnQgc2VsZWN0b3JzIGluc2lkZSBgaW5TZWxlY3RvcmAgYnkgY29udGVudCBvZiBgY29udGV4dGAgYXJyYXlcbiAgICAvLyByZXN1bHRpbmcgc2VsZWN0b3JzIGFyZSByZXR1cm5lZCBpbnNpZGUgYHBhdGhzYCBhcnJheVxuICAgIC8vIHJldHVybnMgdHJ1ZSBpZiBgaW5TZWxlY3RvcmAgY29udGFpbmVkIGF0IGxlYXN0IG9uZSBwYXJlbnQgc2VsZWN0b3JcbiAgICBmdW5jdGlvbiByZXBsYWNlUGFyZW50U2VsZWN0b3IocGF0aHMsIGNvbnRleHQsIGluU2VsZWN0b3IpIHtcbiAgICAgICAgLy8gVGhlIHBhdGhzIGFyZSBbW1NlbGVjdG9yXV1cbiAgICAgICAgLy8gVGhlIGZpcnN0IGxpc3QgaXMgYSBsaXN0IG9mIGNvbW1hIHNlcGFyYXRlZCBzZWxlY3RvcnNcbiAgICAgICAgLy8gVGhlIGlubmVyIGxpc3QgaXMgYSBsaXN0IG9mIGluaGVyaXRhbmNlIHNlcGFyYXRlZCBzZWxlY3RvcnNcbiAgICAgICAgLy8gZS5nLlxuICAgICAgICAvLyAuYSwgLmIge1xuICAgICAgICAvLyAgIC5jIHtcbiAgICAgICAgLy8gICB9XG4gICAgICAgIC8vIH1cbiAgICAgICAgLy8gPT0gW1suYV0gWy5jXV0gW1suYl0gWy5jXV1cbiAgICAgICAgLy9cbiAgICAgICAgdmFyIGksIGosIGssIGN1cnJlbnRFbGVtZW50cywgbmV3U2VsZWN0b3JzLCBzZWxlY3RvcnNNdWx0aXBsaWVkLCBzZWwsIGVsLCBoYWRQYXJlbnRTZWxlY3RvciA9IGZhbHNlLCBsZW5ndGgsIGxhc3RTZWxlY3RvcjtcbiAgICAgICAgZnVuY3Rpb24gZmluZE5lc3RlZFNlbGVjdG9yKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIHZhciBtYXliZVNlbGVjdG9yO1xuICAgICAgICAgICAgaWYgKGVsZW1lbnQudmFsdWUudHlwZSAhPT0gJ1BhcmVuJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBtYXliZVNlbGVjdG9yID0gZWxlbWVudC52YWx1ZS52YWx1ZTtcbiAgICAgICAgICAgIGlmIChtYXliZVNlbGVjdG9yLnR5cGUgIT09ICdTZWxlY3RvcicpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG1heWJlU2VsZWN0b3I7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0aGUgZWxlbWVudHMgZnJvbSB0aGUgY3VycmVudCBzZWxlY3RvciBzbyBmYXJcbiAgICAgICAgY3VycmVudEVsZW1lbnRzID0gW107XG4gICAgICAgIC8vIHRoZSBjdXJyZW50IGxpc3Qgb2YgbmV3IHNlbGVjdG9ycyB0byBhZGQgdG8gdGhlIHBhdGguXG4gICAgICAgIC8vIFdlIHdpbGwgYnVpbGQgaXQgdXAuIFdlIGluaXRpYXRlIGl0IHdpdGggb25lIGVtcHR5IHNlbGVjdG9yIGFzIHdlIFwibXVsdGlwbHlcIiB0aGUgbmV3IHNlbGVjdG9yc1xuICAgICAgICAvLyBieSB0aGUgcGFyZW50c1xuICAgICAgICBuZXdTZWxlY3RvcnMgPSBbXG4gICAgICAgICAgICBbXVxuICAgICAgICBdO1xuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBpblNlbGVjdG9yLmVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBlbCA9IGluU2VsZWN0b3IuZWxlbWVudHNbaV07XG4gICAgICAgICAgICAvLyBub24gcGFyZW50IHJlZmVyZW5jZSBlbGVtZW50cyBqdXN0IGdldCBhZGRlZFxuICAgICAgICAgICAgaWYgKGVsLnZhbHVlICE9PSBcIiZcIikge1xuICAgICAgICAgICAgICAgIHZhciBuZXN0ZWRTZWxlY3RvciA9IGZpbmROZXN0ZWRTZWxlY3RvcihlbCk7XG4gICAgICAgICAgICAgICAgaWYgKG5lc3RlZFNlbGVjdG9yICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gbWVyZ2UgdGhlIGN1cnJlbnQgbGlzdCBvZiBub24gcGFyZW50IHNlbGVjdG9yIGVsZW1lbnRzXG4gICAgICAgICAgICAgICAgICAgIC8vIG9uIHRvIHRoZSBjdXJyZW50IGxpc3Qgb2Ygc2VsZWN0b3JzIHRvIGFkZFxuICAgICAgICAgICAgICAgICAgICBtZXJnZUVsZW1lbnRzT25Ub1NlbGVjdG9ycyhjdXJyZW50RWxlbWVudHMsIG5ld1NlbGVjdG9ycyk7XG5cbiAgICAgICAgICAgICAgICAgICAgdmFyIG5lc3RlZFBhdGhzID0gW10sIHJlcGxhY2VkLCByZXBsYWNlZE5ld1NlbGVjdG9ycyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlZCA9IHJlcGxhY2VQYXJlbnRTZWxlY3RvcihuZXN0ZWRQYXRocywgY29udGV4dCwgbmVzdGVkU2VsZWN0b3IpO1xuICAgICAgICAgICAgICAgICAgICBoYWRQYXJlbnRTZWxlY3RvciA9IGhhZFBhcmVudFNlbGVjdG9yIHx8IHJlcGxhY2VkO1xuICAgICAgICAgICAgICAgICAgICAvL3RoZSBuZXN0ZWRQYXRocyBhcnJheSBzaG91bGQgaGF2ZSBvbmx5IG9uZSBtZW1iZXIgLSByZXBsYWNlUGFyZW50U2VsZWN0b3IgZG9lcyBub3QgbXVsdGlwbHkgc2VsZWN0b3JzXG4gICAgICAgICAgICAgICAgICAgIGZvciAoayA9IDA7IGsgPCBuZXN0ZWRQYXRocy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlcGxhY2VtZW50U2VsZWN0b3IgPSBjcmVhdGVTZWxlY3RvcihjcmVhdGVQYXJlbnRoZXNpcyhuZXN0ZWRQYXRoc1trXSwgZWwpLCBlbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRBbGxSZXBsYWNlbWVudHNJbnRvUGF0aChuZXdTZWxlY3RvcnMsIFtyZXBsYWNlbWVudFNlbGVjdG9yXSwgZWwsIGluU2VsZWN0b3IsIHJlcGxhY2VkTmV3U2VsZWN0b3JzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBuZXdTZWxlY3RvcnMgPSByZXBsYWNlZE5ld1NlbGVjdG9ycztcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudEVsZW1lbnRzID0gW107XG5cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50RWxlbWVudHMucHVzaChlbCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGhhZFBhcmVudFNlbGVjdG9yID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAvLyB0aGUgbmV3IGxpc3Qgb2Ygc2VsZWN0b3JzIHRvIGFkZFxuICAgICAgICAgICAgICAgIHNlbGVjdG9yc011bHRpcGxpZWQgPSBbXTtcblxuICAgICAgICAgICAgICAgIC8vIG1lcmdlIHRoZSBjdXJyZW50IGxpc3Qgb2Ygbm9uIHBhcmVudCBzZWxlY3RvciBlbGVtZW50c1xuICAgICAgICAgICAgICAgIC8vIG9uIHRvIHRoZSBjdXJyZW50IGxpc3Qgb2Ygc2VsZWN0b3JzIHRvIGFkZFxuICAgICAgICAgICAgICAgIG1lcmdlRWxlbWVudHNPblRvU2VsZWN0b3JzKGN1cnJlbnRFbGVtZW50cywgbmV3U2VsZWN0b3JzKTtcblxuICAgICAgICAgICAgICAgIC8vIGxvb3AgdGhyb3VnaCBvdXIgY3VycmVudCBzZWxlY3RvcnNcbiAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgbmV3U2VsZWN0b3JzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbCA9IG5ld1NlbGVjdG9yc1tqXTtcbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgd2UgZG9uJ3QgaGF2ZSBhbnkgcGFyZW50IHBhdGhzLCB0aGUgJiBtaWdodCBiZSBpbiBhIG1peGluIHNvIHRoYXQgaXQgY2FuIGJlIHVzZWRcbiAgICAgICAgICAgICAgICAgICAgLy8gd2hldGhlciB0aGVyZSBhcmUgcGFyZW50cyBvciBub3RcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRleHQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgY29tYmluYXRvciB1c2VkIG9uIGVsIHNob3VsZCBub3cgYmUgYXBwbGllZCB0byB0aGUgbmV4dCBlbGVtZW50IGluc3RlYWQgc28gdGhhdFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXQgaXMgbm90IGxvc3RcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWwubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbFswXS5lbGVtZW50cy5wdXNoKG5ldyBFbGVtZW50KGVsLmNvbWJpbmF0b3IsICcnLCBlbC5pbmRleCwgZWwuY3VycmVudEZpbGVJbmZvKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcnNNdWx0aXBsaWVkLnB1c2goc2VsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCB0aGUgcGFyZW50IHNlbGVjdG9yc1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrID0gMDsgayA8IGNvbnRleHQubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBuZWVkIHRvIHB1dCB0aGUgY3VycmVudCBzZWxlY3RvcnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGVuIGpvaW4gdGhlIGxhc3Qgc2VsZWN0b3IncyBlbGVtZW50cyBvbiB0byB0aGUgcGFyZW50cyBzZWxlY3RvcnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3U2VsZWN0b3JQYXRoID0gYWRkUmVwbGFjZW1lbnRJbnRvUGF0aChzZWwsIGNvbnRleHRba10sIGVsLCBpblNlbGVjdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGQgdGhhdCB0byBvdXIgbmV3IHNldCBvZiBzZWxlY3RvcnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RvcnNNdWx0aXBsaWVkLnB1c2gobmV3U2VsZWN0b3JQYXRoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIG91ciBuZXcgc2VsZWN0b3JzIGhhcyBiZWVuIG11bHRpcGxpZWQsIHNvIHJlc2V0IHRoZSBzdGF0ZVxuICAgICAgICAgICAgICAgIG5ld1NlbGVjdG9ycyA9IHNlbGVjdG9yc011bHRpcGxpZWQ7XG4gICAgICAgICAgICAgICAgY3VycmVudEVsZW1lbnRzID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiB3ZSBoYXZlIGFueSBlbGVtZW50cyBsZWZ0IG92ZXIgKGUuZy4gLmEmIC5iID09IC5iKVxuICAgICAgICAvLyBhZGQgdGhlbSBvbiB0byBhbGwgdGhlIGN1cnJlbnQgc2VsZWN0b3JzXG4gICAgICAgIG1lcmdlRWxlbWVudHNPblRvU2VsZWN0b3JzKGN1cnJlbnRFbGVtZW50cywgbmV3U2VsZWN0b3JzKTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbmV3U2VsZWN0b3JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZW5ndGggPSBuZXdTZWxlY3RvcnNbaV0ubGVuZ3RoO1xuICAgICAgICAgICAgaWYgKGxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBwYXRocy5wdXNoKG5ld1NlbGVjdG9yc1tpXSk7XG4gICAgICAgICAgICAgICAgbGFzdFNlbGVjdG9yID0gbmV3U2VsZWN0b3JzW2ldW2xlbmd0aCAtIDFdO1xuICAgICAgICAgICAgICAgIG5ld1NlbGVjdG9yc1tpXVtsZW5ndGggLSAxXSA9IGxhc3RTZWxlY3Rvci5jcmVhdGVEZXJpdmVkKGxhc3RTZWxlY3Rvci5lbGVtZW50cywgaW5TZWxlY3Rvci5leHRlbmRMaXN0KTtcbiAgICAgICAgICAgICAgICAvL25ld1NlbGVjdG9yc1tpXVtsZW5ndGggLSAxXS5jb3B5VmlzaWJpbGl0eUluZm8oaW5TZWxlY3Rvci52aXNpYmlsaXR5SW5mbygpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBoYWRQYXJlbnRTZWxlY3RvcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkZXJpdmVTZWxlY3Rvcih2aXNpYmlsaXR5SW5mbywgZGVyaXZlRnJvbSkge1xuICAgICAgICB2YXIgbmV3U2VsZWN0b3IgPSBkZXJpdmVGcm9tLmNyZWF0ZURlcml2ZWQoZGVyaXZlRnJvbS5lbGVtZW50cywgZGVyaXZlRnJvbS5leHRlbmRMaXN0LCBkZXJpdmVGcm9tLmV2YWxkQ29uZGl0aW9uKTtcbiAgICAgICAgbmV3U2VsZWN0b3IuY29weVZpc2liaWxpdHlJbmZvKHZpc2liaWxpdHlJbmZvKTtcbiAgICAgICAgcmV0dXJuIG5ld1NlbGVjdG9yO1xuICAgIH1cblxuICAgIC8vIGpvaW5TZWxlY3RvciBjb2RlIGZvbGxvd3NcbiAgICB2YXIgaSwgbmV3UGF0aHMsIGhhZFBhcmVudFNlbGVjdG9yO1xuXG4gICAgbmV3UGF0aHMgPSBbXTtcbiAgICBoYWRQYXJlbnRTZWxlY3RvciA9IHJlcGxhY2VQYXJlbnRTZWxlY3RvcihuZXdQYXRocywgY29udGV4dCwgc2VsZWN0b3IpO1xuXG4gICAgaWYgKCFoYWRQYXJlbnRTZWxlY3Rvcikge1xuICAgICAgICBpZiAoY29udGV4dC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBuZXdQYXRocyA9IFtdO1xuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvbnRleHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAvL3ZhciBjb25jYXRlbmF0ZWQgPSBbXTtcbiAgICAgICAgICAgICAgICAvL2NvbnRleHRbaV0uZm9yRWFjaChmdW5jdGlvbihlbnRyeSkge1xuICAgICAgICAgICAgICAgIC8vICAgIHZhciBuZXdFbnRyeSA9IGVudHJ5LmNyZWF0ZURlcml2ZWQoZW50cnkuZWxlbWVudHMsIGVudHJ5LmV4dGVuZExpc3QsIGVudHJ5LmV2YWxkQ29uZGl0aW9uKTtcbiAgICAgICAgICAgICAgICAvLyAgICBuZXdFbnRyeS5jb3B5VmlzaWJpbGl0eUluZm8oc2VsZWN0b3IudmlzaWJpbGl0eUluZm8oKSk7XG4gICAgICAgICAgICAgICAgLy8gICAgY29uY2F0ZW5hdGVkLnB1c2gobmV3RW50cnkpO1xuICAgICAgICAgICAgICAgIC8vfSwgdGhpcyk7XG4gICAgICAgICAgICAgICAgdmFyIGNvbmNhdGVuYXRlZCA9IGNvbnRleHRbaV0ubWFwKGRlcml2ZVNlbGVjdG9yLmJpbmQodGhpcywgc2VsZWN0b3IudmlzaWJpbGl0eUluZm8oKSkpO1xuXG4gICAgICAgICAgICAgICAgY29uY2F0ZW5hdGVkLnB1c2goc2VsZWN0b3IpO1xuICAgICAgICAgICAgICAgIG5ld1BhdGhzLnB1c2goY29uY2F0ZW5hdGVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG5ld1BhdGhzID0gW1tzZWxlY3Rvcl1dO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IG5ld1BhdGhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHBhdGhzLnB1c2gobmV3UGF0aHNbaV0pO1xuICAgIH1cblxufTtcbm1vZHVsZS5leHBvcnRzID0gUnVsZXNldDtcblxufSx7XCIuLi9jb250ZXh0c1wiOjExLFwiLi4vZnVuY3Rpb25zL2RlZmF1bHRcIjoyMCxcIi4uL2Z1bmN0aW9ucy9mdW5jdGlvbi1yZWdpc3RyeVwiOjIyLFwiLi9kZWJ1Zy1pbmZvXCI6NTQsXCIuL2VsZW1lbnRcIjo1OCxcIi4vbm9kZVwiOjcwLFwiLi9wYXJlblwiOjcyLFwiLi9ydWxlXCI6NzQsXCIuL3NlbGVjdG9yXCI6Nzd9XSw3NzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgTm9kZSA9IHJlcXVpcmUoXCIuL25vZGVcIiksXG4gICAgRWxlbWVudCA9IHJlcXVpcmUoXCIuL2VsZW1lbnRcIik7XG5cbnZhciBTZWxlY3RvciA9IGZ1bmN0aW9uIChlbGVtZW50cywgZXh0ZW5kTGlzdCwgY29uZGl0aW9uLCBpbmRleCwgY3VycmVudEZpbGVJbmZvLCB2aXNpYmlsaXR5SW5mbykge1xuICAgIHRoaXMuZWxlbWVudHMgPSBlbGVtZW50cztcbiAgICB0aGlzLmV4dGVuZExpc3QgPSBleHRlbmRMaXN0O1xuICAgIHRoaXMuY29uZGl0aW9uID0gY29uZGl0aW9uO1xuICAgIHRoaXMuY3VycmVudEZpbGVJbmZvID0gY3VycmVudEZpbGVJbmZvIHx8IHt9O1xuICAgIGlmICghY29uZGl0aW9uKSB7XG4gICAgICAgIHRoaXMuZXZhbGRDb25kaXRpb24gPSB0cnVlO1xuICAgIH1cbiAgICB0aGlzLmNvcHlWaXNpYmlsaXR5SW5mbyh2aXNpYmlsaXR5SW5mbyk7XG59O1xuU2VsZWN0b3IucHJvdG90eXBlID0gbmV3IE5vZGUoKTtcblNlbGVjdG9yLnByb3RvdHlwZS50eXBlID0gXCJTZWxlY3RvclwiO1xuU2VsZWN0b3IucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uICh2aXNpdG9yKSB7XG4gICAgaWYgKHRoaXMuZWxlbWVudHMpIHtcbiAgICAgICAgdGhpcy5lbGVtZW50cyA9IHZpc2l0b3IudmlzaXRBcnJheSh0aGlzLmVsZW1lbnRzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuZXh0ZW5kTGlzdCkge1xuICAgICAgICB0aGlzLmV4dGVuZExpc3QgPSB2aXNpdG9yLnZpc2l0QXJyYXkodGhpcy5leHRlbmRMaXN0KTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY29uZGl0aW9uKSB7XG4gICAgICAgIHRoaXMuY29uZGl0aW9uID0gdmlzaXRvci52aXNpdCh0aGlzLmNvbmRpdGlvbik7XG4gICAgfVxufTtcblNlbGVjdG9yLnByb3RvdHlwZS5jcmVhdGVEZXJpdmVkID0gZnVuY3Rpb24oZWxlbWVudHMsIGV4dGVuZExpc3QsIGV2YWxkQ29uZGl0aW9uKSB7XG4gICAgdmFyIGluZm8gPSB0aGlzLnZpc2liaWxpdHlJbmZvKCk7XG4gICAgZXZhbGRDb25kaXRpb24gPSAoZXZhbGRDb25kaXRpb24gIT0gbnVsbCkgPyBldmFsZENvbmRpdGlvbiA6IHRoaXMuZXZhbGRDb25kaXRpb247XG4gICAgdmFyIG5ld1NlbGVjdG9yID0gbmV3IFNlbGVjdG9yKGVsZW1lbnRzLCBleHRlbmRMaXN0IHx8IHRoaXMuZXh0ZW5kTGlzdCwgbnVsbCwgdGhpcy5pbmRleCwgdGhpcy5jdXJyZW50RmlsZUluZm8sIGluZm8pO1xuICAgIG5ld1NlbGVjdG9yLmV2YWxkQ29uZGl0aW9uID0gZXZhbGRDb25kaXRpb247XG4gICAgbmV3U2VsZWN0b3IubWVkaWFFbXB0eSA9IHRoaXMubWVkaWFFbXB0eTtcbiAgICByZXR1cm4gbmV3U2VsZWN0b3I7XG59O1xuU2VsZWN0b3IucHJvdG90eXBlLmNyZWF0ZUVtcHR5U2VsZWN0b3JzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGVsID0gbmV3IEVsZW1lbnQoJycsICcmJywgdGhpcy5pbmRleCwgdGhpcy5jdXJyZW50RmlsZUluZm8pLFxuICAgICAgICBzZWxzID0gW25ldyBTZWxlY3RvcihbZWxdLCBudWxsLCBudWxsLCB0aGlzLmluZGV4LCB0aGlzLmN1cnJlbnRGaWxlSW5mbyldO1xuICAgIHNlbHNbMF0ubWVkaWFFbXB0eSA9IHRydWU7XG4gICAgcmV0dXJuIHNlbHM7XG59O1xuU2VsZWN0b3IucHJvdG90eXBlLm1hdGNoID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gICAgdmFyIGVsZW1lbnRzID0gdGhpcy5lbGVtZW50cyxcbiAgICAgICAgbGVuID0gZWxlbWVudHMubGVuZ3RoLFxuICAgICAgICBvbGVuLCBpO1xuXG4gICAgb3RoZXIuQ2FjaGVFbGVtZW50cygpO1xuXG4gICAgb2xlbiA9IG90aGVyLl9lbGVtZW50cy5sZW5ndGg7XG4gICAgaWYgKG9sZW4gPT09IDAgfHwgbGVuIDwgb2xlbikge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgb2xlbjsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoZWxlbWVudHNbaV0udmFsdWUgIT09IG90aGVyLl9lbGVtZW50c1tpXSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG9sZW47IC8vIHJldHVybiBudW1iZXIgb2YgbWF0Y2hlZCBlbGVtZW50c1xufTtcblNlbGVjdG9yLnByb3RvdHlwZS5DYWNoZUVsZW1lbnRzID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2VsZW1lbnRzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgZWxlbWVudHMgPSB0aGlzLmVsZW1lbnRzLm1hcCggZnVuY3Rpb24odikge1xuICAgICAgICByZXR1cm4gdi5jb21iaW5hdG9yLnZhbHVlICsgKHYudmFsdWUudmFsdWUgfHwgdi52YWx1ZSk7XG4gICAgfSkuam9pbihcIlwiKS5tYXRjaCgvWywmI1xcKlxcLlxcdy1dKFtcXHctXXwoXFxcXC4pKSovZyk7XG5cbiAgICBpZiAoZWxlbWVudHMpIHtcbiAgICAgICAgaWYgKGVsZW1lbnRzWzBdID09PSBcIiZcIikge1xuICAgICAgICAgICAgZWxlbWVudHMuc2hpZnQoKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnRzID0gW107XG4gICAgfVxuXG4gICAgdGhpcy5fZWxlbWVudHMgPSBlbGVtZW50cztcbn07XG5TZWxlY3Rvci5wcm90b3R5cGUuaXNKdXN0UGFyZW50U2VsZWN0b3IgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gIXRoaXMubWVkaWFFbXB0eSAmJlxuICAgICAgICB0aGlzLmVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICB0aGlzLmVsZW1lbnRzWzBdLnZhbHVlID09PSAnJicgJiZcbiAgICAgICAgKHRoaXMuZWxlbWVudHNbMF0uY29tYmluYXRvci52YWx1ZSA9PT0gJyAnIHx8IHRoaXMuZWxlbWVudHNbMF0uY29tYmluYXRvci52YWx1ZSA9PT0gJycpO1xufTtcblNlbGVjdG9yLnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgZXZhbGRDb25kaXRpb24gPSB0aGlzLmNvbmRpdGlvbiAmJiB0aGlzLmNvbmRpdGlvbi5ldmFsKGNvbnRleHQpLFxuICAgICAgICBlbGVtZW50cyA9IHRoaXMuZWxlbWVudHMsIGV4dGVuZExpc3QgPSB0aGlzLmV4dGVuZExpc3Q7XG5cbiAgICBlbGVtZW50cyA9IGVsZW1lbnRzICYmIGVsZW1lbnRzLm1hcChmdW5jdGlvbiAoZSkgeyByZXR1cm4gZS5ldmFsKGNvbnRleHQpOyB9KTtcbiAgICBleHRlbmRMaXN0ID0gZXh0ZW5kTGlzdCAmJiBleHRlbmRMaXN0Lm1hcChmdW5jdGlvbihleHRlbmQpIHsgcmV0dXJuIGV4dGVuZC5ldmFsKGNvbnRleHQpOyB9KTtcblxuICAgIHJldHVybiB0aGlzLmNyZWF0ZURlcml2ZWQoZWxlbWVudHMsIGV4dGVuZExpc3QsIGV2YWxkQ29uZGl0aW9uKTtcbn07XG5TZWxlY3Rvci5wcm90b3R5cGUuZ2VuQ1NTID0gZnVuY3Rpb24gKGNvbnRleHQsIG91dHB1dCkge1xuICAgIHZhciBpLCBlbGVtZW50O1xuICAgIGlmICgoIWNvbnRleHQgfHwgIWNvbnRleHQuZmlyc3RTZWxlY3RvcikgJiYgdGhpcy5lbGVtZW50c1swXS5jb21iaW5hdG9yLnZhbHVlID09PSBcIlwiKSB7XG4gICAgICAgIG91dHB1dC5hZGQoJyAnLCB0aGlzLmN1cnJlbnRGaWxlSW5mbywgdGhpcy5pbmRleCk7XG4gICAgfVxuICAgIGlmICghdGhpcy5fY3NzKSB7XG4gICAgICAgIC8vVE9ETyBjYWNoaW5nPyBzcGVlZCBjb21wYXJpc29uP1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5lbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgZWxlbWVudCA9IHRoaXMuZWxlbWVudHNbaV07XG4gICAgICAgICAgICBlbGVtZW50LmdlbkNTUyhjb250ZXh0LCBvdXRwdXQpO1xuICAgICAgICB9XG4gICAgfVxufTtcblNlbGVjdG9yLnByb3RvdHlwZS5nZXRJc091dHB1dCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmV2YWxkQ29uZGl0aW9uO1xufTtcbm1vZHVsZS5leHBvcnRzID0gU2VsZWN0b3I7XG5cbn0se1wiLi9lbGVtZW50XCI6NTgsXCIuL25vZGVcIjo3MH1dLDc4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBOb2RlID0gcmVxdWlyZShcIi4vbm9kZVwiKTtcblxudmFyIFVuaWNvZGVEZXNjcmlwdG9yID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xufTtcblVuaWNvZGVEZXNjcmlwdG9yLnByb3RvdHlwZSA9IG5ldyBOb2RlKCk7XG5Vbmljb2RlRGVzY3JpcHRvci5wcm90b3R5cGUudHlwZSA9IFwiVW5pY29kZURlc2NyaXB0b3JcIjtcblxubW9kdWxlLmV4cG9ydHMgPSBVbmljb2RlRGVzY3JpcHRvcjtcblxufSx7XCIuL25vZGVcIjo3MH1dLDc5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBOb2RlID0gcmVxdWlyZShcIi4vbm9kZVwiKSxcbiAgICB1bml0Q29udmVyc2lvbnMgPSByZXF1aXJlKFwiLi4vZGF0YS91bml0LWNvbnZlcnNpb25zXCIpO1xuXG52YXIgVW5pdCA9IGZ1bmN0aW9uIChudW1lcmF0b3IsIGRlbm9taW5hdG9yLCBiYWNrdXBVbml0KSB7XG4gICAgdGhpcy5udW1lcmF0b3IgPSBudW1lcmF0b3IgPyBudW1lcmF0b3Iuc2xpY2UoMCkuc29ydCgpIDogW107XG4gICAgdGhpcy5kZW5vbWluYXRvciA9IGRlbm9taW5hdG9yID8gZGVub21pbmF0b3Iuc2xpY2UoMCkuc29ydCgpIDogW107XG4gICAgaWYgKGJhY2t1cFVuaXQpIHtcbiAgICAgICAgdGhpcy5iYWNrdXBVbml0ID0gYmFja3VwVW5pdDtcbiAgICB9IGVsc2UgaWYgKG51bWVyYXRvciAmJiBudW1lcmF0b3IubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuYmFja3VwVW5pdCA9IG51bWVyYXRvclswXTtcbiAgICB9XG59O1xuXG5Vbml0LnByb3RvdHlwZSA9IG5ldyBOb2RlKCk7XG5Vbml0LnByb3RvdHlwZS50eXBlID0gXCJVbml0XCI7XG5Vbml0LnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbmV3IFVuaXQodGhpcy5udW1lcmF0b3Iuc2xpY2UoMCksIHRoaXMuZGVub21pbmF0b3Iuc2xpY2UoMCksIHRoaXMuYmFja3VwVW5pdCk7XG59O1xuVW5pdC5wcm90b3R5cGUuZ2VuQ1NTID0gZnVuY3Rpb24gKGNvbnRleHQsIG91dHB1dCkge1xuICAgIC8vIERpbWVuc2lvbiBjaGVja3MgdGhlIHVuaXQgaXMgc2luZ3VsYXIgYW5kIHRocm93cyBhbiBlcnJvciBpZiBpbiBzdHJpY3QgbWF0aCBtb2RlLlxuICAgIHZhciBzdHJpY3RVbml0cyA9IGNvbnRleHQgJiYgY29udGV4dC5zdHJpY3RVbml0cztcbiAgICBpZiAodGhpcy5udW1lcmF0b3IubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIG91dHB1dC5hZGQodGhpcy5udW1lcmF0b3JbMF0pOyAvLyB0aGUgaWRlYWwgc2l0dWF0aW9uXG4gICAgfSBlbHNlIGlmICghc3RyaWN0VW5pdHMgJiYgdGhpcy5iYWNrdXBVbml0KSB7XG4gICAgICAgIG91dHB1dC5hZGQodGhpcy5iYWNrdXBVbml0KTtcbiAgICB9IGVsc2UgaWYgKCFzdHJpY3RVbml0cyAmJiB0aGlzLmRlbm9taW5hdG9yLmxlbmd0aCkge1xuICAgICAgICBvdXRwdXQuYWRkKHRoaXMuZGVub21pbmF0b3JbMF0pO1xuICAgIH1cbn07XG5Vbml0LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaSwgcmV0dXJuU3RyID0gdGhpcy5udW1lcmF0b3Iuam9pbihcIipcIik7XG4gICAgZm9yIChpID0gMDsgaSA8IHRoaXMuZGVub21pbmF0b3IubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmV0dXJuU3RyICs9IFwiL1wiICsgdGhpcy5kZW5vbWluYXRvcltpXTtcbiAgICB9XG4gICAgcmV0dXJuIHJldHVyblN0cjtcbn07XG5Vbml0LnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuaXMob3RoZXIudG9TdHJpbmcoKSkgPyAwIDogdW5kZWZpbmVkO1xufTtcblVuaXQucHJvdG90eXBlLmlzID0gZnVuY3Rpb24gKHVuaXRTdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy50b1N0cmluZygpLnRvVXBwZXJDYXNlKCkgPT09IHVuaXRTdHJpbmcudG9VcHBlckNhc2UoKTtcbn07XG5Vbml0LnByb3RvdHlwZS5pc0xlbmd0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gQm9vbGVhbih0aGlzLnRvQ1NTKCkubWF0Y2goL3B4fGVtfCV8aW58Y218bW18cGN8cHR8ZXgvKSk7XG59O1xuVW5pdC5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5udW1lcmF0b3IubGVuZ3RoID09PSAwICYmIHRoaXMuZGVub21pbmF0b3IubGVuZ3RoID09PSAwO1xufTtcblVuaXQucHJvdG90eXBlLmlzU2luZ3VsYXIgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5udW1lcmF0b3IubGVuZ3RoIDw9IDEgJiYgdGhpcy5kZW5vbWluYXRvci5sZW5ndGggPT09IDA7XG59O1xuVW5pdC5wcm90b3R5cGUubWFwID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICB2YXIgaTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLm51bWVyYXRvci5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzLm51bWVyYXRvcltpXSA9IGNhbGxiYWNrKHRoaXMubnVtZXJhdG9yW2ldLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IHRoaXMuZGVub21pbmF0b3IubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy5kZW5vbWluYXRvcltpXSA9IGNhbGxiYWNrKHRoaXMuZGVub21pbmF0b3JbaV0sIHRydWUpO1xuICAgIH1cbn07XG5Vbml0LnByb3RvdHlwZS51c2VkVW5pdHMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgZ3JvdXAsIHJlc3VsdCA9IHt9LCBtYXBVbml0LCBncm91cE5hbWU7XG5cbiAgICBtYXBVbml0ID0gZnVuY3Rpb24gKGF0b21pY1VuaXQpIHtcbiAgICAgICAgLypqc2hpbnQgbG9vcGZ1bmM6dHJ1ZSAqL1xuICAgICAgICBpZiAoZ3JvdXAuaGFzT3duUHJvcGVydHkoYXRvbWljVW5pdCkgJiYgIXJlc3VsdFtncm91cE5hbWVdKSB7XG4gICAgICAgICAgICByZXN1bHRbZ3JvdXBOYW1lXSA9IGF0b21pY1VuaXQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXRvbWljVW5pdDtcbiAgICB9O1xuXG4gICAgZm9yIChncm91cE5hbWUgaW4gdW5pdENvbnZlcnNpb25zKSB7XG4gICAgICAgIGlmICh1bml0Q29udmVyc2lvbnMuaGFzT3duUHJvcGVydHkoZ3JvdXBOYW1lKSkge1xuICAgICAgICAgICAgZ3JvdXAgPSB1bml0Q29udmVyc2lvbnNbZ3JvdXBOYW1lXTtcblxuICAgICAgICAgICAgdGhpcy5tYXAobWFwVW5pdCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufTtcblVuaXQucHJvdG90eXBlLmNhbmNlbCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY291bnRlciA9IHt9LCBhdG9taWNVbml0LCBpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IHRoaXMubnVtZXJhdG9yLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGF0b21pY1VuaXQgPSB0aGlzLm51bWVyYXRvcltpXTtcbiAgICAgICAgY291bnRlclthdG9taWNVbml0XSA9IChjb3VudGVyW2F0b21pY1VuaXRdIHx8IDApICsgMTtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5kZW5vbWluYXRvci5sZW5ndGg7IGkrKykge1xuICAgICAgICBhdG9taWNVbml0ID0gdGhpcy5kZW5vbWluYXRvcltpXTtcbiAgICAgICAgY291bnRlclthdG9taWNVbml0XSA9IChjb3VudGVyW2F0b21pY1VuaXRdIHx8IDApIC0gMTtcbiAgICB9XG5cbiAgICB0aGlzLm51bWVyYXRvciA9IFtdO1xuICAgIHRoaXMuZGVub21pbmF0b3IgPSBbXTtcblxuICAgIGZvciAoYXRvbWljVW5pdCBpbiBjb3VudGVyKSB7XG4gICAgICAgIGlmIChjb3VudGVyLmhhc093blByb3BlcnR5KGF0b21pY1VuaXQpKSB7XG4gICAgICAgICAgICB2YXIgY291bnQgPSBjb3VudGVyW2F0b21pY1VuaXRdO1xuXG4gICAgICAgICAgICBpZiAoY291bnQgPiAwKSB7XG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5udW1lcmF0b3IucHVzaChhdG9taWNVbml0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNvdW50IDwgMCkge1xuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCAtY291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRlbm9taW5hdG9yLnB1c2goYXRvbWljVW5pdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5udW1lcmF0b3Iuc29ydCgpO1xuICAgIHRoaXMuZGVub21pbmF0b3Iuc29ydCgpO1xufTtcbm1vZHVsZS5leHBvcnRzID0gVW5pdDtcblxufSx7XCIuLi9kYXRhL3VuaXQtY29udmVyc2lvbnNcIjoxNCxcIi4vbm9kZVwiOjcwfV0sODA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIE5vZGUgPSByZXF1aXJlKFwiLi9ub2RlXCIpO1xuXG52YXIgVVJMID0gZnVuY3Rpb24gKHZhbCwgaW5kZXgsIGN1cnJlbnRGaWxlSW5mbywgaXNFdmFsZCkge1xuICAgIHRoaXMudmFsdWUgPSB2YWw7XG4gICAgdGhpcy5jdXJyZW50RmlsZUluZm8gPSBjdXJyZW50RmlsZUluZm87XG4gICAgdGhpcy5pbmRleCA9IGluZGV4O1xuICAgIHRoaXMuaXNFdmFsZCA9IGlzRXZhbGQ7XG59O1xuVVJMLnByb3RvdHlwZSA9IG5ldyBOb2RlKCk7XG5VUkwucHJvdG90eXBlLnR5cGUgPSBcIlVybFwiO1xuVVJMLnByb3RvdHlwZS5hY2NlcHQgPSBmdW5jdGlvbiAodmlzaXRvcikge1xuICAgIHRoaXMudmFsdWUgPSB2aXNpdG9yLnZpc2l0KHRoaXMudmFsdWUpO1xufTtcblVSTC5wcm90b3R5cGUuZ2VuQ1NTID0gZnVuY3Rpb24gKGNvbnRleHQsIG91dHB1dCkge1xuICAgIG91dHB1dC5hZGQoXCJ1cmwoXCIpO1xuICAgIHRoaXMudmFsdWUuZ2VuQ1NTKGNvbnRleHQsIG91dHB1dCk7XG4gICAgb3V0cHV0LmFkZChcIilcIik7XG59O1xuVVJMLnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgdmFsID0gdGhpcy52YWx1ZS5ldmFsKGNvbnRleHQpLFxuICAgICAgICByb290cGF0aDtcblxuICAgIGlmICghdGhpcy5pc0V2YWxkKSB7XG4gICAgICAgIC8vIEFkZCB0aGUgYmFzZSBwYXRoIGlmIHRoZSBVUkwgaXMgcmVsYXRpdmVcbiAgICAgICAgcm9vdHBhdGggPSB0aGlzLmN1cnJlbnRGaWxlSW5mbyAmJiB0aGlzLmN1cnJlbnRGaWxlSW5mby5yb290cGF0aDtcbiAgICAgICAgaWYgKHJvb3RwYXRoICYmXG4gICAgICAgICAgICB0eXBlb2YgdmFsLnZhbHVlID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgICBjb250ZXh0LmlzUGF0aFJlbGF0aXZlKHZhbC52YWx1ZSkpIHtcblxuICAgICAgICAgICAgaWYgKCF2YWwucXVvdGUpIHtcbiAgICAgICAgICAgICAgICByb290cGF0aCA9IHJvb3RwYXRoLnJlcGxhY2UoL1tcXChcXCknXCJcXHNdL2csIGZ1bmN0aW9uKG1hdGNoKSB7IHJldHVybiBcIlxcXFxcIiArIG1hdGNoOyB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhbC52YWx1ZSA9IHJvb3RwYXRoICsgdmFsLnZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFsLnZhbHVlID0gY29udGV4dC5ub3JtYWxpemVQYXRoKHZhbC52YWx1ZSk7XG5cbiAgICAgICAgLy8gQWRkIHVybCBhcmdzIGlmIGVuYWJsZWRcbiAgICAgICAgaWYgKGNvbnRleHQudXJsQXJncykge1xuICAgICAgICAgICAgaWYgKCF2YWwudmFsdWUubWF0Y2goL15cXHMqZGF0YTovKSkge1xuICAgICAgICAgICAgICAgIHZhciBkZWxpbWl0ZXIgPSB2YWwudmFsdWUuaW5kZXhPZignPycpID09PSAtMSA/ICc/JyA6ICcmJztcbiAgICAgICAgICAgICAgICB2YXIgdXJsQXJncyA9IGRlbGltaXRlciArIGNvbnRleHQudXJsQXJncztcbiAgICAgICAgICAgICAgICBpZiAodmFsLnZhbHVlLmluZGV4T2YoJyMnKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsLnZhbHVlID0gdmFsLnZhbHVlLnJlcGxhY2UoJyMnLCB1cmxBcmdzICsgJyMnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YWwudmFsdWUgKz0gdXJsQXJncztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFVSTCh2YWwsIHRoaXMuaW5kZXgsIHRoaXMuY3VycmVudEZpbGVJbmZvLCB0cnVlKTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IFVSTDtcblxufSx7XCIuL25vZGVcIjo3MH1dLDgxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbnZhciBOb2RlID0gcmVxdWlyZShcIi4vbm9kZVwiKTtcblxudmFyIFZhbHVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVmFsdWUgcmVxdWlyZXMgYW4gYXJyYXkgYXJndW1lbnRcIik7XG4gICAgfVxufTtcblZhbHVlLnByb3RvdHlwZSA9IG5ldyBOb2RlKCk7XG5WYWx1ZS5wcm90b3R5cGUudHlwZSA9IFwiVmFsdWVcIjtcblZhbHVlLnByb3RvdHlwZS5hY2NlcHQgPSBmdW5jdGlvbiAodmlzaXRvcikge1xuICAgIGlmICh0aGlzLnZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2aXNpdG9yLnZpc2l0QXJyYXkodGhpcy52YWx1ZSk7XG4gICAgfVxufTtcblZhbHVlLnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICBpZiAodGhpcy52YWx1ZS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVbMF0uZXZhbChjb250ZXh0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IFZhbHVlKHRoaXMudmFsdWUubWFwKGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICByZXR1cm4gdi5ldmFsKGNvbnRleHQpO1xuICAgICAgICB9KSk7XG4gICAgfVxufTtcblZhbHVlLnByb3RvdHlwZS5nZW5DU1MgPSBmdW5jdGlvbiAoY29udGV4dCwgb3V0cHV0KSB7XG4gICAgdmFyIGk7XG4gICAgZm9yIChpID0gMDsgaSA8IHRoaXMudmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy52YWx1ZVtpXS5nZW5DU1MoY29udGV4dCwgb3V0cHV0KTtcbiAgICAgICAgaWYgKGkgKyAxIDwgdGhpcy52YWx1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIG91dHB1dC5hZGQoKGNvbnRleHQgJiYgY29udGV4dC5jb21wcmVzcykgPyAnLCcgOiAnLCAnKTtcbiAgICAgICAgfVxuICAgIH1cbn07XG5tb2R1bGUuZXhwb3J0cyA9IFZhbHVlO1xuXG59LHtcIi4vbm9kZVwiOjcwfV0sODI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIE5vZGUgPSByZXF1aXJlKFwiLi9ub2RlXCIpO1xuXG52YXIgVmFyaWFibGUgPSBmdW5jdGlvbiAobmFtZSwgaW5kZXgsIGN1cnJlbnRGaWxlSW5mbykge1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5pbmRleCA9IGluZGV4O1xuICAgIHRoaXMuY3VycmVudEZpbGVJbmZvID0gY3VycmVudEZpbGVJbmZvIHx8IHt9O1xufTtcblZhcmlhYmxlLnByb3RvdHlwZSA9IG5ldyBOb2RlKCk7XG5WYXJpYWJsZS5wcm90b3R5cGUudHlwZSA9IFwiVmFyaWFibGVcIjtcblZhcmlhYmxlLnByb3RvdHlwZS5ldmFsID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB2YXIgdmFyaWFibGUsIG5hbWUgPSB0aGlzLm5hbWU7XG5cbiAgICBpZiAobmFtZS5pbmRleE9mKCdAQCcpID09PSAwKSB7XG4gICAgICAgIG5hbWUgPSAnQCcgKyBuZXcgVmFyaWFibGUobmFtZS5zbGljZSgxKSwgdGhpcy5pbmRleCwgdGhpcy5jdXJyZW50RmlsZUluZm8pLmV2YWwoY29udGV4dCkudmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZXZhbHVhdGluZykge1xuICAgICAgICB0aHJvdyB7IHR5cGU6ICdOYW1lJyxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBcIlJlY3Vyc2l2ZSB2YXJpYWJsZSBkZWZpbml0aW9uIGZvciBcIiArIG5hbWUsXG4gICAgICAgICAgICAgICAgZmlsZW5hbWU6IHRoaXMuY3VycmVudEZpbGVJbmZvLmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgIGluZGV4OiB0aGlzLmluZGV4IH07XG4gICAgfVxuXG4gICAgdGhpcy5ldmFsdWF0aW5nID0gdHJ1ZTtcblxuICAgIHZhcmlhYmxlID0gdGhpcy5maW5kKGNvbnRleHQuZnJhbWVzLCBmdW5jdGlvbiAoZnJhbWUpIHtcbiAgICAgICAgdmFyIHYgPSBmcmFtZS52YXJpYWJsZShuYW1lKTtcbiAgICAgICAgaWYgKHYpIHtcbiAgICAgICAgICAgIGlmICh2LmltcG9ydGFudCkge1xuICAgICAgICAgICAgICAgIHZhciBpbXBvcnRhbnRTY29wZSA9IGNvbnRleHQuaW1wb3J0YW50U2NvcGVbY29udGV4dC5pbXBvcnRhbnRTY29wZS5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgICAgICBpbXBvcnRhbnRTY29wZS5pbXBvcnRhbnQgPSB2LmltcG9ydGFudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2LnZhbHVlLmV2YWwoY29udGV4dCk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAodmFyaWFibGUpIHtcbiAgICAgICAgdGhpcy5ldmFsdWF0aW5nID0gZmFsc2U7XG4gICAgICAgIHJldHVybiB2YXJpYWJsZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyB7IHR5cGU6ICdOYW1lJyxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBcInZhcmlhYmxlIFwiICsgbmFtZSArIFwiIGlzIHVuZGVmaW5lZFwiLFxuICAgICAgICAgICAgICAgIGZpbGVuYW1lOiB0aGlzLmN1cnJlbnRGaWxlSW5mby5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICBpbmRleDogdGhpcy5pbmRleCB9O1xuICAgIH1cbn07XG5WYXJpYWJsZS5wcm90b3R5cGUuZmluZCA9IGZ1bmN0aW9uIChvYmosIGZ1bikge1xuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHIgPSBmdW4uY2FsbChvYmosIG9ialtpXSk7XG4gICAgICAgIGlmIChyKSB7IHJldHVybiByOyB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcbm1vZHVsZS5leHBvcnRzID0gVmFyaWFibGU7XG5cbn0se1wiLi9ub2RlXCI6NzB9XSw4MzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBnZXRMb2NhdGlvbjogZnVuY3Rpb24oaW5kZXgsIGlucHV0U3RyZWFtKSB7XG4gICAgICAgIHZhciBuID0gaW5kZXggKyAxLFxuICAgICAgICAgICAgbGluZSA9IG51bGwsXG4gICAgICAgICAgICBjb2x1bW4gPSAtMTtcblxuICAgICAgICB3aGlsZSAoLS1uID49IDAgJiYgaW5wdXRTdHJlYW0uY2hhckF0KG4pICE9PSAnXFxuJykge1xuICAgICAgICAgICAgY29sdW1uKys7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGluZGV4ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgbGluZSA9IChpbnB1dFN0cmVhbS5zbGljZSgwLCBpbmRleCkubWF0Y2goL1xcbi9nKSB8fCBcIlwiKS5sZW5ndGg7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbGluZTogbGluZSxcbiAgICAgICAgICAgIGNvbHVtbjogY29sdW1uXG4gICAgICAgIH07XG4gICAgfVxufTtcblxufSx7fV0sODQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIHRyZWUgPSByZXF1aXJlKFwiLi4vdHJlZVwiKSxcbiAgICBWaXNpdG9yID0gcmVxdWlyZShcIi4vdmlzaXRvclwiKSxcbiAgICBsb2dnZXIgPSByZXF1aXJlKFwiLi4vbG9nZ2VyXCIpO1xuXG4vKmpzaGludCBsb29wZnVuYzp0cnVlICovXG5cbnZhciBFeHRlbmRGaW5kZXJWaXNpdG9yID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fdmlzaXRvciA9IG5ldyBWaXNpdG9yKHRoaXMpO1xuICAgIHRoaXMuY29udGV4dHMgPSBbXTtcbiAgICB0aGlzLmFsbEV4dGVuZHNTdGFjayA9IFtbXV07XG59O1xuXG5FeHRlbmRGaW5kZXJWaXNpdG9yLnByb3RvdHlwZSA9IHtcbiAgICBydW46IGZ1bmN0aW9uIChyb290KSB7XG4gICAgICAgIHJvb3QgPSB0aGlzLl92aXNpdG9yLnZpc2l0KHJvb3QpO1xuICAgICAgICByb290LmFsbEV4dGVuZHMgPSB0aGlzLmFsbEV4dGVuZHNTdGFja1swXTtcbiAgICAgICAgcmV0dXJuIHJvb3Q7XG4gICAgfSxcbiAgICB2aXNpdFJ1bGU6IGZ1bmN0aW9uIChydWxlTm9kZSwgdmlzaXRBcmdzKSB7XG4gICAgICAgIHZpc2l0QXJncy52aXNpdERlZXBlciA9IGZhbHNlO1xuICAgIH0sXG4gICAgdmlzaXRNaXhpbkRlZmluaXRpb246IGZ1bmN0aW9uIChtaXhpbkRlZmluaXRpb25Ob2RlLCB2aXNpdEFyZ3MpIHtcbiAgICAgICAgdmlzaXRBcmdzLnZpc2l0RGVlcGVyID0gZmFsc2U7XG4gICAgfSxcbiAgICB2aXNpdFJ1bGVzZXQ6IGZ1bmN0aW9uIChydWxlc2V0Tm9kZSwgdmlzaXRBcmdzKSB7XG4gICAgICAgIGlmIChydWxlc2V0Tm9kZS5yb290KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaSwgaiwgZXh0ZW5kLCBhbGxTZWxlY3RvcnNFeHRlbmRMaXN0ID0gW10sIGV4dGVuZExpc3Q7XG5cbiAgICAgICAgLy8gZ2V0ICY6ZXh0ZW5kKC5hKTsgcnVsZXMgd2hpY2ggYXBwbHkgdG8gYWxsIHNlbGVjdG9ycyBpbiB0aGlzIHJ1bGVzZXRcbiAgICAgICAgdmFyIHJ1bGVzID0gcnVsZXNldE5vZGUucnVsZXMsIHJ1bGVDbnQgPSBydWxlcyA/IHJ1bGVzLmxlbmd0aCA6IDA7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBydWxlQ250OyBpKyspIHtcbiAgICAgICAgICAgIGlmIChydWxlc2V0Tm9kZS5ydWxlc1tpXSBpbnN0YW5jZW9mIHRyZWUuRXh0ZW5kKSB7XG4gICAgICAgICAgICAgICAgYWxsU2VsZWN0b3JzRXh0ZW5kTGlzdC5wdXNoKHJ1bGVzW2ldKTtcbiAgICAgICAgICAgICAgICBydWxlc2V0Tm9kZS5leHRlbmRPbkV2ZXJ5UGF0aCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBub3cgZmluZCBldmVyeSBzZWxlY3RvciBhbmQgYXBwbHkgdGhlIGV4dGVuZHMgdGhhdCBhcHBseSB0byBhbGwgZXh0ZW5kc1xuICAgICAgICAvLyBhbmQgdGhlIG9uZXMgd2hpY2ggYXBwbHkgdG8gYW4gaW5kaXZpZHVhbCBleHRlbmRcbiAgICAgICAgdmFyIHBhdGhzID0gcnVsZXNldE5vZGUucGF0aHM7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXRocy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIHNlbGVjdG9yUGF0aCA9IHBhdGhzW2ldLFxuICAgICAgICAgICAgICAgIHNlbGVjdG9yID0gc2VsZWN0b3JQYXRoW3NlbGVjdG9yUGF0aC5sZW5ndGggLSAxXSxcbiAgICAgICAgICAgICAgICBzZWxFeHRlbmRMaXN0ID0gc2VsZWN0b3IuZXh0ZW5kTGlzdDtcblxuICAgICAgICAgICAgZXh0ZW5kTGlzdCA9IHNlbEV4dGVuZExpc3QgPyBzZWxFeHRlbmRMaXN0LnNsaWNlKDApLmNvbmNhdChhbGxTZWxlY3RvcnNFeHRlbmRMaXN0KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBhbGxTZWxlY3RvcnNFeHRlbmRMaXN0O1xuXG4gICAgICAgICAgICBpZiAoZXh0ZW5kTGlzdCkge1xuICAgICAgICAgICAgICAgIGV4dGVuZExpc3QgPSBleHRlbmRMaXN0Lm1hcChmdW5jdGlvbihhbGxTZWxlY3RvcnNFeHRlbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFsbFNlbGVjdG9yc0V4dGVuZC5jbG9uZSgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgZXh0ZW5kTGlzdC5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgIHRoaXMuZm91bmRFeHRlbmRzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBleHRlbmQgPSBleHRlbmRMaXN0W2pdO1xuICAgICAgICAgICAgICAgIGV4dGVuZC5maW5kU2VsZlNlbGVjdG9ycyhzZWxlY3RvclBhdGgpO1xuICAgICAgICAgICAgICAgIGV4dGVuZC5ydWxlc2V0ID0gcnVsZXNldE5vZGU7XG4gICAgICAgICAgICAgICAgaWYgKGogPT09IDApIHsgZXh0ZW5kLmZpcnN0RXh0ZW5kT25UaGlzU2VsZWN0b3JQYXRoID0gdHJ1ZTsgfVxuICAgICAgICAgICAgICAgIHRoaXMuYWxsRXh0ZW5kc1N0YWNrW3RoaXMuYWxsRXh0ZW5kc1N0YWNrLmxlbmd0aCAtIDFdLnB1c2goZXh0ZW5kKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY29udGV4dHMucHVzaChydWxlc2V0Tm9kZS5zZWxlY3RvcnMpO1xuICAgIH0sXG4gICAgdmlzaXRSdWxlc2V0T3V0OiBmdW5jdGlvbiAocnVsZXNldE5vZGUpIHtcbiAgICAgICAgaWYgKCFydWxlc2V0Tm9kZS5yb290KSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHRzLmxlbmd0aCA9IHRoaXMuY29udGV4dHMubGVuZ3RoIC0gMTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgdmlzaXRNZWRpYTogZnVuY3Rpb24gKG1lZGlhTm9kZSwgdmlzaXRBcmdzKSB7XG4gICAgICAgIG1lZGlhTm9kZS5hbGxFeHRlbmRzID0gW107XG4gICAgICAgIHRoaXMuYWxsRXh0ZW5kc1N0YWNrLnB1c2gobWVkaWFOb2RlLmFsbEV4dGVuZHMpO1xuICAgIH0sXG4gICAgdmlzaXRNZWRpYU91dDogZnVuY3Rpb24gKG1lZGlhTm9kZSkge1xuICAgICAgICB0aGlzLmFsbEV4dGVuZHNTdGFjay5sZW5ndGggPSB0aGlzLmFsbEV4dGVuZHNTdGFjay5sZW5ndGggLSAxO1xuICAgIH0sXG4gICAgdmlzaXREaXJlY3RpdmU6IGZ1bmN0aW9uIChkaXJlY3RpdmVOb2RlLCB2aXNpdEFyZ3MpIHtcbiAgICAgICAgZGlyZWN0aXZlTm9kZS5hbGxFeHRlbmRzID0gW107XG4gICAgICAgIHRoaXMuYWxsRXh0ZW5kc1N0YWNrLnB1c2goZGlyZWN0aXZlTm9kZS5hbGxFeHRlbmRzKTtcbiAgICB9LFxuICAgIHZpc2l0RGlyZWN0aXZlT3V0OiBmdW5jdGlvbiAoZGlyZWN0aXZlTm9kZSkge1xuICAgICAgICB0aGlzLmFsbEV4dGVuZHNTdGFjay5sZW5ndGggPSB0aGlzLmFsbEV4dGVuZHNTdGFjay5sZW5ndGggLSAxO1xuICAgIH1cbn07XG5cbnZhciBQcm9jZXNzRXh0ZW5kc1Zpc2l0b3IgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl92aXNpdG9yID0gbmV3IFZpc2l0b3IodGhpcyk7XG59O1xuXG5Qcm9jZXNzRXh0ZW5kc1Zpc2l0b3IucHJvdG90eXBlID0ge1xuICAgIHJ1bjogZnVuY3Rpb24ocm9vdCkge1xuICAgICAgICB2YXIgZXh0ZW5kRmluZGVyID0gbmV3IEV4dGVuZEZpbmRlclZpc2l0b3IoKTtcbiAgICAgICAgdGhpcy5leHRlbmRJbmRpY2VzID0ge307XG4gICAgICAgIGV4dGVuZEZpbmRlci5ydW4ocm9vdCk7XG4gICAgICAgIGlmICghZXh0ZW5kRmluZGVyLmZvdW5kRXh0ZW5kcykgeyByZXR1cm4gcm9vdDsgfVxuICAgICAgICByb290LmFsbEV4dGVuZHMgPSByb290LmFsbEV4dGVuZHMuY29uY2F0KHRoaXMuZG9FeHRlbmRDaGFpbmluZyhyb290LmFsbEV4dGVuZHMsIHJvb3QuYWxsRXh0ZW5kcykpO1xuICAgICAgICB0aGlzLmFsbEV4dGVuZHNTdGFjayA9IFtyb290LmFsbEV4dGVuZHNdO1xuICAgICAgICB2YXIgbmV3Um9vdCA9IHRoaXMuX3Zpc2l0b3IudmlzaXQocm9vdCk7XG4gICAgICAgIHRoaXMuY2hlY2tFeHRlbmRzRm9yTm9uTWF0Y2hlZChyb290LmFsbEV4dGVuZHMpO1xuICAgICAgICByZXR1cm4gbmV3Um9vdDtcbiAgICB9LFxuICAgIGNoZWNrRXh0ZW5kc0Zvck5vbk1hdGNoZWQ6IGZ1bmN0aW9uKGV4dGVuZExpc3QpIHtcbiAgICAgICAgdmFyIGluZGljZXMgPSB0aGlzLmV4dGVuZEluZGljZXM7XG4gICAgICAgIGV4dGVuZExpc3QuZmlsdGVyKGZ1bmN0aW9uKGV4dGVuZCkge1xuICAgICAgICAgICAgcmV0dXJuICFleHRlbmQuaGFzRm91bmRNYXRjaGVzICYmIGV4dGVuZC5wYXJlbnRfaWRzLmxlbmd0aCA9PSAxO1xuICAgICAgICB9KS5mb3JFYWNoKGZ1bmN0aW9uKGV4dGVuZCkge1xuICAgICAgICAgICAgICAgIHZhciBzZWxlY3RvciA9IFwiX3Vua25vd25fXCI7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3IgPSBleHRlbmQuc2VsZWN0b3IudG9DU1Moe30pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaChfKSB7fVxuXG4gICAgICAgICAgICAgICAgaWYgKCFpbmRpY2VzW2V4dGVuZC5pbmRleCArICcgJyArIHNlbGVjdG9yXSkge1xuICAgICAgICAgICAgICAgICAgICBpbmRpY2VzW2V4dGVuZC5pbmRleCArICcgJyArIHNlbGVjdG9yXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKFwiZXh0ZW5kICdcIiArIHNlbGVjdG9yICsgXCInIGhhcyBubyBtYXRjaGVzXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgIH0sXG4gICAgZG9FeHRlbmRDaGFpbmluZzogZnVuY3Rpb24gKGV4dGVuZHNMaXN0LCBleHRlbmRzTGlzdFRhcmdldCwgaXRlcmF0aW9uQ291bnQpIHtcbiAgICAgICAgLy9cbiAgICAgICAgLy8gY2hhaW5pbmcgaXMgZGlmZmVyZW50IGZyb20gbm9ybWFsIGV4dGVuc2lvbi4uIGlmIHdlIGV4dGVuZCBhbiBleHRlbmQgdGhlbiB3ZSBhcmUgbm90IGp1c3QgY29weWluZywgYWx0ZXJpbmdcbiAgICAgICAgLy8gYW5kIHBhc3RpbmcgdGhlIHNlbGVjdG9yIHdlIHdvdWxkIGRvIG5vcm1hbGx5LCBidXQgd2UgYXJlIGFsc28gYWRkaW5nIGFuIGV4dGVuZCB3aXRoIHRoZSBzYW1lIHRhcmdldCBzZWxlY3RvclxuICAgICAgICAvLyB0aGlzIG1lYW5zIHRoaXMgbmV3IGV4dGVuZCBjYW4gdGhlbiBnbyBhbmQgYWx0ZXIgb3RoZXIgZXh0ZW5kc1xuICAgICAgICAvL1xuICAgICAgICAvLyB0aGlzIG1ldGhvZCBkZWFscyB3aXRoIGFsbCB0aGUgY2hhaW5pbmcgd29yayAtIHdpdGhvdXQgaXQsIGV4dGVuZCBpcyBmbGF0IGFuZCBkb2Vzbid0IHdvcmsgb24gb3RoZXIgZXh0ZW5kIHNlbGVjdG9yc1xuICAgICAgICAvLyB0aGlzIGlzIGFsc28gdGhlIG1vc3QgZXhwZW5zaXZlLi4gYW5kIGEgbWF0Y2ggb24gb25lIHNlbGVjdG9yIGNhbiBjYXVzZSBhbiBleHRlbnNpb24gb2YgYSBzZWxlY3RvciB3ZSBoYWQgYWxyZWFkeVxuICAgICAgICAvLyBwcm9jZXNzZWQgaWYgd2UgbG9vayBhdCBlYWNoIHNlbGVjdG9yIGF0IGEgdGltZSwgYXMgaXMgZG9uZSBpbiB2aXNpdFJ1bGVzZXRcblxuICAgICAgICB2YXIgZXh0ZW5kSW5kZXgsIHRhcmdldEV4dGVuZEluZGV4LCBtYXRjaGVzLCBleHRlbmRzVG9BZGQgPSBbXSwgbmV3U2VsZWN0b3IsIGV4dGVuZFZpc2l0b3IgPSB0aGlzLCBzZWxlY3RvclBhdGgsXG4gICAgICAgICAgICBleHRlbmQsIHRhcmdldEV4dGVuZCwgbmV3RXh0ZW5kO1xuXG4gICAgICAgIGl0ZXJhdGlvbkNvdW50ID0gaXRlcmF0aW9uQ291bnQgfHwgMDtcblxuICAgICAgICAvL2xvb3AgdGhyb3VnaCBjb21wYXJpbmcgZXZlcnkgZXh0ZW5kIHdpdGggZXZlcnkgdGFyZ2V0IGV4dGVuZC5cbiAgICAgICAgLy8gYSB0YXJnZXQgZXh0ZW5kIGlzIHRoZSBvbmUgb24gdGhlIHJ1bGVzZXQgd2UgYXJlIGxvb2tpbmcgYXQgY29weS9lZGl0L3Bhc3RpbmcgaW4gcGxhY2VcbiAgICAgICAgLy8gZS5nLiAgLmE6ZXh0ZW5kKC5iKSB7fSAgYW5kIC5iOmV4dGVuZCguYykge30gdGhlbiB0aGUgZmlyc3QgZXh0ZW5kIGV4dGVuZHMgdGhlIHNlY29uZCBvbmVcbiAgICAgICAgLy8gYW5kIHRoZSBzZWNvbmQgaXMgdGhlIHRhcmdldC5cbiAgICAgICAgLy8gdGhlIHNlcGFyYXRpb24gaW50byB0d28gbGlzdHMgYWxsb3dzIHVzIHRvIHByb2Nlc3MgYSBzdWJzZXQgb2YgY2hhaW5zIHdpdGggYSBiaWdnZXIgc2V0LCBhcyBpcyB0aGVcbiAgICAgICAgLy8gY2FzZSB3aGVuIHByb2Nlc3NpbmcgbWVkaWEgcXVlcmllc1xuICAgICAgICBmb3IgKGV4dGVuZEluZGV4ID0gMDsgZXh0ZW5kSW5kZXggPCBleHRlbmRzTGlzdC5sZW5ndGg7IGV4dGVuZEluZGV4KyspIHtcbiAgICAgICAgICAgIGZvciAodGFyZ2V0RXh0ZW5kSW5kZXggPSAwOyB0YXJnZXRFeHRlbmRJbmRleCA8IGV4dGVuZHNMaXN0VGFyZ2V0Lmxlbmd0aDsgdGFyZ2V0RXh0ZW5kSW5kZXgrKykge1xuXG4gICAgICAgICAgICAgICAgZXh0ZW5kID0gZXh0ZW5kc0xpc3RbZXh0ZW5kSW5kZXhdO1xuICAgICAgICAgICAgICAgIHRhcmdldEV4dGVuZCA9IGV4dGVuZHNMaXN0VGFyZ2V0W3RhcmdldEV4dGVuZEluZGV4XTtcblxuICAgICAgICAgICAgICAgIC8vIGxvb2sgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXNcbiAgICAgICAgICAgICAgICBpZiAoIGV4dGVuZC5wYXJlbnRfaWRzLmluZGV4T2YoIHRhcmdldEV4dGVuZC5vYmplY3RfaWQgKSA+PSAwICkgeyBjb250aW51ZTsgfVxuXG4gICAgICAgICAgICAgICAgLy8gZmluZCBhIG1hdGNoIGluIHRoZSB0YXJnZXQgZXh0ZW5kcyBzZWxmIHNlbGVjdG9yICh0aGUgYml0IGJlZm9yZSA6ZXh0ZW5kKVxuICAgICAgICAgICAgICAgIHNlbGVjdG9yUGF0aCA9IFt0YXJnZXRFeHRlbmQuc2VsZlNlbGVjdG9yc1swXV07XG4gICAgICAgICAgICAgICAgbWF0Y2hlcyA9IGV4dGVuZFZpc2l0b3IuZmluZE1hdGNoKGV4dGVuZCwgc2VsZWN0b3JQYXRoKTtcblxuICAgICAgICAgICAgICAgIGlmIChtYXRjaGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBleHRlbmQuaGFzRm91bmRNYXRjaGVzID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgICAgICAvLyB3ZSBmb3VuZCBhIG1hdGNoLCBzbyBmb3IgZWFjaCBzZWxmIHNlbGVjdG9yLi5cbiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kLnNlbGZTZWxlY3RvcnMuZm9yRWFjaChmdW5jdGlvbihzZWxmU2VsZWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbmZvID0gdGFyZ2V0RXh0ZW5kLnZpc2liaWxpdHlJbmZvKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByb2Nlc3MgdGhlIGV4dGVuZCBhcyB1c3VhbFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2VsZWN0b3IgPSBleHRlbmRWaXNpdG9yLmV4dGVuZFNlbGVjdG9yKG1hdGNoZXMsIHNlbGVjdG9yUGF0aCwgc2VsZlNlbGVjdG9yLCBleHRlbmQuaXNWaXNpYmxlKCkpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBidXQgbm93IHdlIGNyZWF0ZSBhIG5ldyBleHRlbmQgZnJvbSBpdFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3RXh0ZW5kID0gbmV3KHRyZWUuRXh0ZW5kKSh0YXJnZXRFeHRlbmQuc2VsZWN0b3IsIHRhcmdldEV4dGVuZC5vcHRpb24sIDAsIHRhcmdldEV4dGVuZC5jdXJyZW50RmlsZUluZm8sIGluZm8pO1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3RXh0ZW5kLnNlbGZTZWxlY3RvcnMgPSBuZXdTZWxlY3RvcjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWRkIHRoZSBleHRlbmQgb250byB0aGUgbGlzdCBvZiBleHRlbmRzIGZvciB0aGF0IHNlbGVjdG9yXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTZWxlY3RvcltuZXdTZWxlY3Rvci5sZW5ndGggLSAxXS5leHRlbmRMaXN0ID0gW25ld0V4dGVuZF07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlY29yZCB0aGF0IHdlIG5lZWQgdG8gYWRkIGl0LlxuICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kc1RvQWRkLnB1c2gobmV3RXh0ZW5kKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0V4dGVuZC5ydWxlc2V0ID0gdGFyZ2V0RXh0ZW5kLnJ1bGVzZXQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVtZW1iZXIgaXRzIHBhcmVudHMgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXNcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0V4dGVuZC5wYXJlbnRfaWRzID0gbmV3RXh0ZW5kLnBhcmVudF9pZHMuY29uY2F0KHRhcmdldEV4dGVuZC5wYXJlbnRfaWRzLCBleHRlbmQucGFyZW50X2lkcyk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9ubHkgcHJvY2VzcyB0aGUgc2VsZWN0b3Igb25jZS4uIGlmIHdlIGhhdmUgOmV4dGVuZCguYSwuYikgdGhlbiBtdWx0aXBsZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXh0ZW5kcyB3aWxsIGxvb2sgYXQgdGhlIHNhbWUgc2VsZWN0b3IgcGF0aCwgc28gd2hlbiBleHRlbmRpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIGtub3cgdGhhdCBhbnkgb3RoZXJzIHdpbGwgYmUgZHVwbGljYXRlcyBpbiB0ZXJtcyBvZiB3aGF0IGlzIGFkZGVkIHRvIHRoZSBjc3NcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXRFeHRlbmQuZmlyc3RFeHRlbmRPblRoaXNTZWxlY3RvclBhdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdFeHRlbmQuZmlyc3RFeHRlbmRPblRoaXNTZWxlY3RvclBhdGggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEV4dGVuZC5ydWxlc2V0LnBhdGhzLnB1c2gobmV3U2VsZWN0b3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXh0ZW5kc1RvQWRkLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8gdHJ5IHRvIGRldGVjdCBjaXJjdWxhciByZWZlcmVuY2VzIHRvIHN0b3AgYSBzdGFjayBvdmVyZmxvdy5cbiAgICAgICAgICAgIC8vIG1heSBubyBsb25nZXIgYmUgbmVlZGVkLlxuICAgICAgICAgICAgdGhpcy5leHRlbmRDaGFpbkNvdW50Kys7XG4gICAgICAgICAgICBpZiAoaXRlcmF0aW9uQ291bnQgPiAxMDApIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0b3JPbmUgPSBcInt1bmFibGUgdG8gY2FsY3VsYXRlfVwiO1xuICAgICAgICAgICAgICAgIHZhciBzZWxlY3RvclR3byA9IFwie3VuYWJsZSB0byBjYWxjdWxhdGV9XCI7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3JPbmUgPSBleHRlbmRzVG9BZGRbMF0uc2VsZlNlbGVjdG9yc1swXS50b0NTUygpO1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvclR3byA9IGV4dGVuZHNUb0FkZFswXS5zZWxlY3Rvci50b0NTUygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaChlKSB7fVxuICAgICAgICAgICAgICAgIHRocm93IHsgbWVzc2FnZTogXCJleHRlbmQgY2lyY3VsYXIgcmVmZXJlbmNlIGRldGVjdGVkLiBPbmUgb2YgdGhlIGNpcmN1bGFyIGV4dGVuZHMgaXMgY3VycmVudGx5OlwiICtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3JPbmUgKyBcIjpleHRlbmQoXCIgKyBzZWxlY3RvclR3byArIFwiKVwifTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gbm93IHByb2Nlc3MgdGhlIG5ldyBleHRlbmRzIG9uIHRoZSBleGlzdGluZyBydWxlcyBzbyB0aGF0IHdlIGNhbiBoYW5kbGUgYSBleHRlbmRpbmcgYiBleHRlbmRpbmcgYyBleHRlbmRpbmdcbiAgICAgICAgICAgIC8vIGQgZXh0ZW5kaW5nIGUuLi5cbiAgICAgICAgICAgIHJldHVybiBleHRlbmRzVG9BZGQuY29uY2F0KGV4dGVuZFZpc2l0b3IuZG9FeHRlbmRDaGFpbmluZyhleHRlbmRzVG9BZGQsIGV4dGVuZHNMaXN0VGFyZ2V0LCBpdGVyYXRpb25Db3VudCArIDEpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBleHRlbmRzVG9BZGQ7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIHZpc2l0UnVsZTogZnVuY3Rpb24gKHJ1bGVOb2RlLCB2aXNpdEFyZ3MpIHtcbiAgICAgICAgdmlzaXRBcmdzLnZpc2l0RGVlcGVyID0gZmFsc2U7XG4gICAgfSxcbiAgICB2aXNpdE1peGluRGVmaW5pdGlvbjogZnVuY3Rpb24gKG1peGluRGVmaW5pdGlvbk5vZGUsIHZpc2l0QXJncykge1xuICAgICAgICB2aXNpdEFyZ3MudmlzaXREZWVwZXIgPSBmYWxzZTtcbiAgICB9LFxuICAgIHZpc2l0U2VsZWN0b3I6IGZ1bmN0aW9uIChzZWxlY3Rvck5vZGUsIHZpc2l0QXJncykge1xuICAgICAgICB2aXNpdEFyZ3MudmlzaXREZWVwZXIgPSBmYWxzZTtcbiAgICB9LFxuICAgIHZpc2l0UnVsZXNldDogZnVuY3Rpb24gKHJ1bGVzZXROb2RlLCB2aXNpdEFyZ3MpIHtcbiAgICAgICAgaWYgKHJ1bGVzZXROb2RlLnJvb3QpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbWF0Y2hlcywgcGF0aEluZGV4LCBleHRlbmRJbmRleCwgYWxsRXh0ZW5kcyA9IHRoaXMuYWxsRXh0ZW5kc1N0YWNrW3RoaXMuYWxsRXh0ZW5kc1N0YWNrLmxlbmd0aCAtIDFdLFxuICAgICAgICAgICAgc2VsZWN0b3JzVG9BZGQgPSBbXSwgZXh0ZW5kVmlzaXRvciA9IHRoaXMsIHNlbGVjdG9yUGF0aDtcblxuICAgICAgICAvLyBsb29rIGF0IGVhY2ggc2VsZWN0b3IgcGF0aCBpbiB0aGUgcnVsZXNldCwgZmluZCBhbnkgZXh0ZW5kIG1hdGNoZXMgYW5kIHRoZW4gY29weSwgZmluZCBhbmQgcmVwbGFjZVxuXG4gICAgICAgIGZvciAoZXh0ZW5kSW5kZXggPSAwOyBleHRlbmRJbmRleCA8IGFsbEV4dGVuZHMubGVuZ3RoOyBleHRlbmRJbmRleCsrKSB7XG4gICAgICAgICAgICBmb3IgKHBhdGhJbmRleCA9IDA7IHBhdGhJbmRleCA8IHJ1bGVzZXROb2RlLnBhdGhzLmxlbmd0aDsgcGF0aEluZGV4KyspIHtcbiAgICAgICAgICAgICAgICBzZWxlY3RvclBhdGggPSBydWxlc2V0Tm9kZS5wYXRoc1twYXRoSW5kZXhdO1xuXG4gICAgICAgICAgICAgICAgLy8gZXh0ZW5kaW5nIGV4dGVuZHMgaGFwcGVucyBpbml0aWFsbHksIGJlZm9yZSB0aGUgbWFpbiBwYXNzXG4gICAgICAgICAgICAgICAgaWYgKHJ1bGVzZXROb2RlLmV4dGVuZE9uRXZlcnlQYXRoKSB7IGNvbnRpbnVlOyB9XG4gICAgICAgICAgICAgICAgdmFyIGV4dGVuZExpc3QgPSBzZWxlY3RvclBhdGhbc2VsZWN0b3JQYXRoLmxlbmd0aCAtIDFdLmV4dGVuZExpc3Q7XG4gICAgICAgICAgICAgICAgaWYgKGV4dGVuZExpc3QgJiYgZXh0ZW5kTGlzdC5sZW5ndGgpIHsgY29udGludWU7IH1cblxuICAgICAgICAgICAgICAgIG1hdGNoZXMgPSB0aGlzLmZpbmRNYXRjaChhbGxFeHRlbmRzW2V4dGVuZEluZGV4XSwgc2VsZWN0b3JQYXRoKTtcblxuICAgICAgICAgICAgICAgIGlmIChtYXRjaGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBhbGxFeHRlbmRzW2V4dGVuZEluZGV4XS5oYXNGb3VuZE1hdGNoZXMgPSB0cnVlO1xuXG4gICAgICAgICAgICAgICAgICAgIGFsbEV4dGVuZHNbZXh0ZW5kSW5kZXhdLnNlbGZTZWxlY3RvcnMuZm9yRWFjaChmdW5jdGlvbihzZWxmU2VsZWN0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleHRlbmRlZFNlbGVjdG9ycztcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuZGVkU2VsZWN0b3JzID0gZXh0ZW5kVmlzaXRvci5leHRlbmRTZWxlY3RvcihtYXRjaGVzLCBzZWxlY3RvclBhdGgsIHNlbGZTZWxlY3RvciwgYWxsRXh0ZW5kc1tleHRlbmRJbmRleF0uaXNWaXNpYmxlKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3JzVG9BZGQucHVzaChleHRlbmRlZFNlbGVjdG9ycyk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBydWxlc2V0Tm9kZS5wYXRocyA9IHJ1bGVzZXROb2RlLnBhdGhzLmNvbmNhdChzZWxlY3RvcnNUb0FkZCk7XG4gICAgfSxcbiAgICBmaW5kTWF0Y2g6IGZ1bmN0aW9uIChleHRlbmQsIGhheXN0YWNrU2VsZWN0b3JQYXRoKSB7XG4gICAgICAgIC8vXG4gICAgICAgIC8vIGxvb2sgdGhyb3VnaCB0aGUgaGF5c3RhY2sgc2VsZWN0b3IgcGF0aCB0byB0cnkgYW5kIGZpbmQgdGhlIG5lZWRsZSAtIGV4dGVuZC5zZWxlY3RvclxuICAgICAgICAvLyByZXR1cm5zIGFuIGFycmF5IG9mIHNlbGVjdG9yIG1hdGNoZXMgdGhhdCBjYW4gdGhlbiBiZSByZXBsYWNlZFxuICAgICAgICAvL1xuICAgICAgICB2YXIgaGF5c3RhY2tTZWxlY3RvckluZGV4LCBoYWNrc3RhY2tTZWxlY3RvciwgaGFja3N0YWNrRWxlbWVudEluZGV4LCBoYXlzdGFja0VsZW1lbnQsXG4gICAgICAgICAgICB0YXJnZXRDb21iaW5hdG9yLCBpLFxuICAgICAgICAgICAgZXh0ZW5kVmlzaXRvciA9IHRoaXMsXG4gICAgICAgICAgICBuZWVkbGVFbGVtZW50cyA9IGV4dGVuZC5zZWxlY3Rvci5lbGVtZW50cyxcbiAgICAgICAgICAgIHBvdGVudGlhbE1hdGNoZXMgPSBbXSwgcG90ZW50aWFsTWF0Y2gsIG1hdGNoZXMgPSBbXTtcblxuICAgICAgICAvLyBsb29wIHRocm91Z2ggdGhlIGhheXN0YWNrIGVsZW1lbnRzXG4gICAgICAgIGZvciAoaGF5c3RhY2tTZWxlY3RvckluZGV4ID0gMDsgaGF5c3RhY2tTZWxlY3RvckluZGV4IDwgaGF5c3RhY2tTZWxlY3RvclBhdGgubGVuZ3RoOyBoYXlzdGFja1NlbGVjdG9ySW5kZXgrKykge1xuICAgICAgICAgICAgaGFja3N0YWNrU2VsZWN0b3IgPSBoYXlzdGFja1NlbGVjdG9yUGF0aFtoYXlzdGFja1NlbGVjdG9ySW5kZXhdO1xuXG4gICAgICAgICAgICBmb3IgKGhhY2tzdGFja0VsZW1lbnRJbmRleCA9IDA7IGhhY2tzdGFja0VsZW1lbnRJbmRleCA8IGhhY2tzdGFja1NlbGVjdG9yLmVsZW1lbnRzLmxlbmd0aDsgaGFja3N0YWNrRWxlbWVudEluZGV4KyspIHtcblxuICAgICAgICAgICAgICAgIGhheXN0YWNrRWxlbWVudCA9IGhhY2tzdGFja1NlbGVjdG9yLmVsZW1lbnRzW2hhY2tzdGFja0VsZW1lbnRJbmRleF07XG5cbiAgICAgICAgICAgICAgICAvLyBpZiB3ZSBhbGxvdyBlbGVtZW50cyBiZWZvcmUgb3VyIG1hdGNoIHdlIGNhbiBhZGQgYSBwb3RlbnRpYWwgbWF0Y2ggZXZlcnkgdGltZS4gb3RoZXJ3aXNlIG9ubHkgYXQgdGhlIGZpcnN0IGVsZW1lbnQuXG4gICAgICAgICAgICAgICAgaWYgKGV4dGVuZC5hbGxvd0JlZm9yZSB8fCAoaGF5c3RhY2tTZWxlY3RvckluZGV4ID09PSAwICYmIGhhY2tzdGFja0VsZW1lbnRJbmRleCA9PT0gMCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcG90ZW50aWFsTWF0Y2hlcy5wdXNoKHtwYXRoSW5kZXg6IGhheXN0YWNrU2VsZWN0b3JJbmRleCwgaW5kZXg6IGhhY2tzdGFja0VsZW1lbnRJbmRleCwgbWF0Y2hlZDogMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluaXRpYWxDb21iaW5hdG9yOiBoYXlzdGFja0VsZW1lbnQuY29tYmluYXRvcn0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBwb3RlbnRpYWxNYXRjaGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHBvdGVudGlhbE1hdGNoID0gcG90ZW50aWFsTWF0Y2hlc1tpXTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBzZWxlY3RvcnMgYWRkIFwiIFwiIG9udG8gdGhlIGZpcnN0IGVsZW1lbnQuIFdoZW4gd2UgdXNlICYgaXQgam9pbnMgdGhlIHNlbGVjdG9ycyB0b2dldGhlciwgYnV0IGlmIHdlIGRvbid0XG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZW4gZWFjaCBzZWxlY3RvciBpbiBoYXlzdGFja1NlbGVjdG9yUGF0aCBoYXMgYSBzcGFjZSBiZWZvcmUgaXQgYWRkZWQgaW4gdGhlIHRvQ1NTIHBoYXNlLiBzbyB3ZSBuZWVkIHRvXG4gICAgICAgICAgICAgICAgICAgIC8vIHdvcmsgb3V0IHdoYXQgdGhlIHJlc3VsdGluZyBjb21iaW5hdG9yIHdpbGwgYmVcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Q29tYmluYXRvciA9IGhheXN0YWNrRWxlbWVudC5jb21iaW5hdG9yLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0Q29tYmluYXRvciA9PT0gJycgJiYgaGFja3N0YWNrRWxlbWVudEluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRDb21iaW5hdG9yID0gJyAnO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgd2UgZG9uJ3QgbWF0Y2gsIG51bGwgb3VyIG1hdGNoIHRvIGluZGljYXRlIGZhaWx1cmVcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFleHRlbmRWaXNpdG9yLmlzRWxlbWVudFZhbHVlc0VxdWFsKG5lZWRsZUVsZW1lbnRzW3BvdGVudGlhbE1hdGNoLm1hdGNoZWRdLnZhbHVlLCBoYXlzdGFja0VsZW1lbnQudmFsdWUpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAocG90ZW50aWFsTWF0Y2gubWF0Y2hlZCA+IDAgJiYgbmVlZGxlRWxlbWVudHNbcG90ZW50aWFsTWF0Y2gubWF0Y2hlZF0uY29tYmluYXRvci52YWx1ZSAhPT0gdGFyZ2V0Q29tYmluYXRvcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvdGVudGlhbE1hdGNoID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvdGVudGlhbE1hdGNoLm1hdGNoZWQrKztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBzdGlsbCB2YWxpZCBhbmQgaGF2ZSBmaW5pc2hlZCwgdGVzdCB3aGV0aGVyIHdlIGhhdmUgZWxlbWVudHMgYWZ0ZXIgYW5kIHdoZXRoZXIgdGhlc2UgYXJlIGFsbG93ZWRcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBvdGVudGlhbE1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwb3RlbnRpYWxNYXRjaC5maW5pc2hlZCA9IHBvdGVudGlhbE1hdGNoLm1hdGNoZWQgPT09IG5lZWRsZUVsZW1lbnRzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwb3RlbnRpYWxNYXRjaC5maW5pc2hlZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICghZXh0ZW5kLmFsbG93QWZ0ZXIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGhhY2tzdGFja0VsZW1lbnRJbmRleCArIDEgPCBoYWNrc3RhY2tTZWxlY3Rvci5lbGVtZW50cy5sZW5ndGggfHwgaGF5c3RhY2tTZWxlY3RvckluZGV4ICsgMSA8IGhheXN0YWNrU2VsZWN0b3JQYXRoLmxlbmd0aCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG90ZW50aWFsTWF0Y2ggPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIG51bGwgd2UgcmVtb3ZlLCBpZiBub3QsIHdlIGFyZSBzdGlsbCB2YWxpZCwgc28gZWl0aGVyIHB1c2ggYXMgYSB2YWxpZCBtYXRjaCBvciBjb250aW51ZVxuICAgICAgICAgICAgICAgICAgICBpZiAocG90ZW50aWFsTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwb3RlbnRpYWxNYXRjaC5maW5pc2hlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvdGVudGlhbE1hdGNoLmxlbmd0aCA9IG5lZWRsZUVsZW1lbnRzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3RlbnRpYWxNYXRjaC5lbmRQYXRoSW5kZXggPSBoYXlzdGFja1NlbGVjdG9ySW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG90ZW50aWFsTWF0Y2guZW5kUGF0aEVsZW1lbnRJbmRleCA9IGhhY2tzdGFja0VsZW1lbnRJbmRleCArIDE7IC8vIGluZGV4IGFmdGVyIGVuZCBvZiBtYXRjaFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvdGVudGlhbE1hdGNoZXMubGVuZ3RoID0gMDsgLy8gd2UgZG9uJ3QgYWxsb3cgbWF0Y2hlcyB0byBvdmVybGFwLCBzbyBzdGFydCBtYXRjaGluZyBhZ2FpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoZXMucHVzaChwb3RlbnRpYWxNYXRjaCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwb3RlbnRpYWxNYXRjaGVzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWF0Y2hlcztcbiAgICB9LFxuICAgIGlzRWxlbWVudFZhbHVlc0VxdWFsOiBmdW5jdGlvbihlbGVtZW50VmFsdWUxLCBlbGVtZW50VmFsdWUyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZWxlbWVudFZhbHVlMSA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgZWxlbWVudFZhbHVlMiA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnRWYWx1ZTEgPT09IGVsZW1lbnRWYWx1ZTI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVsZW1lbnRWYWx1ZTEgaW5zdGFuY2VvZiB0cmVlLkF0dHJpYnV0ZSkge1xuICAgICAgICAgICAgaWYgKGVsZW1lbnRWYWx1ZTEub3AgIT09IGVsZW1lbnRWYWx1ZTIub3AgfHwgZWxlbWVudFZhbHVlMS5rZXkgIT09IGVsZW1lbnRWYWx1ZTIua2V5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFlbGVtZW50VmFsdWUxLnZhbHVlIHx8ICFlbGVtZW50VmFsdWUyLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRWYWx1ZTEudmFsdWUgfHwgZWxlbWVudFZhbHVlMi52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxlbWVudFZhbHVlMSA9IGVsZW1lbnRWYWx1ZTEudmFsdWUudmFsdWUgfHwgZWxlbWVudFZhbHVlMS52YWx1ZTtcbiAgICAgICAgICAgIGVsZW1lbnRWYWx1ZTIgPSBlbGVtZW50VmFsdWUyLnZhbHVlLnZhbHVlIHx8IGVsZW1lbnRWYWx1ZTIudmFsdWU7XG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudFZhbHVlMSA9PT0gZWxlbWVudFZhbHVlMjtcbiAgICAgICAgfVxuICAgICAgICBlbGVtZW50VmFsdWUxID0gZWxlbWVudFZhbHVlMS52YWx1ZTtcbiAgICAgICAgZWxlbWVudFZhbHVlMiA9IGVsZW1lbnRWYWx1ZTIudmFsdWU7XG4gICAgICAgIGlmIChlbGVtZW50VmFsdWUxIGluc3RhbmNlb2YgdHJlZS5TZWxlY3Rvcikge1xuICAgICAgICAgICAgaWYgKCEoZWxlbWVudFZhbHVlMiBpbnN0YW5jZW9mIHRyZWUuU2VsZWN0b3IpIHx8IGVsZW1lbnRWYWx1ZTEuZWxlbWVudHMubGVuZ3RoICE9PSBlbGVtZW50VmFsdWUyLmVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpICA8IGVsZW1lbnRWYWx1ZTEuZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudFZhbHVlMS5lbGVtZW50c1tpXS5jb21iaW5hdG9yLnZhbHVlICE9PSBlbGVtZW50VmFsdWUyLmVsZW1lbnRzW2ldLmNvbWJpbmF0b3IudmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgIT09IDAgfHwgKGVsZW1lbnRWYWx1ZTEuZWxlbWVudHNbaV0uY29tYmluYXRvci52YWx1ZSB8fCAnICcpICE9PSAoZWxlbWVudFZhbHVlMi5lbGVtZW50c1tpXS5jb21iaW5hdG9yLnZhbHVlIHx8ICcgJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNFbGVtZW50VmFsdWVzRXF1YWwoZWxlbWVudFZhbHVlMS5lbGVtZW50c1tpXS52YWx1ZSwgZWxlbWVudFZhbHVlMi5lbGVtZW50c1tpXS52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9LFxuICAgIGV4dGVuZFNlbGVjdG9yOmZ1bmN0aW9uIChtYXRjaGVzLCBzZWxlY3RvclBhdGgsIHJlcGxhY2VtZW50U2VsZWN0b3IsIGlzVmlzaWJsZSkge1xuXG4gICAgICAgIC8vZm9yIGEgc2V0IG9mIG1hdGNoZXMsIHJlcGxhY2UgZWFjaCBtYXRjaCB3aXRoIHRoZSByZXBsYWNlbWVudCBzZWxlY3RvclxuXG4gICAgICAgIHZhciBjdXJyZW50U2VsZWN0b3JQYXRoSW5kZXggPSAwLFxuICAgICAgICAgICAgY3VycmVudFNlbGVjdG9yUGF0aEVsZW1lbnRJbmRleCA9IDAsXG4gICAgICAgICAgICBwYXRoID0gW10sXG4gICAgICAgICAgICBtYXRjaEluZGV4LFxuICAgICAgICAgICAgc2VsZWN0b3IsXG4gICAgICAgICAgICBmaXJzdEVsZW1lbnQsXG4gICAgICAgICAgICBtYXRjaCxcbiAgICAgICAgICAgIG5ld0VsZW1lbnRzO1xuXG4gICAgICAgIGZvciAobWF0Y2hJbmRleCA9IDA7IG1hdGNoSW5kZXggPCBtYXRjaGVzLmxlbmd0aDsgbWF0Y2hJbmRleCsrKSB7XG4gICAgICAgICAgICBtYXRjaCA9IG1hdGNoZXNbbWF0Y2hJbmRleF07XG4gICAgICAgICAgICBzZWxlY3RvciA9IHNlbGVjdG9yUGF0aFttYXRjaC5wYXRoSW5kZXhdO1xuICAgICAgICAgICAgZmlyc3RFbGVtZW50ID0gbmV3IHRyZWUuRWxlbWVudChcbiAgICAgICAgICAgICAgICBtYXRjaC5pbml0aWFsQ29tYmluYXRvcixcbiAgICAgICAgICAgICAgICByZXBsYWNlbWVudFNlbGVjdG9yLmVsZW1lbnRzWzBdLnZhbHVlLFxuICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50U2VsZWN0b3IuZWxlbWVudHNbMF0uaW5kZXgsXG4gICAgICAgICAgICAgICAgcmVwbGFjZW1lbnRTZWxlY3Rvci5lbGVtZW50c1swXS5jdXJyZW50RmlsZUluZm9cbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChtYXRjaC5wYXRoSW5kZXggPiBjdXJyZW50U2VsZWN0b3JQYXRoSW5kZXggJiYgY3VycmVudFNlbGVjdG9yUGF0aEVsZW1lbnRJbmRleCA+IDApIHtcbiAgICAgICAgICAgICAgICBwYXRoW3BhdGgubGVuZ3RoIC0gMV0uZWxlbWVudHMgPSBwYXRoW3BhdGgubGVuZ3RoIC0gMV1cbiAgICAgICAgICAgICAgICAgICAgLmVsZW1lbnRzLmNvbmNhdChzZWxlY3RvclBhdGhbY3VycmVudFNlbGVjdG9yUGF0aEluZGV4XS5lbGVtZW50cy5zbGljZShjdXJyZW50U2VsZWN0b3JQYXRoRWxlbWVudEluZGV4KSk7XG4gICAgICAgICAgICAgICAgY3VycmVudFNlbGVjdG9yUGF0aEVsZW1lbnRJbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgY3VycmVudFNlbGVjdG9yUGF0aEluZGV4Kys7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG5ld0VsZW1lbnRzID0gc2VsZWN0b3IuZWxlbWVudHNcbiAgICAgICAgICAgICAgICAuc2xpY2UoY3VycmVudFNlbGVjdG9yUGF0aEVsZW1lbnRJbmRleCwgbWF0Y2guaW5kZXgpXG4gICAgICAgICAgICAgICAgLmNvbmNhdChbZmlyc3RFbGVtZW50XSlcbiAgICAgICAgICAgICAgICAuY29uY2F0KHJlcGxhY2VtZW50U2VsZWN0b3IuZWxlbWVudHMuc2xpY2UoMSkpO1xuXG4gICAgICAgICAgICBpZiAoY3VycmVudFNlbGVjdG9yUGF0aEluZGV4ID09PSBtYXRjaC5wYXRoSW5kZXggJiYgbWF0Y2hJbmRleCA+IDApIHtcbiAgICAgICAgICAgICAgICBwYXRoW3BhdGgubGVuZ3RoIC0gMV0uZWxlbWVudHMgPVxuICAgICAgICAgICAgICAgICAgICBwYXRoW3BhdGgubGVuZ3RoIC0gMV0uZWxlbWVudHMuY29uY2F0KG5ld0VsZW1lbnRzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcGF0aCA9IHBhdGguY29uY2F0KHNlbGVjdG9yUGF0aC5zbGljZShjdXJyZW50U2VsZWN0b3JQYXRoSW5kZXgsIG1hdGNoLnBhdGhJbmRleCkpO1xuXG4gICAgICAgICAgICAgICAgcGF0aC5wdXNoKG5ldyB0cmVlLlNlbGVjdG9yKFxuICAgICAgICAgICAgICAgICAgICBuZXdFbGVtZW50c1xuICAgICAgICAgICAgICAgICkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3VycmVudFNlbGVjdG9yUGF0aEluZGV4ID0gbWF0Y2guZW5kUGF0aEluZGV4O1xuICAgICAgICAgICAgY3VycmVudFNlbGVjdG9yUGF0aEVsZW1lbnRJbmRleCA9IG1hdGNoLmVuZFBhdGhFbGVtZW50SW5kZXg7XG4gICAgICAgICAgICBpZiAoY3VycmVudFNlbGVjdG9yUGF0aEVsZW1lbnRJbmRleCA+PSBzZWxlY3RvclBhdGhbY3VycmVudFNlbGVjdG9yUGF0aEluZGV4XS5lbGVtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50U2VsZWN0b3JQYXRoRWxlbWVudEluZGV4ID0gMDtcbiAgICAgICAgICAgICAgICBjdXJyZW50U2VsZWN0b3JQYXRoSW5kZXgrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjdXJyZW50U2VsZWN0b3JQYXRoSW5kZXggPCBzZWxlY3RvclBhdGgubGVuZ3RoICYmIGN1cnJlbnRTZWxlY3RvclBhdGhFbGVtZW50SW5kZXggPiAwKSB7XG4gICAgICAgICAgICBwYXRoW3BhdGgubGVuZ3RoIC0gMV0uZWxlbWVudHMgPSBwYXRoW3BhdGgubGVuZ3RoIC0gMV1cbiAgICAgICAgICAgICAgICAuZWxlbWVudHMuY29uY2F0KHNlbGVjdG9yUGF0aFtjdXJyZW50U2VsZWN0b3JQYXRoSW5kZXhdLmVsZW1lbnRzLnNsaWNlKGN1cnJlbnRTZWxlY3RvclBhdGhFbGVtZW50SW5kZXgpKTtcbiAgICAgICAgICAgIGN1cnJlbnRTZWxlY3RvclBhdGhJbmRleCsrO1xuICAgICAgICB9XG5cbiAgICAgICAgcGF0aCA9IHBhdGguY29uY2F0KHNlbGVjdG9yUGF0aC5zbGljZShjdXJyZW50U2VsZWN0b3JQYXRoSW5kZXgsIHNlbGVjdG9yUGF0aC5sZW5ndGgpKTtcbiAgICAgICAgcGF0aCA9IHBhdGgubWFwKGZ1bmN0aW9uIChjdXJyZW50VmFsdWUpIHtcbiAgICAgICAgICAgIC8vIHdlIGNhbiByZS11c2UgZWxlbWVudHMgaGVyZSwgYmVjYXVzZSB0aGUgdmlzaWJpbGl0eSBwcm9wZXJ0eSBtYXR0ZXJzIG9ubHkgZm9yIHNlbGVjdG9yc1xuICAgICAgICAgICAgdmFyIGRlcml2ZWQgPSBjdXJyZW50VmFsdWUuY3JlYXRlRGVyaXZlZChjdXJyZW50VmFsdWUuZWxlbWVudHMpO1xuICAgICAgICAgICAgaWYgKGlzVmlzaWJsZSkge1xuICAgICAgICAgICAgICAgIGRlcml2ZWQuZW5zdXJlVmlzaWJpbGl0eSgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZXJpdmVkLmVuc3VyZUludmlzaWJpbGl0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRlcml2ZWQ7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGF0aDtcbiAgICB9LFxuICAgIHZpc2l0TWVkaWE6IGZ1bmN0aW9uIChtZWRpYU5vZGUsIHZpc2l0QXJncykge1xuICAgICAgICB2YXIgbmV3QWxsRXh0ZW5kcyA9IG1lZGlhTm9kZS5hbGxFeHRlbmRzLmNvbmNhdCh0aGlzLmFsbEV4dGVuZHNTdGFja1t0aGlzLmFsbEV4dGVuZHNTdGFjay5sZW5ndGggLSAxXSk7XG4gICAgICAgIG5ld0FsbEV4dGVuZHMgPSBuZXdBbGxFeHRlbmRzLmNvbmNhdCh0aGlzLmRvRXh0ZW5kQ2hhaW5pbmcobmV3QWxsRXh0ZW5kcywgbWVkaWFOb2RlLmFsbEV4dGVuZHMpKTtcbiAgICAgICAgdGhpcy5hbGxFeHRlbmRzU3RhY2sucHVzaChuZXdBbGxFeHRlbmRzKTtcbiAgICB9LFxuICAgIHZpc2l0TWVkaWFPdXQ6IGZ1bmN0aW9uIChtZWRpYU5vZGUpIHtcbiAgICAgICAgdmFyIGxhc3RJbmRleCA9IHRoaXMuYWxsRXh0ZW5kc1N0YWNrLmxlbmd0aCAtIDE7XG4gICAgICAgIHRoaXMuYWxsRXh0ZW5kc1N0YWNrLmxlbmd0aCA9IGxhc3RJbmRleDtcbiAgICB9LFxuICAgIHZpc2l0RGlyZWN0aXZlOiBmdW5jdGlvbiAoZGlyZWN0aXZlTm9kZSwgdmlzaXRBcmdzKSB7XG4gICAgICAgIHZhciBuZXdBbGxFeHRlbmRzID0gZGlyZWN0aXZlTm9kZS5hbGxFeHRlbmRzLmNvbmNhdCh0aGlzLmFsbEV4dGVuZHNTdGFja1t0aGlzLmFsbEV4dGVuZHNTdGFjay5sZW5ndGggLSAxXSk7XG4gICAgICAgIG5ld0FsbEV4dGVuZHMgPSBuZXdBbGxFeHRlbmRzLmNvbmNhdCh0aGlzLmRvRXh0ZW5kQ2hhaW5pbmcobmV3QWxsRXh0ZW5kcywgZGlyZWN0aXZlTm9kZS5hbGxFeHRlbmRzKSk7XG4gICAgICAgIHRoaXMuYWxsRXh0ZW5kc1N0YWNrLnB1c2gobmV3QWxsRXh0ZW5kcyk7XG4gICAgfSxcbiAgICB2aXNpdERpcmVjdGl2ZU91dDogZnVuY3Rpb24gKGRpcmVjdGl2ZU5vZGUpIHtcbiAgICAgICAgdmFyIGxhc3RJbmRleCA9IHRoaXMuYWxsRXh0ZW5kc1N0YWNrLmxlbmd0aCAtIDE7XG4gICAgICAgIHRoaXMuYWxsRXh0ZW5kc1N0YWNrLmxlbmd0aCA9IGxhc3RJbmRleDtcbiAgICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFByb2Nlc3NFeHRlbmRzVmlzaXRvcjtcblxufSx7XCIuLi9sb2dnZXJcIjozMyxcIi4uL3RyZWVcIjo2MixcIi4vdmlzaXRvclwiOjkxfV0sODU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuZnVuY3Rpb24gSW1wb3J0U2VxdWVuY2VyKG9uU2VxdWVuY2VyRW1wdHkpIHtcbiAgICB0aGlzLmltcG9ydHMgPSBbXTtcbiAgICB0aGlzLnZhcmlhYmxlSW1wb3J0cyA9IFtdO1xuICAgIHRoaXMuX29uU2VxdWVuY2VyRW1wdHkgPSBvblNlcXVlbmNlckVtcHR5O1xuICAgIHRoaXMuX2N1cnJlbnREZXB0aCA9IDA7XG59XG5cbkltcG9ydFNlcXVlbmNlci5wcm90b3R5cGUuYWRkSW1wb3J0ID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICB2YXIgaW1wb3J0U2VxdWVuY2VyID0gdGhpcyxcbiAgICAgICAgaW1wb3J0SXRlbSA9IHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiBjYWxsYmFjayxcbiAgICAgICAgICAgIGFyZ3M6IG51bGwsXG4gICAgICAgICAgICBpc1JlYWR5OiBmYWxzZVxuICAgICAgICB9O1xuICAgIHRoaXMuaW1wb3J0cy5wdXNoKGltcG9ydEl0ZW0pO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgaW1wb3J0SXRlbS5hcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgICAgICAgaW1wb3J0SXRlbS5pc1JlYWR5ID0gdHJ1ZTtcbiAgICAgICAgaW1wb3J0U2VxdWVuY2VyLnRyeVJ1bigpO1xuICAgIH07XG59O1xuXG5JbXBvcnRTZXF1ZW5jZXIucHJvdG90eXBlLmFkZFZhcmlhYmxlSW1wb3J0ID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICB0aGlzLnZhcmlhYmxlSW1wb3J0cy5wdXNoKGNhbGxiYWNrKTtcbn07XG5cbkltcG9ydFNlcXVlbmNlci5wcm90b3R5cGUudHJ5UnVuID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fY3VycmVudERlcHRoKys7XG4gICAgdHJ5IHtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIHdoaWxlICh0aGlzLmltcG9ydHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHZhciBpbXBvcnRJdGVtID0gdGhpcy5pbXBvcnRzWzBdO1xuICAgICAgICAgICAgICAgIGlmICghaW1wb3J0SXRlbS5pc1JlYWR5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5pbXBvcnRzID0gdGhpcy5pbXBvcnRzLnNsaWNlKDEpO1xuICAgICAgICAgICAgICAgIGltcG9ydEl0ZW0uY2FsbGJhY2suYXBwbHkobnVsbCwgaW1wb3J0SXRlbS5hcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLnZhcmlhYmxlSW1wb3J0cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB2YXJpYWJsZUltcG9ydCA9IHRoaXMudmFyaWFibGVJbXBvcnRzWzBdO1xuICAgICAgICAgICAgdGhpcy52YXJpYWJsZUltcG9ydHMgPSB0aGlzLnZhcmlhYmxlSW1wb3J0cy5zbGljZSgxKTtcbiAgICAgICAgICAgIHZhcmlhYmxlSW1wb3J0KCk7XG4gICAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgICB0aGlzLl9jdXJyZW50RGVwdGgtLTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2N1cnJlbnREZXB0aCA9PT0gMCAmJiB0aGlzLl9vblNlcXVlbmNlckVtcHR5KSB7XG4gICAgICAgIHRoaXMuX29uU2VxdWVuY2VyRW1wdHkoKTtcbiAgICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEltcG9ydFNlcXVlbmNlcjtcblxufSx7fV0sODY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIGNvbnRleHRzID0gcmVxdWlyZShcIi4uL2NvbnRleHRzXCIpLFxuICAgIFZpc2l0b3IgPSByZXF1aXJlKFwiLi92aXNpdG9yXCIpLFxuICAgIEltcG9ydFNlcXVlbmNlciA9IHJlcXVpcmUoXCIuL2ltcG9ydC1zZXF1ZW5jZXJcIik7XG5cbnZhciBJbXBvcnRWaXNpdG9yID0gZnVuY3Rpb24oaW1wb3J0ZXIsIGZpbmlzaCkge1xuXG4gICAgdGhpcy5fdmlzaXRvciA9IG5ldyBWaXNpdG9yKHRoaXMpO1xuICAgIHRoaXMuX2ltcG9ydGVyID0gaW1wb3J0ZXI7XG4gICAgdGhpcy5fZmluaXNoID0gZmluaXNoO1xuICAgIHRoaXMuY29udGV4dCA9IG5ldyBjb250ZXh0cy5FdmFsKCk7XG4gICAgdGhpcy5pbXBvcnRDb3VudCA9IDA7XG4gICAgdGhpcy5vbmNlRmlsZURldGVjdGlvbk1hcCA9IHt9O1xuICAgIHRoaXMucmVjdXJzaW9uRGV0ZWN0b3IgPSB7fTtcbiAgICB0aGlzLl9zZXF1ZW5jZXIgPSBuZXcgSW1wb3J0U2VxdWVuY2VyKHRoaXMuX29uU2VxdWVuY2VyRW1wdHkuYmluZCh0aGlzKSk7XG59O1xuXG5JbXBvcnRWaXNpdG9yLnByb3RvdHlwZSA9IHtcbiAgICBpc1JlcGxhY2luZzogZmFsc2UsXG4gICAgcnVuOiBmdW5jdGlvbiAocm9vdCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gcHJvY2VzcyB0aGUgY29udGVudHNcbiAgICAgICAgICAgIHRoaXMuX3Zpc2l0b3IudmlzaXQocm9vdCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2goZSkge1xuICAgICAgICAgICAgdGhpcy5lcnJvciA9IGU7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmlzRmluaXNoZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLl9zZXF1ZW5jZXIudHJ5UnVuKCk7XG4gICAgfSxcbiAgICBfb25TZXF1ZW5jZXJFbXB0eTogZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICghdGhpcy5pc0ZpbmlzaGVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZmluaXNoKHRoaXMuZXJyb3IpO1xuICAgIH0sXG4gICAgdmlzaXRJbXBvcnQ6IGZ1bmN0aW9uIChpbXBvcnROb2RlLCB2aXNpdEFyZ3MpIHtcbiAgICAgICAgdmFyIGlubGluZUNTUyA9IGltcG9ydE5vZGUub3B0aW9ucy5pbmxpbmU7XG5cbiAgICAgICAgaWYgKCFpbXBvcnROb2RlLmNzcyB8fCBpbmxpbmVDU1MpIHtcblxuICAgICAgICAgICAgdmFyIGNvbnRleHQgPSBuZXcgY29udGV4dHMuRXZhbCh0aGlzLmNvbnRleHQsIHRoaXMuY29udGV4dC5mcmFtZXMuc2xpY2UoMCkpO1xuICAgICAgICAgICAgdmFyIGltcG9ydFBhcmVudCA9IGNvbnRleHQuZnJhbWVzWzBdO1xuXG4gICAgICAgICAgICB0aGlzLmltcG9ydENvdW50Kys7XG4gICAgICAgICAgICBpZiAoaW1wb3J0Tm9kZS5pc1ZhcmlhYmxlSW1wb3J0KCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXF1ZW5jZXIuYWRkVmFyaWFibGVJbXBvcnQodGhpcy5wcm9jZXNzSW1wb3J0Tm9kZS5iaW5kKHRoaXMsIGltcG9ydE5vZGUsIGNvbnRleHQsIGltcG9ydFBhcmVudCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NJbXBvcnROb2RlKGltcG9ydE5vZGUsIGNvbnRleHQsIGltcG9ydFBhcmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmlzaXRBcmdzLnZpc2l0RGVlcGVyID0gZmFsc2U7XG4gICAgfSxcbiAgICBwcm9jZXNzSW1wb3J0Tm9kZTogZnVuY3Rpb24oaW1wb3J0Tm9kZSwgY29udGV4dCwgaW1wb3J0UGFyZW50KSB7XG4gICAgICAgIHZhciBldmFsZEltcG9ydE5vZGUsXG4gICAgICAgICAgICBpbmxpbmVDU1MgPSBpbXBvcnROb2RlLm9wdGlvbnMuaW5saW5lO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBldmFsZEltcG9ydE5vZGUgPSBpbXBvcnROb2RlLmV2YWxGb3JJbXBvcnQoY29udGV4dCk7XG4gICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKCFlLmZpbGVuYW1lKSB7IGUuaW5kZXggPSBpbXBvcnROb2RlLmluZGV4OyBlLmZpbGVuYW1lID0gaW1wb3J0Tm9kZS5jdXJyZW50RmlsZUluZm8uZmlsZW5hbWU7IH1cbiAgICAgICAgICAgIC8vIGF0dGVtcHQgdG8gZXZhbCBwcm9wZXJseSBhbmQgdHJlYXQgYXMgY3NzXG4gICAgICAgICAgICBpbXBvcnROb2RlLmNzcyA9IHRydWU7XG4gICAgICAgICAgICAvLyBpZiB0aGF0IGZhaWxzLCB0aGlzIGVycm9yIHdpbGwgYmUgdGhyb3duXG4gICAgICAgICAgICBpbXBvcnROb2RlLmVycm9yID0gZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChldmFsZEltcG9ydE5vZGUgJiYgKCFldmFsZEltcG9ydE5vZGUuY3NzIHx8IGlubGluZUNTUykpIHtcblxuICAgICAgICAgICAgaWYgKGV2YWxkSW1wb3J0Tm9kZS5vcHRpb25zLm11bHRpcGxlKSB7XG4gICAgICAgICAgICAgICAgY29udGV4dC5pbXBvcnRNdWx0aXBsZSA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHRyeSBhcHBlbmRpbmcgaWYgd2UgaGF2ZW4ndCBkZXRlcm1pbmVkIGlmIGl0IGlzIGNzcyBvciBub3RcbiAgICAgICAgICAgIHZhciB0cnlBcHBlbmRMZXNzRXh0ZW5zaW9uID0gZXZhbGRJbXBvcnROb2RlLmNzcyA9PT0gdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGltcG9ydFBhcmVudC5ydWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChpbXBvcnRQYXJlbnQucnVsZXNbaV0gPT09IGltcG9ydE5vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgaW1wb3J0UGFyZW50LnJ1bGVzW2ldID0gZXZhbGRJbXBvcnROb2RlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBvbkltcG9ydGVkID0gdGhpcy5vbkltcG9ydGVkLmJpbmQodGhpcywgZXZhbGRJbXBvcnROb2RlLCBjb250ZXh0KSxcbiAgICAgICAgICAgICAgICBzZXF1ZW5jZWRPbkltcG9ydGVkID0gdGhpcy5fc2VxdWVuY2VyLmFkZEltcG9ydChvbkltcG9ydGVkKTtcblxuICAgICAgICAgICAgdGhpcy5faW1wb3J0ZXIucHVzaChldmFsZEltcG9ydE5vZGUuZ2V0UGF0aCgpLCB0cnlBcHBlbmRMZXNzRXh0ZW5zaW9uLCBldmFsZEltcG9ydE5vZGUuY3VycmVudEZpbGVJbmZvLFxuICAgICAgICAgICAgICAgIGV2YWxkSW1wb3J0Tm9kZS5vcHRpb25zLCBzZXF1ZW5jZWRPbkltcG9ydGVkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaW1wb3J0Q291bnQtLTtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzRmluaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXF1ZW5jZXIudHJ5UnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIG9uSW1wb3J0ZWQ6IGZ1bmN0aW9uIChpbXBvcnROb2RlLCBjb250ZXh0LCBlLCByb290LCBpbXBvcnRlZEF0Um9vdCwgZnVsbFBhdGgpIHtcbiAgICAgICAgaWYgKGUpIHtcbiAgICAgICAgICAgIGlmICghZS5maWxlbmFtZSkge1xuICAgICAgICAgICAgICAgIGUuaW5kZXggPSBpbXBvcnROb2RlLmluZGV4OyBlLmZpbGVuYW1lID0gaW1wb3J0Tm9kZS5jdXJyZW50RmlsZUluZm8uZmlsZW5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVycm9yID0gZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpbXBvcnRWaXNpdG9yID0gdGhpcyxcbiAgICAgICAgICAgIGlubGluZUNTUyA9IGltcG9ydE5vZGUub3B0aW9ucy5pbmxpbmUsXG4gICAgICAgICAgICBpc1BsdWdpbiA9IGltcG9ydE5vZGUub3B0aW9ucy5wbHVnaW4sXG4gICAgICAgICAgICBpc09wdGlvbmFsID0gaW1wb3J0Tm9kZS5vcHRpb25zLm9wdGlvbmFsLFxuICAgICAgICAgICAgZHVwbGljYXRlSW1wb3J0ID0gaW1wb3J0ZWRBdFJvb3QgfHwgZnVsbFBhdGggaW4gaW1wb3J0VmlzaXRvci5yZWN1cnNpb25EZXRlY3RvcjtcblxuICAgICAgICBpZiAoIWNvbnRleHQuaW1wb3J0TXVsdGlwbGUpIHtcbiAgICAgICAgICAgIGlmIChkdXBsaWNhdGVJbXBvcnQpIHtcbiAgICAgICAgICAgICAgICBpbXBvcnROb2RlLnNraXAgPSB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbXBvcnROb2RlLnNraXAgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZ1bGxQYXRoIGluIGltcG9ydFZpc2l0b3Iub25jZUZpbGVEZXRlY3Rpb25NYXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGltcG9ydFZpc2l0b3Iub25jZUZpbGVEZXRlY3Rpb25NYXBbZnVsbFBhdGhdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWZ1bGxQYXRoICYmIGlzT3B0aW9uYWwpIHtcbiAgICAgICAgICAgIGltcG9ydE5vZGUuc2tpcCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocm9vdCkge1xuICAgICAgICAgICAgaW1wb3J0Tm9kZS5yb290ID0gcm9vdDtcbiAgICAgICAgICAgIGltcG9ydE5vZGUuaW1wb3J0ZWRGaWxlbmFtZSA9IGZ1bGxQYXRoO1xuXG4gICAgICAgICAgICBpZiAoIWlubGluZUNTUyAmJiAhaXNQbHVnaW4gJiYgKGNvbnRleHQuaW1wb3J0TXVsdGlwbGUgfHwgIWR1cGxpY2F0ZUltcG9ydCkpIHtcbiAgICAgICAgICAgICAgICBpbXBvcnRWaXNpdG9yLnJlY3Vyc2lvbkRldGVjdG9yW2Z1bGxQYXRoXSA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICB2YXIgb2xkQ29udGV4dCA9IHRoaXMuY29udGV4dDtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3Zpc2l0b3IudmlzaXQocm9vdCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0ID0gb2xkQ29udGV4dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGltcG9ydFZpc2l0b3IuaW1wb3J0Q291bnQtLTtcblxuICAgICAgICBpZiAoaW1wb3J0VmlzaXRvci5pc0ZpbmlzaGVkKSB7XG4gICAgICAgICAgICBpbXBvcnRWaXNpdG9yLl9zZXF1ZW5jZXIudHJ5UnVuKCk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIHZpc2l0UnVsZTogZnVuY3Rpb24gKHJ1bGVOb2RlLCB2aXNpdEFyZ3MpIHtcbiAgICAgICAgaWYgKHJ1bGVOb2RlLnZhbHVlLnR5cGUgPT09IFwiRGV0YWNoZWRSdWxlc2V0XCIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5mcmFtZXMudW5zaGlmdChydWxlTm9kZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2aXNpdEFyZ3MudmlzaXREZWVwZXIgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgdmlzaXRSdWxlT3V0IDogZnVuY3Rpb24ocnVsZU5vZGUpIHtcbiAgICAgICAgaWYgKHJ1bGVOb2RlLnZhbHVlLnR5cGUgPT09IFwiRGV0YWNoZWRSdWxlc2V0XCIpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5mcmFtZXMuc2hpZnQoKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgdmlzaXREaXJlY3RpdmU6IGZ1bmN0aW9uIChkaXJlY3RpdmVOb2RlLCB2aXNpdEFyZ3MpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LmZyYW1lcy51bnNoaWZ0KGRpcmVjdGl2ZU5vZGUpO1xuICAgIH0sXG4gICAgdmlzaXREaXJlY3RpdmVPdXQ6IGZ1bmN0aW9uIChkaXJlY3RpdmVOb2RlKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC5mcmFtZXMuc2hpZnQoKTtcbiAgICB9LFxuICAgIHZpc2l0TWl4aW5EZWZpbml0aW9uOiBmdW5jdGlvbiAobWl4aW5EZWZpbml0aW9uTm9kZSwgdmlzaXRBcmdzKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC5mcmFtZXMudW5zaGlmdChtaXhpbkRlZmluaXRpb25Ob2RlKTtcbiAgICB9LFxuICAgIHZpc2l0TWl4aW5EZWZpbml0aW9uT3V0OiBmdW5jdGlvbiAobWl4aW5EZWZpbml0aW9uTm9kZSkge1xuICAgICAgICB0aGlzLmNvbnRleHQuZnJhbWVzLnNoaWZ0KCk7XG4gICAgfSxcbiAgICB2aXNpdFJ1bGVzZXQ6IGZ1bmN0aW9uIChydWxlc2V0Tm9kZSwgdmlzaXRBcmdzKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC5mcmFtZXMudW5zaGlmdChydWxlc2V0Tm9kZSk7XG4gICAgfSxcbiAgICB2aXNpdFJ1bGVzZXRPdXQ6IGZ1bmN0aW9uIChydWxlc2V0Tm9kZSkge1xuICAgICAgICB0aGlzLmNvbnRleHQuZnJhbWVzLnNoaWZ0KCk7XG4gICAgfSxcbiAgICB2aXNpdE1lZGlhOiBmdW5jdGlvbiAobWVkaWFOb2RlLCB2aXNpdEFyZ3MpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LmZyYW1lcy51bnNoaWZ0KG1lZGlhTm9kZS5ydWxlc1swXSk7XG4gICAgfSxcbiAgICB2aXNpdE1lZGlhT3V0OiBmdW5jdGlvbiAobWVkaWFOb2RlKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC5mcmFtZXMuc2hpZnQoKTtcbiAgICB9XG59O1xubW9kdWxlLmV4cG9ydHMgPSBJbXBvcnRWaXNpdG9yO1xuXG59LHtcIi4uL2NvbnRleHRzXCI6MTEsXCIuL2ltcG9ydC1zZXF1ZW5jZXJcIjo4NSxcIi4vdmlzaXRvclwiOjkxfV0sODc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIHZpc2l0b3JzID0ge1xuICAgIFZpc2l0b3I6IHJlcXVpcmUoXCIuL3Zpc2l0b3JcIiksXG4gICAgSW1wb3J0VmlzaXRvcjogcmVxdWlyZSgnLi9pbXBvcnQtdmlzaXRvcicpLFxuICAgIE1hcmtWaXNpYmxlU2VsZWN0b3JzVmlzaXRvcjogcmVxdWlyZShcIi4vc2V0LXRyZWUtdmlzaWJpbGl0eS12aXNpdG9yXCIpLFxuICAgIEV4dGVuZFZpc2l0b3I6IHJlcXVpcmUoJy4vZXh0ZW5kLXZpc2l0b3InKSxcbiAgICBKb2luU2VsZWN0b3JWaXNpdG9yOiByZXF1aXJlKCcuL2pvaW4tc2VsZWN0b3ItdmlzaXRvcicpLFxuICAgIFRvQ1NTVmlzaXRvcjogcmVxdWlyZSgnLi90by1jc3MtdmlzaXRvcicpXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHZpc2l0b3JzO1xuXG59LHtcIi4vZXh0ZW5kLXZpc2l0b3JcIjo4NCxcIi4vaW1wb3J0LXZpc2l0b3JcIjo4NixcIi4vam9pbi1zZWxlY3Rvci12aXNpdG9yXCI6ODgsXCIuL3NldC10cmVlLXZpc2liaWxpdHktdmlzaXRvclwiOjg5LFwiLi90by1jc3MtdmlzaXRvclwiOjkwLFwiLi92aXNpdG9yXCI6OTF9XSw4ODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgVmlzaXRvciA9IHJlcXVpcmUoXCIuL3Zpc2l0b3JcIik7XG5cbnZhciBKb2luU2VsZWN0b3JWaXNpdG9yID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5jb250ZXh0cyA9IFtbXV07XG4gICAgdGhpcy5fdmlzaXRvciA9IG5ldyBWaXNpdG9yKHRoaXMpO1xufTtcblxuSm9pblNlbGVjdG9yVmlzaXRvci5wcm90b3R5cGUgPSB7XG4gICAgcnVuOiBmdW5jdGlvbiAocm9vdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmlzaXRvci52aXNpdChyb290KTtcbiAgICB9LFxuICAgIHZpc2l0UnVsZTogZnVuY3Rpb24gKHJ1bGVOb2RlLCB2aXNpdEFyZ3MpIHtcbiAgICAgICAgdmlzaXRBcmdzLnZpc2l0RGVlcGVyID0gZmFsc2U7XG4gICAgfSxcbiAgICB2aXNpdE1peGluRGVmaW5pdGlvbjogZnVuY3Rpb24gKG1peGluRGVmaW5pdGlvbk5vZGUsIHZpc2l0QXJncykge1xuICAgICAgICB2aXNpdEFyZ3MudmlzaXREZWVwZXIgPSBmYWxzZTtcbiAgICB9LFxuXG4gICAgdmlzaXRSdWxlc2V0OiBmdW5jdGlvbiAocnVsZXNldE5vZGUsIHZpc2l0QXJncykge1xuICAgICAgICB2YXIgY29udGV4dCA9IHRoaXMuY29udGV4dHNbdGhpcy5jb250ZXh0cy5sZW5ndGggLSAxXSxcbiAgICAgICAgICAgIHBhdGhzID0gW10sIHNlbGVjdG9ycztcblxuICAgICAgICB0aGlzLmNvbnRleHRzLnB1c2gocGF0aHMpO1xuXG4gICAgICAgIGlmICghIHJ1bGVzZXROb2RlLnJvb3QpIHtcbiAgICAgICAgICAgIHNlbGVjdG9ycyA9IHJ1bGVzZXROb2RlLnNlbGVjdG9ycztcbiAgICAgICAgICAgIGlmIChzZWxlY3RvcnMpIHtcbiAgICAgICAgICAgICAgICBzZWxlY3RvcnMgPSBzZWxlY3RvcnMuZmlsdGVyKGZ1bmN0aW9uKHNlbGVjdG9yKSB7IHJldHVybiBzZWxlY3Rvci5nZXRJc091dHB1dCgpOyB9KTtcbiAgICAgICAgICAgICAgICBydWxlc2V0Tm9kZS5zZWxlY3RvcnMgPSBzZWxlY3RvcnMubGVuZ3RoID8gc2VsZWN0b3JzIDogKHNlbGVjdG9ycyA9IG51bGwpO1xuICAgICAgICAgICAgICAgIGlmIChzZWxlY3RvcnMpIHsgcnVsZXNldE5vZGUuam9pblNlbGVjdG9ycyhwYXRocywgY29udGV4dCwgc2VsZWN0b3JzKTsgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFzZWxlY3RvcnMpIHsgcnVsZXNldE5vZGUucnVsZXMgPSBudWxsOyB9XG4gICAgICAgICAgICBydWxlc2V0Tm9kZS5wYXRocyA9IHBhdGhzO1xuICAgICAgICB9XG4gICAgfSxcbiAgICB2aXNpdFJ1bGVzZXRPdXQ6IGZ1bmN0aW9uIChydWxlc2V0Tm9kZSkge1xuICAgICAgICB0aGlzLmNvbnRleHRzLmxlbmd0aCA9IHRoaXMuY29udGV4dHMubGVuZ3RoIC0gMTtcbiAgICB9LFxuICAgIHZpc2l0TWVkaWE6IGZ1bmN0aW9uIChtZWRpYU5vZGUsIHZpc2l0QXJncykge1xuICAgICAgICB2YXIgY29udGV4dCA9IHRoaXMuY29udGV4dHNbdGhpcy5jb250ZXh0cy5sZW5ndGggLSAxXTtcbiAgICAgICAgbWVkaWFOb2RlLnJ1bGVzWzBdLnJvb3QgPSAoY29udGV4dC5sZW5ndGggPT09IDAgfHwgY29udGV4dFswXS5tdWx0aU1lZGlhKTtcbiAgICB9LFxuICAgIHZpc2l0RGlyZWN0aXZlOiBmdW5jdGlvbiAoZGlyZWN0aXZlTm9kZSwgdmlzaXRBcmdzKSB7XG4gICAgICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0c1t0aGlzLmNvbnRleHRzLmxlbmd0aCAtIDFdO1xuICAgICAgICBpZiAoZGlyZWN0aXZlTm9kZS5ydWxlcyAmJiBkaXJlY3RpdmVOb2RlLnJ1bGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgZGlyZWN0aXZlTm9kZS5ydWxlc1swXS5yb290ID0gKGRpcmVjdGl2ZU5vZGUuaXNSb290ZWQgfHwgY29udGV4dC5sZW5ndGggPT09IDAgfHwgbnVsbCk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEpvaW5TZWxlY3RvclZpc2l0b3I7XG5cbn0se1wiLi92aXNpdG9yXCI6OTF9XSw4OTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgU2V0VHJlZVZpc2liaWxpdHlWaXNpdG9yID0gZnVuY3Rpb24odmlzaWJsZSkge1xuICAgIHRoaXMudmlzaWJsZSA9IHZpc2libGU7XG59O1xuU2V0VHJlZVZpc2liaWxpdHlWaXNpdG9yLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbihyb290KSB7XG4gICAgdGhpcy52aXNpdChyb290KTtcbn07XG5TZXRUcmVlVmlzaWJpbGl0eVZpc2l0b3IucHJvdG90eXBlLnZpc2l0QXJyYXkgPSBmdW5jdGlvbihub2Rlcykge1xuICAgIGlmICghbm9kZXMpIHtcbiAgICAgICAgcmV0dXJuIG5vZGVzO1xuICAgIH1cblxuICAgIHZhciBjbnQgPSBub2Rlcy5sZW5ndGgsIGk7XG4gICAgZm9yIChpID0gMDsgaSA8IGNudDsgaSsrKSB7XG4gICAgICAgIHRoaXMudmlzaXQobm9kZXNbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gbm9kZXM7XG59O1xuU2V0VHJlZVZpc2liaWxpdHlWaXNpdG9yLnByb3RvdHlwZS52aXNpdCA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAoIW5vZGUpIHtcbiAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfVxuICAgIGlmIChub2RlLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xuICAgICAgICByZXR1cm4gdGhpcy52aXNpdEFycmF5KG5vZGUpO1xuICAgIH1cblxuICAgIGlmICghbm9kZS5ibG9ja3NWaXNpYmlsaXR5IHx8IG5vZGUuYmxvY2tzVmlzaWJpbGl0eSgpKSB7XG4gICAgICAgIHJldHVybiBub2RlO1xuICAgIH1cbiAgICBpZiAodGhpcy52aXNpYmxlKSB7XG4gICAgICAgIG5vZGUuZW5zdXJlVmlzaWJpbGl0eSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIG5vZGUuZW5zdXJlSW52aXNpYmlsaXR5KCk7XG4gICAgfVxuXG4gICAgbm9kZS5hY2NlcHQodGhpcyk7XG4gICAgcmV0dXJuIG5vZGU7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBTZXRUcmVlVmlzaWJpbGl0eVZpc2l0b3I7XG59LHt9XSw5MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgdHJlZSA9IHJlcXVpcmUoXCIuLi90cmVlXCIpLFxuICAgIFZpc2l0b3IgPSByZXF1aXJlKFwiLi92aXNpdG9yXCIpO1xuXG52YXIgQ1NTVmlzaXRvclV0aWxzID0gZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHRoaXMuX3Zpc2l0b3IgPSBuZXcgVmlzaXRvcih0aGlzKTtcbiAgICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbn07XG5cbkNTU1Zpc2l0b3JVdGlscy5wcm90b3R5cGUgPSB7XG4gICAgY29udGFpbnNTaWxlbnROb25CbG9ja2VkQ2hpbGQ6IGZ1bmN0aW9uKGJvZHlSdWxlcykge1xuICAgICAgICB2YXIgcnVsZTtcbiAgICAgICAgaWYgKGJvZHlSdWxlcyA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZm9yICh2YXIgciA9IDA7IHIgPCBib2R5UnVsZXMubGVuZ3RoOyByKyspIHtcbiAgICAgICAgICAgIHJ1bGUgPSBib2R5UnVsZXNbcl07XG4gICAgICAgICAgICBpZiAocnVsZS5pc1NpbGVudCAmJiBydWxlLmlzU2lsZW50KHRoaXMuX2NvbnRleHQpICYmICFydWxlLmJsb2Nrc1Zpc2liaWxpdHkoKSkge1xuICAgICAgICAgICAgICAgIC8vdGhlIGRpcmVjdGl2ZSBjb250YWlucyBzb21ldGhpbmcgdGhhdCB3YXMgcmVmZXJlbmNlZCAobGlrZWx5IGJ5IGV4dGVuZClcbiAgICAgICAgICAgICAgICAvL3RoZXJlZm9yZSBpdCBuZWVkcyB0byBiZSBzaG93biBpbiBvdXRwdXQgdG9vXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG5cbiAgICBrZWVwT25seVZpc2libGVDaGlsZHM6IGZ1bmN0aW9uKG93bmVyKSB7XG4gICAgICAgIGlmIChvd25lciA9PSBudWxsIHx8IG93bmVyLnJ1bGVzID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiA7XG4gICAgICAgIH1cblxuICAgICAgICBvd25lci5ydWxlcyA9IG93bmVyLnJ1bGVzLmZpbHRlcihmdW5jdGlvbih0aGluZykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGluZy5pc1Zpc2libGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9LFxuXG4gICAgaXNFbXB0eTogZnVuY3Rpb24ob3duZXIpIHtcbiAgICAgICAgaWYgKG93bmVyID09IG51bGwgfHwgb3duZXIucnVsZXMgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG93bmVyLnJ1bGVzLmxlbmd0aCA9PT0gMDtcbiAgICB9LFxuXG4gICAgaGFzVmlzaWJsZVNlbGVjdG9yOiBmdW5jdGlvbihydWxlc2V0Tm9kZSkge1xuICAgICAgICBpZiAocnVsZXNldE5vZGUgPT0gbnVsbCB8fCBydWxlc2V0Tm9kZS5wYXRocyA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJ1bGVzZXROb2RlLnBhdGhzLmxlbmd0aCA+IDA7XG4gICAgfSxcblxuICAgIHJlc29sdmVWaXNpYmlsaXR5OiBmdW5jdGlvbiAobm9kZSwgb3JpZ2luYWxSdWxlcykge1xuICAgICAgICBpZiAoIW5vZGUuYmxvY2tzVmlzaWJpbGl0eSgpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0VtcHR5KG5vZGUpICYmICF0aGlzLmNvbnRhaW5zU2lsZW50Tm9uQmxvY2tlZENoaWxkKG9yaWdpbmFsUnVsZXMpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY29tcGlsZWRSdWxlc0JvZHkgPSBub2RlLnJ1bGVzWzBdO1xuICAgICAgICB0aGlzLmtlZXBPbmx5VmlzaWJsZUNoaWxkcyhjb21waWxlZFJ1bGVzQm9keSk7XG5cbiAgICAgICAgaWYgKHRoaXMuaXNFbXB0eShjb21waWxlZFJ1bGVzQm9keSkpIHtcbiAgICAgICAgICAgIHJldHVybiA7XG4gICAgICAgIH1cblxuICAgICAgICBub2RlLmVuc3VyZVZpc2liaWxpdHkoKTtcbiAgICAgICAgbm9kZS5yZW1vdmVWaXNpYmlsaXR5QmxvY2soKTtcblxuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICB9LFxuXG4gICAgaXNWaXNpYmxlUnVsZXNldDogZnVuY3Rpb24ocnVsZXNldE5vZGUpIHtcbiAgICAgICAgaWYgKHJ1bGVzZXROb2RlLmZpcnN0Um9vdCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5pc0VtcHR5KHJ1bGVzZXROb2RlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFydWxlc2V0Tm9kZS5yb290ICYmICF0aGlzLmhhc1Zpc2libGVTZWxlY3RvcihydWxlc2V0Tm9kZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxufTtcblxudmFyIFRvQ1NTVmlzaXRvciA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB0aGlzLl92aXNpdG9yID0gbmV3IFZpc2l0b3IodGhpcyk7XG4gICAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG4gICAgdGhpcy51dGlscyA9IG5ldyBDU1NWaXNpdG9yVXRpbHMoY29udGV4dCk7XG59O1xuXG5Ub0NTU1Zpc2l0b3IucHJvdG90eXBlID0ge1xuICAgIGlzUmVwbGFjaW5nOiB0cnVlLFxuICAgIHJ1bjogZnVuY3Rpb24gKHJvb3QpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Zpc2l0b3IudmlzaXQocm9vdCk7XG4gICAgfSxcblxuICAgIHZpc2l0UnVsZTogZnVuY3Rpb24gKHJ1bGVOb2RlLCB2aXNpdEFyZ3MpIHtcbiAgICAgICAgaWYgKHJ1bGVOb2RlLmJsb2Nrc1Zpc2liaWxpdHkoKSB8fCBydWxlTm9kZS52YXJpYWJsZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBydWxlTm9kZTtcbiAgICB9LFxuXG4gICAgdmlzaXRNaXhpbkRlZmluaXRpb246IGZ1bmN0aW9uIChtaXhpbk5vZGUsIHZpc2l0QXJncykge1xuICAgICAgICAvLyBtaXhpbiBkZWZpbml0aW9ucyBkbyBub3QgZ2V0IGV2YWwnZCAtIHRoaXMgbWVhbnMgdGhleSBrZWVwIHN0YXRlXG4gICAgICAgIC8vIHNvIHdlIGhhdmUgdG8gY2xlYXIgdGhhdCBzdGF0ZSBoZXJlIHNvIGl0IGlzbid0IHVzZWQgaWYgdG9DU1MgaXMgY2FsbGVkIHR3aWNlXG4gICAgICAgIG1peGluTm9kZS5mcmFtZXMgPSBbXTtcbiAgICB9LFxuXG4gICAgdmlzaXRFeHRlbmQ6IGZ1bmN0aW9uIChleHRlbmROb2RlLCB2aXNpdEFyZ3MpIHtcbiAgICB9LFxuXG4gICAgdmlzaXRDb21tZW50OiBmdW5jdGlvbiAoY29tbWVudE5vZGUsIHZpc2l0QXJncykge1xuICAgICAgICBpZiAoY29tbWVudE5vZGUuYmxvY2tzVmlzaWJpbGl0eSgpIHx8IGNvbW1lbnROb2RlLmlzU2lsZW50KHRoaXMuX2NvbnRleHQpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbW1lbnROb2RlO1xuICAgIH0sXG5cbiAgICB2aXNpdE1lZGlhOiBmdW5jdGlvbihtZWRpYU5vZGUsIHZpc2l0QXJncykge1xuICAgICAgICB2YXIgb3JpZ2luYWxSdWxlcyA9IG1lZGlhTm9kZS5ydWxlc1swXS5ydWxlcztcbiAgICAgICAgbWVkaWFOb2RlLmFjY2VwdCh0aGlzLl92aXNpdG9yKTtcbiAgICAgICAgdmlzaXRBcmdzLnZpc2l0RGVlcGVyID0gZmFsc2U7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudXRpbHMucmVzb2x2ZVZpc2liaWxpdHkobWVkaWFOb2RlLCBvcmlnaW5hbFJ1bGVzKTtcbiAgICB9LFxuXG4gICAgdmlzaXRJbXBvcnQ6IGZ1bmN0aW9uIChpbXBvcnROb2RlLCB2aXNpdEFyZ3MpIHtcbiAgICAgICAgaWYgKGltcG9ydE5vZGUuYmxvY2tzVmlzaWJpbGl0eSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbXBvcnROb2RlO1xuICAgIH0sXG5cbiAgICB2aXNpdERpcmVjdGl2ZTogZnVuY3Rpb24oZGlyZWN0aXZlTm9kZSwgdmlzaXRBcmdzKSB7XG4gICAgICAgIGlmIChkaXJlY3RpdmVOb2RlLnJ1bGVzICYmIGRpcmVjdGl2ZU5vZGUucnVsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy52aXNpdERpcmVjdGl2ZVdpdGhCb2R5KGRpcmVjdGl2ZU5vZGUsIHZpc2l0QXJncyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy52aXNpdERpcmVjdGl2ZVdpdGhvdXRCb2R5KGRpcmVjdGl2ZU5vZGUsIHZpc2l0QXJncyk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgdmlzaXREaXJlY3RpdmVXaXRoQm9keTogZnVuY3Rpb24oZGlyZWN0aXZlTm9kZSwgdmlzaXRBcmdzKSB7XG4gICAgICAgIC8vaWYgdGhlcmUgaXMgb25seSBvbmUgbmVzdGVkIHJ1bGVzZXQgYW5kIHRoYXQgb25lIGhhcyBubyBwYXRoLCB0aGVuIGl0IGlzXG4gICAgICAgIC8vanVzdCBmYWtlIHJ1bGVzZXRcbiAgICAgICAgZnVuY3Rpb24gaGFzRmFrZVJ1bGVzZXQoZGlyZWN0aXZlTm9kZSkge1xuICAgICAgICAgICAgdmFyIGJvZHlSdWxlcyA9IGRpcmVjdGl2ZU5vZGUucnVsZXM7XG4gICAgICAgICAgICByZXR1cm4gYm9keVJ1bGVzLmxlbmd0aCA9PT0gMSAmJiAoIWJvZHlSdWxlc1swXS5wYXRocyB8fCBib2R5UnVsZXNbMF0ucGF0aHMubGVuZ3RoID09PSAwKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBnZXRCb2R5UnVsZXMoZGlyZWN0aXZlTm9kZSkge1xuICAgICAgICAgICAgdmFyIG5vZGVSdWxlcyA9IGRpcmVjdGl2ZU5vZGUucnVsZXM7XG4gICAgICAgICAgICBpZiAoaGFzRmFrZVJ1bGVzZXQoZGlyZWN0aXZlTm9kZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZVJ1bGVzWzBdLnJ1bGVzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbm9kZVJ1bGVzO1xuICAgICAgICB9XG4gICAgICAgIC8vaXQgaXMgc3RpbGwgdHJ1ZSB0aGF0IGl0IGlzIG9ubHkgb25lIHJ1bGVzZXQgaW4gYXJyYXlcbiAgICAgICAgLy90aGlzIGlzIGxhc3Qgc3VjaCBtb21lbnRcbiAgICAgICAgLy9wcm9jZXNzIGNoaWxkc1xuICAgICAgICB2YXIgb3JpZ2luYWxSdWxlcyA9IGdldEJvZHlSdWxlcyhkaXJlY3RpdmVOb2RlKTtcbiAgICAgICAgZGlyZWN0aXZlTm9kZS5hY2NlcHQodGhpcy5fdmlzaXRvcik7XG4gICAgICAgIHZpc2l0QXJncy52aXNpdERlZXBlciA9IGZhbHNlO1xuXG4gICAgICAgIGlmICghdGhpcy51dGlscy5pc0VtcHR5KGRpcmVjdGl2ZU5vZGUpKSB7XG4gICAgICAgICAgICB0aGlzLl9tZXJnZVJ1bGVzKGRpcmVjdGl2ZU5vZGUucnVsZXNbMF0ucnVsZXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudXRpbHMucmVzb2x2ZVZpc2liaWxpdHkoZGlyZWN0aXZlTm9kZSwgb3JpZ2luYWxSdWxlcyk7XG4gICAgfSxcblxuICAgIHZpc2l0RGlyZWN0aXZlV2l0aG91dEJvZHk6IGZ1bmN0aW9uKGRpcmVjdGl2ZU5vZGUsIHZpc2l0QXJncykge1xuICAgICAgICBpZiAoZGlyZWN0aXZlTm9kZS5ibG9ja3NWaXNpYmlsaXR5KCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkaXJlY3RpdmVOb2RlLm5hbWUgPT09IFwiQGNoYXJzZXRcIikge1xuICAgICAgICAgICAgLy8gT25seSBvdXRwdXQgdGhlIGRlYnVnIGluZm8gdG9nZXRoZXIgd2l0aCBzdWJzZXF1ZW50IEBjaGFyc2V0IGRlZmluaXRpb25zXG4gICAgICAgICAgICAvLyBhIGNvbW1lbnQgKG9yIEBtZWRpYSBzdGF0ZW1lbnQpIGJlZm9yZSB0aGUgYWN0dWFsIEBjaGFyc2V0IGRpcmVjdGl2ZSB3b3VsZFxuICAgICAgICAgICAgLy8gYmUgY29uc2lkZXJlZCBpbGxlZ2FsIGNzcyBhcyBpdCBoYXMgdG8gYmUgb24gdGhlIGZpcnN0IGxpbmVcbiAgICAgICAgICAgIGlmICh0aGlzLmNoYXJzZXQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGlyZWN0aXZlTm9kZS5kZWJ1Z0luZm8pIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbW1lbnQgPSBuZXcgdHJlZS5Db21tZW50KFwiLyogXCIgKyBkaXJlY3RpdmVOb2RlLnRvQ1NTKHRoaXMuX2NvbnRleHQpLnJlcGxhY2UoL1xcbi9nLCBcIlwiKSArIFwiICovXFxuXCIpO1xuICAgICAgICAgICAgICAgICAgICBjb21tZW50LmRlYnVnSW5mbyA9IGRpcmVjdGl2ZU5vZGUuZGVidWdJbmZvO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdmlzaXRvci52aXNpdChjb21tZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jaGFyc2V0ID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkaXJlY3RpdmVOb2RlO1xuICAgIH0sXG5cbiAgICBjaGVja1ZhbGlkTm9kZXM6IGZ1bmN0aW9uKHJ1bGVzLCBpc1Jvb3QpIHtcbiAgICAgICAgaWYgKCFydWxlcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBydWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIHJ1bGVOb2RlID0gcnVsZXNbaV07XG4gICAgICAgICAgICBpZiAoaXNSb290ICYmIHJ1bGVOb2RlIGluc3RhbmNlb2YgdHJlZS5SdWxlICYmICFydWxlTm9kZS52YXJpYWJsZSkge1xuICAgICAgICAgICAgICAgIHRocm93IHsgbWVzc2FnZTogXCJQcm9wZXJ0aWVzIG11c3QgYmUgaW5zaWRlIHNlbGVjdG9yIGJsb2Nrcy4gVGhleSBjYW5ub3QgYmUgaW4gdGhlIHJvb3RcIixcbiAgICAgICAgICAgICAgICAgICAgaW5kZXg6IHJ1bGVOb2RlLmluZGV4LCBmaWxlbmFtZTogcnVsZU5vZGUuY3VycmVudEZpbGVJbmZvICYmIHJ1bGVOb2RlLmN1cnJlbnRGaWxlSW5mby5maWxlbmFtZX07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocnVsZU5vZGUgaW5zdGFuY2VvZiB0cmVlLkNhbGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyB7IG1lc3NhZ2U6IFwiRnVuY3Rpb24gJ1wiICsgcnVsZU5vZGUubmFtZSArIFwiJyBpcyB1bmRlZmluZWRcIixcbiAgICAgICAgICAgICAgICAgICAgaW5kZXg6IHJ1bGVOb2RlLmluZGV4LCBmaWxlbmFtZTogcnVsZU5vZGUuY3VycmVudEZpbGVJbmZvICYmIHJ1bGVOb2RlLmN1cnJlbnRGaWxlSW5mby5maWxlbmFtZX07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocnVsZU5vZGUudHlwZSAmJiAhcnVsZU5vZGUuYWxsb3dSb290KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgeyBtZXNzYWdlOiBydWxlTm9kZS50eXBlICsgXCIgbm9kZSByZXR1cm5lZCBieSBhIGZ1bmN0aW9uIGlzIG5vdCB2YWxpZCBoZXJlXCIsXG4gICAgICAgICAgICAgICAgICAgIGluZGV4OiBydWxlTm9kZS5pbmRleCwgZmlsZW5hbWU6IHJ1bGVOb2RlLmN1cnJlbnRGaWxlSW5mbyAmJiBydWxlTm9kZS5jdXJyZW50RmlsZUluZm8uZmlsZW5hbWV9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcblxuICAgIHZpc2l0UnVsZXNldDogZnVuY3Rpb24gKHJ1bGVzZXROb2RlLCB2aXNpdEFyZ3MpIHtcbiAgICAgICAgLy9hdCB0aGlzIHBvaW50IHJ1bGVzZXRzIGFyZSBuZXN0ZWQgaW50byBlYWNoIG90aGVyXG4gICAgICAgIHZhciBydWxlLCBydWxlc2V0cyA9IFtdO1xuXG4gICAgICAgIHRoaXMuY2hlY2tWYWxpZE5vZGVzKHJ1bGVzZXROb2RlLnJ1bGVzLCBydWxlc2V0Tm9kZS5maXJzdFJvb3QpO1xuXG4gICAgICAgIGlmICghIHJ1bGVzZXROb2RlLnJvb3QpIHtcbiAgICAgICAgICAgIC8vcmVtb3ZlIGludmlzaWJsZSBwYXRoc1xuICAgICAgICAgICAgdGhpcy5fY29tcGlsZVJ1bGVzZXRQYXRocyhydWxlc2V0Tm9kZSk7XG5cbiAgICAgICAgICAgIC8vIHJlbW92ZSBydWxlc2V0cyBmcm9tIHRoaXMgcnVsZXNldCBib2R5IGFuZCBjb21waWxlIHRoZW0gc2VwYXJhdGVseVxuICAgICAgICAgICAgdmFyIG5vZGVSdWxlcyA9IHJ1bGVzZXROb2RlLnJ1bGVzLCBub2RlUnVsZUNudCA9IG5vZGVSdWxlcyA/IG5vZGVSdWxlcy5sZW5ndGggOiAwO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlUnVsZUNudDsgKSB7XG4gICAgICAgICAgICAgICAgcnVsZSA9IG5vZGVSdWxlc1tpXTtcbiAgICAgICAgICAgICAgICBpZiAocnVsZSAmJiBydWxlLnJ1bGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHZpc2l0IGJlY2F1c2Ugd2UgYXJlIG1vdmluZyB0aGVtIG91dCBmcm9tIGJlaW5nIGEgY2hpbGRcbiAgICAgICAgICAgICAgICAgICAgcnVsZXNldHMucHVzaCh0aGlzLl92aXNpdG9yLnZpc2l0KHJ1bGUpKTtcbiAgICAgICAgICAgICAgICAgICAgbm9kZVJ1bGVzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgbm9kZVJ1bGVDbnQtLTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGFjY2VwdCB0aGUgdmlzaXRvciB0byByZW1vdmUgcnVsZXMgYW5kIHJlZmFjdG9yIGl0c2VsZlxuICAgICAgICAgICAgLy8gdGhlbiB3ZSBjYW4gZGVjaWRlIG5vZ3cgd2hldGhlciB3ZSB3YW50IGl0IG9yIG5vdFxuICAgICAgICAgICAgLy8gY29tcGlsZSBib2R5XG4gICAgICAgICAgICBpZiAobm9kZVJ1bGVDbnQgPiAwKSB7XG4gICAgICAgICAgICAgICAgcnVsZXNldE5vZGUuYWNjZXB0KHRoaXMuX3Zpc2l0b3IpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBydWxlc2V0Tm9kZS5ydWxlcyA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2aXNpdEFyZ3MudmlzaXREZWVwZXIgPSBmYWxzZTtcblxuICAgICAgICB9IGVsc2UgeyAvL2lmICghIHJ1bGVzZXROb2RlLnJvb3QpIHtcbiAgICAgICAgICAgIHJ1bGVzZXROb2RlLmFjY2VwdCh0aGlzLl92aXNpdG9yKTtcbiAgICAgICAgICAgIHZpc2l0QXJncy52aXNpdERlZXBlciA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJ1bGVzZXROb2RlLnJ1bGVzKSB7XG4gICAgICAgICAgICB0aGlzLl9tZXJnZVJ1bGVzKHJ1bGVzZXROb2RlLnJ1bGVzKTtcbiAgICAgICAgICAgIHRoaXMuX3JlbW92ZUR1cGxpY2F0ZVJ1bGVzKHJ1bGVzZXROb2RlLnJ1bGVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vbm93IGRlY2lkZSB3aGV0aGVyIHdlIGtlZXAgdGhlIHJ1bGVzZXRcbiAgICAgICAgaWYgKHRoaXMudXRpbHMuaXNWaXNpYmxlUnVsZXNldChydWxlc2V0Tm9kZSkpIHtcbiAgICAgICAgICAgIHJ1bGVzZXROb2RlLmVuc3VyZVZpc2liaWxpdHkoKTtcbiAgICAgICAgICAgIHJ1bGVzZXRzLnNwbGljZSgwLCAwLCBydWxlc2V0Tm9kZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocnVsZXNldHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gcnVsZXNldHNbMF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJ1bGVzZXRzO1xuICAgIH0sXG5cbiAgICBfY29tcGlsZVJ1bGVzZXRQYXRoczogZnVuY3Rpb24ocnVsZXNldE5vZGUpIHtcbiAgICAgICAgaWYgKHJ1bGVzZXROb2RlLnBhdGhzKSB7XG4gICAgICAgICAgICBydWxlc2V0Tm9kZS5wYXRocyA9IHJ1bGVzZXROb2RlLnBhdGhzXG4gICAgICAgICAgICAgICAgLmZpbHRlcihmdW5jdGlvbihwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocFswXS5lbGVtZW50c1swXS5jb21iaW5hdG9yLnZhbHVlID09PSAnICcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBbMF0uZWxlbWVudHNbMF0uY29tYmluYXRvciA9IG5ldyh0cmVlLkNvbWJpbmF0b3IpKCcnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBbaV0uaXNWaXNpYmxlKCkgJiYgcFtpXS5nZXRJc091dHB1dCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIF9yZW1vdmVEdXBsaWNhdGVSdWxlczogZnVuY3Rpb24ocnVsZXMpIHtcbiAgICAgICAgaWYgKCFydWxlcykgeyByZXR1cm47IH1cblxuICAgICAgICAvLyByZW1vdmUgZHVwbGljYXRlc1xuICAgICAgICB2YXIgcnVsZUNhY2hlID0ge30sXG4gICAgICAgICAgICBydWxlTGlzdCwgcnVsZSwgaTtcblxuICAgICAgICBmb3IgKGkgPSBydWxlcy5sZW5ndGggLSAxOyBpID49IDAgOyBpLS0pIHtcbiAgICAgICAgICAgIHJ1bGUgPSBydWxlc1tpXTtcbiAgICAgICAgICAgIGlmIChydWxlIGluc3RhbmNlb2YgdHJlZS5SdWxlKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFydWxlQ2FjaGVbcnVsZS5uYW1lXSkge1xuICAgICAgICAgICAgICAgICAgICBydWxlQ2FjaGVbcnVsZS5uYW1lXSA9IHJ1bGU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcnVsZUxpc3QgPSBydWxlQ2FjaGVbcnVsZS5uYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJ1bGVMaXN0IGluc3RhbmNlb2YgdHJlZS5SdWxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBydWxlTGlzdCA9IHJ1bGVDYWNoZVtydWxlLm5hbWVdID0gW3J1bGVDYWNoZVtydWxlLm5hbWVdLnRvQ1NTKHRoaXMuX2NvbnRleHQpXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB2YXIgcnVsZUNTUyA9IHJ1bGUudG9DU1ModGhpcy5fY29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChydWxlTGlzdC5pbmRleE9mKHJ1bGVDU1MpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcnVsZXMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcnVsZUxpc3QucHVzaChydWxlQ1NTKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBfbWVyZ2VSdWxlczogZnVuY3Rpb24gKHJ1bGVzKSB7XG4gICAgICAgIGlmICghcnVsZXMpIHsgcmV0dXJuOyB9XG5cbiAgICAgICAgdmFyIGdyb3VwcyA9IHt9LFxuICAgICAgICAgICAgcGFydHMsXG4gICAgICAgICAgICBydWxlLFxuICAgICAgICAgICAga2V5O1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcnVsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHJ1bGUgPSBydWxlc1tpXTtcblxuICAgICAgICAgICAgaWYgKChydWxlIGluc3RhbmNlb2YgdHJlZS5SdWxlKSAmJiBydWxlLm1lcmdlKSB7XG4gICAgICAgICAgICAgICAga2V5ID0gW3J1bGUubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgcnVsZS5pbXBvcnRhbnQgPyBcIiFcIiA6IFwiXCJdLmpvaW4oXCIsXCIpO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFncm91cHNba2V5XSkge1xuICAgICAgICAgICAgICAgICAgICBncm91cHNba2V5XSA9IFtdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJ1bGVzLnNwbGljZShpLS0sIDEpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGdyb3Vwc1trZXldLnB1c2gocnVsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBPYmplY3Qua2V5cyhncm91cHMpLm1hcChmdW5jdGlvbiAoaykge1xuXG4gICAgICAgICAgICBmdW5jdGlvbiB0b0V4cHJlc3Npb24odmFsdWVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyAodHJlZS5FeHByZXNzaW9uKSh2YWx1ZXMubWFwKGZ1bmN0aW9uIChwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwLnZhbHVlO1xuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZnVuY3Rpb24gdG9WYWx1ZSh2YWx1ZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3ICh0cmVlLlZhbHVlKSh2YWx1ZXMubWFwKGZ1bmN0aW9uIChwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwO1xuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcGFydHMgPSBncm91cHNba107XG5cbiAgICAgICAgICAgIGlmIChwYXJ0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgcnVsZSA9IHBhcnRzWzBdO1xuICAgICAgICAgICAgICAgIHZhciBzcGFjZWRHcm91cHMgPSBbXTtcbiAgICAgICAgICAgICAgICB2YXIgbGFzdFNwYWNlZEdyb3VwID0gW107XG4gICAgICAgICAgICAgICAgcGFydHMubWFwKGZ1bmN0aW9uIChwKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwLm1lcmdlID09PSBcIitcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RTcGFjZWRHcm91cC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BhY2VkR3JvdXBzLnB1c2godG9FeHByZXNzaW9uKGxhc3RTcGFjZWRHcm91cCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFNwYWNlZEdyb3VwID0gW107XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbGFzdFNwYWNlZEdyb3VwLnB1c2gocCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgc3BhY2VkR3JvdXBzLnB1c2godG9FeHByZXNzaW9uKGxhc3RTcGFjZWRHcm91cCkpO1xuICAgICAgICAgICAgICAgIHJ1bGUudmFsdWUgPSB0b1ZhbHVlKHNwYWNlZEdyb3Vwcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICB2aXNpdEFub255bW91czogZnVuY3Rpb24oYW5vbnltb3VzTm9kZSwgdmlzaXRBcmdzKSB7XG4gICAgICAgIGlmIChhbm9ueW1vdXNOb2RlLmJsb2Nrc1Zpc2liaWxpdHkoKSkge1xuICAgICAgICAgICAgcmV0dXJuIDtcbiAgICAgICAgfVxuICAgICAgICBhbm9ueW1vdXNOb2RlLmFjY2VwdCh0aGlzLl92aXNpdG9yKTtcbiAgICAgICAgcmV0dXJuIGFub255bW91c05vZGU7XG4gICAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBUb0NTU1Zpc2l0b3I7XG5cbn0se1wiLi4vdHJlZVwiOjYyLFwiLi92aXNpdG9yXCI6OTF9XSw5MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgdHJlZSA9IHJlcXVpcmUoXCIuLi90cmVlXCIpO1xuXG52YXIgX3Zpc2l0QXJncyA9IHsgdmlzaXREZWVwZXI6IHRydWUgfSxcbiAgICBfaGFzSW5kZXhlZCA9IGZhbHNlO1xuXG5mdW5jdGlvbiBfbm9vcChub2RlKSB7XG4gICAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIGluZGV4Tm9kZVR5cGVzKHBhcmVudCwgdGlja2VyKSB7XG4gICAgLy8gYWRkIC50eXBlSW5kZXggdG8gdHJlZSBub2RlIHR5cGVzIGZvciBsb29rdXAgdGFibGVcbiAgICB2YXIga2V5LCBjaGlsZDtcbiAgICBmb3IgKGtleSBpbiBwYXJlbnQpIHtcbiAgICAgICAgaWYgKHBhcmVudC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICBjaGlsZCA9IHBhcmVudFtrZXldO1xuICAgICAgICAgICAgc3dpdGNoICh0eXBlb2YgY2hpbGQpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwiZnVuY3Rpb25cIjpcbiAgICAgICAgICAgICAgICAgICAgLy8gaWdub3JlIGJvdW5kIGZ1bmN0aW9ucyBkaXJlY3RseSBvbiB0cmVlIHdoaWNoIGRvIG5vdCBoYXZlIGEgcHJvdG90eXBlXG4gICAgICAgICAgICAgICAgICAgIC8vIG9yIGFyZW4ndCBub2Rlc1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQucHJvdG90eXBlICYmIGNoaWxkLnByb3RvdHlwZS50eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5wcm90b3R5cGUudHlwZUluZGV4ID0gdGlja2VyKys7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgICAgICAgICAgICB0aWNrZXIgPSBpbmRleE5vZGVUeXBlcyhjaGlsZCwgdGlja2VyKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRpY2tlcjtcbn1cblxudmFyIFZpc2l0b3IgPSBmdW5jdGlvbihpbXBsZW1lbnRhdGlvbikge1xuICAgIHRoaXMuX2ltcGxlbWVudGF0aW9uID0gaW1wbGVtZW50YXRpb247XG4gICAgdGhpcy5fdmlzaXRGbkNhY2hlID0gW107XG5cbiAgICBpZiAoIV9oYXNJbmRleGVkKSB7XG4gICAgICAgIGluZGV4Tm9kZVR5cGVzKHRyZWUsIDEpO1xuICAgICAgICBfaGFzSW5kZXhlZCA9IHRydWU7XG4gICAgfVxufTtcblxuVmlzaXRvci5wcm90b3R5cGUgPSB7XG4gICAgdmlzaXQ6IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgaWYgKCFub2RlKSB7XG4gICAgICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBub2RlVHlwZUluZGV4ID0gbm9kZS50eXBlSW5kZXg7XG4gICAgICAgIGlmICghbm9kZVR5cGVJbmRleCkge1xuICAgICAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdmlzaXRGbkNhY2hlID0gdGhpcy5fdmlzaXRGbkNhY2hlLFxuICAgICAgICAgICAgaW1wbCA9IHRoaXMuX2ltcGxlbWVudGF0aW9uLFxuICAgICAgICAgICAgYXJ5SW5keCA9IG5vZGVUeXBlSW5kZXggPDwgMSxcbiAgICAgICAgICAgIG91dEFyeUluZGV4ID0gYXJ5SW5keCB8IDEsXG4gICAgICAgICAgICBmdW5jID0gdmlzaXRGbkNhY2hlW2FyeUluZHhdLFxuICAgICAgICAgICAgZnVuY091dCA9IHZpc2l0Rm5DYWNoZVtvdXRBcnlJbmRleF0sXG4gICAgICAgICAgICB2aXNpdEFyZ3MgPSBfdmlzaXRBcmdzLFxuICAgICAgICAgICAgZm5OYW1lO1xuXG4gICAgICAgIHZpc2l0QXJncy52aXNpdERlZXBlciA9IHRydWU7XG5cbiAgICAgICAgaWYgKCFmdW5jKSB7XG4gICAgICAgICAgICBmbk5hbWUgPSBcInZpc2l0XCIgKyBub2RlLnR5cGU7XG4gICAgICAgICAgICBmdW5jID0gaW1wbFtmbk5hbWVdIHx8IF9ub29wO1xuICAgICAgICAgICAgZnVuY091dCA9IGltcGxbZm5OYW1lICsgXCJPdXRcIl0gfHwgX25vb3A7XG4gICAgICAgICAgICB2aXNpdEZuQ2FjaGVbYXJ5SW5keF0gPSBmdW5jO1xuICAgICAgICAgICAgdmlzaXRGbkNhY2hlW291dEFyeUluZGV4XSA9IGZ1bmNPdXQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZnVuYyAhPT0gX25vb3ApIHtcbiAgICAgICAgICAgIHZhciBuZXdOb2RlID0gZnVuYy5jYWxsKGltcGwsIG5vZGUsIHZpc2l0QXJncyk7XG4gICAgICAgICAgICBpZiAoaW1wbC5pc1JlcGxhY2luZykge1xuICAgICAgICAgICAgICAgIG5vZGUgPSBuZXdOb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZpc2l0QXJncy52aXNpdERlZXBlciAmJiBub2RlICYmIG5vZGUuYWNjZXB0KSB7XG4gICAgICAgICAgICBub2RlLmFjY2VwdCh0aGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmdW5jT3V0ICE9IF9ub29wKSB7XG4gICAgICAgICAgICBmdW5jT3V0LmNhbGwoaW1wbCwgbm9kZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICB9LFxuICAgIHZpc2l0QXJyYXk6IGZ1bmN0aW9uKG5vZGVzLCBub25SZXBsYWNpbmcpIHtcbiAgICAgICAgaWYgKCFub2Rlcykge1xuICAgICAgICAgICAgcmV0dXJuIG5vZGVzO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNudCA9IG5vZGVzLmxlbmd0aCwgaTtcblxuICAgICAgICAvLyBOb24tcmVwbGFjaW5nXG4gICAgICAgIGlmIChub25SZXBsYWNpbmcgfHwgIXRoaXMuX2ltcGxlbWVudGF0aW9uLmlzUmVwbGFjaW5nKSB7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY250OyBpKyspIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpc2l0KG5vZGVzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBub2RlcztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlcGxhY2luZ1xuICAgICAgICB2YXIgb3V0ID0gW107XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjbnQ7IGkrKykge1xuICAgICAgICAgICAgdmFyIGV2YWxkID0gdGhpcy52aXNpdChub2Rlc1tpXSk7XG4gICAgICAgICAgICBpZiAoZXZhbGQgPT09IHVuZGVmaW5lZCkgeyBjb250aW51ZTsgfVxuICAgICAgICAgICAgaWYgKCFldmFsZC5zcGxpY2UpIHtcbiAgICAgICAgICAgICAgICBvdXQucHVzaChldmFsZCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGV2YWxkLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZmxhdHRlbihldmFsZCwgb3V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0O1xuICAgIH0sXG4gICAgZmxhdHRlbjogZnVuY3Rpb24oYXJyLCBvdXQpIHtcbiAgICAgICAgaWYgKCFvdXQpIHtcbiAgICAgICAgICAgIG91dCA9IFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNudCwgaSwgaXRlbSxcbiAgICAgICAgICAgIG5lc3RlZENudCwgaiwgbmVzdGVkSXRlbTtcblxuICAgICAgICBmb3IgKGkgPSAwLCBjbnQgPSBhcnIubGVuZ3RoOyBpIDwgY250OyBpKyspIHtcbiAgICAgICAgICAgIGl0ZW0gPSBhcnJbaV07XG4gICAgICAgICAgICBpZiAoaXRlbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWl0ZW0uc3BsaWNlKSB7XG4gICAgICAgICAgICAgICAgb3V0LnB1c2goaXRlbSk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAoaiA9IDAsIG5lc3RlZENudCA9IGl0ZW0ubGVuZ3RoOyBqIDwgbmVzdGVkQ250OyBqKyspIHtcbiAgICAgICAgICAgICAgICBuZXN0ZWRJdGVtID0gaXRlbVtqXTtcbiAgICAgICAgICAgICAgICBpZiAobmVzdGVkSXRlbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIW5lc3RlZEl0ZW0uc3BsaWNlKSB7XG4gICAgICAgICAgICAgICAgICAgIG91dC5wdXNoKG5lc3RlZEl0ZW0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobmVzdGVkSXRlbS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mbGF0dGVuKG5lc3RlZEl0ZW0sIG91dCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICB9XG59O1xubW9kdWxlLmV4cG9ydHMgPSBWaXNpdG9yO1xuXG59LHtcIi4uL3RyZWVcIjo2Mn1dLDkyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcblwidXNlIHN0cmljdFwiO1xuXG4vLyByYXdBc2FwIHByb3ZpZGVzIGV2ZXJ5dGhpbmcgd2UgbmVlZCBleGNlcHQgZXhjZXB0aW9uIG1hbmFnZW1lbnQuXG52YXIgcmF3QXNhcCA9IHJlcXVpcmUoXCIuL3Jhd1wiKTtcbi8vIFJhd1Rhc2tzIGFyZSByZWN5Y2xlZCB0byByZWR1Y2UgR0MgY2h1cm4uXG52YXIgZnJlZVRhc2tzID0gW107XG4vLyBXZSBxdWV1ZSBlcnJvcnMgdG8gZW5zdXJlIHRoZXkgYXJlIHRocm93biBpbiByaWdodCBvcmRlciAoRklGTykuXG4vLyBBcnJheS1hcy1xdWV1ZSBpcyBnb29kIGVub3VnaCBoZXJlLCBzaW5jZSB3ZSBhcmUganVzdCBkZWFsaW5nIHdpdGggZXhjZXB0aW9ucy5cbnZhciBwZW5kaW5nRXJyb3JzID0gW107XG52YXIgcmVxdWVzdEVycm9yVGhyb3cgPSByYXdBc2FwLm1ha2VSZXF1ZXN0Q2FsbEZyb21UaW1lcih0aHJvd0ZpcnN0RXJyb3IpO1xuXG5mdW5jdGlvbiB0aHJvd0ZpcnN0RXJyb3IoKSB7XG4gICAgaWYgKHBlbmRpbmdFcnJvcnMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IHBlbmRpbmdFcnJvcnMuc2hpZnQoKTtcbiAgICB9XG59XG5cbi8qKlxuICogQ2FsbHMgYSB0YXNrIGFzIHNvb24gYXMgcG9zc2libGUgYWZ0ZXIgcmV0dXJuaW5nLCBpbiBpdHMgb3duIGV2ZW50LCB3aXRoIHByaW9yaXR5XG4gKiBvdmVyIG90aGVyIGV2ZW50cyBsaWtlIGFuaW1hdGlvbiwgcmVmbG93LCBhbmQgcmVwYWludC4gQW4gZXJyb3IgdGhyb3duIGZyb20gYW5cbiAqIGV2ZW50IHdpbGwgbm90IGludGVycnVwdCwgbm9yIGV2ZW4gc3Vic3RhbnRpYWxseSBzbG93IGRvd24gdGhlIHByb2Nlc3Npbmcgb2ZcbiAqIG90aGVyIGV2ZW50cywgYnV0IHdpbGwgYmUgcmF0aGVyIHBvc3Rwb25lZCB0byBhIGxvd2VyIHByaW9yaXR5IGV2ZW50LlxuICogQHBhcmFtIHt7Y2FsbH19IHRhc2sgQSBjYWxsYWJsZSBvYmplY3QsIHR5cGljYWxseSBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgbm9cbiAqIGFyZ3VtZW50cy5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBhc2FwO1xuZnVuY3Rpb24gYXNhcCh0YXNrKSB7XG4gICAgdmFyIHJhd1Rhc2s7XG4gICAgaWYgKGZyZWVUYXNrcy5sZW5ndGgpIHtcbiAgICAgICAgcmF3VGFzayA9IGZyZWVUYXNrcy5wb3AoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByYXdUYXNrID0gbmV3IFJhd1Rhc2soKTtcbiAgICB9XG4gICAgcmF3VGFzay50YXNrID0gdGFzaztcbiAgICByYXdBc2FwKHJhd1Rhc2spO1xufVxuXG4vLyBXZSB3cmFwIHRhc2tzIHdpdGggcmVjeWNsYWJsZSB0YXNrIG9iamVjdHMuICBBIHRhc2sgb2JqZWN0IGltcGxlbWVudHNcbi8vIGBjYWxsYCwganVzdCBsaWtlIGEgZnVuY3Rpb24uXG5mdW5jdGlvbiBSYXdUYXNrKCkge1xuICAgIHRoaXMudGFzayA9IG51bGw7XG59XG5cbi8vIFRoZSBzb2xlIHB1cnBvc2Ugb2Ygd3JhcHBpbmcgdGhlIHRhc2sgaXMgdG8gY2F0Y2ggdGhlIGV4Y2VwdGlvbiBhbmQgcmVjeWNsZVxuLy8gdGhlIHRhc2sgb2JqZWN0IGFmdGVyIGl0cyBzaW5nbGUgdXNlLlxuUmF3VGFzay5wcm90b3R5cGUuY2FsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICB0aGlzLnRhc2suY2FsbCgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmIChhc2FwLm9uZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIFRoaXMgaG9vayBleGlzdHMgcHVyZWx5IGZvciB0ZXN0aW5nIHB1cnBvc2VzLlxuICAgICAgICAgICAgLy8gSXRzIG5hbWUgd2lsbCBiZSBwZXJpb2RpY2FsbHkgcmFuZG9taXplZCB0byBicmVhayBhbnkgY29kZSB0aGF0XG4gICAgICAgICAgICAvLyBkZXBlbmRzIG9uIGl0cyBleGlzdGVuY2UuXG4gICAgICAgICAgICBhc2FwLm9uZXJyb3IoZXJyb3IpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSW4gYSB3ZWIgYnJvd3NlciwgZXhjZXB0aW9ucyBhcmUgbm90IGZhdGFsLiBIb3dldmVyLCB0byBhdm9pZFxuICAgICAgICAgICAgLy8gc2xvd2luZyBkb3duIHRoZSBxdWV1ZSBvZiBwZW5kaW5nIHRhc2tzLCB3ZSByZXRocm93IHRoZSBlcnJvciBpbiBhXG4gICAgICAgICAgICAvLyBsb3dlciBwcmlvcml0eSB0dXJuLlxuICAgICAgICAgICAgcGVuZGluZ0Vycm9ycy5wdXNoKGVycm9yKTtcbiAgICAgICAgICAgIHJlcXVlc3RFcnJvclRocm93KCk7XG4gICAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgICB0aGlzLnRhc2sgPSBudWxsO1xuICAgICAgICBmcmVlVGFza3NbZnJlZVRhc2tzLmxlbmd0aF0gPSB0aGlzO1xuICAgIH1cbn07XG5cbn0se1wiLi9yYXdcIjo5M31dLDkzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbihmdW5jdGlvbiAoZ2xvYmFsKXtcblwidXNlIHN0cmljdFwiO1xuXG4vLyBVc2UgdGhlIGZhc3Rlc3QgbWVhbnMgcG9zc2libGUgdG8gZXhlY3V0ZSBhIHRhc2sgaW4gaXRzIG93biB0dXJuLCB3aXRoXG4vLyBwcmlvcml0eSBvdmVyIG90aGVyIGV2ZW50cyBpbmNsdWRpbmcgSU8sIGFuaW1hdGlvbiwgcmVmbG93LCBhbmQgcmVkcmF3XG4vLyBldmVudHMgaW4gYnJvd3NlcnMuXG4vL1xuLy8gQW4gZXhjZXB0aW9uIHRocm93biBieSBhIHRhc2sgd2lsbCBwZXJtYW5lbnRseSBpbnRlcnJ1cHQgdGhlIHByb2Nlc3Npbmcgb2Zcbi8vIHN1YnNlcXVlbnQgdGFza3MuIFRoZSBoaWdoZXIgbGV2ZWwgYGFzYXBgIGZ1bmN0aW9uIGVuc3VyZXMgdGhhdCBpZiBhblxuLy8gZXhjZXB0aW9uIGlzIHRocm93biBieSBhIHRhc2ssIHRoYXQgdGhlIHRhc2sgcXVldWUgd2lsbCBjb250aW51ZSBmbHVzaGluZyBhc1xuLy8gc29vbiBhcyBwb3NzaWJsZSwgYnV0IGlmIHlvdSB1c2UgYHJhd0FzYXBgIGRpcmVjdGx5LCB5b3UgYXJlIHJlc3BvbnNpYmxlIHRvXG4vLyBlaXRoZXIgZW5zdXJlIHRoYXQgbm8gZXhjZXB0aW9ucyBhcmUgdGhyb3duIGZyb20geW91ciB0YXNrLCBvciB0byBtYW51YWxseVxuLy8gY2FsbCBgcmF3QXNhcC5yZXF1ZXN0Rmx1c2hgIGlmIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24uXG5tb2R1bGUuZXhwb3J0cyA9IHJhd0FzYXA7XG5mdW5jdGlvbiByYXdBc2FwKHRhc2spIHtcbiAgICBpZiAoIXF1ZXVlLmxlbmd0aCkge1xuICAgICAgICByZXF1ZXN0Rmx1c2goKTtcbiAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgIH1cbiAgICAvLyBFcXVpdmFsZW50IHRvIHB1c2gsIGJ1dCBhdm9pZHMgYSBmdW5jdGlvbiBjYWxsLlxuICAgIHF1ZXVlW3F1ZXVlLmxlbmd0aF0gPSB0YXNrO1xufVxuXG52YXIgcXVldWUgPSBbXTtcbi8vIE9uY2UgYSBmbHVzaCBoYXMgYmVlbiByZXF1ZXN0ZWQsIG5vIGZ1cnRoZXIgY2FsbHMgdG8gYHJlcXVlc3RGbHVzaGAgYXJlXG4vLyBuZWNlc3NhcnkgdW50aWwgdGhlIG5leHQgYGZsdXNoYCBjb21wbGV0ZXMuXG52YXIgZmx1c2hpbmcgPSBmYWxzZTtcbi8vIGByZXF1ZXN0Rmx1c2hgIGlzIGFuIGltcGxlbWVudGF0aW9uLXNwZWNpZmljIG1ldGhvZCB0aGF0IGF0dGVtcHRzIHRvIGtpY2tcbi8vIG9mZiBhIGBmbHVzaGAgZXZlbnQgYXMgcXVpY2tseSBhcyBwb3NzaWJsZS4gYGZsdXNoYCB3aWxsIGF0dGVtcHQgdG8gZXhoYXVzdFxuLy8gdGhlIGV2ZW50IHF1ZXVlIGJlZm9yZSB5aWVsZGluZyB0byB0aGUgYnJvd3NlcidzIG93biBldmVudCBsb29wLlxudmFyIHJlcXVlc3RGbHVzaDtcbi8vIFRoZSBwb3NpdGlvbiBvZiB0aGUgbmV4dCB0YXNrIHRvIGV4ZWN1dGUgaW4gdGhlIHRhc2sgcXVldWUuIFRoaXMgaXNcbi8vIHByZXNlcnZlZCBiZXR3ZWVuIGNhbGxzIHRvIGBmbHVzaGAgc28gdGhhdCBpdCBjYW4gYmUgcmVzdW1lZCBpZlxuLy8gYSB0YXNrIHRocm93cyBhbiBleGNlcHRpb24uXG52YXIgaW5kZXggPSAwO1xuLy8gSWYgYSB0YXNrIHNjaGVkdWxlcyBhZGRpdGlvbmFsIHRhc2tzIHJlY3Vyc2l2ZWx5LCB0aGUgdGFzayBxdWV1ZSBjYW4gZ3Jvd1xuLy8gdW5ib3VuZGVkLiBUbyBwcmV2ZW50IG1lbW9yeSBleGhhdXN0aW9uLCB0aGUgdGFzayBxdWV1ZSB3aWxsIHBlcmlvZGljYWxseVxuLy8gdHJ1bmNhdGUgYWxyZWFkeS1jb21wbGV0ZWQgdGFza3MuXG52YXIgY2FwYWNpdHkgPSAxMDI0O1xuXG4vLyBUaGUgZmx1c2ggZnVuY3Rpb24gcHJvY2Vzc2VzIGFsbCB0YXNrcyB0aGF0IGhhdmUgYmVlbiBzY2hlZHVsZWQgd2l0aFxuLy8gYHJhd0FzYXBgIHVubGVzcyBhbmQgdW50aWwgb25lIG9mIHRob3NlIHRhc2tzIHRocm93cyBhbiBleGNlcHRpb24uXG4vLyBJZiBhIHRhc2sgdGhyb3dzIGFuIGV4Y2VwdGlvbiwgYGZsdXNoYCBlbnN1cmVzIHRoYXQgaXRzIHN0YXRlIHdpbGwgcmVtYWluXG4vLyBjb25zaXN0ZW50IGFuZCB3aWxsIHJlc3VtZSB3aGVyZSBpdCBsZWZ0IG9mZiB3aGVuIGNhbGxlZCBhZ2Fpbi5cbi8vIEhvd2V2ZXIsIGBmbHVzaGAgZG9lcyBub3QgbWFrZSBhbnkgYXJyYW5nZW1lbnRzIHRvIGJlIGNhbGxlZCBhZ2FpbiBpZiBhblxuLy8gZXhjZXB0aW9uIGlzIHRocm93bi5cbmZ1bmN0aW9uIGZsdXNoKCkge1xuICAgIHdoaWxlIChpbmRleCA8IHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICB2YXIgY3VycmVudEluZGV4ID0gaW5kZXg7XG4gICAgICAgIC8vIEFkdmFuY2UgdGhlIGluZGV4IGJlZm9yZSBjYWxsaW5nIHRoZSB0YXNrLiBUaGlzIGVuc3VyZXMgdGhhdCB3ZSB3aWxsXG4gICAgICAgIC8vIGJlZ2luIGZsdXNoaW5nIG9uIHRoZSBuZXh0IHRhc2sgdGhlIHRhc2sgdGhyb3dzIGFuIGVycm9yLlxuICAgICAgICBpbmRleCA9IGluZGV4ICsgMTtcbiAgICAgICAgcXVldWVbY3VycmVudEluZGV4XS5jYWxsKCk7XG4gICAgICAgIC8vIFByZXZlbnQgbGVha2luZyBtZW1vcnkgZm9yIGxvbmcgY2hhaW5zIG9mIHJlY3Vyc2l2ZSBjYWxscyB0byBgYXNhcGAuXG4gICAgICAgIC8vIElmIHdlIGNhbGwgYGFzYXBgIHdpdGhpbiB0YXNrcyBzY2hlZHVsZWQgYnkgYGFzYXBgLCB0aGUgcXVldWUgd2lsbFxuICAgICAgICAvLyBncm93LCBidXQgdG8gYXZvaWQgYW4gTyhuKSB3YWxrIGZvciBldmVyeSB0YXNrIHdlIGV4ZWN1dGUsIHdlIGRvbid0XG4gICAgICAgIC8vIHNoaWZ0IHRhc2tzIG9mZiB0aGUgcXVldWUgYWZ0ZXIgdGhleSBoYXZlIGJlZW4gZXhlY3V0ZWQuXG4gICAgICAgIC8vIEluc3RlYWQsIHdlIHBlcmlvZGljYWxseSBzaGlmdCAxMDI0IHRhc2tzIG9mZiB0aGUgcXVldWUuXG4gICAgICAgIGlmIChpbmRleCA+IGNhcGFjaXR5KSB7XG4gICAgICAgICAgICAvLyBNYW51YWxseSBzaGlmdCBhbGwgdmFsdWVzIHN0YXJ0aW5nIGF0IHRoZSBpbmRleCBiYWNrIHRvIHRoZVxuICAgICAgICAgICAgLy8gYmVnaW5uaW5nIG9mIHRoZSBxdWV1ZS5cbiAgICAgICAgICAgIGZvciAodmFyIHNjYW4gPSAwLCBuZXdMZW5ndGggPSBxdWV1ZS5sZW5ndGggLSBpbmRleDsgc2NhbiA8IG5ld0xlbmd0aDsgc2NhbisrKSB7XG4gICAgICAgICAgICAgICAgcXVldWVbc2Nhbl0gPSBxdWV1ZVtzY2FuICsgaW5kZXhdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcXVldWUubGVuZ3RoIC09IGluZGV4O1xuICAgICAgICAgICAgaW5kZXggPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLmxlbmd0aCA9IDA7XG4gICAgaW5kZXggPSAwO1xuICAgIGZsdXNoaW5nID0gZmFsc2U7XG59XG5cbi8vIGByZXF1ZXN0Rmx1c2hgIGlzIGltcGxlbWVudGVkIHVzaW5nIGEgc3RyYXRlZ3kgYmFzZWQgb24gZGF0YSBjb2xsZWN0ZWQgZnJvbVxuLy8gZXZlcnkgYXZhaWxhYmxlIFNhdWNlTGFicyBTZWxlbml1bSB3ZWIgZHJpdmVyIHdvcmtlciBhdCB0aW1lIG9mIHdyaXRpbmcuXG4vLyBodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xbUctNVVZR3VwNXF4R2RFTVdraFA2QldDejA1M05VYjJFMVFvVVRVMTZ1QS9lZGl0I2dpZD03ODM3MjQ1OTNcblxuLy8gU2FmYXJpIDYgYW5kIDYuMSBmb3IgZGVza3RvcCwgaVBhZCwgYW5kIGlQaG9uZSBhcmUgdGhlIG9ubHkgYnJvd3NlcnMgdGhhdFxuLy8gaGF2ZSBXZWJLaXRNdXRhdGlvbk9ic2VydmVyIGJ1dCBub3QgdW4tcHJlZml4ZWQgTXV0YXRpb25PYnNlcnZlci5cbi8vIE11c3QgdXNlIGBnbG9iYWxgIGluc3RlYWQgb2YgYHdpbmRvd2AgdG8gd29yayBpbiBib3RoIGZyYW1lcyBhbmQgd2ViXG4vLyB3b3JrZXJzLiBgZ2xvYmFsYCBpcyBhIHByb3Zpc2lvbiBvZiBCcm93c2VyaWZ5LCBNciwgTXJzLCBvciBNb3AuXG52YXIgQnJvd3Nlck11dGF0aW9uT2JzZXJ2ZXIgPSBnbG9iYWwuTXV0YXRpb25PYnNlcnZlciB8fCBnbG9iYWwuV2ViS2l0TXV0YXRpb25PYnNlcnZlcjtcblxuLy8gTXV0YXRpb25PYnNlcnZlcnMgYXJlIGRlc2lyYWJsZSBiZWNhdXNlIHRoZXkgaGF2ZSBoaWdoIHByaW9yaXR5IGFuZCB3b3JrXG4vLyByZWxpYWJseSBldmVyeXdoZXJlIHRoZXkgYXJlIGltcGxlbWVudGVkLlxuLy8gVGhleSBhcmUgaW1wbGVtZW50ZWQgaW4gYWxsIG1vZGVybiBicm93c2Vycy5cbi8vXG4vLyAtIEFuZHJvaWQgNC00LjNcbi8vIC0gQ2hyb21lIDI2LTM0XG4vLyAtIEZpcmVmb3ggMTQtMjlcbi8vIC0gSW50ZXJuZXQgRXhwbG9yZXIgMTFcbi8vIC0gaVBhZCBTYWZhcmkgNi03LjFcbi8vIC0gaVBob25lIFNhZmFyaSA3LTcuMVxuLy8gLSBTYWZhcmkgNi03XG5pZiAodHlwZW9mIEJyb3dzZXJNdXRhdGlvbk9ic2VydmVyID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICByZXF1ZXN0Rmx1c2ggPSBtYWtlUmVxdWVzdENhbGxGcm9tTXV0YXRpb25PYnNlcnZlcihmbHVzaCk7XG5cbi8vIE1lc3NhZ2VDaGFubmVscyBhcmUgZGVzaXJhYmxlIGJlY2F1c2UgdGhleSBnaXZlIGRpcmVjdCBhY2Nlc3MgdG8gdGhlIEhUTUxcbi8vIHRhc2sgcXVldWUsIGFyZSBpbXBsZW1lbnRlZCBpbiBJbnRlcm5ldCBFeHBsb3JlciAxMCwgU2FmYXJpIDUuMC0xLCBhbmQgT3BlcmFcbi8vIDExLTEyLCBhbmQgaW4gd2ViIHdvcmtlcnMgaW4gbWFueSBlbmdpbmVzLlxuLy8gQWx0aG91Z2ggbWVzc2FnZSBjaGFubmVscyB5aWVsZCB0byBhbnkgcXVldWVkIHJlbmRlcmluZyBhbmQgSU8gdGFza3MsIHRoZXlcbi8vIHdvdWxkIGJlIGJldHRlciB0aGFuIGltcG9zaW5nIHRoZSA0bXMgZGVsYXkgb2YgdGltZXJzLlxuLy8gSG93ZXZlciwgdGhleSBkbyBub3Qgd29yayByZWxpYWJseSBpbiBJbnRlcm5ldCBFeHBsb3JlciBvciBTYWZhcmkuXG5cbi8vIEludGVybmV0IEV4cGxvcmVyIDEwIGlzIHRoZSBvbmx5IGJyb3dzZXIgdGhhdCBoYXMgc2V0SW1tZWRpYXRlIGJ1dCBkb2VzXG4vLyBub3QgaGF2ZSBNdXRhdGlvbk9ic2VydmVycy5cbi8vIEFsdGhvdWdoIHNldEltbWVkaWF0ZSB5aWVsZHMgdG8gdGhlIGJyb3dzZXIncyByZW5kZXJlciwgaXQgd291bGQgYmVcbi8vIHByZWZlcnJhYmxlIHRvIGZhbGxpbmcgYmFjayB0byBzZXRUaW1lb3V0IHNpbmNlIGl0IGRvZXMgbm90IGhhdmVcbi8vIHRoZSBtaW5pbXVtIDRtcyBwZW5hbHR5LlxuLy8gVW5mb3J0dW5hdGVseSB0aGVyZSBhcHBlYXJzIHRvIGJlIGEgYnVnIGluIEludGVybmV0IEV4cGxvcmVyIDEwIE1vYmlsZSAoYW5kXG4vLyBEZXNrdG9wIHRvIGEgbGVzc2VyIGV4dGVudCkgdGhhdCByZW5kZXJzIGJvdGggc2V0SW1tZWRpYXRlIGFuZFxuLy8gTWVzc2FnZUNoYW5uZWwgdXNlbGVzcyBmb3IgdGhlIHB1cnBvc2VzIG9mIEFTQVAuXG4vLyBodHRwczovL2dpdGh1Yi5jb20va3Jpc2tvd2FsL3EvaXNzdWVzLzM5NlxuXG4vLyBUaW1lcnMgYXJlIGltcGxlbWVudGVkIHVuaXZlcnNhbGx5LlxuLy8gV2UgZmFsbCBiYWNrIHRvIHRpbWVycyBpbiB3b3JrZXJzIGluIG1vc3QgZW5naW5lcywgYW5kIGluIGZvcmVncm91bmRcbi8vIGNvbnRleHRzIGluIHRoZSBmb2xsb3dpbmcgYnJvd3NlcnMuXG4vLyBIb3dldmVyLCBub3RlIHRoYXQgZXZlbiB0aGlzIHNpbXBsZSBjYXNlIHJlcXVpcmVzIG51YW5jZXMgdG8gb3BlcmF0ZSBpbiBhXG4vLyBicm9hZCBzcGVjdHJ1bSBvZiBicm93c2Vycy5cbi8vXG4vLyAtIEZpcmVmb3ggMy0xM1xuLy8gLSBJbnRlcm5ldCBFeHBsb3JlciA2LTlcbi8vIC0gaVBhZCBTYWZhcmkgNC4zXG4vLyAtIEx5bnggMi44Ljdcbn0gZWxzZSB7XG4gICAgcmVxdWVzdEZsdXNoID0gbWFrZVJlcXVlc3RDYWxsRnJvbVRpbWVyKGZsdXNoKTtcbn1cblxuLy8gYHJlcXVlc3RGbHVzaGAgcmVxdWVzdHMgdGhhdCB0aGUgaGlnaCBwcmlvcml0eSBldmVudCBxdWV1ZSBiZSBmbHVzaGVkIGFzXG4vLyBzb29uIGFzIHBvc3NpYmxlLlxuLy8gVGhpcyBpcyB1c2VmdWwgdG8gcHJldmVudCBhbiBlcnJvciB0aHJvd24gaW4gYSB0YXNrIGZyb20gc3RhbGxpbmcgdGhlIGV2ZW50XG4vLyBxdWV1ZSBpZiB0aGUgZXhjZXB0aW9uIGhhbmRsZWQgYnkgTm9kZS5qc+KAmXNcbi8vIGBwcm9jZXNzLm9uKFwidW5jYXVnaHRFeGNlcHRpb25cIilgIG9yIGJ5IGEgZG9tYWluLlxucmF3QXNhcC5yZXF1ZXN0Rmx1c2ggPSByZXF1ZXN0Rmx1c2g7XG5cbi8vIFRvIHJlcXVlc3QgYSBoaWdoIHByaW9yaXR5IGV2ZW50LCB3ZSBpbmR1Y2UgYSBtdXRhdGlvbiBvYnNlcnZlciBieSB0b2dnbGluZ1xuLy8gdGhlIHRleHQgb2YgYSB0ZXh0IG5vZGUgYmV0d2VlbiBcIjFcIiBhbmQgXCItMVwiLlxuZnVuY3Rpb24gbWFrZVJlcXVlc3RDYWxsRnJvbU11dGF0aW9uT2JzZXJ2ZXIoY2FsbGJhY2spIHtcbiAgICB2YXIgdG9nZ2xlID0gMTtcbiAgICB2YXIgb2JzZXJ2ZXIgPSBuZXcgQnJvd3Nlck11dGF0aW9uT2JzZXJ2ZXIoY2FsbGJhY2spO1xuICAgIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoXCJcIik7XG4gICAgb2JzZXJ2ZXIub2JzZXJ2ZShub2RlLCB7Y2hhcmFjdGVyRGF0YTogdHJ1ZX0pO1xuICAgIHJldHVybiBmdW5jdGlvbiByZXF1ZXN0Q2FsbCgpIHtcbiAgICAgICAgdG9nZ2xlID0gLXRvZ2dsZTtcbiAgICAgICAgbm9kZS5kYXRhID0gdG9nZ2xlO1xuICAgIH07XG59XG5cbi8vIFRoZSBtZXNzYWdlIGNoYW5uZWwgdGVjaG5pcXVlIHdhcyBkaXNjb3ZlcmVkIGJ5IE1hbHRlIFVibCBhbmQgd2FzIHRoZVxuLy8gb3JpZ2luYWwgZm91bmRhdGlvbiBmb3IgdGhpcyBsaWJyYXJ5LlxuLy8gaHR0cDovL3d3dy5ub25ibG9ja2luZy5pby8yMDExLzA2L3dpbmRvd25leHR0aWNrLmh0bWxcblxuLy8gU2FmYXJpIDYuMC41IChhdCBsZWFzdCkgaW50ZXJtaXR0ZW50bHkgZmFpbHMgdG8gY3JlYXRlIG1lc3NhZ2UgcG9ydHMgb24gYVxuLy8gcGFnZSdzIGZpcnN0IGxvYWQuIFRoYW5rZnVsbHksIHRoaXMgdmVyc2lvbiBvZiBTYWZhcmkgc3VwcG9ydHNcbi8vIE11dGF0aW9uT2JzZXJ2ZXJzLCBzbyB3ZSBkb24ndCBuZWVkIHRvIGZhbGwgYmFjayBpbiB0aGF0IGNhc2UuXG5cbi8vIGZ1bmN0aW9uIG1ha2VSZXF1ZXN0Q2FsbEZyb21NZXNzYWdlQ2hhbm5lbChjYWxsYmFjaykge1xuLy8gICAgIHZhciBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4vLyAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBjYWxsYmFjaztcbi8vICAgICByZXR1cm4gZnVuY3Rpb24gcmVxdWVzdENhbGwoKSB7XG4vLyAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4vLyAgICAgfTtcbi8vIH1cblxuLy8gRm9yIHJlYXNvbnMgZXhwbGFpbmVkIGFib3ZlLCB3ZSBhcmUgYWxzbyB1bmFibGUgdG8gdXNlIGBzZXRJbW1lZGlhdGVgXG4vLyB1bmRlciBhbnkgY2lyY3Vtc3RhbmNlcy5cbi8vIEV2ZW4gaWYgd2Ugd2VyZSwgdGhlcmUgaXMgYW5vdGhlciBidWcgaW4gSW50ZXJuZXQgRXhwbG9yZXIgMTAuXG4vLyBJdCBpcyBub3Qgc3VmZmljaWVudCB0byBhc3NpZ24gYHNldEltbWVkaWF0ZWAgdG8gYHJlcXVlc3RGbHVzaGAgYmVjYXVzZVxuLy8gYHNldEltbWVkaWF0ZWAgbXVzdCBiZSBjYWxsZWQgKmJ5IG5hbWUqIGFuZCB0aGVyZWZvcmUgbXVzdCBiZSB3cmFwcGVkIGluIGFcbi8vIGNsb3N1cmUuXG4vLyBOZXZlciBmb3JnZXQuXG5cbi8vIGZ1bmN0aW9uIG1ha2VSZXF1ZXN0Q2FsbEZyb21TZXRJbW1lZGlhdGUoY2FsbGJhY2spIHtcbi8vICAgICByZXR1cm4gZnVuY3Rpb24gcmVxdWVzdENhbGwoKSB7XG4vLyAgICAgICAgIHNldEltbWVkaWF0ZShjYWxsYmFjayk7XG4vLyAgICAgfTtcbi8vIH1cblxuLy8gU2FmYXJpIDYuMCBoYXMgYSBwcm9ibGVtIHdoZXJlIHRpbWVycyB3aWxsIGdldCBsb3N0IHdoaWxlIHRoZSB1c2VyIGlzXG4vLyBzY3JvbGxpbmcuIFRoaXMgcHJvYmxlbSBkb2VzIG5vdCBpbXBhY3QgQVNBUCBiZWNhdXNlIFNhZmFyaSA2LjAgc3VwcG9ydHNcbi8vIG11dGF0aW9uIG9ic2VydmVycywgc28gdGhhdCBpbXBsZW1lbnRhdGlvbiBpcyB1c2VkIGluc3RlYWQuXG4vLyBIb3dldmVyLCBpZiB3ZSBldmVyIGVsZWN0IHRvIHVzZSB0aW1lcnMgaW4gU2FmYXJpLCB0aGUgcHJldmFsZW50IHdvcmstYXJvdW5kXG4vLyBpcyB0byBhZGQgYSBzY3JvbGwgZXZlbnQgbGlzdGVuZXIgdGhhdCBjYWxscyBmb3IgYSBmbHVzaC5cblxuLy8gYHNldFRpbWVvdXRgIGRvZXMgbm90IGNhbGwgdGhlIHBhc3NlZCBjYWxsYmFjayBpZiB0aGUgZGVsYXkgaXMgbGVzcyB0aGFuXG4vLyBhcHByb3hpbWF0ZWx5IDcgaW4gd2ViIHdvcmtlcnMgaW4gRmlyZWZveCA4IHRocm91Z2ggMTgsIGFuZCBzb21ldGltZXMgbm90XG4vLyBldmVuIHRoZW4uXG5cbmZ1bmN0aW9uIG1ha2VSZXF1ZXN0Q2FsbEZyb21UaW1lcihjYWxsYmFjaykge1xuICAgIHJldHVybiBmdW5jdGlvbiByZXF1ZXN0Q2FsbCgpIHtcbiAgICAgICAgLy8gV2UgZGlzcGF0Y2ggYSB0aW1lb3V0IHdpdGggYSBzcGVjaWZpZWQgZGVsYXkgb2YgMCBmb3IgZW5naW5lcyB0aGF0XG4gICAgICAgIC8vIGNhbiByZWxpYWJseSBhY2NvbW1vZGF0ZSB0aGF0IHJlcXVlc3QuIFRoaXMgd2lsbCB1c3VhbGx5IGJlIHNuYXBwZWRcbiAgICAgICAgLy8gdG8gYSA0IG1pbGlzZWNvbmQgZGVsYXksIGJ1dCBvbmNlIHdlJ3JlIGZsdXNoaW5nLCB0aGVyZSdzIG5vIGRlbGF5XG4gICAgICAgIC8vIGJldHdlZW4gZXZlbnRzLlxuICAgICAgICB2YXIgdGltZW91dEhhbmRsZSA9IHNldFRpbWVvdXQoaGFuZGxlVGltZXIsIDApO1xuICAgICAgICAvLyBIb3dldmVyLCBzaW5jZSB0aGlzIHRpbWVyIGdldHMgZnJlcXVlbnRseSBkcm9wcGVkIGluIEZpcmVmb3hcbiAgICAgICAgLy8gd29ya2Vycywgd2UgZW5saXN0IGFuIGludGVydmFsIGhhbmRsZSB0aGF0IHdpbGwgdHJ5IHRvIGZpcmVcbiAgICAgICAgLy8gYW4gZXZlbnQgMjAgdGltZXMgcGVyIHNlY29uZCB1bnRpbCBpdCBzdWNjZWVkcy5cbiAgICAgICAgdmFyIGludGVydmFsSGFuZGxlID0gc2V0SW50ZXJ2YWwoaGFuZGxlVGltZXIsIDUwKTtcblxuICAgICAgICBmdW5jdGlvbiBoYW5kbGVUaW1lcigpIHtcbiAgICAgICAgICAgIC8vIFdoaWNoZXZlciB0aW1lciBzdWNjZWVkcyB3aWxsIGNhbmNlbCBib3RoIHRpbWVycyBhbmRcbiAgICAgICAgICAgIC8vIGV4ZWN1dGUgdGhlIGNhbGxiYWNrLlxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRIYW5kbGUpO1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbEhhbmRsZSk7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgfTtcbn1cblxuLy8gVGhpcyBpcyBmb3IgYGFzYXAuanNgIG9ubHkuXG4vLyBJdHMgbmFtZSB3aWxsIGJlIHBlcmlvZGljYWxseSByYW5kb21pemVkIHRvIGJyZWFrIGFueSBjb2RlIHRoYXQgZGVwZW5kcyBvblxuLy8gaXRzIGV4aXN0ZW5jZS5cbnJhd0FzYXAubWFrZVJlcXVlc3RDYWxsRnJvbVRpbWVyID0gbWFrZVJlcXVlc3RDYWxsRnJvbVRpbWVyO1xuXG4vLyBBU0FQIHdhcyBvcmlnaW5hbGx5IGEgbmV4dFRpY2sgc2hpbSBpbmNsdWRlZCBpbiBRLiBUaGlzIHdhcyBmYWN0b3JlZCBvdXRcbi8vIGludG8gdGhpcyBBU0FQIHBhY2thZ2UuIEl0IHdhcyBsYXRlciBhZGFwdGVkIHRvIFJTVlAgd2hpY2ggbWFkZSBmdXJ0aGVyXG4vLyBhbWVuZG1lbnRzLiBUaGVzZSBkZWNpc2lvbnMsIHBhcnRpY3VsYXJseSB0byBtYXJnaW5hbGl6ZSBNZXNzYWdlQ2hhbm5lbCBhbmRcbi8vIHRvIGNhcHR1cmUgdGhlIE11dGF0aW9uT2JzZXJ2ZXIgaW1wbGVtZW50YXRpb24gaW4gYSBjbG9zdXJlLCB3ZXJlIGludGVncmF0ZWRcbi8vIGJhY2sgaW50byBBU0FQIHByb3Blci5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90aWxkZWlvL3JzdnAuanMvYmxvYi9jZGRmNzIzMjU0NmE5Y2Y4NTg1MjRiNzVjZGU2ZjllZGY3MjYyMGE3L2xpYi9yc3ZwL2FzYXAuanNcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG59LHt9XSw5NDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBhc2FwID0gcmVxdWlyZSgnYXNhcC9yYXcnKTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbi8vIFN0YXRlczpcbi8vXG4vLyAwIC0gcGVuZGluZ1xuLy8gMSAtIGZ1bGZpbGxlZCB3aXRoIF92YWx1ZVxuLy8gMiAtIHJlamVjdGVkIHdpdGggX3ZhbHVlXG4vLyAzIC0gYWRvcHRlZCB0aGUgc3RhdGUgb2YgYW5vdGhlciBwcm9taXNlLCBfdmFsdWVcbi8vXG4vLyBvbmNlIHRoZSBzdGF0ZSBpcyBubyBsb25nZXIgcGVuZGluZyAoMCkgaXQgaXMgaW1tdXRhYmxlXG5cbi8vIEFsbCBgX2AgcHJlZml4ZWQgcHJvcGVydGllcyB3aWxsIGJlIHJlZHVjZWQgdG8gYF97cmFuZG9tIG51bWJlcn1gXG4vLyBhdCBidWlsZCB0aW1lIHRvIG9iZnVzY2F0ZSB0aGVtIGFuZCBkaXNjb3VyYWdlIHRoZWlyIHVzZS5cbi8vIFdlIGRvbid0IHVzZSBzeW1ib2xzIG9yIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSB0byBmdWxseSBoaWRlIHRoZW1cbi8vIGJlY2F1c2UgdGhlIHBlcmZvcm1hbmNlIGlzbid0IGdvb2QgZW5vdWdoLlxuXG5cbi8vIHRvIGF2b2lkIHVzaW5nIHRyeS9jYXRjaCBpbnNpZGUgY3JpdGljYWwgZnVuY3Rpb25zLCB3ZVxuLy8gZXh0cmFjdCB0aGVtIHRvIGhlcmUuXG52YXIgTEFTVF9FUlJPUiA9IG51bGw7XG52YXIgSVNfRVJST1IgPSB7fTtcbmZ1bmN0aW9uIGdldFRoZW4ob2JqKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIG9iai50aGVuO1xuICB9IGNhdGNoIChleCkge1xuICAgIExBU1RfRVJST1IgPSBleDtcbiAgICByZXR1cm4gSVNfRVJST1I7XG4gIH1cbn1cblxuZnVuY3Rpb24gdHJ5Q2FsbE9uZShmbiwgYSkge1xuICB0cnkge1xuICAgIHJldHVybiBmbihhKTtcbiAgfSBjYXRjaCAoZXgpIHtcbiAgICBMQVNUX0VSUk9SID0gZXg7XG4gICAgcmV0dXJuIElTX0VSUk9SO1xuICB9XG59XG5mdW5jdGlvbiB0cnlDYWxsVHdvKGZuLCBhLCBiKSB7XG4gIHRyeSB7XG4gICAgZm4oYSwgYik7XG4gIH0gY2F0Y2ggKGV4KSB7XG4gICAgTEFTVF9FUlJPUiA9IGV4O1xuICAgIHJldHVybiBJU19FUlJPUjtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFByb21pc2U7XG5cbmZ1bmN0aW9uIFByb21pc2UoZm4pIHtcbiAgaWYgKHR5cGVvZiB0aGlzICE9PSAnb2JqZWN0Jykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Byb21pc2VzIG11c3QgYmUgY29uc3RydWN0ZWQgdmlhIG5ldycpO1xuICB9XG4gIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdub3QgYSBmdW5jdGlvbicpO1xuICB9XG4gIHRoaXMuXzQ1ID0gMDtcbiAgdGhpcy5fODEgPSAwO1xuICB0aGlzLl82NSA9IG51bGw7XG4gIHRoaXMuXzU0ID0gbnVsbDtcbiAgaWYgKGZuID09PSBub29wKSByZXR1cm47XG4gIGRvUmVzb2x2ZShmbiwgdGhpcyk7XG59XG5Qcm9taXNlLl8xMCA9IG51bGw7XG5Qcm9taXNlLl85NyA9IG51bGw7XG5Qcm9taXNlLl82MSA9IG5vb3A7XG5cblByb21pc2UucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuICBpZiAodGhpcy5jb25zdHJ1Y3RvciAhPT0gUHJvbWlzZSkge1xuICAgIHJldHVybiBzYWZlVGhlbih0aGlzLCBvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCk7XG4gIH1cbiAgdmFyIHJlcyA9IG5ldyBQcm9taXNlKG5vb3ApO1xuICBoYW5kbGUodGhpcywgbmV3IEhhbmRsZXIob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQsIHJlcykpO1xuICByZXR1cm4gcmVzO1xufTtcblxuZnVuY3Rpb24gc2FmZVRoZW4oc2VsZiwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgcmV0dXJuIG5ldyBzZWxmLmNvbnN0cnVjdG9yKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgcmVzID0gbmV3IFByb21pc2Uobm9vcCk7XG4gICAgcmVzLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICBoYW5kbGUoc2VsZiwgbmV3IEhhbmRsZXIob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQsIHJlcykpO1xuICB9KTtcbn07XG5mdW5jdGlvbiBoYW5kbGUoc2VsZiwgZGVmZXJyZWQpIHtcbiAgd2hpbGUgKHNlbGYuXzgxID09PSAzKSB7XG4gICAgc2VsZiA9IHNlbGYuXzY1O1xuICB9XG4gIGlmIChQcm9taXNlLl8xMCkge1xuICAgIFByb21pc2UuXzEwKHNlbGYpO1xuICB9XG4gIGlmIChzZWxmLl84MSA9PT0gMCkge1xuICAgIGlmIChzZWxmLl80NSA9PT0gMCkge1xuICAgICAgc2VsZi5fNDUgPSAxO1xuICAgICAgc2VsZi5fNTQgPSBkZWZlcnJlZDtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHNlbGYuXzQ1ID09PSAxKSB7XG4gICAgICBzZWxmLl80NSA9IDI7XG4gICAgICBzZWxmLl81NCA9IFtzZWxmLl81NCwgZGVmZXJyZWRdO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZWxmLl81NC5wdXNoKGRlZmVycmVkKTtcbiAgICByZXR1cm47XG4gIH1cbiAgaGFuZGxlUmVzb2x2ZWQoc2VsZiwgZGVmZXJyZWQpO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVSZXNvbHZlZChzZWxmLCBkZWZlcnJlZCkge1xuICBhc2FwKGZ1bmN0aW9uKCkge1xuICAgIHZhciBjYiA9IHNlbGYuXzgxID09PSAxID8gZGVmZXJyZWQub25GdWxmaWxsZWQgOiBkZWZlcnJlZC5vblJlamVjdGVkO1xuICAgIGlmIChjYiA9PT0gbnVsbCkge1xuICAgICAgaWYgKHNlbGYuXzgxID09PSAxKSB7XG4gICAgICAgIHJlc29sdmUoZGVmZXJyZWQucHJvbWlzZSwgc2VsZi5fNjUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVqZWN0KGRlZmVycmVkLnByb21pc2UsIHNlbGYuXzY1KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHJldCA9IHRyeUNhbGxPbmUoY2IsIHNlbGYuXzY1KTtcbiAgICBpZiAocmV0ID09PSBJU19FUlJPUikge1xuICAgICAgcmVqZWN0KGRlZmVycmVkLnByb21pc2UsIExBU1RfRVJST1IpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNvbHZlKGRlZmVycmVkLnByb21pc2UsIHJldCk7XG4gICAgfVxuICB9KTtcbn1cbmZ1bmN0aW9uIHJlc29sdmUoc2VsZiwgbmV3VmFsdWUpIHtcbiAgLy8gUHJvbWlzZSBSZXNvbHV0aW9uIFByb2NlZHVyZTogaHR0cHM6Ly9naXRodWIuY29tL3Byb21pc2VzLWFwbHVzL3Byb21pc2VzLXNwZWMjdGhlLXByb21pc2UtcmVzb2x1dGlvbi1wcm9jZWR1cmVcbiAgaWYgKG5ld1ZhbHVlID09PSBzZWxmKSB7XG4gICAgcmV0dXJuIHJlamVjdChcbiAgICAgIHNlbGYsXG4gICAgICBuZXcgVHlwZUVycm9yKCdBIHByb21pc2UgY2Fubm90IGJlIHJlc29sdmVkIHdpdGggaXRzZWxmLicpXG4gICAgKTtcbiAgfVxuICBpZiAoXG4gICAgbmV3VmFsdWUgJiZcbiAgICAodHlwZW9mIG5ld1ZhbHVlID09PSAnb2JqZWN0JyB8fCB0eXBlb2YgbmV3VmFsdWUgPT09ICdmdW5jdGlvbicpXG4gICkge1xuICAgIHZhciB0aGVuID0gZ2V0VGhlbihuZXdWYWx1ZSk7XG4gICAgaWYgKHRoZW4gPT09IElTX0VSUk9SKSB7XG4gICAgICByZXR1cm4gcmVqZWN0KHNlbGYsIExBU1RfRVJST1IpO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICB0aGVuID09PSBzZWxmLnRoZW4gJiZcbiAgICAgIG5ld1ZhbHVlIGluc3RhbmNlb2YgUHJvbWlzZVxuICAgICkge1xuICAgICAgc2VsZi5fODEgPSAzO1xuICAgICAgc2VsZi5fNjUgPSBuZXdWYWx1ZTtcbiAgICAgIGZpbmFsZShzZWxmKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBkb1Jlc29sdmUodGhlbi5iaW5kKG5ld1ZhbHVlKSwgc2VsZik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG4gIHNlbGYuXzgxID0gMTtcbiAgc2VsZi5fNjUgPSBuZXdWYWx1ZTtcbiAgZmluYWxlKHNlbGYpO1xufVxuXG5mdW5jdGlvbiByZWplY3Qoc2VsZiwgbmV3VmFsdWUpIHtcbiAgc2VsZi5fODEgPSAyO1xuICBzZWxmLl82NSA9IG5ld1ZhbHVlO1xuICBpZiAoUHJvbWlzZS5fOTcpIHtcbiAgICBQcm9taXNlLl85NyhzZWxmLCBuZXdWYWx1ZSk7XG4gIH1cbiAgZmluYWxlKHNlbGYpO1xufVxuZnVuY3Rpb24gZmluYWxlKHNlbGYpIHtcbiAgaWYgKHNlbGYuXzQ1ID09PSAxKSB7XG4gICAgaGFuZGxlKHNlbGYsIHNlbGYuXzU0KTtcbiAgICBzZWxmLl81NCA9IG51bGw7XG4gIH1cbiAgaWYgKHNlbGYuXzQ1ID09PSAyKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWxmLl81NC5sZW5ndGg7IGkrKykge1xuICAgICAgaGFuZGxlKHNlbGYsIHNlbGYuXzU0W2ldKTtcbiAgICB9XG4gICAgc2VsZi5fNTQgPSBudWxsO1xuICB9XG59XG5cbmZ1bmN0aW9uIEhhbmRsZXIob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQsIHByb21pc2Upe1xuICB0aGlzLm9uRnVsZmlsbGVkID0gdHlwZW9mIG9uRnVsZmlsbGVkID09PSAnZnVuY3Rpb24nID8gb25GdWxmaWxsZWQgOiBudWxsO1xuICB0aGlzLm9uUmVqZWN0ZWQgPSB0eXBlb2Ygb25SZWplY3RlZCA9PT0gJ2Z1bmN0aW9uJyA/IG9uUmVqZWN0ZWQgOiBudWxsO1xuICB0aGlzLnByb21pc2UgPSBwcm9taXNlO1xufVxuXG4vKipcbiAqIFRha2UgYSBwb3RlbnRpYWxseSBtaXNiZWhhdmluZyByZXNvbHZlciBmdW5jdGlvbiBhbmQgbWFrZSBzdXJlXG4gKiBvbkZ1bGZpbGxlZCBhbmQgb25SZWplY3RlZCBhcmUgb25seSBjYWxsZWQgb25jZS5cbiAqXG4gKiBNYWtlcyBubyBndWFyYW50ZWVzIGFib3V0IGFzeW5jaHJvbnkuXG4gKi9cbmZ1bmN0aW9uIGRvUmVzb2x2ZShmbiwgcHJvbWlzZSkge1xuICB2YXIgZG9uZSA9IGZhbHNlO1xuICB2YXIgcmVzID0gdHJ5Q2FsbFR3byhmbiwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgaWYgKGRvbmUpIHJldHVybjtcbiAgICBkb25lID0gdHJ1ZTtcbiAgICByZXNvbHZlKHByb21pc2UsIHZhbHVlKTtcbiAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIGlmIChkb25lKSByZXR1cm47XG4gICAgZG9uZSA9IHRydWU7XG4gICAgcmVqZWN0KHByb21pc2UsIHJlYXNvbik7XG4gIH0pXG4gIGlmICghZG9uZSAmJiByZXMgPT09IElTX0VSUk9SKSB7XG4gICAgZG9uZSA9IHRydWU7XG4gICAgcmVqZWN0KHByb21pc2UsIExBU1RfRVJST1IpO1xuICB9XG59XG5cbn0se1wiYXNhcC9yYXdcIjo5M31dLDk1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxuLy9UaGlzIGZpbGUgY29udGFpbnMgdGhlIEVTNiBleHRlbnNpb25zIHRvIHRoZSBjb3JlIFByb21pc2VzL0ErIEFQSVxuXG52YXIgUHJvbWlzZSA9IHJlcXVpcmUoJy4vY29yZS5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFByb21pc2U7XG5cbi8qIFN0YXRpYyBGdW5jdGlvbnMgKi9cblxudmFyIFRSVUUgPSB2YWx1ZVByb21pc2UodHJ1ZSk7XG52YXIgRkFMU0UgPSB2YWx1ZVByb21pc2UoZmFsc2UpO1xudmFyIE5VTEwgPSB2YWx1ZVByb21pc2UobnVsbCk7XG52YXIgVU5ERUZJTkVEID0gdmFsdWVQcm9taXNlKHVuZGVmaW5lZCk7XG52YXIgWkVSTyA9IHZhbHVlUHJvbWlzZSgwKTtcbnZhciBFTVBUWVNUUklORyA9IHZhbHVlUHJvbWlzZSgnJyk7XG5cbmZ1bmN0aW9uIHZhbHVlUHJvbWlzZSh2YWx1ZSkge1xuICB2YXIgcCA9IG5ldyBQcm9taXNlKFByb21pc2UuXzYxKTtcbiAgcC5fODEgPSAxO1xuICBwLl82NSA9IHZhbHVlO1xuICByZXR1cm4gcDtcbn1cblByb21pc2UucmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSByZXR1cm4gdmFsdWU7XG5cbiAgaWYgKHZhbHVlID09PSBudWxsKSByZXR1cm4gTlVMTDtcbiAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybiBVTkRFRklORUQ7XG4gIGlmICh2YWx1ZSA9PT0gdHJ1ZSkgcmV0dXJuIFRSVUU7XG4gIGlmICh2YWx1ZSA9PT0gZmFsc2UpIHJldHVybiBGQUxTRTtcbiAgaWYgKHZhbHVlID09PSAwKSByZXR1cm4gWkVSTztcbiAgaWYgKHZhbHVlID09PSAnJykgcmV0dXJuIEVNUFRZU1RSSU5HO1xuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRyeSB7XG4gICAgICB2YXIgdGhlbiA9IHZhbHVlLnRoZW47XG4gICAgICBpZiAodHlwZW9mIHRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHRoZW4uYmluZCh2YWx1ZSkpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICByZWplY3QoZXgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB2YWx1ZVByb21pc2UodmFsdWUpO1xufTtcblxuUHJvbWlzZS5hbGwgPSBmdW5jdGlvbiAoYXJyKSB7XG4gIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJyKTtcblxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHJlc29sdmUoW10pO1xuICAgIHZhciByZW1haW5pbmcgPSBhcmdzLmxlbmd0aDtcbiAgICBmdW5jdGlvbiByZXMoaSwgdmFsKSB7XG4gICAgICBpZiAodmFsICYmICh0eXBlb2YgdmFsID09PSAnb2JqZWN0JyB8fCB0eXBlb2YgdmFsID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgUHJvbWlzZSAmJiB2YWwudGhlbiA9PT0gUHJvbWlzZS5wcm90b3R5cGUudGhlbikge1xuICAgICAgICAgIHdoaWxlICh2YWwuXzgxID09PSAzKSB7XG4gICAgICAgICAgICB2YWwgPSB2YWwuXzY1O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodmFsLl84MSA9PT0gMSkgcmV0dXJuIHJlcyhpLCB2YWwuXzY1KTtcbiAgICAgICAgICBpZiAodmFsLl84MSA9PT0gMikgcmVqZWN0KHZhbC5fNjUpO1xuICAgICAgICAgIHZhbC50aGVuKGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgICAgIHJlcyhpLCB2YWwpO1xuICAgICAgICAgIH0sIHJlamVjdCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciB0aGVuID0gdmFsLnRoZW47XG4gICAgICAgICAgaWYgKHR5cGVvZiB0aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB2YXIgcCA9IG5ldyBQcm9taXNlKHRoZW4uYmluZCh2YWwpKTtcbiAgICAgICAgICAgIHAudGhlbihmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgICAgICAgIHJlcyhpLCB2YWwpO1xuICAgICAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGFyZ3NbaV0gPSB2YWw7XG4gICAgICBpZiAoLS1yZW1haW5pbmcgPT09IDApIHtcbiAgICAgICAgcmVzb2x2ZShhcmdzKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICByZXMoaSwgYXJnc1tpXSk7XG4gICAgfVxuICB9KTtcbn07XG5cblByb21pc2UucmVqZWN0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgcmVqZWN0KHZhbHVlKTtcbiAgfSk7XG59O1xuXG5Qcm9taXNlLnJhY2UgPSBmdW5jdGlvbiAodmFsdWVzKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgdmFsdWVzLmZvckVhY2goZnVuY3Rpb24odmFsdWUpe1xuICAgICAgUHJvbWlzZS5yZXNvbHZlKHZhbHVlKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgfSk7XG4gIH0pO1xufTtcblxuLyogUHJvdG90eXBlIE1ldGhvZHMgKi9cblxuUHJvbWlzZS5wcm90b3R5cGVbJ2NhdGNoJ10gPSBmdW5jdGlvbiAob25SZWplY3RlZCkge1xuICByZXR1cm4gdGhpcy50aGVuKG51bGwsIG9uUmVqZWN0ZWQpO1xufTtcblxufSx7XCIuL2NvcmUuanNcIjo5NH1dLDk2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbi8vIHNob3VsZCB3b3JrIGluIGFueSBicm93c2VyIHdpdGhvdXQgYnJvd3NlcmlmeVxuXG5pZiAodHlwZW9mIFByb21pc2UucHJvdG90eXBlLmRvbmUgIT09ICdmdW5jdGlvbicpIHtcbiAgUHJvbWlzZS5wcm90b3R5cGUuZG9uZSA9IGZ1bmN0aW9uIChvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuICAgIHZhciBzZWxmID0gYXJndW1lbnRzLmxlbmd0aCA/IHRoaXMudGhlbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogdGhpc1xuICAgIHNlbGYudGhlbihudWxsLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhyb3cgZXJyXG4gICAgICB9LCAwKVxuICAgIH0pXG4gIH1cbn1cbn0se31dLDk3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbi8vIG5vdCBcInVzZSBzdHJpY3RcIiBzbyB3ZSBjYW4gZGVjbGFyZSBnbG9iYWwgXCJQcm9taXNlXCJcblxudmFyIGFzYXAgPSByZXF1aXJlKCdhc2FwJyk7XG5cbmlmICh0eXBlb2YgUHJvbWlzZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgUHJvbWlzZSA9IHJlcXVpcmUoJy4vbGliL2NvcmUuanMnKVxuICByZXF1aXJlKCcuL2xpYi9lczYtZXh0ZW5zaW9ucy5qcycpXG59XG5cbnJlcXVpcmUoJy4vcG9seWZpbGwtZG9uZS5qcycpO1xuXG59LHtcIi4vbGliL2NvcmUuanNcIjo5NCxcIi4vbGliL2VzNi1leHRlbnNpb25zLmpzXCI6OTUsXCIuL3BvbHlmaWxsLWRvbmUuanNcIjo5NixcImFzYXBcIjo5Mn1dfSx7fSxbMl0pKDIpXG59KTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vbGVzcy9kaXN0L2xlc3MuanNcbi8vIG1vZHVsZSBpZCA9IDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==");
},function(module,exports,__webpack_require__){eval('var __vue_exports__, __vue_options__\n\n/* styles */\n__webpack_require__(47)\n\n/* script */\n__vue_exports__ = __webpack_require__(13)\n\n/* template */\nvar __vue_template__ = __webpack_require__(38)\n__vue_options__ = __vue_exports__ = __vue_exports__ || {}\nif (\n  typeof __vue_exports__.default === "object" ||\n  typeof __vue_exports__.default === "function"\n) {\nif (Object.keys(__vue_exports__).some(function (key) { return key !== "default" && key !== "__esModule" })) {console.error("named exports are not supported in *.vue files.")}\n__vue_options__ = __vue_exports__ = __vue_exports__.default\n}\nif (typeof __vue_options__ === "function") {\n  __vue_options__ = __vue_options__.options\n}\n__vue_options__.__file = "/Users/huyirui/Documents/itomix/canada_life_demo/canada-life/src/App.vue"\n__vue_options__.render = __vue_template__.render\n__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\n/* hot reload */\nif (false) {(function () {\n  var hotAPI = require("vue-hot-reload-api")\n  hotAPI.install(require("vue"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord("data-v-2a556f0c", __vue_options__)\n  } else {\n    hotAPI.reload("data-v-2a556f0c", __vue_options__)\n  }\n})()}\nif (__vue_options__.functional) {console.error("[vue-loader] App.vue: functional components are not supported and should be defined in plain js files using render functions.")}\n\nmodule.exports = __vue_exports__\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvQXBwLnZ1ZT8wMTJlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxtREFBbUQsSUFBSTtBQUM3RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsWUFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxDQUFDO0FBQ0QsaUNBQWlDOztBQUVqQyIsImZpbGUiOiI1LmpzIiwic291cmNlc0NvbnRlbnQiOlsidmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cbi8qIHN0eWxlcyAqL1xucmVxdWlyZShcIiEhdnVlLXN0eWxlLWxvYWRlciFjc3MtbG9hZGVyP3NvdXJjZU1hcCF2dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlcj9pZD1kYXRhLXYtMmE1NTZmMGMhdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0FwcC52dWVcIilcblxuLyogc2NyaXB0ICovXG5fX3Z1ZV9leHBvcnRzX18gPSByZXF1aXJlKFwiISFiYWJlbC1sb2FkZXIhdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zY3JpcHQmaW5kZXg9MCEuL0FwcC52dWVcIilcblxuLyogdGVtcGxhdGUgKi9cbnZhciBfX3Z1ZV90ZW1wbGF0ZV9fID0gcmVxdWlyZShcIiEhdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXI/aWQ9ZGF0YS12LTJhNTU2ZjBjIXZ1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL0FwcC52dWVcIilcbl9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXyB8fCB7fVxuaWYgKFxuICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcbiAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcImZ1bmN0aW9uXCJcbikge1xuaWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5fX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdFxufVxuaWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuICBfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9vcHRpb25zX18ub3B0aW9uc1xufVxuX192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiL1VzZXJzL2h1eWlydWkvRG9jdW1lbnRzL2l0b21peC9jYW5hZGFfbGlmZV9kZW1vL2NhbmFkYS1saWZlL3NyYy9BcHAudnVlXCJcbl9fdnVlX29wdGlvbnNfXy5yZW5kZXIgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnJlbmRlclxuX192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cbi8qIGhvdCByZWxvYWQgKi9cbmlmIChtb2R1bGUuaG90KSB7KGZ1bmN0aW9uICgpIHtcbiAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcbiAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG4gIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgaG90QVBJLmNyZWF0ZVJlY29yZChcImRhdGEtdi0yYTU1NmYwY1wiLCBfX3Z1ZV9vcHRpb25zX18pXG4gIH0gZWxzZSB7XG4gICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi0yYTU1NmYwY1wiLCBfX3Z1ZV9vcHRpb25zX18pXG4gIH1cbn0pKCl9XG5pZiAoX192dWVfb3B0aW9uc19fLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIEFwcC52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCBhbmQgc2hvdWxkIGJlIGRlZmluZWQgaW4gcGxhaW4ganMgZmlsZXMgdXNpbmcgcmVuZGVyIGZ1bmN0aW9ucy5cIil9XG5cbm1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9BcHAudnVlXG4vLyBtb2R1bGUgaWQgPSA1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=')},function(module,exports,__webpack_require__){eval('var __vue_exports__, __vue_options__\n\n/* styles */\n__webpack_require__(46)\n\n/* script */\n__vue_exports__ = __webpack_require__(16)\n\n/* template */\nvar __vue_template__ = __webpack_require__(37)\n__vue_options__ = __vue_exports__ = __vue_exports__ || {}\nif (\n  typeof __vue_exports__.default === "object" ||\n  typeof __vue_exports__.default === "function"\n) {\nif (Object.keys(__vue_exports__).some(function (key) { return key !== "default" && key !== "__esModule" })) {console.error("named exports are not supported in *.vue files.")}\n__vue_options__ = __vue_exports__ = __vue_exports__.default\n}\nif (typeof __vue_options__ === "function") {\n  __vue_options__ = __vue_options__.options\n}\n__vue_options__.__file = "/Users/huyirui/Documents/itomix/canada_life_demo/canada-life/src/components/view/school/consultant.vue"\n__vue_options__.render = __vue_template__.render\n__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\n/* hot reload */\nif (false) {(function () {\n  var hotAPI = require("vue-hot-reload-api")\n  hotAPI.install(require("vue"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord("data-v-14f9a6de", __vue_options__)\n  } else {\n    hotAPI.reload("data-v-14f9a6de", __vue_options__)\n  }\n})()}\nif (__vue_options__.functional) {console.error("[vue-loader] consultant.vue: functional components are not supported and should be defined in plain js files using render functions.")}\n\nmodule.exports = __vue_exports__\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9jb25zdWx0YW50LnZ1ZT9hNTFiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxtREFBbUQsSUFBSTtBQUM3RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsWUFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxDQUFDO0FBQ0QsaUNBQWlDOztBQUVqQyIsImZpbGUiOiI2LmpzIiwic291cmNlc0NvbnRlbnQiOlsidmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cbi8qIHN0eWxlcyAqL1xucmVxdWlyZShcIiEhdnVlLXN0eWxlLWxvYWRlciFjc3MtbG9hZGVyP3NvdXJjZU1hcCF2dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlcj9pZD1kYXRhLXYtMTRmOWE2ZGUhdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL2NvbnN1bHRhbnQudnVlXCIpXG5cbi8qIHNjcmlwdCAqL1xuX192dWVfZXhwb3J0c19fID0gcmVxdWlyZShcIiEhYmFiZWwtbG9hZGVyIXZ1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c2NyaXB0JmluZGV4PTAhLi9jb25zdWx0YW50LnZ1ZVwiKVxuXG4vKiB0ZW1wbGF0ZSAqL1xudmFyIF9fdnVlX3RlbXBsYXRlX18gPSByZXF1aXJlKFwiISF2dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlcj9pZD1kYXRhLXYtMTRmOWE2ZGUhdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT10ZW1wbGF0ZSZpbmRleD0wIS4vY29uc3VsdGFudC52dWVcIilcbl9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXyB8fCB7fVxuaWYgKFxuICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcbiAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcImZ1bmN0aW9uXCJcbikge1xuaWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5fX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdFxufVxuaWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuICBfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9vcHRpb25zX18ub3B0aW9uc1xufVxuX192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiL1VzZXJzL2h1eWlydWkvRG9jdW1lbnRzL2l0b21peC9jYW5hZGFfbGlmZV9kZW1vL2NhbmFkYS1saWZlL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL2NvbnN1bHRhbnQudnVlXCJcbl9fdnVlX29wdGlvbnNfXy5yZW5kZXIgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnJlbmRlclxuX192dWVfb3B0aW9uc19fLnN0YXRpY1JlbmRlckZucyA9IF9fdnVlX3RlbXBsYXRlX18uc3RhdGljUmVuZGVyRm5zXG5cbi8qIGhvdCByZWxvYWQgKi9cbmlmIChtb2R1bGUuaG90KSB7KGZ1bmN0aW9uICgpIHtcbiAgdmFyIGhvdEFQSSA9IHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIilcbiAgaG90QVBJLmluc3RhbGwocmVxdWlyZShcInZ1ZVwiKSwgZmFsc2UpXG4gIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgaG90QVBJLmNyZWF0ZVJlY29yZChcImRhdGEtdi0xNGY5YTZkZVwiLCBfX3Z1ZV9vcHRpb25zX18pXG4gIH0gZWxzZSB7XG4gICAgaG90QVBJLnJlbG9hZChcImRhdGEtdi0xNGY5YTZkZVwiLCBfX3Z1ZV9vcHRpb25zX18pXG4gIH1cbn0pKCl9XG5pZiAoX192dWVfb3B0aW9uc19fLmZ1bmN0aW9uYWwpIHtjb25zb2xlLmVycm9yKFwiW3Z1ZS1sb2FkZXJdIGNvbnN1bHRhbnQudnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9fdnVlX2V4cG9ydHNfX1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9jb25zdWx0YW50LnZ1ZVxuLy8gbW9kdWxlIGlkID0gNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('var __vue_exports__, __vue_options__\n\n/* styles */\n__webpack_require__(53)\n\n/* script */\n__vue_exports__ = __webpack_require__(18)\n\n/* template */\nvar __vue_template__ = __webpack_require__(44)\n__vue_options__ = __vue_exports__ = __vue_exports__ || {}\nif (\n  typeof __vue_exports__.default === "object" ||\n  typeof __vue_exports__.default === "function"\n) {\nif (Object.keys(__vue_exports__).some(function (key) { return key !== "default" && key !== "__esModule" })) {console.error("named exports are not supported in *.vue files.")}\n__vue_options__ = __vue_exports__ = __vue_exports__.default\n}\nif (typeof __vue_options__ === "function") {\n  __vue_options__ = __vue_options__.options\n}\n__vue_options__.__file = "/Users/huyirui/Documents/itomix/canada_life_demo/canada-life/src/components/view/school/intro.vue"\n__vue_options__.render = __vue_template__.render\n__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\n/* hot reload */\nif (false) {(function () {\n  var hotAPI = require("vue-hot-reload-api")\n  hotAPI.install(require("vue"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord("data-v-c91fc64e", __vue_options__)\n  } else {\n    hotAPI.reload("data-v-c91fc64e", __vue_options__)\n  }\n})()}\nif (__vue_options__.functional) {console.error("[vue-loader] intro.vue: functional components are not supported and should be defined in plain js files using render functions.")}\n\nmodule.exports = __vue_exports__\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9pbnRyby52dWU/NDcyMSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzREFBc0QsbURBQW1ELElBQUk7QUFDN0c7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFlBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsQ0FBQztBQUNELGlDQUFpQzs7QUFFakMiLCJmaWxlIjoiNy5qcyIsInNvdXJjZXNDb250ZW50IjpbInZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXG4vKiBzdHlsZXMgKi9cbnJlcXVpcmUoXCIhIXZ1ZS1zdHlsZS1sb2FkZXIhY3NzLWxvYWRlcj9zb3VyY2VNYXAhdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXI/aWQ9ZGF0YS12LWM5MWZjNjRlIWxlc3MhdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL2ludHJvLnZ1ZVwiKVxuXG4vKiBzY3JpcHQgKi9cbl9fdnVlX2V4cG9ydHNfXyA9IHJlcXVpcmUoXCIhIWJhYmVsLWxvYWRlciF2dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXNjcmlwdCZpbmRleD0wIS4vaW50cm8udnVlXCIpXG5cbi8qIHRlbXBsYXRlICovXG52YXIgX192dWVfdGVtcGxhdGVfXyA9IHJlcXVpcmUoXCIhIXZ1ZS1sb2FkZXIvbGliL3RlbXBsYXRlLWNvbXBpbGVyP2lkPWRhdGEtdi1jOTFmYzY0ZSF2dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXRlbXBsYXRlJmluZGV4PTAhLi9pbnRyby52dWVcIilcbl9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXyB8fCB7fVxuaWYgKFxuICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcbiAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcImZ1bmN0aW9uXCJcbikge1xuaWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5fX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdFxufVxuaWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuICBfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9vcHRpb25zX18ub3B0aW9uc1xufVxuX192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiL1VzZXJzL2h1eWlydWkvRG9jdW1lbnRzL2l0b21peC9jYW5hZGFfbGlmZV9kZW1vL2NhbmFkYS1saWZlL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL2ludHJvLnZ1ZVwiXG5fX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcbl9fdnVlX29wdGlvbnNfXy5zdGF0aWNSZW5kZXJGbnMgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnN0YXRpY1JlbmRlckZuc1xuXG4vKiBob3QgcmVsb2FkICovXG5pZiAobW9kdWxlLmhvdCkgeyhmdW5jdGlvbiAoKSB7XG4gIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG4gIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtYzkxZmM2NGVcIiwgX192dWVfb3B0aW9uc19fKVxuICB9IGVsc2Uge1xuICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtYzkxZmM2NGVcIiwgX192dWVfb3B0aW9uc19fKVxuICB9XG59KSgpfVxuaWYgKF9fdnVlX29wdGlvbnNfXy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBpbnRyby52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCBhbmQgc2hvdWxkIGJlIGRlZmluZWQgaW4gcGxhaW4ganMgZmlsZXMgdXNpbmcgcmVuZGVyIGZ1bmN0aW9ucy5cIil9XG5cbm1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL2ludHJvLnZ1ZVxuLy8gbW9kdWxlIGlkID0gN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('var __vue_exports__, __vue_options__\n\n/* styles */\n__webpack_require__(50)\n\n/* script */\n__vue_exports__ = __webpack_require__(20)\n\n/* template */\nvar __vue_template__ = __webpack_require__(41)\n__vue_options__ = __vue_exports__ = __vue_exports__ || {}\nif (\n  typeof __vue_exports__.default === "object" ||\n  typeof __vue_exports__.default === "function"\n) {\nif (Object.keys(__vue_exports__).some(function (key) { return key !== "default" && key !== "__esModule" })) {console.error("named exports are not supported in *.vue files.")}\n__vue_options__ = __vue_exports__ = __vue_exports__.default\n}\nif (typeof __vue_options__ === "function") {\n  __vue_options__ = __vue_options__.options\n}\n__vue_options__.__file = "/Users/huyirui/Documents/itomix/canada_life_demo/canada-life/src/components/view/school/question.vue"\n__vue_options__.render = __vue_template__.render\n__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\n/* hot reload */\nif (false) {(function () {\n  var hotAPI = require("vue-hot-reload-api")\n  hotAPI.install(require("vue"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord("data-v-3b7ba589", __vue_options__)\n  } else {\n    hotAPI.reload("data-v-3b7ba589", __vue_options__)\n  }\n})()}\nif (__vue_options__.functional) {console.error("[vue-loader] question.vue: functional components are not supported and should be defined in plain js files using render functions.")}\n\nmodule.exports = __vue_exports__\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9xdWVzdGlvbi52dWU/MGJkOSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzREFBc0QsbURBQW1ELElBQUk7QUFDN0c7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFlBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsQ0FBQztBQUNELGlDQUFpQzs7QUFFakMiLCJmaWxlIjoiOC5qcyIsInNvdXJjZXNDb250ZW50IjpbInZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXG4vKiBzdHlsZXMgKi9cbnJlcXVpcmUoXCIhIXZ1ZS1zdHlsZS1sb2FkZXIhY3NzLWxvYWRlcj9zb3VyY2VNYXAhdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXI/aWQ9ZGF0YS12LTNiN2JhNTg5IWxlc3MhdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3F1ZXN0aW9uLnZ1ZVwiKVxuXG4vKiBzY3JpcHQgKi9cbl9fdnVlX2V4cG9ydHNfXyA9IHJlcXVpcmUoXCIhIWJhYmVsLWxvYWRlciF2dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXNjcmlwdCZpbmRleD0wIS4vcXVlc3Rpb24udnVlXCIpXG5cbi8qIHRlbXBsYXRlICovXG52YXIgX192dWVfdGVtcGxhdGVfXyA9IHJlcXVpcmUoXCIhIXZ1ZS1sb2FkZXIvbGliL3RlbXBsYXRlLWNvbXBpbGVyP2lkPWRhdGEtdi0zYjdiYTU4OSF2dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXRlbXBsYXRlJmluZGV4PTAhLi9xdWVzdGlvbi52dWVcIilcbl9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXyB8fCB7fVxuaWYgKFxuICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcbiAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcImZ1bmN0aW9uXCJcbikge1xuaWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5fX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdFxufVxuaWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuICBfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9vcHRpb25zX18ub3B0aW9uc1xufVxuX192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiL1VzZXJzL2h1eWlydWkvRG9jdW1lbnRzL2l0b21peC9jYW5hZGFfbGlmZV9kZW1vL2NhbmFkYS1saWZlL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL3F1ZXN0aW9uLnZ1ZVwiXG5fX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcbl9fdnVlX29wdGlvbnNfXy5zdGF0aWNSZW5kZXJGbnMgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnN0YXRpY1JlbmRlckZuc1xuXG4vKiBob3QgcmVsb2FkICovXG5pZiAobW9kdWxlLmhvdCkgeyhmdW5jdGlvbiAoKSB7XG4gIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG4gIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtM2I3YmE1ODlcIiwgX192dWVfb3B0aW9uc19fKVxuICB9IGVsc2Uge1xuICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtM2I3YmE1ODlcIiwgX192dWVfb3B0aW9uc19fKVxuICB9XG59KSgpfVxuaWYgKF9fdnVlX29wdGlvbnNfXy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBxdWVzdGlvbi52dWU6IGZ1bmN0aW9uYWwgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZCBhbmQgc2hvdWxkIGJlIGRlZmluZWQgaW4gcGxhaW4ganMgZmlsZXMgdXNpbmcgcmVuZGVyIGZ1bmN0aW9ucy5cIil9XG5cbm1vZHVsZS5leHBvcnRzID0gX192dWVfZXhwb3J0c19fXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL3F1ZXN0aW9uLnZ1ZVxuLy8gbW9kdWxlIGlkID0gOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('var __vue_exports__, __vue_options__\n\n/* styles */\n__webpack_require__(52)\n\n/* script */\n__vue_exports__ = __webpack_require__(21)\n\n/* template */\nvar __vue_template__ = __webpack_require__(43)\n__vue_options__ = __vue_exports__ = __vue_exports__ || {}\nif (\n  typeof __vue_exports__.default === "object" ||\n  typeof __vue_exports__.default === "function"\n) {\nif (Object.keys(__vue_exports__).some(function (key) { return key !== "default" && key !== "__esModule" })) {console.error("named exports are not supported in *.vue files.")}\n__vue_options__ = __vue_exports__ = __vue_exports__.default\n}\nif (typeof __vue_options__ === "function") {\n  __vue_options__ = __vue_options__.options\n}\n__vue_options__.__file = "/Users/huyirui/Documents/itomix/canada_life_demo/canada-life/src/components/view/school/video.vue"\n__vue_options__.render = __vue_template__.render\n__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\n/* hot reload */\nif (false) {(function () {\n  var hotAPI = require("vue-hot-reload-api")\n  hotAPI.install(require("vue"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord("data-v-921da930", __vue_options__)\n  } else {\n    hotAPI.reload("data-v-921da930", __vue_options__)\n  }\n})()}\nif (__vue_options__.functional) {console.error("[vue-loader] video.vue: functional components are not supported and should be defined in plain js files using render functions.")}\n\nmodule.exports = __vue_exports__\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC92aWRlby52dWU/ZjgyNiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzREFBc0QsbURBQW1ELElBQUk7QUFDN0c7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFlBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsQ0FBQztBQUNELGlDQUFpQzs7QUFFakMiLCJmaWxlIjoiOS5qcyIsInNvdXJjZXNDb250ZW50IjpbInZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXG4vKiBzdHlsZXMgKi9cbnJlcXVpcmUoXCIhIXZ1ZS1zdHlsZS1sb2FkZXIhY3NzLWxvYWRlcj9zb3VyY2VNYXAhdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXI/aWQ9ZGF0YS12LTkyMWRhOTMwIXZ1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c3R5bGVzJmluZGV4PTAhLi92aWRlby52dWVcIilcblxuLyogc2NyaXB0ICovXG5fX3Z1ZV9leHBvcnRzX18gPSByZXF1aXJlKFwiISFiYWJlbC1sb2FkZXIhdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zY3JpcHQmaW5kZXg9MCEuL3ZpZGVvLnZ1ZVwiKVxuXG4vKiB0ZW1wbGF0ZSAqL1xudmFyIF9fdnVlX3RlbXBsYXRlX18gPSByZXF1aXJlKFwiISF2dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlcj9pZD1kYXRhLXYtOTIxZGE5MzAhdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT10ZW1wbGF0ZSZpbmRleD0wIS4vdmlkZW8udnVlXCIpXG5fX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cbmlmIChcbiAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcIm9iamVjdFwiIHx8XG4gIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG4pIHtcbmlmIChPYmplY3Qua2V5cyhfX3Z1ZV9leHBvcnRzX18pLnNvbWUoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkgIT09IFwiX19lc01vZHVsZVwiIH0pKSB7Y29uc29sZS5lcnJvcihcIm5hbWVkIGV4cG9ydHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gKi52dWUgZmlsZXMuXCIpfVxuX192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcbn1cbmlmICh0eXBlb2YgX192dWVfb3B0aW9uc19fID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcbn1cbl9fdnVlX29wdGlvbnNfXy5fX2ZpbGUgPSBcIi9Vc2Vycy9odXlpcnVpL0RvY3VtZW50cy9pdG9taXgvY2FuYWRhX2xpZmVfZGVtby9jYW5hZGEtbGlmZS9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC92aWRlby52dWVcIlxuX192dWVfb3B0aW9uc19fLnJlbmRlciA9IF9fdnVlX3RlbXBsYXRlX18ucmVuZGVyXG5fX3Z1ZV9vcHRpb25zX18uc3RhdGljUmVuZGVyRm5zID0gX192dWVfdGVtcGxhdGVfXy5zdGF0aWNSZW5kZXJGbnNcblxuLyogaG90IHJlbG9hZCAqL1xuaWYgKG1vZHVsZS5ob3QpIHsoZnVuY3Rpb24gKCkge1xuICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcbiAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG4gIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcbiAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LTkyMWRhOTMwXCIsIF9fdnVlX29wdGlvbnNfXylcbiAgfSBlbHNlIHtcbiAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTkyMWRhOTMwXCIsIF9fdnVlX29wdGlvbnNfXylcbiAgfVxufSkoKX1cbmlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gdmlkZW8udnVlOiBmdW5jdGlvbmFsIGNvbXBvbmVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIHNob3VsZCBiZSBkZWZpbmVkIGluIHBsYWluIGpzIGZpbGVzIHVzaW5nIHJlbmRlciBmdW5jdGlvbnMuXCIpfVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9fdnVlX2V4cG9ydHNfX1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC92aWRlby52dWVcbi8vIG1vZHVsZSBpZCA9IDlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==')},function(module,exports){"use strict";eval("/*!\n * vue-resource v1.0.3\n * https://github.com/vuejs/vue-resource\n * Released under the MIT License.\n */\n\n'use strict';\n\n/**\n * Promises/A+ polyfill v1.1.4 (https://github.com/bramstein/promis)\n */\n\nvar RESOLVED = 0;\nvar REJECTED = 1;\nvar PENDING = 2;\n\nfunction Promise$1(executor) {\n\n    this.state = PENDING;\n    this.value = undefined;\n    this.deferred = [];\n\n    var promise = this;\n\n    try {\n        executor(function (x) {\n            promise.resolve(x);\n        }, function (r) {\n            promise.reject(r);\n        });\n    } catch (e) {\n        promise.reject(e);\n    }\n}\n\nPromise$1.reject = function (r) {\n    return new Promise$1(function (resolve, reject) {\n        reject(r);\n    });\n};\n\nPromise$1.resolve = function (x) {\n    return new Promise$1(function (resolve, reject) {\n        resolve(x);\n    });\n};\n\nPromise$1.all = function all(iterable) {\n    return new Promise$1(function (resolve, reject) {\n        var count = 0,\n            result = [];\n\n        if (iterable.length === 0) {\n            resolve(result);\n        }\n\n        function resolver(i) {\n            return function (x) {\n                result[i] = x;\n                count += 1;\n\n                if (count === iterable.length) {\n                    resolve(result);\n                }\n            };\n        }\n\n        for (var i = 0; i < iterable.length; i += 1) {\n            Promise$1.resolve(iterable[i]).then(resolver(i), reject);\n        }\n    });\n};\n\nPromise$1.race = function race(iterable) {\n    return new Promise$1(function (resolve, reject) {\n        for (var i = 0; i < iterable.length; i += 1) {\n            Promise$1.resolve(iterable[i]).then(resolve, reject);\n        }\n    });\n};\n\nvar p$1 = Promise$1.prototype;\n\np$1.resolve = function resolve(x) {\n    var promise = this;\n\n    if (promise.state === PENDING) {\n        if (x === promise) {\n            throw new TypeError('Promise settled with itself.');\n        }\n\n        var called = false;\n\n        try {\n            var then = x && x['then'];\n\n            if (x !== null && typeof x === 'object' && typeof then === 'function') {\n                then.call(x, function (x) {\n                    if (!called) {\n                        promise.resolve(x);\n                    }\n                    called = true;\n                }, function (r) {\n                    if (!called) {\n                        promise.reject(r);\n                    }\n                    called = true;\n                });\n                return;\n            }\n        } catch (e) {\n            if (!called) {\n                promise.reject(e);\n            }\n            return;\n        }\n\n        promise.state = RESOLVED;\n        promise.value = x;\n        promise.notify();\n    }\n};\n\np$1.reject = function reject(reason) {\n    var promise = this;\n\n    if (promise.state === PENDING) {\n        if (reason === promise) {\n            throw new TypeError('Promise settled with itself.');\n        }\n\n        promise.state = REJECTED;\n        promise.value = reason;\n        promise.notify();\n    }\n};\n\np$1.notify = function notify() {\n    var promise = this;\n\n    nextTick(function () {\n        if (promise.state !== PENDING) {\n            while (promise.deferred.length) {\n                var deferred = promise.deferred.shift(),\n                    onResolved = deferred[0],\n                    onRejected = deferred[1],\n                    resolve = deferred[2],\n                    reject = deferred[3];\n\n                try {\n                    if (promise.state === RESOLVED) {\n                        if (typeof onResolved === 'function') {\n                            resolve(onResolved.call(undefined, promise.value));\n                        } else {\n                            resolve(promise.value);\n                        }\n                    } else if (promise.state === REJECTED) {\n                        if (typeof onRejected === 'function') {\n                            resolve(onRejected.call(undefined, promise.value));\n                        } else {\n                            reject(promise.value);\n                        }\n                    }\n                } catch (e) {\n                    reject(e);\n                }\n            }\n        }\n    });\n};\n\np$1.then = function then(onResolved, onRejected) {\n    var promise = this;\n\n    return new Promise$1(function (resolve, reject) {\n        promise.deferred.push([onResolved, onRejected, resolve, reject]);\n        promise.notify();\n    });\n};\n\np$1.catch = function (onRejected) {\n    return this.then(undefined, onRejected);\n};\n\n/**\n * Promise adapter.\n */\n\nif (typeof Promise === 'undefined') {\n    window.Promise = Promise$1;\n}\n\nfunction PromiseObj(executor, context) {\n\n    if (executor instanceof Promise) {\n        this.promise = executor;\n    } else {\n        this.promise = new Promise(executor.bind(context));\n    }\n\n    this.context = context;\n}\n\nPromiseObj.all = function (iterable, context) {\n    return new PromiseObj(Promise.all(iterable), context);\n};\n\nPromiseObj.resolve = function (value, context) {\n    return new PromiseObj(Promise.resolve(value), context);\n};\n\nPromiseObj.reject = function (reason, context) {\n    return new PromiseObj(Promise.reject(reason), context);\n};\n\nPromiseObj.race = function (iterable, context) {\n    return new PromiseObj(Promise.race(iterable), context);\n};\n\nvar p = PromiseObj.prototype;\n\np.bind = function (context) {\n    this.context = context;\n    return this;\n};\n\np.then = function (fulfilled, rejected) {\n\n    if (fulfilled && fulfilled.bind && this.context) {\n        fulfilled = fulfilled.bind(this.context);\n    }\n\n    if (rejected && rejected.bind && this.context) {\n        rejected = rejected.bind(this.context);\n    }\n\n    return new PromiseObj(this.promise.then(fulfilled, rejected), this.context);\n};\n\np.catch = function (rejected) {\n\n    if (rejected && rejected.bind && this.context) {\n        rejected = rejected.bind(this.context);\n    }\n\n    return new PromiseObj(this.promise.catch(rejected), this.context);\n};\n\np.finally = function (callback) {\n\n    return this.then(function (value) {\n        callback.call(this);\n        return value;\n    }, function (reason) {\n        callback.call(this);\n        return Promise.reject(reason);\n    });\n};\n\n/**\n * Utility functions.\n */\n\nvar debug = false;var util = {};var slice = [].slice;\n\n\nfunction Util (Vue) {\n    util = Vue.util;\n    debug = Vue.config.debug || !Vue.config.silent;\n}\n\nfunction warn(msg) {\n    if (typeof console !== 'undefined' && debug) {\n        console.warn('[VueResource warn]: ' + msg);\n    }\n}\n\nfunction error(msg) {\n    if (typeof console !== 'undefined') {\n        console.error(msg);\n    }\n}\n\nfunction nextTick(cb, ctx) {\n    return util.nextTick(cb, ctx);\n}\n\nfunction trim(str) {\n    return str.replace(/^\\s*|\\s*$/g, '');\n}\n\nfunction toLower(str) {\n    return str ? str.toLowerCase() : '';\n}\n\nfunction toUpper(str) {\n    return str ? str.toUpperCase() : '';\n}\n\nvar isArray = Array.isArray;\n\nfunction isString(val) {\n    return typeof val === 'string';\n}\n\nfunction isBoolean(val) {\n    return val === true || val === false;\n}\n\nfunction isFunction(val) {\n    return typeof val === 'function';\n}\n\nfunction isObject(obj) {\n    return obj !== null && typeof obj === 'object';\n}\n\nfunction isPlainObject(obj) {\n    return isObject(obj) && Object.getPrototypeOf(obj) == Object.prototype;\n}\n\nfunction isBlob(obj) {\n    return typeof Blob !== 'undefined' && obj instanceof Blob;\n}\n\nfunction isFormData(obj) {\n    return typeof FormData !== 'undefined' && obj instanceof FormData;\n}\n\nfunction when(value, fulfilled, rejected) {\n\n    var promise = PromiseObj.resolve(value);\n\n    if (arguments.length < 2) {\n        return promise;\n    }\n\n    return promise.then(fulfilled, rejected);\n}\n\nfunction options(fn, obj, opts) {\n\n    opts = opts || {};\n\n    if (isFunction(opts)) {\n        opts = opts.call(obj);\n    }\n\n    return merge(fn.bind({ $vm: obj, $options: opts }), fn, { $options: opts });\n}\n\nfunction each(obj, iterator) {\n\n    var i, key;\n\n    if (obj && typeof obj.length == 'number') {\n        for (i = 0; i < obj.length; i++) {\n            iterator.call(obj[i], obj[i], i);\n        }\n    } else if (isObject(obj)) {\n        for (key in obj) {\n            if (obj.hasOwnProperty(key)) {\n                iterator.call(obj[key], obj[key], key);\n            }\n        }\n    }\n\n    return obj;\n}\n\nvar assign = Object.assign || _assign;\n\nfunction merge(target) {\n\n    var args = slice.call(arguments, 1);\n\n    args.forEach(function (source) {\n        _merge(target, source, true);\n    });\n\n    return target;\n}\n\nfunction defaults(target) {\n\n    var args = slice.call(arguments, 1);\n\n    args.forEach(function (source) {\n\n        for (var key in source) {\n            if (target[key] === undefined) {\n                target[key] = source[key];\n            }\n        }\n    });\n\n    return target;\n}\n\nfunction _assign(target) {\n\n    var args = slice.call(arguments, 1);\n\n    args.forEach(function (source) {\n        _merge(target, source);\n    });\n\n    return target;\n}\n\nfunction _merge(target, source, deep) {\n    for (var key in source) {\n        if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {\n            if (isPlainObject(source[key]) && !isPlainObject(target[key])) {\n                target[key] = {};\n            }\n            if (isArray(source[key]) && !isArray(target[key])) {\n                target[key] = [];\n            }\n            _merge(target[key], source[key], deep);\n        } else if (source[key] !== undefined) {\n            target[key] = source[key];\n        }\n    }\n}\n\n/**\n * Root Prefix Transform.\n */\n\nfunction root (options, next) {\n\n    var url = next(options);\n\n    if (isString(options.root) && !url.match(/^(https?:)?\\//)) {\n        url = options.root + '/' + url;\n    }\n\n    return url;\n}\n\n/**\n * Query Parameter Transform.\n */\n\nfunction query (options, next) {\n\n    var urlParams = Object.keys(Url.options.params),\n        query = {},\n        url = next(options);\n\n    each(options.params, function (value, key) {\n        if (urlParams.indexOf(key) === -1) {\n            query[key] = value;\n        }\n    });\n\n    query = Url.params(query);\n\n    if (query) {\n        url += (url.indexOf('?') == -1 ? '?' : '&') + query;\n    }\n\n    return url;\n}\n\n/**\n * URL Template v2.0.6 (https://github.com/bramstein/url-template)\n */\n\nfunction expand(url, params, variables) {\n\n    var tmpl = parse(url),\n        expanded = tmpl.expand(params);\n\n    if (variables) {\n        variables.push.apply(variables, tmpl.vars);\n    }\n\n    return expanded;\n}\n\nfunction parse(template) {\n\n    var operators = ['+', '#', '.', '/', ';', '?', '&'],\n        variables = [];\n\n    return {\n        vars: variables,\n        expand: function (context) {\n            return template.replace(/\\{([^\\{\\}]+)\\}|([^\\{\\}]+)/g, function (_, expression, literal) {\n                if (expression) {\n\n                    var operator = null,\n                        values = [];\n\n                    if (operators.indexOf(expression.charAt(0)) !== -1) {\n                        operator = expression.charAt(0);\n                        expression = expression.substr(1);\n                    }\n\n                    expression.split(/,/g).forEach(function (variable) {\n                        var tmp = /([^:\\*]*)(?::(\\d+)|(\\*))?/.exec(variable);\n                        values.push.apply(values, getValues(context, operator, tmp[1], tmp[2] || tmp[3]));\n                        variables.push(tmp[1]);\n                    });\n\n                    if (operator && operator !== '+') {\n\n                        var separator = ',';\n\n                        if (operator === '?') {\n                            separator = '&';\n                        } else if (operator !== '#') {\n                            separator = operator;\n                        }\n\n                        return (values.length !== 0 ? operator : '') + values.join(separator);\n                    } else {\n                        return values.join(',');\n                    }\n                } else {\n                    return encodeReserved(literal);\n                }\n            });\n        }\n    };\n}\n\nfunction getValues(context, operator, key, modifier) {\n\n    var value = context[key],\n        result = [];\n\n    if (isDefined(value) && value !== '') {\n        if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n            value = value.toString();\n\n            if (modifier && modifier !== '*') {\n                value = value.substring(0, parseInt(modifier, 10));\n            }\n\n            result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : null));\n        } else {\n            if (modifier === '*') {\n                if (Array.isArray(value)) {\n                    value.filter(isDefined).forEach(function (value) {\n                        result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : null));\n                    });\n                } else {\n                    Object.keys(value).forEach(function (k) {\n                        if (isDefined(value[k])) {\n                            result.push(encodeValue(operator, value[k], k));\n                        }\n                    });\n                }\n            } else {\n                var tmp = [];\n\n                if (Array.isArray(value)) {\n                    value.filter(isDefined).forEach(function (value) {\n                        tmp.push(encodeValue(operator, value));\n                    });\n                } else {\n                    Object.keys(value).forEach(function (k) {\n                        if (isDefined(value[k])) {\n                            tmp.push(encodeURIComponent(k));\n                            tmp.push(encodeValue(operator, value[k].toString()));\n                        }\n                    });\n                }\n\n                if (isKeyOperator(operator)) {\n                    result.push(encodeURIComponent(key) + '=' + tmp.join(','));\n                } else if (tmp.length !== 0) {\n                    result.push(tmp.join(','));\n                }\n            }\n        }\n    } else {\n        if (operator === ';') {\n            result.push(encodeURIComponent(key));\n        } else if (value === '' && (operator === '&' || operator === '?')) {\n            result.push(encodeURIComponent(key) + '=');\n        } else if (value === '') {\n            result.push('');\n        }\n    }\n\n    return result;\n}\n\nfunction isDefined(value) {\n    return value !== undefined && value !== null;\n}\n\nfunction isKeyOperator(operator) {\n    return operator === ';' || operator === '&' || operator === '?';\n}\n\nfunction encodeValue(operator, value, key) {\n\n    value = operator === '+' || operator === '#' ? encodeReserved(value) : encodeURIComponent(value);\n\n    if (key) {\n        return encodeURIComponent(key) + '=' + value;\n    } else {\n        return value;\n    }\n}\n\nfunction encodeReserved(str) {\n    return str.split(/(%[0-9A-Fa-f]{2})/g).map(function (part) {\n        if (!/%[0-9A-Fa-f]/.test(part)) {\n            part = encodeURI(part);\n        }\n        return part;\n    }).join('');\n}\n\n/**\n * URL Template (RFC 6570) Transform.\n */\n\nfunction template (options) {\n\n    var variables = [],\n        url = expand(options.url, options.params, variables);\n\n    variables.forEach(function (key) {\n        delete options.params[key];\n    });\n\n    return url;\n}\n\n/**\n * Service for URL templating.\n */\n\nvar ie = document.documentMode;\nvar el = document.createElement('a');\n\nfunction Url(url, params) {\n\n    var self = this || {},\n        options = url,\n        transform;\n\n    if (isString(url)) {\n        options = { url: url, params: params };\n    }\n\n    options = merge({}, Url.options, self.$options, options);\n\n    Url.transforms.forEach(function (handler) {\n        transform = factory(handler, transform, self.$vm);\n    });\n\n    return transform(options);\n}\n\n/**\n * Url options.\n */\n\nUrl.options = {\n    url: '',\n    root: null,\n    params: {}\n};\n\n/**\n * Url transforms.\n */\n\nUrl.transforms = [template, query, root];\n\n/**\n * Encodes a Url parameter string.\n *\n * @param {Object} obj\n */\n\nUrl.params = function (obj) {\n\n    var params = [],\n        escape = encodeURIComponent;\n\n    params.add = function (key, value) {\n\n        if (isFunction(value)) {\n            value = value();\n        }\n\n        if (value === null) {\n            value = '';\n        }\n\n        this.push(escape(key) + '=' + escape(value));\n    };\n\n    serialize(params, obj);\n\n    return params.join('&').replace(/%20/g, '+');\n};\n\n/**\n * Parse a URL and return its components.\n *\n * @param {String} url\n */\n\nUrl.parse = function (url) {\n\n    if (ie) {\n        el.href = url;\n        url = el.href;\n    }\n\n    el.href = url;\n\n    return {\n        href: el.href,\n        protocol: el.protocol ? el.protocol.replace(/:$/, '') : '',\n        port: el.port,\n        host: el.host,\n        hostname: el.hostname,\n        pathname: el.pathname.charAt(0) === '/' ? el.pathname : '/' + el.pathname,\n        search: el.search ? el.search.replace(/^\\?/, '') : '',\n        hash: el.hash ? el.hash.replace(/^#/, '') : ''\n    };\n};\n\nfunction factory(handler, next, vm) {\n    return function (options) {\n        return handler.call(vm, options, next);\n    };\n}\n\nfunction serialize(params, obj, scope) {\n\n    var array = isArray(obj),\n        plain = isPlainObject(obj),\n        hash;\n\n    each(obj, function (value, key) {\n\n        hash = isObject(value) || isArray(value);\n\n        if (scope) {\n            key = scope + '[' + (plain || hash ? key : '') + ']';\n        }\n\n        if (!scope && array) {\n            params.add(value.name, value.value);\n        } else if (hash) {\n            serialize(params, value, key);\n        } else {\n            params.add(key, value);\n        }\n    });\n}\n\n/**\n * XDomain client (Internet Explorer).\n */\n\nfunction xdrClient (request) {\n    return new PromiseObj(function (resolve) {\n\n        var xdr = new XDomainRequest(),\n            handler = function (_ref) {\n            var type = _ref.type;\n\n\n            var status = 0;\n\n            if (type === 'load') {\n                status = 200;\n            } else if (type === 'error') {\n                status = 500;\n            }\n\n            resolve(request.respondWith(xdr.responseText, { status: status }));\n        };\n\n        request.abort = function () {\n            return xdr.abort();\n        };\n\n        xdr.open(request.method, request.getUrl());\n        xdr.timeout = 0;\n        xdr.onload = handler;\n        xdr.onerror = handler;\n        xdr.ontimeout = handler;\n        xdr.onprogress = function () {};\n        xdr.send(request.getBody());\n    });\n}\n\n/**\n * CORS Interceptor.\n */\n\nvar ORIGIN_URL = Url.parse(location.href);\nvar SUPPORTS_CORS = 'withCredentials' in new XMLHttpRequest();\n\nfunction cors (request, next) {\n\n    if (!isBoolean(request.crossOrigin) && crossOrigin(request)) {\n        request.crossOrigin = true;\n    }\n\n    if (request.crossOrigin) {\n\n        if (!SUPPORTS_CORS) {\n            request.client = xdrClient;\n        }\n\n        delete request.emulateHTTP;\n    }\n\n    next();\n}\n\nfunction crossOrigin(request) {\n\n    var requestUrl = Url.parse(Url(request));\n\n    return requestUrl.protocol !== ORIGIN_URL.protocol || requestUrl.host !== ORIGIN_URL.host;\n}\n\n/**\n * Body Interceptor.\n */\n\nfunction body (request, next) {\n\n    if (isFormData(request.body)) {\n\n        request.headers.delete('Content-Type');\n    } else if (isObject(request.body) || isArray(request.body)) {\n\n        if (request.emulateJSON) {\n            request.body = Url.params(request.body);\n            request.headers.set('Content-Type', 'application/x-www-form-urlencoded');\n        } else {\n            request.body = JSON.stringify(request.body);\n        }\n    }\n\n    next(function (response) {\n\n        Object.defineProperty(response, 'data', {\n            get: function () {\n                return this.body;\n            },\n            set: function (body) {\n                this.body = body;\n            }\n        });\n\n        return response.bodyText ? when(response.text(), function (text) {\n\n            var type = response.headers.get('Content-Type');\n\n            if (isString(type) && type.indexOf('application/json') === 0) {\n\n                try {\n                    response.body = JSON.parse(text);\n                } catch (e) {\n                    response.body = null;\n                }\n            } else {\n                response.body = text;\n            }\n\n            return response;\n        }) : response;\n    });\n}\n\n/**\n * JSONP client.\n */\n\nfunction jsonpClient (request) {\n    return new PromiseObj(function (resolve) {\n\n        var name = request.jsonp || 'callback',\n            callback = '_jsonp' + Math.random().toString(36).substr(2),\n            body = null,\n            handler,\n            script;\n\n        handler = function (_ref) {\n            var type = _ref.type;\n\n\n            var status = 0;\n\n            if (type === 'load' && body !== null) {\n                status = 200;\n            } else if (type === 'error') {\n                status = 500;\n            }\n\n            resolve(request.respondWith(body, { status: status }));\n\n            delete window[callback];\n            document.body.removeChild(script);\n        };\n\n        request.params[name] = callback;\n\n        window[callback] = function (result) {\n            body = JSON.stringify(result);\n        };\n\n        script = document.createElement('script');\n        script.src = request.getUrl();\n        script.type = 'text/javascript';\n        script.async = true;\n        script.onload = handler;\n        script.onerror = handler;\n\n        document.body.appendChild(script);\n    });\n}\n\n/**\n * JSONP Interceptor.\n */\n\nfunction jsonp (request, next) {\n\n    if (request.method == 'JSONP') {\n        request.client = jsonpClient;\n    }\n\n    next(function (response) {\n\n        if (request.method == 'JSONP') {\n\n            return when(response.json(), function (json) {\n\n                response.body = json;\n\n                return response;\n            });\n        }\n    });\n}\n\n/**\n * Before Interceptor.\n */\n\nfunction before (request, next) {\n\n    if (isFunction(request.before)) {\n        request.before.call(this, request);\n    }\n\n    next();\n}\n\n/**\n * HTTP method override Interceptor.\n */\n\nfunction method (request, next) {\n\n    if (request.emulateHTTP && /^(PUT|PATCH|DELETE)$/i.test(request.method)) {\n        request.headers.set('X-HTTP-Method-Override', request.method);\n        request.method = 'POST';\n    }\n\n    next();\n}\n\n/**\n * Header Interceptor.\n */\n\nfunction header (request, next) {\n\n    var headers = assign({}, Http.headers.common, !request.crossOrigin ? Http.headers.custom : {}, Http.headers[toLower(request.method)]);\n\n    each(headers, function (value, name) {\n        if (!request.headers.has(name)) {\n            request.headers.set(name, value);\n        }\n    });\n\n    next();\n}\n\n/**\n * Timeout Interceptor.\n */\n\nfunction timeout (request, next) {\n\n    var timeout;\n\n    if (request.timeout) {\n        timeout = setTimeout(function () {\n            request.abort();\n        }, request.timeout);\n    }\n\n    next(function (response) {\n\n        clearTimeout(timeout);\n    });\n}\n\n/**\n * XMLHttp client.\n */\n\nfunction xhrClient (request) {\n    return new PromiseObj(function (resolve) {\n\n        var xhr = new XMLHttpRequest(),\n            handler = function (event) {\n\n            var response = request.respondWith('response' in xhr ? xhr.response : xhr.responseText, {\n                status: xhr.status === 1223 ? 204 : xhr.status, // IE9 status bug\n                statusText: xhr.status === 1223 ? 'No Content' : trim(xhr.statusText)\n            });\n\n            each(trim(xhr.getAllResponseHeaders()).split('\\n'), function (row) {\n                response.headers.append(row.slice(0, row.indexOf(':')), row.slice(row.indexOf(':') + 1));\n            });\n\n            resolve(response);\n        };\n\n        request.abort = function () {\n            return xhr.abort();\n        };\n\n        if (request.progress) {\n            if (request.method === 'GET') {\n                xhr.addEventListener('progress', request.progress);\n            } else if (/^(POST|PUT)$/i.test(request.method)) {\n                xhr.upload.addEventListener('progress', request.progress);\n            }\n        }\n\n        xhr.open(request.method, request.getUrl(), true);\n\n        if ('responseType' in xhr) {\n            xhr.responseType = 'blob';\n        }\n\n        if (request.credentials === true) {\n            xhr.withCredentials = true;\n        }\n\n        request.headers.forEach(function (value, name) {\n            xhr.setRequestHeader(name, value);\n        });\n\n        xhr.timeout = 0;\n        xhr.onload = handler;\n        xhr.onerror = handler;\n        xhr.send(request.getBody());\n    });\n}\n\n/**\n * Base client.\n */\n\nfunction Client (context) {\n\n    var reqHandlers = [sendRequest],\n        resHandlers = [],\n        handler;\n\n    if (!isObject(context)) {\n        context = null;\n    }\n\n    function Client(request) {\n        return new PromiseObj(function (resolve) {\n\n            function exec() {\n\n                handler = reqHandlers.pop();\n\n                if (isFunction(handler)) {\n                    handler.call(context, request, next);\n                } else {\n                    warn('Invalid interceptor of type ' + typeof handler + ', must be a function');\n                    next();\n                }\n            }\n\n            function next(response) {\n\n                if (isFunction(response)) {\n\n                    resHandlers.unshift(response);\n                } else if (isObject(response)) {\n\n                    resHandlers.forEach(function (handler) {\n                        response = when(response, function (response) {\n                            return handler.call(context, response) || response;\n                        });\n                    });\n\n                    when(response, resolve);\n\n                    return;\n                }\n\n                exec();\n            }\n\n            exec();\n        }, context);\n    }\n\n    Client.use = function (handler) {\n        reqHandlers.push(handler);\n    };\n\n    return Client;\n}\n\nfunction sendRequest(request, resolve) {\n\n    var client = request.client || xhrClient;\n\n    resolve(client(request));\n}\n\nvar classCallCheck = function (instance, Constructor) {\n  if (!(instance instanceof Constructor)) {\n    throw new TypeError(\"Cannot call a class as a function\");\n  }\n};\n\n/**\n * HTTP Headers.\n */\n\nvar Headers = function () {\n    function Headers(headers) {\n        var _this = this;\n\n        classCallCheck(this, Headers);\n\n\n        this.map = {};\n\n        each(headers, function (value, name) {\n            return _this.append(name, value);\n        });\n    }\n\n    Headers.prototype.has = function has(name) {\n        return getName(this.map, name) !== null;\n    };\n\n    Headers.prototype.get = function get(name) {\n\n        var list = this.map[getName(this.map, name)];\n\n        return list ? list[0] : null;\n    };\n\n    Headers.prototype.getAll = function getAll(name) {\n        return this.map[getName(this.map, name)] || [];\n    };\n\n    Headers.prototype.set = function set(name, value) {\n        this.map[normalizeName(getName(this.map, name) || name)] = [trim(value)];\n    };\n\n    Headers.prototype.append = function append(name, value) {\n\n        var list = this.getAll(name);\n\n        if (list.length) {\n            list.push(trim(value));\n        } else {\n            this.set(name, value);\n        }\n    };\n\n    Headers.prototype.delete = function _delete(name) {\n        delete this.map[getName(this.map, name)];\n    };\n\n    Headers.prototype.forEach = function forEach(callback, thisArg) {\n        var _this2 = this;\n\n        each(this.map, function (list, name) {\n            each(list, function (value) {\n                return callback.call(thisArg, value, name, _this2);\n            });\n        });\n    };\n\n    return Headers;\n}();\n\nfunction getName(map, name) {\n    return Object.keys(map).reduce(function (prev, curr) {\n        return toLower(name) === toLower(curr) ? curr : prev;\n    }, null);\n}\n\nfunction normalizeName(name) {\n\n    if (/[^a-z0-9\\-#$%&'*+.\\^_`|~]/i.test(name)) {\n        throw new TypeError('Invalid character in header field name');\n    }\n\n    return trim(name);\n}\n\n/**\n * HTTP Response.\n */\n\nvar Response = function () {\n    function Response(body, _ref) {\n        var url = _ref.url;\n        var headers = _ref.headers;\n        var status = _ref.status;\n        var statusText = _ref.statusText;\n        classCallCheck(this, Response);\n\n\n        this.url = url;\n        this.ok = status >= 200 && status < 300;\n        this.status = status || 0;\n        this.statusText = statusText || '';\n        this.headers = new Headers(headers);\n        this.body = body;\n\n        if (isString(body)) {\n\n            this.bodyText = body;\n        } else if (isBlob(body)) {\n\n            this.bodyBlob = body;\n\n            if (isBlobText(body)) {\n                this.bodyText = blobText(body);\n            }\n        }\n    }\n\n    Response.prototype.blob = function blob() {\n        return when(this.bodyBlob);\n    };\n\n    Response.prototype.text = function text() {\n        return when(this.bodyText);\n    };\n\n    Response.prototype.json = function json() {\n        return when(this.text(), function (text) {\n            return JSON.parse(text);\n        });\n    };\n\n    return Response;\n}();\n\nfunction blobText(body) {\n    return new PromiseObj(function (resolve) {\n\n        var reader = new FileReader();\n\n        reader.readAsText(body);\n        reader.onload = function () {\n            resolve(reader.result);\n        };\n    });\n}\n\nfunction isBlobText(body) {\n    return body.type.indexOf('text') === 0 || body.type.indexOf('json') !== -1;\n}\n\n/**\n * HTTP Request.\n */\n\nvar Request = function () {\n    function Request(options) {\n        classCallCheck(this, Request);\n\n\n        this.body = null;\n        this.params = {};\n\n        assign(this, options, {\n            method: toUpper(options.method || 'GET')\n        });\n\n        if (!(this.headers instanceof Headers)) {\n            this.headers = new Headers(this.headers);\n        }\n    }\n\n    Request.prototype.getUrl = function getUrl() {\n        return Url(this);\n    };\n\n    Request.prototype.getBody = function getBody() {\n        return this.body;\n    };\n\n    Request.prototype.respondWith = function respondWith(body, options) {\n        return new Response(body, assign(options || {}, { url: this.getUrl() }));\n    };\n\n    return Request;\n}();\n\n/**\n * Service for sending network requests.\n */\n\nvar CUSTOM_HEADERS = { 'X-Requested-With': 'XMLHttpRequest' };\nvar COMMON_HEADERS = { 'Accept': 'application/json, text/plain, */*' };\nvar JSON_CONTENT_TYPE = { 'Content-Type': 'application/json;charset=utf-8' };\n\nfunction Http(options) {\n\n    var self = this || {},\n        client = Client(self.$vm);\n\n    defaults(options || {}, self.$options, Http.options);\n\n    Http.interceptors.forEach(function (handler) {\n        client.use(handler);\n    });\n\n    return client(new Request(options)).then(function (response) {\n\n        return response.ok ? response : PromiseObj.reject(response);\n    }, function (response) {\n\n        if (response instanceof Error) {\n            error(response);\n        }\n\n        return PromiseObj.reject(response);\n    });\n}\n\nHttp.options = {};\n\nHttp.headers = {\n    put: JSON_CONTENT_TYPE,\n    post: JSON_CONTENT_TYPE,\n    patch: JSON_CONTENT_TYPE,\n    delete: JSON_CONTENT_TYPE,\n    custom: CUSTOM_HEADERS,\n    common: COMMON_HEADERS\n};\n\nHttp.interceptors = [before, timeout, method, body, jsonp, header, cors];\n\n['get', 'delete', 'head', 'jsonp'].forEach(function (method) {\n\n    Http[method] = function (url, options) {\n        return this(assign(options || {}, { url: url, method: method }));\n    };\n});\n\n['post', 'put', 'patch'].forEach(function (method) {\n\n    Http[method] = function (url, body, options) {\n        return this(assign(options || {}, { url: url, method: method, body: body }));\n    };\n});\n\n/**\n * Service for interacting with RESTful services.\n */\n\nfunction Resource(url, params, actions, options) {\n\n    var self = this || {},\n        resource = {};\n\n    actions = assign({}, Resource.actions, actions);\n\n    each(actions, function (action, name) {\n\n        action = merge({ url: url, params: assign({}, params) }, options, action);\n\n        resource[name] = function () {\n            return (self.$http || Http)(opts(action, arguments));\n        };\n    });\n\n    return resource;\n}\n\nfunction opts(action, args) {\n\n    var options = assign({}, action),\n        params = {},\n        body;\n\n    switch (args.length) {\n\n        case 2:\n\n            params = args[0];\n            body = args[1];\n\n            break;\n\n        case 1:\n\n            if (/^(POST|PUT|PATCH)$/i.test(options.method)) {\n                body = args[0];\n            } else {\n                params = args[0];\n            }\n\n            break;\n\n        case 0:\n\n            break;\n\n        default:\n\n            throw 'Expected up to 4 arguments [params, body], got ' + args.length + ' arguments';\n    }\n\n    options.body = body;\n    options.params = assign({}, options.params, params);\n\n    return options;\n}\n\nResource.actions = {\n\n    get: { method: 'GET' },\n    save: { method: 'POST' },\n    query: { method: 'GET' },\n    update: { method: 'PUT' },\n    remove: { method: 'DELETE' },\n    delete: { method: 'DELETE' }\n\n};\n\n/**\n * Install plugin.\n */\n\nfunction plugin(Vue) {\n\n    if (plugin.installed) {\n        return;\n    }\n\n    Util(Vue);\n\n    Vue.url = Url;\n    Vue.http = Http;\n    Vue.resource = Resource;\n    Vue.Promise = PromiseObj;\n\n    Object.defineProperties(Vue.prototype, {\n\n        $url: {\n            get: function () {\n                return options(Vue.url, this, this.$options.url);\n            }\n        },\n\n        $http: {\n            get: function () {\n                return options(Vue.http, this, this.$options.http);\n            }\n        },\n\n        $resource: {\n            get: function () {\n                return Vue.resource.bind(this);\n            }\n        },\n\n        $promise: {\n            get: function () {\n                var _this = this;\n\n                return function (executor) {\n                    return new Vue.Promise(executor, _this);\n                };\n            }\n        }\n\n    });\n}\n\nif (typeof window !== 'undefined' && window.Vue) {\n    window.Vue.use(plugin);\n}\n\nmodule.exports = plugin;\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L3Z1ZS1yZXNvdXJjZS9kaXN0L3Z1ZS1yZXNvdXJjZS5jb21tb24uanM/MmYxMyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsdUJBQXVCLHFCQUFxQjtBQUM1QztBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQSx1QkFBdUIscUJBQXFCO0FBQzVDO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNB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Q0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixTQUFTO0FBQ1Q7O0FBRUE7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esc0RBQXNELEdBQUcscUJBQXFCO0FBQzlFOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUEsc0JBQXNCO0FBQ3RCLHNCQUFzQjtBQUN0Qix5QkFBeUIsbUNBQW1DOztBQUU1RDs7QUFFQSx5QkFBeUI7QUFDekI7O0FBRUEsMEJBQTBCOztBQUUxQjtBQUNBO0FBQ0EsS0FBSzs7QUFFTDs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQSx3Q0FBd0MsR0FBRywyQkFBMkI7QUFDdEU7QUFDQSxDQUFDOztBQUVEOztBQUVBO0FBQ0Esd0NBQXdDLEdBQUcsdUNBQXVDO0FBQ2xGO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEseUJBQXlCO0FBQ3pCOztBQUVBLHVCQUF1Qjs7QUFFdkI7O0FBRUEsd0JBQXdCLDRCQUE0QixXQUFXOztBQUUvRDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7O0FBRUEsMkJBQTJCO0FBQzNCLG1CQUFtQjtBQUNuQjs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsOEJBQThCOztBQUU5QjtBQUNBOztBQUVBOztBQUVBLFVBQVUsZ0JBQWdCO0FBQzFCLFdBQVcsaUJBQWlCO0FBQzVCLFlBQVksZ0JBQWdCO0FBQzVCLGFBQWEsZ0JBQWdCO0FBQzdCLGFBQWEsbUJBQW1CO0FBQ2hDLGFBQWE7O0FBRWI7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBIiwiZmlsZSI6IjEwLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiB2dWUtcmVzb3VyY2UgdjEuMC4zXG4gKiBodHRwczovL2dpdGh1Yi5jb20vdnVlanMvdnVlLXJlc291cmNlXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIFByb21pc2VzL0ErIHBvbHlmaWxsIHYxLjEuNCAoaHR0cHM6Ly9naXRodWIuY29tL2JyYW1zdGVpbi9wcm9taXMpXG4gKi9cblxudmFyIFJFU09MVkVEID0gMDtcbnZhciBSRUpFQ1RFRCA9IDE7XG52YXIgUEVORElORyA9IDI7XG5cbmZ1bmN0aW9uIFByb21pc2UkMShleGVjdXRvcikge1xuXG4gICAgdGhpcy5zdGF0ZSA9IFBFTkRJTkc7XG4gICAgdGhpcy52YWx1ZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmRlZmVycmVkID0gW107XG5cbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG5cbiAgICB0cnkge1xuICAgICAgICBleGVjdXRvcihmdW5jdGlvbiAoeCkge1xuICAgICAgICAgICAgcHJvbWlzZS5yZXNvbHZlKHgpO1xuICAgICAgICB9LCBmdW5jdGlvbiAocikge1xuICAgICAgICAgICAgcHJvbWlzZS5yZWplY3Qocik7XG4gICAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcHJvbWlzZS5yZWplY3QoZSk7XG4gICAgfVxufVxuXG5Qcm9taXNlJDEucmVqZWN0ID0gZnVuY3Rpb24gKHIpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHJlamVjdChyKTtcbiAgICB9KTtcbn07XG5cblByb21pc2UkMS5yZXNvbHZlID0gZnVuY3Rpb24gKHgpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHJlc29sdmUoeCk7XG4gICAgfSk7XG59O1xuXG5Qcm9taXNlJDEuYWxsID0gZnVuY3Rpb24gYWxsKGl0ZXJhYmxlKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICB2YXIgY291bnQgPSAwLFxuICAgICAgICAgICAgcmVzdWx0ID0gW107XG5cbiAgICAgICAgaWYgKGl0ZXJhYmxlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gcmVzb2x2ZXIoaSkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh4KSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0W2ldID0geDtcbiAgICAgICAgICAgICAgICBjb3VudCArPSAxO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNvdW50ID09PSBpdGVyYWJsZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZXJhYmxlLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBQcm9taXNlJDEucmVzb2x2ZShpdGVyYWJsZVtpXSkudGhlbihyZXNvbHZlcihpKSwgcmVqZWN0KTtcbiAgICAgICAgfVxuICAgIH0pO1xufTtcblxuUHJvbWlzZSQxLnJhY2UgPSBmdW5jdGlvbiByYWNlKGl0ZXJhYmxlKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZXJhYmxlLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBQcm9taXNlJDEucmVzb2x2ZShpdGVyYWJsZVtpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuXG52YXIgcCQxID0gUHJvbWlzZSQxLnByb3RvdHlwZTtcblxucCQxLnJlc29sdmUgPSBmdW5jdGlvbiByZXNvbHZlKHgpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG5cbiAgICBpZiAocHJvbWlzZS5zdGF0ZSA9PT0gUEVORElORykge1xuICAgICAgICBpZiAoeCA9PT0gcHJvbWlzZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUHJvbWlzZSBzZXR0bGVkIHdpdGggaXRzZWxmLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YXIgdGhlbiA9IHggJiYgeFsndGhlbiddO1xuXG4gICAgICAgICAgICBpZiAoeCAhPT0gbnVsbCAmJiB0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICB0aGVuLmNhbGwoeCwgZnVuY3Rpb24gKHgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYWxsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2UucmVzb2x2ZSh4KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChyKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY2FsbGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlLnJlamVjdChyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaWYgKCFjYWxsZWQpIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlLnJlamVjdChlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb21pc2Uuc3RhdGUgPSBSRVNPTFZFRDtcbiAgICAgICAgcHJvbWlzZS52YWx1ZSA9IHg7XG4gICAgICAgIHByb21pc2Uubm90aWZ5KCk7XG4gICAgfVxufTtcblxucCQxLnJlamVjdCA9IGZ1bmN0aW9uIHJlamVjdChyZWFzb24pIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG5cbiAgICBpZiAocHJvbWlzZS5zdGF0ZSA9PT0gUEVORElORykge1xuICAgICAgICBpZiAocmVhc29uID09PSBwcm9taXNlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdQcm9taXNlIHNldHRsZWQgd2l0aCBpdHNlbGYuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBwcm9taXNlLnN0YXRlID0gUkVKRUNURUQ7XG4gICAgICAgIHByb21pc2UudmFsdWUgPSByZWFzb247XG4gICAgICAgIHByb21pc2Uubm90aWZ5KCk7XG4gICAgfVxufTtcblxucCQxLm5vdGlmeSA9IGZ1bmN0aW9uIG5vdGlmeSgpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG5cbiAgICBuZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChwcm9taXNlLnN0YXRlICE9PSBQRU5ESU5HKSB7XG4gICAgICAgICAgICB3aGlsZSAocHJvbWlzZS5kZWZlcnJlZC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVmZXJyZWQgPSBwcm9taXNlLmRlZmVycmVkLnNoaWZ0KCksXG4gICAgICAgICAgICAgICAgICAgIG9uUmVzb2x2ZWQgPSBkZWZlcnJlZFswXSxcbiAgICAgICAgICAgICAgICAgICAgb25SZWplY3RlZCA9IGRlZmVycmVkWzFdLFxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlID0gZGVmZXJyZWRbMl0sXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdCA9IGRlZmVycmVkWzNdO1xuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb21pc2Uuc3RhdGUgPT09IFJFU09MVkVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9uUmVzb2x2ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG9uUmVzb2x2ZWQuY2FsbCh1bmRlZmluZWQsIHByb21pc2UudmFsdWUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShwcm9taXNlLnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwcm9taXNlLnN0YXRlID09PSBSRUpFQ1RFRCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvblJlamVjdGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShvblJlamVjdGVkLmNhbGwodW5kZWZpbmVkLCBwcm9taXNlLnZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChwcm9taXNlLnZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xufTtcblxucCQxLnRoZW4gPSBmdW5jdGlvbiB0aGVuKG9uUmVzb2x2ZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICB2YXIgcHJvbWlzZSA9IHRoaXM7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHByb21pc2UuZGVmZXJyZWQucHVzaChbb25SZXNvbHZlZCwgb25SZWplY3RlZCwgcmVzb2x2ZSwgcmVqZWN0XSk7XG4gICAgICAgIHByb21pc2Uubm90aWZ5KCk7XG4gICAgfSk7XG59O1xuXG5wJDEuY2F0Y2ggPSBmdW5jdGlvbiAob25SZWplY3RlZCkge1xuICAgIHJldHVybiB0aGlzLnRoZW4odW5kZWZpbmVkLCBvblJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogUHJvbWlzZSBhZGFwdGVyLlxuICovXG5cbmlmICh0eXBlb2YgUHJvbWlzZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB3aW5kb3cuUHJvbWlzZSA9IFByb21pc2UkMTtcbn1cblxuZnVuY3Rpb24gUHJvbWlzZU9iaihleGVjdXRvciwgY29udGV4dCkge1xuXG4gICAgaWYgKGV4ZWN1dG9yIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICB0aGlzLnByb21pc2UgPSBleGVjdXRvcjtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnByb21pc2UgPSBuZXcgUHJvbWlzZShleGVjdXRvci5iaW5kKGNvbnRleHQpKTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xufVxuXG5Qcm9taXNlT2JqLmFsbCA9IGZ1bmN0aW9uIChpdGVyYWJsZSwgY29udGV4dCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZU9iaihQcm9taXNlLmFsbChpdGVyYWJsZSksIGNvbnRleHQpO1xufTtcblxuUHJvbWlzZU9iai5yZXNvbHZlID0gZnVuY3Rpb24gKHZhbHVlLCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlT2JqKFByb21pc2UucmVzb2x2ZSh2YWx1ZSksIGNvbnRleHQpO1xufTtcblxuUHJvbWlzZU9iai5yZWplY3QgPSBmdW5jdGlvbiAocmVhc29uLCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlT2JqKFByb21pc2UucmVqZWN0KHJlYXNvbiksIGNvbnRleHQpO1xufTtcblxuUHJvbWlzZU9iai5yYWNlID0gZnVuY3Rpb24gKGl0ZXJhYmxlLCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlT2JqKFByb21pc2UucmFjZShpdGVyYWJsZSksIGNvbnRleHQpO1xufTtcblxudmFyIHAgPSBQcm9taXNlT2JqLnByb3RvdHlwZTtcblxucC5iaW5kID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIHJldHVybiB0aGlzO1xufTtcblxucC50aGVuID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpIHtcblxuICAgIGlmIChmdWxmaWxsZWQgJiYgZnVsZmlsbGVkLmJpbmQgJiYgdGhpcy5jb250ZXh0KSB7XG4gICAgICAgIGZ1bGZpbGxlZCA9IGZ1bGZpbGxlZC5iaW5kKHRoaXMuY29udGV4dCk7XG4gICAgfVxuXG4gICAgaWYgKHJlamVjdGVkICYmIHJlamVjdGVkLmJpbmQgJiYgdGhpcy5jb250ZXh0KSB7XG4gICAgICAgIHJlamVjdGVkID0gcmVqZWN0ZWQuYmluZCh0aGlzLmNvbnRleHQpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJvbWlzZU9iaih0aGlzLnByb21pc2UudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKSwgdGhpcy5jb250ZXh0KTtcbn07XG5cbnAuY2F0Y2ggPSBmdW5jdGlvbiAocmVqZWN0ZWQpIHtcblxuICAgIGlmIChyZWplY3RlZCAmJiByZWplY3RlZC5iaW5kICYmIHRoaXMuY29udGV4dCkge1xuICAgICAgICByZWplY3RlZCA9IHJlamVjdGVkLmJpbmQodGhpcy5jb250ZXh0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2VPYmoodGhpcy5wcm9taXNlLmNhdGNoKHJlamVjdGVkKSwgdGhpcy5jb250ZXh0KTtcbn07XG5cbnAuZmluYWxseSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuXG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgY2FsbGJhY2suY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgY2FsbGJhY2suY2FsbCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHJlYXNvbik7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb25zLlxuICovXG5cbnZhciBkZWJ1ZyA9IGZhbHNlO3ZhciB1dGlsID0ge307dmFyIHNsaWNlID0gW10uc2xpY2U7XG5cblxuZnVuY3Rpb24gVXRpbCAoVnVlKSB7XG4gICAgdXRpbCA9IFZ1ZS51dGlsO1xuICAgIGRlYnVnID0gVnVlLmNvbmZpZy5kZWJ1ZyB8fCAhVnVlLmNvbmZpZy5zaWxlbnQ7XG59XG5cbmZ1bmN0aW9uIHdhcm4obXNnKSB7XG4gICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJiBkZWJ1Zykge1xuICAgICAgICBjb25zb2xlLndhcm4oJ1tWdWVSZXNvdXJjZSB3YXJuXTogJyArIG1zZyk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBlcnJvcihtc2cpIHtcbiAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobXNnKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIG5leHRUaWNrKGNiLCBjdHgpIHtcbiAgICByZXR1cm4gdXRpbC5uZXh0VGljayhjYiwgY3R4KTtcbn1cblxuZnVuY3Rpb24gdHJpbShzdHIpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMqfFxccyokL2csICcnKTtcbn1cblxuZnVuY3Rpb24gdG9Mb3dlcihzdHIpIHtcbiAgICByZXR1cm4gc3RyID8gc3RyLnRvTG93ZXJDYXNlKCkgOiAnJztcbn1cblxuZnVuY3Rpb24gdG9VcHBlcihzdHIpIHtcbiAgICByZXR1cm4gc3RyID8gc3RyLnRvVXBwZXJDYXNlKCkgOiAnJztcbn1cblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG5mdW5jdGlvbiBpc1N0cmluZyh2YWwpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbCA9PT0gJ3N0cmluZyc7XG59XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbih2YWwpIHtcbiAgICByZXR1cm4gdmFsID09PSB0cnVlIHx8IHZhbCA9PT0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KG9iaikge1xuICAgIHJldHVybiBvYmogIT09IG51bGwgJiYgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCc7XG59XG5cbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3Qob2JqKSB7XG4gICAgcmV0dXJuIGlzT2JqZWN0KG9iaikgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iaikgPT0gT2JqZWN0LnByb3RvdHlwZTtcbn1cblxuZnVuY3Rpb24gaXNCbG9iKG9iaikge1xuICAgIHJldHVybiB0eXBlb2YgQmxvYiAhPT0gJ3VuZGVmaW5lZCcgJiYgb2JqIGluc3RhbmNlb2YgQmxvYjtcbn1cblxuZnVuY3Rpb24gaXNGb3JtRGF0YShvYmopIHtcbiAgICByZXR1cm4gdHlwZW9mIEZvcm1EYXRhICE9PSAndW5kZWZpbmVkJyAmJiBvYmogaW5zdGFuY2VvZiBGb3JtRGF0YTtcbn1cblxuZnVuY3Rpb24gd2hlbih2YWx1ZSwgZnVsZmlsbGVkLCByZWplY3RlZCkge1xuXG4gICAgdmFyIHByb21pc2UgPSBQcm9taXNlT2JqLnJlc29sdmUodmFsdWUpO1xuXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNlLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7XG59XG5cbmZ1bmN0aW9uIG9wdGlvbnMoZm4sIG9iaiwgb3B0cykge1xuXG4gICAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgICBpZiAoaXNGdW5jdGlvbihvcHRzKSkge1xuICAgICAgICBvcHRzID0gb3B0cy5jYWxsKG9iaik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1lcmdlKGZuLmJpbmQoeyAkdm06IG9iaiwgJG9wdGlvbnM6IG9wdHMgfSksIGZuLCB7ICRvcHRpb25zOiBvcHRzIH0pO1xufVxuXG5mdW5jdGlvbiBlYWNoKG9iaiwgaXRlcmF0b3IpIHtcblxuICAgIHZhciBpLCBrZXk7XG5cbiAgICBpZiAob2JqICYmIHR5cGVvZiBvYmoubGVuZ3RoID09ICdudW1iZXInKSB7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yLmNhbGwob2JqW2ldLCBvYmpbaV0sIGkpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChpc09iamVjdChvYmopKSB7XG4gICAgICAgIGZvciAoa2V5IGluIG9iaikge1xuICAgICAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgaXRlcmF0b3IuY2FsbChvYmpba2V5XSwgb2JqW2tleV0sIGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb2JqO1xufVxuXG52YXIgYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBfYXNzaWduO1xuXG5mdW5jdGlvbiBtZXJnZSh0YXJnZXQpIHtcblxuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgYXJncy5mb3JFYWNoKGZ1bmN0aW9uIChzb3VyY2UpIHtcbiAgICAgICAgX21lcmdlKHRhcmdldCwgc291cmNlLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0YXJnZXQ7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRzKHRhcmdldCkge1xuXG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cbiAgICBhcmdzLmZvckVhY2goZnVuY3Rpb24gKHNvdXJjZSkge1xuXG4gICAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgICAgIGlmICh0YXJnZXRba2V5XSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRhcmdldDtcbn1cblxuZnVuY3Rpb24gX2Fzc2lnbih0YXJnZXQpIHtcblxuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgYXJncy5mb3JFYWNoKGZ1bmN0aW9uIChzb3VyY2UpIHtcbiAgICAgICAgX21lcmdlKHRhcmdldCwgc291cmNlKTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0YXJnZXQ7XG59XG5cbmZ1bmN0aW9uIF9tZXJnZSh0YXJnZXQsIHNvdXJjZSwgZGVlcCkge1xuICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKGRlZXAgJiYgKGlzUGxhaW5PYmplY3Qoc291cmNlW2tleV0pIHx8IGlzQXJyYXkoc291cmNlW2tleV0pKSkge1xuICAgICAgICAgICAgaWYgKGlzUGxhaW5PYmplY3Qoc291cmNlW2tleV0pICYmICFpc1BsYWluT2JqZWN0KHRhcmdldFtrZXldKSkge1xuICAgICAgICAgICAgICAgIHRhcmdldFtrZXldID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNBcnJheShzb3VyY2Vba2V5XSkgJiYgIWlzQXJyYXkodGFyZ2V0W2tleV0pKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9tZXJnZSh0YXJnZXRba2V5XSwgc291cmNlW2tleV0sIGRlZXApO1xuICAgICAgICB9IGVsc2UgaWYgKHNvdXJjZVtrZXldICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV07XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogUm9vdCBQcmVmaXggVHJhbnNmb3JtLlxuICovXG5cbmZ1bmN0aW9uIHJvb3QgKG9wdGlvbnMsIG5leHQpIHtcblxuICAgIHZhciB1cmwgPSBuZXh0KG9wdGlvbnMpO1xuXG4gICAgaWYgKGlzU3RyaW5nKG9wdGlvbnMucm9vdCkgJiYgIXVybC5tYXRjaCgvXihodHRwcz86KT9cXC8vKSkge1xuICAgICAgICB1cmwgPSBvcHRpb25zLnJvb3QgKyAnLycgKyB1cmw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVybDtcbn1cblxuLyoqXG4gKiBRdWVyeSBQYXJhbWV0ZXIgVHJhbnNmb3JtLlxuICovXG5cbmZ1bmN0aW9uIHF1ZXJ5IChvcHRpb25zLCBuZXh0KSB7XG5cbiAgICB2YXIgdXJsUGFyYW1zID0gT2JqZWN0LmtleXMoVXJsLm9wdGlvbnMucGFyYW1zKSxcbiAgICAgICAgcXVlcnkgPSB7fSxcbiAgICAgICAgdXJsID0gbmV4dChvcHRpb25zKTtcblxuICAgIGVhY2gob3B0aW9ucy5wYXJhbXMsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICAgIGlmICh1cmxQYXJhbXMuaW5kZXhPZihrZXkpID09PSAtMSkge1xuICAgICAgICAgICAgcXVlcnlba2V5XSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICBxdWVyeSA9IFVybC5wYXJhbXMocXVlcnkpO1xuXG4gICAgaWYgKHF1ZXJ5KSB7XG4gICAgICAgIHVybCArPSAodXJsLmluZGV4T2YoJz8nKSA9PSAtMSA/ICc/JyA6ICcmJykgKyBxdWVyeTtcbiAgICB9XG5cbiAgICByZXR1cm4gdXJsO1xufVxuXG4vKipcbiAqIFVSTCBUZW1wbGF0ZSB2Mi4wLjYgKGh0dHBzOi8vZ2l0aHViLmNvbS9icmFtc3RlaW4vdXJsLXRlbXBsYXRlKVxuICovXG5cbmZ1bmN0aW9uIGV4cGFuZCh1cmwsIHBhcmFtcywgdmFyaWFibGVzKSB7XG5cbiAgICB2YXIgdG1wbCA9IHBhcnNlKHVybCksXG4gICAgICAgIGV4cGFuZGVkID0gdG1wbC5leHBhbmQocGFyYW1zKTtcblxuICAgIGlmICh2YXJpYWJsZXMpIHtcbiAgICAgICAgdmFyaWFibGVzLnB1c2guYXBwbHkodmFyaWFibGVzLCB0bXBsLnZhcnMpO1xuICAgIH1cblxuICAgIHJldHVybiBleHBhbmRlZDtcbn1cblxuZnVuY3Rpb24gcGFyc2UodGVtcGxhdGUpIHtcblxuICAgIHZhciBvcGVyYXRvcnMgPSBbJysnLCAnIycsICcuJywgJy8nLCAnOycsICc/JywgJyYnXSxcbiAgICAgICAgdmFyaWFibGVzID0gW107XG5cbiAgICByZXR1cm4ge1xuICAgICAgICB2YXJzOiB2YXJpYWJsZXMsXG4gICAgICAgIGV4cGFuZDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZS5yZXBsYWNlKC9cXHsoW15cXHtcXH1dKylcXH18KFteXFx7XFx9XSspL2csIGZ1bmN0aW9uIChfLCBleHByZXNzaW9uLCBsaXRlcmFsKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV4cHJlc3Npb24pIHtcblxuICAgICAgICAgICAgICAgICAgICB2YXIgb3BlcmF0b3IgPSBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gW107XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZXJhdG9ycy5pbmRleE9mKGV4cHJlc3Npb24uY2hhckF0KDApKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yID0gZXhwcmVzc2lvbi5jaGFyQXQoMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uID0gZXhwcmVzc2lvbi5zdWJzdHIoMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uLnNwbGl0KC8sL2cpLmZvckVhY2goZnVuY3Rpb24gKHZhcmlhYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG1wID0gLyhbXjpcXCpdKikoPzo6KFxcZCspfChcXCopKT8vLmV4ZWModmFyaWFibGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzLnB1c2guYXBwbHkodmFsdWVzLCBnZXRWYWx1ZXMoY29udGV4dCwgb3BlcmF0b3IsIHRtcFsxXSwgdG1wWzJdIHx8IHRtcFszXSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVzLnB1c2godG1wWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZXJhdG9yICYmIG9wZXJhdG9yICE9PSAnKycpIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNlcGFyYXRvciA9ICcsJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wZXJhdG9yID09PSAnPycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXBhcmF0b3IgPSAnJic7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG9wZXJhdG9yICE9PSAnIycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXBhcmF0b3IgPSBvcGVyYXRvcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh2YWx1ZXMubGVuZ3RoICE9PSAwID8gb3BlcmF0b3IgOiAnJykgKyB2YWx1ZXMuam9pbihzZXBhcmF0b3IpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlcy5qb2luKCcsJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW5jb2RlUmVzZXJ2ZWQobGl0ZXJhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuXG5mdW5jdGlvbiBnZXRWYWx1ZXMoY29udGV4dCwgb3BlcmF0b3IsIGtleSwgbW9kaWZpZXIpIHtcblxuICAgIHZhciB2YWx1ZSA9IGNvbnRleHRba2V5XSxcbiAgICAgICAgcmVzdWx0ID0gW107XG5cbiAgICBpZiAoaXNEZWZpbmVkKHZhbHVlKSAmJiB2YWx1ZSAhPT0gJycpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS50b1N0cmluZygpO1xuXG4gICAgICAgICAgICBpZiAobW9kaWZpZXIgJiYgbW9kaWZpZXIgIT09ICcqJykge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc3Vic3RyaW5nKDAsIHBhcnNlSW50KG1vZGlmaWVyLCAxMCkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXN1bHQucHVzaChlbmNvZGVWYWx1ZShvcGVyYXRvciwgdmFsdWUsIGlzS2V5T3BlcmF0b3Iob3BlcmF0b3IpID8ga2V5IDogbnVsbCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKG1vZGlmaWVyID09PSAnKicpIHtcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUuZmlsdGVyKGlzRGVmaW5lZCkuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGVuY29kZVZhbHVlKG9wZXJhdG9yLCB2YWx1ZSwgaXNLZXlPcGVyYXRvcihvcGVyYXRvcikgPyBrZXkgOiBudWxsKSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKHZhbHVlKS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNEZWZpbmVkKHZhbHVlW2tdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGVuY29kZVZhbHVlKG9wZXJhdG9yLCB2YWx1ZVtrXSwgaykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciB0bXAgPSBbXTtcblxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZS5maWx0ZXIoaXNEZWZpbmVkKS5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG1wLnB1c2goZW5jb2RlVmFsdWUob3BlcmF0b3IsIHZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKHZhbHVlKS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNEZWZpbmVkKHZhbHVlW2tdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcC5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChrKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wLnB1c2goZW5jb2RlVmFsdWUob3BlcmF0b3IsIHZhbHVlW2tdLnRvU3RyaW5nKCkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGlzS2V5T3BlcmF0b3Iob3BlcmF0b3IpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChrZXkpICsgJz0nICsgdG1wLmpvaW4oJywnKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0bXAubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHRtcC5qb2luKCcsJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChvcGVyYXRvciA9PT0gJzsnKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaChlbmNvZGVVUklDb21wb25lbnQoa2V5KSk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICcnICYmIChvcGVyYXRvciA9PT0gJyYnIHx8IG9wZXJhdG9yID09PSAnPycpKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaChlbmNvZGVVUklDb21wb25lbnQoa2V5KSArICc9Jyk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICcnKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaCgnJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBpc0RlZmluZWQodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNLZXlPcGVyYXRvcihvcGVyYXRvcikge1xuICAgIHJldHVybiBvcGVyYXRvciA9PT0gJzsnIHx8IG9wZXJhdG9yID09PSAnJicgfHwgb3BlcmF0b3IgPT09ICc/Jztcbn1cblxuZnVuY3Rpb24gZW5jb2RlVmFsdWUob3BlcmF0b3IsIHZhbHVlLCBrZXkpIHtcblxuICAgIHZhbHVlID0gb3BlcmF0b3IgPT09ICcrJyB8fCBvcGVyYXRvciA9PT0gJyMnID8gZW5jb2RlUmVzZXJ2ZWQodmFsdWUpIDogZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcblxuICAgIGlmIChrZXkpIHtcbiAgICAgICAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChrZXkpICsgJz0nICsgdmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZW5jb2RlUmVzZXJ2ZWQoc3RyKSB7XG4gICAgcmV0dXJuIHN0ci5zcGxpdCgvKCVbMC05QS1GYS1mXXsyfSkvZykubWFwKGZ1bmN0aW9uIChwYXJ0KSB7XG4gICAgICAgIGlmICghLyVbMC05QS1GYS1mXS8udGVzdChwYXJ0KSkge1xuICAgICAgICAgICAgcGFydCA9IGVuY29kZVVSSShwYXJ0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFydDtcbiAgICB9KS5qb2luKCcnKTtcbn1cblxuLyoqXG4gKiBVUkwgVGVtcGxhdGUgKFJGQyA2NTcwKSBUcmFuc2Zvcm0uXG4gKi9cblxuZnVuY3Rpb24gdGVtcGxhdGUgKG9wdGlvbnMpIHtcblxuICAgIHZhciB2YXJpYWJsZXMgPSBbXSxcbiAgICAgICAgdXJsID0gZXhwYW5kKG9wdGlvbnMudXJsLCBvcHRpb25zLnBhcmFtcywgdmFyaWFibGVzKTtcblxuICAgIHZhcmlhYmxlcy5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgZGVsZXRlIG9wdGlvbnMucGFyYW1zW2tleV07XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdXJsO1xufVxuXG4vKipcbiAqIFNlcnZpY2UgZm9yIFVSTCB0ZW1wbGF0aW5nLlxuICovXG5cbnZhciBpZSA9IGRvY3VtZW50LmRvY3VtZW50TW9kZTtcbnZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcblxuZnVuY3Rpb24gVXJsKHVybCwgcGFyYW1zKSB7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXMgfHwge30sXG4gICAgICAgIG9wdGlvbnMgPSB1cmwsXG4gICAgICAgIHRyYW5zZm9ybTtcblxuICAgIGlmIChpc1N0cmluZyh1cmwpKSB7XG4gICAgICAgIG9wdGlvbnMgPSB7IHVybDogdXJsLCBwYXJhbXM6IHBhcmFtcyB9O1xuICAgIH1cblxuICAgIG9wdGlvbnMgPSBtZXJnZSh7fSwgVXJsLm9wdGlvbnMsIHNlbGYuJG9wdGlvbnMsIG9wdGlvbnMpO1xuXG4gICAgVXJsLnRyYW5zZm9ybXMuZm9yRWFjaChmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgICAgICB0cmFuc2Zvcm0gPSBmYWN0b3J5KGhhbmRsZXIsIHRyYW5zZm9ybSwgc2VsZi4kdm0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRyYW5zZm9ybShvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBVcmwgb3B0aW9ucy5cbiAqL1xuXG5Vcmwub3B0aW9ucyA9IHtcbiAgICB1cmw6ICcnLFxuICAgIHJvb3Q6IG51bGwsXG4gICAgcGFyYW1zOiB7fVxufTtcblxuLyoqXG4gKiBVcmwgdHJhbnNmb3Jtcy5cbiAqL1xuXG5VcmwudHJhbnNmb3JtcyA9IFt0ZW1wbGF0ZSwgcXVlcnksIHJvb3RdO1xuXG4vKipcbiAqIEVuY29kZXMgYSBVcmwgcGFyYW1ldGVyIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKi9cblxuVXJsLnBhcmFtcyA9IGZ1bmN0aW9uIChvYmopIHtcblxuICAgIHZhciBwYXJhbXMgPSBbXSxcbiAgICAgICAgZXNjYXBlID0gZW5jb2RlVVJJQ29tcG9uZW50O1xuXG4gICAgcGFyYW1zLmFkZCA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG5cbiAgICAgICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhbHVlID0gJyc7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnB1c2goZXNjYXBlKGtleSkgKyAnPScgKyBlc2NhcGUodmFsdWUpKTtcbiAgICB9O1xuXG4gICAgc2VyaWFsaXplKHBhcmFtcywgb2JqKTtcblxuICAgIHJldHVybiBwYXJhbXMuam9pbignJicpLnJlcGxhY2UoLyUyMC9nLCAnKycpO1xufTtcblxuLyoqXG4gKiBQYXJzZSBhIFVSTCBhbmQgcmV0dXJuIGl0cyBjb21wb25lbnRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqL1xuXG5VcmwucGFyc2UgPSBmdW5jdGlvbiAodXJsKSB7XG5cbiAgICBpZiAoaWUpIHtcbiAgICAgICAgZWwuaHJlZiA9IHVybDtcbiAgICAgICAgdXJsID0gZWwuaHJlZjtcbiAgICB9XG5cbiAgICBlbC5ocmVmID0gdXJsO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgaHJlZjogZWwuaHJlZixcbiAgICAgICAgcHJvdG9jb2w6IGVsLnByb3RvY29sID8gZWwucHJvdG9jb2wucmVwbGFjZSgvOiQvLCAnJykgOiAnJyxcbiAgICAgICAgcG9ydDogZWwucG9ydCxcbiAgICAgICAgaG9zdDogZWwuaG9zdCxcbiAgICAgICAgaG9zdG5hbWU6IGVsLmhvc3RuYW1lLFxuICAgICAgICBwYXRobmFtZTogZWwucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycgPyBlbC5wYXRobmFtZSA6ICcvJyArIGVsLnBhdGhuYW1lLFxuICAgICAgICBzZWFyY2g6IGVsLnNlYXJjaCA/IGVsLnNlYXJjaC5yZXBsYWNlKC9eXFw/LywgJycpIDogJycsXG4gICAgICAgIGhhc2g6IGVsLmhhc2ggPyBlbC5oYXNoLnJlcGxhY2UoL14jLywgJycpIDogJydcbiAgICB9O1xufTtcblxuZnVuY3Rpb24gZmFjdG9yeShoYW5kbGVyLCBuZXh0LCB2bSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gaGFuZGxlci5jYWxsKHZtLCBvcHRpb25zLCBuZXh0KTtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBzZXJpYWxpemUocGFyYW1zLCBvYmosIHNjb3BlKSB7XG5cbiAgICB2YXIgYXJyYXkgPSBpc0FycmF5KG9iaiksXG4gICAgICAgIHBsYWluID0gaXNQbGFpbk9iamVjdChvYmopLFxuICAgICAgICBoYXNoO1xuXG4gICAgZWFjaChvYmosIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG5cbiAgICAgICAgaGFzaCA9IGlzT2JqZWN0KHZhbHVlKSB8fCBpc0FycmF5KHZhbHVlKTtcblxuICAgICAgICBpZiAoc2NvcGUpIHtcbiAgICAgICAgICAgIGtleSA9IHNjb3BlICsgJ1snICsgKHBsYWluIHx8IGhhc2ggPyBrZXkgOiAnJykgKyAnXSc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXNjb3BlICYmIGFycmF5KSB7XG4gICAgICAgICAgICBwYXJhbXMuYWRkKHZhbHVlLm5hbWUsIHZhbHVlLnZhbHVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChoYXNoKSB7XG4gICAgICAgICAgICBzZXJpYWxpemUocGFyYW1zLCB2YWx1ZSwga2V5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhcmFtcy5hZGQoa2V5LCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuLyoqXG4gKiBYRG9tYWluIGNsaWVudCAoSW50ZXJuZXQgRXhwbG9yZXIpLlxuICovXG5cbmZ1bmN0aW9uIHhkckNsaWVudCAocmVxdWVzdCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZU9iaihmdW5jdGlvbiAocmVzb2x2ZSkge1xuXG4gICAgICAgIHZhciB4ZHIgPSBuZXcgWERvbWFpblJlcXVlc3QoKSxcbiAgICAgICAgICAgIGhhbmRsZXIgPSBmdW5jdGlvbiAoX3JlZikge1xuICAgICAgICAgICAgdmFyIHR5cGUgPSBfcmVmLnR5cGU7XG5cblxuICAgICAgICAgICAgdmFyIHN0YXR1cyA9IDA7XG5cbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnbG9hZCcpIHtcbiAgICAgICAgICAgICAgICBzdGF0dXMgPSAyMDA7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdlcnJvcicpIHtcbiAgICAgICAgICAgICAgICBzdGF0dXMgPSA1MDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJlc29sdmUocmVxdWVzdC5yZXNwb25kV2l0aCh4ZHIucmVzcG9uc2VUZXh0LCB7IHN0YXR1czogc3RhdHVzIH0pKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZXF1ZXN0LmFib3J0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHhkci5hYm9ydCgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHhkci5vcGVuKHJlcXVlc3QubWV0aG9kLCByZXF1ZXN0LmdldFVybCgpKTtcbiAgICAgICAgeGRyLnRpbWVvdXQgPSAwO1xuICAgICAgICB4ZHIub25sb2FkID0gaGFuZGxlcjtcbiAgICAgICAgeGRyLm9uZXJyb3IgPSBoYW5kbGVyO1xuICAgICAgICB4ZHIub250aW1lb3V0ID0gaGFuZGxlcjtcbiAgICAgICAgeGRyLm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgeGRyLnNlbmQocmVxdWVzdC5nZXRCb2R5KCkpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIENPUlMgSW50ZXJjZXB0b3IuXG4gKi9cblxudmFyIE9SSUdJTl9VUkwgPSBVcmwucGFyc2UobG9jYXRpb24uaHJlZik7XG52YXIgU1VQUE9SVFNfQ09SUyA9ICd3aXRoQ3JlZGVudGlhbHMnIGluIG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuXG5mdW5jdGlvbiBjb3JzIChyZXF1ZXN0LCBuZXh0KSB7XG5cbiAgICBpZiAoIWlzQm9vbGVhbihyZXF1ZXN0LmNyb3NzT3JpZ2luKSAmJiBjcm9zc09yaWdpbihyZXF1ZXN0KSkge1xuICAgICAgICByZXF1ZXN0LmNyb3NzT3JpZ2luID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAocmVxdWVzdC5jcm9zc09yaWdpbikge1xuXG4gICAgICAgIGlmICghU1VQUE9SVFNfQ09SUykge1xuICAgICAgICAgICAgcmVxdWVzdC5jbGllbnQgPSB4ZHJDbGllbnQ7XG4gICAgICAgIH1cblxuICAgICAgICBkZWxldGUgcmVxdWVzdC5lbXVsYXRlSFRUUDtcbiAgICB9XG5cbiAgICBuZXh0KCk7XG59XG5cbmZ1bmN0aW9uIGNyb3NzT3JpZ2luKHJlcXVlc3QpIHtcblxuICAgIHZhciByZXF1ZXN0VXJsID0gVXJsLnBhcnNlKFVybChyZXF1ZXN0KSk7XG5cbiAgICByZXR1cm4gcmVxdWVzdFVybC5wcm90b2NvbCAhPT0gT1JJR0lOX1VSTC5wcm90b2NvbCB8fCByZXF1ZXN0VXJsLmhvc3QgIT09IE9SSUdJTl9VUkwuaG9zdDtcbn1cblxuLyoqXG4gKiBCb2R5IEludGVyY2VwdG9yLlxuICovXG5cbmZ1bmN0aW9uIGJvZHkgKHJlcXVlc3QsIG5leHQpIHtcblxuICAgIGlmIChpc0Zvcm1EYXRhKHJlcXVlc3QuYm9keSkpIHtcblxuICAgICAgICByZXF1ZXN0LmhlYWRlcnMuZGVsZXRlKCdDb250ZW50LVR5cGUnKTtcbiAgICB9IGVsc2UgaWYgKGlzT2JqZWN0KHJlcXVlc3QuYm9keSkgfHwgaXNBcnJheShyZXF1ZXN0LmJvZHkpKSB7XG5cbiAgICAgICAgaWYgKHJlcXVlc3QuZW11bGF0ZUpTT04pIHtcbiAgICAgICAgICAgIHJlcXVlc3QuYm9keSA9IFVybC5wYXJhbXMocmVxdWVzdC5ib2R5KTtcbiAgICAgICAgICAgIHJlcXVlc3QuaGVhZGVycy5zZXQoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcXVlc3QuYm9keSA9IEpTT04uc3RyaW5naWZ5KHJlcXVlc3QuYm9keSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuZXh0KGZ1bmN0aW9uIChyZXNwb25zZSkge1xuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXNwb25zZSwgJ2RhdGEnLCB7XG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5ib2R5O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmJvZHkgPSBib2R5O1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmVzcG9uc2UuYm9keVRleHQgPyB3aGVuKHJlc3BvbnNlLnRleHQoKSwgZnVuY3Rpb24gKHRleHQpIHtcblxuICAgICAgICAgICAgdmFyIHR5cGUgPSByZXNwb25zZS5oZWFkZXJzLmdldCgnQ29udGVudC1UeXBlJyk7XG5cbiAgICAgICAgICAgIGlmIChpc1N0cmluZyh0eXBlKSAmJiB0eXBlLmluZGV4T2YoJ2FwcGxpY2F0aW9uL2pzb24nKSA9PT0gMCkge1xuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuYm9keSA9IEpTT04ucGFyc2UodGV4dCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5ib2R5ID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlLmJvZHkgPSB0ZXh0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgIH0pIDogcmVzcG9uc2U7XG4gICAgfSk7XG59XG5cbi8qKlxuICogSlNPTlAgY2xpZW50LlxuICovXG5cbmZ1bmN0aW9uIGpzb25wQ2xpZW50IChyZXF1ZXN0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlT2JqKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG5cbiAgICAgICAgdmFyIG5hbWUgPSByZXF1ZXN0Lmpzb25wIHx8ICdjYWxsYmFjaycsXG4gICAgICAgICAgICBjYWxsYmFjayA9ICdfanNvbnAnICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyKDIpLFxuICAgICAgICAgICAgYm9keSA9IG51bGwsXG4gICAgICAgICAgICBoYW5kbGVyLFxuICAgICAgICAgICAgc2NyaXB0O1xuXG4gICAgICAgIGhhbmRsZXIgPSBmdW5jdGlvbiAoX3JlZikge1xuICAgICAgICAgICAgdmFyIHR5cGUgPSBfcmVmLnR5cGU7XG5cblxuICAgICAgICAgICAgdmFyIHN0YXR1cyA9IDA7XG5cbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnbG9hZCcgJiYgYm9keSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHN0YXR1cyA9IDIwMDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgICAgICAgIHN0YXR1cyA9IDUwMDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmVzb2x2ZShyZXF1ZXN0LnJlc3BvbmRXaXRoKGJvZHksIHsgc3RhdHVzOiBzdGF0dXMgfSkpO1xuXG4gICAgICAgICAgICBkZWxldGUgd2luZG93W2NhbGxiYWNrXTtcbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgfTtcblxuICAgICAgICByZXF1ZXN0LnBhcmFtc1tuYW1lXSA9IGNhbGxiYWNrO1xuXG4gICAgICAgIHdpbmRvd1tjYWxsYmFja10gPSBmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgICBib2R5ID0gSlNPTi5zdHJpbmdpZnkocmVzdWx0KTtcbiAgICAgICAgfTtcblxuICAgICAgICBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcbiAgICAgICAgc2NyaXB0LnNyYyA9IHJlcXVlc3QuZ2V0VXJsKCk7XG4gICAgICAgIHNjcmlwdC50eXBlID0gJ3RleHQvamF2YXNjcmlwdCc7XG4gICAgICAgIHNjcmlwdC5hc3luYyA9IHRydWU7XG4gICAgICAgIHNjcmlwdC5vbmxvYWQgPSBoYW5kbGVyO1xuICAgICAgICBzY3JpcHQub25lcnJvciA9IGhhbmRsZXI7XG5cbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEpTT05QIEludGVyY2VwdG9yLlxuICovXG5cbmZ1bmN0aW9uIGpzb25wIChyZXF1ZXN0LCBuZXh0KSB7XG5cbiAgICBpZiAocmVxdWVzdC5tZXRob2QgPT0gJ0pTT05QJykge1xuICAgICAgICByZXF1ZXN0LmNsaWVudCA9IGpzb25wQ2xpZW50O1xuICAgIH1cblxuICAgIG5leHQoZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG5cbiAgICAgICAgaWYgKHJlcXVlc3QubWV0aG9kID09ICdKU09OUCcpIHtcblxuICAgICAgICAgICAgcmV0dXJuIHdoZW4ocmVzcG9uc2UuanNvbigpLCBmdW5jdGlvbiAoanNvbikge1xuXG4gICAgICAgICAgICAgICAgcmVzcG9uc2UuYm9keSA9IGpzb247XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG4vKipcbiAqIEJlZm9yZSBJbnRlcmNlcHRvci5cbiAqL1xuXG5mdW5jdGlvbiBiZWZvcmUgKHJlcXVlc3QsIG5leHQpIHtcblxuICAgIGlmIChpc0Z1bmN0aW9uKHJlcXVlc3QuYmVmb3JlKSkge1xuICAgICAgICByZXF1ZXN0LmJlZm9yZS5jYWxsKHRoaXMsIHJlcXVlc3QpO1xuICAgIH1cblxuICAgIG5leHQoKTtcbn1cblxuLyoqXG4gKiBIVFRQIG1ldGhvZCBvdmVycmlkZSBJbnRlcmNlcHRvci5cbiAqL1xuXG5mdW5jdGlvbiBtZXRob2QgKHJlcXVlc3QsIG5leHQpIHtcblxuICAgIGlmIChyZXF1ZXN0LmVtdWxhdGVIVFRQICYmIC9eKFBVVHxQQVRDSHxERUxFVEUpJC9pLnRlc3QocmVxdWVzdC5tZXRob2QpKSB7XG4gICAgICAgIHJlcXVlc3QuaGVhZGVycy5zZXQoJ1gtSFRUUC1NZXRob2QtT3ZlcnJpZGUnLCByZXF1ZXN0Lm1ldGhvZCk7XG4gICAgICAgIHJlcXVlc3QubWV0aG9kID0gJ1BPU1QnO1xuICAgIH1cblxuICAgIG5leHQoKTtcbn1cblxuLyoqXG4gKiBIZWFkZXIgSW50ZXJjZXB0b3IuXG4gKi9cblxuZnVuY3Rpb24gaGVhZGVyIChyZXF1ZXN0LCBuZXh0KSB7XG5cbiAgICB2YXIgaGVhZGVycyA9IGFzc2lnbih7fSwgSHR0cC5oZWFkZXJzLmNvbW1vbiwgIXJlcXVlc3QuY3Jvc3NPcmlnaW4gPyBIdHRwLmhlYWRlcnMuY3VzdG9tIDoge30sIEh0dHAuaGVhZGVyc1t0b0xvd2VyKHJlcXVlc3QubWV0aG9kKV0pO1xuXG4gICAgZWFjaChoZWFkZXJzLCBmdW5jdGlvbiAodmFsdWUsIG5hbWUpIHtcbiAgICAgICAgaWYgKCFyZXF1ZXN0LmhlYWRlcnMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICByZXF1ZXN0LmhlYWRlcnMuc2V0KG5hbWUsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgbmV4dCgpO1xufVxuXG4vKipcbiAqIFRpbWVvdXQgSW50ZXJjZXB0b3IuXG4gKi9cblxuZnVuY3Rpb24gdGltZW91dCAocmVxdWVzdCwgbmV4dCkge1xuXG4gICAgdmFyIHRpbWVvdXQ7XG5cbiAgICBpZiAocmVxdWVzdC50aW1lb3V0KSB7XG4gICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlcXVlc3QuYWJvcnQoKTtcbiAgICAgICAgfSwgcmVxdWVzdC50aW1lb3V0KTtcbiAgICB9XG5cbiAgICBuZXh0KGZ1bmN0aW9uIChyZXNwb25zZSkge1xuXG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBYTUxIdHRwIGNsaWVudC5cbiAqL1xuXG5mdW5jdGlvbiB4aHJDbGllbnQgKHJlcXVlc3QpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2VPYmooZnVuY3Rpb24gKHJlc29sdmUpIHtcblxuICAgICAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCksXG4gICAgICAgICAgICBoYW5kbGVyID0gZnVuY3Rpb24gKGV2ZW50KSB7XG5cbiAgICAgICAgICAgIHZhciByZXNwb25zZSA9IHJlcXVlc3QucmVzcG9uZFdpdGgoJ3Jlc3BvbnNlJyBpbiB4aHIgPyB4aHIucmVzcG9uc2UgOiB4aHIucmVzcG9uc2VUZXh0LCB7XG4gICAgICAgICAgICAgICAgc3RhdHVzOiB4aHIuc3RhdHVzID09PSAxMjIzID8gMjA0IDogeGhyLnN0YXR1cywgLy8gSUU5IHN0YXR1cyBidWdcbiAgICAgICAgICAgICAgICBzdGF0dXNUZXh0OiB4aHIuc3RhdHVzID09PSAxMjIzID8gJ05vIENvbnRlbnQnIDogdHJpbSh4aHIuc3RhdHVzVGV4dClcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBlYWNoKHRyaW0oeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpKS5zcGxpdCgnXFxuJyksIGZ1bmN0aW9uIChyb3cpIHtcbiAgICAgICAgICAgICAgICByZXNwb25zZS5oZWFkZXJzLmFwcGVuZChyb3cuc2xpY2UoMCwgcm93LmluZGV4T2YoJzonKSksIHJvdy5zbGljZShyb3cuaW5kZXhPZignOicpICsgMSkpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJlcXVlc3QuYWJvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4geGhyLmFib3J0KCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHJlcXVlc3QucHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgIGlmIChyZXF1ZXN0Lm1ldGhvZCA9PT0gJ0dFVCcpIHtcbiAgICAgICAgICAgICAgICB4aHIuYWRkRXZlbnRMaXN0ZW5lcigncHJvZ3Jlc3MnLCByZXF1ZXN0LnByb2dyZXNzKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoL14oUE9TVHxQVVQpJC9pLnRlc3QocmVxdWVzdC5tZXRob2QpKSB7XG4gICAgICAgICAgICAgICAgeGhyLnVwbG9hZC5hZGRFdmVudExpc3RlbmVyKCdwcm9ncmVzcycsIHJlcXVlc3QucHJvZ3Jlc3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgeGhyLm9wZW4ocmVxdWVzdC5tZXRob2QsIHJlcXVlc3QuZ2V0VXJsKCksIHRydWUpO1xuXG4gICAgICAgIGlmICgncmVzcG9uc2VUeXBlJyBpbiB4aHIpIHtcbiAgICAgICAgICAgIHhoci5yZXNwb25zZVR5cGUgPSAnYmxvYic7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVxdWVzdC5jcmVkZW50aWFscyA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgeGhyLndpdGhDcmVkZW50aWFscyA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0LmhlYWRlcnMuZm9yRWFjaChmdW5jdGlvbiAodmFsdWUsIG5hbWUpIHtcbiAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKG5hbWUsIHZhbHVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgeGhyLnRpbWVvdXQgPSAwO1xuICAgICAgICB4aHIub25sb2FkID0gaGFuZGxlcjtcbiAgICAgICAgeGhyLm9uZXJyb3IgPSBoYW5kbGVyO1xuICAgICAgICB4aHIuc2VuZChyZXF1ZXN0LmdldEJvZHkoKSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogQmFzZSBjbGllbnQuXG4gKi9cblxuZnVuY3Rpb24gQ2xpZW50IChjb250ZXh0KSB7XG5cbiAgICB2YXIgcmVxSGFuZGxlcnMgPSBbc2VuZFJlcXVlc3RdLFxuICAgICAgICByZXNIYW5kbGVycyA9IFtdLFxuICAgICAgICBoYW5kbGVyO1xuXG4gICAgaWYgKCFpc09iamVjdChjb250ZXh0KSkge1xuICAgICAgICBjb250ZXh0ID0gbnVsbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBDbGllbnQocmVxdWVzdCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2VPYmooZnVuY3Rpb24gKHJlc29sdmUpIHtcblxuICAgICAgICAgICAgZnVuY3Rpb24gZXhlYygpIHtcblxuICAgICAgICAgICAgICAgIGhhbmRsZXIgPSByZXFIYW5kbGVycy5wb3AoKTtcblxuICAgICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuY2FsbChjb250ZXh0LCByZXF1ZXN0LCBuZXh0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB3YXJuKCdJbnZhbGlkIGludGVyY2VwdG9yIG9mIHR5cGUgJyArIHR5cGVvZiBoYW5kbGVyICsgJywgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgICAgICAgICAgICAgIG5leHQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIG5leHQocmVzcG9uc2UpIHtcblxuICAgICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHJlc3BvbnNlKSkge1xuXG4gICAgICAgICAgICAgICAgICAgIHJlc0hhbmRsZXJzLnVuc2hpZnQocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPYmplY3QocmVzcG9uc2UpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzSGFuZGxlcnMuZm9yRWFjaChmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSB3aGVuKHJlc3BvbnNlLCBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlci5jYWxsKGNvbnRleHQsIHJlc3BvbnNlKSB8fCByZXNwb25zZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICB3aGVuKHJlc3BvbnNlLCByZXNvbHZlKTtcblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZXhlYygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBleGVjKCk7XG4gICAgICAgIH0sIGNvbnRleHQpO1xuICAgIH1cblxuICAgIENsaWVudC51c2UgPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICAgICAgICByZXFIYW5kbGVycy5wdXNoKGhhbmRsZXIpO1xuICAgIH07XG5cbiAgICByZXR1cm4gQ2xpZW50O1xufVxuXG5mdW5jdGlvbiBzZW5kUmVxdWVzdChyZXF1ZXN0LCByZXNvbHZlKSB7XG5cbiAgICB2YXIgY2xpZW50ID0gcmVxdWVzdC5jbGllbnQgfHwgeGhyQ2xpZW50O1xuXG4gICAgcmVzb2x2ZShjbGllbnQocmVxdWVzdCkpO1xufVxuXG52YXIgY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7XG4gIGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTtcbiAgfVxufTtcblxuLyoqXG4gKiBIVFRQIEhlYWRlcnMuXG4gKi9cblxudmFyIEhlYWRlcnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gSGVhZGVycyhoZWFkZXJzKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgY2xhc3NDYWxsQ2hlY2sodGhpcywgSGVhZGVycyk7XG5cblxuICAgICAgICB0aGlzLm1hcCA9IHt9O1xuXG4gICAgICAgIGVhY2goaGVhZGVycywgZnVuY3Rpb24gKHZhbHVlLCBuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuYXBwZW5kKG5hbWUsIHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgSGVhZGVycy5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24gaGFzKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGdldE5hbWUodGhpcy5tYXAsIG5hbWUpICE9PSBudWxsO1xuICAgIH07XG5cbiAgICBIZWFkZXJzLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiBnZXQobmFtZSkge1xuXG4gICAgICAgIHZhciBsaXN0ID0gdGhpcy5tYXBbZ2V0TmFtZSh0aGlzLm1hcCwgbmFtZSldO1xuXG4gICAgICAgIHJldHVybiBsaXN0ID8gbGlzdFswXSA6IG51bGw7XG4gICAgfTtcblxuICAgIEhlYWRlcnMucHJvdG90eXBlLmdldEFsbCA9IGZ1bmN0aW9uIGdldEFsbChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcFtnZXROYW1lKHRoaXMubWFwLCBuYW1lKV0gfHwgW107XG4gICAgfTtcblxuICAgIEhlYWRlcnMucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIHNldChuYW1lLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLm1hcFtub3JtYWxpemVOYW1lKGdldE5hbWUodGhpcy5tYXAsIG5hbWUpIHx8IG5hbWUpXSA9IFt0cmltKHZhbHVlKV07XG4gICAgfTtcblxuICAgIEhlYWRlcnMucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uIGFwcGVuZChuYW1lLCB2YWx1ZSkge1xuXG4gICAgICAgIHZhciBsaXN0ID0gdGhpcy5nZXRBbGwobmFtZSk7XG5cbiAgICAgICAgaWYgKGxpc3QubGVuZ3RoKSB7XG4gICAgICAgICAgICBsaXN0LnB1c2godHJpbSh2YWx1ZSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXQobmFtZSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIEhlYWRlcnMucHJvdG90eXBlLmRlbGV0ZSA9IGZ1bmN0aW9uIF9kZWxldGUobmFtZSkge1xuICAgICAgICBkZWxldGUgdGhpcy5tYXBbZ2V0TmFtZSh0aGlzLm1hcCwgbmFtZSldO1xuICAgIH07XG5cbiAgICBIZWFkZXJzLnByb3RvdHlwZS5mb3JFYWNoID0gZnVuY3Rpb24gZm9yRWFjaChjYWxsYmFjaywgdGhpc0FyZykge1xuICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICBlYWNoKHRoaXMubWFwLCBmdW5jdGlvbiAobGlzdCwgbmFtZSkge1xuICAgICAgICAgICAgZWFjaChsaXN0LCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB2YWx1ZSwgbmFtZSwgX3RoaXMyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEhlYWRlcnM7XG59KCk7XG5cbmZ1bmN0aW9uIGdldE5hbWUobWFwLCBuYW1lKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKG1hcCkucmVkdWNlKGZ1bmN0aW9uIChwcmV2LCBjdXJyKSB7XG4gICAgICAgIHJldHVybiB0b0xvd2VyKG5hbWUpID09PSB0b0xvd2VyKGN1cnIpID8gY3VyciA6IHByZXY7XG4gICAgfSwgbnVsbCk7XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZU5hbWUobmFtZSkge1xuXG4gICAgaWYgKC9bXmEtejAtOVxcLSMkJSYnKisuXFxeX2B8fl0vaS50ZXN0KG5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgY2hhcmFjdGVyIGluIGhlYWRlciBmaWVsZCBuYW1lJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRyaW0obmFtZSk7XG59XG5cbi8qKlxuICogSFRUUCBSZXNwb25zZS5cbiAqL1xuXG52YXIgUmVzcG9uc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gUmVzcG9uc2UoYm9keSwgX3JlZikge1xuICAgICAgICB2YXIgdXJsID0gX3JlZi51cmw7XG4gICAgICAgIHZhciBoZWFkZXJzID0gX3JlZi5oZWFkZXJzO1xuICAgICAgICB2YXIgc3RhdHVzID0gX3JlZi5zdGF0dXM7XG4gICAgICAgIHZhciBzdGF0dXNUZXh0ID0gX3JlZi5zdGF0dXNUZXh0O1xuICAgICAgICBjbGFzc0NhbGxDaGVjayh0aGlzLCBSZXNwb25zZSk7XG5cblxuICAgICAgICB0aGlzLnVybCA9IHVybDtcbiAgICAgICAgdGhpcy5vayA9IHN0YXR1cyA+PSAyMDAgJiYgc3RhdHVzIDwgMzAwO1xuICAgICAgICB0aGlzLnN0YXR1cyA9IHN0YXR1cyB8fCAwO1xuICAgICAgICB0aGlzLnN0YXR1c1RleHQgPSBzdGF0dXNUZXh0IHx8ICcnO1xuICAgICAgICB0aGlzLmhlYWRlcnMgPSBuZXcgSGVhZGVycyhoZWFkZXJzKTtcbiAgICAgICAgdGhpcy5ib2R5ID0gYm9keTtcblxuICAgICAgICBpZiAoaXNTdHJpbmcoYm9keSkpIHtcblxuICAgICAgICAgICAgdGhpcy5ib2R5VGV4dCA9IGJvZHk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNCbG9iKGJvZHkpKSB7XG5cbiAgICAgICAgICAgIHRoaXMuYm9keUJsb2IgPSBib2R5O1xuXG4gICAgICAgICAgICBpZiAoaXNCbG9iVGV4dChib2R5KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYm9keVRleHQgPSBibG9iVGV4dChib2R5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIFJlc3BvbnNlLnByb3RvdHlwZS5ibG9iID0gZnVuY3Rpb24gYmxvYigpIHtcbiAgICAgICAgcmV0dXJuIHdoZW4odGhpcy5ib2R5QmxvYik7XG4gICAgfTtcblxuICAgIFJlc3BvbnNlLnByb3RvdHlwZS50ZXh0ID0gZnVuY3Rpb24gdGV4dCgpIHtcbiAgICAgICAgcmV0dXJuIHdoZW4odGhpcy5ib2R5VGV4dCk7XG4gICAgfTtcblxuICAgIFJlc3BvbnNlLnByb3RvdHlwZS5qc29uID0gZnVuY3Rpb24ganNvbigpIHtcbiAgICAgICAgcmV0dXJuIHdoZW4odGhpcy50ZXh0KCksIGZ1bmN0aW9uICh0ZXh0KSB7XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZSh0ZXh0KTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIHJldHVybiBSZXNwb25zZTtcbn0oKTtcblxuZnVuY3Rpb24gYmxvYlRleHQoYm9keSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZU9iaihmdW5jdGlvbiAocmVzb2x2ZSkge1xuXG4gICAgICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuXG4gICAgICAgIHJlYWRlci5yZWFkQXNUZXh0KGJvZHkpO1xuICAgICAgICByZWFkZXIub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVzb2x2ZShyZWFkZXIucmVzdWx0KTtcbiAgICAgICAgfTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gaXNCbG9iVGV4dChib2R5KSB7XG4gICAgcmV0dXJuIGJvZHkudHlwZS5pbmRleE9mKCd0ZXh0JykgPT09IDAgfHwgYm9keS50eXBlLmluZGV4T2YoJ2pzb24nKSAhPT0gLTE7XG59XG5cbi8qKlxuICogSFRUUCBSZXF1ZXN0LlxuICovXG5cbnZhciBSZXF1ZXN0ID0gZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFJlcXVlc3Qob3B0aW9ucykge1xuICAgICAgICBjbGFzc0NhbGxDaGVjayh0aGlzLCBSZXF1ZXN0KTtcblxuXG4gICAgICAgIHRoaXMuYm9keSA9IG51bGw7XG4gICAgICAgIHRoaXMucGFyYW1zID0ge307XG5cbiAgICAgICAgYXNzaWduKHRoaXMsIG9wdGlvbnMsIHtcbiAgICAgICAgICAgIG1ldGhvZDogdG9VcHBlcihvcHRpb25zLm1ldGhvZCB8fCAnR0VUJylcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCEodGhpcy5oZWFkZXJzIGluc3RhbmNlb2YgSGVhZGVycykpIHtcbiAgICAgICAgICAgIHRoaXMuaGVhZGVycyA9IG5ldyBIZWFkZXJzKHRoaXMuaGVhZGVycyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBSZXF1ZXN0LnByb3RvdHlwZS5nZXRVcmwgPSBmdW5jdGlvbiBnZXRVcmwoKSB7XG4gICAgICAgIHJldHVybiBVcmwodGhpcyk7XG4gICAgfTtcblxuICAgIFJlcXVlc3QucHJvdG90eXBlLmdldEJvZHkgPSBmdW5jdGlvbiBnZXRCb2R5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ib2R5O1xuICAgIH07XG5cbiAgICBSZXF1ZXN0LnByb3RvdHlwZS5yZXNwb25kV2l0aCA9IGZ1bmN0aW9uIHJlc3BvbmRXaXRoKGJvZHksIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShib2R5LCBhc3NpZ24ob3B0aW9ucyB8fCB7fSwgeyB1cmw6IHRoaXMuZ2V0VXJsKCkgfSkpO1xuICAgIH07XG5cbiAgICByZXR1cm4gUmVxdWVzdDtcbn0oKTtcblxuLyoqXG4gKiBTZXJ2aWNlIGZvciBzZW5kaW5nIG5ldHdvcmsgcmVxdWVzdHMuXG4gKi9cblxudmFyIENVU1RPTV9IRUFERVJTID0geyAnWC1SZXF1ZXN0ZWQtV2l0aCc6ICdYTUxIdHRwUmVxdWVzdCcgfTtcbnZhciBDT01NT05fSEVBREVSUyA9IHsgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L3BsYWluLCAqLyonIH07XG52YXIgSlNPTl9DT05URU5UX1RZUEUgPSB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04JyB9O1xuXG5mdW5jdGlvbiBIdHRwKG9wdGlvbnMpIHtcblxuICAgIHZhciBzZWxmID0gdGhpcyB8fCB7fSxcbiAgICAgICAgY2xpZW50ID0gQ2xpZW50KHNlbGYuJHZtKTtcblxuICAgIGRlZmF1bHRzKG9wdGlvbnMgfHwge30sIHNlbGYuJG9wdGlvbnMsIEh0dHAub3B0aW9ucyk7XG5cbiAgICBIdHRwLmludGVyY2VwdG9ycy5mb3JFYWNoKGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gICAgICAgIGNsaWVudC51c2UoaGFuZGxlcik7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY2xpZW50KG5ldyBSZXF1ZXN0KG9wdGlvbnMpKS50aGVuKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuXG4gICAgICAgIHJldHVybiByZXNwb25zZS5vayA/IHJlc3BvbnNlIDogUHJvbWlzZU9iai5yZWplY3QocmVzcG9uc2UpO1xuICAgIH0sIGZ1bmN0aW9uIChyZXNwb25zZSkge1xuXG4gICAgICAgIGlmIChyZXNwb25zZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICBlcnJvcihyZXNwb25zZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUHJvbWlzZU9iai5yZWplY3QocmVzcG9uc2UpO1xuICAgIH0pO1xufVxuXG5IdHRwLm9wdGlvbnMgPSB7fTtcblxuSHR0cC5oZWFkZXJzID0ge1xuICAgIHB1dDogSlNPTl9DT05URU5UX1RZUEUsXG4gICAgcG9zdDogSlNPTl9DT05URU5UX1RZUEUsXG4gICAgcGF0Y2g6IEpTT05fQ09OVEVOVF9UWVBFLFxuICAgIGRlbGV0ZTogSlNPTl9DT05URU5UX1RZUEUsXG4gICAgY3VzdG9tOiBDVVNUT01fSEVBREVSUyxcbiAgICBjb21tb246IENPTU1PTl9IRUFERVJTXG59O1xuXG5IdHRwLmludGVyY2VwdG9ycyA9IFtiZWZvcmUsIHRpbWVvdXQsIG1ldGhvZCwgYm9keSwganNvbnAsIGhlYWRlciwgY29yc107XG5cblsnZ2V0JywgJ2RlbGV0ZScsICdoZWFkJywgJ2pzb25wJ10uZm9yRWFjaChmdW5jdGlvbiAobWV0aG9kKSB7XG5cbiAgICBIdHRwW21ldGhvZF0gPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzKGFzc2lnbihvcHRpb25zIHx8IHt9LCB7IHVybDogdXJsLCBtZXRob2Q6IG1ldGhvZCB9KSk7XG4gICAgfTtcbn0pO1xuXG5bJ3Bvc3QnLCAncHV0JywgJ3BhdGNoJ10uZm9yRWFjaChmdW5jdGlvbiAobWV0aG9kKSB7XG5cbiAgICBIdHRwW21ldGhvZF0gPSBmdW5jdGlvbiAodXJsLCBib2R5LCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzKGFzc2lnbihvcHRpb25zIHx8IHt9LCB7IHVybDogdXJsLCBtZXRob2Q6IG1ldGhvZCwgYm9keTogYm9keSB9KSk7XG4gICAgfTtcbn0pO1xuXG4vKipcbiAqIFNlcnZpY2UgZm9yIGludGVyYWN0aW5nIHdpdGggUkVTVGZ1bCBzZXJ2aWNlcy5cbiAqL1xuXG5mdW5jdGlvbiBSZXNvdXJjZSh1cmwsIHBhcmFtcywgYWN0aW9ucywgb3B0aW9ucykge1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzIHx8IHt9LFxuICAgICAgICByZXNvdXJjZSA9IHt9O1xuXG4gICAgYWN0aW9ucyA9IGFzc2lnbih7fSwgUmVzb3VyY2UuYWN0aW9ucywgYWN0aW9ucyk7XG5cbiAgICBlYWNoKGFjdGlvbnMsIGZ1bmN0aW9uIChhY3Rpb24sIG5hbWUpIHtcblxuICAgICAgICBhY3Rpb24gPSBtZXJnZSh7IHVybDogdXJsLCBwYXJhbXM6IGFzc2lnbih7fSwgcGFyYW1zKSB9LCBvcHRpb25zLCBhY3Rpb24pO1xuXG4gICAgICAgIHJlc291cmNlW25hbWVdID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIChzZWxmLiRodHRwIHx8IEh0dHApKG9wdHMoYWN0aW9uLCBhcmd1bWVudHMpKTtcbiAgICAgICAgfTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXNvdXJjZTtcbn1cblxuZnVuY3Rpb24gb3B0cyhhY3Rpb24sIGFyZ3MpIHtcblxuICAgIHZhciBvcHRpb25zID0gYXNzaWduKHt9LCBhY3Rpb24pLFxuICAgICAgICBwYXJhbXMgPSB7fSxcbiAgICAgICAgYm9keTtcblxuICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcblxuICAgICAgICBjYXNlIDI6XG5cbiAgICAgICAgICAgIHBhcmFtcyA9IGFyZ3NbMF07XG4gICAgICAgICAgICBib2R5ID0gYXJnc1sxXTtcblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAxOlxuXG4gICAgICAgICAgICBpZiAoL14oUE9TVHxQVVR8UEFUQ0gpJC9pLnRlc3Qob3B0aW9ucy5tZXRob2QpKSB7XG4gICAgICAgICAgICAgICAgYm9keSA9IGFyZ3NbMF07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmFtcyA9IGFyZ3NbMF07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgMDpcblxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgZGVmYXVsdDpcblxuICAgICAgICAgICAgdGhyb3cgJ0V4cGVjdGVkIHVwIHRvIDQgYXJndW1lbnRzIFtwYXJhbXMsIGJvZHldLCBnb3QgJyArIGFyZ3MubGVuZ3RoICsgJyBhcmd1bWVudHMnO1xuICAgIH1cblxuICAgIG9wdGlvbnMuYm9keSA9IGJvZHk7XG4gICAgb3B0aW9ucy5wYXJhbXMgPSBhc3NpZ24oe30sIG9wdGlvbnMucGFyYW1zLCBwYXJhbXMpO1xuXG4gICAgcmV0dXJuIG9wdGlvbnM7XG59XG5cblJlc291cmNlLmFjdGlvbnMgPSB7XG5cbiAgICBnZXQ6IHsgbWV0aG9kOiAnR0VUJyB9LFxuICAgIHNhdmU6IHsgbWV0aG9kOiAnUE9TVCcgfSxcbiAgICBxdWVyeTogeyBtZXRob2Q6ICdHRVQnIH0sXG4gICAgdXBkYXRlOiB7IG1ldGhvZDogJ1BVVCcgfSxcbiAgICByZW1vdmU6IHsgbWV0aG9kOiAnREVMRVRFJyB9LFxuICAgIGRlbGV0ZTogeyBtZXRob2Q6ICdERUxFVEUnIH1cblxufTtcblxuLyoqXG4gKiBJbnN0YWxsIHBsdWdpbi5cbiAqL1xuXG5mdW5jdGlvbiBwbHVnaW4oVnVlKSB7XG5cbiAgICBpZiAocGx1Z2luLmluc3RhbGxlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgVXRpbChWdWUpO1xuXG4gICAgVnVlLnVybCA9IFVybDtcbiAgICBWdWUuaHR0cCA9IEh0dHA7XG4gICAgVnVlLnJlc291cmNlID0gUmVzb3VyY2U7XG4gICAgVnVlLlByb21pc2UgPSBQcm9taXNlT2JqO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoVnVlLnByb3RvdHlwZSwge1xuXG4gICAgICAgICR1cmw6IHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zKFZ1ZS51cmwsIHRoaXMsIHRoaXMuJG9wdGlvbnMudXJsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICAkaHR0cDoge1xuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMoVnVlLmh0dHAsIHRoaXMsIHRoaXMuJG9wdGlvbnMuaHR0cCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgJHJlc291cmNlOiB7XG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gVnVlLnJlc291cmNlLmJpbmQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgJHByb21pc2U6IHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGV4ZWN1dG9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgVnVlLlByb21pc2UoZXhlY3V0b3IsIF90aGlzKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICB9KTtcbn1cblxuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5WdWUpIHtcbiAgICB3aW5kb3cuVnVlLnVzZShwbHVnaW4pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBsdWdpbjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vdnVlLXJlc291cmNlL2Rpc3QvdnVlLXJlc291cmNlLmNvbW1vbi5qc1xuLy8gbW9kdWxlIGlkID0gMTBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==");
},function(module,exports,__webpack_require__){eval("/**\n * vue-router v2.0.1\n * (c) 2016 Evan You\n * @license MIT\n */\n(function (global, factory) {\n   true ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) :\n  (global.VueRouter = factory());\n}(this, (function () { 'use strict';\n\nvar View = {\n  name: 'router-view',\n  functional: true,\n  props: {\n    name: {\n      type: String,\n      default: 'default'\n    }\n  },\n  render: function render (h, ref) {\n    var props = ref.props;\n    var children = ref.children;\n    var parent = ref.parent;\n    var data = ref.data;\n\n    data.routerView = true\n\n    var route = parent.$route\n    var cache = parent._routerViewCache || (parent._routerViewCache = {})\n    var depth = 0\n    var inactive = false\n\n    while (parent) {\n      if (parent.$vnode && parent.$vnode.data.routerView) {\n        depth++\n      }\n      if (parent._inactive) {\n        inactive = true\n      }\n      parent = parent.$parent\n    }\n\n    data.routerViewDepth = depth\n    var matched = route.matched[depth]\n    if (!matched) {\n      return h()\n    }\n\n    var name = props.name\n    var component = inactive\n      ? cache[name]\n      : (cache[name] = matched.components[name])\n\n    if (!inactive) {\n      var hooks = data.hook || (data.hook = {})\n      hooks.init = function (vnode) {\n        matched.instances[name] = vnode.child\n      }\n      hooks.destroy = function (vnode) {\n        if (matched.instances[name] === vnode.child) {\n          matched.instances[name] = undefined\n        }\n      }\n    }\n\n    return h(component, data, children)\n  }\n}\n\n/*  */\n\nfunction resolvePath (\n  relative,\n  base,\n  append\n) {\n  if (relative.charAt(0) === '/') {\n    return relative\n  }\n\n  if (relative.charAt(0) === '?' || relative.charAt(0) === '#') {\n    return base + relative\n  }\n\n  var stack = base.split('/')\n\n  // remove trailing segment if:\n  // - not appending\n  // - appending to trailing slash (last segment is empty)\n  if (!append || !stack[stack.length - 1]) {\n    stack.pop()\n  }\n\n  // resolve relative path\n  var segments = relative.replace(/^\\//, '').split('/')\n  for (var i = 0; i < segments.length; i++) {\n    var segment = segments[i]\n    if (segment === '.') {\n      continue\n    } else if (segment === '..') {\n      stack.pop()\n    } else {\n      stack.push(segment)\n    }\n  }\n\n  // ensure leading slash\n  if (stack[0] !== '') {\n    stack.unshift('')\n  }\n\n  return stack.join('/')\n}\n\nfunction parsePath (path) {\n  var hash = ''\n  var query = ''\n\n  var hashIndex = path.indexOf('#')\n  if (hashIndex >= 0) {\n    hash = path.slice(hashIndex)\n    path = path.slice(0, hashIndex)\n  }\n\n  var queryIndex = path.indexOf('?')\n  if (queryIndex >= 0) {\n    query = path.slice(queryIndex + 1)\n    path = path.slice(0, queryIndex)\n  }\n\n  return {\n    path: path,\n    query: query,\n    hash: hash\n  }\n}\n\nfunction cleanPath (path) {\n  return path.replace(/\\/\\//g, '/')\n}\n\n/*  */\n\nfunction assert (condition, message) {\n  if (!condition) {\n    throw new Error((\"[vue-router] \" + message))\n  }\n}\n\nfunction warn (condition, message) {\n  if (!condition) {\n    typeof console !== 'undefined' && console.warn((\"[vue-router] \" + message))\n  }\n}\n\n/*  */\n\nvar encode = encodeURIComponent\nvar decode = decodeURIComponent\n\nfunction resolveQuery (\n  query,\n  extraQuery\n) {\n  if ( extraQuery === void 0 ) extraQuery = {};\n\n  if (query) {\n    var parsedQuery\n    try {\n      parsedQuery = parseQuery(query)\n    } catch (e) {\n      warn(false, e.message)\n      parsedQuery = {}\n    }\n    for (var key in extraQuery) {\n      parsedQuery[key] = extraQuery[key]\n    }\n    return parsedQuery\n  } else {\n    return extraQuery\n  }\n}\n\nfunction parseQuery (query) {\n  var res = Object.create(null)\n\n  query = query.trim().replace(/^(\\?|#|&)/, '')\n\n  if (!query) {\n    return res\n  }\n\n  query.split('&').forEach(function (param) {\n    var parts = param.replace(/\\+/g, ' ').split('=')\n    var key = decode(parts.shift())\n    var val = parts.length > 0\n      ? decode(parts.join('='))\n      : null\n\n    if (res[key] === undefined) {\n      res[key] = val\n    } else if (Array.isArray(res[key])) {\n      res[key].push(val)\n    } else {\n      res[key] = [res[key], val]\n    }\n  })\n\n  return res\n}\n\nfunction stringifyQuery (obj) {\n  var res = obj ? Object.keys(obj).sort().map(function (key) {\n    var val = obj[key]\n\n    if (val === undefined) {\n      return ''\n    }\n\n    if (val === null) {\n      return encode(key)\n    }\n\n    if (Array.isArray(val)) {\n      var result = []\n      val.slice().forEach(function (val2) {\n        if (val2 === undefined) {\n          return\n        }\n        if (val2 === null) {\n          result.push(encode(key))\n        } else {\n          result.push(encode(key) + '=' + encode(val2))\n        }\n      })\n      return result.join('&')\n    }\n\n    return encode(key) + '=' + encode(val)\n  }).filter(function (x) { return x.length > 0; }).join('&') : null\n  return res ? (\"?\" + res) : ''\n}\n\n/*  */\n\nfunction createRoute (\n  record,\n  location,\n  redirectedFrom\n) {\n  var route = {\n    name: location.name || (record && record.name),\n    meta: (record && record.meta) || {},\n    path: location.path || '/',\n    hash: location.hash || '',\n    query: location.query || {},\n    params: location.params || {},\n    fullPath: getFullPath(location),\n    matched: record ? formatMatch(record) : []\n  }\n  if (redirectedFrom) {\n    route.redirectedFrom = getFullPath(redirectedFrom)\n  }\n  return Object.freeze(route)\n}\n\n// the starting route that represents the initial state\nvar START = createRoute(null, {\n  path: '/'\n})\n\nfunction formatMatch (record) {\n  var res = []\n  while (record) {\n    res.unshift(record)\n    record = record.parent\n  }\n  return res\n}\n\nfunction getFullPath (ref) {\n  var path = ref.path;\n  var query = ref.query; if ( query === void 0 ) query = {};\n  var hash = ref.hash; if ( hash === void 0 ) hash = '';\n\n  return (path || '/') + stringifyQuery(query) + hash\n}\n\nvar trailingSlashRE = /\\/$/\nfunction isSameRoute (a, b) {\n  if (b === START) {\n    return a === b\n  } else if (!b) {\n    return false\n  } else if (a.path && b.path) {\n    return (\n      a.path.replace(trailingSlashRE, '') === b.path.replace(trailingSlashRE, '') &&\n      a.hash === b.hash &&\n      isObjectEqual(a.query, b.query)\n    )\n  } else if (a.name && b.name) {\n    return (\n      a.name === b.name &&\n      a.hash === b.hash &&\n      isObjectEqual(a.query, b.query) &&\n      isObjectEqual(a.params, b.params)\n    )\n  } else {\n    return false\n  }\n}\n\nfunction isObjectEqual (a, b) {\n  if ( a === void 0 ) a = {};\n  if ( b === void 0 ) b = {};\n\n  var aKeys = Object.keys(a)\n  var bKeys = Object.keys(b)\n  if (aKeys.length !== bKeys.length) {\n    return false\n  }\n  return aKeys.every(function (key) { return String(a[key]) === String(b[key]); })\n}\n\nfunction isIncludedRoute (current, target) {\n  return (\n    current.path.indexOf(target.path) === 0 &&\n    (!target.hash || current.hash === target.hash) &&\n    queryIncludes(current.query, target.query)\n  )\n}\n\nfunction queryIncludes (current, target) {\n  for (var key in target) {\n    if (!(key in current)) {\n      return false\n    }\n  }\n  return true\n}\n\n/*  */\n\nfunction normalizeLocation (\n  raw,\n  current,\n  append\n) {\n  var next = typeof raw === 'string' ? { path: raw } : raw\n  if (next.name || next._normalized) {\n    return next\n  }\n\n  var parsedPath = parsePath(next.path || '')\n  var basePath = (current && current.path) || '/'\n  var path = parsedPath.path\n    ? resolvePath(parsedPath.path, basePath, append)\n    : (current && current.path) || '/'\n  var query = resolveQuery(parsedPath.query, next.query)\n  var hash = next.hash || parsedPath.hash\n  if (hash && hash.charAt(0) !== '#') {\n    hash = \"#\" + hash\n  }\n\n  return {\n    _normalized: true,\n    path: path,\n    query: query,\n    hash: hash\n  }\n}\n\n/*  */\n\n// work around weird flow bug\nvar toTypes = [String, Object]\n\nvar Link = {\n  name: 'router-link',\n  props: {\n    to: {\n      type: toTypes,\n      required: true\n    },\n    tag: {\n      type: String,\n      default: 'a'\n    },\n    exact: Boolean,\n    append: Boolean,\n    replace: Boolean,\n    activeClass: String\n  },\n  render: function render (h) {\n    var this$1 = this;\n\n    var router = this.$router\n    var current = this.$route\n    var to = normalizeLocation(this.to, current, this.append)\n    var resolved = router.match(to)\n    var fullPath = resolved.redirectedFrom || resolved.fullPath\n    var base = router.history.base\n    var href = base ? cleanPath(base + fullPath) : fullPath\n    var classes = {}\n    var activeClass = this.activeClass || router.options.linkActiveClass || 'router-link-active'\n    var compareTarget = to.path ? createRoute(null, to) : resolved\n    classes[activeClass] = this.exact\n      ? isSameRoute(current, compareTarget)\n      : isIncludedRoute(current, compareTarget)\n\n    var on = {\n      click: function (e) {\n        // don't redirect with control keys\n        /* istanbul ignore if */\n        if (e.metaKey || e.ctrlKey || e.shiftKey) { return }\n        // don't redirect when preventDefault called\n        /* istanbul ignore if */\n        if (e.defaultPrevented) { return }\n        // don't redirect on right click\n        /* istanbul ignore if */\n        if (e.button !== 0) { return }\n        e.preventDefault()\n        if (this$1.replace) {\n          router.replace(to)\n        } else {\n          router.push(to)\n        }\n      }\n    }\n\n    var data = {\n      class: classes\n    }\n\n    if (this.tag === 'a') {\n      data.on = on\n      data.attrs = { href: href }\n    } else {\n      // find the first <a> child and apply listener and href\n      var a = findAnchor(this.$slots.default)\n      if (a) {\n        var aData = a.data || (a.data = {})\n        aData.on = on\n        var aAttrs = aData.attrs || (aData.attrs = {})\n        aAttrs.href = href\n      } else {\n        // doesn't have <a> child, apply listener to self\n        data.on = on\n      }\n    }\n\n    return h(this.tag, data, this.$slots.default)\n  }\n}\n\nfunction findAnchor (children) {\n  if (children) {\n    var child\n    for (var i = 0; i < children.length; i++) {\n      child = children[i]\n      if (child.tag === 'a') {\n        return child\n      }\n      if (child.children && (child = findAnchor(child.children))) {\n        return child\n      }\n    }\n  }\n}\n\nfunction install (Vue) {\n  if (install.installed) { return }\n  install.installed = true\n\n  Object.defineProperty(Vue.prototype, '$router', {\n    get: function get () { return this.$root._router }\n  })\n\n  Object.defineProperty(Vue.prototype, '$route', {\n    get: function get$1 () { return this.$root._route }\n  })\n\n  Vue.mixin({\n    beforeCreate: function beforeCreate () {\n      if (this.$options.router) {\n        this._router = this.$options.router\n        this._router.init(this)\n        Vue.util.defineReactive(this, '_route', this._router.history.current)\n      }\n    }\n  })\n\n  Vue.component('router-view', View)\n  Vue.component('router-link', Link)\n}\n\nvar __moduleExports = Array.isArray || function (arr) {\n  return Object.prototype.toString.call(arr) == '[object Array]';\n};\n\nvar isarray = __moduleExports\n\n/**\n * Expose `pathToRegexp`.\n */\nvar index = pathToRegexp\nvar parse_1 = parse\nvar compile_1 = compile\nvar tokensToFunction_1 = tokensToFunction\nvar tokensToRegExp_1 = tokensToRegExp\n\n/**\n * The main path matching regexp utility.\n *\n * @type {RegExp}\n */\nvar PATH_REGEXP = new RegExp([\n  // Match escaped characters that would otherwise appear in future matches.\n  // This allows the user to escape special characters that won't transform.\n  '(\\\\\\\\.)',\n  // Match Express-style parameters and un-named parameters with a prefix\n  // and optional suffixes. Matches appear as:\n  //\n  // \"/:test(\\\\d+)?\" => [\"/\", \"test\", \"\\d+\", undefined, \"?\", undefined]\n  // \"/route(\\\\d+)\"  => [undefined, undefined, undefined, \"\\d+\", undefined, undefined]\n  // \"/*\"            => [\"/\", undefined, undefined, undefined, undefined, \"*\"]\n  '([\\\\/.])?(?:(?:\\\\:(\\\\w+)(?:\\\\(((?:\\\\\\\\.|[^\\\\\\\\()])+)\\\\))?|\\\\(((?:\\\\\\\\.|[^\\\\\\\\()])+)\\\\))([+*?])?|(\\\\*))'\n].join('|'), 'g')\n\n/**\n * Parse a string for the raw tokens.\n *\n * @param  {string} str\n * @return {!Array}\n */\nfunction parse (str) {\n  var tokens = []\n  var key = 0\n  var index = 0\n  var path = ''\n  var res\n\n  while ((res = PATH_REGEXP.exec(str)) != null) {\n    var m = res[0]\n    var escaped = res[1]\n    var offset = res.index\n    path += str.slice(index, offset)\n    index = offset + m.length\n\n    // Ignore already escaped sequences.\n    if (escaped) {\n      path += escaped[1]\n      continue\n    }\n\n    var next = str[index]\n    var prefix = res[2]\n    var name = res[3]\n    var capture = res[4]\n    var group = res[5]\n    var modifier = res[6]\n    var asterisk = res[7]\n\n    // Push the current path onto the tokens.\n    if (path) {\n      tokens.push(path)\n      path = ''\n    }\n\n    var partial = prefix != null && next != null && next !== prefix\n    var repeat = modifier === '+' || modifier === '*'\n    var optional = modifier === '?' || modifier === '*'\n    var delimiter = res[2] || '/'\n    var pattern = capture || group || (asterisk ? '.*' : '[^' + delimiter + ']+?')\n\n    tokens.push({\n      name: name || key++,\n      prefix: prefix || '',\n      delimiter: delimiter,\n      optional: optional,\n      repeat: repeat,\n      partial: partial,\n      asterisk: !!asterisk,\n      pattern: escapeGroup(pattern)\n    })\n  }\n\n  // Match any characters still remaining.\n  if (index < str.length) {\n    path += str.substr(index)\n  }\n\n  // If the path exists, push it onto the end.\n  if (path) {\n    tokens.push(path)\n  }\n\n  return tokens\n}\n\n/**\n * Compile a string to a template function for the path.\n *\n * @param  {string}             str\n * @return {!function(Object=, Object=)}\n */\nfunction compile (str) {\n  return tokensToFunction(parse(str))\n}\n\n/**\n * Prettier encoding of URI path segments.\n *\n * @param  {string}\n * @return {string}\n */\nfunction encodeURIComponentPretty (str) {\n  return encodeURI(str).replace(/[\\/?#]/g, function (c) {\n    return '%' + c.charCodeAt(0).toString(16).toUpperCase()\n  })\n}\n\n/**\n * Encode the asterisk parameter. Similar to `pretty`, but allows slashes.\n *\n * @param  {string}\n * @return {string}\n */\nfunction encodeAsterisk (str) {\n  return encodeURI(str).replace(/[?#]/g, function (c) {\n    return '%' + c.charCodeAt(0).toString(16).toUpperCase()\n  })\n}\n\n/**\n * Expose a method for transforming tokens into the path function.\n */\nfunction tokensToFunction (tokens) {\n  // Compile all the tokens into regexps.\n  var matches = new Array(tokens.length)\n\n  // Compile all the patterns before compilation.\n  for (var i = 0; i < tokens.length; i++) {\n    if (typeof tokens[i] === 'object') {\n      matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$')\n    }\n  }\n\n  return function (obj, opts) {\n    var path = ''\n    var data = obj || {}\n    var options = opts || {}\n    var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent\n\n    for (var i = 0; i < tokens.length; i++) {\n      var token = tokens[i]\n\n      if (typeof token === 'string') {\n        path += token\n\n        continue\n      }\n\n      var value = data[token.name]\n      var segment\n\n      if (value == null) {\n        if (token.optional) {\n          // Prepend partial segment prefixes.\n          if (token.partial) {\n            path += token.prefix\n          }\n\n          continue\n        } else {\n          throw new TypeError('Expected \"' + token.name + '\" to be defined')\n        }\n      }\n\n      if (isarray(value)) {\n        if (!token.repeat) {\n          throw new TypeError('Expected \"' + token.name + '\" to not repeat, but received `' + JSON.stringify(value) + '`')\n        }\n\n        if (value.length === 0) {\n          if (token.optional) {\n            continue\n          } else {\n            throw new TypeError('Expected \"' + token.name + '\" to not be empty')\n          }\n        }\n\n        for (var j = 0; j < value.length; j++) {\n          segment = encode(value[j])\n\n          if (!matches[i].test(segment)) {\n            throw new TypeError('Expected all \"' + token.name + '\" to match \"' + token.pattern + '\", but received `' + JSON.stringify(segment) + '`')\n          }\n\n          path += (j === 0 ? token.prefix : token.delimiter) + segment\n        }\n\n        continue\n      }\n\n      segment = token.asterisk ? encodeAsterisk(value) : encode(value)\n\n      if (!matches[i].test(segment)) {\n        throw new TypeError('Expected \"' + token.name + '\" to match \"' + token.pattern + '\", but received \"' + segment + '\"')\n      }\n\n      path += token.prefix + segment\n    }\n\n    return path\n  }\n}\n\n/**\n * Escape a regular expression string.\n *\n * @param  {string} str\n * @return {string}\n */\nfunction escapeString (str) {\n  return str.replace(/([.+*?=^!:${}()[\\]|\\/\\\\])/g, '\\\\$1')\n}\n\n/**\n * Escape the capturing group by escaping special characters and meaning.\n *\n * @param  {string} group\n * @return {string}\n */\nfunction escapeGroup (group) {\n  return group.replace(/([=!:$\\/()])/g, '\\\\$1')\n}\n\n/**\n * Attach the keys as a property of the regexp.\n *\n * @param  {!RegExp} re\n * @param  {Array}   keys\n * @return {!RegExp}\n */\nfunction attachKeys (re, keys) {\n  re.keys = keys\n  return re\n}\n\n/**\n * Get the flags for a regexp from the options.\n *\n * @param  {Object} options\n * @return {string}\n */\nfunction flags (options) {\n  return options.sensitive ? '' : 'i'\n}\n\n/**\n * Pull out keys from a regexp.\n *\n * @param  {!RegExp} path\n * @param  {!Array}  keys\n * @return {!RegExp}\n */\nfunction regexpToRegexp (path, keys) {\n  // Use a negative lookahead to match only capturing groups.\n  var groups = path.source.match(/\\((?!\\?)/g)\n\n  if (groups) {\n    for (var i = 0; i < groups.length; i++) {\n      keys.push({\n        name: i,\n        prefix: null,\n        delimiter: null,\n        optional: false,\n        repeat: false,\n        partial: false,\n        asterisk: false,\n        pattern: null\n      })\n    }\n  }\n\n  return attachKeys(path, keys)\n}\n\n/**\n * Transform an array into a regexp.\n *\n * @param  {!Array}  path\n * @param  {Array}   keys\n * @param  {!Object} options\n * @return {!RegExp}\n */\nfunction arrayToRegexp (path, keys, options) {\n  var parts = []\n\n  for (var i = 0; i < path.length; i++) {\n    parts.push(pathToRegexp(path[i], keys, options).source)\n  }\n\n  var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))\n\n  return attachKeys(regexp, keys)\n}\n\n/**\n * Create a path regexp from string input.\n *\n * @param  {string}  path\n * @param  {!Array}  keys\n * @param  {!Object} options\n * @return {!RegExp}\n */\nfunction stringToRegexp (path, keys, options) {\n  var tokens = parse(path)\n  var re = tokensToRegExp(tokens, options)\n\n  // Attach keys back to the regexp.\n  for (var i = 0; i < tokens.length; i++) {\n    if (typeof tokens[i] !== 'string') {\n      keys.push(tokens[i])\n    }\n  }\n\n  return attachKeys(re, keys)\n}\n\n/**\n * Expose a function for taking tokens and returning a RegExp.\n *\n * @param  {!Array}  tokens\n * @param  {Object=} options\n * @return {!RegExp}\n */\nfunction tokensToRegExp (tokens, options) {\n  options = options || {}\n\n  var strict = options.strict\n  var end = options.end !== false\n  var route = ''\n  var lastToken = tokens[tokens.length - 1]\n  var endsWithSlash = typeof lastToken === 'string' && /\\/$/.test(lastToken)\n\n  // Iterate over the tokens and create our regexp string.\n  for (var i = 0; i < tokens.length; i++) {\n    var token = tokens[i]\n\n    if (typeof token === 'string') {\n      route += escapeString(token)\n    } else {\n      var prefix = escapeString(token.prefix)\n      var capture = '(?:' + token.pattern + ')'\n\n      if (token.repeat) {\n        capture += '(?:' + prefix + capture + ')*'\n      }\n\n      if (token.optional) {\n        if (!token.partial) {\n          capture = '(?:' + prefix + '(' + capture + '))?'\n        } else {\n          capture = prefix + '(' + capture + ')?'\n        }\n      } else {\n        capture = prefix + '(' + capture + ')'\n      }\n\n      route += capture\n    }\n  }\n\n  // In non-strict mode we allow a slash at the end of match. If the path to\n  // match already ends with a slash, we remove it for consistency. The slash\n  // is valid at the end of a path match, not in the middle. This is important\n  // in non-ending mode, where \"/test/\" shouldn't match \"/test//route\".\n  if (!strict) {\n    route = (endsWithSlash ? route.slice(0, -2) : route) + '(?:\\\\/(?=$))?'\n  }\n\n  if (end) {\n    route += '$'\n  } else {\n    // In non-ending mode, we need the capturing groups to match as much as\n    // possible by using a positive lookahead to the end or next path segment.\n    route += strict && endsWithSlash ? '' : '(?=\\\\/|$)'\n  }\n\n  return new RegExp('^' + route, flags(options))\n}\n\n/**\n * Normalize the given path string, returning a regular expression.\n *\n * An empty array can be passed in for the keys, which will hold the\n * placeholder key descriptions. For example, using `/user/:id`, `keys` will\n * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.\n *\n * @param  {(string|RegExp|Array)} path\n * @param  {(Array|Object)=}       keys\n * @param  {Object=}               options\n * @return {!RegExp}\n */\nfunction pathToRegexp (path, keys, options) {\n  keys = keys || []\n\n  if (!isarray(keys)) {\n    options = /** @type {!Object} */ (keys)\n    keys = []\n  } else if (!options) {\n    options = {}\n  }\n\n  if (path instanceof RegExp) {\n    return regexpToRegexp(path, /** @type {!Array} */ (keys))\n  }\n\n  if (isarray(path)) {\n    return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options)\n  }\n\n  return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options)\n}\n\nindex.parse = parse_1;\nindex.compile = compile_1;\nindex.tokensToFunction = tokensToFunction_1;\nindex.tokensToRegExp = tokensToRegExp_1;\n\n/*  */\n\nfunction createRouteMap (routes) {\n  var pathMap = Object.create(null)\n  var nameMap = Object.create(null)\n\n  routes.forEach(function (route) {\n    addRouteRecord(pathMap, nameMap, route)\n  })\n\n  return {\n    pathMap: pathMap,\n    nameMap: nameMap\n  }\n}\n\nfunction addRouteRecord (\n  pathMap,\n  nameMap,\n  route,\n  parent,\n  matchAs\n) {\n  var path = route.path;\n  var name = route.name;\n  assert(path != null, \"\\\"path\\\" is required in a route configuration.\")\n\n  var record = {\n    path: normalizePath(path, parent),\n    components: route.components || { default: route.component },\n    instances: {},\n    name: name,\n    parent: parent,\n    matchAs: matchAs,\n    redirect: route.redirect,\n    beforeEnter: route.beforeEnter,\n    meta: route.meta || {}\n  }\n\n  if (route.children) {\n    // Warn if route is named and has a default child route.\n    // If users navigate to this route by name, the default child will\n    // not be rendered (GH Issue #629)\n    if (false) {}\n    route.children.forEach(function (child) {\n      addRouteRecord(pathMap, nameMap, child, record)\n    })\n  }\n\n  if (route.alias) {\n    if (Array.isArray(route.alias)) {\n      route.alias.forEach(function (alias) {\n        addRouteRecord(pathMap, nameMap, { path: alias }, parent, record.path)\n      })\n    } else {\n      addRouteRecord(pathMap, nameMap, { path: route.alias }, parent, record.path)\n    }\n  }\n\n  pathMap[record.path] = record\n  if (name) { nameMap[name] = record }\n}\n\nfunction normalizePath (path, parent) {\n  path = path.replace(/\\/$/, '')\n  if (path[0] === '/') { return path }\n  if (parent == null) { return path }\n  return cleanPath(((parent.path) + \"/\" + path))\n}\n\n/*  */\n\nvar regexpCache = Object.create(null)\n\nvar regexpCompileCache = Object.create(null)\n\nfunction createMatcher (routes) {\n  var ref = createRouteMap(routes);\n  var pathMap = ref.pathMap;\n  var nameMap = ref.nameMap;\n\n  function match (\n    raw,\n    currentRoute,\n    redirectedFrom\n  ) {\n    var location = normalizeLocation(raw, currentRoute)\n    var name = location.name;\n\n    if (name) {\n      var record = nameMap[name]\n      if (record) {\n        location.path = fillParams(record.path, location.params, (\"named route \\\"\" + name + \"\\\"\"))\n        return _createRoute(record, location, redirectedFrom)\n      }\n    } else if (location.path) {\n      location.params = {}\n      for (var path in pathMap) {\n        if (matchRoute(path, location.params, location.path)) {\n          return _createRoute(pathMap[path], location, redirectedFrom)\n        }\n      }\n    }\n    // no match\n    return _createRoute(null, location)\n  }\n\n  function redirect (\n    record,\n    location\n  ) {\n    var originalRedirect = record.redirect\n    var redirect = typeof originalRedirect === 'function'\n        ? originalRedirect(createRoute(record, location))\n        : originalRedirect\n\n    if (typeof redirect === 'string') {\n      redirect = { path: redirect }\n    }\n\n    if (!redirect || typeof redirect !== 'object') {\n      warn(false, (\"invalid redirect option: \" + (JSON.stringify(redirect))))\n      return _createRoute(null, location)\n    }\n\n    var re = redirect\n    var name = re.name;\n    var path = re.path;\n    var query = location.query;\n    var hash = location.hash;\n    var params = location.params;\n    query = re.hasOwnProperty('query') ? re.query : query\n    hash = re.hasOwnProperty('hash') ? re.hash : hash\n    params = re.hasOwnProperty('params') ? re.params : params\n\n    if (name) {\n      // resolved named direct\n      var targetRecord = nameMap[name]\n      assert(targetRecord, (\"redirect failed: named route \\\"\" + name + \"\\\" not found.\"))\n      return match({\n        _normalized: true,\n        name: name,\n        query: query,\n        hash: hash,\n        params: params\n      }, undefined, location)\n    } else if (path) {\n      // 1. resolve relative redirect\n      var rawPath = resolveRecordPath(path, record)\n      // 2. resolve params\n      var resolvedPath = fillParams(rawPath, params, (\"redirect route with path \\\"\" + rawPath + \"\\\"\"))\n      // 3. rematch with existing query and hash\n      return match({\n        _normalized: true,\n        path: resolvedPath,\n        query: query,\n        hash: hash\n      }, undefined, location)\n    } else {\n      warn(false, (\"invalid redirect option: \" + (JSON.stringify(redirect))))\n      return _createRoute(null, location)\n    }\n  }\n\n  function alias (\n    record,\n    location,\n    matchAs\n  ) {\n    var aliasedPath = fillParams(matchAs, location.params, (\"aliased route with path \\\"\" + matchAs + \"\\\"\"))\n    var aliasedMatch = match({\n      _normalized: true,\n      path: aliasedPath\n    })\n    if (aliasedMatch) {\n      var matched = aliasedMatch.matched\n      var aliasedRecord = matched[matched.length - 1]\n      location.params = aliasedMatch.params\n      return _createRoute(aliasedRecord, location)\n    }\n    return _createRoute(null, location)\n  }\n\n  function _createRoute (\n    record,\n    location,\n    redirectedFrom\n  ) {\n    if (record && record.redirect) {\n      return redirect(record, redirectedFrom || location)\n    }\n    if (record && record.matchAs) {\n      return alias(record, location, record.matchAs)\n    }\n    return createRoute(record, location, redirectedFrom)\n  }\n\n  return match\n}\n\nfunction matchRoute (\n  path,\n  params,\n  pathname\n) {\n  var keys, regexp\n  var hit = regexpCache[path]\n  if (hit) {\n    keys = hit.keys\n    regexp = hit.regexp\n  } else {\n    keys = []\n    regexp = index(path, keys)\n    regexpCache[path] = { keys: keys, regexp: regexp }\n  }\n  var m = pathname.match(regexp)\n\n  if (!m) {\n    return false\n  } else if (!params) {\n    return true\n  }\n\n  for (var i = 1, len = m.length; i < len; ++i) {\n    var key = keys[i - 1]\n    var val = typeof m[i] === 'string' ? decodeURIComponent(m[i]) : m[i]\n    if (key) { params[key.name] = val }\n  }\n\n  return true\n}\n\nfunction fillParams (\n  path,\n  params,\n  routeMsg\n) {\n  try {\n    var filler =\n      regexpCompileCache[path] ||\n      (regexpCompileCache[path] = index.compile(path))\n    return filler(params || {}, { pretty: true })\n  } catch (e) {\n    assert(false, (\"missing param for \" + routeMsg + \": \" + (e.message)))\n    return ''\n  }\n}\n\nfunction resolveRecordPath (path, record) {\n  return resolvePath(path, record.parent ? record.parent.path : '/', true)\n}\n\n/*  */\n\nvar inBrowser = typeof window !== 'undefined'\n\nvar supportsHistory = inBrowser && (function () {\n  var ua = window.navigator.userAgent\n\n  if (\n    (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&\n    ua.indexOf('Mobile Safari') !== -1 &&\n    ua.indexOf('Chrome') === -1 &&\n    ua.indexOf('Windows Phone') === -1\n  ) {\n    return false\n  }\n\n  return window.history && 'pushState' in window.history\n})()\n\n/*  */\n\nfunction runQueue (queue, fn, cb) {\n  var step = function (index) {\n    if (index >= queue.length) {\n      cb()\n    } else {\n      if (queue[index]) {\n        fn(queue[index], function () {\n          step(index + 1)\n        })\n      } else {\n        step(index + 1)\n      }\n    }\n  }\n  step(0)\n}\n\n/*  */\n\n\nvar History = function History (router, base) {\n  this.router = router\n  this.base = normalizeBase(base)\n  // start with a route object that stands for \"nowhere\"\n  this.current = START\n  this.pending = null\n};\n\nHistory.prototype.listen = function listen (cb) {\n  this.cb = cb\n};\n\nHistory.prototype.transitionTo = function transitionTo (location, cb) {\n    var this$1 = this;\n\n  var route = this.router.match(location, this.current)\n  this.confirmTransition(route, function () {\n    this$1.updateRoute(route)\n    cb && cb(route)\n    this$1.ensureURL()\n  })\n};\n\nHistory.prototype.confirmTransition = function confirmTransition (route, cb) {\n    var this$1 = this;\n\n  var current = this.current\n  if (isSameRoute(route, current)) {\n    this.ensureURL()\n    return\n  }\n\n  var ref = resolveQueue(this.current.matched, route.matched);\n    var deactivated = ref.deactivated;\n    var activated = ref.activated;\n\n  var queue = [].concat(\n    // in-component leave guards\n    extractLeaveGuards(deactivated),\n    // global before hooks\n    this.router.beforeHooks,\n    // enter guards\n    activated.map(function (m) { return m.beforeEnter; }),\n    // async components\n    resolveAsyncComponents(activated)\n  )\n\n  this.pending = route\n  var iterator = function (hook, next) {\n    if (this$1.pending !== route) { return }\n    hook(route, current, function (to) {\n      if (to === false) {\n        // next(false) -> abort navigation, ensure current URL\n        this$1.ensureURL()\n      } else if (typeof to === 'string' || typeof to === 'object') {\n        // next('/') or next({ path: '/' }) -> redirect\n        this$1.push(to)\n      } else {\n        // confirm transition and pass on the value\n        next(to)\n      }\n    })\n  }\n\n  runQueue(queue, iterator, function () {\n    var postEnterCbs = []\n    var enterGuards = extractEnterGuards(activated, postEnterCbs, function () {\n      return this$1.current === route\n    })\n    // wait until async components are resolved before\n    // extracting in-component enter guards\n    runQueue(enterGuards, iterator, function () {\n      if (this$1.pending === route) {\n        this$1.pending = null\n        cb(route)\n        this$1.router.app.$nextTick(function () {\n          postEnterCbs.forEach(function (cb) { return cb(); })\n        })\n      }\n    })\n  })\n};\n\nHistory.prototype.updateRoute = function updateRoute (route) {\n  var prev = this.current\n  this.current = route\n  this.cb && this.cb(route)\n  this.router.afterHooks.forEach(function (hook) {\n    hook && hook(route, prev)\n  })\n};\n\nfunction normalizeBase (base) {\n  if (!base) {\n    if (inBrowser) {\n      // respect <base> tag\n      var baseEl = document.querySelector('base')\n      base = baseEl ? baseEl.getAttribute('href') : '/'\n    } else {\n      base = '/'\n    }\n  }\n  // make sure there's the starting slash\n  if (base.charAt(0) !== '/') {\n    base = '/' + base\n  }\n  // remove trailing slash\n  return base.replace(/\\/$/, '')\n}\n\nfunction resolveQueue (\n  current,\n  next\n) {\n  var i\n  var max = Math.max(current.length, next.length)\n  for (i = 0; i < max; i++) {\n    if (current[i] !== next[i]) {\n      break\n    }\n  }\n  return {\n    activated: next.slice(i),\n    deactivated: current.slice(i)\n  }\n}\n\nfunction extractLeaveGuards (matched) {\n  return flatMapComponents(matched, function (def, instance) {\n    var guard = def && def.beforeRouteLeave\n    if (guard) {\n      return function routeLeaveGuard () {\n        return guard.apply(instance, arguments)\n      }\n    }\n  }).reverse()\n}\n\nfunction extractEnterGuards (\n  matched,\n  cbs,\n  isValid\n) {\n  return flatMapComponents(matched, function (def, _, match, key) {\n    var guard = def && def.beforeRouteEnter\n    if (guard) {\n      return function routeEnterGuard (to, from, next) {\n        return guard(to, from, function (cb) {\n          next(cb)\n          if (typeof cb === 'function') {\n            cbs.push(function () {\n              // #750\n              // if a router-view is wrapped with an out-in transition,\n              // the instance may not have been registered at this time.\n              // we will need to poll for registration until current route\n              // is no longer valid.\n              poll(cb, match.instances, key, isValid)\n            })\n          }\n        })\n      }\n    }\n  })\n}\n\nfunction poll (cb, instances, key, isValid) {\n  if (instances[key]) {\n    cb(instances[key])\n  } else if (isValid()) {\n    setTimeout(function () {\n      poll(cb, instances, key, isValid)\n    }, 16)\n  }\n}\n\nfunction resolveAsyncComponents (matched) {\n  return flatMapComponents(matched, function (def, _, match, key) {\n    // if it's a function and doesn't have Vue options attached,\n    // assume it's an async component resolve function.\n    // we are not using Vue's default async resolving mechanism because\n    // we want to halt the navigation until the incoming component has been\n    // resolved.\n    if (typeof def === 'function' && !def.options) {\n      return function (to, from, next) {\n        var resolve = function (resolvedDef) {\n          match.components[key] = resolvedDef\n          next()\n        }\n\n        var reject = function (reason) {\n          warn(false, (\"Failed to resolve async component \" + key + \": \" + reason))\n          next(false)\n        }\n\n        var res = def(resolve, reject)\n        if (res && typeof res.then === 'function') {\n          res.then(resolve, reject)\n        }\n      }\n    }\n  })\n}\n\nfunction flatMapComponents (\n  matched,\n  fn\n) {\n  return Array.prototype.concat.apply([], matched.map(function (m) {\n    return Object.keys(m.components).map(function (key) { return fn(\n      m.components[key],\n      m.instances[key],\n      m, key\n    ); })\n  }))\n}\n\n/*  */\n\nfunction saveScrollPosition (key) {\n  if (!key) { return }\n  window.sessionStorage.setItem(key, JSON.stringify({\n    x: window.pageXOffset,\n    y: window.pageYOffset\n  }))\n}\n\nfunction getScrollPosition (key) {\n  if (!key) { return }\n  return JSON.parse(window.sessionStorage.getItem(key))\n}\n\nfunction getElementPosition (el) {\n  var docRect = document.documentElement.getBoundingClientRect()\n  var elRect = el.getBoundingClientRect()\n  return {\n    x: elRect.left - docRect.left,\n    y: elRect.top - docRect.top\n  }\n}\n\nfunction isValidPosition (obj) {\n  return isNumber(obj.x) || isNumber(obj.y)\n}\n\nfunction normalizePosition (obj) {\n  return {\n    x: isNumber(obj.x) ? obj.x : window.pageXOffset,\n    y: isNumber(obj.y) ? obj.y : window.pageYOffset\n  }\n}\n\nfunction isNumber (v) {\n  return typeof v === 'number'\n}\n\n/*  */\n\n\nvar genKey = function () { return String(Date.now()); }\nvar _key = genKey()\n\nvar HTML5History = (function (History) {\n  function HTML5History (router, base) {\n    var this$1 = this;\n\n    History.call(this, router, base)\n\n    this.transitionTo(getLocation(this.base))\n\n    var expectScroll = router.options.scrollBehavior\n    window.addEventListener('popstate', function (e) {\n      _key = e.state && e.state.key\n      var current = this$1.current\n      this$1.transitionTo(getLocation(this$1.base), function (next) {\n        if (expectScroll) {\n          this$1.handleScroll(next, current, true)\n        }\n      })\n    })\n\n    if (expectScroll) {\n      window.addEventListener('scroll', function () {\n        saveScrollPosition(_key)\n      })\n    }\n  }\n\n  if ( History ) HTML5History.__proto__ = History;\n  HTML5History.prototype = Object.create( History && History.prototype );\n  HTML5History.prototype.constructor = HTML5History;\n\n  HTML5History.prototype.go = function go (n) {\n    window.history.go(n)\n  };\n\n  HTML5History.prototype.push = function push (location) {\n    var this$1 = this;\n\n    var current = this.current\n    this.transitionTo(location, function (route) {\n      pushState(cleanPath(this$1.base + route.fullPath))\n      this$1.handleScroll(route, current, false)\n    })\n  };\n\n  HTML5History.prototype.replace = function replace (location) {\n    var this$1 = this;\n\n    var current = this.current\n    this.transitionTo(location, function (route) {\n      replaceState(cleanPath(this$1.base + route.fullPath))\n      this$1.handleScroll(route, current, false)\n    })\n  };\n\n  HTML5History.prototype.ensureURL = function ensureURL () {\n    if (getLocation(this.base) !== this.current.fullPath) {\n      replaceState(cleanPath(this.base + this.current.fullPath))\n    }\n  };\n\n  HTML5History.prototype.handleScroll = function handleScroll (to, from, isPop) {\n    var router = this.router\n    if (!router.app) {\n      return\n    }\n\n    var behavior = router.options.scrollBehavior\n    if (!behavior) {\n      return\n    }\n    assert(typeof behavior === 'function', \"scrollBehavior must be a function\")\n\n    // wait until re-render finishes before scrolling\n    router.app.$nextTick(function () {\n      var position = getScrollPosition(_key)\n      var shouldScroll = behavior(to, from, isPop ? position : null)\n      if (!shouldScroll) {\n        return\n      }\n      var isObject = typeof shouldScroll === 'object'\n      if (isObject && typeof shouldScroll.selector === 'string') {\n        var el = document.querySelector(shouldScroll.selector)\n        if (el) {\n          position = getElementPosition(el)\n        } else if (isValidPosition(shouldScroll)) {\n          position = normalizePosition(shouldScroll)\n        }\n      } else if (isObject && isValidPosition(shouldScroll)) {\n        position = normalizePosition(shouldScroll)\n      }\n\n      if (position) {\n        window.scrollTo(position.x, position.y)\n      }\n    })\n  };\n\n  return HTML5History;\n}(History));\n\nfunction getLocation (base) {\n  var path = window.location.pathname\n  if (base && path.indexOf(base) === 0) {\n    path = path.slice(base.length)\n  }\n  return (path || '/') + window.location.search + window.location.hash\n}\n\nfunction pushState (url, replace) {\n  // try...catch the pushState call to get around Safari\n  // DOM Exception 18 where it limits to 100 pushState calls\n  var history = window.history\n  try {\n    if (replace) {\n      history.replaceState({ key: _key }, '', url)\n    } else {\n      _key = genKey()\n      history.pushState({ key: _key }, '', url)\n    }\n    saveScrollPosition(_key)\n  } catch (e) {\n    window.location[replace ? 'assign' : 'replace'](url)\n  }\n}\n\nfunction replaceState (url) {\n  pushState(url, true)\n}\n\n/*  */\n\n\nvar HashHistory = (function (History) {\n  function HashHistory (router, base, fallback) {\n    var this$1 = this;\n\n    History.call(this, router, base)\n\n    // check history fallback deeplinking\n    if (fallback && this.checkFallback()) {\n      return\n    }\n\n    ensureSlash()\n    this.transitionTo(getHash(), function () {\n      window.addEventListener('hashchange', function () {\n        this$1.onHashChange()\n      })\n    })\n  }\n\n  if ( History ) HashHistory.__proto__ = History;\n  HashHistory.prototype = Object.create( History && History.prototype );\n  HashHistory.prototype.constructor = HashHistory;\n\n  HashHistory.prototype.checkFallback = function checkFallback () {\n    var location = getLocation(this.base)\n    if (!/^\\/#/.test(location)) {\n      window.location.replace(\n        cleanPath(this.base + '/#' + location)\n      )\n      return true\n    }\n  };\n\n  HashHistory.prototype.onHashChange = function onHashChange () {\n    if (!ensureSlash()) {\n      return\n    }\n    this.transitionTo(getHash(), function (route) {\n      replaceHash(route.fullPath)\n    })\n  };\n\n  HashHistory.prototype.push = function push (location) {\n    this.transitionTo(location, function (route) {\n      pushHash(route.fullPath)\n    })\n  };\n\n  HashHistory.prototype.replace = function replace (location) {\n    this.transitionTo(location, function (route) {\n      replaceHash(route.fullPath)\n    })\n  };\n\n  HashHistory.prototype.go = function go (n) {\n    window.history.go(n)\n  };\n\n  HashHistory.prototype.ensureURL = function ensureURL () {\n    if (getHash() !== this.current.fullPath) {\n      replaceHash(this.current.fullPath)\n    }\n  };\n\n  return HashHistory;\n}(History));\n\nfunction ensureSlash () {\n  var path = getHash()\n  if (path.charAt(0) === '/') {\n    return true\n  }\n  replaceHash('/' + path)\n  return false\n}\n\nfunction getHash () {\n  // We can't use window.location.hash here because it's not\n  // consistent across browsers - Firefox will pre-decode it!\n  var href = window.location.href\n  var index = href.indexOf('#')\n  return index === -1 ? '' : href.slice(index + 1)\n}\n\nfunction pushHash (path) {\n  window.location.hash = path\n}\n\nfunction replaceHash (path) {\n  var i = window.location.href.indexOf('#')\n  window.location.replace(\n    window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path\n  )\n}\n\n/*  */\n\n\nvar AbstractHistory = (function (History) {\n  function AbstractHistory (router) {\n    History.call(this, router)\n    this.stack = []\n    this.index = -1\n  }\n\n  if ( History ) AbstractHistory.__proto__ = History;\n  AbstractHistory.prototype = Object.create( History && History.prototype );\n  AbstractHistory.prototype.constructor = AbstractHistory;\n\n  AbstractHistory.prototype.push = function push (location) {\n    var this$1 = this;\n\n    this.transitionTo(location, function (route) {\n      this$1.stack = this$1.stack.slice(0, this$1.index + 1).concat(route)\n      this$1.index++\n    })\n  };\n\n  AbstractHistory.prototype.replace = function replace (location) {\n    var this$1 = this;\n\n    this.transitionTo(location, function (route) {\n      this$1.stack = this$1.stack.slice(0, this$1.index).concat(route)\n    })\n  };\n\n  AbstractHistory.prototype.go = function go (n) {\n    var this$1 = this;\n\n    var targetIndex = this.index + n\n    if (targetIndex < 0 || targetIndex >= this.stack.length) {\n      return\n    }\n    var route = this.stack[targetIndex]\n    this.confirmTransition(route, function () {\n      this$1.index = targetIndex\n      this$1.updateRoute(route)\n    })\n  };\n\n  AbstractHistory.prototype.ensureURL = function ensureURL () {\n    // noop\n  };\n\n  return AbstractHistory;\n}(History));\n\n/*  */\n\nvar VueRouter = function VueRouter (options) {\n  if ( options === void 0 ) options = {};\n\n  this.app = null\n  this.options = options\n  this.beforeHooks = []\n  this.afterHooks = []\n  this.match = createMatcher(options.routes || [])\n\n  var mode = options.mode || 'hash'\n  this.fallback = mode === 'history' && !supportsHistory\n  if (this.fallback) {\n    mode = 'hash'\n  }\n  if (!inBrowser) {\n    mode = 'abstract'\n  }\n  this.mode = mode\n};\n\nvar prototypeAccessors = { currentRoute: {} };\n\nprototypeAccessors.currentRoute.get = function () {\n  return this.history && this.history.current\n};\n\nVueRouter.prototype.init = function init (app /* Vue component instance */) {\n    var this$1 = this;\n\n  assert(\n    install.installed,\n    \"not installed. Make sure to call `Vue.use(VueRouter)` \" +\n    \"before creating root instance.\"\n  )\n\n  this.app = app\n\n  var ref = this;\n    var mode = ref.mode;\n    var options = ref.options;\n    var fallback = ref.fallback;\n  switch (mode) {\n    case 'history':\n      this.history = new HTML5History(this, options.base)\n      break\n    case 'hash':\n      this.history = new HashHistory(this, options.base, fallback)\n      break\n    case 'abstract':\n      this.history = new AbstractHistory(this)\n      break\n    default:\n      assert(false, (\"invalid mode: \" + mode))\n  }\n\n  this.history.listen(function (route) {\n    this$1.app._route = route\n  })\n};\n\nVueRouter.prototype.beforeEach = function beforeEach (fn) {\n  this.beforeHooks.push(fn)\n};\n\nVueRouter.prototype.afterEach = function afterEach (fn) {\n  this.afterHooks.push(fn)\n};\n\nVueRouter.prototype.push = function push (location) {\n  this.history.push(location)\n};\n\nVueRouter.prototype.replace = function replace (location) {\n  this.history.replace(location)\n};\n\nVueRouter.prototype.go = function go (n) {\n  this.history.go(n)\n};\n\nVueRouter.prototype.back = function back () {\n  this.go(-1)\n};\n\nVueRouter.prototype.forward = function forward () {\n  this.go(1)\n};\n\nVueRouter.prototype.getMatchedComponents = function getMatchedComponents () {\n  if (!this.currentRoute) {\n    return []\n  }\n  return [].concat.apply([], this.currentRoute.matched.map(function (m) {\n    return Object.keys(m.components).map(function (key) {\n      return m.components[key]\n    })\n  }))\n};\n\nObject.defineProperties( VueRouter.prototype, prototypeAccessors );\n\nVueRouter.install = install\n\nif (inBrowser && window.Vue) {\n  window.Vue.use(VueRouter)\n}\n\nreturn VueRouter;\n\n})));\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L3Z1ZS1yb3V0ZXIvZGlzdC92dWUtcm91dGVyLmpzP2U3MWYiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxxQkFBcUI7O0FBRXRCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLHdFQUF3RTtBQUN4RTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOENBQThDO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUIscUJBQXFCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFD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Q0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RDtBQUN6RDtBQUNBO0FBQ0E7QUFDQSxNQUFNLEVBQUU7QUFDUixHQUFHO0FBQ0g7O0FBRUE7O0FBRUE7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7O0FBR0EsMEJBQTBCLDJCQUEyQjtBQUNyRDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsWUFBWTtBQUN4QyxLQUFLO0FBQ0w7QUFDQSx5QkFBeUIsWUFBWTtBQUNyQztBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMEJBQTBCLGlCQUFpQjs7QUFFM0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSDs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQyIsImZpbGUiOiIxMS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogdnVlLXJvdXRlciB2Mi4wLjFcbiAqIChjKSAyMDE2IEV2YW4gWW91XG4gKiBAbGljZW5zZSBNSVRcbiAqL1xuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgOlxuICB0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOlxuICAoZ2xvYmFsLlZ1ZVJvdXRlciA9IGZhY3RvcnkoKSk7XG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxudmFyIFZpZXcgPSB7XG4gIG5hbWU6ICdyb3V0ZXItdmlldycsXG4gIGZ1bmN0aW9uYWw6IHRydWUsXG4gIHByb3BzOiB7XG4gICAgbmFtZToge1xuICAgICAgdHlwZTogU3RyaW5nLFxuICAgICAgZGVmYXVsdDogJ2RlZmF1bHQnXG4gICAgfVxuICB9LFxuICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlciAoaCwgcmVmKSB7XG4gICAgdmFyIHByb3BzID0gcmVmLnByb3BzO1xuICAgIHZhciBjaGlsZHJlbiA9IHJlZi5jaGlsZHJlbjtcbiAgICB2YXIgcGFyZW50ID0gcmVmLnBhcmVudDtcbiAgICB2YXIgZGF0YSA9IHJlZi5kYXRhO1xuXG4gICAgZGF0YS5yb3V0ZXJWaWV3ID0gdHJ1ZVxuXG4gICAgdmFyIHJvdXRlID0gcGFyZW50LiRyb3V0ZVxuICAgIHZhciBjYWNoZSA9IHBhcmVudC5fcm91dGVyVmlld0NhY2hlIHx8IChwYXJlbnQuX3JvdXRlclZpZXdDYWNoZSA9IHt9KVxuICAgIHZhciBkZXB0aCA9IDBcbiAgICB2YXIgaW5hY3RpdmUgPSBmYWxzZVxuXG4gICAgd2hpbGUgKHBhcmVudCkge1xuICAgICAgaWYgKHBhcmVudC4kdm5vZGUgJiYgcGFyZW50LiR2bm9kZS5kYXRhLnJvdXRlclZpZXcpIHtcbiAgICAgICAgZGVwdGgrK1xuICAgICAgfVxuICAgICAgaWYgKHBhcmVudC5faW5hY3RpdmUpIHtcbiAgICAgICAgaW5hY3RpdmUgPSB0cnVlXG4gICAgICB9XG4gICAgICBwYXJlbnQgPSBwYXJlbnQuJHBhcmVudFxuICAgIH1cblxuICAgIGRhdGEucm91dGVyVmlld0RlcHRoID0gZGVwdGhcbiAgICB2YXIgbWF0Y2hlZCA9IHJvdXRlLm1hdGNoZWRbZGVwdGhdXG4gICAgaWYgKCFtYXRjaGVkKSB7XG4gICAgICByZXR1cm4gaCgpXG4gICAgfVxuXG4gICAgdmFyIG5hbWUgPSBwcm9wcy5uYW1lXG4gICAgdmFyIGNvbXBvbmVudCA9IGluYWN0aXZlXG4gICAgICA/IGNhY2hlW25hbWVdXG4gICAgICA6IChjYWNoZVtuYW1lXSA9IG1hdGNoZWQuY29tcG9uZW50c1tuYW1lXSlcblxuICAgIGlmICghaW5hY3RpdmUpIHtcbiAgICAgIHZhciBob29rcyA9IGRhdGEuaG9vayB8fCAoZGF0YS5ob29rID0ge30pXG4gICAgICBob29rcy5pbml0ID0gZnVuY3Rpb24gKHZub2RlKSB7XG4gICAgICAgIG1hdGNoZWQuaW5zdGFuY2VzW25hbWVdID0gdm5vZGUuY2hpbGRcbiAgICAgIH1cbiAgICAgIGhvb2tzLmRlc3Ryb3kgPSBmdW5jdGlvbiAodm5vZGUpIHtcbiAgICAgICAgaWYgKG1hdGNoZWQuaW5zdGFuY2VzW25hbWVdID09PSB2bm9kZS5jaGlsZCkge1xuICAgICAgICAgIG1hdGNoZWQuaW5zdGFuY2VzW25hbWVdID0gdW5kZWZpbmVkXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaChjb21wb25lbnQsIGRhdGEsIGNoaWxkcmVuKVxuICB9XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiByZXNvbHZlUGF0aCAoXG4gIHJlbGF0aXZlLFxuICBiYXNlLFxuICBhcHBlbmRcbikge1xuICBpZiAocmVsYXRpdmUuY2hhckF0KDApID09PSAnLycpIHtcbiAgICByZXR1cm4gcmVsYXRpdmVcbiAgfVxuXG4gIGlmIChyZWxhdGl2ZS5jaGFyQXQoMCkgPT09ICc/JyB8fCByZWxhdGl2ZS5jaGFyQXQoMCkgPT09ICcjJykge1xuICAgIHJldHVybiBiYXNlICsgcmVsYXRpdmVcbiAgfVxuXG4gIHZhciBzdGFjayA9IGJhc2Uuc3BsaXQoJy8nKVxuXG4gIC8vIHJlbW92ZSB0cmFpbGluZyBzZWdtZW50IGlmOlxuICAvLyAtIG5vdCBhcHBlbmRpbmdcbiAgLy8gLSBhcHBlbmRpbmcgdG8gdHJhaWxpbmcgc2xhc2ggKGxhc3Qgc2VnbWVudCBpcyBlbXB0eSlcbiAgaWYgKCFhcHBlbmQgfHwgIXN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdKSB7XG4gICAgc3RhY2sucG9wKClcbiAgfVxuXG4gIC8vIHJlc29sdmUgcmVsYXRpdmUgcGF0aFxuICB2YXIgc2VnbWVudHMgPSByZWxhdGl2ZS5yZXBsYWNlKC9eXFwvLywgJycpLnNwbGl0KCcvJylcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBzZWdtZW50ID0gc2VnbWVudHNbaV1cbiAgICBpZiAoc2VnbWVudCA9PT0gJy4nKSB7XG4gICAgICBjb250aW51ZVxuICAgIH0gZWxzZSBpZiAoc2VnbWVudCA9PT0gJy4uJykge1xuICAgICAgc3RhY2sucG9wKClcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhY2sucHVzaChzZWdtZW50KVxuICAgIH1cbiAgfVxuXG4gIC8vIGVuc3VyZSBsZWFkaW5nIHNsYXNoXG4gIGlmIChzdGFja1swXSAhPT0gJycpIHtcbiAgICBzdGFjay51bnNoaWZ0KCcnKVxuICB9XG5cbiAgcmV0dXJuIHN0YWNrLmpvaW4oJy8nKVxufVxuXG5mdW5jdGlvbiBwYXJzZVBhdGggKHBhdGgpIHtcbiAgdmFyIGhhc2ggPSAnJ1xuICB2YXIgcXVlcnkgPSAnJ1xuXG4gIHZhciBoYXNoSW5kZXggPSBwYXRoLmluZGV4T2YoJyMnKVxuICBpZiAoaGFzaEluZGV4ID49IDApIHtcbiAgICBoYXNoID0gcGF0aC5zbGljZShoYXNoSW5kZXgpXG4gICAgcGF0aCA9IHBhdGguc2xpY2UoMCwgaGFzaEluZGV4KVxuICB9XG5cbiAgdmFyIHF1ZXJ5SW5kZXggPSBwYXRoLmluZGV4T2YoJz8nKVxuICBpZiAocXVlcnlJbmRleCA+PSAwKSB7XG4gICAgcXVlcnkgPSBwYXRoLnNsaWNlKHF1ZXJ5SW5kZXggKyAxKVxuICAgIHBhdGggPSBwYXRoLnNsaWNlKDAsIHF1ZXJ5SW5kZXgpXG4gIH1cblxuICByZXR1cm4ge1xuICAgIHBhdGg6IHBhdGgsXG4gICAgcXVlcnk6IHF1ZXJ5LFxuICAgIGhhc2g6IGhhc2hcbiAgfVxufVxuXG5mdW5jdGlvbiBjbGVhblBhdGggKHBhdGgpIHtcbiAgcmV0dXJuIHBhdGgucmVwbGFjZSgvXFwvXFwvL2csICcvJylcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGFzc2VydCAoY29uZGl0aW9uLCBtZXNzYWdlKSB7XG4gIGlmICghY29uZGl0aW9uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKChcIlt2dWUtcm91dGVyXSBcIiArIG1lc3NhZ2UpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHdhcm4gKGNvbmRpdGlvbiwgbWVzc2FnZSkge1xuICBpZiAoIWNvbmRpdGlvbikge1xuICAgIHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJiBjb25zb2xlLndhcm4oKFwiW3Z1ZS1yb3V0ZXJdIFwiICsgbWVzc2FnZSkpXG4gIH1cbn1cblxuLyogICovXG5cbnZhciBlbmNvZGUgPSBlbmNvZGVVUklDb21wb25lbnRcbnZhciBkZWNvZGUgPSBkZWNvZGVVUklDb21wb25lbnRcblxuZnVuY3Rpb24gcmVzb2x2ZVF1ZXJ5IChcbiAgcXVlcnksXG4gIGV4dHJhUXVlcnlcbikge1xuICBpZiAoIGV4dHJhUXVlcnkgPT09IHZvaWQgMCApIGV4dHJhUXVlcnkgPSB7fTtcblxuICBpZiAocXVlcnkpIHtcbiAgICB2YXIgcGFyc2VkUXVlcnlcbiAgICB0cnkge1xuICAgICAgcGFyc2VkUXVlcnkgPSBwYXJzZVF1ZXJ5KHF1ZXJ5KVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHdhcm4oZmFsc2UsIGUubWVzc2FnZSlcbiAgICAgIHBhcnNlZFF1ZXJ5ID0ge31cbiAgICB9XG4gICAgZm9yICh2YXIga2V5IGluIGV4dHJhUXVlcnkpIHtcbiAgICAgIHBhcnNlZFF1ZXJ5W2tleV0gPSBleHRyYVF1ZXJ5W2tleV1cbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlZFF1ZXJ5XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGV4dHJhUXVlcnlcbiAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZVF1ZXJ5IChxdWVyeSkge1xuICB2YXIgcmVzID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuXG4gIHF1ZXJ5ID0gcXVlcnkudHJpbSgpLnJlcGxhY2UoL14oXFw/fCN8JikvLCAnJylcblxuICBpZiAoIXF1ZXJ5KSB7XG4gICAgcmV0dXJuIHJlc1xuICB9XG5cbiAgcXVlcnkuc3BsaXQoJyYnKS5mb3JFYWNoKGZ1bmN0aW9uIChwYXJhbSkge1xuICAgIHZhciBwYXJ0cyA9IHBhcmFtLnJlcGxhY2UoL1xcKy9nLCAnICcpLnNwbGl0KCc9JylcbiAgICB2YXIga2V5ID0gZGVjb2RlKHBhcnRzLnNoaWZ0KCkpXG4gICAgdmFyIHZhbCA9IHBhcnRzLmxlbmd0aCA+IDBcbiAgICAgID8gZGVjb2RlKHBhcnRzLmpvaW4oJz0nKSlcbiAgICAgIDogbnVsbFxuXG4gICAgaWYgKHJlc1trZXldID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJlc1trZXldID0gdmFsXG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHJlc1trZXldKSkge1xuICAgICAgcmVzW2tleV0ucHVzaCh2YWwpXG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc1trZXldID0gW3Jlc1trZXldLCB2YWxdXG4gICAgfVxuICB9KVxuXG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gc3RyaW5naWZ5UXVlcnkgKG9iaikge1xuICB2YXIgcmVzID0gb2JqID8gT2JqZWN0LmtleXMob2JqKS5zb3J0KCkubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICB2YXIgdmFsID0gb2JqW2tleV1cblxuICAgIGlmICh2YWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuICcnXG4gICAgfVxuXG4gICAgaWYgKHZhbCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGVuY29kZShrZXkpXG4gICAgfVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsKSkge1xuICAgICAgdmFyIHJlc3VsdCA9IFtdXG4gICAgICB2YWwuc2xpY2UoKS5mb3JFYWNoKGZ1bmN0aW9uICh2YWwyKSB7XG4gICAgICAgIGlmICh2YWwyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsMiA9PT0gbnVsbCkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGVuY29kZShrZXkpKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGVuY29kZShrZXkpICsgJz0nICsgZW5jb2RlKHZhbDIpKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgcmV0dXJuIHJlc3VsdC5qb2luKCcmJylcbiAgICB9XG5cbiAgICByZXR1cm4gZW5jb2RlKGtleSkgKyAnPScgKyBlbmNvZGUodmFsKVxuICB9KS5maWx0ZXIoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHgubGVuZ3RoID4gMDsgfSkuam9pbignJicpIDogbnVsbFxuICByZXR1cm4gcmVzID8gKFwiP1wiICsgcmVzKSA6ICcnXG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBjcmVhdGVSb3V0ZSAoXG4gIHJlY29yZCxcbiAgbG9jYXRpb24sXG4gIHJlZGlyZWN0ZWRGcm9tXG4pIHtcbiAgdmFyIHJvdXRlID0ge1xuICAgIG5hbWU6IGxvY2F0aW9uLm5hbWUgfHwgKHJlY29yZCAmJiByZWNvcmQubmFtZSksXG4gICAgbWV0YTogKHJlY29yZCAmJiByZWNvcmQubWV0YSkgfHwge30sXG4gICAgcGF0aDogbG9jYXRpb24ucGF0aCB8fCAnLycsXG4gICAgaGFzaDogbG9jYXRpb24uaGFzaCB8fCAnJyxcbiAgICBxdWVyeTogbG9jYXRpb24ucXVlcnkgfHwge30sXG4gICAgcGFyYW1zOiBsb2NhdGlvbi5wYXJhbXMgfHwge30sXG4gICAgZnVsbFBhdGg6IGdldEZ1bGxQYXRoKGxvY2F0aW9uKSxcbiAgICBtYXRjaGVkOiByZWNvcmQgPyBmb3JtYXRNYXRjaChyZWNvcmQpIDogW11cbiAgfVxuICBpZiAocmVkaXJlY3RlZEZyb20pIHtcbiAgICByb3V0ZS5yZWRpcmVjdGVkRnJvbSA9IGdldEZ1bGxQYXRoKHJlZGlyZWN0ZWRGcm9tKVxuICB9XG4gIHJldHVybiBPYmplY3QuZnJlZXplKHJvdXRlKVxufVxuXG4vLyB0aGUgc3RhcnRpbmcgcm91dGUgdGhhdCByZXByZXNlbnRzIHRoZSBpbml0aWFsIHN0YXRlXG52YXIgU1RBUlQgPSBjcmVhdGVSb3V0ZShudWxsLCB7XG4gIHBhdGg6ICcvJ1xufSlcblxuZnVuY3Rpb24gZm9ybWF0TWF0Y2ggKHJlY29yZCkge1xuICB2YXIgcmVzID0gW11cbiAgd2hpbGUgKHJlY29yZCkge1xuICAgIHJlcy51bnNoaWZ0KHJlY29yZClcbiAgICByZWNvcmQgPSByZWNvcmQucGFyZW50XG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBnZXRGdWxsUGF0aCAocmVmKSB7XG4gIHZhciBwYXRoID0gcmVmLnBhdGg7XG4gIHZhciBxdWVyeSA9IHJlZi5xdWVyeTsgaWYgKCBxdWVyeSA9PT0gdm9pZCAwICkgcXVlcnkgPSB7fTtcbiAgdmFyIGhhc2ggPSByZWYuaGFzaDsgaWYgKCBoYXNoID09PSB2b2lkIDAgKSBoYXNoID0gJyc7XG5cbiAgcmV0dXJuIChwYXRoIHx8ICcvJykgKyBzdHJpbmdpZnlRdWVyeShxdWVyeSkgKyBoYXNoXG59XG5cbnZhciB0cmFpbGluZ1NsYXNoUkUgPSAvXFwvJC9cbmZ1bmN0aW9uIGlzU2FtZVJvdXRlIChhLCBiKSB7XG4gIGlmIChiID09PSBTVEFSVCkge1xuICAgIHJldHVybiBhID09PSBiXG4gIH0gZWxzZSBpZiAoIWIpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfSBlbHNlIGlmIChhLnBhdGggJiYgYi5wYXRoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGEucGF0aC5yZXBsYWNlKHRyYWlsaW5nU2xhc2hSRSwgJycpID09PSBiLnBhdGgucmVwbGFjZSh0cmFpbGluZ1NsYXNoUkUsICcnKSAmJlxuICAgICAgYS5oYXNoID09PSBiLmhhc2ggJiZcbiAgICAgIGlzT2JqZWN0RXF1YWwoYS5xdWVyeSwgYi5xdWVyeSlcbiAgICApXG4gIH0gZWxzZSBpZiAoYS5uYW1lICYmIGIubmFtZSkge1xuICAgIHJldHVybiAoXG4gICAgICBhLm5hbWUgPT09IGIubmFtZSAmJlxuICAgICAgYS5oYXNoID09PSBiLmhhc2ggJiZcbiAgICAgIGlzT2JqZWN0RXF1YWwoYS5xdWVyeSwgYi5xdWVyeSkgJiZcbiAgICAgIGlzT2JqZWN0RXF1YWwoYS5wYXJhbXMsIGIucGFyYW1zKVxuICAgIClcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5mdW5jdGlvbiBpc09iamVjdEVxdWFsIChhLCBiKSB7XG4gIGlmICggYSA9PT0gdm9pZCAwICkgYSA9IHt9O1xuICBpZiAoIGIgPT09IHZvaWQgMCApIGIgPSB7fTtcblxuICB2YXIgYUtleXMgPSBPYmplY3Qua2V5cyhhKVxuICB2YXIgYktleXMgPSBPYmplY3Qua2V5cyhiKVxuICBpZiAoYUtleXMubGVuZ3RoICE9PSBiS2V5cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICByZXR1cm4gYUtleXMuZXZlcnkoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gU3RyaW5nKGFba2V5XSkgPT09IFN0cmluZyhiW2tleV0pOyB9KVxufVxuXG5mdW5jdGlvbiBpc0luY2x1ZGVkUm91dGUgKGN1cnJlbnQsIHRhcmdldCkge1xuICByZXR1cm4gKFxuICAgIGN1cnJlbnQucGF0aC5pbmRleE9mKHRhcmdldC5wYXRoKSA9PT0gMCAmJlxuICAgICghdGFyZ2V0Lmhhc2ggfHwgY3VycmVudC5oYXNoID09PSB0YXJnZXQuaGFzaCkgJiZcbiAgICBxdWVyeUluY2x1ZGVzKGN1cnJlbnQucXVlcnksIHRhcmdldC5xdWVyeSlcbiAgKVxufVxuXG5mdW5jdGlvbiBxdWVyeUluY2x1ZGVzIChjdXJyZW50LCB0YXJnZXQpIHtcbiAgZm9yICh2YXIga2V5IGluIHRhcmdldCkge1xuICAgIGlmICghKGtleSBpbiBjdXJyZW50KSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBub3JtYWxpemVMb2NhdGlvbiAoXG4gIHJhdyxcbiAgY3VycmVudCxcbiAgYXBwZW5kXG4pIHtcbiAgdmFyIG5leHQgPSB0eXBlb2YgcmF3ID09PSAnc3RyaW5nJyA/IHsgcGF0aDogcmF3IH0gOiByYXdcbiAgaWYgKG5leHQubmFtZSB8fCBuZXh0Ll9ub3JtYWxpemVkKSB7XG4gICAgcmV0dXJuIG5leHRcbiAgfVxuXG4gIHZhciBwYXJzZWRQYXRoID0gcGFyc2VQYXRoKG5leHQucGF0aCB8fCAnJylcbiAgdmFyIGJhc2VQYXRoID0gKGN1cnJlbnQgJiYgY3VycmVudC5wYXRoKSB8fCAnLydcbiAgdmFyIHBhdGggPSBwYXJzZWRQYXRoLnBhdGhcbiAgICA/IHJlc29sdmVQYXRoKHBhcnNlZFBhdGgucGF0aCwgYmFzZVBhdGgsIGFwcGVuZClcbiAgICA6IChjdXJyZW50ICYmIGN1cnJlbnQucGF0aCkgfHwgJy8nXG4gIHZhciBxdWVyeSA9IHJlc29sdmVRdWVyeShwYXJzZWRQYXRoLnF1ZXJ5LCBuZXh0LnF1ZXJ5KVxuICB2YXIgaGFzaCA9IG5leHQuaGFzaCB8fCBwYXJzZWRQYXRoLmhhc2hcbiAgaWYgKGhhc2ggJiYgaGFzaC5jaGFyQXQoMCkgIT09ICcjJykge1xuICAgIGhhc2ggPSBcIiNcIiArIGhhc2hcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgX25vcm1hbGl6ZWQ6IHRydWUsXG4gICAgcGF0aDogcGF0aCxcbiAgICBxdWVyeTogcXVlcnksXG4gICAgaGFzaDogaGFzaFxuICB9XG59XG5cbi8qICAqL1xuXG4vLyB3b3JrIGFyb3VuZCB3ZWlyZCBmbG93IGJ1Z1xudmFyIHRvVHlwZXMgPSBbU3RyaW5nLCBPYmplY3RdXG5cbnZhciBMaW5rID0ge1xuICBuYW1lOiAncm91dGVyLWxpbmsnLFxuICBwcm9wczoge1xuICAgIHRvOiB7XG4gICAgICB0eXBlOiB0b1R5cGVzLFxuICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICB9LFxuICAgIHRhZzoge1xuICAgICAgdHlwZTogU3RyaW5nLFxuICAgICAgZGVmYXVsdDogJ2EnXG4gICAgfSxcbiAgICBleGFjdDogQm9vbGVhbixcbiAgICBhcHBlbmQ6IEJvb2xlYW4sXG4gICAgcmVwbGFjZTogQm9vbGVhbixcbiAgICBhY3RpdmVDbGFzczogU3RyaW5nXG4gIH0sXG4gIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyIChoKSB7XG4gICAgdmFyIHRoaXMkMSA9IHRoaXM7XG5cbiAgICB2YXIgcm91dGVyID0gdGhpcy4kcm91dGVyXG4gICAgdmFyIGN1cnJlbnQgPSB0aGlzLiRyb3V0ZVxuICAgIHZhciB0byA9IG5vcm1hbGl6ZUxvY2F0aW9uKHRoaXMudG8sIGN1cnJlbnQsIHRoaXMuYXBwZW5kKVxuICAgIHZhciByZXNvbHZlZCA9IHJvdXRlci5tYXRjaCh0bylcbiAgICB2YXIgZnVsbFBhdGggPSByZXNvbHZlZC5yZWRpcmVjdGVkRnJvbSB8fCByZXNvbHZlZC5mdWxsUGF0aFxuICAgIHZhciBiYXNlID0gcm91dGVyLmhpc3RvcnkuYmFzZVxuICAgIHZhciBocmVmID0gYmFzZSA/IGNsZWFuUGF0aChiYXNlICsgZnVsbFBhdGgpIDogZnVsbFBhdGhcbiAgICB2YXIgY2xhc3NlcyA9IHt9XG4gICAgdmFyIGFjdGl2ZUNsYXNzID0gdGhpcy5hY3RpdmVDbGFzcyB8fCByb3V0ZXIub3B0aW9ucy5saW5rQWN0aXZlQ2xhc3MgfHwgJ3JvdXRlci1saW5rLWFjdGl2ZSdcbiAgICB2YXIgY29tcGFyZVRhcmdldCA9IHRvLnBhdGggPyBjcmVhdGVSb3V0ZShudWxsLCB0bykgOiByZXNvbHZlZFxuICAgIGNsYXNzZXNbYWN0aXZlQ2xhc3NdID0gdGhpcy5leGFjdFxuICAgICAgPyBpc1NhbWVSb3V0ZShjdXJyZW50LCBjb21wYXJlVGFyZ2V0KVxuICAgICAgOiBpc0luY2x1ZGVkUm91dGUoY3VycmVudCwgY29tcGFyZVRhcmdldClcblxuICAgIHZhciBvbiA9IHtcbiAgICAgIGNsaWNrOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICAvLyBkb24ndCByZWRpcmVjdCB3aXRoIGNvbnRyb2wga2V5c1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgaWYgKGUubWV0YUtleSB8fCBlLmN0cmxLZXkgfHwgZS5zaGlmdEtleSkgeyByZXR1cm4gfVxuICAgICAgICAvLyBkb24ndCByZWRpcmVjdCB3aGVuIHByZXZlbnREZWZhdWx0IGNhbGxlZFxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgaWYgKGUuZGVmYXVsdFByZXZlbnRlZCkgeyByZXR1cm4gfVxuICAgICAgICAvLyBkb24ndCByZWRpcmVjdCBvbiByaWdodCBjbGlja1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgaWYgKGUuYnV0dG9uICE9PSAwKSB7IHJldHVybiB9XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgICBpZiAodGhpcyQxLnJlcGxhY2UpIHtcbiAgICAgICAgICByb3V0ZXIucmVwbGFjZSh0bylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByb3V0ZXIucHVzaCh0bylcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkYXRhID0ge1xuICAgICAgY2xhc3M6IGNsYXNzZXNcbiAgICB9XG5cbiAgICBpZiAodGhpcy50YWcgPT09ICdhJykge1xuICAgICAgZGF0YS5vbiA9IG9uXG4gICAgICBkYXRhLmF0dHJzID0geyBocmVmOiBocmVmIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gZmluZCB0aGUgZmlyc3QgPGE+IGNoaWxkIGFuZCBhcHBseSBsaXN0ZW5lciBhbmQgaHJlZlxuICAgICAgdmFyIGEgPSBmaW5kQW5jaG9yKHRoaXMuJHNsb3RzLmRlZmF1bHQpXG4gICAgICBpZiAoYSkge1xuICAgICAgICB2YXIgYURhdGEgPSBhLmRhdGEgfHwgKGEuZGF0YSA9IHt9KVxuICAgICAgICBhRGF0YS5vbiA9IG9uXG4gICAgICAgIHZhciBhQXR0cnMgPSBhRGF0YS5hdHRycyB8fCAoYURhdGEuYXR0cnMgPSB7fSlcbiAgICAgICAgYUF0dHJzLmhyZWYgPSBocmVmXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBkb2Vzbid0IGhhdmUgPGE+IGNoaWxkLCBhcHBseSBsaXN0ZW5lciB0byBzZWxmXG4gICAgICAgIGRhdGEub24gPSBvblxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBoKHRoaXMudGFnLCBkYXRhLCB0aGlzLiRzbG90cy5kZWZhdWx0KVxuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmRBbmNob3IgKGNoaWxkcmVuKSB7XG4gIGlmIChjaGlsZHJlbikge1xuICAgIHZhciBjaGlsZFxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoaWxkID0gY2hpbGRyZW5baV1cbiAgICAgIGlmIChjaGlsZC50YWcgPT09ICdhJykge1xuICAgICAgICByZXR1cm4gY2hpbGRcbiAgICAgIH1cbiAgICAgIGlmIChjaGlsZC5jaGlsZHJlbiAmJiAoY2hpbGQgPSBmaW5kQW5jaG9yKGNoaWxkLmNoaWxkcmVuKSkpIHtcbiAgICAgICAgcmV0dXJuIGNoaWxkXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGluc3RhbGwgKFZ1ZSkge1xuICBpZiAoaW5zdGFsbC5pbnN0YWxsZWQpIHsgcmV0dXJuIH1cbiAgaW5zdGFsbC5pbnN0YWxsZWQgPSB0cnVlXG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFZ1ZS5wcm90b3R5cGUsICckcm91dGVyJywge1xuICAgIGdldDogZnVuY3Rpb24gZ2V0ICgpIHsgcmV0dXJuIHRoaXMuJHJvb3QuX3JvdXRlciB9XG4gIH0pXG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFZ1ZS5wcm90b3R5cGUsICckcm91dGUnLCB7XG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQkMSAoKSB7IHJldHVybiB0aGlzLiRyb290Ll9yb3V0ZSB9XG4gIH0pXG5cbiAgVnVlLm1peGluKHtcbiAgICBiZWZvcmVDcmVhdGU6IGZ1bmN0aW9uIGJlZm9yZUNyZWF0ZSAoKSB7XG4gICAgICBpZiAodGhpcy4kb3B0aW9ucy5yb3V0ZXIpIHtcbiAgICAgICAgdGhpcy5fcm91dGVyID0gdGhpcy4kb3B0aW9ucy5yb3V0ZXJcbiAgICAgICAgdGhpcy5fcm91dGVyLmluaXQodGhpcylcbiAgICAgICAgVnVlLnV0aWwuZGVmaW5lUmVhY3RpdmUodGhpcywgJ19yb3V0ZScsIHRoaXMuX3JvdXRlci5oaXN0b3J5LmN1cnJlbnQpXG4gICAgICB9XG4gICAgfVxuICB9KVxuXG4gIFZ1ZS5jb21wb25lbnQoJ3JvdXRlci12aWV3JywgVmlldylcbiAgVnVlLmNvbXBvbmVudCgncm91dGVyLWxpbmsnLCBMaW5rKVxufVxuXG52YXIgX19tb2R1bGVFeHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJyKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxudmFyIGlzYXJyYXkgPSBfX21vZHVsZUV4cG9ydHNcblxuLyoqXG4gKiBFeHBvc2UgYHBhdGhUb1JlZ2V4cGAuXG4gKi9cbnZhciBpbmRleCA9IHBhdGhUb1JlZ2V4cFxudmFyIHBhcnNlXzEgPSBwYXJzZVxudmFyIGNvbXBpbGVfMSA9IGNvbXBpbGVcbnZhciB0b2tlbnNUb0Z1bmN0aW9uXzEgPSB0b2tlbnNUb0Z1bmN0aW9uXG52YXIgdG9rZW5zVG9SZWdFeHBfMSA9IHRva2Vuc1RvUmVnRXhwXG5cbi8qKlxuICogVGhlIG1haW4gcGF0aCBtYXRjaGluZyByZWdleHAgdXRpbGl0eS5cbiAqXG4gKiBAdHlwZSB7UmVnRXhwfVxuICovXG52YXIgUEFUSF9SRUdFWFAgPSBuZXcgUmVnRXhwKFtcbiAgLy8gTWF0Y2ggZXNjYXBlZCBjaGFyYWN0ZXJzIHRoYXQgd291bGQgb3RoZXJ3aXNlIGFwcGVhciBpbiBmdXR1cmUgbWF0Y2hlcy5cbiAgLy8gVGhpcyBhbGxvd3MgdGhlIHVzZXIgdG8gZXNjYXBlIHNwZWNpYWwgY2hhcmFjdGVycyB0aGF0IHdvbid0IHRyYW5zZm9ybS5cbiAgJyhcXFxcXFxcXC4pJyxcbiAgLy8gTWF0Y2ggRXhwcmVzcy1zdHlsZSBwYXJhbWV0ZXJzIGFuZCB1bi1uYW1lZCBwYXJhbWV0ZXJzIHdpdGggYSBwcmVmaXhcbiAgLy8gYW5kIG9wdGlvbmFsIHN1ZmZpeGVzLiBNYXRjaGVzIGFwcGVhciBhczpcbiAgLy9cbiAgLy8gXCIvOnRlc3QoXFxcXGQrKT9cIiA9PiBbXCIvXCIsIFwidGVzdFwiLCBcIlxcZCtcIiwgdW5kZWZpbmVkLCBcIj9cIiwgdW5kZWZpbmVkXVxuICAvLyBcIi9yb3V0ZShcXFxcZCspXCIgID0+IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBcIlxcZCtcIiwgdW5kZWZpbmVkLCB1bmRlZmluZWRdXG4gIC8vIFwiLypcIiAgICAgICAgICAgID0+IFtcIi9cIiwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBcIipcIl1cbiAgJyhbXFxcXC8uXSk/KD86KD86XFxcXDooXFxcXHcrKSg/OlxcXFwoKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcKCldKSspXFxcXCkpP3xcXFxcKCgoPzpcXFxcXFxcXC58W15cXFxcXFxcXCgpXSkrKVxcXFwpKShbKyo/XSk/fChcXFxcKikpJ1xuXS5qb2luKCd8JyksICdnJylcblxuLyoqXG4gKiBQYXJzZSBhIHN0cmluZyBmb3IgdGhlIHJhdyB0b2tlbnMuXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBzdHJcbiAqIEByZXR1cm4geyFBcnJheX1cbiAqL1xuZnVuY3Rpb24gcGFyc2UgKHN0cikge1xuICB2YXIgdG9rZW5zID0gW11cbiAgdmFyIGtleSA9IDBcbiAgdmFyIGluZGV4ID0gMFxuICB2YXIgcGF0aCA9ICcnXG4gIHZhciByZXNcblxuICB3aGlsZSAoKHJlcyA9IFBBVEhfUkVHRVhQLmV4ZWMoc3RyKSkgIT0gbnVsbCkge1xuICAgIHZhciBtID0gcmVzWzBdXG4gICAgdmFyIGVzY2FwZWQgPSByZXNbMV1cbiAgICB2YXIgb2Zmc2V0ID0gcmVzLmluZGV4XG4gICAgcGF0aCArPSBzdHIuc2xpY2UoaW5kZXgsIG9mZnNldClcbiAgICBpbmRleCA9IG9mZnNldCArIG0ubGVuZ3RoXG5cbiAgICAvLyBJZ25vcmUgYWxyZWFkeSBlc2NhcGVkIHNlcXVlbmNlcy5cbiAgICBpZiAoZXNjYXBlZCkge1xuICAgICAgcGF0aCArPSBlc2NhcGVkWzFdXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIHZhciBuZXh0ID0gc3RyW2luZGV4XVxuICAgIHZhciBwcmVmaXggPSByZXNbMl1cbiAgICB2YXIgbmFtZSA9IHJlc1szXVxuICAgIHZhciBjYXB0dXJlID0gcmVzWzRdXG4gICAgdmFyIGdyb3VwID0gcmVzWzVdXG4gICAgdmFyIG1vZGlmaWVyID0gcmVzWzZdXG4gICAgdmFyIGFzdGVyaXNrID0gcmVzWzddXG5cbiAgICAvLyBQdXNoIHRoZSBjdXJyZW50IHBhdGggb250byB0aGUgdG9rZW5zLlxuICAgIGlmIChwYXRoKSB7XG4gICAgICB0b2tlbnMucHVzaChwYXRoKVxuICAgICAgcGF0aCA9ICcnXG4gICAgfVxuXG4gICAgdmFyIHBhcnRpYWwgPSBwcmVmaXggIT0gbnVsbCAmJiBuZXh0ICE9IG51bGwgJiYgbmV4dCAhPT0gcHJlZml4XG4gICAgdmFyIHJlcGVhdCA9IG1vZGlmaWVyID09PSAnKycgfHwgbW9kaWZpZXIgPT09ICcqJ1xuICAgIHZhciBvcHRpb25hbCA9IG1vZGlmaWVyID09PSAnPycgfHwgbW9kaWZpZXIgPT09ICcqJ1xuICAgIHZhciBkZWxpbWl0ZXIgPSByZXNbMl0gfHwgJy8nXG4gICAgdmFyIHBhdHRlcm4gPSBjYXB0dXJlIHx8IGdyb3VwIHx8IChhc3RlcmlzayA/ICcuKicgOiAnW14nICsgZGVsaW1pdGVyICsgJ10rPycpXG5cbiAgICB0b2tlbnMucHVzaCh7XG4gICAgICBuYW1lOiBuYW1lIHx8IGtleSsrLFxuICAgICAgcHJlZml4OiBwcmVmaXggfHwgJycsXG4gICAgICBkZWxpbWl0ZXI6IGRlbGltaXRlcixcbiAgICAgIG9wdGlvbmFsOiBvcHRpb25hbCxcbiAgICAgIHJlcGVhdDogcmVwZWF0LFxuICAgICAgcGFydGlhbDogcGFydGlhbCxcbiAgICAgIGFzdGVyaXNrOiAhIWFzdGVyaXNrLFxuICAgICAgcGF0dGVybjogZXNjYXBlR3JvdXAocGF0dGVybilcbiAgICB9KVxuICB9XG5cbiAgLy8gTWF0Y2ggYW55IGNoYXJhY3RlcnMgc3RpbGwgcmVtYWluaW5nLlxuICBpZiAoaW5kZXggPCBzdHIubGVuZ3RoKSB7XG4gICAgcGF0aCArPSBzdHIuc3Vic3RyKGluZGV4KVxuICB9XG5cbiAgLy8gSWYgdGhlIHBhdGggZXhpc3RzLCBwdXNoIGl0IG9udG8gdGhlIGVuZC5cbiAgaWYgKHBhdGgpIHtcbiAgICB0b2tlbnMucHVzaChwYXRoKVxuICB9XG5cbiAgcmV0dXJuIHRva2Vuc1xufVxuXG4vKipcbiAqIENvbXBpbGUgYSBzdHJpbmcgdG8gYSB0ZW1wbGF0ZSBmdW5jdGlvbiBmb3IgdGhlIHBhdGguXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSAgICAgICAgICAgICBzdHJcbiAqIEByZXR1cm4geyFmdW5jdGlvbihPYmplY3Q9LCBPYmplY3Q9KX1cbiAqL1xuZnVuY3Rpb24gY29tcGlsZSAoc3RyKSB7XG4gIHJldHVybiB0b2tlbnNUb0Z1bmN0aW9uKHBhcnNlKHN0cikpXG59XG5cbi8qKlxuICogUHJldHRpZXIgZW5jb2Rpbmcgb2YgVVJJIHBhdGggc2VnbWVudHMuXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfVxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBlbmNvZGVVUklDb21wb25lbnRQcmV0dHkgKHN0cikge1xuICByZXR1cm4gZW5jb2RlVVJJKHN0cikucmVwbGFjZSgvW1xcLz8jXS9nLCBmdW5jdGlvbiAoYykge1xuICAgIHJldHVybiAnJScgKyBjLmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKClcbiAgfSlcbn1cblxuLyoqXG4gKiBFbmNvZGUgdGhlIGFzdGVyaXNrIHBhcmFtZXRlci4gU2ltaWxhciB0byBgcHJldHR5YCwgYnV0IGFsbG93cyBzbGFzaGVzLlxuICpcbiAqIEBwYXJhbSAge3N0cmluZ31cbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuZnVuY3Rpb24gZW5jb2RlQXN0ZXJpc2sgKHN0cikge1xuICByZXR1cm4gZW5jb2RlVVJJKHN0cikucmVwbGFjZSgvWz8jXS9nLCBmdW5jdGlvbiAoYykge1xuICAgIHJldHVybiAnJScgKyBjLmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKClcbiAgfSlcbn1cblxuLyoqXG4gKiBFeHBvc2UgYSBtZXRob2QgZm9yIHRyYW5zZm9ybWluZyB0b2tlbnMgaW50byB0aGUgcGF0aCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gdG9rZW5zVG9GdW5jdGlvbiAodG9rZW5zKSB7XG4gIC8vIENvbXBpbGUgYWxsIHRoZSB0b2tlbnMgaW50byByZWdleHBzLlxuICB2YXIgbWF0Y2hlcyA9IG5ldyBBcnJheSh0b2tlbnMubGVuZ3RoKVxuXG4gIC8vIENvbXBpbGUgYWxsIHRoZSBwYXR0ZXJucyBiZWZvcmUgY29tcGlsYXRpb24uXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdG9rZW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHR5cGVvZiB0b2tlbnNbaV0gPT09ICdvYmplY3QnKSB7XG4gICAgICBtYXRjaGVzW2ldID0gbmV3IFJlZ0V4cCgnXig/OicgKyB0b2tlbnNbaV0ucGF0dGVybiArICcpJCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChvYmosIG9wdHMpIHtcbiAgICB2YXIgcGF0aCA9ICcnXG4gICAgdmFyIGRhdGEgPSBvYmogfHwge31cbiAgICB2YXIgb3B0aW9ucyA9IG9wdHMgfHwge31cbiAgICB2YXIgZW5jb2RlID0gb3B0aW9ucy5wcmV0dHkgPyBlbmNvZGVVUklDb21wb25lbnRQcmV0dHkgOiBlbmNvZGVVUklDb21wb25lbnRcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdG9rZW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdG9rZW4gPSB0b2tlbnNbaV1cblxuICAgICAgaWYgKHR5cGVvZiB0b2tlbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcGF0aCArPSB0b2tlblxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIHZhciB2YWx1ZSA9IGRhdGFbdG9rZW4ubmFtZV1cbiAgICAgIHZhciBzZWdtZW50XG5cbiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICAgIGlmICh0b2tlbi5vcHRpb25hbCkge1xuICAgICAgICAgIC8vIFByZXBlbmQgcGFydGlhbCBzZWdtZW50IHByZWZpeGVzLlxuICAgICAgICAgIGlmICh0b2tlbi5wYXJ0aWFsKSB7XG4gICAgICAgICAgICBwYXRoICs9IHRva2VuLnByZWZpeFxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRXhwZWN0ZWQgXCInICsgdG9rZW4ubmFtZSArICdcIiB0byBiZSBkZWZpbmVkJylcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoaXNhcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgaWYgKCF0b2tlbi5yZXBlYXQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdFeHBlY3RlZCBcIicgKyB0b2tlbi5uYW1lICsgJ1wiIHRvIG5vdCByZXBlYXQsIGJ1dCByZWNlaXZlZCBgJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKSArICdgJylcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICBpZiAodG9rZW4ub3B0aW9uYWwpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0V4cGVjdGVkIFwiJyArIHRva2VuLm5hbWUgKyAnXCIgdG8gbm90IGJlIGVtcHR5JylcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHZhbHVlLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgc2VnbWVudCA9IGVuY29kZSh2YWx1ZVtqXSlcblxuICAgICAgICAgIGlmICghbWF0Y2hlc1tpXS50ZXN0KHNlZ21lbnQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdFeHBlY3RlZCBhbGwgXCInICsgdG9rZW4ubmFtZSArICdcIiB0byBtYXRjaCBcIicgKyB0b2tlbi5wYXR0ZXJuICsgJ1wiLCBidXQgcmVjZWl2ZWQgYCcgKyBKU09OLnN0cmluZ2lmeShzZWdtZW50KSArICdgJylcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBwYXRoICs9IChqID09PSAwID8gdG9rZW4ucHJlZml4IDogdG9rZW4uZGVsaW1pdGVyKSArIHNlZ21lbnRcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIHNlZ21lbnQgPSB0b2tlbi5hc3RlcmlzayA/IGVuY29kZUFzdGVyaXNrKHZhbHVlKSA6IGVuY29kZSh2YWx1ZSlcblxuICAgICAgaWYgKCFtYXRjaGVzW2ldLnRlc3Qoc2VnbWVudCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRXhwZWN0ZWQgXCInICsgdG9rZW4ubmFtZSArICdcIiB0byBtYXRjaCBcIicgKyB0b2tlbi5wYXR0ZXJuICsgJ1wiLCBidXQgcmVjZWl2ZWQgXCInICsgc2VnbWVudCArICdcIicpXG4gICAgICB9XG5cbiAgICAgIHBhdGggKz0gdG9rZW4ucHJlZml4ICsgc2VnbWVudFxuICAgIH1cblxuICAgIHJldHVybiBwYXRoXG4gIH1cbn1cblxuLyoqXG4gKiBFc2NhcGUgYSByZWd1bGFyIGV4cHJlc3Npb24gc3RyaW5nLlxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGVzY2FwZVN0cmluZyAoc3RyKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvKFsuKyo/PV4hOiR7fSgpW1xcXXxcXC9cXFxcXSkvZywgJ1xcXFwkMScpXG59XG5cbi8qKlxuICogRXNjYXBlIHRoZSBjYXB0dXJpbmcgZ3JvdXAgYnkgZXNjYXBpbmcgc3BlY2lhbCBjaGFyYWN0ZXJzIGFuZCBtZWFuaW5nLlxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gZ3JvdXBcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuZnVuY3Rpb24gZXNjYXBlR3JvdXAgKGdyb3VwKSB7XG4gIHJldHVybiBncm91cC5yZXBsYWNlKC8oWz0hOiRcXC8oKV0pL2csICdcXFxcJDEnKVxufVxuXG4vKipcbiAqIEF0dGFjaCB0aGUga2V5cyBhcyBhIHByb3BlcnR5IG9mIHRoZSByZWdleHAuXG4gKlxuICogQHBhcmFtICB7IVJlZ0V4cH0gcmVcbiAqIEBwYXJhbSAge0FycmF5fSAgIGtleXNcbiAqIEByZXR1cm4geyFSZWdFeHB9XG4gKi9cbmZ1bmN0aW9uIGF0dGFjaEtleXMgKHJlLCBrZXlzKSB7XG4gIHJlLmtleXMgPSBrZXlzXG4gIHJldHVybiByZVxufVxuXG4vKipcbiAqIEdldCB0aGUgZmxhZ3MgZm9yIGEgcmVnZXhwIGZyb20gdGhlIG9wdGlvbnMuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGZsYWdzIChvcHRpb25zKSB7XG4gIHJldHVybiBvcHRpb25zLnNlbnNpdGl2ZSA/ICcnIDogJ2knXG59XG5cbi8qKlxuICogUHVsbCBvdXQga2V5cyBmcm9tIGEgcmVnZXhwLlxuICpcbiAqIEBwYXJhbSAgeyFSZWdFeHB9IHBhdGhcbiAqIEBwYXJhbSAgeyFBcnJheX0gIGtleXNcbiAqIEByZXR1cm4geyFSZWdFeHB9XG4gKi9cbmZ1bmN0aW9uIHJlZ2V4cFRvUmVnZXhwIChwYXRoLCBrZXlzKSB7XG4gIC8vIFVzZSBhIG5lZ2F0aXZlIGxvb2thaGVhZCB0byBtYXRjaCBvbmx5IGNhcHR1cmluZyBncm91cHMuXG4gIHZhciBncm91cHMgPSBwYXRoLnNvdXJjZS5tYXRjaCgvXFwoKD8hXFw/KS9nKVxuXG4gIGlmIChncm91cHMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGdyb3Vwcy5sZW5ndGg7IGkrKykge1xuICAgICAga2V5cy5wdXNoKHtcbiAgICAgICAgbmFtZTogaSxcbiAgICAgICAgcHJlZml4OiBudWxsLFxuICAgICAgICBkZWxpbWl0ZXI6IG51bGwsXG4gICAgICAgIG9wdGlvbmFsOiBmYWxzZSxcbiAgICAgICAgcmVwZWF0OiBmYWxzZSxcbiAgICAgICAgcGFydGlhbDogZmFsc2UsXG4gICAgICAgIGFzdGVyaXNrOiBmYWxzZSxcbiAgICAgICAgcGF0dGVybjogbnVsbFxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYXR0YWNoS2V5cyhwYXRoLCBrZXlzKVxufVxuXG4vKipcbiAqIFRyYW5zZm9ybSBhbiBhcnJheSBpbnRvIGEgcmVnZXhwLlxuICpcbiAqIEBwYXJhbSAgeyFBcnJheX0gIHBhdGhcbiAqIEBwYXJhbSAge0FycmF5fSAgIGtleXNcbiAqIEBwYXJhbSAgeyFPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4geyFSZWdFeHB9XG4gKi9cbmZ1bmN0aW9uIGFycmF5VG9SZWdleHAgKHBhdGgsIGtleXMsIG9wdGlvbnMpIHtcbiAgdmFyIHBhcnRzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHBhdGgubGVuZ3RoOyBpKyspIHtcbiAgICBwYXJ0cy5wdXNoKHBhdGhUb1JlZ2V4cChwYXRoW2ldLCBrZXlzLCBvcHRpb25zKS5zb3VyY2UpXG4gIH1cblxuICB2YXIgcmVnZXhwID0gbmV3IFJlZ0V4cCgnKD86JyArIHBhcnRzLmpvaW4oJ3wnKSArICcpJywgZmxhZ3Mob3B0aW9ucykpXG5cbiAgcmV0dXJuIGF0dGFjaEtleXMocmVnZXhwLCBrZXlzKVxufVxuXG4vKipcbiAqIENyZWF0ZSBhIHBhdGggcmVnZXhwIGZyb20gc3RyaW5nIGlucHV0LlxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gIHBhdGhcbiAqIEBwYXJhbSAgeyFBcnJheX0gIGtleXNcbiAqIEBwYXJhbSAgeyFPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4geyFSZWdFeHB9XG4gKi9cbmZ1bmN0aW9uIHN0cmluZ1RvUmVnZXhwIChwYXRoLCBrZXlzLCBvcHRpb25zKSB7XG4gIHZhciB0b2tlbnMgPSBwYXJzZShwYXRoKVxuICB2YXIgcmUgPSB0b2tlbnNUb1JlZ0V4cCh0b2tlbnMsIG9wdGlvbnMpXG5cbiAgLy8gQXR0YWNoIGtleXMgYmFjayB0byB0aGUgcmVnZXhwLlxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRva2Vucy5sZW5ndGg7IGkrKykge1xuICAgIGlmICh0eXBlb2YgdG9rZW5zW2ldICE9PSAnc3RyaW5nJykge1xuICAgICAga2V5cy5wdXNoKHRva2Vuc1tpXSlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYXR0YWNoS2V5cyhyZSwga2V5cylcbn1cblxuLyoqXG4gKiBFeHBvc2UgYSBmdW5jdGlvbiBmb3IgdGFraW5nIHRva2VucyBhbmQgcmV0dXJuaW5nIGEgUmVnRXhwLlxuICpcbiAqIEBwYXJhbSAgeyFBcnJheX0gIHRva2Vuc1xuICogQHBhcmFtICB7T2JqZWN0PX0gb3B0aW9uc1xuICogQHJldHVybiB7IVJlZ0V4cH1cbiAqL1xuZnVuY3Rpb24gdG9rZW5zVG9SZWdFeHAgKHRva2Vucywgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuXG4gIHZhciBzdHJpY3QgPSBvcHRpb25zLnN0cmljdFxuICB2YXIgZW5kID0gb3B0aW9ucy5lbmQgIT09IGZhbHNlXG4gIHZhciByb3V0ZSA9ICcnXG4gIHZhciBsYXN0VG9rZW4gPSB0b2tlbnNbdG9rZW5zLmxlbmd0aCAtIDFdXG4gIHZhciBlbmRzV2l0aFNsYXNoID0gdHlwZW9mIGxhc3RUb2tlbiA9PT0gJ3N0cmluZycgJiYgL1xcLyQvLnRlc3QobGFzdFRva2VuKVxuXG4gIC8vIEl0ZXJhdGUgb3ZlciB0aGUgdG9rZW5zIGFuZCBjcmVhdGUgb3VyIHJlZ2V4cCBzdHJpbmcuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdG9rZW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHRva2VuID0gdG9rZW5zW2ldXG5cbiAgICBpZiAodHlwZW9mIHRva2VuID09PSAnc3RyaW5nJykge1xuICAgICAgcm91dGUgKz0gZXNjYXBlU3RyaW5nKHRva2VuKVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgcHJlZml4ID0gZXNjYXBlU3RyaW5nKHRva2VuLnByZWZpeClcbiAgICAgIHZhciBjYXB0dXJlID0gJyg/OicgKyB0b2tlbi5wYXR0ZXJuICsgJyknXG5cbiAgICAgIGlmICh0b2tlbi5yZXBlYXQpIHtcbiAgICAgICAgY2FwdHVyZSArPSAnKD86JyArIHByZWZpeCArIGNhcHR1cmUgKyAnKSonXG4gICAgICB9XG5cbiAgICAgIGlmICh0b2tlbi5vcHRpb25hbCkge1xuICAgICAgICBpZiAoIXRva2VuLnBhcnRpYWwpIHtcbiAgICAgICAgICBjYXB0dXJlID0gJyg/OicgKyBwcmVmaXggKyAnKCcgKyBjYXB0dXJlICsgJykpPydcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjYXB0dXJlID0gcHJlZml4ICsgJygnICsgY2FwdHVyZSArICcpPydcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FwdHVyZSA9IHByZWZpeCArICcoJyArIGNhcHR1cmUgKyAnKSdcbiAgICAgIH1cblxuICAgICAgcm91dGUgKz0gY2FwdHVyZVxuICAgIH1cbiAgfVxuXG4gIC8vIEluIG5vbi1zdHJpY3QgbW9kZSB3ZSBhbGxvdyBhIHNsYXNoIGF0IHRoZSBlbmQgb2YgbWF0Y2guIElmIHRoZSBwYXRoIHRvXG4gIC8vIG1hdGNoIGFscmVhZHkgZW5kcyB3aXRoIGEgc2xhc2gsIHdlIHJlbW92ZSBpdCBmb3IgY29uc2lzdGVuY3kuIFRoZSBzbGFzaFxuICAvLyBpcyB2YWxpZCBhdCB0aGUgZW5kIG9mIGEgcGF0aCBtYXRjaCwgbm90IGluIHRoZSBtaWRkbGUuIFRoaXMgaXMgaW1wb3J0YW50XG4gIC8vIGluIG5vbi1lbmRpbmcgbW9kZSwgd2hlcmUgXCIvdGVzdC9cIiBzaG91bGRuJ3QgbWF0Y2ggXCIvdGVzdC8vcm91dGVcIi5cbiAgaWYgKCFzdHJpY3QpIHtcbiAgICByb3V0ZSA9IChlbmRzV2l0aFNsYXNoID8gcm91dGUuc2xpY2UoMCwgLTIpIDogcm91dGUpICsgJyg/OlxcXFwvKD89JCkpPydcbiAgfVxuXG4gIGlmIChlbmQpIHtcbiAgICByb3V0ZSArPSAnJCdcbiAgfSBlbHNlIHtcbiAgICAvLyBJbiBub24tZW5kaW5nIG1vZGUsIHdlIG5lZWQgdGhlIGNhcHR1cmluZyBncm91cHMgdG8gbWF0Y2ggYXMgbXVjaCBhc1xuICAgIC8vIHBvc3NpYmxlIGJ5IHVzaW5nIGEgcG9zaXRpdmUgbG9va2FoZWFkIHRvIHRoZSBlbmQgb3IgbmV4dCBwYXRoIHNlZ21lbnQuXG4gICAgcm91dGUgKz0gc3RyaWN0ICYmIGVuZHNXaXRoU2xhc2ggPyAnJyA6ICcoPz1cXFxcL3wkKSdcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVnRXhwKCdeJyArIHJvdXRlLCBmbGFncyhvcHRpb25zKSlcbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgdGhlIGdpdmVuIHBhdGggc3RyaW5nLCByZXR1cm5pbmcgYSByZWd1bGFyIGV4cHJlc3Npb24uXG4gKlxuICogQW4gZW1wdHkgYXJyYXkgY2FuIGJlIHBhc3NlZCBpbiBmb3IgdGhlIGtleXMsIHdoaWNoIHdpbGwgaG9sZCB0aGVcbiAqIHBsYWNlaG9sZGVyIGtleSBkZXNjcmlwdGlvbnMuIEZvciBleGFtcGxlLCB1c2luZyBgL3VzZXIvOmlkYCwgYGtleXNgIHdpbGxcbiAqIGNvbnRhaW4gYFt7IG5hbWU6ICdpZCcsIGRlbGltaXRlcjogJy8nLCBvcHRpb25hbDogZmFsc2UsIHJlcGVhdDogZmFsc2UgfV1gLlxuICpcbiAqIEBwYXJhbSAgeyhzdHJpbmd8UmVnRXhwfEFycmF5KX0gcGF0aFxuICogQHBhcmFtICB7KEFycmF5fE9iamVjdCk9fSAgICAgICBrZXlzXG4gKiBAcGFyYW0gIHtPYmplY3Q9fSAgICAgICAgICAgICAgIG9wdGlvbnNcbiAqIEByZXR1cm4geyFSZWdFeHB9XG4gKi9cbmZ1bmN0aW9uIHBhdGhUb1JlZ2V4cCAocGF0aCwga2V5cywgb3B0aW9ucykge1xuICBrZXlzID0ga2V5cyB8fCBbXVxuXG4gIGlmICghaXNhcnJheShrZXlzKSkge1xuICAgIG9wdGlvbnMgPSAvKiogQHR5cGUgeyFPYmplY3R9ICovIChrZXlzKVxuICAgIGtleXMgPSBbXVxuICB9IGVsc2UgaWYgKCFvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IHt9XG4gIH1cblxuICBpZiAocGF0aCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgIHJldHVybiByZWdleHBUb1JlZ2V4cChwYXRoLCAvKiogQHR5cGUgeyFBcnJheX0gKi8gKGtleXMpKVxuICB9XG5cbiAgaWYgKGlzYXJyYXkocGF0aCkpIHtcbiAgICByZXR1cm4gYXJyYXlUb1JlZ2V4cCgvKiogQHR5cGUgeyFBcnJheX0gKi8gKHBhdGgpLCAvKiogQHR5cGUgeyFBcnJheX0gKi8gKGtleXMpLCBvcHRpb25zKVxuICB9XG5cbiAgcmV0dXJuIHN0cmluZ1RvUmVnZXhwKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAocGF0aCksIC8qKiBAdHlwZSB7IUFycmF5fSAqLyAoa2V5cyksIG9wdGlvbnMpXG59XG5cbmluZGV4LnBhcnNlID0gcGFyc2VfMTtcbmluZGV4LmNvbXBpbGUgPSBjb21waWxlXzE7XG5pbmRleC50b2tlbnNUb0Z1bmN0aW9uID0gdG9rZW5zVG9GdW5jdGlvbl8xO1xuaW5kZXgudG9rZW5zVG9SZWdFeHAgPSB0b2tlbnNUb1JlZ0V4cF8xO1xuXG4vKiAgKi9cblxuZnVuY3Rpb24gY3JlYXRlUm91dGVNYXAgKHJvdXRlcykge1xuICB2YXIgcGF0aE1hcCA9IE9iamVjdC5jcmVhdGUobnVsbClcbiAgdmFyIG5hbWVNYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgcm91dGVzLmZvckVhY2goZnVuY3Rpb24gKHJvdXRlKSB7XG4gICAgYWRkUm91dGVSZWNvcmQocGF0aE1hcCwgbmFtZU1hcCwgcm91dGUpXG4gIH0pXG5cbiAgcmV0dXJuIHtcbiAgICBwYXRoTWFwOiBwYXRoTWFwLFxuICAgIG5hbWVNYXA6IG5hbWVNYXBcbiAgfVxufVxuXG5mdW5jdGlvbiBhZGRSb3V0ZVJlY29yZCAoXG4gIHBhdGhNYXAsXG4gIG5hbWVNYXAsXG4gIHJvdXRlLFxuICBwYXJlbnQsXG4gIG1hdGNoQXNcbikge1xuICB2YXIgcGF0aCA9IHJvdXRlLnBhdGg7XG4gIHZhciBuYW1lID0gcm91dGUubmFtZTtcbiAgYXNzZXJ0KHBhdGggIT0gbnVsbCwgXCJcXFwicGF0aFxcXCIgaXMgcmVxdWlyZWQgaW4gYSByb3V0ZSBjb25maWd1cmF0aW9uLlwiKVxuXG4gIHZhciByZWNvcmQgPSB7XG4gICAgcGF0aDogbm9ybWFsaXplUGF0aChwYXRoLCBwYXJlbnQpLFxuICAgIGNvbXBvbmVudHM6IHJvdXRlLmNvbXBvbmVudHMgfHwgeyBkZWZhdWx0OiByb3V0ZS5jb21wb25lbnQgfSxcbiAgICBpbnN0YW5jZXM6IHt9LFxuICAgIG5hbWU6IG5hbWUsXG4gICAgcGFyZW50OiBwYXJlbnQsXG4gICAgbWF0Y2hBczogbWF0Y2hBcyxcbiAgICByZWRpcmVjdDogcm91dGUucmVkaXJlY3QsXG4gICAgYmVmb3JlRW50ZXI6IHJvdXRlLmJlZm9yZUVudGVyLFxuICAgIG1ldGE6IHJvdXRlLm1ldGEgfHwge31cbiAgfVxuXG4gIGlmIChyb3V0ZS5jaGlsZHJlbikge1xuICAgIC8vIFdhcm4gaWYgcm91dGUgaXMgbmFtZWQgYW5kIGhhcyBhIGRlZmF1bHQgY2hpbGQgcm91dGUuXG4gICAgLy8gSWYgdXNlcnMgbmF2aWdhdGUgdG8gdGhpcyByb3V0ZSBieSBuYW1lLCB0aGUgZGVmYXVsdCBjaGlsZCB3aWxsXG4gICAgLy8gbm90IGJlIHJlbmRlcmVkIChHSCBJc3N1ZSAjNjI5KVxuICAgIGlmIChcInByb2R1Y3Rpb25cIiAhPT0gJ3Byb2R1Y3Rpb24nKSB7fVxuICAgIHJvdXRlLmNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICBhZGRSb3V0ZVJlY29yZChwYXRoTWFwLCBuYW1lTWFwLCBjaGlsZCwgcmVjb3JkKVxuICAgIH0pXG4gIH1cblxuICBpZiAocm91dGUuYWxpYXMpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyb3V0ZS5hbGlhcykpIHtcbiAgICAgIHJvdXRlLmFsaWFzLmZvckVhY2goZnVuY3Rpb24gKGFsaWFzKSB7XG4gICAgICAgIGFkZFJvdXRlUmVjb3JkKHBhdGhNYXAsIG5hbWVNYXAsIHsgcGF0aDogYWxpYXMgfSwgcGFyZW50LCByZWNvcmQucGF0aClcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIGFkZFJvdXRlUmVjb3JkKHBhdGhNYXAsIG5hbWVNYXAsIHsgcGF0aDogcm91dGUuYWxpYXMgfSwgcGFyZW50LCByZWNvcmQucGF0aClcbiAgICB9XG4gIH1cblxuICBwYXRoTWFwW3JlY29yZC5wYXRoXSA9IHJlY29yZFxuICBpZiAobmFtZSkgeyBuYW1lTWFwW25hbWVdID0gcmVjb3JkIH1cbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplUGF0aCAocGF0aCwgcGFyZW50KSB7XG4gIHBhdGggPSBwYXRoLnJlcGxhY2UoL1xcLyQvLCAnJylcbiAgaWYgKHBhdGhbMF0gPT09ICcvJykgeyByZXR1cm4gcGF0aCB9XG4gIGlmIChwYXJlbnQgPT0gbnVsbCkgeyByZXR1cm4gcGF0aCB9XG4gIHJldHVybiBjbGVhblBhdGgoKChwYXJlbnQucGF0aCkgKyBcIi9cIiArIHBhdGgpKVxufVxuXG4vKiAgKi9cblxudmFyIHJlZ2V4cENhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuXG52YXIgcmVnZXhwQ29tcGlsZUNhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuXG5mdW5jdGlvbiBjcmVhdGVNYXRjaGVyIChyb3V0ZXMpIHtcbiAgdmFyIHJlZiA9IGNyZWF0ZVJvdXRlTWFwKHJvdXRlcyk7XG4gIHZhciBwYXRoTWFwID0gcmVmLnBhdGhNYXA7XG4gIHZhciBuYW1lTWFwID0gcmVmLm5hbWVNYXA7XG5cbiAgZnVuY3Rpb24gbWF0Y2ggKFxuICAgIHJhdyxcbiAgICBjdXJyZW50Um91dGUsXG4gICAgcmVkaXJlY3RlZEZyb21cbiAgKSB7XG4gICAgdmFyIGxvY2F0aW9uID0gbm9ybWFsaXplTG9jYXRpb24ocmF3LCBjdXJyZW50Um91dGUpXG4gICAgdmFyIG5hbWUgPSBsb2NhdGlvbi5uYW1lO1xuXG4gICAgaWYgKG5hbWUpIHtcbiAgICAgIHZhciByZWNvcmQgPSBuYW1lTWFwW25hbWVdXG4gICAgICBpZiAocmVjb3JkKSB7XG4gICAgICAgIGxvY2F0aW9uLnBhdGggPSBmaWxsUGFyYW1zKHJlY29yZC5wYXRoLCBsb2NhdGlvbi5wYXJhbXMsIChcIm5hbWVkIHJvdXRlIFxcXCJcIiArIG5hbWUgKyBcIlxcXCJcIikpXG4gICAgICAgIHJldHVybiBfY3JlYXRlUm91dGUocmVjb3JkLCBsb2NhdGlvbiwgcmVkaXJlY3RlZEZyb20pXG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChsb2NhdGlvbi5wYXRoKSB7XG4gICAgICBsb2NhdGlvbi5wYXJhbXMgPSB7fVxuICAgICAgZm9yICh2YXIgcGF0aCBpbiBwYXRoTWFwKSB7XG4gICAgICAgIGlmIChtYXRjaFJvdXRlKHBhdGgsIGxvY2F0aW9uLnBhcmFtcywgbG9jYXRpb24ucGF0aCkpIHtcbiAgICAgICAgICByZXR1cm4gX2NyZWF0ZVJvdXRlKHBhdGhNYXBbcGF0aF0sIGxvY2F0aW9uLCByZWRpcmVjdGVkRnJvbSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBubyBtYXRjaFxuICAgIHJldHVybiBfY3JlYXRlUm91dGUobnVsbCwgbG9jYXRpb24pXG4gIH1cblxuICBmdW5jdGlvbiByZWRpcmVjdCAoXG4gICAgcmVjb3JkLFxuICAgIGxvY2F0aW9uXG4gICkge1xuICAgIHZhciBvcmlnaW5hbFJlZGlyZWN0ID0gcmVjb3JkLnJlZGlyZWN0XG4gICAgdmFyIHJlZGlyZWN0ID0gdHlwZW9mIG9yaWdpbmFsUmVkaXJlY3QgPT09ICdmdW5jdGlvbidcbiAgICAgICAgPyBvcmlnaW5hbFJlZGlyZWN0KGNyZWF0ZVJvdXRlKHJlY29yZCwgbG9jYXRpb24pKVxuICAgICAgICA6IG9yaWdpbmFsUmVkaXJlY3RcblxuICAgIGlmICh0eXBlb2YgcmVkaXJlY3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZWRpcmVjdCA9IHsgcGF0aDogcmVkaXJlY3QgfVxuICAgIH1cblxuICAgIGlmICghcmVkaXJlY3QgfHwgdHlwZW9mIHJlZGlyZWN0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgd2FybihmYWxzZSwgKFwiaW52YWxpZCByZWRpcmVjdCBvcHRpb246IFwiICsgKEpTT04uc3RyaW5naWZ5KHJlZGlyZWN0KSkpKVxuICAgICAgcmV0dXJuIF9jcmVhdGVSb3V0ZShudWxsLCBsb2NhdGlvbilcbiAgICB9XG5cbiAgICB2YXIgcmUgPSByZWRpcmVjdFxuICAgIHZhciBuYW1lID0gcmUubmFtZTtcbiAgICB2YXIgcGF0aCA9IHJlLnBhdGg7XG4gICAgdmFyIHF1ZXJ5ID0gbG9jYXRpb24ucXVlcnk7XG4gICAgdmFyIGhhc2ggPSBsb2NhdGlvbi5oYXNoO1xuICAgIHZhciBwYXJhbXMgPSBsb2NhdGlvbi5wYXJhbXM7XG4gICAgcXVlcnkgPSByZS5oYXNPd25Qcm9wZXJ0eSgncXVlcnknKSA/IHJlLnF1ZXJ5IDogcXVlcnlcbiAgICBoYXNoID0gcmUuaGFzT3duUHJvcGVydHkoJ2hhc2gnKSA/IHJlLmhhc2ggOiBoYXNoXG4gICAgcGFyYW1zID0gcmUuaGFzT3duUHJvcGVydHkoJ3BhcmFtcycpID8gcmUucGFyYW1zIDogcGFyYW1zXG5cbiAgICBpZiAobmFtZSkge1xuICAgICAgLy8gcmVzb2x2ZWQgbmFtZWQgZGlyZWN0XG4gICAgICB2YXIgdGFyZ2V0UmVjb3JkID0gbmFtZU1hcFtuYW1lXVxuICAgICAgYXNzZXJ0KHRhcmdldFJlY29yZCwgKFwicmVkaXJlY3QgZmFpbGVkOiBuYW1lZCByb3V0ZSBcXFwiXCIgKyBuYW1lICsgXCJcXFwiIG5vdCBmb3VuZC5cIikpXG4gICAgICByZXR1cm4gbWF0Y2goe1xuICAgICAgICBfbm9ybWFsaXplZDogdHJ1ZSxcbiAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgcXVlcnk6IHF1ZXJ5LFxuICAgICAgICBoYXNoOiBoYXNoLFxuICAgICAgICBwYXJhbXM6IHBhcmFtc1xuICAgICAgfSwgdW5kZWZpbmVkLCBsb2NhdGlvbilcbiAgICB9IGVsc2UgaWYgKHBhdGgpIHtcbiAgICAgIC8vIDEuIHJlc29sdmUgcmVsYXRpdmUgcmVkaXJlY3RcbiAgICAgIHZhciByYXdQYXRoID0gcmVzb2x2ZVJlY29yZFBhdGgocGF0aCwgcmVjb3JkKVxuICAgICAgLy8gMi4gcmVzb2x2ZSBwYXJhbXNcbiAgICAgIHZhciByZXNvbHZlZFBhdGggPSBmaWxsUGFyYW1zKHJhd1BhdGgsIHBhcmFtcywgKFwicmVkaXJlY3Qgcm91dGUgd2l0aCBwYXRoIFxcXCJcIiArIHJhd1BhdGggKyBcIlxcXCJcIikpXG4gICAgICAvLyAzLiByZW1hdGNoIHdpdGggZXhpc3RpbmcgcXVlcnkgYW5kIGhhc2hcbiAgICAgIHJldHVybiBtYXRjaCh7XG4gICAgICAgIF9ub3JtYWxpemVkOiB0cnVlLFxuICAgICAgICBwYXRoOiByZXNvbHZlZFBhdGgsXG4gICAgICAgIHF1ZXJ5OiBxdWVyeSxcbiAgICAgICAgaGFzaDogaGFzaFxuICAgICAgfSwgdW5kZWZpbmVkLCBsb2NhdGlvbilcbiAgICB9IGVsc2Uge1xuICAgICAgd2FybihmYWxzZSwgKFwiaW52YWxpZCByZWRpcmVjdCBvcHRpb246IFwiICsgKEpTT04uc3RyaW5naWZ5KHJlZGlyZWN0KSkpKVxuICAgICAgcmV0dXJuIF9jcmVhdGVSb3V0ZShudWxsLCBsb2NhdGlvbilcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBhbGlhcyAoXG4gICAgcmVjb3JkLFxuICAgIGxvY2F0aW9uLFxuICAgIG1hdGNoQXNcbiAgKSB7XG4gICAgdmFyIGFsaWFzZWRQYXRoID0gZmlsbFBhcmFtcyhtYXRjaEFzLCBsb2NhdGlvbi5wYXJhbXMsIChcImFsaWFzZWQgcm91dGUgd2l0aCBwYXRoIFxcXCJcIiArIG1hdGNoQXMgKyBcIlxcXCJcIikpXG4gICAgdmFyIGFsaWFzZWRNYXRjaCA9IG1hdGNoKHtcbiAgICAgIF9ub3JtYWxpemVkOiB0cnVlLFxuICAgICAgcGF0aDogYWxpYXNlZFBhdGhcbiAgICB9KVxuICAgIGlmIChhbGlhc2VkTWF0Y2gpIHtcbiAgICAgIHZhciBtYXRjaGVkID0gYWxpYXNlZE1hdGNoLm1hdGNoZWRcbiAgICAgIHZhciBhbGlhc2VkUmVjb3JkID0gbWF0Y2hlZFttYXRjaGVkLmxlbmd0aCAtIDFdXG4gICAgICBsb2NhdGlvbi5wYXJhbXMgPSBhbGlhc2VkTWF0Y2gucGFyYW1zXG4gICAgICByZXR1cm4gX2NyZWF0ZVJvdXRlKGFsaWFzZWRSZWNvcmQsIGxvY2F0aW9uKVxuICAgIH1cbiAgICByZXR1cm4gX2NyZWF0ZVJvdXRlKG51bGwsIGxvY2F0aW9uKVxuICB9XG5cbiAgZnVuY3Rpb24gX2NyZWF0ZVJvdXRlIChcbiAgICByZWNvcmQsXG4gICAgbG9jYXRpb24sXG4gICAgcmVkaXJlY3RlZEZyb21cbiAgKSB7XG4gICAgaWYgKHJlY29yZCAmJiByZWNvcmQucmVkaXJlY3QpIHtcbiAgICAgIHJldHVybiByZWRpcmVjdChyZWNvcmQsIHJlZGlyZWN0ZWRGcm9tIHx8IGxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAocmVjb3JkICYmIHJlY29yZC5tYXRjaEFzKSB7XG4gICAgICByZXR1cm4gYWxpYXMocmVjb3JkLCBsb2NhdGlvbiwgcmVjb3JkLm1hdGNoQXMpXG4gICAgfVxuICAgIHJldHVybiBjcmVhdGVSb3V0ZShyZWNvcmQsIGxvY2F0aW9uLCByZWRpcmVjdGVkRnJvbSlcbiAgfVxuXG4gIHJldHVybiBtYXRjaFxufVxuXG5mdW5jdGlvbiBtYXRjaFJvdXRlIChcbiAgcGF0aCxcbiAgcGFyYW1zLFxuICBwYXRobmFtZVxuKSB7XG4gIHZhciBrZXlzLCByZWdleHBcbiAgdmFyIGhpdCA9IHJlZ2V4cENhY2hlW3BhdGhdXG4gIGlmIChoaXQpIHtcbiAgICBrZXlzID0gaGl0LmtleXNcbiAgICByZWdleHAgPSBoaXQucmVnZXhwXG4gIH0gZWxzZSB7XG4gICAga2V5cyA9IFtdXG4gICAgcmVnZXhwID0gaW5kZXgocGF0aCwga2V5cylcbiAgICByZWdleHBDYWNoZVtwYXRoXSA9IHsga2V5czoga2V5cywgcmVnZXhwOiByZWdleHAgfVxuICB9XG4gIHZhciBtID0gcGF0aG5hbWUubWF0Y2gocmVnZXhwKVxuXG4gIGlmICghbSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9IGVsc2UgaWYgKCFwYXJhbXMpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgZm9yICh2YXIgaSA9IDEsIGxlbiA9IG0ubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICB2YXIga2V5ID0ga2V5c1tpIC0gMV1cbiAgICB2YXIgdmFsID0gdHlwZW9mIG1baV0gPT09ICdzdHJpbmcnID8gZGVjb2RlVVJJQ29tcG9uZW50KG1baV0pIDogbVtpXVxuICAgIGlmIChrZXkpIHsgcGFyYW1zW2tleS5uYW1lXSA9IHZhbCB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuXG5mdW5jdGlvbiBmaWxsUGFyYW1zIChcbiAgcGF0aCxcbiAgcGFyYW1zLFxuICByb3V0ZU1zZ1xuKSB7XG4gIHRyeSB7XG4gICAgdmFyIGZpbGxlciA9XG4gICAgICByZWdleHBDb21waWxlQ2FjaGVbcGF0aF0gfHxcbiAgICAgIChyZWdleHBDb21waWxlQ2FjaGVbcGF0aF0gPSBpbmRleC5jb21waWxlKHBhdGgpKVxuICAgIHJldHVybiBmaWxsZXIocGFyYW1zIHx8IHt9LCB7IHByZXR0eTogdHJ1ZSB9KVxuICB9IGNhdGNoIChlKSB7XG4gICAgYXNzZXJ0KGZhbHNlLCAoXCJtaXNzaW5nIHBhcmFtIGZvciBcIiArIHJvdXRlTXNnICsgXCI6IFwiICsgKGUubWVzc2FnZSkpKVxuICAgIHJldHVybiAnJ1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVSZWNvcmRQYXRoIChwYXRoLCByZWNvcmQpIHtcbiAgcmV0dXJuIHJlc29sdmVQYXRoKHBhdGgsIHJlY29yZC5wYXJlbnQgPyByZWNvcmQucGFyZW50LnBhdGggOiAnLycsIHRydWUpXG59XG5cbi8qICAqL1xuXG52YXIgaW5Ccm93c2VyID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCdcblxudmFyIHN1cHBvcnRzSGlzdG9yeSA9IGluQnJvd3NlciAmJiAoZnVuY3Rpb24gKCkge1xuICB2YXIgdWEgPSB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudFxuXG4gIGlmIChcbiAgICAodWEuaW5kZXhPZignQW5kcm9pZCAyLicpICE9PSAtMSB8fCB1YS5pbmRleE9mKCdBbmRyb2lkIDQuMCcpICE9PSAtMSkgJiZcbiAgICB1YS5pbmRleE9mKCdNb2JpbGUgU2FmYXJpJykgIT09IC0xICYmXG4gICAgdWEuaW5kZXhPZignQ2hyb21lJykgPT09IC0xICYmXG4gICAgdWEuaW5kZXhPZignV2luZG93cyBQaG9uZScpID09PSAtMVxuICApIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiB3aW5kb3cuaGlzdG9yeSAmJiAncHVzaFN0YXRlJyBpbiB3aW5kb3cuaGlzdG9yeVxufSkoKVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gcnVuUXVldWUgKHF1ZXVlLCBmbiwgY2IpIHtcbiAgdmFyIHN0ZXAgPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICBpZiAoaW5kZXggPj0gcXVldWUubGVuZ3RoKSB7XG4gICAgICBjYigpXG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChxdWV1ZVtpbmRleF0pIHtcbiAgICAgICAgZm4ocXVldWVbaW5kZXhdLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgc3RlcChpbmRleCArIDEpXG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGVwKGluZGV4ICsgMSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgc3RlcCgwKVxufVxuXG4vKiAgKi9cblxuXG52YXIgSGlzdG9yeSA9IGZ1bmN0aW9uIEhpc3RvcnkgKHJvdXRlciwgYmFzZSkge1xuICB0aGlzLnJvdXRlciA9IHJvdXRlclxuICB0aGlzLmJhc2UgPSBub3JtYWxpemVCYXNlKGJhc2UpXG4gIC8vIHN0YXJ0IHdpdGggYSByb3V0ZSBvYmplY3QgdGhhdCBzdGFuZHMgZm9yIFwibm93aGVyZVwiXG4gIHRoaXMuY3VycmVudCA9IFNUQVJUXG4gIHRoaXMucGVuZGluZyA9IG51bGxcbn07XG5cbkhpc3RvcnkucHJvdG90eXBlLmxpc3RlbiA9IGZ1bmN0aW9uIGxpc3RlbiAoY2IpIHtcbiAgdGhpcy5jYiA9IGNiXG59O1xuXG5IaXN0b3J5LnByb3RvdHlwZS50cmFuc2l0aW9uVG8gPSBmdW5jdGlvbiB0cmFuc2l0aW9uVG8gKGxvY2F0aW9uLCBjYikge1xuICAgIHZhciB0aGlzJDEgPSB0aGlzO1xuXG4gIHZhciByb3V0ZSA9IHRoaXMucm91dGVyLm1hdGNoKGxvY2F0aW9uLCB0aGlzLmN1cnJlbnQpXG4gIHRoaXMuY29uZmlybVRyYW5zaXRpb24ocm91dGUsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzJDEudXBkYXRlUm91dGUocm91dGUpXG4gICAgY2IgJiYgY2Iocm91dGUpXG4gICAgdGhpcyQxLmVuc3VyZVVSTCgpXG4gIH0pXG59O1xuXG5IaXN0b3J5LnByb3RvdHlwZS5jb25maXJtVHJhbnNpdGlvbiA9IGZ1bmN0aW9uIGNvbmZpcm1UcmFuc2l0aW9uIChyb3V0ZSwgY2IpIHtcbiAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuICB2YXIgY3VycmVudCA9IHRoaXMuY3VycmVudFxuICBpZiAoaXNTYW1lUm91dGUocm91dGUsIGN1cnJlbnQpKSB7XG4gICAgdGhpcy5lbnN1cmVVUkwoKVxuICAgIHJldHVyblxuICB9XG5cbiAgdmFyIHJlZiA9IHJlc29sdmVRdWV1ZSh0aGlzLmN1cnJlbnQubWF0Y2hlZCwgcm91dGUubWF0Y2hlZCk7XG4gICAgdmFyIGRlYWN0aXZhdGVkID0gcmVmLmRlYWN0aXZhdGVkO1xuICAgIHZhciBhY3RpdmF0ZWQgPSByZWYuYWN0aXZhdGVkO1xuXG4gIHZhciBxdWV1ZSA9IFtdLmNvbmNhdChcbiAgICAvLyBpbi1jb21wb25lbnQgbGVhdmUgZ3VhcmRzXG4gICAgZXh0cmFjdExlYXZlR3VhcmRzKGRlYWN0aXZhdGVkKSxcbiAgICAvLyBnbG9iYWwgYmVmb3JlIGhvb2tzXG4gICAgdGhpcy5yb3V0ZXIuYmVmb3JlSG9va3MsXG4gICAgLy8gZW50ZXIgZ3VhcmRzXG4gICAgYWN0aXZhdGVkLm1hcChmdW5jdGlvbiAobSkgeyByZXR1cm4gbS5iZWZvcmVFbnRlcjsgfSksXG4gICAgLy8gYXN5bmMgY29tcG9uZW50c1xuICAgIHJlc29sdmVBc3luY0NvbXBvbmVudHMoYWN0aXZhdGVkKVxuICApXG5cbiAgdGhpcy5wZW5kaW5nID0gcm91dGVcbiAgdmFyIGl0ZXJhdG9yID0gZnVuY3Rpb24gKGhvb2ssIG5leHQpIHtcbiAgICBpZiAodGhpcyQxLnBlbmRpbmcgIT09IHJvdXRlKSB7IHJldHVybiB9XG4gICAgaG9vayhyb3V0ZSwgY3VycmVudCwgZnVuY3Rpb24gKHRvKSB7XG4gICAgICBpZiAodG8gPT09IGZhbHNlKSB7XG4gICAgICAgIC8vIG5leHQoZmFsc2UpIC0+IGFib3J0IG5hdmlnYXRpb24sIGVuc3VyZSBjdXJyZW50IFVSTFxuICAgICAgICB0aGlzJDEuZW5zdXJlVVJMKClcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRvID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgdG8gPT09ICdvYmplY3QnKSB7XG4gICAgICAgIC8vIG5leHQoJy8nKSBvciBuZXh0KHsgcGF0aDogJy8nIH0pIC0+IHJlZGlyZWN0XG4gICAgICAgIHRoaXMkMS5wdXNoKHRvKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gY29uZmlybSB0cmFuc2l0aW9uIGFuZCBwYXNzIG9uIHRoZSB2YWx1ZVxuICAgICAgICBuZXh0KHRvKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBydW5RdWV1ZShxdWV1ZSwgaXRlcmF0b3IsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcG9zdEVudGVyQ2JzID0gW11cbiAgICB2YXIgZW50ZXJHdWFyZHMgPSBleHRyYWN0RW50ZXJHdWFyZHMoYWN0aXZhdGVkLCBwb3N0RW50ZXJDYnMsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB0aGlzJDEuY3VycmVudCA9PT0gcm91dGVcbiAgICB9KVxuICAgIC8vIHdhaXQgdW50aWwgYXN5bmMgY29tcG9uZW50cyBhcmUgcmVzb2x2ZWQgYmVmb3JlXG4gICAgLy8gZXh0cmFjdGluZyBpbi1jb21wb25lbnQgZW50ZXIgZ3VhcmRzXG4gICAgcnVuUXVldWUoZW50ZXJHdWFyZHMsIGl0ZXJhdG9yLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAodGhpcyQxLnBlbmRpbmcgPT09IHJvdXRlKSB7XG4gICAgICAgIHRoaXMkMS5wZW5kaW5nID0gbnVsbFxuICAgICAgICBjYihyb3V0ZSlcbiAgICAgICAgdGhpcyQxLnJvdXRlci5hcHAuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBwb3N0RW50ZXJDYnMuZm9yRWFjaChmdW5jdGlvbiAoY2IpIHsgcmV0dXJuIGNiKCk7IH0pXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSlcbiAgfSlcbn07XG5cbkhpc3RvcnkucHJvdG90eXBlLnVwZGF0ZVJvdXRlID0gZnVuY3Rpb24gdXBkYXRlUm91dGUgKHJvdXRlKSB7XG4gIHZhciBwcmV2ID0gdGhpcy5jdXJyZW50XG4gIHRoaXMuY3VycmVudCA9IHJvdXRlXG4gIHRoaXMuY2IgJiYgdGhpcy5jYihyb3V0ZSlcbiAgdGhpcy5yb3V0ZXIuYWZ0ZXJIb29rcy5mb3JFYWNoKGZ1bmN0aW9uIChob29rKSB7XG4gICAgaG9vayAmJiBob29rKHJvdXRlLCBwcmV2KVxuICB9KVxufTtcblxuZnVuY3Rpb24gbm9ybWFsaXplQmFzZSAoYmFzZSkge1xuICBpZiAoIWJhc2UpIHtcbiAgICBpZiAoaW5Ccm93c2VyKSB7XG4gICAgICAvLyByZXNwZWN0IDxiYXNlPiB0YWdcbiAgICAgIHZhciBiYXNlRWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdiYXNlJylcbiAgICAgIGJhc2UgPSBiYXNlRWwgPyBiYXNlRWwuZ2V0QXR0cmlidXRlKCdocmVmJykgOiAnLydcbiAgICB9IGVsc2Uge1xuICAgICAgYmFzZSA9ICcvJ1xuICAgIH1cbiAgfVxuICAvLyBtYWtlIHN1cmUgdGhlcmUncyB0aGUgc3RhcnRpbmcgc2xhc2hcbiAgaWYgKGJhc2UuY2hhckF0KDApICE9PSAnLycpIHtcbiAgICBiYXNlID0gJy8nICsgYmFzZVxuICB9XG4gIC8vIHJlbW92ZSB0cmFpbGluZyBzbGFzaFxuICByZXR1cm4gYmFzZS5yZXBsYWNlKC9cXC8kLywgJycpXG59XG5cbmZ1bmN0aW9uIHJlc29sdmVRdWV1ZSAoXG4gIGN1cnJlbnQsXG4gIG5leHRcbikge1xuICB2YXIgaVxuICB2YXIgbWF4ID0gTWF0aC5tYXgoY3VycmVudC5sZW5ndGgsIG5leHQubGVuZ3RoKVxuICBmb3IgKGkgPSAwOyBpIDwgbWF4OyBpKyspIHtcbiAgICBpZiAoY3VycmVudFtpXSAhPT0gbmV4dFtpXSkge1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBhY3RpdmF0ZWQ6IG5leHQuc2xpY2UoaSksXG4gICAgZGVhY3RpdmF0ZWQ6IGN1cnJlbnQuc2xpY2UoaSlcbiAgfVxufVxuXG5mdW5jdGlvbiBleHRyYWN0TGVhdmVHdWFyZHMgKG1hdGNoZWQpIHtcbiAgcmV0dXJuIGZsYXRNYXBDb21wb25lbnRzKG1hdGNoZWQsIGZ1bmN0aW9uIChkZWYsIGluc3RhbmNlKSB7XG4gICAgdmFyIGd1YXJkID0gZGVmICYmIGRlZi5iZWZvcmVSb3V0ZUxlYXZlXG4gICAgaWYgKGd1YXJkKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gcm91dGVMZWF2ZUd1YXJkICgpIHtcbiAgICAgICAgcmV0dXJuIGd1YXJkLmFwcGx5KGluc3RhbmNlLCBhcmd1bWVudHMpXG4gICAgICB9XG4gICAgfVxuICB9KS5yZXZlcnNlKClcbn1cblxuZnVuY3Rpb24gZXh0cmFjdEVudGVyR3VhcmRzIChcbiAgbWF0Y2hlZCxcbiAgY2JzLFxuICBpc1ZhbGlkXG4pIHtcbiAgcmV0dXJuIGZsYXRNYXBDb21wb25lbnRzKG1hdGNoZWQsIGZ1bmN0aW9uIChkZWYsIF8sIG1hdGNoLCBrZXkpIHtcbiAgICB2YXIgZ3VhcmQgPSBkZWYgJiYgZGVmLmJlZm9yZVJvdXRlRW50ZXJcbiAgICBpZiAoZ3VhcmQpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbiByb3V0ZUVudGVyR3VhcmQgKHRvLCBmcm9tLCBuZXh0KSB7XG4gICAgICAgIHJldHVybiBndWFyZCh0bywgZnJvbSwgZnVuY3Rpb24gKGNiKSB7XG4gICAgICAgICAgbmV4dChjYilcbiAgICAgICAgICBpZiAodHlwZW9mIGNiID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYnMucHVzaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIC8vICM3NTBcbiAgICAgICAgICAgICAgLy8gaWYgYSByb3V0ZXItdmlldyBpcyB3cmFwcGVkIHdpdGggYW4gb3V0LWluIHRyYW5zaXRpb24sXG4gICAgICAgICAgICAgIC8vIHRoZSBpbnN0YW5jZSBtYXkgbm90IGhhdmUgYmVlbiByZWdpc3RlcmVkIGF0IHRoaXMgdGltZS5cbiAgICAgICAgICAgICAgLy8gd2Ugd2lsbCBuZWVkIHRvIHBvbGwgZm9yIHJlZ2lzdHJhdGlvbiB1bnRpbCBjdXJyZW50IHJvdXRlXG4gICAgICAgICAgICAgIC8vIGlzIG5vIGxvbmdlciB2YWxpZC5cbiAgICAgICAgICAgICAgcG9sbChjYiwgbWF0Y2guaW5zdGFuY2VzLCBrZXksIGlzVmFsaWQpXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG4gIH0pXG59XG5cbmZ1bmN0aW9uIHBvbGwgKGNiLCBpbnN0YW5jZXMsIGtleSwgaXNWYWxpZCkge1xuICBpZiAoaW5zdGFuY2VzW2tleV0pIHtcbiAgICBjYihpbnN0YW5jZXNba2V5XSlcbiAgfSBlbHNlIGlmIChpc1ZhbGlkKCkpIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHBvbGwoY2IsIGluc3RhbmNlcywga2V5LCBpc1ZhbGlkKVxuICAgIH0sIDE2KVxuICB9XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVBc3luY0NvbXBvbmVudHMgKG1hdGNoZWQpIHtcbiAgcmV0dXJuIGZsYXRNYXBDb21wb25lbnRzKG1hdGNoZWQsIGZ1bmN0aW9uIChkZWYsIF8sIG1hdGNoLCBrZXkpIHtcbiAgICAvLyBpZiBpdCdzIGEgZnVuY3Rpb24gYW5kIGRvZXNuJ3QgaGF2ZSBWdWUgb3B0aW9ucyBhdHRhY2hlZCxcbiAgICAvLyBhc3N1bWUgaXQncyBhbiBhc3luYyBjb21wb25lbnQgcmVzb2x2ZSBmdW5jdGlvbi5cbiAgICAvLyB3ZSBhcmUgbm90IHVzaW5nIFZ1ZSdzIGRlZmF1bHQgYXN5bmMgcmVzb2x2aW5nIG1lY2hhbmlzbSBiZWNhdXNlXG4gICAgLy8gd2Ugd2FudCB0byBoYWx0IHRoZSBuYXZpZ2F0aW9uIHVudGlsIHRoZSBpbmNvbWluZyBjb21wb25lbnQgaGFzIGJlZW5cbiAgICAvLyByZXNvbHZlZC5cbiAgICBpZiAodHlwZW9mIGRlZiA9PT0gJ2Z1bmN0aW9uJyAmJiAhZGVmLm9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbiAodG8sIGZyb20sIG5leHQpIHtcbiAgICAgICAgdmFyIHJlc29sdmUgPSBmdW5jdGlvbiAocmVzb2x2ZWREZWYpIHtcbiAgICAgICAgICBtYXRjaC5jb21wb25lbnRzW2tleV0gPSByZXNvbHZlZERlZlxuICAgICAgICAgIG5leHQoKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlamVjdCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgICB3YXJuKGZhbHNlLCAoXCJGYWlsZWQgdG8gcmVzb2x2ZSBhc3luYyBjb21wb25lbnQgXCIgKyBrZXkgKyBcIjogXCIgKyByZWFzb24pKVxuICAgICAgICAgIG5leHQoZmFsc2UpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVzID0gZGVmKHJlc29sdmUsIHJlamVjdClcbiAgICAgICAgaWYgKHJlcyAmJiB0eXBlb2YgcmVzLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICByZXMudGhlbihyZXNvbHZlLCByZWplY3QpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pXG59XG5cbmZ1bmN0aW9uIGZsYXRNYXBDb21wb25lbnRzIChcbiAgbWF0Y2hlZCxcbiAgZm5cbikge1xuICByZXR1cm4gQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSwgbWF0Y2hlZC5tYXAoZnVuY3Rpb24gKG0pIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMobS5jb21wb25lbnRzKS5tYXAoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gZm4oXG4gICAgICBtLmNvbXBvbmVudHNba2V5XSxcbiAgICAgIG0uaW5zdGFuY2VzW2tleV0sXG4gICAgICBtLCBrZXlcbiAgICApOyB9KVxuICB9KSlcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIHNhdmVTY3JvbGxQb3NpdGlvbiAoa2V5KSB7XG4gIGlmICgha2V5KSB7IHJldHVybiB9XG4gIHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKGtleSwgSlNPTi5zdHJpbmdpZnkoe1xuICAgIHg6IHdpbmRvdy5wYWdlWE9mZnNldCxcbiAgICB5OiB3aW5kb3cucGFnZVlPZmZzZXRcbiAgfSkpXG59XG5cbmZ1bmN0aW9uIGdldFNjcm9sbFBvc2l0aW9uIChrZXkpIHtcbiAgaWYgKCFrZXkpIHsgcmV0dXJuIH1cbiAgcmV0dXJuIEpTT04ucGFyc2Uod2luZG93LnNlc3Npb25TdG9yYWdlLmdldEl0ZW0oa2V5KSlcbn1cblxuZnVuY3Rpb24gZ2V0RWxlbWVudFBvc2l0aW9uIChlbCkge1xuICB2YXIgZG9jUmVjdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICB2YXIgZWxSZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgcmV0dXJuIHtcbiAgICB4OiBlbFJlY3QubGVmdCAtIGRvY1JlY3QubGVmdCxcbiAgICB5OiBlbFJlY3QudG9wIC0gZG9jUmVjdC50b3BcbiAgfVxufVxuXG5mdW5jdGlvbiBpc1ZhbGlkUG9zaXRpb24gKG9iaikge1xuICByZXR1cm4gaXNOdW1iZXIob2JqLngpIHx8IGlzTnVtYmVyKG9iai55KVxufVxuXG5mdW5jdGlvbiBub3JtYWxpemVQb3NpdGlvbiAob2JqKSB7XG4gIHJldHVybiB7XG4gICAgeDogaXNOdW1iZXIob2JqLngpID8gb2JqLnggOiB3aW5kb3cucGFnZVhPZmZzZXQsXG4gICAgeTogaXNOdW1iZXIob2JqLnkpID8gb2JqLnkgOiB3aW5kb3cucGFnZVlPZmZzZXRcbiAgfVxufVxuXG5mdW5jdGlvbiBpc051bWJlciAodikge1xuICByZXR1cm4gdHlwZW9mIHYgPT09ICdudW1iZXInXG59XG5cbi8qICAqL1xuXG5cbnZhciBnZW5LZXkgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBTdHJpbmcoRGF0ZS5ub3coKSk7IH1cbnZhciBfa2V5ID0gZ2VuS2V5KClcblxudmFyIEhUTUw1SGlzdG9yeSA9IChmdW5jdGlvbiAoSGlzdG9yeSkge1xuICBmdW5jdGlvbiBIVE1MNUhpc3RvcnkgKHJvdXRlciwgYmFzZSkge1xuICAgIHZhciB0aGlzJDEgPSB0aGlzO1xuXG4gICAgSGlzdG9yeS5jYWxsKHRoaXMsIHJvdXRlciwgYmFzZSlcblxuICAgIHRoaXMudHJhbnNpdGlvblRvKGdldExvY2F0aW9uKHRoaXMuYmFzZSkpXG5cbiAgICB2YXIgZXhwZWN0U2Nyb2xsID0gcm91dGVyLm9wdGlvbnMuc2Nyb2xsQmVoYXZpb3JcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncG9wc3RhdGUnLCBmdW5jdGlvbiAoZSkge1xuICAgICAgX2tleSA9IGUuc3RhdGUgJiYgZS5zdGF0ZS5rZXlcbiAgICAgIHZhciBjdXJyZW50ID0gdGhpcyQxLmN1cnJlbnRcbiAgICAgIHRoaXMkMS50cmFuc2l0aW9uVG8oZ2V0TG9jYXRpb24odGhpcyQxLmJhc2UpLCBmdW5jdGlvbiAobmV4dCkge1xuICAgICAgICBpZiAoZXhwZWN0U2Nyb2xsKSB7XG4gICAgICAgICAgdGhpcyQxLmhhbmRsZVNjcm9sbChuZXh0LCBjdXJyZW50LCB0cnVlKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0pXG5cbiAgICBpZiAoZXhwZWN0U2Nyb2xsKSB7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBzYXZlU2Nyb2xsUG9zaXRpb24oX2tleSlcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgaWYgKCBIaXN0b3J5ICkgSFRNTDVIaXN0b3J5Ll9fcHJvdG9fXyA9IEhpc3Rvcnk7XG4gIEhUTUw1SGlzdG9yeS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBIaXN0b3J5ICYmIEhpc3RvcnkucHJvdG90eXBlICk7XG4gIEhUTUw1SGlzdG9yeS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBIVE1MNUhpc3Rvcnk7XG5cbiAgSFRNTDVIaXN0b3J5LnByb3RvdHlwZS5nbyA9IGZ1bmN0aW9uIGdvIChuKSB7XG4gICAgd2luZG93Lmhpc3RvcnkuZ28obilcbiAgfTtcblxuICBIVE1MNUhpc3RvcnkucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiBwdXNoIChsb2NhdGlvbikge1xuICAgIHZhciB0aGlzJDEgPSB0aGlzO1xuXG4gICAgdmFyIGN1cnJlbnQgPSB0aGlzLmN1cnJlbnRcbiAgICB0aGlzLnRyYW5zaXRpb25Ubyhsb2NhdGlvbiwgZnVuY3Rpb24gKHJvdXRlKSB7XG4gICAgICBwdXNoU3RhdGUoY2xlYW5QYXRoKHRoaXMkMS5iYXNlICsgcm91dGUuZnVsbFBhdGgpKVxuICAgICAgdGhpcyQxLmhhbmRsZVNjcm9sbChyb3V0ZSwgY3VycmVudCwgZmFsc2UpXG4gICAgfSlcbiAgfTtcblxuICBIVE1MNUhpc3RvcnkucHJvdG90eXBlLnJlcGxhY2UgPSBmdW5jdGlvbiByZXBsYWNlIChsb2NhdGlvbikge1xuICAgIHZhciB0aGlzJDEgPSB0aGlzO1xuXG4gICAgdmFyIGN1cnJlbnQgPSB0aGlzLmN1cnJlbnRcbiAgICB0aGlzLnRyYW5zaXRpb25Ubyhsb2NhdGlvbiwgZnVuY3Rpb24gKHJvdXRlKSB7XG4gICAgICByZXBsYWNlU3RhdGUoY2xlYW5QYXRoKHRoaXMkMS5iYXNlICsgcm91dGUuZnVsbFBhdGgpKVxuICAgICAgdGhpcyQxLmhhbmRsZVNjcm9sbChyb3V0ZSwgY3VycmVudCwgZmFsc2UpXG4gICAgfSlcbiAgfTtcblxuICBIVE1MNUhpc3RvcnkucHJvdG90eXBlLmVuc3VyZVVSTCA9IGZ1bmN0aW9uIGVuc3VyZVVSTCAoKSB7XG4gICAgaWYgKGdldExvY2F0aW9uKHRoaXMuYmFzZSkgIT09IHRoaXMuY3VycmVudC5mdWxsUGF0aCkge1xuICAgICAgcmVwbGFjZVN0YXRlKGNsZWFuUGF0aCh0aGlzLmJhc2UgKyB0aGlzLmN1cnJlbnQuZnVsbFBhdGgpKVxuICAgIH1cbiAgfTtcblxuICBIVE1MNUhpc3RvcnkucHJvdG90eXBlLmhhbmRsZVNjcm9sbCA9IGZ1bmN0aW9uIGhhbmRsZVNjcm9sbCAodG8sIGZyb20sIGlzUG9wKSB7XG4gICAgdmFyIHJvdXRlciA9IHRoaXMucm91dGVyXG4gICAgaWYgKCFyb3V0ZXIuYXBwKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB2YXIgYmVoYXZpb3IgPSByb3V0ZXIub3B0aW9ucy5zY3JvbGxCZWhhdmlvclxuICAgIGlmICghYmVoYXZpb3IpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBhc3NlcnQodHlwZW9mIGJlaGF2aW9yID09PSAnZnVuY3Rpb24nLCBcInNjcm9sbEJlaGF2aW9yIG11c3QgYmUgYSBmdW5jdGlvblwiKVxuXG4gICAgLy8gd2FpdCB1bnRpbCByZS1yZW5kZXIgZmluaXNoZXMgYmVmb3JlIHNjcm9sbGluZ1xuICAgIHJvdXRlci5hcHAuJG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBwb3NpdGlvbiA9IGdldFNjcm9sbFBvc2l0aW9uKF9rZXkpXG4gICAgICB2YXIgc2hvdWxkU2Nyb2xsID0gYmVoYXZpb3IodG8sIGZyb20sIGlzUG9wID8gcG9zaXRpb24gOiBudWxsKVxuICAgICAgaWYgKCFzaG91bGRTY3JvbGwpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICB2YXIgaXNPYmplY3QgPSB0eXBlb2Ygc2hvdWxkU2Nyb2xsID09PSAnb2JqZWN0J1xuICAgICAgaWYgKGlzT2JqZWN0ICYmIHR5cGVvZiBzaG91bGRTY3JvbGwuc2VsZWN0b3IgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHZhciBlbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2hvdWxkU2Nyb2xsLnNlbGVjdG9yKVxuICAgICAgICBpZiAoZWwpIHtcbiAgICAgICAgICBwb3NpdGlvbiA9IGdldEVsZW1lbnRQb3NpdGlvbihlbClcbiAgICAgICAgfSBlbHNlIGlmIChpc1ZhbGlkUG9zaXRpb24oc2hvdWxkU2Nyb2xsKSkge1xuICAgICAgICAgIHBvc2l0aW9uID0gbm9ybWFsaXplUG9zaXRpb24oc2hvdWxkU2Nyb2xsKVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGlzT2JqZWN0ICYmIGlzVmFsaWRQb3NpdGlvbihzaG91bGRTY3JvbGwpKSB7XG4gICAgICAgIHBvc2l0aW9uID0gbm9ybWFsaXplUG9zaXRpb24oc2hvdWxkU2Nyb2xsKVxuICAgICAgfVxuXG4gICAgICBpZiAocG9zaXRpb24pIHtcbiAgICAgICAgd2luZG93LnNjcm9sbFRvKHBvc2l0aW9uLngsIHBvc2l0aW9uLnkpXG4gICAgICB9XG4gICAgfSlcbiAgfTtcblxuICByZXR1cm4gSFRNTDVIaXN0b3J5O1xufShIaXN0b3J5KSk7XG5cbmZ1bmN0aW9uIGdldExvY2F0aW9uIChiYXNlKSB7XG4gIHZhciBwYXRoID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lXG4gIGlmIChiYXNlICYmIHBhdGguaW5kZXhPZihiYXNlKSA9PT0gMCkge1xuICAgIHBhdGggPSBwYXRoLnNsaWNlKGJhc2UubGVuZ3RoKVxuICB9XG4gIHJldHVybiAocGF0aCB8fCAnLycpICsgd2luZG93LmxvY2F0aW9uLnNlYXJjaCArIHdpbmRvdy5sb2NhdGlvbi5oYXNoXG59XG5cbmZ1bmN0aW9uIHB1c2hTdGF0ZSAodXJsLCByZXBsYWNlKSB7XG4gIC8vIHRyeS4uLmNhdGNoIHRoZSBwdXNoU3RhdGUgY2FsbCB0byBnZXQgYXJvdW5kIFNhZmFyaVxuICAvLyBET00gRXhjZXB0aW9uIDE4IHdoZXJlIGl0IGxpbWl0cyB0byAxMDAgcHVzaFN0YXRlIGNhbGxzXG4gIHZhciBoaXN0b3J5ID0gd2luZG93Lmhpc3RvcnlcbiAgdHJ5IHtcbiAgICBpZiAocmVwbGFjZSkge1xuICAgICAgaGlzdG9yeS5yZXBsYWNlU3RhdGUoeyBrZXk6IF9rZXkgfSwgJycsIHVybClcbiAgICB9IGVsc2Uge1xuICAgICAgX2tleSA9IGdlbktleSgpXG4gICAgICBoaXN0b3J5LnB1c2hTdGF0ZSh7IGtleTogX2tleSB9LCAnJywgdXJsKVxuICAgIH1cbiAgICBzYXZlU2Nyb2xsUG9zaXRpb24oX2tleSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIHdpbmRvdy5sb2NhdGlvbltyZXBsYWNlID8gJ2Fzc2lnbicgOiAncmVwbGFjZSddKHVybClcbiAgfVxufVxuXG5mdW5jdGlvbiByZXBsYWNlU3RhdGUgKHVybCkge1xuICBwdXNoU3RhdGUodXJsLCB0cnVlKVxufVxuXG4vKiAgKi9cblxuXG52YXIgSGFzaEhpc3RvcnkgPSAoZnVuY3Rpb24gKEhpc3RvcnkpIHtcbiAgZnVuY3Rpb24gSGFzaEhpc3RvcnkgKHJvdXRlciwgYmFzZSwgZmFsbGJhY2spIHtcbiAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuICAgIEhpc3RvcnkuY2FsbCh0aGlzLCByb3V0ZXIsIGJhc2UpXG5cbiAgICAvLyBjaGVjayBoaXN0b3J5IGZhbGxiYWNrIGRlZXBsaW5raW5nXG4gICAgaWYgKGZhbGxiYWNrICYmIHRoaXMuY2hlY2tGYWxsYmFjaygpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBlbnN1cmVTbGFzaCgpXG4gICAgdGhpcy50cmFuc2l0aW9uVG8oZ2V0SGFzaCgpLCBmdW5jdGlvbiAoKSB7XG4gICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignaGFzaGNoYW5nZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcyQxLm9uSGFzaENoYW5nZSgpXG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICBpZiAoIEhpc3RvcnkgKSBIYXNoSGlzdG9yeS5fX3Byb3RvX18gPSBIaXN0b3J5O1xuICBIYXNoSGlzdG9yeS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBIaXN0b3J5ICYmIEhpc3RvcnkucHJvdG90eXBlICk7XG4gIEhhc2hIaXN0b3J5LnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IEhhc2hIaXN0b3J5O1xuXG4gIEhhc2hIaXN0b3J5LnByb3RvdHlwZS5jaGVja0ZhbGxiYWNrID0gZnVuY3Rpb24gY2hlY2tGYWxsYmFjayAoKSB7XG4gICAgdmFyIGxvY2F0aW9uID0gZ2V0TG9jYXRpb24odGhpcy5iYXNlKVxuICAgIGlmICghL15cXC8jLy50ZXN0KGxvY2F0aW9uKSkge1xuICAgICAgd2luZG93LmxvY2F0aW9uLnJlcGxhY2UoXG4gICAgICAgIGNsZWFuUGF0aCh0aGlzLmJhc2UgKyAnLyMnICsgbG9jYXRpb24pXG4gICAgICApXG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgfTtcblxuICBIYXNoSGlzdG9yeS5wcm90b3R5cGUub25IYXNoQ2hhbmdlID0gZnVuY3Rpb24gb25IYXNoQ2hhbmdlICgpIHtcbiAgICBpZiAoIWVuc3VyZVNsYXNoKCkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICB0aGlzLnRyYW5zaXRpb25UbyhnZXRIYXNoKCksIGZ1bmN0aW9uIChyb3V0ZSkge1xuICAgICAgcmVwbGFjZUhhc2gocm91dGUuZnVsbFBhdGgpXG4gICAgfSlcbiAgfTtcblxuICBIYXNoSGlzdG9yeS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIHB1c2ggKGxvY2F0aW9uKSB7XG4gICAgdGhpcy50cmFuc2l0aW9uVG8obG9jYXRpb24sIGZ1bmN0aW9uIChyb3V0ZSkge1xuICAgICAgcHVzaEhhc2gocm91dGUuZnVsbFBhdGgpXG4gICAgfSlcbiAgfTtcblxuICBIYXNoSGlzdG9yeS5wcm90b3R5cGUucmVwbGFjZSA9IGZ1bmN0aW9uIHJlcGxhY2UgKGxvY2F0aW9uKSB7XG4gICAgdGhpcy50cmFuc2l0aW9uVG8obG9jYXRpb24sIGZ1bmN0aW9uIChyb3V0ZSkge1xuICAgICAgcmVwbGFjZUhhc2gocm91dGUuZnVsbFBhdGgpXG4gICAgfSlcbiAgfTtcblxuICBIYXNoSGlzdG9yeS5wcm90b3R5cGUuZ28gPSBmdW5jdGlvbiBnbyAobikge1xuICAgIHdpbmRvdy5oaXN0b3J5LmdvKG4pXG4gIH07XG5cbiAgSGFzaEhpc3RvcnkucHJvdG90eXBlLmVuc3VyZVVSTCA9IGZ1bmN0aW9uIGVuc3VyZVVSTCAoKSB7XG4gICAgaWYgKGdldEhhc2goKSAhPT0gdGhpcy5jdXJyZW50LmZ1bGxQYXRoKSB7XG4gICAgICByZXBsYWNlSGFzaCh0aGlzLmN1cnJlbnQuZnVsbFBhdGgpXG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBIYXNoSGlzdG9yeTtcbn0oSGlzdG9yeSkpO1xuXG5mdW5jdGlvbiBlbnN1cmVTbGFzaCAoKSB7XG4gIHZhciBwYXRoID0gZ2V0SGFzaCgpXG4gIGlmIChwYXRoLmNoYXJBdCgwKSA9PT0gJy8nKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuICByZXBsYWNlSGFzaCgnLycgKyBwYXRoKVxuICByZXR1cm4gZmFsc2Vcbn1cblxuZnVuY3Rpb24gZ2V0SGFzaCAoKSB7XG4gIC8vIFdlIGNhbid0IHVzZSB3aW5kb3cubG9jYXRpb24uaGFzaCBoZXJlIGJlY2F1c2UgaXQncyBub3RcbiAgLy8gY29uc2lzdGVudCBhY3Jvc3MgYnJvd3NlcnMgLSBGaXJlZm94IHdpbGwgcHJlLWRlY29kZSBpdCFcbiAgdmFyIGhyZWYgPSB3aW5kb3cubG9jYXRpb24uaHJlZlxuICB2YXIgaW5kZXggPSBocmVmLmluZGV4T2YoJyMnKVxuICByZXR1cm4gaW5kZXggPT09IC0xID8gJycgOiBocmVmLnNsaWNlKGluZGV4ICsgMSlcbn1cblxuZnVuY3Rpb24gcHVzaEhhc2ggKHBhdGgpIHtcbiAgd2luZG93LmxvY2F0aW9uLmhhc2ggPSBwYXRoXG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VIYXNoIChwYXRoKSB7XG4gIHZhciBpID0gd2luZG93LmxvY2F0aW9uLmhyZWYuaW5kZXhPZignIycpXG4gIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKFxuICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNsaWNlKDAsIGkgPj0gMCA/IGkgOiAwKSArICcjJyArIHBhdGhcbiAgKVxufVxuXG4vKiAgKi9cblxuXG52YXIgQWJzdHJhY3RIaXN0b3J5ID0gKGZ1bmN0aW9uIChIaXN0b3J5KSB7XG4gIGZ1bmN0aW9uIEFic3RyYWN0SGlzdG9yeSAocm91dGVyKSB7XG4gICAgSGlzdG9yeS5jYWxsKHRoaXMsIHJvdXRlcilcbiAgICB0aGlzLnN0YWNrID0gW11cbiAgICB0aGlzLmluZGV4ID0gLTFcbiAgfVxuXG4gIGlmICggSGlzdG9yeSApIEFic3RyYWN0SGlzdG9yeS5fX3Byb3RvX18gPSBIaXN0b3J5O1xuICBBYnN0cmFjdEhpc3RvcnkucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZSggSGlzdG9yeSAmJiBIaXN0b3J5LnByb3RvdHlwZSApO1xuICBBYnN0cmFjdEhpc3RvcnkucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQWJzdHJhY3RIaXN0b3J5O1xuXG4gIEFic3RyYWN0SGlzdG9yeS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIHB1c2ggKGxvY2F0aW9uKSB7XG4gICAgdmFyIHRoaXMkMSA9IHRoaXM7XG5cbiAgICB0aGlzLnRyYW5zaXRpb25Ubyhsb2NhdGlvbiwgZnVuY3Rpb24gKHJvdXRlKSB7XG4gICAgICB0aGlzJDEuc3RhY2sgPSB0aGlzJDEuc3RhY2suc2xpY2UoMCwgdGhpcyQxLmluZGV4ICsgMSkuY29uY2F0KHJvdXRlKVxuICAgICAgdGhpcyQxLmluZGV4KytcbiAgICB9KVxuICB9O1xuXG4gIEFic3RyYWN0SGlzdG9yeS5wcm90b3R5cGUucmVwbGFjZSA9IGZ1bmN0aW9uIHJlcGxhY2UgKGxvY2F0aW9uKSB7XG4gICAgdmFyIHRoaXMkMSA9IHRoaXM7XG5cbiAgICB0aGlzLnRyYW5zaXRpb25Ubyhsb2NhdGlvbiwgZnVuY3Rpb24gKHJvdXRlKSB7XG4gICAgICB0aGlzJDEuc3RhY2sgPSB0aGlzJDEuc3RhY2suc2xpY2UoMCwgdGhpcyQxLmluZGV4KS5jb25jYXQocm91dGUpXG4gICAgfSlcbiAgfTtcblxuICBBYnN0cmFjdEhpc3RvcnkucHJvdG90eXBlLmdvID0gZnVuY3Rpb24gZ28gKG4pIHtcbiAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuICAgIHZhciB0YXJnZXRJbmRleCA9IHRoaXMuaW5kZXggKyBuXG4gICAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0aGlzLnN0YWNrLmxlbmd0aCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIHZhciByb3V0ZSA9IHRoaXMuc3RhY2tbdGFyZ2V0SW5kZXhdXG4gICAgdGhpcy5jb25maXJtVHJhbnNpdGlvbihyb3V0ZSwgZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcyQxLmluZGV4ID0gdGFyZ2V0SW5kZXhcbiAgICAgIHRoaXMkMS51cGRhdGVSb3V0ZShyb3V0ZSlcbiAgICB9KVxuICB9O1xuXG4gIEFic3RyYWN0SGlzdG9yeS5wcm90b3R5cGUuZW5zdXJlVVJMID0gZnVuY3Rpb24gZW5zdXJlVVJMICgpIHtcbiAgICAvLyBub29wXG4gIH07XG5cbiAgcmV0dXJuIEFic3RyYWN0SGlzdG9yeTtcbn0oSGlzdG9yeSkpO1xuXG4vKiAgKi9cblxudmFyIFZ1ZVJvdXRlciA9IGZ1bmN0aW9uIFZ1ZVJvdXRlciAob3B0aW9ucykge1xuICBpZiAoIG9wdGlvbnMgPT09IHZvaWQgMCApIG9wdGlvbnMgPSB7fTtcblxuICB0aGlzLmFwcCA9IG51bGxcbiAgdGhpcy5vcHRpb25zID0gb3B0aW9uc1xuICB0aGlzLmJlZm9yZUhvb2tzID0gW11cbiAgdGhpcy5hZnRlckhvb2tzID0gW11cbiAgdGhpcy5tYXRjaCA9IGNyZWF0ZU1hdGNoZXIob3B0aW9ucy5yb3V0ZXMgfHwgW10pXG5cbiAgdmFyIG1vZGUgPSBvcHRpb25zLm1vZGUgfHwgJ2hhc2gnXG4gIHRoaXMuZmFsbGJhY2sgPSBtb2RlID09PSAnaGlzdG9yeScgJiYgIXN1cHBvcnRzSGlzdG9yeVxuICBpZiAodGhpcy5mYWxsYmFjaykge1xuICAgIG1vZGUgPSAnaGFzaCdcbiAgfVxuICBpZiAoIWluQnJvd3Nlcikge1xuICAgIG1vZGUgPSAnYWJzdHJhY3QnXG4gIH1cbiAgdGhpcy5tb2RlID0gbW9kZVxufTtcblxudmFyIHByb3RvdHlwZUFjY2Vzc29ycyA9IHsgY3VycmVudFJvdXRlOiB7fSB9O1xuXG5wcm90b3R5cGVBY2Nlc3NvcnMuY3VycmVudFJvdXRlLmdldCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuaGlzdG9yeSAmJiB0aGlzLmhpc3RvcnkuY3VycmVudFxufTtcblxuVnVlUm91dGVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gaW5pdCAoYXBwIC8qIFZ1ZSBjb21wb25lbnQgaW5zdGFuY2UgKi8pIHtcbiAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuICBhc3NlcnQoXG4gICAgaW5zdGFsbC5pbnN0YWxsZWQsXG4gICAgXCJub3QgaW5zdGFsbGVkLiBNYWtlIHN1cmUgdG8gY2FsbCBgVnVlLnVzZShWdWVSb3V0ZXIpYCBcIiArXG4gICAgXCJiZWZvcmUgY3JlYXRpbmcgcm9vdCBpbnN0YW5jZS5cIlxuICApXG5cbiAgdGhpcy5hcHAgPSBhcHBcblxuICB2YXIgcmVmID0gdGhpcztcbiAgICB2YXIgbW9kZSA9IHJlZi5tb2RlO1xuICAgIHZhciBvcHRpb25zID0gcmVmLm9wdGlvbnM7XG4gICAgdmFyIGZhbGxiYWNrID0gcmVmLmZhbGxiYWNrO1xuICBzd2l0Y2ggKG1vZGUpIHtcbiAgICBjYXNlICdoaXN0b3J5JzpcbiAgICAgIHRoaXMuaGlzdG9yeSA9IG5ldyBIVE1MNUhpc3RvcnkodGhpcywgb3B0aW9ucy5iYXNlKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdoYXNoJzpcbiAgICAgIHRoaXMuaGlzdG9yeSA9IG5ldyBIYXNoSGlzdG9yeSh0aGlzLCBvcHRpb25zLmJhc2UsIGZhbGxiYWNrKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdhYnN0cmFjdCc6XG4gICAgICB0aGlzLmhpc3RvcnkgPSBuZXcgQWJzdHJhY3RIaXN0b3J5KHRoaXMpXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICBhc3NlcnQoZmFsc2UsIChcImludmFsaWQgbW9kZTogXCIgKyBtb2RlKSlcbiAgfVxuXG4gIHRoaXMuaGlzdG9yeS5saXN0ZW4oZnVuY3Rpb24gKHJvdXRlKSB7XG4gICAgdGhpcyQxLmFwcC5fcm91dGUgPSByb3V0ZVxuICB9KVxufTtcblxuVnVlUm91dGVyLnByb3RvdHlwZS5iZWZvcmVFYWNoID0gZnVuY3Rpb24gYmVmb3JlRWFjaCAoZm4pIHtcbiAgdGhpcy5iZWZvcmVIb29rcy5wdXNoKGZuKVxufTtcblxuVnVlUm91dGVyLnByb3RvdHlwZS5hZnRlckVhY2ggPSBmdW5jdGlvbiBhZnRlckVhY2ggKGZuKSB7XG4gIHRoaXMuYWZ0ZXJIb29rcy5wdXNoKGZuKVxufTtcblxuVnVlUm91dGVyLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gcHVzaCAobG9jYXRpb24pIHtcbiAgdGhpcy5oaXN0b3J5LnB1c2gobG9jYXRpb24pXG59O1xuXG5WdWVSb3V0ZXIucHJvdG90eXBlLnJlcGxhY2UgPSBmdW5jdGlvbiByZXBsYWNlIChsb2NhdGlvbikge1xuICB0aGlzLmhpc3RvcnkucmVwbGFjZShsb2NhdGlvbilcbn07XG5cblZ1ZVJvdXRlci5wcm90b3R5cGUuZ28gPSBmdW5jdGlvbiBnbyAobikge1xuICB0aGlzLmhpc3RvcnkuZ28obilcbn07XG5cblZ1ZVJvdXRlci5wcm90b3R5cGUuYmFjayA9IGZ1bmN0aW9uIGJhY2sgKCkge1xuICB0aGlzLmdvKC0xKVxufTtcblxuVnVlUm91dGVyLnByb3RvdHlwZS5mb3J3YXJkID0gZnVuY3Rpb24gZm9yd2FyZCAoKSB7XG4gIHRoaXMuZ28oMSlcbn07XG5cblZ1ZVJvdXRlci5wcm90b3R5cGUuZ2V0TWF0Y2hlZENvbXBvbmVudHMgPSBmdW5jdGlvbiBnZXRNYXRjaGVkQ29tcG9uZW50cyAoKSB7XG4gIGlmICghdGhpcy5jdXJyZW50Um91dGUpIHtcbiAgICByZXR1cm4gW11cbiAgfVxuICByZXR1cm4gW10uY29uY2F0LmFwcGx5KFtdLCB0aGlzLmN1cnJlbnRSb3V0ZS5tYXRjaGVkLm1hcChmdW5jdGlvbiAobSkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhtLmNvbXBvbmVudHMpLm1hcChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICByZXR1cm4gbS5jb21wb25lbnRzW2tleV1cbiAgICB9KVxuICB9KSlcbn07XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKCBWdWVSb3V0ZXIucHJvdG90eXBlLCBwcm90b3R5cGVBY2Nlc3NvcnMgKTtcblxuVnVlUm91dGVyLmluc3RhbGwgPSBpbnN0YWxsXG5cbmlmIChpbkJyb3dzZXIgJiYgd2luZG93LlZ1ZSkge1xuICB3aW5kb3cuVnVlLnVzZShWdWVSb3V0ZXIpXG59XG5cbnJldHVybiBWdWVSb3V0ZXI7XG5cbn0pKSk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Z1ZS1yb3V0ZXIvZGlzdC92dWUtcm91dGVyLmpzXG4vLyBtb2R1bGUgaWQgPSAxMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9");
},function(module,exports,__webpack_require__){"use strict";eval("/* WEBPACK VAR INJECTION */(function(process) {/*!\n * Vue.js v2.0.3\n * (c) 2014-2016 Evan You\n * Released under the MIT License.\n */\n'use strict';\n\n/*  */\n\n/**\n * Convert a value to a string that is actually rendered.\n */\nfunction _toString (val) {\n  return val == null\n    ? ''\n    : typeof val === 'object'\n      ? JSON.stringify(val, null, 2)\n      : String(val)\n}\n\n/**\n * Convert a input value to a number for persistence.\n * If the conversion fails, return original string.\n */\nfunction toNumber (val) {\n  var n = parseFloat(val, 10);\n  return (n || n === 0) ? n : val\n}\n\n/**\n * Make a map and return a function for checking if a key\n * is in that map.\n */\nfunction makeMap (\n  str,\n  expectsLowerCase\n) {\n  var map = Object.create(null);\n  var list = str.split(',');\n  for (var i = 0; i < list.length; i++) {\n    map[list[i]] = true;\n  }\n  return expectsLowerCase\n    ? function (val) { return map[val.toLowerCase()]; }\n    : function (val) { return map[val]; }\n}\n\n/**\n * Check if a tag is a built-in tag.\n */\nvar isBuiltInTag = makeMap('slot,component', true);\n\n/**\n * Remove an item from an array\n */\nfunction remove$1 (arr, item) {\n  if (arr.length) {\n    var index = arr.indexOf(item);\n    if (index > -1) {\n      return arr.splice(index, 1)\n    }\n  }\n}\n\n/**\n * Check whether the object has the property.\n */\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nfunction hasOwn (obj, key) {\n  return hasOwnProperty.call(obj, key)\n}\n\n/**\n * Check if value is primitive\n */\nfunction isPrimitive (value) {\n  return typeof value === 'string' || typeof value === 'number'\n}\n\n/**\n * Create a cached version of a pure function.\n */\nfunction cached (fn) {\n  var cache = Object.create(null);\n  return function cachedFn (str) {\n    var hit = cache[str];\n    return hit || (cache[str] = fn(str))\n  }\n}\n\n/**\n * Camelize a hyphen-delmited string.\n */\nvar camelizeRE = /-(\\w)/g;\nvar camelize = cached(function (str) {\n  return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; })\n});\n\n/**\n * Capitalize a string.\n */\nvar capitalize = cached(function (str) {\n  return str.charAt(0).toUpperCase() + str.slice(1)\n});\n\n/**\n * Hyphenate a camelCase string.\n */\nvar hyphenateRE = /([^-])([A-Z])/g;\nvar hyphenate = cached(function (str) {\n  return str\n    .replace(hyphenateRE, '$1-$2')\n    .replace(hyphenateRE, '$1-$2')\n    .toLowerCase()\n});\n\n/**\n * Simple bind, faster than native\n */\nfunction bind$1 (fn, ctx) {\n  function boundFn (a) {\n    var l = arguments.length;\n    return l\n      ? l > 1\n        ? fn.apply(ctx, arguments)\n        : fn.call(ctx, a)\n      : fn.call(ctx)\n  }\n  // record original fn length\n  boundFn._length = fn.length;\n  return boundFn\n}\n\n/**\n * Convert an Array-like object to a real Array.\n */\nfunction toArray (list, start) {\n  start = start || 0;\n  var i = list.length - start;\n  var ret = new Array(i);\n  while (i--) {\n    ret[i] = list[i + start];\n  }\n  return ret\n}\n\n/**\n * Mix properties into target object.\n */\nfunction extend (to, _from) {\n  for (var key in _from) {\n    to[key] = _from[key];\n  }\n  return to\n}\n\n/**\n * Quick object check - this is primarily used to tell\n * Objects from primitive values when we know the value\n * is a JSON-compliant type.\n */\nfunction isObject (obj) {\n  return obj !== null && typeof obj === 'object'\n}\n\n/**\n * Strict object type check. Only returns true\n * for plain JavaScript objects.\n */\nvar toString = Object.prototype.toString;\nvar OBJECT_STRING = '[object Object]';\nfunction isPlainObject (obj) {\n  return toString.call(obj) === OBJECT_STRING\n}\n\n/**\n * Merge an Array of Objects into a single Object.\n */\nfunction toObject (arr) {\n  var res = {};\n  for (var i = 0; i < arr.length; i++) {\n    if (arr[i]) {\n      extend(res, arr[i]);\n    }\n  }\n  return res\n}\n\n/**\n * Perform no operation.\n */\nfunction noop () {}\n\n/**\n * Always return false.\n */\nvar no = function () { return false; };\n\n/**\n * Generate a static keys string from compiler modules.\n */\nfunction genStaticKeys (modules) {\n  return modules.reduce(function (keys, m) {\n    return keys.concat(m.staticKeys || [])\n  }, []).join(',')\n}\n\n/**\n * Check if two values are loosely equal - that is,\n * if they are plain objects, do they have the same shape?\n */\nfunction looseEqual (a, b) {\n  /* eslint-disable eqeqeq */\n  return a == b || (\n    isObject(a) && isObject(b)\n      ? JSON.stringify(a) === JSON.stringify(b)\n      : false\n  )\n  /* eslint-enable eqeqeq */\n}\n\nfunction looseIndexOf (arr, val) {\n  for (var i = 0; i < arr.length; i++) {\n    if (looseEqual(arr[i], val)) { return i }\n  }\n  return -1\n}\n\n/*  */\n\nvar config = {\n  /**\n   * Option merge strategies (used in core/util/options)\n   */\n  optionMergeStrategies: Object.create(null),\n\n  /**\n   * Whether to suppress warnings.\n   */\n  silent: false,\n\n  /**\n   * Whether to enable devtools\n   */\n  devtools: process.env.NODE_ENV !== 'production',\n\n  /**\n   * Error handler for watcher errors\n   */\n  errorHandler: null,\n\n  /**\n   * Ignore certain custom elements\n   */\n  ignoredElements: null,\n\n  /**\n   * Custom user key aliases for v-on\n   */\n  keyCodes: Object.create(null),\n\n  /**\n   * Check if a tag is reserved so that it cannot be registered as a\n   * component. This is platform-dependent and may be overwritten.\n   */\n  isReservedTag: no,\n\n  /**\n   * Check if a tag is an unknown element.\n   * Platform-dependent.\n   */\n  isUnknownElement: no,\n\n  /**\n   * Get the namespace of an element\n   */\n  getTagNamespace: noop,\n\n  /**\n   * Check if an attribute must be bound using property, e.g. value\n   * Platform-dependent.\n   */\n  mustUseProp: no,\n\n  /**\n   * List of asset types that a component can own.\n   */\n  _assetTypes: [\n    'component',\n    'directive',\n    'filter'\n  ],\n\n  /**\n   * List of lifecycle hooks.\n   */\n  _lifecycleHooks: [\n    'beforeCreate',\n    'created',\n    'beforeMount',\n    'mounted',\n    'beforeUpdate',\n    'updated',\n    'beforeDestroy',\n    'destroyed',\n    'activated',\n    'deactivated'\n  ],\n\n  /**\n   * Max circular updates allowed in a scheduler flush cycle.\n   */\n  _maxUpdateCount: 100,\n\n  /**\n   * Server rendering?\n   */\n  _isServer: process.env.VUE_ENV === 'server'\n};\n\n/*  */\n\n/**\n * Check if a string starts with $ or _\n */\nfunction isReserved (str) {\n  var c = (str + '').charCodeAt(0);\n  return c === 0x24 || c === 0x5F\n}\n\n/**\n * Define a property.\n */\nfunction def (obj, key, val, enumerable) {\n  Object.defineProperty(obj, key, {\n    value: val,\n    enumerable: !!enumerable,\n    writable: true,\n    configurable: true\n  });\n}\n\n/**\n * Parse simple path.\n */\nvar bailRE = /[^\\w\\.\\$]/;\nfunction parsePath (path) {\n  if (bailRE.test(path)) {\n    return\n  } else {\n    var segments = path.split('.');\n    return function (obj) {\n      for (var i = 0; i < segments.length; i++) {\n        if (!obj) { return }\n        obj = obj[segments[i]];\n      }\n      return obj\n    }\n  }\n}\n\n/*  */\n/* globals MutationObserver */\n\n// can we use __proto__?\nvar hasProto = '__proto__' in {};\n\n// Browser environment sniffing\nvar inBrowser =\n  typeof window !== 'undefined' &&\n  Object.prototype.toString.call(window) !== '[object Object]';\n\nvar UA = inBrowser && window.navigator.userAgent.toLowerCase();\nvar isIE = UA && /msie|trident/.test(UA);\nvar isIE9 = UA && UA.indexOf('msie 9.0') > 0;\nvar isEdge = UA && UA.indexOf('edge/') > 0;\nvar isAndroid = UA && UA.indexOf('android') > 0;\nvar isIOS = UA && /iphone|ipad|ipod|ios/.test(UA);\n\n// detect devtools\nvar devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;\n\n/* istanbul ignore next */\nfunction isNative (Ctor) {\n  return /native code/.test(Ctor.toString())\n}\n\n/**\n * Defer a task to execute it asynchronously.\n */\nvar nextTick = (function () {\n  var callbacks = [];\n  var pending = false;\n  var timerFunc;\n\n  function nextTickHandler () {\n    pending = false;\n    var copies = callbacks.slice(0);\n    callbacks.length = 0;\n    for (var i = 0; i < copies.length; i++) {\n      copies[i]();\n    }\n  }\n\n  // the nextTick behavior leverages the microtask queue, which can be accessed\n  // via either native Promise.then or MutationObserver.\n  // MutationObserver has wider support, however it is seriously bugged in\n  // UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It\n  // completely stops working after triggering a few times... so, if native\n  // Promise is available, we will use it:\n  /* istanbul ignore if */\n  if (typeof Promise !== 'undefined' && isNative(Promise)) {\n    var p = Promise.resolve();\n    timerFunc = function () {\n      p.then(nextTickHandler);\n      // in problematic UIWebViews, Promise.then doesn't completely break, but\n      // it can get stuck in a weird state where callbacks are pushed into the\n      // microtask queue but the queue isn't being flushed, until the browser\n      // needs to do some other work, e.g. handle a timer. Therefore we can\n      // \"force\" the microtask queue to be flushed by adding an empty timer.\n      if (isIOS) { setTimeout(noop); }\n    };\n  } else if (typeof MutationObserver !== 'undefined' && (\n    isNative(MutationObserver) ||\n    // PhantomJS and iOS 7.x\n    MutationObserver.toString() === '[object MutationObserverConstructor]'\n  )) {\n    // use MutationObserver where native Promise is not available,\n    // e.g. PhantomJS IE11, iOS7, Android 4.4\n    var counter = 1;\n    var observer = new MutationObserver(nextTickHandler);\n    var textNode = document.createTextNode(String(counter));\n    observer.observe(textNode, {\n      characterData: true\n    });\n    timerFunc = function () {\n      counter = (counter + 1) % 2;\n      textNode.data = String(counter);\n    };\n  } else {\n    // fallback to setTimeout\n    /* istanbul ignore next */\n    timerFunc = function () {\n      setTimeout(nextTickHandler, 0);\n    };\n  }\n\n  return function queueNextTick (cb, ctx) {\n    var func = ctx\n      ? function () { cb.call(ctx); }\n      : cb;\n    callbacks.push(func);\n    if (!pending) {\n      pending = true;\n      timerFunc();\n    }\n  }\n})();\n\nvar _Set;\n/* istanbul ignore if */\nif (typeof Set !== 'undefined' && isNative(Set)) {\n  // use native Set when available.\n  _Set = Set;\n} else {\n  // a non-standard Set polyfill that only works with primitive keys.\n  _Set = (function () {\n    function Set () {\n      this.set = Object.create(null);\n    }\n    Set.prototype.has = function has (key) {\n      return this.set[key] !== undefined\n    };\n    Set.prototype.add = function add (key) {\n      this.set[key] = 1;\n    };\n    Set.prototype.clear = function clear () {\n      this.set = Object.create(null);\n    };\n\n    return Set;\n  }());\n}\n\n/* not type checking this file because flow doesn't play well with Proxy */\n\nvar hasProxy;\nvar proxyHandlers;\nvar initProxy;\n\nif (process.env.NODE_ENV !== 'production') {\n  var allowedGlobals = makeMap(\n    'Infinity,undefined,NaN,isFinite,isNaN,' +\n    'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +\n    'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +\n    'require' // for Webpack/Browserify\n  );\n\n  hasProxy =\n    typeof Proxy !== 'undefined' &&\n    Proxy.toString().match(/native code/);\n\n  proxyHandlers = {\n    has: function has (target, key) {\n      var has = key in target;\n      var isAllowed = allowedGlobals(key) || key.charAt(0) === '_';\n      if (!has && !isAllowed) {\n        warn(\n          \"Property or method \\\"\" + key + \"\\\" is not defined on the instance but \" +\n          \"referenced during render. Make sure to declare reactive data \" +\n          \"properties in the data option.\",\n          target\n        );\n      }\n      return has || !isAllowed\n    }\n  };\n\n  initProxy = function initProxy (vm) {\n    if (hasProxy) {\n      vm._renderProxy = new Proxy(vm, proxyHandlers);\n    } else {\n      vm._renderProxy = vm;\n    }\n  };\n}\n\n/*  */\n\n\nvar uid$2 = 0;\n\n/**\n * A dep is an observable that can have multiple\n * directives subscribing to it.\n */\nvar Dep = function Dep () {\n  this.id = uid$2++;\n  this.subs = [];\n};\n\nDep.prototype.addSub = function addSub (sub) {\n  this.subs.push(sub);\n};\n\nDep.prototype.removeSub = function removeSub (sub) {\n  remove$1(this.subs, sub);\n};\n\nDep.prototype.depend = function depend () {\n  if (Dep.target) {\n    Dep.target.addDep(this);\n  }\n};\n\nDep.prototype.notify = function notify () {\n  // stablize the subscriber list first\n  var subs = this.subs.slice();\n  for (var i = 0, l = subs.length; i < l; i++) {\n    subs[i].update();\n  }\n};\n\n// the current target watcher being evaluated.\n// this is globally unique because there could be only one\n// watcher being evaluated at any time.\nDep.target = null;\nvar targetStack = [];\n\nfunction pushTarget (_target) {\n  if (Dep.target) { targetStack.push(Dep.target); }\n  Dep.target = _target;\n}\n\nfunction popTarget () {\n  Dep.target = targetStack.pop();\n}\n\n/*  */\n\n\nvar queue = [];\nvar has$1 = {};\nvar circular = {};\nvar waiting = false;\nvar flushing = false;\nvar index = 0;\n\n/**\n * Reset the scheduler's state.\n */\nfunction resetSchedulerState () {\n  queue.length = 0;\n  has$1 = {};\n  if (process.env.NODE_ENV !== 'production') {\n    circular = {};\n  }\n  waiting = flushing = false;\n}\n\n/**\n * Flush both queues and run the watchers.\n */\nfunction flushSchedulerQueue () {\n  flushing = true;\n\n  // Sort queue before flush.\n  // This ensures that:\n  // 1. Components are updated from parent to child. (because parent is always\n  //    created before the child)\n  // 2. A component's user watchers are run before its render watcher (because\n  //    user watchers are created before the render watcher)\n  // 3. If a component is destroyed during a parent component's watcher run,\n  //    its watchers can be skipped.\n  queue.sort(function (a, b) { return a.id - b.id; });\n\n  // do not cache length because more watchers might be pushed\n  // as we run existing watchers\n  for (index = 0; index < queue.length; index++) {\n    var watcher = queue[index];\n    var id = watcher.id;\n    has$1[id] = null;\n    watcher.run();\n    // in dev build, check and stop circular updates.\n    if (process.env.NODE_ENV !== 'production' && has$1[id] != null) {\n      circular[id] = (circular[id] || 0) + 1;\n      if (circular[id] > config._maxUpdateCount) {\n        warn(\n          'You may have an infinite update loop ' + (\n            watcher.user\n              ? (\"in watcher with expression \\\"\" + (watcher.expression) + \"\\\"\")\n              : \"in a component render function.\"\n          ),\n          watcher.vm\n        );\n        break\n      }\n    }\n  }\n\n  // devtool hook\n  /* istanbul ignore if */\n  if (devtools && config.devtools) {\n    devtools.emit('flush');\n  }\n\n  resetSchedulerState();\n}\n\n/**\n * Push a watcher into the watcher queue.\n * Jobs with duplicate IDs will be skipped unless it's\n * pushed when the queue is being flushed.\n */\nfunction queueWatcher (watcher) {\n  var id = watcher.id;\n  if (has$1[id] == null) {\n    has$1[id] = true;\n    if (!flushing) {\n      queue.push(watcher);\n    } else {\n      // if already flushing, splice the watcher based on its id\n      // if already past its id, it will be run next immediately.\n      var i = queue.length - 1;\n      while (i >= 0 && queue[i].id > watcher.id) {\n        i--;\n      }\n      queue.splice(Math.max(i, index) + 1, 0, watcher);\n    }\n    // queue the flush\n    if (!waiting) {\n      waiting = true;\n      nextTick(flushSchedulerQueue);\n    }\n  }\n}\n\n/*  */\n\nvar uid$1 = 0;\n\n/**\n * A watcher parses an expression, collects dependencies,\n * and fires callback when the expression value changes.\n * This is used for both the $watch() api and directives.\n */\nvar Watcher = function Watcher (\n  vm,\n  expOrFn,\n  cb,\n  options\n) {\n  if ( options === void 0 ) options = {};\n\n  this.vm = vm;\n  vm._watchers.push(this);\n  // options\n  this.deep = !!options.deep;\n  this.user = !!options.user;\n  this.lazy = !!options.lazy;\n  this.sync = !!options.sync;\n  this.expression = expOrFn.toString();\n  this.cb = cb;\n  this.id = ++uid$1; // uid for batching\n  this.active = true;\n  this.dirty = this.lazy; // for lazy watchers\n  this.deps = [];\n  this.newDeps = [];\n  this.depIds = new _Set();\n  this.newDepIds = new _Set();\n  // parse expression for getter\n  if (typeof expOrFn === 'function') {\n    this.getter = expOrFn;\n  } else {\n    this.getter = parsePath(expOrFn);\n    if (!this.getter) {\n      this.getter = function () {};\n      process.env.NODE_ENV !== 'production' && warn(\n        \"Failed watching path: \\\"\" + expOrFn + \"\\\" \" +\n        'Watcher only accepts simple dot-delimited paths. ' +\n        'For full control, use a function instead.',\n        vm\n      );\n    }\n  }\n  this.value = this.lazy\n    ? undefined\n    : this.get();\n};\n\n/**\n * Evaluate the getter, and re-collect dependencies.\n */\nWatcher.prototype.get = function get () {\n  pushTarget(this);\n  var value = this.getter.call(this.vm, this.vm);\n  // \"touch\" every property so they are all tracked as\n  // dependencies for deep watching\n  if (this.deep) {\n    traverse(value);\n  }\n  popTarget();\n  this.cleanupDeps();\n  return value\n};\n\n/**\n * Add a dependency to this directive.\n */\nWatcher.prototype.addDep = function addDep (dep) {\n  var id = dep.id;\n  if (!this.newDepIds.has(id)) {\n    this.newDepIds.add(id);\n    this.newDeps.push(dep);\n    if (!this.depIds.has(id)) {\n      dep.addSub(this);\n    }\n  }\n};\n\n/**\n * Clean up for dependency collection.\n */\nWatcher.prototype.cleanupDeps = function cleanupDeps () {\n    var this$1 = this;\n\n  var i = this.deps.length;\n  while (i--) {\n    var dep = this$1.deps[i];\n    if (!this$1.newDepIds.has(dep.id)) {\n      dep.removeSub(this$1);\n    }\n  }\n  var tmp = this.depIds;\n  this.depIds = this.newDepIds;\n  this.newDepIds = tmp;\n  this.newDepIds.clear();\n  tmp = this.deps;\n  this.deps = this.newDeps;\n  this.newDeps = tmp;\n  this.newDeps.length = 0;\n};\n\n/**\n * Subscriber interface.\n * Will be called when a dependency changes.\n */\nWatcher.prototype.update = function update () {\n  /* istanbul ignore else */\n  if (this.lazy) {\n    this.dirty = true;\n  } else if (this.sync) {\n    this.run();\n  } else {\n    queueWatcher(this);\n  }\n};\n\n/**\n * Scheduler job interface.\n * Will be called by the scheduler.\n */\nWatcher.prototype.run = function run () {\n  if (this.active) {\n    var value = this.get();\n      if (\n        value !== this.value ||\n      // Deep watchers and watchers on Object/Arrays should fire even\n      // when the value is the same, because the value may\n      // have mutated.\n      isObject(value) ||\n      this.deep\n    ) {\n      // set new value\n      var oldValue = this.value;\n      this.value = value;\n      if (this.user) {\n        try {\n          this.cb.call(this.vm, value, oldValue);\n        } catch (e) {\n          process.env.NODE_ENV !== 'production' && warn(\n            (\"Error in watcher \\\"\" + (this.expression) + \"\\\"\"),\n            this.vm\n          );\n          /* istanbul ignore else */\n          if (config.errorHandler) {\n            config.errorHandler.call(null, e, this.vm);\n          } else {\n            throw e\n          }\n        }\n      } else {\n        this.cb.call(this.vm, value, oldValue);\n      }\n    }\n  }\n};\n\n/**\n * Evaluate the value of the watcher.\n * This only gets called for lazy watchers.\n */\nWatcher.prototype.evaluate = function evaluate () {\n  this.value = this.get();\n  this.dirty = false;\n};\n\n/**\n * Depend on all deps collected by this watcher.\n */\nWatcher.prototype.depend = function depend () {\n    var this$1 = this;\n\n  var i = this.deps.length;\n  while (i--) {\n    this$1.deps[i].depend();\n  }\n};\n\n/**\n * Remove self from all dependencies' subcriber list.\n */\nWatcher.prototype.teardown = function teardown () {\n    var this$1 = this;\n\n  if (this.active) {\n    // remove self from vm's watcher list\n    // this is a somewhat expensive operation so we skip it\n    // if the vm is being destroyed or is performing a v-for\n    // re-render (the watcher list is then filtered by v-for).\n    if (!this.vm._isBeingDestroyed && !this.vm._vForRemoving) {\n      remove$1(this.vm._watchers, this);\n    }\n    var i = this.deps.length;\n    while (i--) {\n      this$1.deps[i].removeSub(this$1);\n    }\n    this.active = false;\n  }\n};\n\n/**\n * Recursively traverse an object to evoke all converted\n * getters, so that every nested property inside the object\n * is collected as a \"deep\" dependency.\n */\nvar seenObjects = new _Set();\nfunction traverse (val, seen) {\n  var i, keys;\n  if (!seen) {\n    seen = seenObjects;\n    seen.clear();\n  }\n  var isA = Array.isArray(val);\n  var isO = isObject(val);\n  if ((isA || isO) && Object.isExtensible(val)) {\n    if (val.__ob__) {\n      var depId = val.__ob__.dep.id;\n      if (seen.has(depId)) {\n        return\n      } else {\n        seen.add(depId);\n      }\n    }\n    if (isA) {\n      i = val.length;\n      while (i--) { traverse(val[i], seen); }\n    } else if (isO) {\n      keys = Object.keys(val);\n      i = keys.length;\n      while (i--) { traverse(val[keys[i]], seen); }\n    }\n  }\n}\n\n/*\n * not type checking this file because flow doesn't play well with\n * dynamically accessing methods on Array prototype\n */\n\nvar arrayProto = Array.prototype;\nvar arrayMethods = Object.create(arrayProto);[\n  'push',\n  'pop',\n  'shift',\n  'unshift',\n  'splice',\n  'sort',\n  'reverse'\n]\n.forEach(function (method) {\n  // cache original method\n  var original = arrayProto[method];\n  def(arrayMethods, method, function mutator () {\n    var arguments$1 = arguments;\n\n    // avoid leaking arguments:\n    // http://jsperf.com/closure-with-arguments\n    var i = arguments.length;\n    var args = new Array(i);\n    while (i--) {\n      args[i] = arguments$1[i];\n    }\n    var result = original.apply(this, args);\n    var ob = this.__ob__;\n    var inserted;\n    switch (method) {\n      case 'push':\n        inserted = args;\n        break\n      case 'unshift':\n        inserted = args;\n        break\n      case 'splice':\n        inserted = args.slice(2);\n        break\n    }\n    if (inserted) { ob.observeArray(inserted); }\n    // notify change\n    ob.dep.notify();\n    return result\n  });\n});\n\n/*  */\n\nvar arrayKeys = Object.getOwnPropertyNames(arrayMethods);\n\n/**\n * By default, when a reactive property is set, the new value is\n * also converted to become reactive. However when passing down props,\n * we don't want to force conversion because the value may be a nested value\n * under a frozen data structure. Converting it would defeat the optimization.\n */\nvar observerState = {\n  shouldConvert: true,\n  isSettingProps: false\n};\n\n/**\n * Observer class that are attached to each observed\n * object. Once attached, the observer converts target\n * object's property keys into getter/setters that\n * collect dependencies and dispatches updates.\n */\nvar Observer = function Observer (value) {\n  this.value = value;\n  this.dep = new Dep();\n  this.vmCount = 0;\n  def(value, '__ob__', this);\n  if (Array.isArray(value)) {\n    var augment = hasProto\n      ? protoAugment\n      : copyAugment;\n    augment(value, arrayMethods, arrayKeys);\n    this.observeArray(value);\n  } else {\n    this.walk(value);\n  }\n};\n\n/**\n * Walk through each property and convert them into\n * getter/setters. This method should only be called when\n * value type is Object.\n */\nObserver.prototype.walk = function walk (obj) {\n  var keys = Object.keys(obj);\n  for (var i = 0; i < keys.length; i++) {\n    defineReactive$$1(obj, keys[i], obj[keys[i]]);\n  }\n};\n\n/**\n * Observe a list of Array items.\n */\nObserver.prototype.observeArray = function observeArray (items) {\n  for (var i = 0, l = items.length; i < l; i++) {\n    observe(items[i]);\n  }\n};\n\n// helpers\n\n/**\n * Augment an target Object or Array by intercepting\n * the prototype chain using __proto__\n */\nfunction protoAugment (target, src) {\n  /* eslint-disable no-proto */\n  target.__proto__ = src;\n  /* eslint-enable no-proto */\n}\n\n/**\n * Augment an target Object or Array by defining\n * hidden properties.\n *\n * istanbul ignore next\n */\nfunction copyAugment (target, src, keys) {\n  for (var i = 0, l = keys.length; i < l; i++) {\n    var key = keys[i];\n    def(target, key, src[key]);\n  }\n}\n\n/**\n * Attempt to create an observer instance for a value,\n * returns the new observer if successfully observed,\n * or the existing observer if the value already has one.\n */\nfunction observe (value) {\n  if (!isObject(value)) {\n    return\n  }\n  var ob;\n  if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {\n    ob = value.__ob__;\n  } else if (\n    observerState.shouldConvert &&\n    !config._isServer &&\n    (Array.isArray(value) || isPlainObject(value)) &&\n    Object.isExtensible(value) &&\n    !value._isVue\n  ) {\n    ob = new Observer(value);\n  }\n  return ob\n}\n\n/**\n * Define a reactive property on an Object.\n */\nfunction defineReactive$$1 (\n  obj,\n  key,\n  val,\n  customSetter\n) {\n  var dep = new Dep();\n\n  var property = Object.getOwnPropertyDescriptor(obj, key);\n  if (property && property.configurable === false) {\n    return\n  }\n\n  // cater for pre-defined getter/setters\n  var getter = property && property.get;\n  var setter = property && property.set;\n\n  var childOb = observe(val);\n  Object.defineProperty(obj, key, {\n    enumerable: true,\n    configurable: true,\n    get: function reactiveGetter () {\n      var value = getter ? getter.call(obj) : val;\n      if (Dep.target) {\n        dep.depend();\n        if (childOb) {\n          childOb.dep.depend();\n        }\n        if (Array.isArray(value)) {\n          dependArray(value);\n        }\n      }\n      return value\n    },\n    set: function reactiveSetter (newVal) {\n      var value = getter ? getter.call(obj) : val;\n      if (newVal === value) {\n        return\n      }\n      if (process.env.NODE_ENV !== 'production' && customSetter) {\n        customSetter();\n      }\n      if (setter) {\n        setter.call(obj, newVal);\n      } else {\n        val = newVal;\n      }\n      childOb = observe(newVal);\n      dep.notify();\n    }\n  });\n}\n\n/**\n * Set a property on an object. Adds the new property and\n * triggers change notification if the property doesn't\n * already exist.\n */\nfunction set (obj, key, val) {\n  if (Array.isArray(obj)) {\n    obj.splice(key, 1, val);\n    return val\n  }\n  if (hasOwn(obj, key)) {\n    obj[key] = val;\n    return\n  }\n  var ob = obj.__ob__;\n  if (obj._isVue || (ob && ob.vmCount)) {\n    process.env.NODE_ENV !== 'production' && warn(\n      'Avoid adding reactive properties to a Vue instance or its root $data ' +\n      'at runtime - declare it upfront in the data option.'\n    );\n    return\n  }\n  if (!ob) {\n    obj[key] = val;\n    return\n  }\n  defineReactive$$1(ob.value, key, val);\n  ob.dep.notify();\n  return val\n}\n\n/**\n * Delete a property and trigger change if necessary.\n */\nfunction del (obj, key) {\n  var ob = obj.__ob__;\n  if (obj._isVue || (ob && ob.vmCount)) {\n    process.env.NODE_ENV !== 'production' && warn(\n      'Avoid deleting properties on a Vue instance or its root $data ' +\n      '- just set it to null.'\n    );\n    return\n  }\n  if (!hasOwn(obj, key)) {\n    return\n  }\n  delete obj[key];\n  if (!ob) {\n    return\n  }\n  ob.dep.notify();\n}\n\n/**\n * Collect dependencies on array elements when the array is touched, since\n * we cannot intercept array element access like property getters.\n */\nfunction dependArray (value) {\n  for (var e = void 0, i = 0, l = value.length; i < l; i++) {\n    e = value[i];\n    e && e.__ob__ && e.__ob__.dep.depend();\n    if (Array.isArray(e)) {\n      dependArray(e);\n    }\n  }\n}\n\n/*  */\n\nfunction initState (vm) {\n  vm._watchers = [];\n  initProps(vm);\n  initData(vm);\n  initComputed(vm);\n  initMethods(vm);\n  initWatch(vm);\n}\n\nfunction initProps (vm) {\n  var props = vm.$options.props;\n  if (props) {\n    var propsData = vm.$options.propsData || {};\n    var keys = vm.$options._propKeys = Object.keys(props);\n    var isRoot = !vm.$parent;\n    // root instance props should be converted\n    observerState.shouldConvert = isRoot;\n    var loop = function ( i ) {\n      var key = keys[i];\n      /* istanbul ignore else */\n      if (process.env.NODE_ENV !== 'production') {\n        defineReactive$$1(vm, key, validateProp(key, props, propsData, vm), function () {\n          if (vm.$parent && !observerState.isSettingProps) {\n            warn(\n              \"Avoid mutating a prop directly since the value will be \" +\n              \"overwritten whenever the parent component re-renders. \" +\n              \"Instead, use a data or computed property based on the prop's \" +\n              \"value. Prop being mutated: \\\"\" + key + \"\\\"\",\n              vm\n            );\n          }\n        });\n      } else {\n        defineReactive$$1(vm, key, validateProp(key, props, propsData, vm));\n      }\n    };\n\n    for (var i = 0; i < keys.length; i++) loop( i );\n    observerState.shouldConvert = true;\n  }\n}\n\nfunction initData (vm) {\n  var data = vm.$options.data;\n  data = vm._data = typeof data === 'function'\n    ? data.call(vm)\n    : data || {};\n  if (!isPlainObject(data)) {\n    data = {};\n    process.env.NODE_ENV !== 'production' && warn(\n      'data functions should return an object.',\n      vm\n    );\n  }\n  // proxy data on instance\n  var keys = Object.keys(data);\n  var props = vm.$options.props;\n  var i = keys.length;\n  while (i--) {\n    if (props && hasOwn(props, keys[i])) {\n      process.env.NODE_ENV !== 'production' && warn(\n        \"The data property \\\"\" + (keys[i]) + \"\\\" is already declared as a prop. \" +\n        \"Use prop default value instead.\",\n        vm\n      );\n    } else {\n      proxy(vm, keys[i]);\n    }\n  }\n  // observe data\n  observe(data);\n  data.__ob__ && data.__ob__.vmCount++;\n}\n\nvar computedSharedDefinition = {\n  enumerable: true,\n  configurable: true,\n  get: noop,\n  set: noop\n};\n\nfunction initComputed (vm) {\n  var computed = vm.$options.computed;\n  if (computed) {\n    for (var key in computed) {\n      var userDef = computed[key];\n      if (typeof userDef === 'function') {\n        computedSharedDefinition.get = makeComputedGetter(userDef, vm);\n        computedSharedDefinition.set = noop;\n      } else {\n        computedSharedDefinition.get = userDef.get\n          ? userDef.cache !== false\n            ? makeComputedGetter(userDef.get, vm)\n            : bind$1(userDef.get, vm)\n          : noop;\n        computedSharedDefinition.set = userDef.set\n          ? bind$1(userDef.set, vm)\n          : noop;\n      }\n      Object.defineProperty(vm, key, computedSharedDefinition);\n    }\n  }\n}\n\nfunction makeComputedGetter (getter, owner) {\n  var watcher = new Watcher(owner, getter, noop, {\n    lazy: true\n  });\n  return function computedGetter () {\n    if (watcher.dirty) {\n      watcher.evaluate();\n    }\n    if (Dep.target) {\n      watcher.depend();\n    }\n    return watcher.value\n  }\n}\n\nfunction initMethods (vm) {\n  var methods = vm.$options.methods;\n  if (methods) {\n    for (var key in methods) {\n      vm[key] = methods[key] == null ? noop : bind$1(methods[key], vm);\n      if (process.env.NODE_ENV !== 'production' && methods[key] == null) {\n        warn(\n          \"method \\\"\" + key + \"\\\" has an undefined value in the component definition. \" +\n          \"Did you reference the function correctly?\",\n          vm\n        );\n      }\n    }\n  }\n}\n\nfunction initWatch (vm) {\n  var watch = vm.$options.watch;\n  if (watch) {\n    for (var key in watch) {\n      var handler = watch[key];\n      if (Array.isArray(handler)) {\n        for (var i = 0; i < handler.length; i++) {\n          createWatcher(vm, key, handler[i]);\n        }\n      } else {\n        createWatcher(vm, key, handler);\n      }\n    }\n  }\n}\n\nfunction createWatcher (vm, key, handler) {\n  var options;\n  if (isPlainObject(handler)) {\n    options = handler;\n    handler = handler.handler;\n  }\n  if (typeof handler === 'string') {\n    handler = vm[handler];\n  }\n  vm.$watch(key, handler, options);\n}\n\nfunction stateMixin (Vue) {\n  // flow somehow has problems with directly declared definition object\n  // when using Object.defineProperty, so we have to procedurally build up\n  // the object here.\n  var dataDef = {};\n  dataDef.get = function () {\n    return this._data\n  };\n  if (process.env.NODE_ENV !== 'production') {\n    dataDef.set = function (newData) {\n      warn(\n        'Avoid replacing instance root $data. ' +\n        'Use nested data properties instead.',\n        this\n      );\n    };\n  }\n  Object.defineProperty(Vue.prototype, '$data', dataDef);\n\n  Vue.prototype.$set = set;\n  Vue.prototype.$delete = del;\n\n  Vue.prototype.$watch = function (\n    expOrFn,\n    cb,\n    options\n  ) {\n    var vm = this;\n    options = options || {};\n    options.user = true;\n    var watcher = new Watcher(vm, expOrFn, cb, options);\n    if (options.immediate) {\n      cb.call(vm, watcher.value);\n    }\n    return function unwatchFn () {\n      watcher.teardown();\n    }\n  };\n}\n\nfunction proxy (vm, key) {\n  if (!isReserved(key)) {\n    Object.defineProperty(vm, key, {\n      configurable: true,\n      enumerable: true,\n      get: function proxyGetter () {\n        return vm._data[key]\n      },\n      set: function proxySetter (val) {\n        vm._data[key] = val;\n      }\n    });\n  }\n}\n\n/*  */\n\nvar VNode = function VNode (\n  tag,\n  data,\n  children,\n  text,\n  elm,\n  ns,\n  context,\n  componentOptions\n) {\n  this.tag = tag;\n  this.data = data;\n  this.children = children;\n  this.text = text;\n  this.elm = elm;\n  this.ns = ns;\n  this.context = context;\n  this.functionalContext = undefined;\n  this.key = data && data.key;\n  this.componentOptions = componentOptions;\n  this.child = undefined;\n  this.parent = undefined;\n  this.raw = false;\n  this.isStatic = false;\n  this.isRootInsert = true;\n  this.isComment = false;\n  this.isCloned = false;\n};\n\nvar emptyVNode = function () {\n  var node = new VNode();\n  node.text = '';\n  node.isComment = true;\n  return node\n};\n\n// optimized shallow clone\n// used for static nodes and slot nodes because they may be reused across\n// multiple renders, cloning them avoids errors when DOM manipulations rely\n// on their elm reference.\nfunction cloneVNode (vnode) {\n  var cloned = new VNode(\n    vnode.tag,\n    vnode.data,\n    vnode.children,\n    vnode.text,\n    vnode.elm,\n    vnode.ns,\n    vnode.context,\n    vnode.componentOptions\n  );\n  cloned.isStatic = vnode.isStatic;\n  cloned.key = vnode.key;\n  cloned.isCloned = true;\n  return cloned\n}\n\nfunction cloneVNodes (vnodes) {\n  var res = new Array(vnodes.length);\n  for (var i = 0; i < vnodes.length; i++) {\n    res[i] = cloneVNode(vnodes[i]);\n  }\n  return res\n}\n\n/*  */\n\nfunction mergeVNodeHook (def, hookKey, hook, key) {\n  key = key + hookKey;\n  var injectedHash = def.__injected || (def.__injected = {});\n  if (!injectedHash[key]) {\n    injectedHash[key] = true;\n    var oldHook = def[hookKey];\n    if (oldHook) {\n      def[hookKey] = function () {\n        oldHook.apply(this, arguments);\n        hook.apply(this, arguments);\n      };\n    } else {\n      def[hookKey] = hook;\n    }\n  }\n}\n\n/*  */\n\nfunction updateListeners (\n  on,\n  oldOn,\n  add,\n  remove$$1,\n  vm\n) {\n  var name, cur, old, fn, event, capture;\n  for (name in on) {\n    cur = on[name];\n    old = oldOn[name];\n    if (!cur) {\n      process.env.NODE_ENV !== 'production' && warn(\n        \"Invalid handler for event \\\"\" + name + \"\\\": got \" + String(cur),\n        vm\n      );\n    } else if (!old) {\n      capture = name.charAt(0) === '!';\n      event = capture ? name.slice(1) : name;\n      if (Array.isArray(cur)) {\n        add(event, (cur.invoker = arrInvoker(cur)), capture);\n      } else {\n        if (!cur.invoker) {\n          fn = cur;\n          cur = on[name] = {};\n          cur.fn = fn;\n          cur.invoker = fnInvoker(cur);\n        }\n        add(event, cur.invoker, capture);\n      }\n    } else if (cur !== old) {\n      if (Array.isArray(old)) {\n        old.length = cur.length;\n        for (var i = 0; i < old.length; i++) { old[i] = cur[i]; }\n        on[name] = old;\n      } else {\n        old.fn = cur;\n        on[name] = old;\n      }\n    }\n  }\n  for (name in oldOn) {\n    if (!on[name]) {\n      event = name.charAt(0) === '!' ? name.slice(1) : name;\n      remove$$1(event, oldOn[name].invoker);\n    }\n  }\n}\n\nfunction arrInvoker (arr) {\n  return function (ev) {\n    var arguments$1 = arguments;\n\n    var single = arguments.length === 1;\n    for (var i = 0; i < arr.length; i++) {\n      single ? arr[i](ev) : arr[i].apply(null, arguments$1);\n    }\n  }\n}\n\nfunction fnInvoker (o) {\n  return function (ev) {\n    var single = arguments.length === 1;\n    single ? o.fn(ev) : o.fn.apply(null, arguments);\n  }\n}\n\n/*  */\n\nfunction normalizeChildren (\n  children,\n  ns,\n  nestedIndex\n) {\n  if (isPrimitive(children)) {\n    return [createTextVNode(children)]\n  }\n  if (Array.isArray(children)) {\n    var res = [];\n    for (var i = 0, l = children.length; i < l; i++) {\n      var c = children[i];\n      var last = res[res.length - 1];\n      //  nested\n      if (Array.isArray(c)) {\n        res.push.apply(res, normalizeChildren(c, ns, ((nestedIndex || '') + \"_\" + i)));\n      } else if (isPrimitive(c)) {\n        if (last && last.text) {\n          last.text += String(c);\n        } else if (c !== '') {\n          // convert primitive to vnode\n          res.push(createTextVNode(c));\n        }\n      } else if (c instanceof VNode) {\n        if (c.text && last && last.text) {\n          last.text += c.text;\n        } else {\n          // inherit parent namespace\n          if (ns) {\n            applyNS(c, ns);\n          }\n          // default key for nested array children (likely generated by v-for)\n          if (c.tag && c.key == null && nestedIndex != null) {\n            c.key = \"__vlist\" + nestedIndex + \"_\" + i + \"__\";\n          }\n          res.push(c);\n        }\n      }\n    }\n    return res\n  }\n}\n\nfunction createTextVNode (val) {\n  return new VNode(undefined, undefined, undefined, String(val))\n}\n\nfunction applyNS (vnode, ns) {\n  if (vnode.tag && !vnode.ns) {\n    vnode.ns = ns;\n    if (vnode.children) {\n      for (var i = 0, l = vnode.children.length; i < l; i++) {\n        applyNS(vnode.children[i], ns);\n      }\n    }\n  }\n}\n\n/*  */\n\nfunction getFirstComponentChild (children) {\n  return children && children.filter(function (c) { return c && c.componentOptions; })[0]\n}\n\n/*  */\n\nvar activeInstance = null;\n\nfunction initLifecycle (vm) {\n  var options = vm.$options;\n\n  // locate first non-abstract parent\n  var parent = options.parent;\n  if (parent && !options.abstract) {\n    while (parent.$options.abstract && parent.$parent) {\n      parent = parent.$parent;\n    }\n    parent.$children.push(vm);\n  }\n\n  vm.$parent = parent;\n  vm.$root = parent ? parent.$root : vm;\n\n  vm.$children = [];\n  vm.$refs = {};\n\n  vm._watcher = null;\n  vm._inactive = false;\n  vm._isMounted = false;\n  vm._isDestroyed = false;\n  vm._isBeingDestroyed = false;\n}\n\nfunction lifecycleMixin (Vue) {\n  Vue.prototype._mount = function (\n    el,\n    hydrating\n  ) {\n    var vm = this;\n    vm.$el = el;\n    if (!vm.$options.render) {\n      vm.$options.render = emptyVNode;\n      if (process.env.NODE_ENV !== 'production') {\n        /* istanbul ignore if */\n        if (vm.$options.template) {\n          warn(\n            'You are using the runtime-only build of Vue where the template ' +\n            'option is not available. Either pre-compile the templates into ' +\n            'render functions, or use the compiler-included build.',\n            vm\n          );\n        } else {\n          warn(\n            'Failed to mount component: template or render function not defined.',\n            vm\n          );\n        }\n      }\n    }\n    callHook(vm, 'beforeMount');\n    vm._watcher = new Watcher(vm, function () {\n      vm._update(vm._render(), hydrating);\n    }, noop);\n    hydrating = false;\n    // manually mounted instance, call mounted on self\n    // mounted is called for render-created child components in its inserted hook\n    if (vm.$vnode == null) {\n      vm._isMounted = true;\n      callHook(vm, 'mounted');\n    }\n    return vm\n  };\n\n  Vue.prototype._update = function (vnode, hydrating) {\n    var vm = this;\n    if (vm._isMounted) {\n      callHook(vm, 'beforeUpdate');\n    }\n    var prevEl = vm.$el;\n    var prevActiveInstance = activeInstance;\n    activeInstance = vm;\n    var prevVnode = vm._vnode;\n    vm._vnode = vnode;\n    if (!prevVnode) {\n      // Vue.prototype.__patch__ is injected in entry points\n      // based on the rendering backend used.\n      vm.$el = vm.__patch__(vm.$el, vnode, hydrating);\n    } else {\n      vm.$el = vm.__patch__(prevVnode, vnode);\n    }\n    activeInstance = prevActiveInstance;\n    // update __vue__ reference\n    if (prevEl) {\n      prevEl.__vue__ = null;\n    }\n    if (vm.$el) {\n      vm.$el.__vue__ = vm;\n    }\n    // if parent is an HOC, update its $el as well\n    if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {\n      vm.$parent.$el = vm.$el;\n    }\n    if (vm._isMounted) {\n      callHook(vm, 'updated');\n    }\n  };\n\n  Vue.prototype._updateFromParent = function (\n    propsData,\n    listeners,\n    parentVnode,\n    renderChildren\n  ) {\n    var vm = this;\n    var hasChildren = !!(vm.$options._renderChildren || renderChildren);\n    vm.$options._parentVnode = parentVnode;\n    vm.$options._renderChildren = renderChildren;\n    // update props\n    if (propsData && vm.$options.props) {\n      observerState.shouldConvert = false;\n      if (process.env.NODE_ENV !== 'production') {\n        observerState.isSettingProps = true;\n      }\n      var propKeys = vm.$options._propKeys || [];\n      for (var i = 0; i < propKeys.length; i++) {\n        var key = propKeys[i];\n        vm[key] = validateProp(key, vm.$options.props, propsData, vm);\n      }\n      observerState.shouldConvert = true;\n      if (process.env.NODE_ENV !== 'production') {\n        observerState.isSettingProps = false;\n      }\n    }\n    // update listeners\n    if (listeners) {\n      var oldListeners = vm.$options._parentListeners;\n      vm.$options._parentListeners = listeners;\n      vm._updateListeners(listeners, oldListeners);\n    }\n    // resolve slots + force update if has children\n    if (hasChildren) {\n      vm.$slots = resolveSlots(renderChildren, vm._renderContext);\n      vm.$forceUpdate();\n    }\n  };\n\n  Vue.prototype.$forceUpdate = function () {\n    var vm = this;\n    if (vm._watcher) {\n      vm._watcher.update();\n    }\n  };\n\n  Vue.prototype.$destroy = function () {\n    var vm = this;\n    if (vm._isBeingDestroyed) {\n      return\n    }\n    callHook(vm, 'beforeDestroy');\n    vm._isBeingDestroyed = true;\n    // remove self from parent\n    var parent = vm.$parent;\n    if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) {\n      remove$1(parent.$children, vm);\n    }\n    // teardown watchers\n    if (vm._watcher) {\n      vm._watcher.teardown();\n    }\n    var i = vm._watchers.length;\n    while (i--) {\n      vm._watchers[i].teardown();\n    }\n    // remove reference from data ob\n    // frozen object may not have observer.\n    if (vm._data.__ob__) {\n      vm._data.__ob__.vmCount--;\n    }\n    // call the last hook...\n    vm._isDestroyed = true;\n    callHook(vm, 'destroyed');\n    // turn off all instance listeners.\n    vm.$off();\n    // remove __vue__ reference\n    if (vm.$el) {\n      vm.$el.__vue__ = null;\n    }\n    // invoke destroy hooks on current rendered tree\n    vm.__patch__(vm._vnode, null);\n  };\n}\n\nfunction callHook (vm, hook) {\n  var handlers = vm.$options[hook];\n  if (handlers) {\n    for (var i = 0, j = handlers.length; i < j; i++) {\n      handlers[i].call(vm);\n    }\n  }\n  vm.$emit('hook:' + hook);\n}\n\n/*  */\n\nvar hooks = { init: init, prepatch: prepatch, insert: insert, destroy: destroy$1 };\nvar hooksToMerge = Object.keys(hooks);\n\nfunction createComponent (\n  Ctor,\n  data,\n  context,\n  children,\n  tag\n) {\n  if (!Ctor) {\n    return\n  }\n\n  if (isObject(Ctor)) {\n    Ctor = Vue$2.extend(Ctor);\n  }\n\n  if (typeof Ctor !== 'function') {\n    if (process.env.NODE_ENV !== 'production') {\n      warn((\"Invalid Component definition: \" + (String(Ctor))), context);\n    }\n    return\n  }\n\n  // async component\n  if (!Ctor.cid) {\n    if (Ctor.resolved) {\n      Ctor = Ctor.resolved;\n    } else {\n      Ctor = resolveAsyncComponent(Ctor, function () {\n        // it's ok to queue this on every render because\n        // $forceUpdate is buffered by the scheduler.\n        context.$forceUpdate();\n      });\n      if (!Ctor) {\n        // return nothing if this is indeed an async component\n        // wait for the callback to trigger parent update.\n        return\n      }\n    }\n  }\n\n  data = data || {};\n\n  // extract props\n  var propsData = extractProps(data, Ctor);\n\n  // functional component\n  if (Ctor.options.functional) {\n    return createFunctionalComponent(Ctor, propsData, data, context, children)\n  }\n\n  // extract listeners, since these needs to be treated as\n  // child component listeners instead of DOM listeners\n  var listeners = data.on;\n  // replace with listeners with .native modifier\n  data.on = data.nativeOn;\n\n  if (Ctor.options.abstract) {\n    // abstract components do not keep anything\n    // other than props & listeners\n    data = {};\n  }\n\n  // merge component management hooks onto the placeholder node\n  mergeHooks(data);\n\n  // return a placeholder vnode\n  var name = Ctor.options.name || tag;\n  var vnode = new VNode(\n    (\"vue-component-\" + (Ctor.cid) + (name ? (\"-\" + name) : '')),\n    data, undefined, undefined, undefined, undefined, context,\n    { Ctor: Ctor, propsData: propsData, listeners: listeners, tag: tag, children: children }\n  );\n  return vnode\n}\n\nfunction createFunctionalComponent (\n  Ctor,\n  propsData,\n  data,\n  context,\n  children\n) {\n  var props = {};\n  var propOptions = Ctor.options.props;\n  if (propOptions) {\n    for (var key in propOptions) {\n      props[key] = validateProp(key, propOptions, propsData);\n    }\n  }\n  var vnode = Ctor.options.render.call(\n    null,\n    // ensure the createElement function in functional components\n    // gets a unique context - this is necessary for correct named slot check\n    bind$1(createElement, { _self: Object.create(context) }),\n    {\n      props: props,\n      data: data,\n      parent: context,\n      children: normalizeChildren(children),\n      slots: function () { return resolveSlots(children, context); }\n    }\n  );\n  if (vnode instanceof VNode) {\n    vnode.functionalContext = context;\n    if (data.slot) {\n      (vnode.data || (vnode.data = {})).slot = data.slot;\n    }\n  }\n  return vnode\n}\n\nfunction createComponentInstanceForVnode (\n  vnode, // we know it's MountedComponentVNode but flow doesn't\n  parent // activeInstance in lifecycle state\n) {\n  var vnodeComponentOptions = vnode.componentOptions;\n  var options = {\n    _isComponent: true,\n    parent: parent,\n    propsData: vnodeComponentOptions.propsData,\n    _componentTag: vnodeComponentOptions.tag,\n    _parentVnode: vnode,\n    _parentListeners: vnodeComponentOptions.listeners,\n    _renderChildren: vnodeComponentOptions.children\n  };\n  // check inline-template render functions\n  var inlineTemplate = vnode.data.inlineTemplate;\n  if (inlineTemplate) {\n    options.render = inlineTemplate.render;\n    options.staticRenderFns = inlineTemplate.staticRenderFns;\n  }\n  return new vnodeComponentOptions.Ctor(options)\n}\n\nfunction init (vnode, hydrating) {\n  if (!vnode.child || vnode.child._isDestroyed) {\n    var child = vnode.child = createComponentInstanceForVnode(vnode, activeInstance);\n    child.$mount(hydrating ? vnode.elm : undefined, hydrating);\n  }\n}\n\nfunction prepatch (\n  oldVnode,\n  vnode\n) {\n  var options = vnode.componentOptions;\n  var child = vnode.child = oldVnode.child;\n  child._updateFromParent(\n    options.propsData, // updated props\n    options.listeners, // updated listeners\n    vnode, // new parent vnode\n    options.children // new children\n  );\n}\n\nfunction insert (vnode) {\n  if (!vnode.child._isMounted) {\n    vnode.child._isMounted = true;\n    callHook(vnode.child, 'mounted');\n  }\n  if (vnode.data.keepAlive) {\n    vnode.child._inactive = false;\n    callHook(vnode.child, 'activated');\n  }\n}\n\nfunction destroy$1 (vnode) {\n  if (!vnode.child._isDestroyed) {\n    if (!vnode.data.keepAlive) {\n      vnode.child.$destroy();\n    } else {\n      vnode.child._inactive = true;\n      callHook(vnode.child, 'deactivated');\n    }\n  }\n}\n\nfunction resolveAsyncComponent (\n  factory,\n  cb\n) {\n  if (factory.requested) {\n    // pool callbacks\n    factory.pendingCallbacks.push(cb);\n  } else {\n    factory.requested = true;\n    var cbs = factory.pendingCallbacks = [cb];\n    var sync = true;\n\n    var resolve = function (res) {\n      if (isObject(res)) {\n        res = Vue$2.extend(res);\n      }\n      // cache resolved\n      factory.resolved = res;\n      // invoke callbacks only if this is not a synchronous resolve\n      // (async resolves are shimmed as synchronous during SSR)\n      if (!sync) {\n        for (var i = 0, l = cbs.length; i < l; i++) {\n          cbs[i](res);\n        }\n      }\n    };\n\n    var reject = function (reason) {\n      process.env.NODE_ENV !== 'production' && warn(\n        \"Failed to resolve async component: \" + (String(factory)) +\n        (reason ? (\"\\nReason: \" + reason) : '')\n      );\n    };\n\n    var res = factory(resolve, reject);\n\n    // handle promise\n    if (res && typeof res.then === 'function' && !factory.resolved) {\n      res.then(resolve, reject);\n    }\n\n    sync = false;\n    // return in case resolved synchronously\n    return factory.resolved\n  }\n}\n\nfunction extractProps (data, Ctor) {\n  // we are only extrating raw values here.\n  // validation and default values are handled in the child\n  // component itself.\n  var propOptions = Ctor.options.props;\n  if (!propOptions) {\n    return\n  }\n  var res = {};\n  var attrs = data.attrs;\n  var props = data.props;\n  var domProps = data.domProps;\n  if (attrs || props || domProps) {\n    for (var key in propOptions) {\n      var altKey = hyphenate(key);\n      checkProp(res, props, key, altKey, true) ||\n      checkProp(res, attrs, key, altKey) ||\n      checkProp(res, domProps, key, altKey);\n    }\n  }\n  return res\n}\n\nfunction checkProp (\n  res,\n  hash,\n  key,\n  altKey,\n  preserve\n) {\n  if (hash) {\n    if (hasOwn(hash, key)) {\n      res[key] = hash[key];\n      if (!preserve) {\n        delete hash[key];\n      }\n      return true\n    } else if (hasOwn(hash, altKey)) {\n      res[key] = hash[altKey];\n      if (!preserve) {\n        delete hash[altKey];\n      }\n      return true\n    }\n  }\n  return false\n}\n\nfunction mergeHooks (data) {\n  if (!data.hook) {\n    data.hook = {};\n  }\n  for (var i = 0; i < hooksToMerge.length; i++) {\n    var key = hooksToMerge[i];\n    var fromParent = data.hook[key];\n    var ours = hooks[key];\n    data.hook[key] = fromParent ? mergeHook$1(ours, fromParent) : ours;\n  }\n}\n\nfunction mergeHook$1 (a, b) {\n  // since all hooks have at most two args, use fixed args\n  // to avoid having to use fn.apply().\n  return function (_, __) {\n    a(_, __);\n    b(_, __);\n  }\n}\n\n/*  */\n\n// wrapper function for providing a more flexible interface\n// without getting yelled at by flow\nfunction createElement (\n  tag,\n  data,\n  children\n) {\n  if (data && (Array.isArray(data) || typeof data !== 'object')) {\n    children = data;\n    data = undefined;\n  }\n  // make sure to use real instance instead of proxy as context\n  return _createElement(this._self, tag, data, children)\n}\n\nfunction _createElement (\n  context,\n  tag,\n  data,\n  children\n) {\n  if (data && data.__ob__) {\n    process.env.NODE_ENV !== 'production' && warn(\n      \"Avoid using observed data object as vnode data: \" + (JSON.stringify(data)) + \"\\n\" +\n      'Always create fresh vnode data objects in each render!',\n      context\n    );\n    return\n  }\n  if (!tag) {\n    // in case of component :is set to falsy value\n    return emptyVNode()\n  }\n  if (typeof tag === 'string') {\n    var Ctor;\n    var ns = config.getTagNamespace(tag);\n    if (config.isReservedTag(tag)) {\n      // platform built-in elements\n      return new VNode(\n        tag, data, normalizeChildren(children, ns),\n        undefined, undefined, ns, context\n      )\n    } else if ((Ctor = resolveAsset(context.$options, 'components', tag))) {\n      // component\n      return createComponent(Ctor, data, context, children, tag)\n    } else {\n      // unknown or unlisted namespaced elements\n      // check at runtime because it may get assigned a namespace when its\n      // parent normalizes children\n      return new VNode(\n        tag, data, normalizeChildren(children, ns),\n        undefined, undefined, ns, context\n      )\n    }\n  } else {\n    // direct component options / constructor\n    return createComponent(tag, data, context, children)\n  }\n}\n\n/*  */\n\nfunction initRender (vm) {\n  vm.$vnode = null; // the placeholder node in parent tree\n  vm._vnode = null; // the root of the child tree\n  vm._staticTrees = null;\n  vm._renderContext = vm.$options._parentVnode && vm.$options._parentVnode.context;\n  vm.$slots = resolveSlots(vm.$options._renderChildren, vm._renderContext);\n  // bind the public createElement fn to this instance\n  // so that we get proper render context inside it.\n  vm.$createElement = bind$1(createElement, vm);\n  if (vm.$options.el) {\n    vm.$mount(vm.$options.el);\n  }\n}\n\nfunction renderMixin (Vue) {\n  Vue.prototype.$nextTick = function (fn) {\n    nextTick(fn, this);\n  };\n\n  Vue.prototype._render = function () {\n    var vm = this;\n    var ref = vm.$options;\n    var render = ref.render;\n    var staticRenderFns = ref.staticRenderFns;\n    var _parentVnode = ref._parentVnode;\n\n    if (vm._isMounted) {\n      // clone slot nodes on re-renders\n      for (var key in vm.$slots) {\n        vm.$slots[key] = cloneVNodes(vm.$slots[key]);\n      }\n    }\n\n    if (staticRenderFns && !vm._staticTrees) {\n      vm._staticTrees = [];\n    }\n    // set parent vnode. this allows render functions to have access\n    // to the data on the placeholder node.\n    vm.$vnode = _parentVnode;\n    // render self\n    var vnode;\n    try {\n      vnode = render.call(vm._renderProxy, vm.$createElement);\n    } catch (e) {\n      if (process.env.NODE_ENV !== 'production') {\n        warn((\"Error when rendering \" + (formatComponentName(vm)) + \":\"));\n      }\n      /* istanbul ignore else */\n      if (config.errorHandler) {\n        config.errorHandler.call(null, e, vm);\n      } else {\n        if (config._isServer) {\n          throw e\n        } else {\n          setTimeout(function () { throw e }, 0);\n        }\n      }\n      // return previous vnode to prevent render error causing blank component\n      vnode = vm._vnode;\n    }\n    // return empty vnode in case the render function errored out\n    if (!(vnode instanceof VNode)) {\n      if (process.env.NODE_ENV !== 'production' && Array.isArray(vnode)) {\n        warn(\n          'Multiple root nodes returned from render function. Render function ' +\n          'should return a single root node.',\n          vm\n        );\n      }\n      vnode = emptyVNode();\n    }\n    // set parent\n    vnode.parent = _parentVnode;\n    return vnode\n  };\n\n  // shorthands used in render functions\n  Vue.prototype._h = createElement;\n  // toString for mustaches\n  Vue.prototype._s = _toString;\n  // number conversion\n  Vue.prototype._n = toNumber;\n  // empty vnode\n  Vue.prototype._e = emptyVNode;\n  // loose equal\n  Vue.prototype._q = looseEqual;\n  // loose indexOf\n  Vue.prototype._i = looseIndexOf;\n\n  // render static tree by index\n  Vue.prototype._m = function renderStatic (\n    index,\n    isInFor\n  ) {\n    var tree = this._staticTrees[index];\n    // if has already-rendered static tree and not inside v-for,\n    // we can reuse the same tree by doing a shallow clone.\n    if (tree && !isInFor) {\n      return Array.isArray(tree)\n        ? cloneVNodes(tree)\n        : cloneVNode(tree)\n    }\n    // otherwise, render a fresh tree.\n    tree = this._staticTrees[index] = this.$options.staticRenderFns[index].call(this._renderProxy);\n    if (Array.isArray(tree)) {\n      for (var i = 0; i < tree.length; i++) {\n        if (typeof tree[i] !== 'string') {\n          tree[i].isStatic = true;\n          tree[i].key = \"__static__\" + index + \"_\" + i;\n        }\n      }\n    } else {\n      tree.isStatic = true;\n      tree.key = \"__static__\" + index;\n    }\n    return tree\n  };\n\n  // filter resolution helper\n  var identity = function (_) { return _; };\n  Vue.prototype._f = function resolveFilter (id) {\n    return resolveAsset(this.$options, 'filters', id, true) || identity\n  };\n\n  // render v-for\n  Vue.prototype._l = function renderList (\n    val,\n    render\n  ) {\n    var ret, i, l, keys, key;\n    if (Array.isArray(val)) {\n      ret = new Array(val.length);\n      for (i = 0, l = val.length; i < l; i++) {\n        ret[i] = render(val[i], i);\n      }\n    } else if (typeof val === 'number') {\n      ret = new Array(val);\n      for (i = 0; i < val; i++) {\n        ret[i] = render(i + 1, i);\n      }\n    } else if (isObject(val)) {\n      keys = Object.keys(val);\n      ret = new Array(keys.length);\n      for (i = 0, l = keys.length; i < l; i++) {\n        key = keys[i];\n        ret[i] = render(val[key], key, i);\n      }\n    }\n    return ret\n  };\n\n  // renderSlot\n  Vue.prototype._t = function (\n    name,\n    fallback\n  ) {\n    var slotNodes = this.$slots[name];\n    // warn duplicate slot usage\n    if (slotNodes && process.env.NODE_ENV !== 'production') {\n      slotNodes._rendered && warn(\n        \"Duplicate presence of slot \\\"\" + name + \"\\\" found in the same render tree \" +\n        \"- this will likely cause render errors.\",\n        this\n      );\n      slotNodes._rendered = true;\n    }\n    return slotNodes || fallback\n  };\n\n  // apply v-bind object\n  Vue.prototype._b = function bindProps (\n    data,\n    value,\n    asProp\n  ) {\n    if (value) {\n      if (!isObject(value)) {\n        process.env.NODE_ENV !== 'production' && warn(\n          'v-bind without argument expects an Object or Array value',\n          this\n        );\n      } else {\n        if (Array.isArray(value)) {\n          value = toObject(value);\n        }\n        for (var key in value) {\n          if (key === 'class' || key === 'style') {\n            data[key] = value[key];\n          } else {\n            var hash = asProp || config.mustUseProp(key)\n              ? data.domProps || (data.domProps = {})\n              : data.attrs || (data.attrs = {});\n            hash[key] = value[key];\n          }\n        }\n      }\n    }\n    return data\n  };\n\n  // expose v-on keyCodes\n  Vue.prototype._k = function getKeyCodes (key) {\n    return config.keyCodes[key]\n  };\n}\n\nfunction resolveSlots (\n  renderChildren,\n  context\n) {\n  var slots = {};\n  if (!renderChildren) {\n    return slots\n  }\n  var children = normalizeChildren(renderChildren) || [];\n  var defaultSlot = [];\n  var name, child;\n  for (var i = 0, l = children.length; i < l; i++) {\n    child = children[i];\n    // named slots should only be respected if the vnode was rendered in the\n    // same context.\n    if ((child.context === context || child.functionalContext === context) &&\n        child.data && (name = child.data.slot)) {\n      var slot = (slots[name] || (slots[name] = []));\n      if (child.tag === 'template') {\n        slot.push.apply(slot, child.children);\n      } else {\n        slot.push(child);\n      }\n    } else {\n      defaultSlot.push(child);\n    }\n  }\n  // ignore single whitespace\n  if (defaultSlot.length && !(\n    defaultSlot.length === 1 &&\n    (defaultSlot[0].text === ' ' || defaultSlot[0].isComment)\n  )) {\n    slots.default = defaultSlot;\n  }\n  return slots\n}\n\n/*  */\n\nfunction initEvents (vm) {\n  vm._events = Object.create(null);\n  // init parent attached events\n  var listeners = vm.$options._parentListeners;\n  var on = bind$1(vm.$on, vm);\n  var off = bind$1(vm.$off, vm);\n  vm._updateListeners = function (listeners, oldListeners) {\n    updateListeners(listeners, oldListeners || {}, on, off, vm);\n  };\n  if (listeners) {\n    vm._updateListeners(listeners);\n  }\n}\n\nfunction eventsMixin (Vue) {\n  Vue.prototype.$on = function (event, fn) {\n    var vm = this;(vm._events[event] || (vm._events[event] = [])).push(fn);\n    return vm\n  };\n\n  Vue.prototype.$once = function (event, fn) {\n    var vm = this;\n    function on () {\n      vm.$off(event, on);\n      fn.apply(vm, arguments);\n    }\n    on.fn = fn;\n    vm.$on(event, on);\n    return vm\n  };\n\n  Vue.prototype.$off = function (event, fn) {\n    var vm = this;\n    // all\n    if (!arguments.length) {\n      vm._events = Object.create(null);\n      return vm\n    }\n    // specific event\n    var cbs = vm._events[event];\n    if (!cbs) {\n      return vm\n    }\n    if (arguments.length === 1) {\n      vm._events[event] = null;\n      return vm\n    }\n    // specific handler\n    var cb;\n    var i = cbs.length;\n    while (i--) {\n      cb = cbs[i];\n      if (cb === fn || cb.fn === fn) {\n        cbs.splice(i, 1);\n        break\n      }\n    }\n    return vm\n  };\n\n  Vue.prototype.$emit = function (event) {\n    var vm = this;\n    var cbs = vm._events[event];\n    if (cbs) {\n      cbs = cbs.length > 1 ? toArray(cbs) : cbs;\n      var args = toArray(arguments, 1);\n      for (var i = 0, l = cbs.length; i < l; i++) {\n        cbs[i].apply(vm, args);\n      }\n    }\n    return vm\n  };\n}\n\n/*  */\n\nvar uid = 0;\n\nfunction initMixin (Vue) {\n  Vue.prototype._init = function (options) {\n    var vm = this;\n    // a uid\n    vm._uid = uid++;\n    // a flag to avoid this being observed\n    vm._isVue = true;\n    // merge options\n    if (options && options._isComponent) {\n      // optimize internal component instantiation\n      // since dynamic options merging is pretty slow, and none of the\n      // internal component options needs special treatment.\n      initInternalComponent(vm, options);\n    } else {\n      vm.$options = mergeOptions(\n        resolveConstructorOptions(vm),\n        options || {},\n        vm\n      );\n    }\n    /* istanbul ignore else */\n    if (process.env.NODE_ENV !== 'production') {\n      initProxy(vm);\n    } else {\n      vm._renderProxy = vm;\n    }\n    // expose real self\n    vm._self = vm;\n    initLifecycle(vm);\n    initEvents(vm);\n    callHook(vm, 'beforeCreate');\n    initState(vm);\n    callHook(vm, 'created');\n    initRender(vm);\n  };\n\n  function initInternalComponent (vm, options) {\n    var opts = vm.$options = Object.create(resolveConstructorOptions(vm));\n    // doing this because it's faster than dynamic enumeration.\n    opts.parent = options.parent;\n    opts.propsData = options.propsData;\n    opts._parentVnode = options._parentVnode;\n    opts._parentListeners = options._parentListeners;\n    opts._renderChildren = options._renderChildren;\n    opts._componentTag = options._componentTag;\n    if (options.render) {\n      opts.render = options.render;\n      opts.staticRenderFns = options.staticRenderFns;\n    }\n  }\n\n  function resolveConstructorOptions (vm) {\n    var Ctor = vm.constructor;\n    var options = Ctor.options;\n    if (Ctor.super) {\n      var superOptions = Ctor.super.options;\n      var cachedSuperOptions = Ctor.superOptions;\n      if (superOptions !== cachedSuperOptions) {\n        // super option changed\n        Ctor.superOptions = superOptions;\n        options = Ctor.options = mergeOptions(superOptions, Ctor.extendOptions);\n        if (options.name) {\n          options.components[options.name] = Ctor;\n        }\n      }\n    }\n    return options\n  }\n}\n\nfunction Vue$2 (options) {\n  if (process.env.NODE_ENV !== 'production' &&\n    !(this instanceof Vue$2)) {\n    warn('Vue is a constructor and should be called with the `new` keyword');\n  }\n  this._init(options);\n}\n\ninitMixin(Vue$2);\nstateMixin(Vue$2);\neventsMixin(Vue$2);\nlifecycleMixin(Vue$2);\nrenderMixin(Vue$2);\n\nvar warn = noop;\nvar formatComponentName;\n\nif (process.env.NODE_ENV !== 'production') {\n  var hasConsole = typeof console !== 'undefined';\n\n  warn = function (msg, vm) {\n    if (hasConsole && (!config.silent)) {\n      console.error(\"[Vue warn]: \" + msg + \" \" + (\n        vm ? formatLocation(formatComponentName(vm)) : ''\n      ));\n    }\n  };\n\n  formatComponentName = function (vm) {\n    if (vm.$root === vm) {\n      return 'root instance'\n    }\n    var name = vm._isVue\n      ? vm.$options.name || vm.$options._componentTag\n      : vm.name;\n    return (\n      (name ? (\"component <\" + name + \">\") : \"anonymous component\") +\n      (vm._isVue && vm.$options.__file ? (\" at \" + (vm.$options.__file)) : '')\n    )\n  };\n\n  var formatLocation = function (str) {\n    if (str === 'anonymous component') {\n      str += \" - use the \\\"name\\\" option for better debugging messages.\";\n    }\n    return (\"\\n(found in \" + str + \")\")\n  };\n}\n\n/*  */\n\n/**\n * Option overwriting strategies are functions that handle\n * how to merge a parent option value and a child option\n * value into the final value.\n */\nvar strats = config.optionMergeStrategies;\n\n/**\n * Options with restrictions\n */\nif (process.env.NODE_ENV !== 'production') {\n  strats.el = strats.propsData = function (parent, child, vm, key) {\n    if (!vm) {\n      warn(\n        \"option \\\"\" + key + \"\\\" can only be used during instance \" +\n        'creation with the `new` keyword.'\n      );\n    }\n    return defaultStrat(parent, child)\n  };\n}\n\n/**\n * Helper that recursively merges two data objects together.\n */\nfunction mergeData (to, from) {\n  var key, toVal, fromVal;\n  for (key in from) {\n    toVal = to[key];\n    fromVal = from[key];\n    if (!hasOwn(to, key)) {\n      set(to, key, fromVal);\n    } else if (isObject(toVal) && isObject(fromVal)) {\n      mergeData(toVal, fromVal);\n    }\n  }\n  return to\n}\n\n/**\n * Data\n */\nstrats.data = function (\n  parentVal,\n  childVal,\n  vm\n) {\n  if (!vm) {\n    // in a Vue.extend merge, both should be functions\n    if (!childVal) {\n      return parentVal\n    }\n    if (typeof childVal !== 'function') {\n      process.env.NODE_ENV !== 'production' && warn(\n        'The \"data\" option should be a function ' +\n        'that returns a per-instance value in component ' +\n        'definitions.',\n        vm\n      );\n      return parentVal\n    }\n    if (!parentVal) {\n      return childVal\n    }\n    // when parentVal & childVal are both present,\n    // we need to return a function that returns the\n    // merged result of both functions... no need to\n    // check if parentVal is a function here because\n    // it has to be a function to pass previous merges.\n    return function mergedDataFn () {\n      return mergeData(\n        childVal.call(this),\n        parentVal.call(this)\n      )\n    }\n  } else if (parentVal || childVal) {\n    return function mergedInstanceDataFn () {\n      // instance merge\n      var instanceData = typeof childVal === 'function'\n        ? childVal.call(vm)\n        : childVal;\n      var defaultData = typeof parentVal === 'function'\n        ? parentVal.call(vm)\n        : undefined;\n      if (instanceData) {\n        return mergeData(instanceData, defaultData)\n      } else {\n        return defaultData\n      }\n    }\n  }\n};\n\n/**\n * Hooks and param attributes are merged as arrays.\n */\nfunction mergeHook (\n  parentVal,\n  childVal\n) {\n  return childVal\n    ? parentVal\n      ? parentVal.concat(childVal)\n      : Array.isArray(childVal)\n        ? childVal\n        : [childVal]\n    : parentVal\n}\n\nconfig._lifecycleHooks.forEach(function (hook) {\n  strats[hook] = mergeHook;\n});\n\n/**\n * Assets\n *\n * When a vm is present (instance creation), we need to do\n * a three-way merge between constructor options, instance\n * options and parent options.\n */\nfunction mergeAssets (parentVal, childVal) {\n  var res = Object.create(parentVal || null);\n  return childVal\n    ? extend(res, childVal)\n    : res\n}\n\nconfig._assetTypes.forEach(function (type) {\n  strats[type + 's'] = mergeAssets;\n});\n\n/**\n * Watchers.\n *\n * Watchers hashes should not overwrite one\n * another, so we merge them as arrays.\n */\nstrats.watch = function (parentVal, childVal) {\n  /* istanbul ignore if */\n  if (!childVal) { return parentVal }\n  if (!parentVal) { return childVal }\n  var ret = {};\n  extend(ret, parentVal);\n  for (var key in childVal) {\n    var parent = ret[key];\n    var child = childVal[key];\n    if (parent && !Array.isArray(parent)) {\n      parent = [parent];\n    }\n    ret[key] = parent\n      ? parent.concat(child)\n      : [child];\n  }\n  return ret\n};\n\n/**\n * Other object hashes.\n */\nstrats.props =\nstrats.methods =\nstrats.computed = function (parentVal, childVal) {\n  if (!childVal) { return parentVal }\n  if (!parentVal) { return childVal }\n  var ret = Object.create(null);\n  extend(ret, parentVal);\n  extend(ret, childVal);\n  return ret\n};\n\n/**\n * Default strategy.\n */\nvar defaultStrat = function (parentVal, childVal) {\n  return childVal === undefined\n    ? parentVal\n    : childVal\n};\n\n/**\n * Make sure component options get converted to actual\n * constructors.\n */\nfunction normalizeComponents (options) {\n  if (options.components) {\n    var components = options.components;\n    var def;\n    for (var key in components) {\n      var lower = key.toLowerCase();\n      if (isBuiltInTag(lower) || config.isReservedTag(lower)) {\n        process.env.NODE_ENV !== 'production' && warn(\n          'Do not use built-in or reserved HTML elements as component ' +\n          'id: ' + key\n        );\n        continue\n      }\n      def = components[key];\n      if (isPlainObject(def)) {\n        components[key] = Vue$2.extend(def);\n      }\n    }\n  }\n}\n\n/**\n * Ensure all props option syntax are normalized into the\n * Object-based format.\n */\nfunction normalizeProps (options) {\n  var props = options.props;\n  if (!props) { return }\n  var res = {};\n  var i, val, name;\n  if (Array.isArray(props)) {\n    i = props.length;\n    while (i--) {\n      val = props[i];\n      if (typeof val === 'string') {\n        name = camelize(val);\n        res[name] = { type: null };\n      } else if (process.env.NODE_ENV !== 'production') {\n        warn('props must be strings when using array syntax.');\n      }\n    }\n  } else if (isPlainObject(props)) {\n    for (var key in props) {\n      val = props[key];\n      name = camelize(key);\n      res[name] = isPlainObject(val)\n        ? val\n        : { type: val };\n    }\n  }\n  options.props = res;\n}\n\n/**\n * Normalize raw function directives into object format.\n */\nfunction normalizeDirectives (options) {\n  var dirs = options.directives;\n  if (dirs) {\n    for (var key in dirs) {\n      var def = dirs[key];\n      if (typeof def === 'function') {\n        dirs[key] = { bind: def, update: def };\n      }\n    }\n  }\n}\n\n/**\n * Merge two option objects into a new one.\n * Core utility used in both instantiation and inheritance.\n */\nfunction mergeOptions (\n  parent,\n  child,\n  vm\n) {\n  normalizeComponents(child);\n  normalizeProps(child);\n  normalizeDirectives(child);\n  var extendsFrom = child.extends;\n  if (extendsFrom) {\n    parent = typeof extendsFrom === 'function'\n      ? mergeOptions(parent, extendsFrom.options, vm)\n      : mergeOptions(parent, extendsFrom, vm);\n  }\n  if (child.mixins) {\n    for (var i = 0, l = child.mixins.length; i < l; i++) {\n      var mixin = child.mixins[i];\n      if (mixin.prototype instanceof Vue$2) {\n        mixin = mixin.options;\n      }\n      parent = mergeOptions(parent, mixin, vm);\n    }\n  }\n  var options = {};\n  var key;\n  for (key in parent) {\n    mergeField(key);\n  }\n  for (key in child) {\n    if (!hasOwn(parent, key)) {\n      mergeField(key);\n    }\n  }\n  function mergeField (key) {\n    var strat = strats[key] || defaultStrat;\n    options[key] = strat(parent[key], child[key], vm, key);\n  }\n  return options\n}\n\n/**\n * Resolve an asset.\n * This function is used because child instances need access\n * to assets defined in its ancestor chain.\n */\nfunction resolveAsset (\n  options,\n  type,\n  id,\n  warnMissing\n) {\n  /* istanbul ignore if */\n  if (typeof id !== 'string') {\n    return\n  }\n  var assets = options[type];\n  var res = assets[id] ||\n    // camelCase ID\n    assets[camelize(id)] ||\n    // Pascal Case ID\n    assets[capitalize(camelize(id))];\n  if (process.env.NODE_ENV !== 'production' && warnMissing && !res) {\n    warn(\n      'Failed to resolve ' + type.slice(0, -1) + ': ' + id,\n      options\n    );\n  }\n  return res\n}\n\n/*  */\n\nfunction validateProp (\n  key,\n  propOptions,\n  propsData,\n  vm\n) {\n  var prop = propOptions[key];\n  var absent = !hasOwn(propsData, key);\n  var value = propsData[key];\n  // handle boolean props\n  if (isBooleanType(prop.type)) {\n    if (absent && !hasOwn(prop, 'default')) {\n      value = false;\n    } else if (value === '' || value === hyphenate(key)) {\n      value = true;\n    }\n  }\n  // check default value\n  if (value === undefined) {\n    value = getPropDefaultValue(vm, prop, key);\n    // since the default value is a fresh copy,\n    // make sure to observe it.\n    var prevShouldConvert = observerState.shouldConvert;\n    observerState.shouldConvert = true;\n    observe(value);\n    observerState.shouldConvert = prevShouldConvert;\n  }\n  if (process.env.NODE_ENV !== 'production') {\n    assertProp(prop, key, value, vm, absent);\n  }\n  return value\n}\n\n/**\n * Get the default value of a prop.\n */\nfunction getPropDefaultValue (vm, prop, name) {\n  // no default, return undefined\n  if (!hasOwn(prop, 'default')) {\n    return undefined\n  }\n  var def = prop.default;\n  // warn against non-factory defaults for Object & Array\n  if (isObject(def)) {\n    process.env.NODE_ENV !== 'production' && warn(\n      'Invalid default value for prop \"' + name + '\": ' +\n      'Props with type Object/Array must use a factory function ' +\n      'to return the default value.',\n      vm\n    );\n  }\n  // call factory function for non-Function types\n  return typeof def === 'function' && prop.type !== Function\n    ? def.call(vm)\n    : def\n}\n\n/**\n * Assert whether a prop is valid.\n */\nfunction assertProp (\n  prop,\n  name,\n  value,\n  vm,\n  absent\n) {\n  if (prop.required && absent) {\n    warn(\n      'Missing required prop: \"' + name + '\"',\n      vm\n    );\n    return\n  }\n  if (value == null && !prop.required) {\n    return\n  }\n  var type = prop.type;\n  var valid = !type || type === true;\n  var expectedTypes = [];\n  if (type) {\n    if (!Array.isArray(type)) {\n      type = [type];\n    }\n    for (var i = 0; i < type.length && !valid; i++) {\n      var assertedType = assertType(value, type[i]);\n      expectedTypes.push(assertedType.expectedType);\n      valid = assertedType.valid;\n    }\n  }\n  if (!valid) {\n    warn(\n      'Invalid prop: type check failed for prop \"' + name + '\".' +\n      ' Expected ' + expectedTypes.map(capitalize).join(', ') +\n      ', got ' + Object.prototype.toString.call(value).slice(8, -1) + '.',\n      vm\n    );\n    return\n  }\n  var validator = prop.validator;\n  if (validator) {\n    if (!validator(value)) {\n      warn(\n        'Invalid prop: custom validator check failed for prop \"' + name + '\".',\n        vm\n      );\n    }\n  }\n}\n\n/**\n * Assert the type of a value\n */\nfunction assertType (value, type) {\n  var valid;\n  var expectedType = getType(type);\n  if (expectedType === 'String') {\n    valid = typeof value === (expectedType = 'string');\n  } else if (expectedType === 'Number') {\n    valid = typeof value === (expectedType = 'number');\n  } else if (expectedType === 'Boolean') {\n    valid = typeof value === (expectedType = 'boolean');\n  } else if (expectedType === 'Function') {\n    valid = typeof value === (expectedType = 'function');\n  } else if (expectedType === 'Object') {\n    valid = isPlainObject(value);\n  } else if (expectedType === 'Array') {\n    valid = Array.isArray(value);\n  } else {\n    valid = value instanceof type;\n  }\n  return {\n    valid: valid,\n    expectedType: expectedType\n  }\n}\n\n/**\n * Use function string name to check built-in types,\n * because a simple equality check will fail when running\n * across different vms / iframes.\n */\nfunction getType (fn) {\n  var match = fn && fn.toString().match(/^\\s*function (\\w+)/);\n  return match && match[1]\n}\n\nfunction isBooleanType (fn) {\n  if (!Array.isArray(fn)) {\n    return getType(fn) === 'Boolean'\n  }\n  for (var i = 0, len = fn.length; i < len; i++) {\n    if (getType(fn[i]) === 'Boolean') {\n      return true\n    }\n  }\n  /* istanbul ignore next */\n  return false\n}\n\n\n\nvar util = Object.freeze({\n\tdefineReactive: defineReactive$$1,\n\t_toString: _toString,\n\ttoNumber: toNumber,\n\tmakeMap: makeMap,\n\tisBuiltInTag: isBuiltInTag,\n\tremove: remove$1,\n\thasOwn: hasOwn,\n\tisPrimitive: isPrimitive,\n\tcached: cached,\n\tcamelize: camelize,\n\tcapitalize: capitalize,\n\thyphenate: hyphenate,\n\tbind: bind$1,\n\ttoArray: toArray,\n\textend: extend,\n\tisObject: isObject,\n\tisPlainObject: isPlainObject,\n\ttoObject: toObject,\n\tnoop: noop,\n\tno: no,\n\tgenStaticKeys: genStaticKeys,\n\tlooseEqual: looseEqual,\n\tlooseIndexOf: looseIndexOf,\n\tisReserved: isReserved,\n\tdef: def,\n\tparsePath: parsePath,\n\thasProto: hasProto,\n\tinBrowser: inBrowser,\n\tUA: UA,\n\tisIE: isIE,\n\tisIE9: isIE9,\n\tisEdge: isEdge,\n\tisAndroid: isAndroid,\n\tisIOS: isIOS,\n\tdevtools: devtools,\n\tnextTick: nextTick,\n\tget _Set () { return _Set; },\n\tmergeOptions: mergeOptions,\n\tresolveAsset: resolveAsset,\n\tget warn () { return warn; },\n\tget formatComponentName () { return formatComponentName; },\n\tvalidateProp: validateProp\n});\n\n/*  */\n\nfunction initUse (Vue) {\n  Vue.use = function (plugin) {\n    /* istanbul ignore if */\n    if (plugin.installed) {\n      return\n    }\n    // additional parameters\n    var args = toArray(arguments, 1);\n    args.unshift(this);\n    if (typeof plugin.install === 'function') {\n      plugin.install.apply(plugin, args);\n    } else {\n      plugin.apply(null, args);\n    }\n    plugin.installed = true;\n    return this\n  };\n}\n\n/*  */\n\nfunction initMixin$1 (Vue) {\n  Vue.mixin = function (mixin) {\n    Vue.options = mergeOptions(Vue.options, mixin);\n  };\n}\n\n/*  */\n\nfunction initExtend (Vue) {\n  /**\n   * Each instance constructor, including Vue, has a unique\n   * cid. This enables us to create wrapped \"child\n   * constructors\" for prototypal inheritance and cache them.\n   */\n  Vue.cid = 0;\n  var cid = 1;\n\n  /**\n   * Class inheritance\n   */\n  Vue.extend = function (extendOptions) {\n    extendOptions = extendOptions || {};\n    var Super = this;\n    var isFirstExtend = Super.cid === 0;\n    if (isFirstExtend && extendOptions._Ctor) {\n      return extendOptions._Ctor\n    }\n    var name = extendOptions.name || Super.options.name;\n    if (process.env.NODE_ENV !== 'production') {\n      if (!/^[a-zA-Z][\\w-]*$/.test(name)) {\n        warn(\n          'Invalid component name: \"' + name + '\". Component names ' +\n          'can only contain alphanumeric characaters and the hyphen.'\n        );\n        name = null;\n      }\n    }\n    var Sub = function VueComponent (options) {\n      this._init(options);\n    };\n    Sub.prototype = Object.create(Super.prototype);\n    Sub.prototype.constructor = Sub;\n    Sub.cid = cid++;\n    Sub.options = mergeOptions(\n      Super.options,\n      extendOptions\n    );\n    Sub['super'] = Super;\n    // allow further extension\n    Sub.extend = Super.extend;\n    // create asset registers, so extended classes\n    // can have their private assets too.\n    config._assetTypes.forEach(function (type) {\n      Sub[type] = Super[type];\n    });\n    // enable recursive self-lookup\n    if (name) {\n      Sub.options.components[name] = Sub;\n    }\n    // keep a reference to the super options at extension time.\n    // later at instantiation we can check if Super's options have\n    // been updated.\n    Sub.superOptions = Super.options;\n    Sub.extendOptions = extendOptions;\n    // cache constructor\n    if (isFirstExtend) {\n      extendOptions._Ctor = Sub;\n    }\n    return Sub\n  };\n}\n\n/*  */\n\nfunction initAssetRegisters (Vue) {\n  /**\n   * Create asset registration methods.\n   */\n  config._assetTypes.forEach(function (type) {\n    Vue[type] = function (\n      id,\n      definition\n    ) {\n      if (!definition) {\n        return this.options[type + 's'][id]\n      } else {\n        /* istanbul ignore if */\n        if (process.env.NODE_ENV !== 'production') {\n          if (type === 'component' && config.isReservedTag(id)) {\n            warn(\n              'Do not use built-in or reserved HTML elements as component ' +\n              'id: ' + id\n            );\n          }\n        }\n        if (type === 'component' && isPlainObject(definition)) {\n          definition.name = definition.name || id;\n          definition = Vue.extend(definition);\n        }\n        if (type === 'directive' && typeof definition === 'function') {\n          definition = { bind: definition, update: definition };\n        }\n        this.options[type + 's'][id] = definition;\n        return definition\n      }\n    };\n  });\n}\n\nvar KeepAlive = {\n  name: 'keep-alive',\n  abstract: true,\n  created: function created () {\n    this.cache = Object.create(null);\n  },\n  render: function render () {\n    var vnode = getFirstComponentChild(this.$slots.default);\n    if (vnode && vnode.componentOptions) {\n      var opts = vnode.componentOptions;\n      var key = vnode.key == null\n        // same constructor may get registered as different local components\n        // so cid alone is not enough (#3269)\n        ? opts.Ctor.cid + '::' + opts.tag\n        : vnode.key;\n      if (this.cache[key]) {\n        vnode.child = this.cache[key].child;\n      } else {\n        this.cache[key] = vnode;\n      }\n      vnode.data.keepAlive = true;\n    }\n    return vnode\n  },\n  destroyed: function destroyed () {\n    var this$1 = this;\n\n    for (var key in this.cache) {\n      var vnode = this$1.cache[key];\n      callHook(vnode.child, 'deactivated');\n      vnode.child.$destroy();\n    }\n  }\n};\n\nvar builtInComponents = {\n  KeepAlive: KeepAlive\n};\n\n/*  */\n\nfunction initGlobalAPI (Vue) {\n  // config\n  var configDef = {};\n  configDef.get = function () { return config; };\n  if (process.env.NODE_ENV !== 'production') {\n    configDef.set = function () {\n      warn(\n        'Do not replace the Vue.config object, set individual fields instead.'\n      );\n    };\n  }\n  Object.defineProperty(Vue, 'config', configDef);\n  Vue.util = util;\n  Vue.set = set;\n  Vue.delete = del;\n  Vue.nextTick = nextTick;\n\n  Vue.options = Object.create(null);\n  config._assetTypes.forEach(function (type) {\n    Vue.options[type + 's'] = Object.create(null);\n  });\n\n  extend(Vue.options.components, builtInComponents);\n\n  initUse(Vue);\n  initMixin$1(Vue);\n  initExtend(Vue);\n  initAssetRegisters(Vue);\n}\n\ninitGlobalAPI(Vue$2);\n\nObject.defineProperty(Vue$2.prototype, '$isServer', {\n  get: function () { return config._isServer; }\n});\n\nVue$2.version = '2.0.3';\n\n/*  */\n\n// attributes that should be using props for binding\nvar mustUseProp = makeMap('value,selected,checked,muted');\n\nvar isEnumeratedAttr = makeMap('contenteditable,draggable,spellcheck');\n\nvar isBooleanAttr = makeMap(\n  'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' +\n  'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' +\n  'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' +\n  'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' +\n  'required,reversed,scoped,seamless,selected,sortable,translate,' +\n  'truespeed,typemustmatch,visible'\n);\n\nvar isAttr = makeMap(\n  'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,' +\n  'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,' +\n  'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,' +\n  'name,contenteditable,contextmenu,controls,coords,data,datetime,default,' +\n  'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,' +\n  'form,formaction,headers,<th>,height,hidden,high,href,hreflang,http-equiv,' +\n  'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,' +\n  'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,' +\n  'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,' +\n  'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,' +\n  'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,' +\n  'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,' +\n  'target,title,type,usemap,value,width,wrap'\n);\n\n\n\nvar xlinkNS = 'http://www.w3.org/1999/xlink';\n\nvar isXlink = function (name) {\n  return name.charAt(5) === ':' && name.slice(0, 5) === 'xlink'\n};\n\nvar getXlinkProp = function (name) {\n  return isXlink(name) ? name.slice(6, name.length) : ''\n};\n\nvar isFalsyAttrValue = function (val) {\n  return val == null || val === false\n};\n\n/*  */\n\nfunction genClassForVnode (vnode) {\n  var data = vnode.data;\n  var parentNode = vnode;\n  var childNode = vnode;\n  while (childNode.child) {\n    childNode = childNode.child._vnode;\n    if (childNode.data) {\n      data = mergeClassData(childNode.data, data);\n    }\n  }\n  while ((parentNode = parentNode.parent)) {\n    if (parentNode.data) {\n      data = mergeClassData(data, parentNode.data);\n    }\n  }\n  return genClassFromData(data)\n}\n\nfunction mergeClassData (child, parent) {\n  return {\n    staticClass: concat(child.staticClass, parent.staticClass),\n    class: child.class\n      ? [child.class, parent.class]\n      : parent.class\n  }\n}\n\nfunction genClassFromData (data) {\n  var dynamicClass = data.class;\n  var staticClass = data.staticClass;\n  if (staticClass || dynamicClass) {\n    return concat(staticClass, stringifyClass(dynamicClass))\n  }\n  /* istanbul ignore next */\n  return ''\n}\n\nfunction concat (a, b) {\n  return a ? b ? (a + ' ' + b) : a : (b || '')\n}\n\nfunction stringifyClass (value) {\n  var res = '';\n  if (!value) {\n    return res\n  }\n  if (typeof value === 'string') {\n    return value\n  }\n  if (Array.isArray(value)) {\n    var stringified;\n    for (var i = 0, l = value.length; i < l; i++) {\n      if (value[i]) {\n        if ((stringified = stringifyClass(value[i]))) {\n          res += stringified + ' ';\n        }\n      }\n    }\n    return res.slice(0, -1)\n  }\n  if (isObject(value)) {\n    for (var key in value) {\n      if (value[key]) { res += key + ' '; }\n    }\n    return res.slice(0, -1)\n  }\n  /* istanbul ignore next */\n  return res\n}\n\n/*  */\n\nvar namespaceMap = {\n  svg: 'http://www.w3.org/2000/svg',\n  math: 'http://www.w3.org/1998/Math/MathML'\n};\n\nvar isHTMLTag = makeMap(\n  'html,body,base,head,link,meta,style,title,' +\n  'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +\n  'div,dd,dl,dt,figcaption,figure,hr,img,li,main,ol,p,pre,ul,' +\n  'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +\n  's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +\n  'embed,object,param,source,canvas,script,noscript,del,ins,' +\n  'caption,col,colgroup,table,thead,tbody,td,th,tr,' +\n  'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +\n  'output,progress,select,textarea,' +\n  'details,dialog,menu,menuitem,summary,' +\n  'content,element,shadow,template'\n);\n\nvar isUnaryTag = makeMap(\n  'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +\n  'link,meta,param,source,track,wbr',\n  true\n);\n\n// Elements that you can, intentionally, leave open\n// (and which close themselves)\nvar canBeLeftOpenTag = makeMap(\n  'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source',\n  true\n);\n\n// HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3\n// Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content\nvar isNonPhrasingTag = makeMap(\n  'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' +\n  'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' +\n  'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' +\n  'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' +\n  'title,tr,track',\n  true\n);\n\n// this map is intentionally selective, only covering SVG elements that may\n// contain child elements.\nvar isSVG = makeMap(\n  'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font,' +\n  'font-face,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +\n  'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',\n  true\n);\n\n\n\nvar isReservedTag = function (tag) {\n  return isHTMLTag(tag) || isSVG(tag)\n};\n\nfunction getTagNamespace (tag) {\n  if (isSVG(tag)) {\n    return 'svg'\n  }\n  // basic support for MathML\n  // note it doesn't support other MathML elements being component roots\n  if (tag === 'math') {\n    return 'math'\n  }\n}\n\nvar unknownElementCache = Object.create(null);\nfunction isUnknownElement (tag) {\n  /* istanbul ignore if */\n  if (!inBrowser) {\n    return true\n  }\n  if (isReservedTag(tag)) {\n    return false\n  }\n  tag = tag.toLowerCase();\n  /* istanbul ignore if */\n  if (unknownElementCache[tag] != null) {\n    return unknownElementCache[tag]\n  }\n  var el = document.createElement(tag);\n  if (tag.indexOf('-') > -1) {\n    // http://stackoverflow.com/a/28210364/1070244\n    return (unknownElementCache[tag] = (\n      el.constructor === window.HTMLUnknownElement ||\n      el.constructor === window.HTMLElement\n    ))\n  } else {\n    return (unknownElementCache[tag] = /HTMLUnknownElement/.test(el.toString()))\n  }\n}\n\n/*  */\n\n/**\n * Query an element selector if it's not an element already.\n */\nfunction query (el) {\n  if (typeof el === 'string') {\n    var selector = el;\n    el = document.querySelector(el);\n    if (!el) {\n      process.env.NODE_ENV !== 'production' && warn(\n        'Cannot find element: ' + selector\n      );\n      return document.createElement('div')\n    }\n  }\n  return el\n}\n\n/*  */\n\nfunction createElement$1 (tagName, vnode) {\n  var elm = document.createElement(tagName);\n  if (tagName !== 'select') {\n    return elm\n  }\n  if (vnode.data && vnode.data.attrs && 'multiple' in vnode.data.attrs) {\n    elm.setAttribute('multiple', 'multiple');\n  }\n  return elm\n}\n\nfunction createElementNS (namespace, tagName) {\n  return document.createElementNS(namespaceMap[namespace], tagName)\n}\n\nfunction createTextNode (text) {\n  return document.createTextNode(text)\n}\n\nfunction createComment (text) {\n  return document.createComment(text)\n}\n\nfunction insertBefore (parentNode, newNode, referenceNode) {\n  parentNode.insertBefore(newNode, referenceNode);\n}\n\nfunction removeChild (node, child) {\n  node.removeChild(child);\n}\n\nfunction appendChild (node, child) {\n  node.appendChild(child);\n}\n\nfunction parentNode (node) {\n  return node.parentNode\n}\n\nfunction nextSibling (node) {\n  return node.nextSibling\n}\n\nfunction tagName (node) {\n  return node.tagName\n}\n\nfunction setTextContent (node, text) {\n  node.textContent = text;\n}\n\nfunction childNodes (node) {\n  return node.childNodes\n}\n\nfunction setAttribute (node, key, val) {\n  node.setAttribute(key, val);\n}\n\n\nvar nodeOps = Object.freeze({\n\tcreateElement: createElement$1,\n\tcreateElementNS: createElementNS,\n\tcreateTextNode: createTextNode,\n\tcreateComment: createComment,\n\tinsertBefore: insertBefore,\n\tremoveChild: removeChild,\n\tappendChild: appendChild,\n\tparentNode: parentNode,\n\tnextSibling: nextSibling,\n\ttagName: tagName,\n\tsetTextContent: setTextContent,\n\tchildNodes: childNodes,\n\tsetAttribute: setAttribute\n});\n\n/*  */\n\nvar ref = {\n  create: function create (_, vnode) {\n    registerRef(vnode);\n  },\n  update: function update (oldVnode, vnode) {\n    if (oldVnode.data.ref !== vnode.data.ref) {\n      registerRef(oldVnode, true);\n      registerRef(vnode);\n    }\n  },\n  destroy: function destroy (vnode) {\n    registerRef(vnode, true);\n  }\n};\n\nfunction registerRef (vnode, isRemoval) {\n  var key = vnode.data.ref;\n  if (!key) { return }\n\n  var vm = vnode.context;\n  var ref = vnode.child || vnode.elm;\n  var refs = vm.$refs;\n  if (isRemoval) {\n    if (Array.isArray(refs[key])) {\n      remove$1(refs[key], ref);\n    } else if (refs[key] === ref) {\n      refs[key] = undefined;\n    }\n  } else {\n    if (vnode.data.refInFor) {\n      if (Array.isArray(refs[key])) {\n        refs[key].push(ref);\n      } else {\n        refs[key] = [ref];\n      }\n    } else {\n      refs[key] = ref;\n    }\n  }\n}\n\n/**\n * Virtual DOM patching algorithm based on Snabbdom by\n * Simon Friis Vindum (@paldepind)\n * Licensed under the MIT License\n * https://github.com/paldepind/snabbdom/blob/master/LICENSE\n *\n * modified by Evan You (@yyx990803)\n *\n\n/*\n * Not type-checking this because this file is perf-critical and the cost\n * of making flow understand it is not worth it.\n */\n\nvar emptyNode = new VNode('', {}, []);\n\nvar hooks$1 = ['create', 'update', 'remove', 'destroy'];\n\nfunction isUndef (s) {\n  return s == null\n}\n\nfunction isDef (s) {\n  return s != null\n}\n\nfunction sameVnode (vnode1, vnode2) {\n  return (\n    vnode1.key === vnode2.key &&\n    vnode1.tag === vnode2.tag &&\n    vnode1.isComment === vnode2.isComment &&\n    !vnode1.data === !vnode2.data\n  )\n}\n\nfunction createKeyToOldIdx (children, beginIdx, endIdx) {\n  var i, key;\n  var map = {};\n  for (i = beginIdx; i <= endIdx; ++i) {\n    key = children[i].key;\n    if (isDef(key)) { map[key] = i; }\n  }\n  return map\n}\n\nfunction createPatchFunction (backend) {\n  var i, j;\n  var cbs = {};\n\n  var modules = backend.modules;\n  var nodeOps = backend.nodeOps;\n\n  for (i = 0; i < hooks$1.length; ++i) {\n    cbs[hooks$1[i]] = [];\n    for (j = 0; j < modules.length; ++j) {\n      if (modules[j][hooks$1[i]] !== undefined) { cbs[hooks$1[i]].push(modules[j][hooks$1[i]]); }\n    }\n  }\n\n  function emptyNodeAt (elm) {\n    return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm)\n  }\n\n  function createRmCb (childElm, listeners) {\n    function remove$$1 () {\n      if (--remove$$1.listeners === 0) {\n        removeElement(childElm);\n      }\n    }\n    remove$$1.listeners = listeners;\n    return remove$$1\n  }\n\n  function removeElement (el) {\n    var parent = nodeOps.parentNode(el);\n    nodeOps.removeChild(parent, el);\n  }\n\n  function createElm (vnode, insertedVnodeQueue, nested) {\n    var i;\n    var data = vnode.data;\n    vnode.isRootInsert = !nested;\n    if (isDef(data)) {\n      if (isDef(i = data.hook) && isDef(i = i.init)) { i(vnode); }\n      // after calling the init hook, if the vnode is a child component\n      // it should've created a child instance and mounted it. the child\n      // component also has set the placeholder vnode's elm.\n      // in that case we can just return the element and be done.\n      if (isDef(i = vnode.child)) {\n        initComponent(vnode, insertedVnodeQueue);\n        return vnode.elm\n      }\n    }\n    var children = vnode.children;\n    var tag = vnode.tag;\n    if (isDef(tag)) {\n      if (process.env.NODE_ENV !== 'production') {\n        if (\n          !vnode.ns &&\n          !(config.ignoredElements && config.ignoredElements.indexOf(tag) > -1) &&\n          config.isUnknownElement(tag)\n        ) {\n          warn(\n            'Unknown custom element: <' + tag + '> - did you ' +\n            'register the component correctly? For recursive components, ' +\n            'make sure to provide the \"name\" option.',\n            vnode.context\n          );\n        }\n      }\n      vnode.elm = vnode.ns\n        ? nodeOps.createElementNS(vnode.ns, tag)\n        : nodeOps.createElement(tag, vnode);\n      setScope(vnode);\n      createChildren(vnode, children, insertedVnodeQueue);\n      if (isDef(data)) {\n        invokeCreateHooks(vnode, insertedVnodeQueue);\n      }\n    } else if (vnode.isComment) {\n      vnode.elm = nodeOps.createComment(vnode.text);\n    } else {\n      vnode.elm = nodeOps.createTextNode(vnode.text);\n    }\n    return vnode.elm\n  }\n\n  function createChildren (vnode, children, insertedVnodeQueue) {\n    if (Array.isArray(children)) {\n      for (var i = 0; i < children.length; ++i) {\n        nodeOps.appendChild(vnode.elm, createElm(children[i], insertedVnodeQueue, true));\n      }\n    } else if (isPrimitive(vnode.text)) {\n      nodeOps.appendChild(vnode.elm, nodeOps.createTextNode(vnode.text));\n    }\n  }\n\n  function isPatchable (vnode) {\n    while (vnode.child) {\n      vnode = vnode.child._vnode;\n    }\n    return isDef(vnode.tag)\n  }\n\n  function invokeCreateHooks (vnode, insertedVnodeQueue) {\n    for (var i$1 = 0; i$1 < cbs.create.length; ++i$1) {\n      cbs.create[i$1](emptyNode, vnode);\n    }\n    i = vnode.data.hook; // Reuse variable\n    if (isDef(i)) {\n      if (i.create) { i.create(emptyNode, vnode); }\n      if (i.insert) { insertedVnodeQueue.push(vnode); }\n    }\n  }\n\n  function initComponent (vnode, insertedVnodeQueue) {\n    if (vnode.data.pendingInsert) {\n      insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert);\n    }\n    vnode.elm = vnode.child.$el;\n    if (isPatchable(vnode)) {\n      invokeCreateHooks(vnode, insertedVnodeQueue);\n      setScope(vnode);\n    } else {\n      // empty component root.\n      // skip all element-related modules except for ref (#3455)\n      registerRef(vnode);\n      // make sure to invoke the insert hook\n      insertedVnodeQueue.push(vnode);\n    }\n  }\n\n  // set scope id attribute for scoped CSS.\n  // this is implemented as a special case to avoid the overhead\n  // of going through the normal attribute patching process.\n  function setScope (vnode) {\n    var i;\n    if (isDef(i = vnode.context) && isDef(i = i.$options._scopeId)) {\n      nodeOps.setAttribute(vnode.elm, i, '');\n    }\n    if (isDef(i = activeInstance) &&\n        i !== vnode.context &&\n        isDef(i = i.$options._scopeId)) {\n      nodeOps.setAttribute(vnode.elm, i, '');\n    }\n  }\n\n  function addVnodes (parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) {\n    for (; startIdx <= endIdx; ++startIdx) {\n      nodeOps.insertBefore(parentElm, createElm(vnodes[startIdx], insertedVnodeQueue), before);\n    }\n  }\n\n  function invokeDestroyHook (vnode) {\n    var i, j;\n    var data = vnode.data;\n    if (isDef(data)) {\n      if (isDef(i = data.hook) && isDef(i = i.destroy)) { i(vnode); }\n      for (i = 0; i < cbs.destroy.length; ++i) { cbs.destroy[i](vnode); }\n    }\n    if (isDef(i = vnode.children)) {\n      for (j = 0; j < vnode.children.length; ++j) {\n        invokeDestroyHook(vnode.children[j]);\n      }\n    }\n  }\n\n  function removeVnodes (parentElm, vnodes, startIdx, endIdx) {\n    for (; startIdx <= endIdx; ++startIdx) {\n      var ch = vnodes[startIdx];\n      if (isDef(ch)) {\n        if (isDef(ch.tag)) {\n          removeAndInvokeRemoveHook(ch);\n          invokeDestroyHook(ch);\n        } else { // Text node\n          nodeOps.removeChild(parentElm, ch.elm);\n        }\n      }\n    }\n  }\n\n  function removeAndInvokeRemoveHook (vnode, rm) {\n    if (rm || isDef(vnode.data)) {\n      var listeners = cbs.remove.length + 1;\n      if (!rm) {\n        // directly removing\n        rm = createRmCb(vnode.elm, listeners);\n      } else {\n        // we have a recursively passed down rm callback\n        // increase the listeners count\n        rm.listeners += listeners;\n      }\n      // recursively invoke hooks on child component root node\n      if (isDef(i = vnode.child) && isDef(i = i._vnode) && isDef(i.data)) {\n        removeAndInvokeRemoveHook(i, rm);\n      }\n      for (i = 0; i < cbs.remove.length; ++i) {\n        cbs.remove[i](vnode, rm);\n      }\n      if (isDef(i = vnode.data.hook) && isDef(i = i.remove)) {\n        i(vnode, rm);\n      } else {\n        rm();\n      }\n    } else {\n      removeElement(vnode.elm);\n    }\n  }\n\n  function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {\n    var oldStartIdx = 0;\n    var newStartIdx = 0;\n    var oldEndIdx = oldCh.length - 1;\n    var oldStartVnode = oldCh[0];\n    var oldEndVnode = oldCh[oldEndIdx];\n    var newEndIdx = newCh.length - 1;\n    var newStartVnode = newCh[0];\n    var newEndVnode = newCh[newEndIdx];\n    var oldKeyToIdx, idxInOld, elmToMove, before;\n\n    // removeOnly is a special flag used only by <transition-group>\n    // to ensure removed elements stay in correct relative positions\n    // during leaving transitions\n    var canMove = !removeOnly;\n\n    while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {\n      if (isUndef(oldStartVnode)) {\n        oldStartVnode = oldCh[++oldStartIdx]; // Vnode has been moved left\n      } else if (isUndef(oldEndVnode)) {\n        oldEndVnode = oldCh[--oldEndIdx];\n      } else if (sameVnode(oldStartVnode, newStartVnode)) {\n        patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue);\n        oldStartVnode = oldCh[++oldStartIdx];\n        newStartVnode = newCh[++newStartIdx];\n      } else if (sameVnode(oldEndVnode, newEndVnode)) {\n        patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue);\n        oldEndVnode = oldCh[--oldEndIdx];\n        newEndVnode = newCh[--newEndIdx];\n      } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right\n        patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue);\n        canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm));\n        oldStartVnode = oldCh[++oldStartIdx];\n        newEndVnode = newCh[--newEndIdx];\n      } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left\n        patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue);\n        canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);\n        oldEndVnode = oldCh[--oldEndIdx];\n        newStartVnode = newCh[++newStartIdx];\n      } else {\n        if (isUndef(oldKeyToIdx)) { oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); }\n        idxInOld = isDef(newStartVnode.key) ? oldKeyToIdx[newStartVnode.key] : null;\n        if (isUndef(idxInOld)) { // New element\n          nodeOps.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);\n          newStartVnode = newCh[++newStartIdx];\n        } else {\n          elmToMove = oldCh[idxInOld];\n          /* istanbul ignore if */\n          if (process.env.NODE_ENV !== 'production' && !elmToMove) {\n            warn(\n              'It seems there are duplicate keys that is causing an update error. ' +\n              'Make sure each v-for item has a unique key.'\n            );\n          }\n          if (elmToMove.tag !== newStartVnode.tag) {\n            // same key but different element. treat as new element\n            nodeOps.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);\n            newStartVnode = newCh[++newStartIdx];\n          } else {\n            patchVnode(elmToMove, newStartVnode, insertedVnodeQueue);\n            oldCh[idxInOld] = undefined;\n            canMove && nodeOps.insertBefore(parentElm, newStartVnode.elm, oldStartVnode.elm);\n            newStartVnode = newCh[++newStartIdx];\n          }\n        }\n      }\n    }\n    if (oldStartIdx > oldEndIdx) {\n      before = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm;\n      addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);\n    } else if (newStartIdx > newEndIdx) {\n      removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);\n    }\n  }\n\n  function patchVnode (oldVnode, vnode, insertedVnodeQueue, removeOnly) {\n    if (oldVnode === vnode) {\n      return\n    }\n    // reuse element for static trees.\n    // note we only do this if the vnode is cloned -\n    // if the new node is not cloned it means the render functions have been\n    // reset by the hot-reload-api and we need to do a proper re-render.\n    if (vnode.isStatic &&\n        oldVnode.isStatic &&\n        vnode.key === oldVnode.key &&\n        vnode.isCloned) {\n      vnode.elm = oldVnode.elm;\n      return\n    }\n    var i;\n    var data = vnode.data;\n    var hasData = isDef(data);\n    if (hasData && isDef(i = data.hook) && isDef(i = i.prepatch)) {\n      i(oldVnode, vnode);\n    }\n    var elm = vnode.elm = oldVnode.elm;\n    var oldCh = oldVnode.children;\n    var ch = vnode.children;\n    if (hasData && isPatchable(vnode)) {\n      for (i = 0; i < cbs.update.length; ++i) { cbs.update[i](oldVnode, vnode); }\n      if (isDef(i = data.hook) && isDef(i = i.update)) { i(oldVnode, vnode); }\n    }\n    if (isUndef(vnode.text)) {\n      if (isDef(oldCh) && isDef(ch)) {\n        if (oldCh !== ch) { updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly); }\n      } else if (isDef(ch)) {\n        if (isDef(oldVnode.text)) { nodeOps.setTextContent(elm, ''); }\n        addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);\n      } else if (isDef(oldCh)) {\n        removeVnodes(elm, oldCh, 0, oldCh.length - 1);\n      } else if (isDef(oldVnode.text)) {\n        nodeOps.setTextContent(elm, '');\n      }\n    } else if (oldVnode.text !== vnode.text) {\n      nodeOps.setTextContent(elm, vnode.text);\n    }\n    if (hasData) {\n      if (isDef(i = data.hook) && isDef(i = i.postpatch)) { i(oldVnode, vnode); }\n    }\n  }\n\n  function invokeInsertHook (vnode, queue, initial) {\n    // delay insert hooks for component root nodes, invoke them after the\n    // element is really inserted\n    if (initial && vnode.parent) {\n      vnode.parent.data.pendingInsert = queue;\n    } else {\n      for (var i = 0; i < queue.length; ++i) {\n        queue[i].data.hook.insert(queue[i]);\n      }\n    }\n  }\n\n  var bailed = false;\n  function hydrate (elm, vnode, insertedVnodeQueue) {\n    if (process.env.NODE_ENV !== 'production') {\n      if (!assertNodeMatch(elm, vnode)) {\n        return false\n      }\n    }\n    vnode.elm = elm;\n    var tag = vnode.tag;\n    var data = vnode.data;\n    var children = vnode.children;\n    if (isDef(data)) {\n      if (isDef(i = data.hook) && isDef(i = i.init)) { i(vnode, true /* hydrating */); }\n      if (isDef(i = vnode.child)) {\n        // child component. it should have hydrated its own tree.\n        initComponent(vnode, insertedVnodeQueue);\n        return true\n      }\n    }\n    if (isDef(tag)) {\n      if (isDef(children)) {\n        var childNodes = nodeOps.childNodes(elm);\n        // empty element, allow client to pick up and populate children\n        if (!childNodes.length) {\n          createChildren(vnode, children, insertedVnodeQueue);\n        } else {\n          var childrenMatch = true;\n          if (childNodes.length !== children.length) {\n            childrenMatch = false;\n          } else {\n            for (var i$1 = 0; i$1 < children.length; i$1++) {\n              if (!hydrate(childNodes[i$1], children[i$1], insertedVnodeQueue)) {\n                childrenMatch = false;\n                break\n              }\n            }\n          }\n          if (!childrenMatch) {\n            if (process.env.NODE_ENV !== 'production' &&\n                typeof console !== 'undefined' &&\n                !bailed) {\n              bailed = true;\n              console.warn('Parent: ', elm);\n              console.warn('Mismatching childNodes vs. VNodes: ', childNodes, children);\n            }\n            return false\n          }\n        }\n      }\n      if (isDef(data)) {\n        invokeCreateHooks(vnode, insertedVnodeQueue);\n      }\n    }\n    return true\n  }\n\n  function assertNodeMatch (node, vnode) {\n    if (vnode.tag) {\n      return (\n        vnode.tag.indexOf('vue-component') === 0 ||\n        vnode.tag === nodeOps.tagName(node).toLowerCase()\n      )\n    } else {\n      return _toString(vnode.text) === node.data\n    }\n  }\n\n  return function patch (oldVnode, vnode, hydrating, removeOnly) {\n    if (!vnode) {\n      if (oldVnode) { invokeDestroyHook(oldVnode); }\n      return\n    }\n\n    var elm, parent;\n    var isInitialPatch = false;\n    var insertedVnodeQueue = [];\n\n    if (!oldVnode) {\n      // empty mount, create new root element\n      isInitialPatch = true;\n      createElm(vnode, insertedVnodeQueue);\n    } else {\n      var isRealElement = isDef(oldVnode.nodeType);\n      if (!isRealElement && sameVnode(oldVnode, vnode)) {\n        patchVnode(oldVnode, vnode, insertedVnodeQueue, removeOnly);\n      } else {\n        if (isRealElement) {\n          // mounting to a real element\n          // check if this is server-rendered content and if we can perform\n          // a successful hydration.\n          if (oldVnode.nodeType === 1 && oldVnode.hasAttribute('server-rendered')) {\n            oldVnode.removeAttribute('server-rendered');\n            hydrating = true;\n          }\n          if (hydrating) {\n            if (hydrate(oldVnode, vnode, insertedVnodeQueue)) {\n              invokeInsertHook(vnode, insertedVnodeQueue, true);\n              return oldVnode\n            } else if (process.env.NODE_ENV !== 'production') {\n              warn(\n                'The client-side rendered virtual DOM tree is not matching ' +\n                'server-rendered content. This is likely caused by incorrect ' +\n                'HTML markup, for example nesting block-level elements inside ' +\n                '<p>, or missing <tbody>. Bailing hydration and performing ' +\n                'full client-side render.'\n              );\n            }\n          }\n          // either not server-rendered, or hydration failed.\n          // create an empty node and replace it\n          oldVnode = emptyNodeAt(oldVnode);\n        }\n        elm = oldVnode.elm;\n        parent = nodeOps.parentNode(elm);\n\n        createElm(vnode, insertedVnodeQueue);\n\n        // component root element replaced.\n        // update parent placeholder node element.\n        if (vnode.parent) {\n          vnode.parent.elm = vnode.elm;\n          if (isPatchable(vnode)) {\n            for (var i = 0; i < cbs.create.length; ++i) {\n              cbs.create[i](emptyNode, vnode.parent);\n            }\n          }\n        }\n\n        if (parent !== null) {\n          nodeOps.insertBefore(parent, vnode.elm, nodeOps.nextSibling(elm));\n          removeVnodes(parent, [oldVnode], 0, 0);\n        } else if (isDef(oldVnode.tag)) {\n          invokeDestroyHook(oldVnode);\n        }\n      }\n    }\n\n    invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch);\n    return vnode.elm\n  }\n}\n\n/*  */\n\nvar directives = {\n  create: updateDirectives,\n  update: updateDirectives,\n  destroy: function unbindDirectives (vnode) {\n    updateDirectives(vnode, emptyNode);\n  }\n};\n\nfunction updateDirectives (\n  oldVnode,\n  vnode\n) {\n  if (!oldVnode.data.directives && !vnode.data.directives) {\n    return\n  }\n  var isCreate = oldVnode === emptyNode;\n  var oldDirs = normalizeDirectives$1(oldVnode.data.directives, oldVnode.context);\n  var newDirs = normalizeDirectives$1(vnode.data.directives, vnode.context);\n\n  var dirsWithInsert = [];\n  var dirsWithPostpatch = [];\n\n  var key, oldDir, dir;\n  for (key in newDirs) {\n    oldDir = oldDirs[key];\n    dir = newDirs[key];\n    if (!oldDir) {\n      // new directive, bind\n      callHook$1(dir, 'bind', vnode, oldVnode);\n      if (dir.def && dir.def.inserted) {\n        dirsWithInsert.push(dir);\n      }\n    } else {\n      // existing directive, update\n      dir.oldValue = oldDir.value;\n      callHook$1(dir, 'update', vnode, oldVnode);\n      if (dir.def && dir.def.componentUpdated) {\n        dirsWithPostpatch.push(dir);\n      }\n    }\n  }\n\n  if (dirsWithInsert.length) {\n    var callInsert = function () {\n      dirsWithInsert.forEach(function (dir) {\n        callHook$1(dir, 'inserted', vnode, oldVnode);\n      });\n    };\n    if (isCreate) {\n      mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', callInsert, 'dir-insert');\n    } else {\n      callInsert();\n    }\n  }\n\n  if (dirsWithPostpatch.length) {\n    mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'postpatch', function () {\n      dirsWithPostpatch.forEach(function (dir) {\n        callHook$1(dir, 'componentUpdated', vnode, oldVnode);\n      });\n    }, 'dir-postpatch');\n  }\n\n  if (!isCreate) {\n    for (key in oldDirs) {\n      if (!newDirs[key]) {\n        // no longer present, unbind\n        callHook$1(oldDirs[key], 'unbind', oldVnode);\n      }\n    }\n  }\n}\n\nvar emptyModifiers = Object.create(null);\n\nfunction normalizeDirectives$1 (\n  dirs,\n  vm\n) {\n  var res = Object.create(null);\n  if (!dirs) {\n    return res\n  }\n  var i, dir;\n  for (i = 0; i < dirs.length; i++) {\n    dir = dirs[i];\n    if (!dir.modifiers) {\n      dir.modifiers = emptyModifiers;\n    }\n    res[getRawDirName(dir)] = dir;\n    dir.def = resolveAsset(vm.$options, 'directives', dir.name, true);\n  }\n  return res\n}\n\nfunction getRawDirName (dir) {\n  return dir.rawName || ((dir.name) + \".\" + (Object.keys(dir.modifiers || {}).join('.')))\n}\n\nfunction callHook$1 (dir, hook, vnode, oldVnode) {\n  var fn = dir.def && dir.def[hook];\n  if (fn) {\n    fn(vnode.elm, dir, vnode, oldVnode);\n  }\n}\n\nvar baseModules = [\n  ref,\n  directives\n];\n\n/*  */\n\nfunction updateAttrs (oldVnode, vnode) {\n  if (!oldVnode.data.attrs && !vnode.data.attrs) {\n    return\n  }\n  var key, cur, old;\n  var elm = vnode.elm;\n  var oldAttrs = oldVnode.data.attrs || {};\n  var attrs = vnode.data.attrs || {};\n  // clone observed objects, as the user probably wants to mutate it\n  if (attrs.__ob__) {\n    attrs = vnode.data.attrs = extend({}, attrs);\n  }\n\n  for (key in attrs) {\n    cur = attrs[key];\n    old = oldAttrs[key];\n    if (old !== cur) {\n      setAttr(elm, key, cur);\n    }\n  }\n  for (key in oldAttrs) {\n    if (attrs[key] == null) {\n      if (isXlink(key)) {\n        elm.removeAttributeNS(xlinkNS, getXlinkProp(key));\n      } else if (!isEnumeratedAttr(key)) {\n        elm.removeAttribute(key);\n      }\n    }\n  }\n}\n\nfunction setAttr (el, key, value) {\n  if (isBooleanAttr(key)) {\n    // set attribute for blank value\n    // e.g. <option disabled>Select one</option>\n    if (isFalsyAttrValue(value)) {\n      el.removeAttribute(key);\n    } else {\n      el.setAttribute(key, key);\n    }\n  } else if (isEnumeratedAttr(key)) {\n    el.setAttribute(key, isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true');\n  } else if (isXlink(key)) {\n    if (isFalsyAttrValue(value)) {\n      el.removeAttributeNS(xlinkNS, getXlinkProp(key));\n    } else {\n      el.setAttributeNS(xlinkNS, key, value);\n    }\n  } else {\n    if (isFalsyAttrValue(value)) {\n      el.removeAttribute(key);\n    } else {\n      el.setAttribute(key, value);\n    }\n  }\n}\n\nvar attrs = {\n  create: updateAttrs,\n  update: updateAttrs\n};\n\n/*  */\n\nfunction updateClass (oldVnode, vnode) {\n  var el = vnode.elm;\n  var data = vnode.data;\n  var oldData = oldVnode.data;\n  if (!data.staticClass && !data.class &&\n      (!oldData || (!oldData.staticClass && !oldData.class))) {\n    return\n  }\n\n  var cls = genClassForVnode(vnode);\n\n  // handle transition classes\n  var transitionClass = el._transitionClasses;\n  if (transitionClass) {\n    cls = concat(cls, stringifyClass(transitionClass));\n  }\n\n  // set the class\n  if (cls !== el._prevClass) {\n    el.setAttribute('class', cls);\n    el._prevClass = cls;\n  }\n}\n\nvar klass = {\n  create: updateClass,\n  update: updateClass\n};\n\n// skip type checking this file because we need to attach private properties\n// to elements\n\nfunction updateDOMListeners (oldVnode, vnode) {\n  if (!oldVnode.data.on && !vnode.data.on) {\n    return\n  }\n  var on = vnode.data.on || {};\n  var oldOn = oldVnode.data.on || {};\n  var add = vnode.elm._v_add || (vnode.elm._v_add = function (event, handler, capture) {\n    vnode.elm.addEventListener(event, handler, capture);\n  });\n  var remove = vnode.elm._v_remove || (vnode.elm._v_remove = function (event, handler) {\n    vnode.elm.removeEventListener(event, handler);\n  });\n  updateListeners(on, oldOn, add, remove, vnode.context);\n}\n\nvar events = {\n  create: updateDOMListeners,\n  update: updateDOMListeners\n};\n\n/*  */\n\nfunction updateDOMProps (oldVnode, vnode) {\n  if (!oldVnode.data.domProps && !vnode.data.domProps) {\n    return\n  }\n  var key, cur;\n  var elm = vnode.elm;\n  var oldProps = oldVnode.data.domProps || {};\n  var props = vnode.data.domProps || {};\n  // clone observed objects, as the user probably wants to mutate it\n  if (props.__ob__) {\n    props = vnode.data.domProps = extend({}, props);\n  }\n\n  for (key in oldProps) {\n    if (props[key] == null) {\n      elm[key] = undefined;\n    }\n  }\n  for (key in props) {\n    // ignore children if the node has textContent or innerHTML,\n    // as these will throw away existing DOM nodes and cause removal errors\n    // on subsequent patches (#3360)\n    if ((key === 'textContent' || key === 'innerHTML') && vnode.children) {\n      vnode.children.length = 0;\n    }\n    cur = props[key];\n    if (key === 'value') {\n      // store value as _value as well since\n      // non-string values will be stringified\n      elm._value = cur;\n      // avoid resetting cursor position when value is the same\n      var strCur = cur == null ? '' : String(cur);\n      if (elm.value !== strCur && !elm.composing) {\n        elm.value = strCur;\n      }\n    } else {\n      elm[key] = cur;\n    }\n  }\n}\n\nvar domProps = {\n  create: updateDOMProps,\n  update: updateDOMProps\n};\n\n/*  */\n\nvar prefixes = ['Webkit', 'Moz', 'ms'];\n\nvar testEl;\nvar normalize = cached(function (prop) {\n  testEl = testEl || document.createElement('div');\n  prop = camelize(prop);\n  if (prop !== 'filter' && (prop in testEl.style)) {\n    return prop\n  }\n  var upper = prop.charAt(0).toUpperCase() + prop.slice(1);\n  for (var i = 0; i < prefixes.length; i++) {\n    var prefixed = prefixes[i] + upper;\n    if (prefixed in testEl.style) {\n      return prefixed\n    }\n  }\n});\n\nfunction updateStyle (oldVnode, vnode) {\n  if ((!oldVnode.data || !oldVnode.data.style) && !vnode.data.style) {\n    return\n  }\n  var cur, name;\n  var el = vnode.elm;\n  var oldStyle = oldVnode.data.style || {};\n  var style = vnode.data.style || {};\n\n  // handle string\n  if (typeof style === 'string') {\n    el.style.cssText = style;\n    return\n  }\n\n  var needClone = style.__ob__;\n\n  // handle array syntax\n  if (Array.isArray(style)) {\n    style = vnode.data.style = toObject(style);\n  }\n\n  // clone the style for future updates,\n  // in case the user mutates the style object in-place.\n  if (needClone) {\n    style = vnode.data.style = extend({}, style);\n  }\n\n  for (name in oldStyle) {\n    if (style[name] == null) {\n      el.style[normalize(name)] = '';\n    }\n  }\n  for (name in style) {\n    cur = style[name];\n    if (cur !== oldStyle[name]) {\n      // ie9 setting to null has no effect, must use empty string\n      el.style[normalize(name)] = cur == null ? '' : cur;\n    }\n  }\n}\n\nvar style = {\n  create: updateStyle,\n  update: updateStyle\n};\n\n/*  */\n\n/**\n * Add class with compatibility for SVG since classList is not supported on\n * SVG elements in IE\n */\nfunction addClass (el, cls) {\n  /* istanbul ignore else */\n  if (el.classList) {\n    if (cls.indexOf(' ') > -1) {\n      cls.split(/\\s+/).forEach(function (c) { return el.classList.add(c); });\n    } else {\n      el.classList.add(cls);\n    }\n  } else {\n    var cur = ' ' + el.getAttribute('class') + ' ';\n    if (cur.indexOf(' ' + cls + ' ') < 0) {\n      el.setAttribute('class', (cur + cls).trim());\n    }\n  }\n}\n\n/**\n * Remove class with compatibility for SVG since classList is not supported on\n * SVG elements in IE\n */\nfunction removeClass (el, cls) {\n  /* istanbul ignore else */\n  if (el.classList) {\n    if (cls.indexOf(' ') > -1) {\n      cls.split(/\\s+/).forEach(function (c) { return el.classList.remove(c); });\n    } else {\n      el.classList.remove(cls);\n    }\n  } else {\n    var cur = ' ' + el.getAttribute('class') + ' ';\n    var tar = ' ' + cls + ' ';\n    while (cur.indexOf(tar) >= 0) {\n      cur = cur.replace(tar, ' ');\n    }\n    el.setAttribute('class', cur.trim());\n  }\n}\n\n/*  */\n\nvar hasTransition = inBrowser && !isIE9;\nvar TRANSITION = 'transition';\nvar ANIMATION = 'animation';\n\n// Transition property/event sniffing\nvar transitionProp = 'transition';\nvar transitionEndEvent = 'transitionend';\nvar animationProp = 'animation';\nvar animationEndEvent = 'animationend';\nif (hasTransition) {\n  /* istanbul ignore if */\n  if (window.ontransitionend === undefined &&\n    window.onwebkittransitionend !== undefined) {\n    transitionProp = 'WebkitTransition';\n    transitionEndEvent = 'webkitTransitionEnd';\n  }\n  if (window.onanimationend === undefined &&\n    window.onwebkitanimationend !== undefined) {\n    animationProp = 'WebkitAnimation';\n    animationEndEvent = 'webkitAnimationEnd';\n  }\n}\n\nvar raf = (inBrowser && window.requestAnimationFrame) || setTimeout;\nfunction nextFrame (fn) {\n  raf(function () {\n    raf(fn);\n  });\n}\n\nfunction addTransitionClass (el, cls) {\n  (el._transitionClasses || (el._transitionClasses = [])).push(cls);\n  addClass(el, cls);\n}\n\nfunction removeTransitionClass (el, cls) {\n  if (el._transitionClasses) {\n    remove$1(el._transitionClasses, cls);\n  }\n  removeClass(el, cls);\n}\n\nfunction whenTransitionEnds (\n  el,\n  expectedType,\n  cb\n) {\n  var ref = getTransitionInfo(el, expectedType);\n  var type = ref.type;\n  var timeout = ref.timeout;\n  var propCount = ref.propCount;\n  if (!type) { return cb() }\n  var event = type === TRANSITION ? transitionEndEvent : animationEndEvent;\n  var ended = 0;\n  var end = function () {\n    el.removeEventListener(event, onEnd);\n    cb();\n  };\n  var onEnd = function (e) {\n    if (e.target === el) {\n      if (++ended >= propCount) {\n        end();\n      }\n    }\n  };\n  setTimeout(function () {\n    if (ended < propCount) {\n      end();\n    }\n  }, timeout + 1);\n  el.addEventListener(event, onEnd);\n}\n\nvar transformRE = /\\b(transform|all)(,|$)/;\n\nfunction getTransitionInfo (el, expectedType) {\n  var styles = window.getComputedStyle(el);\n  var transitioneDelays = styles[transitionProp + 'Delay'].split(', ');\n  var transitionDurations = styles[transitionProp + 'Duration'].split(', ');\n  var transitionTimeout = getTimeout(transitioneDelays, transitionDurations);\n  var animationDelays = styles[animationProp + 'Delay'].split(', ');\n  var animationDurations = styles[animationProp + 'Duration'].split(', ');\n  var animationTimeout = getTimeout(animationDelays, animationDurations);\n\n  var type;\n  var timeout = 0;\n  var propCount = 0;\n  /* istanbul ignore if */\n  if (expectedType === TRANSITION) {\n    if (transitionTimeout > 0) {\n      type = TRANSITION;\n      timeout = transitionTimeout;\n      propCount = transitionDurations.length;\n    }\n  } else if (expectedType === ANIMATION) {\n    if (animationTimeout > 0) {\n      type = ANIMATION;\n      timeout = animationTimeout;\n      propCount = animationDurations.length;\n    }\n  } else {\n    timeout = Math.max(transitionTimeout, animationTimeout);\n    type = timeout > 0\n      ? transitionTimeout > animationTimeout\n        ? TRANSITION\n        : ANIMATION\n      : null;\n    propCount = type\n      ? type === TRANSITION\n        ? transitionDurations.length\n        : animationDurations.length\n      : 0;\n  }\n  var hasTransform =\n    type === TRANSITION &&\n    transformRE.test(styles[transitionProp + 'Property']);\n  return {\n    type: type,\n    timeout: timeout,\n    propCount: propCount,\n    hasTransform: hasTransform\n  }\n}\n\nfunction getTimeout (delays, durations) {\n  return Math.max.apply(null, durations.map(function (d, i) {\n    return toMs(d) + toMs(delays[i])\n  }))\n}\n\nfunction toMs (s) {\n  return Number(s.slice(0, -1)) * 1000\n}\n\n/*  */\n\nfunction enter (vnode) {\n  var el = vnode.elm;\n\n  // call leave callback now\n  if (el._leaveCb) {\n    el._leaveCb.cancelled = true;\n    el._leaveCb();\n  }\n\n  var data = resolveTransition(vnode.data.transition);\n  if (!data) {\n    return\n  }\n\n  /* istanbul ignore if */\n  if (el._enterCb || el.nodeType !== 1) {\n    return\n  }\n\n  var css = data.css;\n  var type = data.type;\n  var enterClass = data.enterClass;\n  var enterActiveClass = data.enterActiveClass;\n  var appearClass = data.appearClass;\n  var appearActiveClass = data.appearActiveClass;\n  var beforeEnter = data.beforeEnter;\n  var enter = data.enter;\n  var afterEnter = data.afterEnter;\n  var enterCancelled = data.enterCancelled;\n  var beforeAppear = data.beforeAppear;\n  var appear = data.appear;\n  var afterAppear = data.afterAppear;\n  var appearCancelled = data.appearCancelled;\n\n  // activeInstance will always be the <transition> component managing this\n  // transition. One edge case to check is when the <transition> is placed\n  // as the root node of a child component. In that case we need to check\n  // <transition>'s parent for appear check.\n  var transitionNode = activeInstance.$vnode;\n  var context = transitionNode && transitionNode.parent\n    ? transitionNode.parent.context\n    : activeInstance;\n\n  var isAppear = !context._isMounted || !vnode.isRootInsert;\n\n  if (isAppear && !appear && appear !== '') {\n    return\n  }\n\n  var startClass = isAppear ? appearClass : enterClass;\n  var activeClass = isAppear ? appearActiveClass : enterActiveClass;\n  var beforeEnterHook = isAppear ? (beforeAppear || beforeEnter) : beforeEnter;\n  var enterHook = isAppear ? (typeof appear === 'function' ? appear : enter) : enter;\n  var afterEnterHook = isAppear ? (afterAppear || afterEnter) : afterEnter;\n  var enterCancelledHook = isAppear ? (appearCancelled || enterCancelled) : enterCancelled;\n\n  var expectsCSS = css !== false && !isIE9;\n  var userWantsControl =\n    enterHook &&\n    // enterHook may be a bound method which exposes\n    // the length of original fn as _length\n    (enterHook._length || enterHook.length) > 1;\n\n  var cb = el._enterCb = once(function () {\n    if (expectsCSS) {\n      removeTransitionClass(el, activeClass);\n    }\n    if (cb.cancelled) {\n      if (expectsCSS) {\n        removeTransitionClass(el, startClass);\n      }\n      enterCancelledHook && enterCancelledHook(el);\n    } else {\n      afterEnterHook && afterEnterHook(el);\n    }\n    el._enterCb = null;\n  });\n\n  if (!vnode.data.show) {\n    // remove pending leave element on enter by injecting an insert hook\n    mergeVNodeHook(vnode.data.hook || (vnode.data.hook = {}), 'insert', function () {\n      var parent = el.parentNode;\n      var pendingNode = parent && parent._pending && parent._pending[vnode.key];\n      if (pendingNode && pendingNode.tag === vnode.tag && pendingNode.elm._leaveCb) {\n        pendingNode.elm._leaveCb();\n      }\n      enterHook && enterHook(el, cb);\n    }, 'transition-insert');\n  }\n\n  // start enter transition\n  beforeEnterHook && beforeEnterHook(el);\n  if (expectsCSS) {\n    addTransitionClass(el, startClass);\n    addTransitionClass(el, activeClass);\n    nextFrame(function () {\n      removeTransitionClass(el, startClass);\n      if (!cb.cancelled && !userWantsControl) {\n        whenTransitionEnds(el, type, cb);\n      }\n    });\n  }\n\n  if (vnode.data.show) {\n    enterHook && enterHook(el, cb);\n  }\n\n  if (!expectsCSS && !userWantsControl) {\n    cb();\n  }\n}\n\nfunction leave (vnode, rm) {\n  var el = vnode.elm;\n\n  // call enter callback now\n  if (el._enterCb) {\n    el._enterCb.cancelled = true;\n    el._enterCb();\n  }\n\n  var data = resolveTransition(vnode.data.transition);\n  if (!data) {\n    return rm()\n  }\n\n  /* istanbul ignore if */\n  if (el._leaveCb || el.nodeType !== 1) {\n    return\n  }\n\n  var css = data.css;\n  var type = data.type;\n  var leaveClass = data.leaveClass;\n  var leaveActiveClass = data.leaveActiveClass;\n  var beforeLeave = data.beforeLeave;\n  var leave = data.leave;\n  var afterLeave = data.afterLeave;\n  var leaveCancelled = data.leaveCancelled;\n  var delayLeave = data.delayLeave;\n\n  var expectsCSS = css !== false && !isIE9;\n  var userWantsControl =\n    leave &&\n    // leave hook may be a bound method which exposes\n    // the length of original fn as _length\n    (leave._length || leave.length) > 1;\n\n  var cb = el._leaveCb = once(function () {\n    if (el.parentNode && el.parentNode._pending) {\n      el.parentNode._pending[vnode.key] = null;\n    }\n    if (expectsCSS) {\n      removeTransitionClass(el, leaveActiveClass);\n    }\n    if (cb.cancelled) {\n      if (expectsCSS) {\n        removeTransitionClass(el, leaveClass);\n      }\n      leaveCancelled && leaveCancelled(el);\n    } else {\n      rm();\n      afterLeave && afterLeave(el);\n    }\n    el._leaveCb = null;\n  });\n\n  if (delayLeave) {\n    delayLeave(performLeave);\n  } else {\n    performLeave();\n  }\n\n  function performLeave () {\n    // the delayed leave may have already been cancelled\n    if (cb.cancelled) {\n      return\n    }\n    // record leaving element\n    if (!vnode.data.show) {\n      (el.parentNode._pending || (el.parentNode._pending = {}))[vnode.key] = vnode;\n    }\n    beforeLeave && beforeLeave(el);\n    if (expectsCSS) {\n      addTransitionClass(el, leaveClass);\n      addTransitionClass(el, leaveActiveClass);\n      nextFrame(function () {\n        removeTransitionClass(el, leaveClass);\n        if (!cb.cancelled && !userWantsControl) {\n          whenTransitionEnds(el, type, cb);\n        }\n      });\n    }\n    leave && leave(el, cb);\n    if (!expectsCSS && !userWantsControl) {\n      cb();\n    }\n  }\n}\n\nfunction resolveTransition (def$$1) {\n  if (!def$$1) {\n    return\n  }\n  /* istanbul ignore else */\n  if (typeof def$$1 === 'object') {\n    var res = {};\n    if (def$$1.css !== false) {\n      extend(res, autoCssTransition(def$$1.name || 'v'));\n    }\n    extend(res, def$$1);\n    return res\n  } else if (typeof def$$1 === 'string') {\n    return autoCssTransition(def$$1)\n  }\n}\n\nvar autoCssTransition = cached(function (name) {\n  return {\n    enterClass: (name + \"-enter\"),\n    leaveClass: (name + \"-leave\"),\n    appearClass: (name + \"-enter\"),\n    enterActiveClass: (name + \"-enter-active\"),\n    leaveActiveClass: (name + \"-leave-active\"),\n    appearActiveClass: (name + \"-enter-active\")\n  }\n});\n\nfunction once (fn) {\n  var called = false;\n  return function () {\n    if (!called) {\n      called = true;\n      fn();\n    }\n  }\n}\n\nvar transition = inBrowser ? {\n  create: function create (_, vnode) {\n    if (!vnode.data.show) {\n      enter(vnode);\n    }\n  },\n  remove: function remove (vnode, rm) {\n    /* istanbul ignore else */\n    if (!vnode.data.show) {\n      leave(vnode, rm);\n    } else {\n      rm();\n    }\n  }\n} : {};\n\nvar platformModules = [\n  attrs,\n  klass,\n  events,\n  domProps,\n  style,\n  transition\n];\n\n/*  */\n\n// the directive module should be applied last, after all\n// built-in modules have been applied.\nvar modules = platformModules.concat(baseModules);\n\nvar patch$1 = createPatchFunction({ nodeOps: nodeOps, modules: modules });\n\n/**\n * Not type checking this file because flow doesn't like attaching\n * properties to Elements.\n */\n\nvar modelableTagRE = /^input|select|textarea|vue-component-[0-9]+(-[0-9a-zA-Z_\\-]*)?$/;\n\n/* istanbul ignore if */\nif (isIE9) {\n  // http://www.matts411.com/post/internet-explorer-9-oninput/\n  document.addEventListener('selectionchange', function () {\n    var el = document.activeElement;\n    if (el && el.vmodel) {\n      trigger(el, 'input');\n    }\n  });\n}\n\nvar model = {\n  inserted: function inserted (el, binding, vnode) {\n    if (process.env.NODE_ENV !== 'production') {\n      if (!modelableTagRE.test(vnode.tag)) {\n        warn(\n          \"v-model is not supported on element type: <\" + (vnode.tag) + \">. \" +\n          'If you are working with contenteditable, it\\'s recommended to ' +\n          'wrap a library dedicated for that purpose inside a custom component.',\n          vnode.context\n        );\n      }\n    }\n    if (vnode.tag === 'select') {\n      var cb = function () {\n        setSelected(el, binding, vnode.context);\n      };\n      cb();\n      /* istanbul ignore if */\n      if (isIE || isEdge) {\n        setTimeout(cb, 0);\n      }\n    } else if (\n      (vnode.tag === 'textarea' || el.type === 'text') &&\n      !binding.modifiers.lazy\n    ) {\n      if (!isAndroid) {\n        el.addEventListener('compositionstart', onCompositionStart);\n        el.addEventListener('compositionend', onCompositionEnd);\n      }\n      /* istanbul ignore if */\n      if (isIE9) {\n        el.vmodel = true;\n      }\n    }\n  },\n  componentUpdated: function componentUpdated (el, binding, vnode) {\n    if (vnode.tag === 'select') {\n      setSelected(el, binding, vnode.context);\n      // in case the options rendered by v-for have changed,\n      // it's possible that the value is out-of-sync with the rendered options.\n      // detect such cases and filter out values that no longer has a matchig\n      // option in the DOM.\n      var needReset = el.multiple\n        ? binding.value.some(function (v) { return hasNoMatchingOption(v, el.options); })\n        : binding.value !== binding.oldValue && hasNoMatchingOption(binding.value, el.options);\n      if (needReset) {\n        trigger(el, 'change');\n      }\n    }\n  }\n};\n\nfunction setSelected (el, binding, vm) {\n  var value = binding.value;\n  var isMultiple = el.multiple;\n  if (isMultiple && !Array.isArray(value)) {\n    process.env.NODE_ENV !== 'production' && warn(\n      \"<select multiple v-model=\\\"\" + (binding.expression) + \"\\\"> \" +\n      \"expects an Array value for its binding, but got \" + (Object.prototype.toString.call(value).slice(8, -1)),\n      vm\n    );\n    return\n  }\n  var selected, option;\n  for (var i = 0, l = el.options.length; i < l; i++) {\n    option = el.options[i];\n    if (isMultiple) {\n      selected = looseIndexOf(value, getValue(option)) > -1;\n      if (option.selected !== selected) {\n        option.selected = selected;\n      }\n    } else {\n      if (looseEqual(getValue(option), value)) {\n        if (el.selectedIndex !== i) {\n          el.selectedIndex = i;\n        }\n        return\n      }\n    }\n  }\n  if (!isMultiple) {\n    el.selectedIndex = -1;\n  }\n}\n\nfunction hasNoMatchingOption (value, options) {\n  for (var i = 0, l = options.length; i < l; i++) {\n    if (looseEqual(getValue(options[i]), value)) {\n      return false\n    }\n  }\n  return true\n}\n\nfunction getValue (option) {\n  return '_value' in option\n    ? option._value\n    : option.value\n}\n\nfunction onCompositionStart (e) {\n  e.target.composing = true;\n}\n\nfunction onCompositionEnd (e) {\n  e.target.composing = false;\n  trigger(e.target, 'input');\n}\n\nfunction trigger (el, type) {\n  var e = document.createEvent('HTMLEvents');\n  e.initEvent(type, true, true);\n  el.dispatchEvent(e);\n}\n\n/*  */\n\n// recursively search for possible transition defined inside the component root\nfunction locateNode (vnode) {\n  return vnode.child && (!vnode.data || !vnode.data.transition)\n    ? locateNode(vnode.child._vnode)\n    : vnode\n}\n\nvar show = {\n  bind: function bind (el, ref, vnode) {\n    var value = ref.value;\n\n    vnode = locateNode(vnode);\n    var transition = vnode.data && vnode.data.transition;\n    if (value && transition && !isIE9) {\n      enter(vnode);\n    }\n    var originalDisplay = el.style.display === 'none' ? '' : el.style.display;\n    el.style.display = value ? originalDisplay : 'none';\n    el.__vOriginalDisplay = originalDisplay;\n  },\n  update: function update (el, ref, vnode) {\n    var value = ref.value;\n    var oldValue = ref.oldValue;\n\n    /* istanbul ignore if */\n    if (value === oldValue) { return }\n    vnode = locateNode(vnode);\n    var transition = vnode.data && vnode.data.transition;\n    if (transition && !isIE9) {\n      if (value) {\n        enter(vnode);\n        el.style.display = el.__vOriginalDisplay;\n      } else {\n        leave(vnode, function () {\n          el.style.display = 'none';\n        });\n      }\n    } else {\n      el.style.display = value ? el.__vOriginalDisplay : 'none';\n    }\n  }\n};\n\nvar platformDirectives = {\n  model: model,\n  show: show\n};\n\n/*  */\n\n// Provides transition support for a single element/component.\n// supports transition mode (out-in / in-out)\n\nvar transitionProps = {\n  name: String,\n  appear: Boolean,\n  css: Boolean,\n  mode: String,\n  type: String,\n  enterClass: String,\n  leaveClass: String,\n  enterActiveClass: String,\n  leaveActiveClass: String,\n  appearClass: String,\n  appearActiveClass: String\n};\n\n// in case the child is also an abstract component, e.g. <keep-alive>\n// we want to recrusively retrieve the real component to be rendered\nfunction getRealChild (vnode) {\n  var compOptions = vnode && vnode.componentOptions;\n  if (compOptions && compOptions.Ctor.options.abstract) {\n    return getRealChild(getFirstComponentChild(compOptions.children))\n  } else {\n    return vnode\n  }\n}\n\nfunction extractTransitionData (comp) {\n  var data = {};\n  var options = comp.$options;\n  // props\n  for (var key in options.propsData) {\n    data[key] = comp[key];\n  }\n  // events.\n  // extract listeners and pass them directly to the transition methods\n  var listeners = options._parentListeners;\n  for (var key$1 in listeners) {\n    data[camelize(key$1)] = listeners[key$1].fn;\n  }\n  return data\n}\n\nfunction placeholder (h, rawChild) {\n  return /\\d-keep-alive$/.test(rawChild.tag)\n    ? h('keep-alive')\n    : null\n}\n\nfunction hasParentTransition (vnode) {\n  while ((vnode = vnode.parent)) {\n    if (vnode.data.transition) {\n      return true\n    }\n  }\n}\n\nvar Transition = {\n  name: 'transition',\n  props: transitionProps,\n  abstract: true,\n  render: function render (h) {\n    var this$1 = this;\n\n    var children = this.$slots.default;\n    if (!children) {\n      return\n    }\n\n    // filter out text nodes (possible whitespaces)\n    children = children.filter(function (c) { return c.tag; });\n    /* istanbul ignore if */\n    if (!children.length) {\n      return\n    }\n\n    // warn multiple elements\n    if (process.env.NODE_ENV !== 'production' && children.length > 1) {\n      warn(\n        '<transition> can only be used on a single element. Use ' +\n        '<transition-group> for lists.',\n        this.$parent\n      );\n    }\n\n    var mode = this.mode;\n\n    // warn invalid mode\n    if (process.env.NODE_ENV !== 'production' &&\n        mode && mode !== 'in-out' && mode !== 'out-in') {\n      warn(\n        'invalid <transition> mode: ' + mode,\n        this.$parent\n      );\n    }\n\n    var rawChild = children[0];\n\n    // if this is a component root node and the component's\n    // parent container node also has transition, skip.\n    if (hasParentTransition(this.$vnode)) {\n      return rawChild\n    }\n\n    // apply transition data to child\n    // use getRealChild() to ignore abstract components e.g. keep-alive\n    var child = getRealChild(rawChild);\n    /* istanbul ignore if */\n    if (!child) {\n      return rawChild\n    }\n\n    if (this._leaving) {\n      return placeholder(h, rawChild)\n    }\n\n    var key = child.key = child.key == null || child.isStatic\n      ? (\"__v\" + (child.tag + this._uid) + \"__\")\n      : child.key;\n    var data = (child.data || (child.data = {})).transition = extractTransitionData(this);\n    var oldRawChild = this._vnode;\n    var oldChild = getRealChild(oldRawChild);\n\n    // mark v-show\n    // so that the transition module can hand over the control to the directive\n    if (child.data.directives && child.data.directives.some(function (d) { return d.name === 'show'; })) {\n      child.data.show = true;\n    }\n\n    if (oldChild && oldChild.data && oldChild.key !== key) {\n      // replace old child transition data with fresh one\n      // important for dynamic transitions!\n      var oldData = oldChild.data.transition = extend({}, data);\n\n      // handle transition mode\n      if (mode === 'out-in') {\n        // return placeholder node and queue update when leave finishes\n        this._leaving = true;\n        mergeVNodeHook(oldData, 'afterLeave', function () {\n          this$1._leaving = false;\n          this$1.$forceUpdate();\n        }, key);\n        return placeholder(h, rawChild)\n      } else if (mode === 'in-out') {\n        var delayedLeave;\n        var performLeave = function () { delayedLeave(); };\n        mergeVNodeHook(data, 'afterEnter', performLeave, key);\n        mergeVNodeHook(data, 'enterCancelled', performLeave, key);\n        mergeVNodeHook(oldData, 'delayLeave', function (leave) {\n          delayedLeave = leave;\n        }, key);\n      }\n    }\n\n    return rawChild\n  }\n};\n\n/*  */\n\n// Provides transition support for list items.\n// supports move transitions using the FLIP technique.\n\n// Because the vdom's children update algorithm is \"unstable\" - i.e.\n// it doesn't guarantee the relative positioning of removed elements,\n// we force transition-group to update its children into two passes:\n// in the first pass, we remove all nodes that need to be removed,\n// triggering their leaving transition; in the second pass, we insert/move\n// into the final disired state. This way in the second pass removed\n// nodes will remain where they should be.\n\nvar props = extend({\n  tag: String,\n  moveClass: String\n}, transitionProps);\n\ndelete props.mode;\n\nvar TransitionGroup = {\n  props: props,\n\n  render: function render (h) {\n    var tag = this.tag || this.$vnode.data.tag || 'span';\n    var map = Object.create(null);\n    var prevChildren = this.prevChildren = this.children;\n    var rawChildren = this.$slots.default || [];\n    var children = this.children = [];\n    var transitionData = extractTransitionData(this);\n\n    for (var i = 0; i < rawChildren.length; i++) {\n      var c = rawChildren[i];\n      if (c.tag) {\n        if (c.key != null && String(c.key).indexOf('__vlist') !== 0) {\n          children.push(c);\n          map[c.key] = c\n          ;(c.data || (c.data = {})).transition = transitionData;\n        } else if (process.env.NODE_ENV !== 'production') {\n          var opts = c.componentOptions;\n          var name = opts\n            ? (opts.Ctor.options.name || opts.tag)\n            : c.tag;\n          warn((\"<transition-group> children must be keyed: <\" + name + \">\"));\n        }\n      }\n    }\n\n    if (prevChildren) {\n      var kept = [];\n      var removed = [];\n      for (var i$1 = 0; i$1 < prevChildren.length; i$1++) {\n        var c$1 = prevChildren[i$1];\n        c$1.data.transition = transitionData;\n        c$1.data.pos = c$1.elm.getBoundingClientRect();\n        if (map[c$1.key]) {\n          kept.push(c$1);\n        } else {\n          removed.push(c$1);\n        }\n      }\n      this.kept = h(tag, null, kept);\n      this.removed = removed;\n    }\n\n    return h(tag, null, children)\n  },\n\n  beforeUpdate: function beforeUpdate () {\n    // force removing pass\n    this.__patch__(\n      this._vnode,\n      this.kept,\n      false, // hydrating\n      true // removeOnly (!important, avoids unnecessary moves)\n    );\n    this._vnode = this.kept;\n  },\n\n  updated: function updated () {\n    var children = this.prevChildren;\n    var moveClass = this.moveClass || (this.name + '-move');\n    if (!children.length || !this.hasMove(children[0].elm, moveClass)) {\n      return\n    }\n\n    // we divide the work into three loops to avoid mixing DOM reads and writes\n    // in each iteration - which helps prevent layout thrashing.\n    children.forEach(callPendingCbs);\n    children.forEach(recordPosition);\n    children.forEach(applyTranslation);\n\n    // force reflow to put everything in position\n    var f = document.body.offsetHeight; // eslint-disable-line\n\n    children.forEach(function (c) {\n      if (c.data.moved) {\n        var el = c.elm;\n        var s = el.style;\n        addTransitionClass(el, moveClass);\n        s.transform = s.WebkitTransform = s.transitionDuration = '';\n        el.addEventListener(transitionEndEvent, el._moveCb = function cb (e) {\n          if (!e || /transform$/.test(e.propertyName)) {\n            el.removeEventListener(transitionEndEvent, cb);\n            el._moveCb = null;\n            removeTransitionClass(el, moveClass);\n          }\n        });\n      }\n    });\n  },\n\n  methods: {\n    hasMove: function hasMove (el, moveClass) {\n      /* istanbul ignore if */\n      if (!hasTransition) {\n        return false\n      }\n      if (this._hasMove != null) {\n        return this._hasMove\n      }\n      addTransitionClass(el, moveClass);\n      var info = getTransitionInfo(el);\n      removeTransitionClass(el, moveClass);\n      return (this._hasMove = info.hasTransform)\n    }\n  }\n};\n\nfunction callPendingCbs (c) {\n  /* istanbul ignore if */\n  if (c.elm._moveCb) {\n    c.elm._moveCb();\n  }\n  /* istanbul ignore if */\n  if (c.elm._enterCb) {\n    c.elm._enterCb();\n  }\n}\n\nfunction recordPosition (c) {\n  c.data.newPos = c.elm.getBoundingClientRect();\n}\n\nfunction applyTranslation (c) {\n  var oldPos = c.data.pos;\n  var newPos = c.data.newPos;\n  var dx = oldPos.left - newPos.left;\n  var dy = oldPos.top - newPos.top;\n  if (dx || dy) {\n    c.data.moved = true;\n    var s = c.elm.style;\n    s.transform = s.WebkitTransform = \"translate(\" + dx + \"px,\" + dy + \"px)\";\n    s.transitionDuration = '0s';\n  }\n}\n\nvar platformComponents = {\n  Transition: Transition,\n  TransitionGroup: TransitionGroup\n};\n\n/*  */\n\n// install platform specific utils\nVue$2.config.isUnknownElement = isUnknownElement;\nVue$2.config.isReservedTag = isReservedTag;\nVue$2.config.getTagNamespace = getTagNamespace;\nVue$2.config.mustUseProp = mustUseProp;\n\n// install platform runtime directives & components\nextend(Vue$2.options.directives, platformDirectives);\nextend(Vue$2.options.components, platformComponents);\n\n// install platform patch function\nVue$2.prototype.__patch__ = config._isServer ? noop : patch$1;\n\n// wrap mount\nVue$2.prototype.$mount = function (\n  el,\n  hydrating\n) {\n  el = el && !config._isServer ? query(el) : undefined;\n  return this._mount(el, hydrating)\n};\n\n// devtools global hook\n/* istanbul ignore next */\nsetTimeout(function () {\n  if (config.devtools) {\n    if (devtools) {\n      devtools.emit('init', Vue$2);\n    } else if (\n      process.env.NODE_ENV !== 'production' &&\n      inBrowser && /Chrome\\/\\d+/.test(window.navigator.userAgent)\n    ) {\n      console.log(\n        'Download the Vue Devtools for a better development experience:\\n' +\n        'https://github.com/vuejs/vue-devtools'\n      );\n    }\n  }\n}, 0);\n\nmodule.exports = Vue$2;\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(31)))\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L3Z1ZS9kaXN0L3Z1ZS5jb21tb24uanM/ZTg4MSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixpQkFBaUI7QUFDbEM7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLCtCQUErQjtBQUNyRCxzQkFBc0IsaUJBQWlCO0FBQ3ZDOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrREFBa0QsaUNBQWlDLEVBQUU7QUFDckYsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixnQkFBZ0I7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixjQUFjOztBQUVwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsZ0JBQWdCO0FBQ2pDLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EscUJBQXFCLHFCQUFxQjtBQUMxQyxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLGtCQUFrQjtBQUNwQztBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCLGNBQWM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyxPQUFPO0FBQ3pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsbUJBQW1CLDhCQUE4QjtBQUNqRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLG9CQUFvQixFQUFFOztBQUVwRDtBQUNBO0FBQ0EsaUJBQWlCLHNCQUFzQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQix3QkFBd0I7QUFDM0MsS0FBSztBQUNMO0FBQ0E7QUFDQSxtQkFBbUIsOEJBQThCO0FBQ2pEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsMkJBQTJCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxDQUFDOztBQUVEOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGlCQUFpQjtBQUNsQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsT0FBTztBQUMxQztBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLE9BQU87QUFDekM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUErQyxPQUFPO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsaUJBQWlCO0FBQ3BDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLG9CQUFvQjtBQUMzQztBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUIsbUJBQW1CO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSwyREFBMkQ7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSx1QkFBdUIsZ0JBQWdCLE9BQU8saUJBQWlCO0FBQy9EO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxtQkFBbUIsZ0JBQWdCO0FBQ25DO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxPQUFPO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELE9BQU87QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLG1EQUFtRCxnQ0FBZ0MsRUFBRTtBQUNyRjs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIscUJBQXFCO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLE9BQU87QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxhQUFhO0FBQ2I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixnQ0FBZ0M7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQix3Q0FBd0M7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQztBQUNyQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLE9BQU87QUFDOUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIseUJBQXlCO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLG1CQUFtQjtBQUNuQixtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLFNBQVM7QUFDVCxrQ0FBa0MsVUFBVTtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixpQkFBaUI7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsK0JBQStCLFVBQVU7QUFDekM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsT0FBTztBQUN4QztBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0Esa0NBQWtDLE9BQU87QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBLG9EQUFvRDtBQUNwRCw4Q0FBOEM7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLE9BQU87QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlEQUFpRDtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsT0FBTztBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQixtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEIsbUJBQW1CO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckIsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDQUE0QyxPQUFPO0FBQ25EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsMkJBQTJCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyxTQUFTO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLGFBQWEsRUFBRTtBQUM3QjtBQUNBO0FBQ0EsY0FBYyxhQUFhLEVBQUU7QUFDN0IsNkJBQTZCLDRCQUE0QixFQUFFO0FBQzNEO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLGVBQWU7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLG9CQUFvQix5QkFBeUI7QUFDN0MsQ0FBQzs7QUFFRDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsT0FBTztBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixrQkFBa0I7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHFCQUFxQiw2QkFBNkI7QUFDbEQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQix1QkFBdUI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsNkRBQTZEO0FBQzdELEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyREFBMkQ7QUFDM0Q7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsaUJBQWlCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRFQUE0RTtBQUM1RTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0M7QUFDeEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQztBQUMzQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLHFCQUFxQjtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDO0FBQ3hDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsNEJBQTRCLEVBQUU7QUFDM0UsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsK0JBQStCLEVBQUU7QUFDOUUsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLDJEQUEyRDtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkRBQTZEO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBLG1DQUFtQyxxQ0FBcUM7O0FBRXhFO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLDJDQUEyQyxFQUFFO0FBQ3hGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxPQUFPO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQ0FBcUMsT0FBTztBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2Q0FBNkMsY0FBYyxFQUFFO0FBQzdEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEM7QUFDOUM7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMEVBQTBFLDBCQUEwQixFQUFFO0FBQ3RHO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0RBQXdEOztBQUV4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLE9BQU87QUFDUDtBQUNBLHdDQUF3QyxnQkFBZ0I7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QztBQUN2QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsd0JBQXdCO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHVCQUF1QjtBQUNsQyxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsMkJBQTJCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdUNBQXVDOztBQUV2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0wsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsImZpbGUiOiIxMi5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qIVxuICogVnVlLmpzIHYyLjAuM1xuICogKGMpIDIwMTQtMjAxNiBFdmFuIFlvdVxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbi8qICAqL1xuXG4vKipcbiAqIENvbnZlcnQgYSB2YWx1ZSB0byBhIHN0cmluZyB0aGF0IGlzIGFjdHVhbGx5IHJlbmRlcmVkLlxuICovXG5mdW5jdGlvbiBfdG9TdHJpbmcgKHZhbCkge1xuICByZXR1cm4gdmFsID09IG51bGxcbiAgICA/ICcnXG4gICAgOiB0eXBlb2YgdmFsID09PSAnb2JqZWN0J1xuICAgICAgPyBKU09OLnN0cmluZ2lmeSh2YWwsIG51bGwsIDIpXG4gICAgICA6IFN0cmluZyh2YWwpXG59XG5cbi8qKlxuICogQ29udmVydCBhIGlucHV0IHZhbHVlIHRvIGEgbnVtYmVyIGZvciBwZXJzaXN0ZW5jZS5cbiAqIElmIHRoZSBjb252ZXJzaW9uIGZhaWxzLCByZXR1cm4gb3JpZ2luYWwgc3RyaW5nLlxuICovXG5mdW5jdGlvbiB0b051bWJlciAodmFsKSB7XG4gIHZhciBuID0gcGFyc2VGbG9hdCh2YWwsIDEwKTtcbiAgcmV0dXJuIChuIHx8IG4gPT09IDApID8gbiA6IHZhbFxufVxuXG4vKipcbiAqIE1ha2UgYSBtYXAgYW5kIHJldHVybiBhIGZ1bmN0aW9uIGZvciBjaGVja2luZyBpZiBhIGtleVxuICogaXMgaW4gdGhhdCBtYXAuXG4gKi9cbmZ1bmN0aW9uIG1ha2VNYXAgKFxuICBzdHIsXG4gIGV4cGVjdHNMb3dlckNhc2Vcbikge1xuICB2YXIgbWFwID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgdmFyIGxpc3QgPSBzdHIuc3BsaXQoJywnKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgbWFwW2xpc3RbaV1dID0gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZXhwZWN0c0xvd2VyQ2FzZVxuICAgID8gZnVuY3Rpb24gKHZhbCkgeyByZXR1cm4gbWFwW3ZhbC50b0xvd2VyQ2FzZSgpXTsgfVxuICAgIDogZnVuY3Rpb24gKHZhbCkgeyByZXR1cm4gbWFwW3ZhbF07IH1cbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhIHRhZyBpcyBhIGJ1aWx0LWluIHRhZy5cbiAqL1xudmFyIGlzQnVpbHRJblRhZyA9IG1ha2VNYXAoJ3Nsb3QsY29tcG9uZW50JywgdHJ1ZSk7XG5cbi8qKlxuICogUmVtb3ZlIGFuIGl0ZW0gZnJvbSBhbiBhcnJheVxuICovXG5mdW5jdGlvbiByZW1vdmUkMSAoYXJyLCBpdGVtKSB7XG4gIGlmIChhcnIubGVuZ3RoKSB7XG4gICAgdmFyIGluZGV4ID0gYXJyLmluZGV4T2YoaXRlbSk7XG4gICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgIHJldHVybiBhcnIuc3BsaWNlKGluZGV4LCAxKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgdGhlIG9iamVjdCBoYXMgdGhlIHByb3BlcnR5LlxuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuZnVuY3Rpb24gaGFzT3duIChvYmosIGtleSkge1xuICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSlcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB2YWx1ZSBpcyBwcmltaXRpdmVcbiAqL1xuZnVuY3Rpb24gaXNQcmltaXRpdmUgKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcidcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBjYWNoZWQgdmVyc2lvbiBvZiBhIHB1cmUgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNhY2hlZCAoZm4pIHtcbiAgdmFyIGNhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIGNhY2hlZEZuIChzdHIpIHtcbiAgICB2YXIgaGl0ID0gY2FjaGVbc3RyXTtcbiAgICByZXR1cm4gaGl0IHx8IChjYWNoZVtzdHJdID0gZm4oc3RyKSlcbiAgfVxufVxuXG4vKipcbiAqIENhbWVsaXplIGEgaHlwaGVuLWRlbG1pdGVkIHN0cmluZy5cbiAqL1xudmFyIGNhbWVsaXplUkUgPSAvLShcXHcpL2c7XG52YXIgY2FtZWxpemUgPSBjYWNoZWQoZnVuY3Rpb24gKHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoY2FtZWxpemVSRSwgZnVuY3Rpb24gKF8sIGMpIHsgcmV0dXJuIGMgPyBjLnRvVXBwZXJDYXNlKCkgOiAnJzsgfSlcbn0pO1xuXG4vKipcbiAqIENhcGl0YWxpemUgYSBzdHJpbmcuXG4gKi9cbnZhciBjYXBpdGFsaXplID0gY2FjaGVkKGZ1bmN0aW9uIChzdHIpIHtcbiAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKVxufSk7XG5cbi8qKlxuICogSHlwaGVuYXRlIGEgY2FtZWxDYXNlIHN0cmluZy5cbiAqL1xudmFyIGh5cGhlbmF0ZVJFID0gLyhbXi1dKShbQS1aXSkvZztcbnZhciBoeXBoZW5hdGUgPSBjYWNoZWQoZnVuY3Rpb24gKHN0cikge1xuICByZXR1cm4gc3RyXG4gICAgLnJlcGxhY2UoaHlwaGVuYXRlUkUsICckMS0kMicpXG4gICAgLnJlcGxhY2UoaHlwaGVuYXRlUkUsICckMS0kMicpXG4gICAgLnRvTG93ZXJDYXNlKClcbn0pO1xuXG4vKipcbiAqIFNpbXBsZSBiaW5kLCBmYXN0ZXIgdGhhbiBuYXRpdmVcbiAqL1xuZnVuY3Rpb24gYmluZCQxIChmbiwgY3R4KSB7XG4gIGZ1bmN0aW9uIGJvdW5kRm4gKGEpIHtcbiAgICB2YXIgbCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgcmV0dXJuIGxcbiAgICAgID8gbCA+IDFcbiAgICAgICAgPyBmbi5hcHBseShjdHgsIGFyZ3VtZW50cylcbiAgICAgICAgOiBmbi5jYWxsKGN0eCwgYSlcbiAgICAgIDogZm4uY2FsbChjdHgpXG4gIH1cbiAgLy8gcmVjb3JkIG9yaWdpbmFsIGZuIGxlbmd0aFxuICBib3VuZEZuLl9sZW5ndGggPSBmbi5sZW5ndGg7XG4gIHJldHVybiBib3VuZEZuXG59XG5cbi8qKlxuICogQ29udmVydCBhbiBBcnJheS1saWtlIG9iamVjdCB0byBhIHJlYWwgQXJyYXkuXG4gKi9cbmZ1bmN0aW9uIHRvQXJyYXkgKGxpc3QsIHN0YXJ0KSB7XG4gIHN0YXJ0ID0gc3RhcnQgfHwgMDtcbiAgdmFyIGkgPSBsaXN0Lmxlbmd0aCAtIHN0YXJ0O1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGkpO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgcmV0W2ldID0gbGlzdFtpICsgc3RhcnRdO1xuICB9XG4gIHJldHVybiByZXRcbn1cblxuLyoqXG4gKiBNaXggcHJvcGVydGllcyBpbnRvIHRhcmdldCBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGV4dGVuZCAodG8sIF9mcm9tKSB7XG4gIGZvciAodmFyIGtleSBpbiBfZnJvbSkge1xuICAgIHRvW2tleV0gPSBfZnJvbVtrZXldO1xuICB9XG4gIHJldHVybiB0b1xufVxuXG4vKipcbiAqIFF1aWNrIG9iamVjdCBjaGVjayAtIHRoaXMgaXMgcHJpbWFyaWx5IHVzZWQgdG8gdGVsbFxuICogT2JqZWN0cyBmcm9tIHByaW1pdGl2ZSB2YWx1ZXMgd2hlbiB3ZSBrbm93IHRoZSB2YWx1ZVxuICogaXMgYSBKU09OLWNvbXBsaWFudCB0eXBlLlxuICovXG5mdW5jdGlvbiBpc09iamVjdCAob2JqKSB7XG4gIHJldHVybiBvYmogIT09IG51bGwgJiYgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCdcbn1cblxuLyoqXG4gKiBTdHJpY3Qgb2JqZWN0IHR5cGUgY2hlY2suIE9ubHkgcmV0dXJucyB0cnVlXG4gKiBmb3IgcGxhaW4gSmF2YVNjcmlwdCBvYmplY3RzLlxuICovXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIE9CSkVDVF9TVFJJTkcgPSAnW29iamVjdCBPYmplY3RdJztcbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3QgKG9iaikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChvYmopID09PSBPQkpFQ1RfU1RSSU5HXG59XG5cbi8qKlxuICogTWVyZ2UgYW4gQXJyYXkgb2YgT2JqZWN0cyBpbnRvIGEgc2luZ2xlIE9iamVjdC5cbiAqL1xuZnVuY3Rpb24gdG9PYmplY3QgKGFycikge1xuICB2YXIgcmVzID0ge307XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGFycltpXSkge1xuICAgICAgZXh0ZW5kKHJlcywgYXJyW2ldKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG4vKipcbiAqIFBlcmZvcm0gbm8gb3BlcmF0aW9uLlxuICovXG5mdW5jdGlvbiBub29wICgpIHt9XG5cbi8qKlxuICogQWx3YXlzIHJldHVybiBmYWxzZS5cbiAqL1xudmFyIG5vID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gZmFsc2U7IH07XG5cbi8qKlxuICogR2VuZXJhdGUgYSBzdGF0aWMga2V5cyBzdHJpbmcgZnJvbSBjb21waWxlciBtb2R1bGVzLlxuICovXG5mdW5jdGlvbiBnZW5TdGF0aWNLZXlzIChtb2R1bGVzKSB7XG4gIHJldHVybiBtb2R1bGVzLnJlZHVjZShmdW5jdGlvbiAoa2V5cywgbSkge1xuICAgIHJldHVybiBrZXlzLmNvbmNhdChtLnN0YXRpY0tleXMgfHwgW10pXG4gIH0sIFtdKS5qb2luKCcsJylcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB0d28gdmFsdWVzIGFyZSBsb29zZWx5IGVxdWFsIC0gdGhhdCBpcyxcbiAqIGlmIHRoZXkgYXJlIHBsYWluIG9iamVjdHMsIGRvIHRoZXkgaGF2ZSB0aGUgc2FtZSBzaGFwZT9cbiAqL1xuZnVuY3Rpb24gbG9vc2VFcXVhbCAoYSwgYikge1xuICAvKiBlc2xpbnQtZGlzYWJsZSBlcWVxZXEgKi9cbiAgcmV0dXJuIGEgPT0gYiB8fCAoXG4gICAgaXNPYmplY3QoYSkgJiYgaXNPYmplY3QoYilcbiAgICAgID8gSlNPTi5zdHJpbmdpZnkoYSkgPT09IEpTT04uc3RyaW5naWZ5KGIpXG4gICAgICA6IGZhbHNlXG4gIClcbiAgLyogZXNsaW50LWVuYWJsZSBlcWVxZXEgKi9cbn1cblxuZnVuY3Rpb24gbG9vc2VJbmRleE9mIChhcnIsIHZhbCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGlmIChsb29zZUVxdWFsKGFycltpXSwgdmFsKSkgeyByZXR1cm4gaSB9XG4gIH1cbiAgcmV0dXJuIC0xXG59XG5cbi8qICAqL1xuXG52YXIgY29uZmlnID0ge1xuICAvKipcbiAgICogT3B0aW9uIG1lcmdlIHN0cmF0ZWdpZXMgKHVzZWQgaW4gY29yZS91dGlsL29wdGlvbnMpXG4gICAqL1xuICBvcHRpb25NZXJnZVN0cmF0ZWdpZXM6IE9iamVjdC5jcmVhdGUobnVsbCksXG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gc3VwcHJlc3Mgd2FybmluZ3MuXG4gICAqL1xuICBzaWxlbnQ6IGZhbHNlLFxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGVuYWJsZSBkZXZ0b29sc1xuICAgKi9cbiAgZGV2dG9vbHM6IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicsXG5cbiAgLyoqXG4gICAqIEVycm9yIGhhbmRsZXIgZm9yIHdhdGNoZXIgZXJyb3JzXG4gICAqL1xuICBlcnJvckhhbmRsZXI6IG51bGwsXG5cbiAgLyoqXG4gICAqIElnbm9yZSBjZXJ0YWluIGN1c3RvbSBlbGVtZW50c1xuICAgKi9cbiAgaWdub3JlZEVsZW1lbnRzOiBudWxsLFxuXG4gIC8qKlxuICAgKiBDdXN0b20gdXNlciBrZXkgYWxpYXNlcyBmb3Igdi1vblxuICAgKi9cbiAga2V5Q29kZXM6IE9iamVjdC5jcmVhdGUobnVsbCksXG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgdGFnIGlzIHJlc2VydmVkIHNvIHRoYXQgaXQgY2Fubm90IGJlIHJlZ2lzdGVyZWQgYXMgYVxuICAgKiBjb21wb25lbnQuIFRoaXMgaXMgcGxhdGZvcm0tZGVwZW5kZW50IGFuZCBtYXkgYmUgb3ZlcndyaXR0ZW4uXG4gICAqL1xuICBpc1Jlc2VydmVkVGFnOiBubyxcblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSB0YWcgaXMgYW4gdW5rbm93biBlbGVtZW50LlxuICAgKiBQbGF0Zm9ybS1kZXBlbmRlbnQuXG4gICAqL1xuICBpc1Vua25vd25FbGVtZW50OiBubyxcblxuICAvKipcbiAgICogR2V0IHRoZSBuYW1lc3BhY2Ugb2YgYW4gZWxlbWVudFxuICAgKi9cbiAgZ2V0VGFnTmFtZXNwYWNlOiBub29wLFxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhbiBhdHRyaWJ1dGUgbXVzdCBiZSBib3VuZCB1c2luZyBwcm9wZXJ0eSwgZS5nLiB2YWx1ZVxuICAgKiBQbGF0Zm9ybS1kZXBlbmRlbnQuXG4gICAqL1xuICBtdXN0VXNlUHJvcDogbm8sXG5cbiAgLyoqXG4gICAqIExpc3Qgb2YgYXNzZXQgdHlwZXMgdGhhdCBhIGNvbXBvbmVudCBjYW4gb3duLlxuICAgKi9cbiAgX2Fzc2V0VHlwZXM6IFtcbiAgICAnY29tcG9uZW50JyxcbiAgICAnZGlyZWN0aXZlJyxcbiAgICAnZmlsdGVyJ1xuICBdLFxuXG4gIC8qKlxuICAgKiBMaXN0IG9mIGxpZmVjeWNsZSBob29rcy5cbiAgICovXG4gIF9saWZlY3ljbGVIb29rczogW1xuICAgICdiZWZvcmVDcmVhdGUnLFxuICAgICdjcmVhdGVkJyxcbiAgICAnYmVmb3JlTW91bnQnLFxuICAgICdtb3VudGVkJyxcbiAgICAnYmVmb3JlVXBkYXRlJyxcbiAgICAndXBkYXRlZCcsXG4gICAgJ2JlZm9yZURlc3Ryb3knLFxuICAgICdkZXN0cm95ZWQnLFxuICAgICdhY3RpdmF0ZWQnLFxuICAgICdkZWFjdGl2YXRlZCdcbiAgXSxcblxuICAvKipcbiAgICogTWF4IGNpcmN1bGFyIHVwZGF0ZXMgYWxsb3dlZCBpbiBhIHNjaGVkdWxlciBmbHVzaCBjeWNsZS5cbiAgICovXG4gIF9tYXhVcGRhdGVDb3VudDogMTAwLFxuXG4gIC8qKlxuICAgKiBTZXJ2ZXIgcmVuZGVyaW5nP1xuICAgKi9cbiAgX2lzU2VydmVyOiBwcm9jZXNzLmVudi5WVUVfRU5WID09PSAnc2VydmVyJ1xufTtcblxuLyogICovXG5cbi8qKlxuICogQ2hlY2sgaWYgYSBzdHJpbmcgc3RhcnRzIHdpdGggJCBvciBfXG4gKi9cbmZ1bmN0aW9uIGlzUmVzZXJ2ZWQgKHN0cikge1xuICB2YXIgYyA9IChzdHIgKyAnJykuY2hhckNvZGVBdCgwKTtcbiAgcmV0dXJuIGMgPT09IDB4MjQgfHwgYyA9PT0gMHg1RlxufVxuXG4vKipcbiAqIERlZmluZSBhIHByb3BlcnR5LlxuICovXG5mdW5jdGlvbiBkZWYgKG9iaiwga2V5LCB2YWwsIGVudW1lcmFibGUpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7XG4gICAgdmFsdWU6IHZhbCxcbiAgICBlbnVtZXJhYmxlOiAhIWVudW1lcmFibGUsXG4gICAgd3JpdGFibGU6IHRydWUsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xufVxuXG4vKipcbiAqIFBhcnNlIHNpbXBsZSBwYXRoLlxuICovXG52YXIgYmFpbFJFID0gL1teXFx3XFwuXFwkXS87XG5mdW5jdGlvbiBwYXJzZVBhdGggKHBhdGgpIHtcbiAgaWYgKGJhaWxSRS50ZXN0KHBhdGgpKSB7XG4gICAgcmV0dXJuXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNlZ21lbnRzID0gcGF0aC5zcGxpdCgnLicpO1xuICAgIHJldHVybiBmdW5jdGlvbiAob2JqKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICghb2JqKSB7IHJldHVybiB9XG4gICAgICAgIG9iaiA9IG9ialtzZWdtZW50c1tpXV07XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqXG4gICAgfVxuICB9XG59XG5cbi8qICAqL1xuLyogZ2xvYmFscyBNdXRhdGlvbk9ic2VydmVyICovXG5cbi8vIGNhbiB3ZSB1c2UgX19wcm90b19fP1xudmFyIGhhc1Byb3RvID0gJ19fcHJvdG9fXycgaW4ge307XG5cbi8vIEJyb3dzZXIgZW52aXJvbm1lbnQgc25pZmZpbmdcbnZhciBpbkJyb3dzZXIgPVxuICB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJlxuICBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwod2luZG93KSAhPT0gJ1tvYmplY3QgT2JqZWN0XSc7XG5cbnZhciBVQSA9IGluQnJvd3NlciAmJiB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpO1xudmFyIGlzSUUgPSBVQSAmJiAvbXNpZXx0cmlkZW50Ly50ZXN0KFVBKTtcbnZhciBpc0lFOSA9IFVBICYmIFVBLmluZGV4T2YoJ21zaWUgOS4wJykgPiAwO1xudmFyIGlzRWRnZSA9IFVBICYmIFVBLmluZGV4T2YoJ2VkZ2UvJykgPiAwO1xudmFyIGlzQW5kcm9pZCA9IFVBICYmIFVBLmluZGV4T2YoJ2FuZHJvaWQnKSA+IDA7XG52YXIgaXNJT1MgPSBVQSAmJiAvaXBob25lfGlwYWR8aXBvZHxpb3MvLnRlc3QoVUEpO1xuXG4vLyBkZXRlY3QgZGV2dG9vbHNcbnZhciBkZXZ0b29scyA9IGluQnJvd3NlciAmJiB3aW5kb3cuX19WVUVfREVWVE9PTFNfR0xPQkFMX0hPT0tfXztcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIGlzTmF0aXZlIChDdG9yKSB7XG4gIHJldHVybiAvbmF0aXZlIGNvZGUvLnRlc3QoQ3Rvci50b1N0cmluZygpKVxufVxuXG4vKipcbiAqIERlZmVyIGEgdGFzayB0byBleGVjdXRlIGl0IGFzeW5jaHJvbm91c2x5LlxuICovXG52YXIgbmV4dFRpY2sgPSAoZnVuY3Rpb24gKCkge1xuICB2YXIgY2FsbGJhY2tzID0gW107XG4gIHZhciBwZW5kaW5nID0gZmFsc2U7XG4gIHZhciB0aW1lckZ1bmM7XG5cbiAgZnVuY3Rpb24gbmV4dFRpY2tIYW5kbGVyICgpIHtcbiAgICBwZW5kaW5nID0gZmFsc2U7XG4gICAgdmFyIGNvcGllcyA9IGNhbGxiYWNrcy5zbGljZSgwKTtcbiAgICBjYWxsYmFja3MubGVuZ3RoID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvcGllcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29waWVzW2ldKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gdGhlIG5leHRUaWNrIGJlaGF2aW9yIGxldmVyYWdlcyB0aGUgbWljcm90YXNrIHF1ZXVlLCB3aGljaCBjYW4gYmUgYWNjZXNzZWRcbiAgLy8gdmlhIGVpdGhlciBuYXRpdmUgUHJvbWlzZS50aGVuIG9yIE11dGF0aW9uT2JzZXJ2ZXIuXG4gIC8vIE11dGF0aW9uT2JzZXJ2ZXIgaGFzIHdpZGVyIHN1cHBvcnQsIGhvd2V2ZXIgaXQgaXMgc2VyaW91c2x5IGJ1Z2dlZCBpblxuICAvLyBVSVdlYlZpZXcgaW4gaU9TID49IDkuMy4zIHdoZW4gdHJpZ2dlcmVkIGluIHRvdWNoIGV2ZW50IGhhbmRsZXJzLiBJdFxuICAvLyBjb21wbGV0ZWx5IHN0b3BzIHdvcmtpbmcgYWZ0ZXIgdHJpZ2dlcmluZyBhIGZldyB0aW1lcy4uLiBzbywgaWYgbmF0aXZlXG4gIC8vIFByb21pc2UgaXMgYXZhaWxhYmxlLCB3ZSB3aWxsIHVzZSBpdDpcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmICh0eXBlb2YgUHJvbWlzZSAhPT0gJ3VuZGVmaW5lZCcgJiYgaXNOYXRpdmUoUHJvbWlzZSkpIHtcbiAgICB2YXIgcCA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIHRpbWVyRnVuYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHAudGhlbihuZXh0VGlja0hhbmRsZXIpO1xuICAgICAgLy8gaW4gcHJvYmxlbWF0aWMgVUlXZWJWaWV3cywgUHJvbWlzZS50aGVuIGRvZXNuJ3QgY29tcGxldGVseSBicmVhaywgYnV0XG4gICAgICAvLyBpdCBjYW4gZ2V0IHN0dWNrIGluIGEgd2VpcmQgc3RhdGUgd2hlcmUgY2FsbGJhY2tzIGFyZSBwdXNoZWQgaW50byB0aGVcbiAgICAgIC8vIG1pY3JvdGFzayBxdWV1ZSBidXQgdGhlIHF1ZXVlIGlzbid0IGJlaW5nIGZsdXNoZWQsIHVudGlsIHRoZSBicm93c2VyXG4gICAgICAvLyBuZWVkcyB0byBkbyBzb21lIG90aGVyIHdvcmssIGUuZy4gaGFuZGxlIGEgdGltZXIuIFRoZXJlZm9yZSB3ZSBjYW5cbiAgICAgIC8vIFwiZm9yY2VcIiB0aGUgbWljcm90YXNrIHF1ZXVlIHRvIGJlIGZsdXNoZWQgYnkgYWRkaW5nIGFuIGVtcHR5IHRpbWVyLlxuICAgICAgaWYgKGlzSU9TKSB7IHNldFRpbWVvdXQobm9vcCk7IH1cbiAgICB9O1xuICB9IGVsc2UgaWYgKHR5cGVvZiBNdXRhdGlvbk9ic2VydmVyICE9PSAndW5kZWZpbmVkJyAmJiAoXG4gICAgaXNOYXRpdmUoTXV0YXRpb25PYnNlcnZlcikgfHxcbiAgICAvLyBQaGFudG9tSlMgYW5kIGlPUyA3LnhcbiAgICBNdXRhdGlvbk9ic2VydmVyLnRvU3RyaW5nKCkgPT09ICdbb2JqZWN0IE11dGF0aW9uT2JzZXJ2ZXJDb25zdHJ1Y3Rvcl0nXG4gICkpIHtcbiAgICAvLyB1c2UgTXV0YXRpb25PYnNlcnZlciB3aGVyZSBuYXRpdmUgUHJvbWlzZSBpcyBub3QgYXZhaWxhYmxlLFxuICAgIC8vIGUuZy4gUGhhbnRvbUpTIElFMTEsIGlPUzcsIEFuZHJvaWQgNC40XG4gICAgdmFyIGNvdW50ZXIgPSAxO1xuICAgIHZhciBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKG5leHRUaWNrSGFuZGxlcik7XG4gICAgdmFyIHRleHROb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoU3RyaW5nKGNvdW50ZXIpKTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKHRleHROb2RlLCB7XG4gICAgICBjaGFyYWN0ZXJEYXRhOiB0cnVlXG4gICAgfSk7XG4gICAgdGltZXJGdW5jID0gZnVuY3Rpb24gKCkge1xuICAgICAgY291bnRlciA9IChjb3VudGVyICsgMSkgJSAyO1xuICAgICAgdGV4dE5vZGUuZGF0YSA9IFN0cmluZyhjb3VudGVyKTtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIC8vIGZhbGxiYWNrIHRvIHNldFRpbWVvdXRcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIHRpbWVyRnVuYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHNldFRpbWVvdXQobmV4dFRpY2tIYW5kbGVyLCAwKTtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIHF1ZXVlTmV4dFRpY2sgKGNiLCBjdHgpIHtcbiAgICB2YXIgZnVuYyA9IGN0eFxuICAgICAgPyBmdW5jdGlvbiAoKSB7IGNiLmNhbGwoY3R4KTsgfVxuICAgICAgOiBjYjtcbiAgICBjYWxsYmFja3MucHVzaChmdW5jKTtcbiAgICBpZiAoIXBlbmRpbmcpIHtcbiAgICAgIHBlbmRpbmcgPSB0cnVlO1xuICAgICAgdGltZXJGdW5jKCk7XG4gICAgfVxuICB9XG59KSgpO1xuXG52YXIgX1NldDtcbi8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuaWYgKHR5cGVvZiBTZXQgIT09ICd1bmRlZmluZWQnICYmIGlzTmF0aXZlKFNldCkpIHtcbiAgLy8gdXNlIG5hdGl2ZSBTZXQgd2hlbiBhdmFpbGFibGUuXG4gIF9TZXQgPSBTZXQ7XG59IGVsc2Uge1xuICAvLyBhIG5vbi1zdGFuZGFyZCBTZXQgcG9seWZpbGwgdGhhdCBvbmx5IHdvcmtzIHdpdGggcHJpbWl0aXZlIGtleXMuXG4gIF9TZXQgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFNldCAoKSB7XG4gICAgICB0aGlzLnNldCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgfVxuICAgIFNldC5wcm90b3R5cGUuaGFzID0gZnVuY3Rpb24gaGFzIChrZXkpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldFtrZXldICE9PSB1bmRlZmluZWRcbiAgICB9O1xuICAgIFNldC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkIChrZXkpIHtcbiAgICAgIHRoaXMuc2V0W2tleV0gPSAxO1xuICAgIH07XG4gICAgU2V0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uIGNsZWFyICgpIHtcbiAgICAgIHRoaXMuc2V0ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFNldDtcbiAgfSgpKTtcbn1cblxuLyogbm90IHR5cGUgY2hlY2tpbmcgdGhpcyBmaWxlIGJlY2F1c2UgZmxvdyBkb2Vzbid0IHBsYXkgd2VsbCB3aXRoIFByb3h5ICovXG5cbnZhciBoYXNQcm94eTtcbnZhciBwcm94eUhhbmRsZXJzO1xudmFyIGluaXRQcm94eTtcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgdmFyIGFsbG93ZWRHbG9iYWxzID0gbWFrZU1hcChcbiAgICAnSW5maW5pdHksdW5kZWZpbmVkLE5hTixpc0Zpbml0ZSxpc05hTiwnICtcbiAgICAncGFyc2VGbG9hdCxwYXJzZUludCxkZWNvZGVVUkksZGVjb2RlVVJJQ29tcG9uZW50LGVuY29kZVVSSSxlbmNvZGVVUklDb21wb25lbnQsJyArXG4gICAgJ01hdGgsTnVtYmVyLERhdGUsQXJyYXksT2JqZWN0LEJvb2xlYW4sU3RyaW5nLFJlZ0V4cCxNYXAsU2V0LEpTT04sSW50bCwnICtcbiAgICAncmVxdWlyZScgLy8gZm9yIFdlYnBhY2svQnJvd3NlcmlmeVxuICApO1xuXG4gIGhhc1Byb3h5ID1cbiAgICB0eXBlb2YgUHJveHkgIT09ICd1bmRlZmluZWQnICYmXG4gICAgUHJveHkudG9TdHJpbmcoKS5tYXRjaCgvbmF0aXZlIGNvZGUvKTtcblxuICBwcm94eUhhbmRsZXJzID0ge1xuICAgIGhhczogZnVuY3Rpb24gaGFzICh0YXJnZXQsIGtleSkge1xuICAgICAgdmFyIGhhcyA9IGtleSBpbiB0YXJnZXQ7XG4gICAgICB2YXIgaXNBbGxvd2VkID0gYWxsb3dlZEdsb2JhbHMoa2V5KSB8fCBrZXkuY2hhckF0KDApID09PSAnXyc7XG4gICAgICBpZiAoIWhhcyAmJiAhaXNBbGxvd2VkKSB7XG4gICAgICAgIHdhcm4oXG4gICAgICAgICAgXCJQcm9wZXJ0eSBvciBtZXRob2QgXFxcIlwiICsga2V5ICsgXCJcXFwiIGlzIG5vdCBkZWZpbmVkIG9uIHRoZSBpbnN0YW5jZSBidXQgXCIgK1xuICAgICAgICAgIFwicmVmZXJlbmNlZCBkdXJpbmcgcmVuZGVyLiBNYWtlIHN1cmUgdG8gZGVjbGFyZSByZWFjdGl2ZSBkYXRhIFwiICtcbiAgICAgICAgICBcInByb3BlcnRpZXMgaW4gdGhlIGRhdGEgb3B0aW9uLlwiLFxuICAgICAgICAgIHRhcmdldFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhcyB8fCAhaXNBbGxvd2VkXG4gICAgfVxuICB9O1xuXG4gIGluaXRQcm94eSA9IGZ1bmN0aW9uIGluaXRQcm94eSAodm0pIHtcbiAgICBpZiAoaGFzUHJveHkpIHtcbiAgICAgIHZtLl9yZW5kZXJQcm94eSA9IG5ldyBQcm94eSh2bSwgcHJveHlIYW5kbGVycyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZtLl9yZW5kZXJQcm94eSA9IHZtO1xuICAgIH1cbiAgfTtcbn1cblxuLyogICovXG5cblxudmFyIHVpZCQyID0gMDtcblxuLyoqXG4gKiBBIGRlcCBpcyBhbiBvYnNlcnZhYmxlIHRoYXQgY2FuIGhhdmUgbXVsdGlwbGVcbiAqIGRpcmVjdGl2ZXMgc3Vic2NyaWJpbmcgdG8gaXQuXG4gKi9cbnZhciBEZXAgPSBmdW5jdGlvbiBEZXAgKCkge1xuICB0aGlzLmlkID0gdWlkJDIrKztcbiAgdGhpcy5zdWJzID0gW107XG59O1xuXG5EZXAucHJvdG90eXBlLmFkZFN1YiA9IGZ1bmN0aW9uIGFkZFN1YiAoc3ViKSB7XG4gIHRoaXMuc3Vicy5wdXNoKHN1Yik7XG59O1xuXG5EZXAucHJvdG90eXBlLnJlbW92ZVN1YiA9IGZ1bmN0aW9uIHJlbW92ZVN1YiAoc3ViKSB7XG4gIHJlbW92ZSQxKHRoaXMuc3Vicywgc3ViKTtcbn07XG5cbkRlcC5wcm90b3R5cGUuZGVwZW5kID0gZnVuY3Rpb24gZGVwZW5kICgpIHtcbiAgaWYgKERlcC50YXJnZXQpIHtcbiAgICBEZXAudGFyZ2V0LmFkZERlcCh0aGlzKTtcbiAgfVxufTtcblxuRGVwLnByb3RvdHlwZS5ub3RpZnkgPSBmdW5jdGlvbiBub3RpZnkgKCkge1xuICAvLyBzdGFibGl6ZSB0aGUgc3Vic2NyaWJlciBsaXN0IGZpcnN0XG4gIHZhciBzdWJzID0gdGhpcy5zdWJzLnNsaWNlKCk7XG4gIGZvciAodmFyIGkgPSAwLCBsID0gc3Vicy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBzdWJzW2ldLnVwZGF0ZSgpO1xuICB9XG59O1xuXG4vLyB0aGUgY3VycmVudCB0YXJnZXQgd2F0Y2hlciBiZWluZyBldmFsdWF0ZWQuXG4vLyB0aGlzIGlzIGdsb2JhbGx5IHVuaXF1ZSBiZWNhdXNlIHRoZXJlIGNvdWxkIGJlIG9ubHkgb25lXG4vLyB3YXRjaGVyIGJlaW5nIGV2YWx1YXRlZCBhdCBhbnkgdGltZS5cbkRlcC50YXJnZXQgPSBudWxsO1xudmFyIHRhcmdldFN0YWNrID0gW107XG5cbmZ1bmN0aW9uIHB1c2hUYXJnZXQgKF90YXJnZXQpIHtcbiAgaWYgKERlcC50YXJnZXQpIHsgdGFyZ2V0U3RhY2sucHVzaChEZXAudGFyZ2V0KTsgfVxuICBEZXAudGFyZ2V0ID0gX3RhcmdldDtcbn1cblxuZnVuY3Rpb24gcG9wVGFyZ2V0ICgpIHtcbiAgRGVwLnRhcmdldCA9IHRhcmdldFN0YWNrLnBvcCgpO1xufVxuXG4vKiAgKi9cblxuXG52YXIgcXVldWUgPSBbXTtcbnZhciBoYXMkMSA9IHt9O1xudmFyIGNpcmN1bGFyID0ge307XG52YXIgd2FpdGluZyA9IGZhbHNlO1xudmFyIGZsdXNoaW5nID0gZmFsc2U7XG52YXIgaW5kZXggPSAwO1xuXG4vKipcbiAqIFJlc2V0IHRoZSBzY2hlZHVsZXIncyBzdGF0ZS5cbiAqL1xuZnVuY3Rpb24gcmVzZXRTY2hlZHVsZXJTdGF0ZSAoKSB7XG4gIHF1ZXVlLmxlbmd0aCA9IDA7XG4gIGhhcyQxID0ge307XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgY2lyY3VsYXIgPSB7fTtcbiAgfVxuICB3YWl0aW5nID0gZmx1c2hpbmcgPSBmYWxzZTtcbn1cblxuLyoqXG4gKiBGbHVzaCBib3RoIHF1ZXVlcyBhbmQgcnVuIHRoZSB3YXRjaGVycy5cbiAqL1xuZnVuY3Rpb24gZmx1c2hTY2hlZHVsZXJRdWV1ZSAoKSB7XG4gIGZsdXNoaW5nID0gdHJ1ZTtcblxuICAvLyBTb3J0IHF1ZXVlIGJlZm9yZSBmbHVzaC5cbiAgLy8gVGhpcyBlbnN1cmVzIHRoYXQ6XG4gIC8vIDEuIENvbXBvbmVudHMgYXJlIHVwZGF0ZWQgZnJvbSBwYXJlbnQgdG8gY2hpbGQuIChiZWNhdXNlIHBhcmVudCBpcyBhbHdheXNcbiAgLy8gICAgY3JlYXRlZCBiZWZvcmUgdGhlIGNoaWxkKVxuICAvLyAyLiBBIGNvbXBvbmVudCdzIHVzZXIgd2F0Y2hlcnMgYXJlIHJ1biBiZWZvcmUgaXRzIHJlbmRlciB3YXRjaGVyIChiZWNhdXNlXG4gIC8vICAgIHVzZXIgd2F0Y2hlcnMgYXJlIGNyZWF0ZWQgYmVmb3JlIHRoZSByZW5kZXIgd2F0Y2hlcilcbiAgLy8gMy4gSWYgYSBjb21wb25lbnQgaXMgZGVzdHJveWVkIGR1cmluZyBhIHBhcmVudCBjb21wb25lbnQncyB3YXRjaGVyIHJ1bixcbiAgLy8gICAgaXRzIHdhdGNoZXJzIGNhbiBiZSBza2lwcGVkLlxuICBxdWV1ZS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhLmlkIC0gYi5pZDsgfSk7XG5cbiAgLy8gZG8gbm90IGNhY2hlIGxlbmd0aCBiZWNhdXNlIG1vcmUgd2F0Y2hlcnMgbWlnaHQgYmUgcHVzaGVkXG4gIC8vIGFzIHdlIHJ1biBleGlzdGluZyB3YXRjaGVyc1xuICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBxdWV1ZS5sZW5ndGg7IGluZGV4KyspIHtcbiAgICB2YXIgd2F0Y2hlciA9IHF1ZXVlW2luZGV4XTtcbiAgICB2YXIgaWQgPSB3YXRjaGVyLmlkO1xuICAgIGhhcyQxW2lkXSA9IG51bGw7XG4gICAgd2F0Y2hlci5ydW4oKTtcbiAgICAvLyBpbiBkZXYgYnVpbGQsIGNoZWNrIGFuZCBzdG9wIGNpcmN1bGFyIHVwZGF0ZXMuXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgaGFzJDFbaWRdICE9IG51bGwpIHtcbiAgICAgIGNpcmN1bGFyW2lkXSA9IChjaXJjdWxhcltpZF0gfHwgMCkgKyAxO1xuICAgICAgaWYgKGNpcmN1bGFyW2lkXSA+IGNvbmZpZy5fbWF4VXBkYXRlQ291bnQpIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICAnWW91IG1heSBoYXZlIGFuIGluZmluaXRlIHVwZGF0ZSBsb29wICcgKyAoXG4gICAgICAgICAgICB3YXRjaGVyLnVzZXJcbiAgICAgICAgICAgICAgPyAoXCJpbiB3YXRjaGVyIHdpdGggZXhwcmVzc2lvbiBcXFwiXCIgKyAod2F0Y2hlci5leHByZXNzaW9uKSArIFwiXFxcIlwiKVxuICAgICAgICAgICAgICA6IFwiaW4gYSBjb21wb25lbnQgcmVuZGVyIGZ1bmN0aW9uLlwiXG4gICAgICAgICAgKSxcbiAgICAgICAgICB3YXRjaGVyLnZtXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gZGV2dG9vbCBob29rXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoZGV2dG9vbHMgJiYgY29uZmlnLmRldnRvb2xzKSB7XG4gICAgZGV2dG9vbHMuZW1pdCgnZmx1c2gnKTtcbiAgfVxuXG4gIHJlc2V0U2NoZWR1bGVyU3RhdGUoKTtcbn1cblxuLyoqXG4gKiBQdXNoIGEgd2F0Y2hlciBpbnRvIHRoZSB3YXRjaGVyIHF1ZXVlLlxuICogSm9icyB3aXRoIGR1cGxpY2F0ZSBJRHMgd2lsbCBiZSBza2lwcGVkIHVubGVzcyBpdCdzXG4gKiBwdXNoZWQgd2hlbiB0aGUgcXVldWUgaXMgYmVpbmcgZmx1c2hlZC5cbiAqL1xuZnVuY3Rpb24gcXVldWVXYXRjaGVyICh3YXRjaGVyKSB7XG4gIHZhciBpZCA9IHdhdGNoZXIuaWQ7XG4gIGlmIChoYXMkMVtpZF0gPT0gbnVsbCkge1xuICAgIGhhcyQxW2lkXSA9IHRydWU7XG4gICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgcXVldWUucHVzaCh3YXRjaGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaWYgYWxyZWFkeSBmbHVzaGluZywgc3BsaWNlIHRoZSB3YXRjaGVyIGJhc2VkIG9uIGl0cyBpZFxuICAgICAgLy8gaWYgYWxyZWFkeSBwYXN0IGl0cyBpZCwgaXQgd2lsbCBiZSBydW4gbmV4dCBpbW1lZGlhdGVseS5cbiAgICAgIHZhciBpID0gcXVldWUubGVuZ3RoIC0gMTtcbiAgICAgIHdoaWxlIChpID49IDAgJiYgcXVldWVbaV0uaWQgPiB3YXRjaGVyLmlkKSB7XG4gICAgICAgIGktLTtcbiAgICAgIH1cbiAgICAgIHF1ZXVlLnNwbGljZShNYXRoLm1heChpLCBpbmRleCkgKyAxLCAwLCB3YXRjaGVyKTtcbiAgICB9XG4gICAgLy8gcXVldWUgdGhlIGZsdXNoXG4gICAgaWYgKCF3YWl0aW5nKSB7XG4gICAgICB3YWl0aW5nID0gdHJ1ZTtcbiAgICAgIG5leHRUaWNrKGZsdXNoU2NoZWR1bGVyUXVldWUpO1xuICAgIH1cbiAgfVxufVxuXG4vKiAgKi9cblxudmFyIHVpZCQxID0gMDtcblxuLyoqXG4gKiBBIHdhdGNoZXIgcGFyc2VzIGFuIGV4cHJlc3Npb24sIGNvbGxlY3RzIGRlcGVuZGVuY2llcyxcbiAqIGFuZCBmaXJlcyBjYWxsYmFjayB3aGVuIHRoZSBleHByZXNzaW9uIHZhbHVlIGNoYW5nZXMuXG4gKiBUaGlzIGlzIHVzZWQgZm9yIGJvdGggdGhlICR3YXRjaCgpIGFwaSBhbmQgZGlyZWN0aXZlcy5cbiAqL1xudmFyIFdhdGNoZXIgPSBmdW5jdGlvbiBXYXRjaGVyIChcbiAgdm0sXG4gIGV4cE9yRm4sXG4gIGNiLFxuICBvcHRpb25zXG4pIHtcbiAgaWYgKCBvcHRpb25zID09PSB2b2lkIDAgKSBvcHRpb25zID0ge307XG5cbiAgdGhpcy52bSA9IHZtO1xuICB2bS5fd2F0Y2hlcnMucHVzaCh0aGlzKTtcbiAgLy8gb3B0aW9uc1xuICB0aGlzLmRlZXAgPSAhIW9wdGlvbnMuZGVlcDtcbiAgdGhpcy51c2VyID0gISFvcHRpb25zLnVzZXI7XG4gIHRoaXMubGF6eSA9ICEhb3B0aW9ucy5sYXp5O1xuICB0aGlzLnN5bmMgPSAhIW9wdGlvbnMuc3luYztcbiAgdGhpcy5leHByZXNzaW9uID0gZXhwT3JGbi50b1N0cmluZygpO1xuICB0aGlzLmNiID0gY2I7XG4gIHRoaXMuaWQgPSArK3VpZCQxOyAvLyB1aWQgZm9yIGJhdGNoaW5nXG4gIHRoaXMuYWN0aXZlID0gdHJ1ZTtcbiAgdGhpcy5kaXJ0eSA9IHRoaXMubGF6eTsgLy8gZm9yIGxhenkgd2F0Y2hlcnNcbiAgdGhpcy5kZXBzID0gW107XG4gIHRoaXMubmV3RGVwcyA9IFtdO1xuICB0aGlzLmRlcElkcyA9IG5ldyBfU2V0KCk7XG4gIHRoaXMubmV3RGVwSWRzID0gbmV3IF9TZXQoKTtcbiAgLy8gcGFyc2UgZXhwcmVzc2lvbiBmb3IgZ2V0dGVyXG4gIGlmICh0eXBlb2YgZXhwT3JGbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMuZ2V0dGVyID0gZXhwT3JGbjtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmdldHRlciA9IHBhcnNlUGF0aChleHBPckZuKTtcbiAgICBpZiAoIXRoaXMuZ2V0dGVyKSB7XG4gICAgICB0aGlzLmdldHRlciA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKFxuICAgICAgICBcIkZhaWxlZCB3YXRjaGluZyBwYXRoOiBcXFwiXCIgKyBleHBPckZuICsgXCJcXFwiIFwiICtcbiAgICAgICAgJ1dhdGNoZXIgb25seSBhY2NlcHRzIHNpbXBsZSBkb3QtZGVsaW1pdGVkIHBhdGhzLiAnICtcbiAgICAgICAgJ0ZvciBmdWxsIGNvbnRyb2wsIHVzZSBhIGZ1bmN0aW9uIGluc3RlYWQuJyxcbiAgICAgICAgdm1cbiAgICAgICk7XG4gICAgfVxuICB9XG4gIHRoaXMudmFsdWUgPSB0aGlzLmxhenlcbiAgICA/IHVuZGVmaW5lZFxuICAgIDogdGhpcy5nZXQoKTtcbn07XG5cbi8qKlxuICogRXZhbHVhdGUgdGhlIGdldHRlciwgYW5kIHJlLWNvbGxlY3QgZGVwZW5kZW5jaWVzLlxuICovXG5XYXRjaGVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiBnZXQgKCkge1xuICBwdXNoVGFyZ2V0KHRoaXMpO1xuICB2YXIgdmFsdWUgPSB0aGlzLmdldHRlci5jYWxsKHRoaXMudm0sIHRoaXMudm0pO1xuICAvLyBcInRvdWNoXCIgZXZlcnkgcHJvcGVydHkgc28gdGhleSBhcmUgYWxsIHRyYWNrZWQgYXNcbiAgLy8gZGVwZW5kZW5jaWVzIGZvciBkZWVwIHdhdGNoaW5nXG4gIGlmICh0aGlzLmRlZXApIHtcbiAgICB0cmF2ZXJzZSh2YWx1ZSk7XG4gIH1cbiAgcG9wVGFyZ2V0KCk7XG4gIHRoaXMuY2xlYW51cERlcHMoKTtcbiAgcmV0dXJuIHZhbHVlXG59O1xuXG4vKipcbiAqIEFkZCBhIGRlcGVuZGVuY3kgdG8gdGhpcyBkaXJlY3RpdmUuXG4gKi9cbldhdGNoZXIucHJvdG90eXBlLmFkZERlcCA9IGZ1bmN0aW9uIGFkZERlcCAoZGVwKSB7XG4gIHZhciBpZCA9IGRlcC5pZDtcbiAgaWYgKCF0aGlzLm5ld0RlcElkcy5oYXMoaWQpKSB7XG4gICAgdGhpcy5uZXdEZXBJZHMuYWRkKGlkKTtcbiAgICB0aGlzLm5ld0RlcHMucHVzaChkZXApO1xuICAgIGlmICghdGhpcy5kZXBJZHMuaGFzKGlkKSkge1xuICAgICAgZGVwLmFkZFN1Yih0aGlzKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogQ2xlYW4gdXAgZm9yIGRlcGVuZGVuY3kgY29sbGVjdGlvbi5cbiAqL1xuV2F0Y2hlci5wcm90b3R5cGUuY2xlYW51cERlcHMgPSBmdW5jdGlvbiBjbGVhbnVwRGVwcyAoKSB7XG4gICAgdmFyIHRoaXMkMSA9IHRoaXM7XG5cbiAgdmFyIGkgPSB0aGlzLmRlcHMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgdmFyIGRlcCA9IHRoaXMkMS5kZXBzW2ldO1xuICAgIGlmICghdGhpcyQxLm5ld0RlcElkcy5oYXMoZGVwLmlkKSkge1xuICAgICAgZGVwLnJlbW92ZVN1Yih0aGlzJDEpO1xuICAgIH1cbiAgfVxuICB2YXIgdG1wID0gdGhpcy5kZXBJZHM7XG4gIHRoaXMuZGVwSWRzID0gdGhpcy5uZXdEZXBJZHM7XG4gIHRoaXMubmV3RGVwSWRzID0gdG1wO1xuICB0aGlzLm5ld0RlcElkcy5jbGVhcigpO1xuICB0bXAgPSB0aGlzLmRlcHM7XG4gIHRoaXMuZGVwcyA9IHRoaXMubmV3RGVwcztcbiAgdGhpcy5uZXdEZXBzID0gdG1wO1xuICB0aGlzLm5ld0RlcHMubGVuZ3RoID0gMDtcbn07XG5cbi8qKlxuICogU3Vic2NyaWJlciBpbnRlcmZhY2UuXG4gKiBXaWxsIGJlIGNhbGxlZCB3aGVuIGEgZGVwZW5kZW5jeSBjaGFuZ2VzLlxuICovXG5XYXRjaGVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUgKCkge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICBpZiAodGhpcy5sYXp5KSB7XG4gICAgdGhpcy5kaXJ0eSA9IHRydWU7XG4gIH0gZWxzZSBpZiAodGhpcy5zeW5jKSB7XG4gICAgdGhpcy5ydW4oKTtcbiAgfSBlbHNlIHtcbiAgICBxdWV1ZVdhdGNoZXIodGhpcyk7XG4gIH1cbn07XG5cbi8qKlxuICogU2NoZWR1bGVyIGpvYiBpbnRlcmZhY2UuXG4gKiBXaWxsIGJlIGNhbGxlZCBieSB0aGUgc2NoZWR1bGVyLlxuICovXG5XYXRjaGVyLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiBydW4gKCkge1xuICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLmdldCgpO1xuICAgICAgaWYgKFxuICAgICAgICB2YWx1ZSAhPT0gdGhpcy52YWx1ZSB8fFxuICAgICAgLy8gRGVlcCB3YXRjaGVycyBhbmQgd2F0Y2hlcnMgb24gT2JqZWN0L0FycmF5cyBzaG91bGQgZmlyZSBldmVuXG4gICAgICAvLyB3aGVuIHRoZSB2YWx1ZSBpcyB0aGUgc2FtZSwgYmVjYXVzZSB0aGUgdmFsdWUgbWF5XG4gICAgICAvLyBoYXZlIG11dGF0ZWQuXG4gICAgICBpc09iamVjdCh2YWx1ZSkgfHxcbiAgICAgIHRoaXMuZGVlcFxuICAgICkge1xuICAgICAgLy8gc2V0IG5ldyB2YWx1ZVxuICAgICAgdmFyIG9sZFZhbHVlID0gdGhpcy52YWx1ZTtcbiAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgIGlmICh0aGlzLnVzZXIpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLmNiLmNhbGwodGhpcy52bSwgdmFsdWUsIG9sZFZhbHVlKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybihcbiAgICAgICAgICAgIChcIkVycm9yIGluIHdhdGNoZXIgXFxcIlwiICsgKHRoaXMuZXhwcmVzc2lvbikgKyBcIlxcXCJcIiksXG4gICAgICAgICAgICB0aGlzLnZtXG4gICAgICAgICAgKTtcbiAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgICAgIGlmIChjb25maWcuZXJyb3JIYW5kbGVyKSB7XG4gICAgICAgICAgICBjb25maWcuZXJyb3JIYW5kbGVyLmNhbGwobnVsbCwgZSwgdGhpcy52bSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGVcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY2IuY2FsbCh0aGlzLnZtLCB2YWx1ZSwgb2xkVmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBFdmFsdWF0ZSB0aGUgdmFsdWUgb2YgdGhlIHdhdGNoZXIuXG4gKiBUaGlzIG9ubHkgZ2V0cyBjYWxsZWQgZm9yIGxhenkgd2F0Y2hlcnMuXG4gKi9cbldhdGNoZXIucHJvdG90eXBlLmV2YWx1YXRlID0gZnVuY3Rpb24gZXZhbHVhdGUgKCkge1xuICB0aGlzLnZhbHVlID0gdGhpcy5nZXQoKTtcbiAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xufTtcblxuLyoqXG4gKiBEZXBlbmQgb24gYWxsIGRlcHMgY29sbGVjdGVkIGJ5IHRoaXMgd2F0Y2hlci5cbiAqL1xuV2F0Y2hlci5wcm90b3R5cGUuZGVwZW5kID0gZnVuY3Rpb24gZGVwZW5kICgpIHtcbiAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuICB2YXIgaSA9IHRoaXMuZGVwcy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICB0aGlzJDEuZGVwc1tpXS5kZXBlbmQoKTtcbiAgfVxufTtcblxuLyoqXG4gKiBSZW1vdmUgc2VsZiBmcm9tIGFsbCBkZXBlbmRlbmNpZXMnIHN1YmNyaWJlciBsaXN0LlxuICovXG5XYXRjaGVyLnByb3RvdHlwZS50ZWFyZG93biA9IGZ1bmN0aW9uIHRlYXJkb3duICgpIHtcbiAgICB2YXIgdGhpcyQxID0gdGhpcztcblxuICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAvLyByZW1vdmUgc2VsZiBmcm9tIHZtJ3Mgd2F0Y2hlciBsaXN0XG4gICAgLy8gdGhpcyBpcyBhIHNvbWV3aGF0IGV4cGVuc2l2ZSBvcGVyYXRpb24gc28gd2Ugc2tpcCBpdFxuICAgIC8vIGlmIHRoZSB2bSBpcyBiZWluZyBkZXN0cm95ZWQgb3IgaXMgcGVyZm9ybWluZyBhIHYtZm9yXG4gICAgLy8gcmUtcmVuZGVyICh0aGUgd2F0Y2hlciBsaXN0IGlzIHRoZW4gZmlsdGVyZWQgYnkgdi1mb3IpLlxuICAgIGlmICghdGhpcy52bS5faXNCZWluZ0Rlc3Ryb3llZCAmJiAhdGhpcy52bS5fdkZvclJlbW92aW5nKSB7XG4gICAgICByZW1vdmUkMSh0aGlzLnZtLl93YXRjaGVycywgdGhpcyk7XG4gICAgfVxuICAgIHZhciBpID0gdGhpcy5kZXBzLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICB0aGlzJDEuZGVwc1tpXS5yZW1vdmVTdWIodGhpcyQxKTtcbiAgICB9XG4gICAgdGhpcy5hY3RpdmUgPSBmYWxzZTtcbiAgfVxufTtcblxuLyoqXG4gKiBSZWN1cnNpdmVseSB0cmF2ZXJzZSBhbiBvYmplY3QgdG8gZXZva2UgYWxsIGNvbnZlcnRlZFxuICogZ2V0dGVycywgc28gdGhhdCBldmVyeSBuZXN0ZWQgcHJvcGVydHkgaW5zaWRlIHRoZSBvYmplY3RcbiAqIGlzIGNvbGxlY3RlZCBhcyBhIFwiZGVlcFwiIGRlcGVuZGVuY3kuXG4gKi9cbnZhciBzZWVuT2JqZWN0cyA9IG5ldyBfU2V0KCk7XG5mdW5jdGlvbiB0cmF2ZXJzZSAodmFsLCBzZWVuKSB7XG4gIHZhciBpLCBrZXlzO1xuICBpZiAoIXNlZW4pIHtcbiAgICBzZWVuID0gc2Vlbk9iamVjdHM7XG4gICAgc2Vlbi5jbGVhcigpO1xuICB9XG4gIHZhciBpc0EgPSBBcnJheS5pc0FycmF5KHZhbCk7XG4gIHZhciBpc08gPSBpc09iamVjdCh2YWwpO1xuICBpZiAoKGlzQSB8fCBpc08pICYmIE9iamVjdC5pc0V4dGVuc2libGUodmFsKSkge1xuICAgIGlmICh2YWwuX19vYl9fKSB7XG4gICAgICB2YXIgZGVwSWQgPSB2YWwuX19vYl9fLmRlcC5pZDtcbiAgICAgIGlmIChzZWVuLmhhcyhkZXBJZCkpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZWVuLmFkZChkZXBJZCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpc0EpIHtcbiAgICAgIGkgPSB2YWwubGVuZ3RoO1xuICAgICAgd2hpbGUgKGktLSkgeyB0cmF2ZXJzZSh2YWxbaV0sIHNlZW4pOyB9XG4gICAgfSBlbHNlIGlmIChpc08pIHtcbiAgICAgIGtleXMgPSBPYmplY3Qua2V5cyh2YWwpO1xuICAgICAgaSA9IGtleXMubGVuZ3RoO1xuICAgICAgd2hpbGUgKGktLSkgeyB0cmF2ZXJzZSh2YWxba2V5c1tpXV0sIHNlZW4pOyB9XG4gICAgfVxuICB9XG59XG5cbi8qXG4gKiBub3QgdHlwZSBjaGVja2luZyB0aGlzIGZpbGUgYmVjYXVzZSBmbG93IGRvZXNuJ3QgcGxheSB3ZWxsIHdpdGhcbiAqIGR5bmFtaWNhbGx5IGFjY2Vzc2luZyBtZXRob2RzIG9uIEFycmF5IHByb3RvdHlwZVxuICovXG5cbnZhciBhcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlO1xudmFyIGFycmF5TWV0aG9kcyA9IE9iamVjdC5jcmVhdGUoYXJyYXlQcm90byk7W1xuICAncHVzaCcsXG4gICdwb3AnLFxuICAnc2hpZnQnLFxuICAndW5zaGlmdCcsXG4gICdzcGxpY2UnLFxuICAnc29ydCcsXG4gICdyZXZlcnNlJ1xuXVxuLmZvckVhY2goZnVuY3Rpb24gKG1ldGhvZCkge1xuICAvLyBjYWNoZSBvcmlnaW5hbCBtZXRob2RcbiAgdmFyIG9yaWdpbmFsID0gYXJyYXlQcm90b1ttZXRob2RdO1xuICBkZWYoYXJyYXlNZXRob2RzLCBtZXRob2QsIGZ1bmN0aW9uIG11dGF0b3IgKCkge1xuICAgIHZhciBhcmd1bWVudHMkMSA9IGFyZ3VtZW50cztcblxuICAgIC8vIGF2b2lkIGxlYWtpbmcgYXJndW1lbnRzOlxuICAgIC8vIGh0dHA6Ly9qc3BlcmYuY29tL2Nsb3N1cmUtd2l0aC1hcmd1bWVudHNcbiAgICB2YXIgaSA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoaSk7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50cyQxW2ldO1xuICAgIH1cbiAgICB2YXIgcmVzdWx0ID0gb3JpZ2luYWwuYXBwbHkodGhpcywgYXJncyk7XG4gICAgdmFyIG9iID0gdGhpcy5fX29iX187XG4gICAgdmFyIGluc2VydGVkO1xuICAgIHN3aXRjaCAobWV0aG9kKSB7XG4gICAgICBjYXNlICdwdXNoJzpcbiAgICAgICAgaW5zZXJ0ZWQgPSBhcmdzO1xuICAgICAgICBicmVha1xuICAgICAgY2FzZSAndW5zaGlmdCc6XG4gICAgICAgIGluc2VydGVkID0gYXJncztcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ3NwbGljZSc6XG4gICAgICAgIGluc2VydGVkID0gYXJncy5zbGljZSgyKTtcbiAgICAgICAgYnJlYWtcbiAgICB9XG4gICAgaWYgKGluc2VydGVkKSB7IG9iLm9ic2VydmVBcnJheShpbnNlcnRlZCk7IH1cbiAgICAvLyBub3RpZnkgY2hhbmdlXG4gICAgb2IuZGVwLm5vdGlmeSgpO1xuICAgIHJldHVybiByZXN1bHRcbiAgfSk7XG59KTtcblxuLyogICovXG5cbnZhciBhcnJheUtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhhcnJheU1ldGhvZHMpO1xuXG4vKipcbiAqIEJ5IGRlZmF1bHQsIHdoZW4gYSByZWFjdGl2ZSBwcm9wZXJ0eSBpcyBzZXQsIHRoZSBuZXcgdmFsdWUgaXNcbiAqIGFsc28gY29udmVydGVkIHRvIGJlY29tZSByZWFjdGl2ZS4gSG93ZXZlciB3aGVuIHBhc3NpbmcgZG93biBwcm9wcyxcbiAqIHdlIGRvbid0IHdhbnQgdG8gZm9yY2UgY29udmVyc2lvbiBiZWNhdXNlIHRoZSB2YWx1ZSBtYXkgYmUgYSBuZXN0ZWQgdmFsdWVcbiAqIHVuZGVyIGEgZnJvemVuIGRhdGEgc3RydWN0dXJlLiBDb252ZXJ0aW5nIGl0IHdvdWxkIGRlZmVhdCB0aGUgb3B0aW1pemF0aW9uLlxuICovXG52YXIgb2JzZXJ2ZXJTdGF0ZSA9IHtcbiAgc2hvdWxkQ29udmVydDogdHJ1ZSxcbiAgaXNTZXR0aW5nUHJvcHM6IGZhbHNlXG59O1xuXG4vKipcbiAqIE9ic2VydmVyIGNsYXNzIHRoYXQgYXJlIGF0dGFjaGVkIHRvIGVhY2ggb2JzZXJ2ZWRcbiAqIG9iamVjdC4gT25jZSBhdHRhY2hlZCwgdGhlIG9ic2VydmVyIGNvbnZlcnRzIHRhcmdldFxuICogb2JqZWN0J3MgcHJvcGVydHkga2V5cyBpbnRvIGdldHRlci9zZXR0ZXJzIHRoYXRcbiAqIGNvbGxlY3QgZGVwZW5kZW5jaWVzIGFuZCBkaXNwYXRjaGVzIHVwZGF0ZXMuXG4gKi9cbnZhciBPYnNlcnZlciA9IGZ1bmN0aW9uIE9ic2VydmVyICh2YWx1ZSkge1xuICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gIHRoaXMuZGVwID0gbmV3IERlcCgpO1xuICB0aGlzLnZtQ291bnQgPSAwO1xuICBkZWYodmFsdWUsICdfX29iX18nLCB0aGlzKTtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgdmFyIGF1Z21lbnQgPSBoYXNQcm90b1xuICAgICAgPyBwcm90b0F1Z21lbnRcbiAgICAgIDogY29weUF1Z21lbnQ7XG4gICAgYXVnbWVudCh2YWx1ZSwgYXJyYXlNZXRob2RzLCBhcnJheUtleXMpO1xuICAgIHRoaXMub2JzZXJ2ZUFycmF5KHZhbHVlKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLndhbGsodmFsdWUpO1xuICB9XG59O1xuXG4vKipcbiAqIFdhbGsgdGhyb3VnaCBlYWNoIHByb3BlcnR5IGFuZCBjb252ZXJ0IHRoZW0gaW50b1xuICogZ2V0dGVyL3NldHRlcnMuIFRoaXMgbWV0aG9kIHNob3VsZCBvbmx5IGJlIGNhbGxlZCB3aGVuXG4gKiB2YWx1ZSB0eXBlIGlzIE9iamVjdC5cbiAqL1xuT2JzZXJ2ZXIucHJvdG90eXBlLndhbGsgPSBmdW5jdGlvbiB3YWxrIChvYmopIHtcbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICBkZWZpbmVSZWFjdGl2ZSQkMShvYmosIGtleXNbaV0sIG9ialtrZXlzW2ldXSk7XG4gIH1cbn07XG5cbi8qKlxuICogT2JzZXJ2ZSBhIGxpc3Qgb2YgQXJyYXkgaXRlbXMuXG4gKi9cbk9ic2VydmVyLnByb3RvdHlwZS5vYnNlcnZlQXJyYXkgPSBmdW5jdGlvbiBvYnNlcnZlQXJyYXkgKGl0ZW1zKSB7XG4gIGZvciAodmFyIGkgPSAwLCBsID0gaXRlbXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgb2JzZXJ2ZShpdGVtc1tpXSk7XG4gIH1cbn07XG5cbi8vIGhlbHBlcnNcblxuLyoqXG4gKiBBdWdtZW50IGFuIHRhcmdldCBPYmplY3Qgb3IgQXJyYXkgYnkgaW50ZXJjZXB0aW5nXG4gKiB0aGUgcHJvdG90eXBlIGNoYWluIHVzaW5nIF9fcHJvdG9fX1xuICovXG5mdW5jdGlvbiBwcm90b0F1Z21lbnQgKHRhcmdldCwgc3JjKSB7XG4gIC8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG4gIHRhcmdldC5fX3Byb3RvX18gPSBzcmM7XG4gIC8qIGVzbGludC1lbmFibGUgbm8tcHJvdG8gKi9cbn1cblxuLyoqXG4gKiBBdWdtZW50IGFuIHRhcmdldCBPYmplY3Qgb3IgQXJyYXkgYnkgZGVmaW5pbmdcbiAqIGhpZGRlbiBwcm9wZXJ0aWVzLlxuICpcbiAqIGlzdGFuYnVsIGlnbm9yZSBuZXh0XG4gKi9cbmZ1bmN0aW9uIGNvcHlBdWdtZW50ICh0YXJnZXQsIHNyYywga2V5cykge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IGtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgZGVmKHRhcmdldCwga2V5LCBzcmNba2V5XSk7XG4gIH1cbn1cblxuLyoqXG4gKiBBdHRlbXB0IHRvIGNyZWF0ZSBhbiBvYnNlcnZlciBpbnN0YW5jZSBmb3IgYSB2YWx1ZSxcbiAqIHJldHVybnMgdGhlIG5ldyBvYnNlcnZlciBpZiBzdWNjZXNzZnVsbHkgb2JzZXJ2ZWQsXG4gKiBvciB0aGUgZXhpc3Rpbmcgb2JzZXJ2ZXIgaWYgdGhlIHZhbHVlIGFscmVhZHkgaGFzIG9uZS5cbiAqL1xuZnVuY3Rpb24gb2JzZXJ2ZSAodmFsdWUpIHtcbiAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgb2I7XG4gIGlmIChoYXNPd24odmFsdWUsICdfX29iX18nKSAmJiB2YWx1ZS5fX29iX18gaW5zdGFuY2VvZiBPYnNlcnZlcikge1xuICAgIG9iID0gdmFsdWUuX19vYl9fO1xuICB9IGVsc2UgaWYgKFxuICAgIG9ic2VydmVyU3RhdGUuc2hvdWxkQ29udmVydCAmJlxuICAgICFjb25maWcuX2lzU2VydmVyICYmXG4gICAgKEFycmF5LmlzQXJyYXkodmFsdWUpIHx8IGlzUGxhaW5PYmplY3QodmFsdWUpKSAmJlxuICAgIE9iamVjdC5pc0V4dGVuc2libGUodmFsdWUpICYmXG4gICAgIXZhbHVlLl9pc1Z1ZVxuICApIHtcbiAgICBvYiA9IG5ldyBPYnNlcnZlcih2YWx1ZSk7XG4gIH1cbiAgcmV0dXJuIG9iXG59XG5cbi8qKlxuICogRGVmaW5lIGEgcmVhY3RpdmUgcHJvcGVydHkgb24gYW4gT2JqZWN0LlxuICovXG5mdW5jdGlvbiBkZWZpbmVSZWFjdGl2ZSQkMSAoXG4gIG9iaixcbiAga2V5LFxuICB2YWwsXG4gIGN1c3RvbVNldHRlclxuKSB7XG4gIHZhciBkZXAgPSBuZXcgRGVwKCk7XG5cbiAgdmFyIHByb3BlcnR5ID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmosIGtleSk7XG4gIGlmIChwcm9wZXJ0eSAmJiBwcm9wZXJ0eS5jb25maWd1cmFibGUgPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICAvLyBjYXRlciBmb3IgcHJlLWRlZmluZWQgZ2V0dGVyL3NldHRlcnNcbiAgdmFyIGdldHRlciA9IHByb3BlcnR5ICYmIHByb3BlcnR5LmdldDtcbiAgdmFyIHNldHRlciA9IHByb3BlcnR5ICYmIHByb3BlcnR5LnNldDtcblxuICB2YXIgY2hpbGRPYiA9IG9ic2VydmUodmFsKTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbiByZWFjdGl2ZUdldHRlciAoKSB7XG4gICAgICB2YXIgdmFsdWUgPSBnZXR0ZXIgPyBnZXR0ZXIuY2FsbChvYmopIDogdmFsO1xuICAgICAgaWYgKERlcC50YXJnZXQpIHtcbiAgICAgICAgZGVwLmRlcGVuZCgpO1xuICAgICAgICBpZiAoY2hpbGRPYikge1xuICAgICAgICAgIGNoaWxkT2IuZGVwLmRlcGVuZCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIGRlcGVuZEFycmF5KHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlXG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uIHJlYWN0aXZlU2V0dGVyIChuZXdWYWwpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGdldHRlciA/IGdldHRlci5jYWxsKG9iaikgOiB2YWw7XG4gICAgICBpZiAobmV3VmFsID09PSB2YWx1ZSkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIGN1c3RvbVNldHRlcikge1xuICAgICAgICBjdXN0b21TZXR0ZXIoKTtcbiAgICAgIH1cbiAgICAgIGlmIChzZXR0ZXIpIHtcbiAgICAgICAgc2V0dGVyLmNhbGwob2JqLCBuZXdWYWwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsID0gbmV3VmFsO1xuICAgICAgfVxuICAgICAgY2hpbGRPYiA9IG9ic2VydmUobmV3VmFsKTtcbiAgICAgIGRlcC5ub3RpZnkoKTtcbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIFNldCBhIHByb3BlcnR5IG9uIGFuIG9iamVjdC4gQWRkcyB0aGUgbmV3IHByb3BlcnR5IGFuZFxuICogdHJpZ2dlcnMgY2hhbmdlIG5vdGlmaWNhdGlvbiBpZiB0aGUgcHJvcGVydHkgZG9lc24ndFxuICogYWxyZWFkeSBleGlzdC5cbiAqL1xuZnVuY3Rpb24gc2V0IChvYmosIGtleSwgdmFsKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICBvYmouc3BsaWNlKGtleSwgMSwgdmFsKTtcbiAgICByZXR1cm4gdmFsXG4gIH1cbiAgaWYgKGhhc093bihvYmosIGtleSkpIHtcbiAgICBvYmpba2V5XSA9IHZhbDtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgb2IgPSBvYmouX19vYl9fO1xuICBpZiAob2JqLl9pc1Z1ZSB8fCAob2IgJiYgb2Iudm1Db3VudCkpIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oXG4gICAgICAnQXZvaWQgYWRkaW5nIHJlYWN0aXZlIHByb3BlcnRpZXMgdG8gYSBWdWUgaW5zdGFuY2Ugb3IgaXRzIHJvb3QgJGRhdGEgJyArXG4gICAgICAnYXQgcnVudGltZSAtIGRlY2xhcmUgaXQgdXBmcm9udCBpbiB0aGUgZGF0YSBvcHRpb24uJ1xuICAgICk7XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKCFvYikge1xuICAgIG9ialtrZXldID0gdmFsO1xuICAgIHJldHVyblxuICB9XG4gIGRlZmluZVJlYWN0aXZlJCQxKG9iLnZhbHVlLCBrZXksIHZhbCk7XG4gIG9iLmRlcC5ub3RpZnkoKTtcbiAgcmV0dXJuIHZhbFxufVxuXG4vKipcbiAqIERlbGV0ZSBhIHByb3BlcnR5IGFuZCB0cmlnZ2VyIGNoYW5nZSBpZiBuZWNlc3NhcnkuXG4gKi9cbmZ1bmN0aW9uIGRlbCAob2JqLCBrZXkpIHtcbiAgdmFyIG9iID0gb2JqLl9fb2JfXztcbiAgaWYgKG9iai5faXNWdWUgfHwgKG9iICYmIG9iLnZtQ291bnQpKSB7XG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKFxuICAgICAgJ0F2b2lkIGRlbGV0aW5nIHByb3BlcnRpZXMgb24gYSBWdWUgaW5zdGFuY2Ugb3IgaXRzIHJvb3QgJGRhdGEgJyArXG4gICAgICAnLSBqdXN0IHNldCBpdCB0byBudWxsLidcbiAgICApO1xuICAgIHJldHVyblxuICB9XG4gIGlmICghaGFzT3duKG9iaiwga2V5KSkge1xuICAgIHJldHVyblxuICB9XG4gIGRlbGV0ZSBvYmpba2V5XTtcbiAgaWYgKCFvYikge1xuICAgIHJldHVyblxuICB9XG4gIG9iLmRlcC5ub3RpZnkoKTtcbn1cblxuLyoqXG4gKiBDb2xsZWN0IGRlcGVuZGVuY2llcyBvbiBhcnJheSBlbGVtZW50cyB3aGVuIHRoZSBhcnJheSBpcyB0b3VjaGVkLCBzaW5jZVxuICogd2UgY2Fubm90IGludGVyY2VwdCBhcnJheSBlbGVtZW50IGFjY2VzcyBsaWtlIHByb3BlcnR5IGdldHRlcnMuXG4gKi9cbmZ1bmN0aW9uIGRlcGVuZEFycmF5ICh2YWx1ZSkge1xuICBmb3IgKHZhciBlID0gdm9pZCAwLCBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGUgPSB2YWx1ZVtpXTtcbiAgICBlICYmIGUuX19vYl9fICYmIGUuX19vYl9fLmRlcC5kZXBlbmQoKTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShlKSkge1xuICAgICAgZGVwZW5kQXJyYXkoZSk7XG4gICAgfVxuICB9XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0U3RhdGUgKHZtKSB7XG4gIHZtLl93YXRjaGVycyA9IFtdO1xuICBpbml0UHJvcHModm0pO1xuICBpbml0RGF0YSh2bSk7XG4gIGluaXRDb21wdXRlZCh2bSk7XG4gIGluaXRNZXRob2RzKHZtKTtcbiAgaW5pdFdhdGNoKHZtKTtcbn1cblxuZnVuY3Rpb24gaW5pdFByb3BzICh2bSkge1xuICB2YXIgcHJvcHMgPSB2bS4kb3B0aW9ucy5wcm9wcztcbiAgaWYgKHByb3BzKSB7XG4gICAgdmFyIHByb3BzRGF0YSA9IHZtLiRvcHRpb25zLnByb3BzRGF0YSB8fCB7fTtcbiAgICB2YXIga2V5cyA9IHZtLiRvcHRpb25zLl9wcm9wS2V5cyA9IE9iamVjdC5rZXlzKHByb3BzKTtcbiAgICB2YXIgaXNSb290ID0gIXZtLiRwYXJlbnQ7XG4gICAgLy8gcm9vdCBpbnN0YW5jZSBwcm9wcyBzaG91bGQgYmUgY29udmVydGVkXG4gICAgb2JzZXJ2ZXJTdGF0ZS5zaG91bGRDb252ZXJ0ID0gaXNSb290O1xuICAgIHZhciBsb29wID0gZnVuY3Rpb24gKCBpICkge1xuICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgZGVmaW5lUmVhY3RpdmUkJDEodm0sIGtleSwgdmFsaWRhdGVQcm9wKGtleSwgcHJvcHMsIHByb3BzRGF0YSwgdm0pLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKHZtLiRwYXJlbnQgJiYgIW9ic2VydmVyU3RhdGUuaXNTZXR0aW5nUHJvcHMpIHtcbiAgICAgICAgICAgIHdhcm4oXG4gICAgICAgICAgICAgIFwiQXZvaWQgbXV0YXRpbmcgYSBwcm9wIGRpcmVjdGx5IHNpbmNlIHRoZSB2YWx1ZSB3aWxsIGJlIFwiICtcbiAgICAgICAgICAgICAgXCJvdmVyd3JpdHRlbiB3aGVuZXZlciB0aGUgcGFyZW50IGNvbXBvbmVudCByZS1yZW5kZXJzLiBcIiArXG4gICAgICAgICAgICAgIFwiSW5zdGVhZCwgdXNlIGEgZGF0YSBvciBjb21wdXRlZCBwcm9wZXJ0eSBiYXNlZCBvbiB0aGUgcHJvcCdzIFwiICtcbiAgICAgICAgICAgICAgXCJ2YWx1ZS4gUHJvcCBiZWluZyBtdXRhdGVkOiBcXFwiXCIgKyBrZXkgKyBcIlxcXCJcIixcbiAgICAgICAgICAgICAgdm1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlZmluZVJlYWN0aXZlJCQxKHZtLCBrZXksIHZhbGlkYXRlUHJvcChrZXksIHByb3BzLCBwcm9wc0RhdGEsIHZtKSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgbG9vcCggaSApO1xuICAgIG9ic2VydmVyU3RhdGUuc2hvdWxkQ29udmVydCA9IHRydWU7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5pdERhdGEgKHZtKSB7XG4gIHZhciBkYXRhID0gdm0uJG9wdGlvbnMuZGF0YTtcbiAgZGF0YSA9IHZtLl9kYXRhID0gdHlwZW9mIGRhdGEgPT09ICdmdW5jdGlvbidcbiAgICA/IGRhdGEuY2FsbCh2bSlcbiAgICA6IGRhdGEgfHwge307XG4gIGlmICghaXNQbGFpbk9iamVjdChkYXRhKSkge1xuICAgIGRhdGEgPSB7fTtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oXG4gICAgICAnZGF0YSBmdW5jdGlvbnMgc2hvdWxkIHJldHVybiBhbiBvYmplY3QuJyxcbiAgICAgIHZtXG4gICAgKTtcbiAgfVxuICAvLyBwcm94eSBkYXRhIG9uIGluc3RhbmNlXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMoZGF0YSk7XG4gIHZhciBwcm9wcyA9IHZtLiRvcHRpb25zLnByb3BzO1xuICB2YXIgaSA9IGtleXMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgaWYgKHByb3BzICYmIGhhc093bihwcm9wcywga2V5c1tpXSkpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybihcbiAgICAgICAgXCJUaGUgZGF0YSBwcm9wZXJ0eSBcXFwiXCIgKyAoa2V5c1tpXSkgKyBcIlxcXCIgaXMgYWxyZWFkeSBkZWNsYXJlZCBhcyBhIHByb3AuIFwiICtcbiAgICAgICAgXCJVc2UgcHJvcCBkZWZhdWx0IHZhbHVlIGluc3RlYWQuXCIsXG4gICAgICAgIHZtXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm94eSh2bSwga2V5c1tpXSk7XG4gICAgfVxuICB9XG4gIC8vIG9ic2VydmUgZGF0YVxuICBvYnNlcnZlKGRhdGEpO1xuICBkYXRhLl9fb2JfXyAmJiBkYXRhLl9fb2JfXy52bUNvdW50Kys7XG59XG5cbnZhciBjb21wdXRlZFNoYXJlZERlZmluaXRpb24gPSB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBub29wLFxuICBzZXQ6IG5vb3Bcbn07XG5cbmZ1bmN0aW9uIGluaXRDb21wdXRlZCAodm0pIHtcbiAgdmFyIGNvbXB1dGVkID0gdm0uJG9wdGlvbnMuY29tcHV0ZWQ7XG4gIGlmIChjb21wdXRlZCkge1xuICAgIGZvciAodmFyIGtleSBpbiBjb21wdXRlZCkge1xuICAgICAgdmFyIHVzZXJEZWYgPSBjb21wdXRlZFtrZXldO1xuICAgICAgaWYgKHR5cGVvZiB1c2VyRGVmID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNvbXB1dGVkU2hhcmVkRGVmaW5pdGlvbi5nZXQgPSBtYWtlQ29tcHV0ZWRHZXR0ZXIodXNlckRlZiwgdm0pO1xuICAgICAgICBjb21wdXRlZFNoYXJlZERlZmluaXRpb24uc2V0ID0gbm9vcDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbXB1dGVkU2hhcmVkRGVmaW5pdGlvbi5nZXQgPSB1c2VyRGVmLmdldFxuICAgICAgICAgID8gdXNlckRlZi5jYWNoZSAhPT0gZmFsc2VcbiAgICAgICAgICAgID8gbWFrZUNvbXB1dGVkR2V0dGVyKHVzZXJEZWYuZ2V0LCB2bSlcbiAgICAgICAgICAgIDogYmluZCQxKHVzZXJEZWYuZ2V0LCB2bSlcbiAgICAgICAgICA6IG5vb3A7XG4gICAgICAgIGNvbXB1dGVkU2hhcmVkRGVmaW5pdGlvbi5zZXQgPSB1c2VyRGVmLnNldFxuICAgICAgICAgID8gYmluZCQxKHVzZXJEZWYuc2V0LCB2bSlcbiAgICAgICAgICA6IG5vb3A7XG4gICAgICB9XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodm0sIGtleSwgY29tcHV0ZWRTaGFyZWREZWZpbml0aW9uKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gbWFrZUNvbXB1dGVkR2V0dGVyIChnZXR0ZXIsIG93bmVyKSB7XG4gIHZhciB3YXRjaGVyID0gbmV3IFdhdGNoZXIob3duZXIsIGdldHRlciwgbm9vcCwge1xuICAgIGxhenk6IHRydWVcbiAgfSk7XG4gIHJldHVybiBmdW5jdGlvbiBjb21wdXRlZEdldHRlciAoKSB7XG4gICAgaWYgKHdhdGNoZXIuZGlydHkpIHtcbiAgICAgIHdhdGNoZXIuZXZhbHVhdGUoKTtcbiAgICB9XG4gICAgaWYgKERlcC50YXJnZXQpIHtcbiAgICAgIHdhdGNoZXIuZGVwZW5kKCk7XG4gICAgfVxuICAgIHJldHVybiB3YXRjaGVyLnZhbHVlXG4gIH1cbn1cblxuZnVuY3Rpb24gaW5pdE1ldGhvZHMgKHZtKSB7XG4gIHZhciBtZXRob2RzID0gdm0uJG9wdGlvbnMubWV0aG9kcztcbiAgaWYgKG1ldGhvZHMpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gbWV0aG9kcykge1xuICAgICAgdm1ba2V5XSA9IG1ldGhvZHNba2V5XSA9PSBudWxsID8gbm9vcCA6IGJpbmQkMShtZXRob2RzW2tleV0sIHZtKTtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIG1ldGhvZHNba2V5XSA9PSBudWxsKSB7XG4gICAgICAgIHdhcm4oXG4gICAgICAgICAgXCJtZXRob2QgXFxcIlwiICsga2V5ICsgXCJcXFwiIGhhcyBhbiB1bmRlZmluZWQgdmFsdWUgaW4gdGhlIGNvbXBvbmVudCBkZWZpbml0aW9uLiBcIiArXG4gICAgICAgICAgXCJEaWQgeW91IHJlZmVyZW5jZSB0aGUgZnVuY3Rpb24gY29ycmVjdGx5P1wiLFxuICAgICAgICAgIHZtXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGluaXRXYXRjaCAodm0pIHtcbiAgdmFyIHdhdGNoID0gdm0uJG9wdGlvbnMud2F0Y2g7XG4gIGlmICh3YXRjaCkge1xuICAgIGZvciAodmFyIGtleSBpbiB3YXRjaCkge1xuICAgICAgdmFyIGhhbmRsZXIgPSB3YXRjaFtrZXldO1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoaGFuZGxlcikpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYW5kbGVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgY3JlYXRlV2F0Y2hlcih2bSwga2V5LCBoYW5kbGVyW2ldKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3JlYXRlV2F0Y2hlcih2bSwga2V5LCBoYW5kbGVyKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlV2F0Y2hlciAodm0sIGtleSwgaGFuZGxlcikge1xuICB2YXIgb3B0aW9ucztcbiAgaWYgKGlzUGxhaW5PYmplY3QoaGFuZGxlcikpIHtcbiAgICBvcHRpb25zID0gaGFuZGxlcjtcbiAgICBoYW5kbGVyID0gaGFuZGxlci5oYW5kbGVyO1xuICB9XG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ3N0cmluZycpIHtcbiAgICBoYW5kbGVyID0gdm1baGFuZGxlcl07XG4gIH1cbiAgdm0uJHdhdGNoKGtleSwgaGFuZGxlciwgb3B0aW9ucyk7XG59XG5cbmZ1bmN0aW9uIHN0YXRlTWl4aW4gKFZ1ZSkge1xuICAvLyBmbG93IHNvbWVob3cgaGFzIHByb2JsZW1zIHdpdGggZGlyZWN0bHkgZGVjbGFyZWQgZGVmaW5pdGlvbiBvYmplY3RcbiAgLy8gd2hlbiB1c2luZyBPYmplY3QuZGVmaW5lUHJvcGVydHksIHNvIHdlIGhhdmUgdG8gcHJvY2VkdXJhbGx5IGJ1aWxkIHVwXG4gIC8vIHRoZSBvYmplY3QgaGVyZS5cbiAgdmFyIGRhdGFEZWYgPSB7fTtcbiAgZGF0YURlZi5nZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RhdGFcbiAgfTtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICBkYXRhRGVmLnNldCA9IGZ1bmN0aW9uIChuZXdEYXRhKSB7XG4gICAgICB3YXJuKFxuICAgICAgICAnQXZvaWQgcmVwbGFjaW5nIGluc3RhbmNlIHJvb3QgJGRhdGEuICcgK1xuICAgICAgICAnVXNlIG5lc3RlZCBkYXRhIHByb3BlcnRpZXMgaW5zdGVhZC4nLFxuICAgICAgICB0aGlzXG4gICAgICApO1xuICAgIH07XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFZ1ZS5wcm90b3R5cGUsICckZGF0YScsIGRhdGFEZWYpO1xuXG4gIFZ1ZS5wcm90b3R5cGUuJHNldCA9IHNldDtcbiAgVnVlLnByb3RvdHlwZS4kZGVsZXRlID0gZGVsO1xuXG4gIFZ1ZS5wcm90b3R5cGUuJHdhdGNoID0gZnVuY3Rpb24gKFxuICAgIGV4cE9yRm4sXG4gICAgY2IsXG4gICAgb3B0aW9uc1xuICApIHtcbiAgICB2YXIgdm0gPSB0aGlzO1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgIG9wdGlvbnMudXNlciA9IHRydWU7XG4gICAgdmFyIHdhdGNoZXIgPSBuZXcgV2F0Y2hlcih2bSwgZXhwT3JGbiwgY2IsIG9wdGlvbnMpO1xuICAgIGlmIChvcHRpb25zLmltbWVkaWF0ZSkge1xuICAgICAgY2IuY2FsbCh2bSwgd2F0Y2hlci52YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiBmdW5jdGlvbiB1bndhdGNoRm4gKCkge1xuICAgICAgd2F0Y2hlci50ZWFyZG93bigpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gcHJveHkgKHZtLCBrZXkpIHtcbiAgaWYgKCFpc1Jlc2VydmVkKGtleSkpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodm0sIGtleSwge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogZnVuY3Rpb24gcHJveHlHZXR0ZXIgKCkge1xuICAgICAgICByZXR1cm4gdm0uX2RhdGFba2V5XVxuICAgICAgfSxcbiAgICAgIHNldDogZnVuY3Rpb24gcHJveHlTZXR0ZXIgKHZhbCkge1xuICAgICAgICB2bS5fZGF0YVtrZXldID0gdmFsO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbi8qICAqL1xuXG52YXIgVk5vZGUgPSBmdW5jdGlvbiBWTm9kZSAoXG4gIHRhZyxcbiAgZGF0YSxcbiAgY2hpbGRyZW4sXG4gIHRleHQsXG4gIGVsbSxcbiAgbnMsXG4gIGNvbnRleHQsXG4gIGNvbXBvbmVudE9wdGlvbnNcbikge1xuICB0aGlzLnRhZyA9IHRhZztcbiAgdGhpcy5kYXRhID0gZGF0YTtcbiAgdGhpcy5jaGlsZHJlbiA9IGNoaWxkcmVuO1xuICB0aGlzLnRleHQgPSB0ZXh0O1xuICB0aGlzLmVsbSA9IGVsbTtcbiAgdGhpcy5ucyA9IG5zO1xuICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICB0aGlzLmZ1bmN0aW9uYWxDb250ZXh0ID0gdW5kZWZpbmVkO1xuICB0aGlzLmtleSA9IGRhdGEgJiYgZGF0YS5rZXk7XG4gIHRoaXMuY29tcG9uZW50T3B0aW9ucyA9IGNvbXBvbmVudE9wdGlvbnM7XG4gIHRoaXMuY2hpbGQgPSB1bmRlZmluZWQ7XG4gIHRoaXMucGFyZW50ID0gdW5kZWZpbmVkO1xuICB0aGlzLnJhdyA9IGZhbHNlO1xuICB0aGlzLmlzU3RhdGljID0gZmFsc2U7XG4gIHRoaXMuaXNSb290SW5zZXJ0ID0gdHJ1ZTtcbiAgdGhpcy5pc0NvbW1lbnQgPSBmYWxzZTtcbiAgdGhpcy5pc0Nsb25lZCA9IGZhbHNlO1xufTtcblxudmFyIGVtcHR5Vk5vZGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBub2RlID0gbmV3IFZOb2RlKCk7XG4gIG5vZGUudGV4dCA9ICcnO1xuICBub2RlLmlzQ29tbWVudCA9IHRydWU7XG4gIHJldHVybiBub2RlXG59O1xuXG4vLyBvcHRpbWl6ZWQgc2hhbGxvdyBjbG9uZVxuLy8gdXNlZCBmb3Igc3RhdGljIG5vZGVzIGFuZCBzbG90IG5vZGVzIGJlY2F1c2UgdGhleSBtYXkgYmUgcmV1c2VkIGFjcm9zc1xuLy8gbXVsdGlwbGUgcmVuZGVycywgY2xvbmluZyB0aGVtIGF2b2lkcyBlcnJvcnMgd2hlbiBET00gbWFuaXB1bGF0aW9ucyByZWx5XG4vLyBvbiB0aGVpciBlbG0gcmVmZXJlbmNlLlxuZnVuY3Rpb24gY2xvbmVWTm9kZSAodm5vZGUpIHtcbiAgdmFyIGNsb25lZCA9IG5ldyBWTm9kZShcbiAgICB2bm9kZS50YWcsXG4gICAgdm5vZGUuZGF0YSxcbiAgICB2bm9kZS5jaGlsZHJlbixcbiAgICB2bm9kZS50ZXh0LFxuICAgIHZub2RlLmVsbSxcbiAgICB2bm9kZS5ucyxcbiAgICB2bm9kZS5jb250ZXh0LFxuICAgIHZub2RlLmNvbXBvbmVudE9wdGlvbnNcbiAgKTtcbiAgY2xvbmVkLmlzU3RhdGljID0gdm5vZGUuaXNTdGF0aWM7XG4gIGNsb25lZC5rZXkgPSB2bm9kZS5rZXk7XG4gIGNsb25lZC5pc0Nsb25lZCA9IHRydWU7XG4gIHJldHVybiBjbG9uZWRcbn1cblxuZnVuY3Rpb24gY2xvbmVWTm9kZXMgKHZub2Rlcykge1xuICB2YXIgcmVzID0gbmV3IEFycmF5KHZub2Rlcy5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHZub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgIHJlc1tpXSA9IGNsb25lVk5vZGUodm5vZGVzW2ldKTtcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBtZXJnZVZOb2RlSG9vayAoZGVmLCBob29rS2V5LCBob29rLCBrZXkpIHtcbiAga2V5ID0ga2V5ICsgaG9va0tleTtcbiAgdmFyIGluamVjdGVkSGFzaCA9IGRlZi5fX2luamVjdGVkIHx8IChkZWYuX19pbmplY3RlZCA9IHt9KTtcbiAgaWYgKCFpbmplY3RlZEhhc2hba2V5XSkge1xuICAgIGluamVjdGVkSGFzaFtrZXldID0gdHJ1ZTtcbiAgICB2YXIgb2xkSG9vayA9IGRlZltob29rS2V5XTtcbiAgICBpZiAob2xkSG9vaykge1xuICAgICAgZGVmW2hvb2tLZXldID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBvbGRIb29rLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIGhvb2suYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlZltob29rS2V5XSA9IGhvb2s7XG4gICAgfVxuICB9XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiB1cGRhdGVMaXN0ZW5lcnMgKFxuICBvbixcbiAgb2xkT24sXG4gIGFkZCxcbiAgcmVtb3ZlJCQxLFxuICB2bVxuKSB7XG4gIHZhciBuYW1lLCBjdXIsIG9sZCwgZm4sIGV2ZW50LCBjYXB0dXJlO1xuICBmb3IgKG5hbWUgaW4gb24pIHtcbiAgICBjdXIgPSBvbltuYW1lXTtcbiAgICBvbGQgPSBvbGRPbltuYW1lXTtcbiAgICBpZiAoIWN1cikge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKFxuICAgICAgICBcIkludmFsaWQgaGFuZGxlciBmb3IgZXZlbnQgXFxcIlwiICsgbmFtZSArIFwiXFxcIjogZ290IFwiICsgU3RyaW5nKGN1ciksXG4gICAgICAgIHZtXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoIW9sZCkge1xuICAgICAgY2FwdHVyZSA9IG5hbWUuY2hhckF0KDApID09PSAnISc7XG4gICAgICBldmVudCA9IGNhcHR1cmUgPyBuYW1lLnNsaWNlKDEpIDogbmFtZTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGN1cikpIHtcbiAgICAgICAgYWRkKGV2ZW50LCAoY3VyLmludm9rZXIgPSBhcnJJbnZva2VyKGN1cikpLCBjYXB0dXJlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghY3VyLmludm9rZXIpIHtcbiAgICAgICAgICBmbiA9IGN1cjtcbiAgICAgICAgICBjdXIgPSBvbltuYW1lXSA9IHt9O1xuICAgICAgICAgIGN1ci5mbiA9IGZuO1xuICAgICAgICAgIGN1ci5pbnZva2VyID0gZm5JbnZva2VyKGN1cik7XG4gICAgICAgIH1cbiAgICAgICAgYWRkKGV2ZW50LCBjdXIuaW52b2tlciwgY2FwdHVyZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjdXIgIT09IG9sZCkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2xkKSkge1xuICAgICAgICBvbGQubGVuZ3RoID0gY3VyLmxlbmd0aDtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvbGQubGVuZ3RoOyBpKyspIHsgb2xkW2ldID0gY3VyW2ldOyB9XG4gICAgICAgIG9uW25hbWVdID0gb2xkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2xkLmZuID0gY3VyO1xuICAgICAgICBvbltuYW1lXSA9IG9sZDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZm9yIChuYW1lIGluIG9sZE9uKSB7XG4gICAgaWYgKCFvbltuYW1lXSkge1xuICAgICAgZXZlbnQgPSBuYW1lLmNoYXJBdCgwKSA9PT0gJyEnID8gbmFtZS5zbGljZSgxKSA6IG5hbWU7XG4gICAgICByZW1vdmUkJDEoZXZlbnQsIG9sZE9uW25hbWVdLmludm9rZXIpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhcnJJbnZva2VyIChhcnIpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChldikge1xuICAgIHZhciBhcmd1bWVudHMkMSA9IGFyZ3VtZW50cztcblxuICAgIHZhciBzaW5nbGUgPSBhcmd1bWVudHMubGVuZ3RoID09PSAxO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBzaW5nbGUgPyBhcnJbaV0oZXYpIDogYXJyW2ldLmFwcGx5KG51bGwsIGFyZ3VtZW50cyQxKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZm5JbnZva2VyIChvKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZXYpIHtcbiAgICB2YXIgc2luZ2xlID0gYXJndW1lbnRzLmxlbmd0aCA9PT0gMTtcbiAgICBzaW5nbGUgPyBvLmZuKGV2KSA6IG8uZm4uYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgfVxufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gbm9ybWFsaXplQ2hpbGRyZW4gKFxuICBjaGlsZHJlbixcbiAgbnMsXG4gIG5lc3RlZEluZGV4XG4pIHtcbiAgaWYgKGlzUHJpbWl0aXZlKGNoaWxkcmVuKSkge1xuICAgIHJldHVybiBbY3JlYXRlVGV4dFZOb2RlKGNoaWxkcmVuKV1cbiAgfVxuICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZHJlbikpIHtcbiAgICB2YXIgcmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHZhciBjID0gY2hpbGRyZW5baV07XG4gICAgICB2YXIgbGFzdCA9IHJlc1tyZXMubGVuZ3RoIC0gMV07XG4gICAgICAvLyAgbmVzdGVkXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShjKSkge1xuICAgICAgICByZXMucHVzaC5hcHBseShyZXMsIG5vcm1hbGl6ZUNoaWxkcmVuKGMsIG5zLCAoKG5lc3RlZEluZGV4IHx8ICcnKSArIFwiX1wiICsgaSkpKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNQcmltaXRpdmUoYykpIHtcbiAgICAgICAgaWYgKGxhc3QgJiYgbGFzdC50ZXh0KSB7XG4gICAgICAgICAgbGFzdC50ZXh0ICs9IFN0cmluZyhjKTtcbiAgICAgICAgfSBlbHNlIGlmIChjICE9PSAnJykge1xuICAgICAgICAgIC8vIGNvbnZlcnQgcHJpbWl0aXZlIHRvIHZub2RlXG4gICAgICAgICAgcmVzLnB1c2goY3JlYXRlVGV4dFZOb2RlKGMpKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChjIGluc3RhbmNlb2YgVk5vZGUpIHtcbiAgICAgICAgaWYgKGMudGV4dCAmJiBsYXN0ICYmIGxhc3QudGV4dCkge1xuICAgICAgICAgIGxhc3QudGV4dCArPSBjLnRleHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gaW5oZXJpdCBwYXJlbnQgbmFtZXNwYWNlXG4gICAgICAgICAgaWYgKG5zKSB7XG4gICAgICAgICAgICBhcHBseU5TKGMsIG5zKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gZGVmYXVsdCBrZXkgZm9yIG5lc3RlZCBhcnJheSBjaGlsZHJlbiAobGlrZWx5IGdlbmVyYXRlZCBieSB2LWZvcilcbiAgICAgICAgICBpZiAoYy50YWcgJiYgYy5rZXkgPT0gbnVsbCAmJiBuZXN0ZWRJbmRleCAhPSBudWxsKSB7XG4gICAgICAgICAgICBjLmtleSA9IFwiX192bGlzdFwiICsgbmVzdGVkSW5kZXggKyBcIl9cIiArIGkgKyBcIl9fXCI7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlcy5wdXNoKGMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXNcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVUZXh0Vk5vZGUgKHZhbCkge1xuICByZXR1cm4gbmV3IFZOb2RlKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIFN0cmluZyh2YWwpKVxufVxuXG5mdW5jdGlvbiBhcHBseU5TICh2bm9kZSwgbnMpIHtcbiAgaWYgKHZub2RlLnRhZyAmJiAhdm5vZGUubnMpIHtcbiAgICB2bm9kZS5ucyA9IG5zO1xuICAgIGlmICh2bm9kZS5jaGlsZHJlbikge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB2bm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgYXBwbHlOUyh2bm9kZS5jaGlsZHJlbltpXSwgbnMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gZ2V0Rmlyc3RDb21wb25lbnRDaGlsZCAoY2hpbGRyZW4pIHtcbiAgcmV0dXJuIGNoaWxkcmVuICYmIGNoaWxkcmVuLmZpbHRlcihmdW5jdGlvbiAoYykgeyByZXR1cm4gYyAmJiBjLmNvbXBvbmVudE9wdGlvbnM7IH0pWzBdXG59XG5cbi8qICAqL1xuXG52YXIgYWN0aXZlSW5zdGFuY2UgPSBudWxsO1xuXG5mdW5jdGlvbiBpbml0TGlmZWN5Y2xlICh2bSkge1xuICB2YXIgb3B0aW9ucyA9IHZtLiRvcHRpb25zO1xuXG4gIC8vIGxvY2F0ZSBmaXJzdCBub24tYWJzdHJhY3QgcGFyZW50XG4gIHZhciBwYXJlbnQgPSBvcHRpb25zLnBhcmVudDtcbiAgaWYgKHBhcmVudCAmJiAhb3B0aW9ucy5hYnN0cmFjdCkge1xuICAgIHdoaWxlIChwYXJlbnQuJG9wdGlvbnMuYWJzdHJhY3QgJiYgcGFyZW50LiRwYXJlbnQpIHtcbiAgICAgIHBhcmVudCA9IHBhcmVudC4kcGFyZW50O1xuICAgIH1cbiAgICBwYXJlbnQuJGNoaWxkcmVuLnB1c2godm0pO1xuICB9XG5cbiAgdm0uJHBhcmVudCA9IHBhcmVudDtcbiAgdm0uJHJvb3QgPSBwYXJlbnQgPyBwYXJlbnQuJHJvb3QgOiB2bTtcblxuICB2bS4kY2hpbGRyZW4gPSBbXTtcbiAgdm0uJHJlZnMgPSB7fTtcblxuICB2bS5fd2F0Y2hlciA9IG51bGw7XG4gIHZtLl9pbmFjdGl2ZSA9IGZhbHNlO1xuICB2bS5faXNNb3VudGVkID0gZmFsc2U7XG4gIHZtLl9pc0Rlc3Ryb3llZCA9IGZhbHNlO1xuICB2bS5faXNCZWluZ0Rlc3Ryb3llZCA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBsaWZlY3ljbGVNaXhpbiAoVnVlKSB7XG4gIFZ1ZS5wcm90b3R5cGUuX21vdW50ID0gZnVuY3Rpb24gKFxuICAgIGVsLFxuICAgIGh5ZHJhdGluZ1xuICApIHtcbiAgICB2YXIgdm0gPSB0aGlzO1xuICAgIHZtLiRlbCA9IGVsO1xuICAgIGlmICghdm0uJG9wdGlvbnMucmVuZGVyKSB7XG4gICAgICB2bS4kb3B0aW9ucy5yZW5kZXIgPSBlbXB0eVZOb2RlO1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgIGlmICh2bS4kb3B0aW9ucy50ZW1wbGF0ZSkge1xuICAgICAgICAgIHdhcm4oXG4gICAgICAgICAgICAnWW91IGFyZSB1c2luZyB0aGUgcnVudGltZS1vbmx5IGJ1aWxkIG9mIFZ1ZSB3aGVyZSB0aGUgdGVtcGxhdGUgJyArXG4gICAgICAgICAgICAnb3B0aW9uIGlzIG5vdCBhdmFpbGFibGUuIEVpdGhlciBwcmUtY29tcGlsZSB0aGUgdGVtcGxhdGVzIGludG8gJyArXG4gICAgICAgICAgICAncmVuZGVyIGZ1bmN0aW9ucywgb3IgdXNlIHRoZSBjb21waWxlci1pbmNsdWRlZCBidWlsZC4nLFxuICAgICAgICAgICAgdm1cbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHdhcm4oXG4gICAgICAgICAgICAnRmFpbGVkIHRvIG1vdW50IGNvbXBvbmVudDogdGVtcGxhdGUgb3IgcmVuZGVyIGZ1bmN0aW9uIG5vdCBkZWZpbmVkLicsXG4gICAgICAgICAgICB2bVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgY2FsbEhvb2sodm0sICdiZWZvcmVNb3VudCcpO1xuICAgIHZtLl93YXRjaGVyID0gbmV3IFdhdGNoZXIodm0sIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZtLl91cGRhdGUodm0uX3JlbmRlcigpLCBoeWRyYXRpbmcpO1xuICAgIH0sIG5vb3ApO1xuICAgIGh5ZHJhdGluZyA9IGZhbHNlO1xuICAgIC8vIG1hbnVhbGx5IG1vdW50ZWQgaW5zdGFuY2UsIGNhbGwgbW91bnRlZCBvbiBzZWxmXG4gICAgLy8gbW91bnRlZCBpcyBjYWxsZWQgZm9yIHJlbmRlci1jcmVhdGVkIGNoaWxkIGNvbXBvbmVudHMgaW4gaXRzIGluc2VydGVkIGhvb2tcbiAgICBpZiAodm0uJHZub2RlID09IG51bGwpIHtcbiAgICAgIHZtLl9pc01vdW50ZWQgPSB0cnVlO1xuICAgICAgY2FsbEhvb2sodm0sICdtb3VudGVkJyk7XG4gICAgfVxuICAgIHJldHVybiB2bVxuICB9O1xuXG4gIFZ1ZS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uICh2bm9kZSwgaHlkcmF0aW5nKSB7XG4gICAgdmFyIHZtID0gdGhpcztcbiAgICBpZiAodm0uX2lzTW91bnRlZCkge1xuICAgICAgY2FsbEhvb2sodm0sICdiZWZvcmVVcGRhdGUnKTtcbiAgICB9XG4gICAgdmFyIHByZXZFbCA9IHZtLiRlbDtcbiAgICB2YXIgcHJldkFjdGl2ZUluc3RhbmNlID0gYWN0aXZlSW5zdGFuY2U7XG4gICAgYWN0aXZlSW5zdGFuY2UgPSB2bTtcbiAgICB2YXIgcHJldlZub2RlID0gdm0uX3Zub2RlO1xuICAgIHZtLl92bm9kZSA9IHZub2RlO1xuICAgIGlmICghcHJldlZub2RlKSB7XG4gICAgICAvLyBWdWUucHJvdG90eXBlLl9fcGF0Y2hfXyBpcyBpbmplY3RlZCBpbiBlbnRyeSBwb2ludHNcbiAgICAgIC8vIGJhc2VkIG9uIHRoZSByZW5kZXJpbmcgYmFja2VuZCB1c2VkLlxuICAgICAgdm0uJGVsID0gdm0uX19wYXRjaF9fKHZtLiRlbCwgdm5vZGUsIGh5ZHJhdGluZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZtLiRlbCA9IHZtLl9fcGF0Y2hfXyhwcmV2Vm5vZGUsIHZub2RlKTtcbiAgICB9XG4gICAgYWN0aXZlSW5zdGFuY2UgPSBwcmV2QWN0aXZlSW5zdGFuY2U7XG4gICAgLy8gdXBkYXRlIF9fdnVlX18gcmVmZXJlbmNlXG4gICAgaWYgKHByZXZFbCkge1xuICAgICAgcHJldkVsLl9fdnVlX18gPSBudWxsO1xuICAgIH1cbiAgICBpZiAodm0uJGVsKSB7XG4gICAgICB2bS4kZWwuX192dWVfXyA9IHZtO1xuICAgIH1cbiAgICAvLyBpZiBwYXJlbnQgaXMgYW4gSE9DLCB1cGRhdGUgaXRzICRlbCBhcyB3ZWxsXG4gICAgaWYgKHZtLiR2bm9kZSAmJiB2bS4kcGFyZW50ICYmIHZtLiR2bm9kZSA9PT0gdm0uJHBhcmVudC5fdm5vZGUpIHtcbiAgICAgIHZtLiRwYXJlbnQuJGVsID0gdm0uJGVsO1xuICAgIH1cbiAgICBpZiAodm0uX2lzTW91bnRlZCkge1xuICAgICAgY2FsbEhvb2sodm0sICd1cGRhdGVkJyk7XG4gICAgfVxuICB9O1xuXG4gIFZ1ZS5wcm90b3R5cGUuX3VwZGF0ZUZyb21QYXJlbnQgPSBmdW5jdGlvbiAoXG4gICAgcHJvcHNEYXRhLFxuICAgIGxpc3RlbmVycyxcbiAgICBwYXJlbnRWbm9kZSxcbiAgICByZW5kZXJDaGlsZHJlblxuICApIHtcbiAgICB2YXIgdm0gPSB0aGlzO1xuICAgIHZhciBoYXNDaGlsZHJlbiA9ICEhKHZtLiRvcHRpb25zLl9yZW5kZXJDaGlsZHJlbiB8fCByZW5kZXJDaGlsZHJlbik7XG4gICAgdm0uJG9wdGlvbnMuX3BhcmVudFZub2RlID0gcGFyZW50Vm5vZGU7XG4gICAgdm0uJG9wdGlvbnMuX3JlbmRlckNoaWxkcmVuID0gcmVuZGVyQ2hpbGRyZW47XG4gICAgLy8gdXBkYXRlIHByb3BzXG4gICAgaWYgKHByb3BzRGF0YSAmJiB2bS4kb3B0aW9ucy5wcm9wcykge1xuICAgICAgb2JzZXJ2ZXJTdGF0ZS5zaG91bGRDb252ZXJ0ID0gZmFsc2U7XG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICBvYnNlcnZlclN0YXRlLmlzU2V0dGluZ1Byb3BzID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHZhciBwcm9wS2V5cyA9IHZtLiRvcHRpb25zLl9wcm9wS2V5cyB8fCBbXTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcEtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGtleSA9IHByb3BLZXlzW2ldO1xuICAgICAgICB2bVtrZXldID0gdmFsaWRhdGVQcm9wKGtleSwgdm0uJG9wdGlvbnMucHJvcHMsIHByb3BzRGF0YSwgdm0pO1xuICAgICAgfVxuICAgICAgb2JzZXJ2ZXJTdGF0ZS5zaG91bGRDb252ZXJ0ID0gdHJ1ZTtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIG9ic2VydmVyU3RhdGUuaXNTZXR0aW5nUHJvcHMgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gdXBkYXRlIGxpc3RlbmVyc1xuICAgIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAgIHZhciBvbGRMaXN0ZW5lcnMgPSB2bS4kb3B0aW9ucy5fcGFyZW50TGlzdGVuZXJzO1xuICAgICAgdm0uJG9wdGlvbnMuX3BhcmVudExpc3RlbmVycyA9IGxpc3RlbmVycztcbiAgICAgIHZtLl91cGRhdGVMaXN0ZW5lcnMobGlzdGVuZXJzLCBvbGRMaXN0ZW5lcnMpO1xuICAgIH1cbiAgICAvLyByZXNvbHZlIHNsb3RzICsgZm9yY2UgdXBkYXRlIGlmIGhhcyBjaGlsZHJlblxuICAgIGlmIChoYXNDaGlsZHJlbikge1xuICAgICAgdm0uJHNsb3RzID0gcmVzb2x2ZVNsb3RzKHJlbmRlckNoaWxkcmVuLCB2bS5fcmVuZGVyQ29udGV4dCk7XG4gICAgICB2bS4kZm9yY2VVcGRhdGUoKTtcbiAgICB9XG4gIH07XG5cbiAgVnVlLnByb3RvdHlwZS4kZm9yY2VVcGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZtID0gdGhpcztcbiAgICBpZiAodm0uX3dhdGNoZXIpIHtcbiAgICAgIHZtLl93YXRjaGVyLnVwZGF0ZSgpO1xuICAgIH1cbiAgfTtcblxuICBWdWUucHJvdG90eXBlLiRkZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2bSA9IHRoaXM7XG4gICAgaWYgKHZtLl9pc0JlaW5nRGVzdHJveWVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgY2FsbEhvb2sodm0sICdiZWZvcmVEZXN0cm95Jyk7XG4gICAgdm0uX2lzQmVpbmdEZXN0cm95ZWQgPSB0cnVlO1xuICAgIC8vIHJlbW92ZSBzZWxmIGZyb20gcGFyZW50XG4gICAgdmFyIHBhcmVudCA9IHZtLiRwYXJlbnQ7XG4gICAgaWYgKHBhcmVudCAmJiAhcGFyZW50Ll9pc0JlaW5nRGVzdHJveWVkICYmICF2bS4kb3B0aW9ucy5hYnN0cmFjdCkge1xuICAgICAgcmVtb3ZlJDEocGFyZW50LiRjaGlsZHJlbiwgdm0pO1xuICAgIH1cbiAgICAvLyB0ZWFyZG93biB3YXRjaGVyc1xuICAgIGlmICh2bS5fd2F0Y2hlcikge1xuICAgICAgdm0uX3dhdGNoZXIudGVhcmRvd24oKTtcbiAgICB9XG4gICAgdmFyIGkgPSB2bS5fd2F0Y2hlcnMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIHZtLl93YXRjaGVyc1tpXS50ZWFyZG93bigpO1xuICAgIH1cbiAgICAvLyByZW1vdmUgcmVmZXJlbmNlIGZyb20gZGF0YSBvYlxuICAgIC8vIGZyb3plbiBvYmplY3QgbWF5IG5vdCBoYXZlIG9ic2VydmVyLlxuICAgIGlmICh2bS5fZGF0YS5fX29iX18pIHtcbiAgICAgIHZtLl9kYXRhLl9fb2JfXy52bUNvdW50LS07XG4gICAgfVxuICAgIC8vIGNhbGwgdGhlIGxhc3QgaG9vay4uLlxuICAgIHZtLl9pc0Rlc3Ryb3llZCA9IHRydWU7XG4gICAgY2FsbEhvb2sodm0sICdkZXN0cm95ZWQnKTtcbiAgICAvLyB0dXJuIG9mZiBhbGwgaW5zdGFuY2UgbGlzdGVuZXJzLlxuICAgIHZtLiRvZmYoKTtcbiAgICAvLyByZW1vdmUgX192dWVfXyByZWZlcmVuY2VcbiAgICBpZiAodm0uJGVsKSB7XG4gICAgICB2bS4kZWwuX192dWVfXyA9IG51bGw7XG4gICAgfVxuICAgIC8vIGludm9rZSBkZXN0cm95IGhvb2tzIG9uIGN1cnJlbnQgcmVuZGVyZWQgdHJlZVxuICAgIHZtLl9fcGF0Y2hfXyh2bS5fdm5vZGUsIG51bGwpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBjYWxsSG9vayAodm0sIGhvb2spIHtcbiAgdmFyIGhhbmRsZXJzID0gdm0uJG9wdGlvbnNbaG9va107XG4gIGlmIChoYW5kbGVycykge1xuICAgIGZvciAodmFyIGkgPSAwLCBqID0gaGFuZGxlcnMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG4gICAgICBoYW5kbGVyc1tpXS5jYWxsKHZtKTtcbiAgICB9XG4gIH1cbiAgdm0uJGVtaXQoJ2hvb2s6JyArIGhvb2spO1xufVxuXG4vKiAgKi9cblxudmFyIGhvb2tzID0geyBpbml0OiBpbml0LCBwcmVwYXRjaDogcHJlcGF0Y2gsIGluc2VydDogaW5zZXJ0LCBkZXN0cm95OiBkZXN0cm95JDEgfTtcbnZhciBob29rc1RvTWVyZ2UgPSBPYmplY3Qua2V5cyhob29rcyk7XG5cbmZ1bmN0aW9uIGNyZWF0ZUNvbXBvbmVudCAoXG4gIEN0b3IsXG4gIGRhdGEsXG4gIGNvbnRleHQsXG4gIGNoaWxkcmVuLFxuICB0YWdcbikge1xuICBpZiAoIUN0b3IpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmIChpc09iamVjdChDdG9yKSkge1xuICAgIEN0b3IgPSBWdWUkMi5leHRlbmQoQ3Rvcik7XG4gIH1cblxuICBpZiAodHlwZW9mIEN0b3IgIT09ICdmdW5jdGlvbicpIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgd2FybigoXCJJbnZhbGlkIENvbXBvbmVudCBkZWZpbml0aW9uOiBcIiArIChTdHJpbmcoQ3RvcikpKSwgY29udGV4dCk7XG4gICAgfVxuICAgIHJldHVyblxuICB9XG5cbiAgLy8gYXN5bmMgY29tcG9uZW50XG4gIGlmICghQ3Rvci5jaWQpIHtcbiAgICBpZiAoQ3Rvci5yZXNvbHZlZCkge1xuICAgICAgQ3RvciA9IEN0b3IucmVzb2x2ZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIEN0b3IgPSByZXNvbHZlQXN5bmNDb21wb25lbnQoQ3RvciwgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBpdCdzIG9rIHRvIHF1ZXVlIHRoaXMgb24gZXZlcnkgcmVuZGVyIGJlY2F1c2VcbiAgICAgICAgLy8gJGZvcmNlVXBkYXRlIGlzIGJ1ZmZlcmVkIGJ5IHRoZSBzY2hlZHVsZXIuXG4gICAgICAgIGNvbnRleHQuJGZvcmNlVXBkYXRlKCk7XG4gICAgICB9KTtcbiAgICAgIGlmICghQ3Rvcikge1xuICAgICAgICAvLyByZXR1cm4gbm90aGluZyBpZiB0aGlzIGlzIGluZGVlZCBhbiBhc3luYyBjb21wb25lbnRcbiAgICAgICAgLy8gd2FpdCBmb3IgdGhlIGNhbGxiYWNrIHRvIHRyaWdnZXIgcGFyZW50IHVwZGF0ZS5cbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZGF0YSA9IGRhdGEgfHwge307XG5cbiAgLy8gZXh0cmFjdCBwcm9wc1xuICB2YXIgcHJvcHNEYXRhID0gZXh0cmFjdFByb3BzKGRhdGEsIEN0b3IpO1xuXG4gIC8vIGZ1bmN0aW9uYWwgY29tcG9uZW50XG4gIGlmIChDdG9yLm9wdGlvbnMuZnVuY3Rpb25hbCkge1xuICAgIHJldHVybiBjcmVhdGVGdW5jdGlvbmFsQ29tcG9uZW50KEN0b3IsIHByb3BzRGF0YSwgZGF0YSwgY29udGV4dCwgY2hpbGRyZW4pXG4gIH1cblxuICAvLyBleHRyYWN0IGxpc3RlbmVycywgc2luY2UgdGhlc2UgbmVlZHMgdG8gYmUgdHJlYXRlZCBhc1xuICAvLyBjaGlsZCBjb21wb25lbnQgbGlzdGVuZXJzIGluc3RlYWQgb2YgRE9NIGxpc3RlbmVyc1xuICB2YXIgbGlzdGVuZXJzID0gZGF0YS5vbjtcbiAgLy8gcmVwbGFjZSB3aXRoIGxpc3RlbmVycyB3aXRoIC5uYXRpdmUgbW9kaWZpZXJcbiAgZGF0YS5vbiA9IGRhdGEubmF0aXZlT247XG5cbiAgaWYgKEN0b3Iub3B0aW9ucy5hYnN0cmFjdCkge1xuICAgIC8vIGFic3RyYWN0IGNvbXBvbmVudHMgZG8gbm90IGtlZXAgYW55dGhpbmdcbiAgICAvLyBvdGhlciB0aGFuIHByb3BzICYgbGlzdGVuZXJzXG4gICAgZGF0YSA9IHt9O1xuICB9XG5cbiAgLy8gbWVyZ2UgY29tcG9uZW50IG1hbmFnZW1lbnQgaG9va3Mgb250byB0aGUgcGxhY2Vob2xkZXIgbm9kZVxuICBtZXJnZUhvb2tzKGRhdGEpO1xuXG4gIC8vIHJldHVybiBhIHBsYWNlaG9sZGVyIHZub2RlXG4gIHZhciBuYW1lID0gQ3Rvci5vcHRpb25zLm5hbWUgfHwgdGFnO1xuICB2YXIgdm5vZGUgPSBuZXcgVk5vZGUoXG4gICAgKFwidnVlLWNvbXBvbmVudC1cIiArIChDdG9yLmNpZCkgKyAobmFtZSA/IChcIi1cIiArIG5hbWUpIDogJycpKSxcbiAgICBkYXRhLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGNvbnRleHQsXG4gICAgeyBDdG9yOiBDdG9yLCBwcm9wc0RhdGE6IHByb3BzRGF0YSwgbGlzdGVuZXJzOiBsaXN0ZW5lcnMsIHRhZzogdGFnLCBjaGlsZHJlbjogY2hpbGRyZW4gfVxuICApO1xuICByZXR1cm4gdm5vZGVcbn1cblxuZnVuY3Rpb24gY3JlYXRlRnVuY3Rpb25hbENvbXBvbmVudCAoXG4gIEN0b3IsXG4gIHByb3BzRGF0YSxcbiAgZGF0YSxcbiAgY29udGV4dCxcbiAgY2hpbGRyZW5cbikge1xuICB2YXIgcHJvcHMgPSB7fTtcbiAgdmFyIHByb3BPcHRpb25zID0gQ3Rvci5vcHRpb25zLnByb3BzO1xuICBpZiAocHJvcE9wdGlvbnMpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gcHJvcE9wdGlvbnMpIHtcbiAgICAgIHByb3BzW2tleV0gPSB2YWxpZGF0ZVByb3Aoa2V5LCBwcm9wT3B0aW9ucywgcHJvcHNEYXRhKTtcbiAgICB9XG4gIH1cbiAgdmFyIHZub2RlID0gQ3Rvci5vcHRpb25zLnJlbmRlci5jYWxsKFxuICAgIG51bGwsXG4gICAgLy8gZW5zdXJlIHRoZSBjcmVhdGVFbGVtZW50IGZ1bmN0aW9uIGluIGZ1bmN0aW9uYWwgY29tcG9uZW50c1xuICAgIC8vIGdldHMgYSB1bmlxdWUgY29udGV4dCAtIHRoaXMgaXMgbmVjZXNzYXJ5IGZvciBjb3JyZWN0IG5hbWVkIHNsb3QgY2hlY2tcbiAgICBiaW5kJDEoY3JlYXRlRWxlbWVudCwgeyBfc2VsZjogT2JqZWN0LmNyZWF0ZShjb250ZXh0KSB9KSxcbiAgICB7XG4gICAgICBwcm9wczogcHJvcHMsXG4gICAgICBkYXRhOiBkYXRhLFxuICAgICAgcGFyZW50OiBjb250ZXh0LFxuICAgICAgY2hpbGRyZW46IG5vcm1hbGl6ZUNoaWxkcmVuKGNoaWxkcmVuKSxcbiAgICAgIHNsb3RzOiBmdW5jdGlvbiAoKSB7IHJldHVybiByZXNvbHZlU2xvdHMoY2hpbGRyZW4sIGNvbnRleHQpOyB9XG4gICAgfVxuICApO1xuICBpZiAodm5vZGUgaW5zdGFuY2VvZiBWTm9kZSkge1xuICAgIHZub2RlLmZ1bmN0aW9uYWxDb250ZXh0ID0gY29udGV4dDtcbiAgICBpZiAoZGF0YS5zbG90KSB7XG4gICAgICAodm5vZGUuZGF0YSB8fCAodm5vZGUuZGF0YSA9IHt9KSkuc2xvdCA9IGRhdGEuc2xvdDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHZub2RlXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNvbXBvbmVudEluc3RhbmNlRm9yVm5vZGUgKFxuICB2bm9kZSwgLy8gd2Uga25vdyBpdCdzIE1vdW50ZWRDb21wb25lbnRWTm9kZSBidXQgZmxvdyBkb2Vzbid0XG4gIHBhcmVudCAvLyBhY3RpdmVJbnN0YW5jZSBpbiBsaWZlY3ljbGUgc3RhdGVcbikge1xuICB2YXIgdm5vZGVDb21wb25lbnRPcHRpb25zID0gdm5vZGUuY29tcG9uZW50T3B0aW9ucztcbiAgdmFyIG9wdGlvbnMgPSB7XG4gICAgX2lzQ29tcG9uZW50OiB0cnVlLFxuICAgIHBhcmVudDogcGFyZW50LFxuICAgIHByb3BzRGF0YTogdm5vZGVDb21wb25lbnRPcHRpb25zLnByb3BzRGF0YSxcbiAgICBfY29tcG9uZW50VGFnOiB2bm9kZUNvbXBvbmVudE9wdGlvbnMudGFnLFxuICAgIF9wYXJlbnRWbm9kZTogdm5vZGUsXG4gICAgX3BhcmVudExpc3RlbmVyczogdm5vZGVDb21wb25lbnRPcHRpb25zLmxpc3RlbmVycyxcbiAgICBfcmVuZGVyQ2hpbGRyZW46IHZub2RlQ29tcG9uZW50T3B0aW9ucy5jaGlsZHJlblxuICB9O1xuICAvLyBjaGVjayBpbmxpbmUtdGVtcGxhdGUgcmVuZGVyIGZ1bmN0aW9uc1xuICB2YXIgaW5saW5lVGVtcGxhdGUgPSB2bm9kZS5kYXRhLmlubGluZVRlbXBsYXRlO1xuICBpZiAoaW5saW5lVGVtcGxhdGUpIHtcbiAgICBvcHRpb25zLnJlbmRlciA9IGlubGluZVRlbXBsYXRlLnJlbmRlcjtcbiAgICBvcHRpb25zLnN0YXRpY1JlbmRlckZucyA9IGlubGluZVRlbXBsYXRlLnN0YXRpY1JlbmRlckZucztcbiAgfVxuICByZXR1cm4gbmV3IHZub2RlQ29tcG9uZW50T3B0aW9ucy5DdG9yKG9wdGlvbnMpXG59XG5cbmZ1bmN0aW9uIGluaXQgKHZub2RlLCBoeWRyYXRpbmcpIHtcbiAgaWYgKCF2bm9kZS5jaGlsZCB8fCB2bm9kZS5jaGlsZC5faXNEZXN0cm95ZWQpIHtcbiAgICB2YXIgY2hpbGQgPSB2bm9kZS5jaGlsZCA9IGNyZWF0ZUNvbXBvbmVudEluc3RhbmNlRm9yVm5vZGUodm5vZGUsIGFjdGl2ZUluc3RhbmNlKTtcbiAgICBjaGlsZC4kbW91bnQoaHlkcmF0aW5nID8gdm5vZGUuZWxtIDogdW5kZWZpbmVkLCBoeWRyYXRpbmcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHByZXBhdGNoIChcbiAgb2xkVm5vZGUsXG4gIHZub2RlXG4pIHtcbiAgdmFyIG9wdGlvbnMgPSB2bm9kZS5jb21wb25lbnRPcHRpb25zO1xuICB2YXIgY2hpbGQgPSB2bm9kZS5jaGlsZCA9IG9sZFZub2RlLmNoaWxkO1xuICBjaGlsZC5fdXBkYXRlRnJvbVBhcmVudChcbiAgICBvcHRpb25zLnByb3BzRGF0YSwgLy8gdXBkYXRlZCBwcm9wc1xuICAgIG9wdGlvbnMubGlzdGVuZXJzLCAvLyB1cGRhdGVkIGxpc3RlbmVyc1xuICAgIHZub2RlLCAvLyBuZXcgcGFyZW50IHZub2RlXG4gICAgb3B0aW9ucy5jaGlsZHJlbiAvLyBuZXcgY2hpbGRyZW5cbiAgKTtcbn1cblxuZnVuY3Rpb24gaW5zZXJ0ICh2bm9kZSkge1xuICBpZiAoIXZub2RlLmNoaWxkLl9pc01vdW50ZWQpIHtcbiAgICB2bm9kZS5jaGlsZC5faXNNb3VudGVkID0gdHJ1ZTtcbiAgICBjYWxsSG9vayh2bm9kZS5jaGlsZCwgJ21vdW50ZWQnKTtcbiAgfVxuICBpZiAodm5vZGUuZGF0YS5rZWVwQWxpdmUpIHtcbiAgICB2bm9kZS5jaGlsZC5faW5hY3RpdmUgPSBmYWxzZTtcbiAgICBjYWxsSG9vayh2bm9kZS5jaGlsZCwgJ2FjdGl2YXRlZCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGRlc3Ryb3kkMSAodm5vZGUpIHtcbiAgaWYgKCF2bm9kZS5jaGlsZC5faXNEZXN0cm95ZWQpIHtcbiAgICBpZiAoIXZub2RlLmRhdGEua2VlcEFsaXZlKSB7XG4gICAgICB2bm9kZS5jaGlsZC4kZGVzdHJveSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2bm9kZS5jaGlsZC5faW5hY3RpdmUgPSB0cnVlO1xuICAgICAgY2FsbEhvb2sodm5vZGUuY2hpbGQsICdkZWFjdGl2YXRlZCcpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZXNvbHZlQXN5bmNDb21wb25lbnQgKFxuICBmYWN0b3J5LFxuICBjYlxuKSB7XG4gIGlmIChmYWN0b3J5LnJlcXVlc3RlZCkge1xuICAgIC8vIHBvb2wgY2FsbGJhY2tzXG4gICAgZmFjdG9yeS5wZW5kaW5nQ2FsbGJhY2tzLnB1c2goY2IpO1xuICB9IGVsc2Uge1xuICAgIGZhY3RvcnkucmVxdWVzdGVkID0gdHJ1ZTtcbiAgICB2YXIgY2JzID0gZmFjdG9yeS5wZW5kaW5nQ2FsbGJhY2tzID0gW2NiXTtcbiAgICB2YXIgc3luYyA9IHRydWU7XG5cbiAgICB2YXIgcmVzb2x2ZSA9IGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgIGlmIChpc09iamVjdChyZXMpKSB7XG4gICAgICAgIHJlcyA9IFZ1ZSQyLmV4dGVuZChyZXMpO1xuICAgICAgfVxuICAgICAgLy8gY2FjaGUgcmVzb2x2ZWRcbiAgICAgIGZhY3RvcnkucmVzb2x2ZWQgPSByZXM7XG4gICAgICAvLyBpbnZva2UgY2FsbGJhY2tzIG9ubHkgaWYgdGhpcyBpcyBub3QgYSBzeW5jaHJvbm91cyByZXNvbHZlXG4gICAgICAvLyAoYXN5bmMgcmVzb2x2ZXMgYXJlIHNoaW1tZWQgYXMgc3luY2hyb25vdXMgZHVyaW5nIFNTUilcbiAgICAgIGlmICghc3luYykge1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGNicy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICBjYnNbaV0ocmVzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgcmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKFxuICAgICAgICBcIkZhaWxlZCB0byByZXNvbHZlIGFzeW5jIGNvbXBvbmVudDogXCIgKyAoU3RyaW5nKGZhY3RvcnkpKSArXG4gICAgICAgIChyZWFzb24gPyAoXCJcXG5SZWFzb246IFwiICsgcmVhc29uKSA6ICcnKVxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgdmFyIHJlcyA9IGZhY3RvcnkocmVzb2x2ZSwgcmVqZWN0KTtcblxuICAgIC8vIGhhbmRsZSBwcm9taXNlXG4gICAgaWYgKHJlcyAmJiB0eXBlb2YgcmVzLnRoZW4gPT09ICdmdW5jdGlvbicgJiYgIWZhY3RvcnkucmVzb2x2ZWQpIHtcbiAgICAgIHJlcy50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgfVxuXG4gICAgc3luYyA9IGZhbHNlO1xuICAgIC8vIHJldHVybiBpbiBjYXNlIHJlc29sdmVkIHN5bmNocm9ub3VzbHlcbiAgICByZXR1cm4gZmFjdG9yeS5yZXNvbHZlZFxuICB9XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RQcm9wcyAoZGF0YSwgQ3Rvcikge1xuICAvLyB3ZSBhcmUgb25seSBleHRyYXRpbmcgcmF3IHZhbHVlcyBoZXJlLlxuICAvLyB2YWxpZGF0aW9uIGFuZCBkZWZhdWx0IHZhbHVlcyBhcmUgaGFuZGxlZCBpbiB0aGUgY2hpbGRcbiAgLy8gY29tcG9uZW50IGl0c2VsZi5cbiAgdmFyIHByb3BPcHRpb25zID0gQ3Rvci5vcHRpb25zLnByb3BzO1xuICBpZiAoIXByb3BPcHRpb25zKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIHJlcyA9IHt9O1xuICB2YXIgYXR0cnMgPSBkYXRhLmF0dHJzO1xuICB2YXIgcHJvcHMgPSBkYXRhLnByb3BzO1xuICB2YXIgZG9tUHJvcHMgPSBkYXRhLmRvbVByb3BzO1xuICBpZiAoYXR0cnMgfHwgcHJvcHMgfHwgZG9tUHJvcHMpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gcHJvcE9wdGlvbnMpIHtcbiAgICAgIHZhciBhbHRLZXkgPSBoeXBoZW5hdGUoa2V5KTtcbiAgICAgIGNoZWNrUHJvcChyZXMsIHByb3BzLCBrZXksIGFsdEtleSwgdHJ1ZSkgfHxcbiAgICAgIGNoZWNrUHJvcChyZXMsIGF0dHJzLCBrZXksIGFsdEtleSkgfHxcbiAgICAgIGNoZWNrUHJvcChyZXMsIGRvbVByb3BzLCBrZXksIGFsdEtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gY2hlY2tQcm9wIChcbiAgcmVzLFxuICBoYXNoLFxuICBrZXksXG4gIGFsdEtleSxcbiAgcHJlc2VydmVcbikge1xuICBpZiAoaGFzaCkge1xuICAgIGlmIChoYXNPd24oaGFzaCwga2V5KSkge1xuICAgICAgcmVzW2tleV0gPSBoYXNoW2tleV07XG4gICAgICBpZiAoIXByZXNlcnZlKSB7XG4gICAgICAgIGRlbGV0ZSBoYXNoW2tleV07XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH0gZWxzZSBpZiAoaGFzT3duKGhhc2gsIGFsdEtleSkpIHtcbiAgICAgIHJlc1trZXldID0gaGFzaFthbHRLZXldO1xuICAgICAgaWYgKCFwcmVzZXJ2ZSkge1xuICAgICAgICBkZWxldGUgaGFzaFthbHRLZXldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlXG59XG5cbmZ1bmN0aW9uIG1lcmdlSG9va3MgKGRhdGEpIHtcbiAgaWYgKCFkYXRhLmhvb2spIHtcbiAgICBkYXRhLmhvb2sgPSB7fTtcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGhvb2tzVG9NZXJnZS5sZW5ndGg7IGkrKykge1xuICAgIHZhciBrZXkgPSBob29rc1RvTWVyZ2VbaV07XG4gICAgdmFyIGZyb21QYXJlbnQgPSBkYXRhLmhvb2tba2V5XTtcbiAgICB2YXIgb3VycyA9IGhvb2tzW2tleV07XG4gICAgZGF0YS5ob29rW2tleV0gPSBmcm9tUGFyZW50ID8gbWVyZ2VIb29rJDEob3VycywgZnJvbVBhcmVudCkgOiBvdXJzO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1lcmdlSG9vayQxIChhLCBiKSB7XG4gIC8vIHNpbmNlIGFsbCBob29rcyBoYXZlIGF0IG1vc3QgdHdvIGFyZ3MsIHVzZSBmaXhlZCBhcmdzXG4gIC8vIHRvIGF2b2lkIGhhdmluZyB0byB1c2UgZm4uYXBwbHkoKS5cbiAgcmV0dXJuIGZ1bmN0aW9uIChfLCBfXykge1xuICAgIGEoXywgX18pO1xuICAgIGIoXywgX18pO1xuICB9XG59XG5cbi8qICAqL1xuXG4vLyB3cmFwcGVyIGZ1bmN0aW9uIGZvciBwcm92aWRpbmcgYSBtb3JlIGZsZXhpYmxlIGludGVyZmFjZVxuLy8gd2l0aG91dCBnZXR0aW5nIHllbGxlZCBhdCBieSBmbG93XG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50IChcbiAgdGFnLFxuICBkYXRhLFxuICBjaGlsZHJlblxuKSB7XG4gIGlmIChkYXRhICYmIChBcnJheS5pc0FycmF5KGRhdGEpIHx8IHR5cGVvZiBkYXRhICE9PSAnb2JqZWN0JykpIHtcbiAgICBjaGlsZHJlbiA9IGRhdGE7XG4gICAgZGF0YSA9IHVuZGVmaW5lZDtcbiAgfVxuICAvLyBtYWtlIHN1cmUgdG8gdXNlIHJlYWwgaW5zdGFuY2UgaW5zdGVhZCBvZiBwcm94eSBhcyBjb250ZXh0XG4gIHJldHVybiBfY3JlYXRlRWxlbWVudCh0aGlzLl9zZWxmLCB0YWcsIGRhdGEsIGNoaWxkcmVuKVxufVxuXG5mdW5jdGlvbiBfY3JlYXRlRWxlbWVudCAoXG4gIGNvbnRleHQsXG4gIHRhZyxcbiAgZGF0YSxcbiAgY2hpbGRyZW5cbikge1xuICBpZiAoZGF0YSAmJiBkYXRhLl9fb2JfXykge1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybihcbiAgICAgIFwiQXZvaWQgdXNpbmcgb2JzZXJ2ZWQgZGF0YSBvYmplY3QgYXMgdm5vZGUgZGF0YTogXCIgKyAoSlNPTi5zdHJpbmdpZnkoZGF0YSkpICsgXCJcXG5cIiArXG4gICAgICAnQWx3YXlzIGNyZWF0ZSBmcmVzaCB2bm9kZSBkYXRhIG9iamVjdHMgaW4gZWFjaCByZW5kZXIhJyxcbiAgICAgIGNvbnRleHRcbiAgICApO1xuICAgIHJldHVyblxuICB9XG4gIGlmICghdGFnKSB7XG4gICAgLy8gaW4gY2FzZSBvZiBjb21wb25lbnQgOmlzIHNldCB0byBmYWxzeSB2YWx1ZVxuICAgIHJldHVybiBlbXB0eVZOb2RlKClcbiAgfVxuICBpZiAodHlwZW9mIHRhZyA9PT0gJ3N0cmluZycpIHtcbiAgICB2YXIgQ3RvcjtcbiAgICB2YXIgbnMgPSBjb25maWcuZ2V0VGFnTmFtZXNwYWNlKHRhZyk7XG4gICAgaWYgKGNvbmZpZy5pc1Jlc2VydmVkVGFnKHRhZykpIHtcbiAgICAgIC8vIHBsYXRmb3JtIGJ1aWx0LWluIGVsZW1lbnRzXG4gICAgICByZXR1cm4gbmV3IFZOb2RlKFxuICAgICAgICB0YWcsIGRhdGEsIG5vcm1hbGl6ZUNoaWxkcmVuKGNoaWxkcmVuLCBucyksXG4gICAgICAgIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBucywgY29udGV4dFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoKEN0b3IgPSByZXNvbHZlQXNzZXQoY29udGV4dC4kb3B0aW9ucywgJ2NvbXBvbmVudHMnLCB0YWcpKSkge1xuICAgICAgLy8gY29tcG9uZW50XG4gICAgICByZXR1cm4gY3JlYXRlQ29tcG9uZW50KEN0b3IsIGRhdGEsIGNvbnRleHQsIGNoaWxkcmVuLCB0YWcpXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHVua25vd24gb3IgdW5saXN0ZWQgbmFtZXNwYWNlZCBlbGVtZW50c1xuICAgICAgLy8gY2hlY2sgYXQgcnVudGltZSBiZWNhdXNlIGl0IG1heSBnZXQgYXNzaWduZWQgYSBuYW1lc3BhY2Ugd2hlbiBpdHNcbiAgICAgIC8vIHBhcmVudCBub3JtYWxpemVzIGNoaWxkcmVuXG4gICAgICByZXR1cm4gbmV3IFZOb2RlKFxuICAgICAgICB0YWcsIGRhdGEsIG5vcm1hbGl6ZUNoaWxkcmVuKGNoaWxkcmVuLCBucyksXG4gICAgICAgIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBucywgY29udGV4dFxuICAgICAgKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBkaXJlY3QgY29tcG9uZW50IG9wdGlvbnMgLyBjb25zdHJ1Y3RvclxuICAgIHJldHVybiBjcmVhdGVDb21wb25lbnQodGFnLCBkYXRhLCBjb250ZXh0LCBjaGlsZHJlbilcbiAgfVxufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gaW5pdFJlbmRlciAodm0pIHtcbiAgdm0uJHZub2RlID0gbnVsbDsgLy8gdGhlIHBsYWNlaG9sZGVyIG5vZGUgaW4gcGFyZW50IHRyZWVcbiAgdm0uX3Zub2RlID0gbnVsbDsgLy8gdGhlIHJvb3Qgb2YgdGhlIGNoaWxkIHRyZWVcbiAgdm0uX3N0YXRpY1RyZWVzID0gbnVsbDtcbiAgdm0uX3JlbmRlckNvbnRleHQgPSB2bS4kb3B0aW9ucy5fcGFyZW50Vm5vZGUgJiYgdm0uJG9wdGlvbnMuX3BhcmVudFZub2RlLmNvbnRleHQ7XG4gIHZtLiRzbG90cyA9IHJlc29sdmVTbG90cyh2bS4kb3B0aW9ucy5fcmVuZGVyQ2hpbGRyZW4sIHZtLl9yZW5kZXJDb250ZXh0KTtcbiAgLy8gYmluZCB0aGUgcHVibGljIGNyZWF0ZUVsZW1lbnQgZm4gdG8gdGhpcyBpbnN0YW5jZVxuICAvLyBzbyB0aGF0IHdlIGdldCBwcm9wZXIgcmVuZGVyIGNvbnRleHQgaW5zaWRlIGl0LlxuICB2bS4kY3JlYXRlRWxlbWVudCA9IGJpbmQkMShjcmVhdGVFbGVtZW50LCB2bSk7XG4gIGlmICh2bS4kb3B0aW9ucy5lbCkge1xuICAgIHZtLiRtb3VudCh2bS4kb3B0aW9ucy5lbCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVuZGVyTWl4aW4gKFZ1ZSkge1xuICBWdWUucHJvdG90eXBlLiRuZXh0VGljayA9IGZ1bmN0aW9uIChmbikge1xuICAgIG5leHRUaWNrKGZuLCB0aGlzKTtcbiAgfTtcblxuICBWdWUucHJvdG90eXBlLl9yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZtID0gdGhpcztcbiAgICB2YXIgcmVmID0gdm0uJG9wdGlvbnM7XG4gICAgdmFyIHJlbmRlciA9IHJlZi5yZW5kZXI7XG4gICAgdmFyIHN0YXRpY1JlbmRlckZucyA9IHJlZi5zdGF0aWNSZW5kZXJGbnM7XG4gICAgdmFyIF9wYXJlbnRWbm9kZSA9IHJlZi5fcGFyZW50Vm5vZGU7XG5cbiAgICBpZiAodm0uX2lzTW91bnRlZCkge1xuICAgICAgLy8gY2xvbmUgc2xvdCBub2RlcyBvbiByZS1yZW5kZXJzXG4gICAgICBmb3IgKHZhciBrZXkgaW4gdm0uJHNsb3RzKSB7XG4gICAgICAgIHZtLiRzbG90c1trZXldID0gY2xvbmVWTm9kZXModm0uJHNsb3RzW2tleV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzdGF0aWNSZW5kZXJGbnMgJiYgIXZtLl9zdGF0aWNUcmVlcykge1xuICAgICAgdm0uX3N0YXRpY1RyZWVzID0gW107XG4gICAgfVxuICAgIC8vIHNldCBwYXJlbnQgdm5vZGUuIHRoaXMgYWxsb3dzIHJlbmRlciBmdW5jdGlvbnMgdG8gaGF2ZSBhY2Nlc3NcbiAgICAvLyB0byB0aGUgZGF0YSBvbiB0aGUgcGxhY2Vob2xkZXIgbm9kZS5cbiAgICB2bS4kdm5vZGUgPSBfcGFyZW50Vm5vZGU7XG4gICAgLy8gcmVuZGVyIHNlbGZcbiAgICB2YXIgdm5vZGU7XG4gICAgdHJ5IHtcbiAgICAgIHZub2RlID0gcmVuZGVyLmNhbGwodm0uX3JlbmRlclByb3h5LCB2bS4kY3JlYXRlRWxlbWVudCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgd2FybigoXCJFcnJvciB3aGVuIHJlbmRlcmluZyBcIiArIChmb3JtYXRDb21wb25lbnROYW1lKHZtKSkgKyBcIjpcIikpO1xuICAgICAgfVxuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgIGlmIChjb25maWcuZXJyb3JIYW5kbGVyKSB7XG4gICAgICAgIGNvbmZpZy5lcnJvckhhbmRsZXIuY2FsbChudWxsLCBlLCB2bSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoY29uZmlnLl9pc1NlcnZlcikge1xuICAgICAgICAgIHRocm93IGVcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgdGhyb3cgZSB9LCAwKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gcmV0dXJuIHByZXZpb3VzIHZub2RlIHRvIHByZXZlbnQgcmVuZGVyIGVycm9yIGNhdXNpbmcgYmxhbmsgY29tcG9uZW50XG4gICAgICB2bm9kZSA9IHZtLl92bm9kZTtcbiAgICB9XG4gICAgLy8gcmV0dXJuIGVtcHR5IHZub2RlIGluIGNhc2UgdGhlIHJlbmRlciBmdW5jdGlvbiBlcnJvcmVkIG91dFxuICAgIGlmICghKHZub2RlIGluc3RhbmNlb2YgVk5vZGUpKSB7XG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBBcnJheS5pc0FycmF5KHZub2RlKSkge1xuICAgICAgICB3YXJuKFxuICAgICAgICAgICdNdWx0aXBsZSByb290IG5vZGVzIHJldHVybmVkIGZyb20gcmVuZGVyIGZ1bmN0aW9uLiBSZW5kZXIgZnVuY3Rpb24gJyArXG4gICAgICAgICAgJ3Nob3VsZCByZXR1cm4gYSBzaW5nbGUgcm9vdCBub2RlLicsXG4gICAgICAgICAgdm1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHZub2RlID0gZW1wdHlWTm9kZSgpO1xuICAgIH1cbiAgICAvLyBzZXQgcGFyZW50XG4gICAgdm5vZGUucGFyZW50ID0gX3BhcmVudFZub2RlO1xuICAgIHJldHVybiB2bm9kZVxuICB9O1xuXG4gIC8vIHNob3J0aGFuZHMgdXNlZCBpbiByZW5kZXIgZnVuY3Rpb25zXG4gIFZ1ZS5wcm90b3R5cGUuX2ggPSBjcmVhdGVFbGVtZW50O1xuICAvLyB0b1N0cmluZyBmb3IgbXVzdGFjaGVzXG4gIFZ1ZS5wcm90b3R5cGUuX3MgPSBfdG9TdHJpbmc7XG4gIC8vIG51bWJlciBjb252ZXJzaW9uXG4gIFZ1ZS5wcm90b3R5cGUuX24gPSB0b051bWJlcjtcbiAgLy8gZW1wdHkgdm5vZGVcbiAgVnVlLnByb3RvdHlwZS5fZSA9IGVtcHR5Vk5vZGU7XG4gIC8vIGxvb3NlIGVxdWFsXG4gIFZ1ZS5wcm90b3R5cGUuX3EgPSBsb29zZUVxdWFsO1xuICAvLyBsb29zZSBpbmRleE9mXG4gIFZ1ZS5wcm90b3R5cGUuX2kgPSBsb29zZUluZGV4T2Y7XG5cbiAgLy8gcmVuZGVyIHN0YXRpYyB0cmVlIGJ5IGluZGV4XG4gIFZ1ZS5wcm90b3R5cGUuX20gPSBmdW5jdGlvbiByZW5kZXJTdGF0aWMgKFxuICAgIGluZGV4LFxuICAgIGlzSW5Gb3JcbiAgKSB7XG4gICAgdmFyIHRyZWUgPSB0aGlzLl9zdGF0aWNUcmVlc1tpbmRleF07XG4gICAgLy8gaWYgaGFzIGFscmVhZHktcmVuZGVyZWQgc3RhdGljIHRyZWUgYW5kIG5vdCBpbnNpZGUgdi1mb3IsXG4gICAgLy8gd2UgY2FuIHJldXNlIHRoZSBzYW1lIHRyZWUgYnkgZG9pbmcgYSBzaGFsbG93IGNsb25lLlxuICAgIGlmICh0cmVlICYmICFpc0luRm9yKSB7XG4gICAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh0cmVlKVxuICAgICAgICA/IGNsb25lVk5vZGVzKHRyZWUpXG4gICAgICAgIDogY2xvbmVWTm9kZSh0cmVlKVxuICAgIH1cbiAgICAvLyBvdGhlcndpc2UsIHJlbmRlciBhIGZyZXNoIHRyZWUuXG4gICAgdHJlZSA9IHRoaXMuX3N0YXRpY1RyZWVzW2luZGV4XSA9IHRoaXMuJG9wdGlvbnMuc3RhdGljUmVuZGVyRm5zW2luZGV4XS5jYWxsKHRoaXMuX3JlbmRlclByb3h5KTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0cmVlKSkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0cmVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdHJlZVtpXSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0cmVlW2ldLmlzU3RhdGljID0gdHJ1ZTtcbiAgICAgICAgICB0cmVlW2ldLmtleSA9IFwiX19zdGF0aWNfX1wiICsgaW5kZXggKyBcIl9cIiArIGk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdHJlZS5pc1N0YXRpYyA9IHRydWU7XG4gICAgICB0cmVlLmtleSA9IFwiX19zdGF0aWNfX1wiICsgaW5kZXg7XG4gICAgfVxuICAgIHJldHVybiB0cmVlXG4gIH07XG5cbiAgLy8gZmlsdGVyIHJlc29sdXRpb24gaGVscGVyXG4gIHZhciBpZGVudGl0eSA9IGZ1bmN0aW9uIChfKSB7IHJldHVybiBfOyB9O1xuICBWdWUucHJvdG90eXBlLl9mID0gZnVuY3Rpb24gcmVzb2x2ZUZpbHRlciAoaWQpIHtcbiAgICByZXR1cm4gcmVzb2x2ZUFzc2V0KHRoaXMuJG9wdGlvbnMsICdmaWx0ZXJzJywgaWQsIHRydWUpIHx8IGlkZW50aXR5XG4gIH07XG5cbiAgLy8gcmVuZGVyIHYtZm9yXG4gIFZ1ZS5wcm90b3R5cGUuX2wgPSBmdW5jdGlvbiByZW5kZXJMaXN0IChcbiAgICB2YWwsXG4gICAgcmVuZGVyXG4gICkge1xuICAgIHZhciByZXQsIGksIGwsIGtleXMsIGtleTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICByZXQgPSBuZXcgQXJyYXkodmFsLmxlbmd0aCk7XG4gICAgICBmb3IgKGkgPSAwLCBsID0gdmFsLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICByZXRbaV0gPSByZW5kZXIodmFsW2ldLCBpKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgICByZXQgPSBuZXcgQXJyYXkodmFsKTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWw7IGkrKykge1xuICAgICAgICByZXRbaV0gPSByZW5kZXIoaSArIDEsIGkpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNPYmplY3QodmFsKSkge1xuICAgICAga2V5cyA9IE9iamVjdC5rZXlzKHZhbCk7XG4gICAgICByZXQgPSBuZXcgQXJyYXkoa2V5cy5sZW5ndGgpO1xuICAgICAgZm9yIChpID0gMCwgbCA9IGtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgIHJldFtpXSA9IHJlbmRlcih2YWxba2V5XSwga2V5LCBpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldFxuICB9O1xuXG4gIC8vIHJlbmRlclNsb3RcbiAgVnVlLnByb3RvdHlwZS5fdCA9IGZ1bmN0aW9uIChcbiAgICBuYW1lLFxuICAgIGZhbGxiYWNrXG4gICkge1xuICAgIHZhciBzbG90Tm9kZXMgPSB0aGlzLiRzbG90c1tuYW1lXTtcbiAgICAvLyB3YXJuIGR1cGxpY2F0ZSBzbG90IHVzYWdlXG4gICAgaWYgKHNsb3ROb2RlcyAmJiBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICBzbG90Tm9kZXMuX3JlbmRlcmVkICYmIHdhcm4oXG4gICAgICAgIFwiRHVwbGljYXRlIHByZXNlbmNlIG9mIHNsb3QgXFxcIlwiICsgbmFtZSArIFwiXFxcIiBmb3VuZCBpbiB0aGUgc2FtZSByZW5kZXIgdHJlZSBcIiArXG4gICAgICAgIFwiLSB0aGlzIHdpbGwgbGlrZWx5IGNhdXNlIHJlbmRlciBlcnJvcnMuXCIsXG4gICAgICAgIHRoaXNcbiAgICAgICk7XG4gICAgICBzbG90Tm9kZXMuX3JlbmRlcmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHNsb3ROb2RlcyB8fCBmYWxsYmFja1xuICB9O1xuXG4gIC8vIGFwcGx5IHYtYmluZCBvYmplY3RcbiAgVnVlLnByb3RvdHlwZS5fYiA9IGZ1bmN0aW9uIGJpbmRQcm9wcyAoXG4gICAgZGF0YSxcbiAgICB2YWx1ZSxcbiAgICBhc1Byb3BcbiAgKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oXG4gICAgICAgICAgJ3YtYmluZCB3aXRob3V0IGFyZ3VtZW50IGV4cGVjdHMgYW4gT2JqZWN0IG9yIEFycmF5IHZhbHVlJyxcbiAgICAgICAgICB0aGlzXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICB2YWx1ZSA9IHRvT2JqZWN0KHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBrZXkgaW4gdmFsdWUpIHtcbiAgICAgICAgICBpZiAoa2V5ID09PSAnY2xhc3MnIHx8IGtleSA9PT0gJ3N0eWxlJykge1xuICAgICAgICAgICAgZGF0YVtrZXldID0gdmFsdWVba2V5XTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIGhhc2ggPSBhc1Byb3AgfHwgY29uZmlnLm11c3RVc2VQcm9wKGtleSlcbiAgICAgICAgICAgICAgPyBkYXRhLmRvbVByb3BzIHx8IChkYXRhLmRvbVByb3BzID0ge30pXG4gICAgICAgICAgICAgIDogZGF0YS5hdHRycyB8fCAoZGF0YS5hdHRycyA9IHt9KTtcbiAgICAgICAgICAgIGhhc2hba2V5XSA9IHZhbHVlW2tleV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkYXRhXG4gIH07XG5cbiAgLy8gZXhwb3NlIHYtb24ga2V5Q29kZXNcbiAgVnVlLnByb3RvdHlwZS5fayA9IGZ1bmN0aW9uIGdldEtleUNvZGVzIChrZXkpIHtcbiAgICByZXR1cm4gY29uZmlnLmtleUNvZGVzW2tleV1cbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZVNsb3RzIChcbiAgcmVuZGVyQ2hpbGRyZW4sXG4gIGNvbnRleHRcbikge1xuICB2YXIgc2xvdHMgPSB7fTtcbiAgaWYgKCFyZW5kZXJDaGlsZHJlbikge1xuICAgIHJldHVybiBzbG90c1xuICB9XG4gIHZhciBjaGlsZHJlbiA9IG5vcm1hbGl6ZUNoaWxkcmVuKHJlbmRlckNoaWxkcmVuKSB8fCBbXTtcbiAgdmFyIGRlZmF1bHRTbG90ID0gW107XG4gIHZhciBuYW1lLCBjaGlsZDtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBjaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBjaGlsZCA9IGNoaWxkcmVuW2ldO1xuICAgIC8vIG5hbWVkIHNsb3RzIHNob3VsZCBvbmx5IGJlIHJlc3BlY3RlZCBpZiB0aGUgdm5vZGUgd2FzIHJlbmRlcmVkIGluIHRoZVxuICAgIC8vIHNhbWUgY29udGV4dC5cbiAgICBpZiAoKGNoaWxkLmNvbnRleHQgPT09IGNvbnRleHQgfHwgY2hpbGQuZnVuY3Rpb25hbENvbnRleHQgPT09IGNvbnRleHQpICYmXG4gICAgICAgIGNoaWxkLmRhdGEgJiYgKG5hbWUgPSBjaGlsZC5kYXRhLnNsb3QpKSB7XG4gICAgICB2YXIgc2xvdCA9IChzbG90c1tuYW1lXSB8fCAoc2xvdHNbbmFtZV0gPSBbXSkpO1xuICAgICAgaWYgKGNoaWxkLnRhZyA9PT0gJ3RlbXBsYXRlJykge1xuICAgICAgICBzbG90LnB1c2guYXBwbHkoc2xvdCwgY2hpbGQuY2hpbGRyZW4pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2xvdC5wdXNoKGNoaWxkKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZGVmYXVsdFNsb3QucHVzaChjaGlsZCk7XG4gICAgfVxuICB9XG4gIC8vIGlnbm9yZSBzaW5nbGUgd2hpdGVzcGFjZVxuICBpZiAoZGVmYXVsdFNsb3QubGVuZ3RoICYmICEoXG4gICAgZGVmYXVsdFNsb3QubGVuZ3RoID09PSAxICYmXG4gICAgKGRlZmF1bHRTbG90WzBdLnRleHQgPT09ICcgJyB8fCBkZWZhdWx0U2xvdFswXS5pc0NvbW1lbnQpXG4gICkpIHtcbiAgICBzbG90cy5kZWZhdWx0ID0gZGVmYXVsdFNsb3Q7XG4gIH1cbiAgcmV0dXJuIHNsb3RzXG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0RXZlbnRzICh2bSkge1xuICB2bS5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgLy8gaW5pdCBwYXJlbnQgYXR0YWNoZWQgZXZlbnRzXG4gIHZhciBsaXN0ZW5lcnMgPSB2bS4kb3B0aW9ucy5fcGFyZW50TGlzdGVuZXJzO1xuICB2YXIgb24gPSBiaW5kJDEodm0uJG9uLCB2bSk7XG4gIHZhciBvZmYgPSBiaW5kJDEodm0uJG9mZiwgdm0pO1xuICB2bS5fdXBkYXRlTGlzdGVuZXJzID0gZnVuY3Rpb24gKGxpc3RlbmVycywgb2xkTGlzdGVuZXJzKSB7XG4gICAgdXBkYXRlTGlzdGVuZXJzKGxpc3RlbmVycywgb2xkTGlzdGVuZXJzIHx8IHt9LCBvbiwgb2ZmLCB2bSk7XG4gIH07XG4gIGlmIChsaXN0ZW5lcnMpIHtcbiAgICB2bS5fdXBkYXRlTGlzdGVuZXJzKGxpc3RlbmVycyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZXZlbnRzTWl4aW4gKFZ1ZSkge1xuICBWdWUucHJvdG90eXBlLiRvbiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcbiAgICB2YXIgdm0gPSB0aGlzOyh2bS5fZXZlbnRzW2V2ZW50XSB8fCAodm0uX2V2ZW50c1tldmVudF0gPSBbXSkpLnB1c2goZm4pO1xuICAgIHJldHVybiB2bVxuICB9O1xuXG4gIFZ1ZS5wcm90b3R5cGUuJG9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgdmFyIHZtID0gdGhpcztcbiAgICBmdW5jdGlvbiBvbiAoKSB7XG4gICAgICB2bS4kb2ZmKGV2ZW50LCBvbik7XG4gICAgICBmbi5hcHBseSh2bSwgYXJndW1lbnRzKTtcbiAgICB9XG4gICAgb24uZm4gPSBmbjtcbiAgICB2bS4kb24oZXZlbnQsIG9uKTtcbiAgICByZXR1cm4gdm1cbiAgfTtcblxuICBWdWUucHJvdG90eXBlLiRvZmYgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgdmFyIHZtID0gdGhpcztcbiAgICAvLyBhbGxcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHZtLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgcmV0dXJuIHZtXG4gICAgfVxuICAgIC8vIHNwZWNpZmljIGV2ZW50XG4gICAgdmFyIGNicyA9IHZtLl9ldmVudHNbZXZlbnRdO1xuICAgIGlmICghY2JzKSB7XG4gICAgICByZXR1cm4gdm1cbiAgICB9XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZtLl9ldmVudHNbZXZlbnRdID0gbnVsbDtcbiAgICAgIHJldHVybiB2bVxuICAgIH1cbiAgICAvLyBzcGVjaWZpYyBoYW5kbGVyXG4gICAgdmFyIGNiO1xuICAgIHZhciBpID0gY2JzLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICBjYiA9IGNic1tpXTtcbiAgICAgIGlmIChjYiA9PT0gZm4gfHwgY2IuZm4gPT09IGZuKSB7XG4gICAgICAgIGNicy5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB2bVxuICB9O1xuXG4gIFZ1ZS5wcm90b3R5cGUuJGVtaXQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB2YXIgdm0gPSB0aGlzO1xuICAgIHZhciBjYnMgPSB2bS5fZXZlbnRzW2V2ZW50XTtcbiAgICBpZiAoY2JzKSB7XG4gICAgICBjYnMgPSBjYnMubGVuZ3RoID4gMSA/IHRvQXJyYXkoY2JzKSA6IGNicztcbiAgICAgIHZhciBhcmdzID0gdG9BcnJheShhcmd1bWVudHMsIDEpO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjYnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGNic1tpXS5hcHBseSh2bSwgYXJncyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB2bVxuICB9O1xufVxuXG4vKiAgKi9cblxudmFyIHVpZCA9IDA7XG5cbmZ1bmN0aW9uIGluaXRNaXhpbiAoVnVlKSB7XG4gIFZ1ZS5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIHZhciB2bSA9IHRoaXM7XG4gICAgLy8gYSB1aWRcbiAgICB2bS5fdWlkID0gdWlkKys7XG4gICAgLy8gYSBmbGFnIHRvIGF2b2lkIHRoaXMgYmVpbmcgb2JzZXJ2ZWRcbiAgICB2bS5faXNWdWUgPSB0cnVlO1xuICAgIC8vIG1lcmdlIG9wdGlvbnNcbiAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLl9pc0NvbXBvbmVudCkge1xuICAgICAgLy8gb3B0aW1pemUgaW50ZXJuYWwgY29tcG9uZW50IGluc3RhbnRpYXRpb25cbiAgICAgIC8vIHNpbmNlIGR5bmFtaWMgb3B0aW9ucyBtZXJnaW5nIGlzIHByZXR0eSBzbG93LCBhbmQgbm9uZSBvZiB0aGVcbiAgICAgIC8vIGludGVybmFsIGNvbXBvbmVudCBvcHRpb25zIG5lZWRzIHNwZWNpYWwgdHJlYXRtZW50LlxuICAgICAgaW5pdEludGVybmFsQ29tcG9uZW50KHZtLCBvcHRpb25zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdm0uJG9wdGlvbnMgPSBtZXJnZU9wdGlvbnMoXG4gICAgICAgIHJlc29sdmVDb25zdHJ1Y3Rvck9wdGlvbnModm0pLFxuICAgICAgICBvcHRpb25zIHx8IHt9LFxuICAgICAgICB2bVxuICAgICAgKTtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgaW5pdFByb3h5KHZtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdm0uX3JlbmRlclByb3h5ID0gdm07XG4gICAgfVxuICAgIC8vIGV4cG9zZSByZWFsIHNlbGZcbiAgICB2bS5fc2VsZiA9IHZtO1xuICAgIGluaXRMaWZlY3ljbGUodm0pO1xuICAgIGluaXRFdmVudHModm0pO1xuICAgIGNhbGxIb29rKHZtLCAnYmVmb3JlQ3JlYXRlJyk7XG4gICAgaW5pdFN0YXRlKHZtKTtcbiAgICBjYWxsSG9vayh2bSwgJ2NyZWF0ZWQnKTtcbiAgICBpbml0UmVuZGVyKHZtKTtcbiAgfTtcblxuICBmdW5jdGlvbiBpbml0SW50ZXJuYWxDb21wb25lbnQgKHZtLCBvcHRpb25zKSB7XG4gICAgdmFyIG9wdHMgPSB2bS4kb3B0aW9ucyA9IE9iamVjdC5jcmVhdGUocmVzb2x2ZUNvbnN0cnVjdG9yT3B0aW9ucyh2bSkpO1xuICAgIC8vIGRvaW5nIHRoaXMgYmVjYXVzZSBpdCdzIGZhc3RlciB0aGFuIGR5bmFtaWMgZW51bWVyYXRpb24uXG4gICAgb3B0cy5wYXJlbnQgPSBvcHRpb25zLnBhcmVudDtcbiAgICBvcHRzLnByb3BzRGF0YSA9IG9wdGlvbnMucHJvcHNEYXRhO1xuICAgIG9wdHMuX3BhcmVudFZub2RlID0gb3B0aW9ucy5fcGFyZW50Vm5vZGU7XG4gICAgb3B0cy5fcGFyZW50TGlzdGVuZXJzID0gb3B0aW9ucy5fcGFyZW50TGlzdGVuZXJzO1xuICAgIG9wdHMuX3JlbmRlckNoaWxkcmVuID0gb3B0aW9ucy5fcmVuZGVyQ2hpbGRyZW47XG4gICAgb3B0cy5fY29tcG9uZW50VGFnID0gb3B0aW9ucy5fY29tcG9uZW50VGFnO1xuICAgIGlmIChvcHRpb25zLnJlbmRlcikge1xuICAgICAgb3B0cy5yZW5kZXIgPSBvcHRpb25zLnJlbmRlcjtcbiAgICAgIG9wdHMuc3RhdGljUmVuZGVyRm5zID0gb3B0aW9ucy5zdGF0aWNSZW5kZXJGbnM7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVzb2x2ZUNvbnN0cnVjdG9yT3B0aW9ucyAodm0pIHtcbiAgICB2YXIgQ3RvciA9IHZtLmNvbnN0cnVjdG9yO1xuICAgIHZhciBvcHRpb25zID0gQ3Rvci5vcHRpb25zO1xuICAgIGlmIChDdG9yLnN1cGVyKSB7XG4gICAgICB2YXIgc3VwZXJPcHRpb25zID0gQ3Rvci5zdXBlci5vcHRpb25zO1xuICAgICAgdmFyIGNhY2hlZFN1cGVyT3B0aW9ucyA9IEN0b3Iuc3VwZXJPcHRpb25zO1xuICAgICAgaWYgKHN1cGVyT3B0aW9ucyAhPT0gY2FjaGVkU3VwZXJPcHRpb25zKSB7XG4gICAgICAgIC8vIHN1cGVyIG9wdGlvbiBjaGFuZ2VkXG4gICAgICAgIEN0b3Iuc3VwZXJPcHRpb25zID0gc3VwZXJPcHRpb25zO1xuICAgICAgICBvcHRpb25zID0gQ3Rvci5vcHRpb25zID0gbWVyZ2VPcHRpb25zKHN1cGVyT3B0aW9ucywgQ3Rvci5leHRlbmRPcHRpb25zKTtcbiAgICAgICAgaWYgKG9wdGlvbnMubmFtZSkge1xuICAgICAgICAgIG9wdGlvbnMuY29tcG9uZW50c1tvcHRpb25zLm5hbWVdID0gQ3RvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb3B0aW9uc1xuICB9XG59XG5cbmZ1bmN0aW9uIFZ1ZSQyIChvcHRpb25zKSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmXG4gICAgISh0aGlzIGluc3RhbmNlb2YgVnVlJDIpKSB7XG4gICAgd2FybignVnVlIGlzIGEgY29uc3RydWN0b3IgYW5kIHNob3VsZCBiZSBjYWxsZWQgd2l0aCB0aGUgYG5ld2Aga2V5d29yZCcpO1xuICB9XG4gIHRoaXMuX2luaXQob3B0aW9ucyk7XG59XG5cbmluaXRNaXhpbihWdWUkMik7XG5zdGF0ZU1peGluKFZ1ZSQyKTtcbmV2ZW50c01peGluKFZ1ZSQyKTtcbmxpZmVjeWNsZU1peGluKFZ1ZSQyKTtcbnJlbmRlck1peGluKFZ1ZSQyKTtcblxudmFyIHdhcm4gPSBub29wO1xudmFyIGZvcm1hdENvbXBvbmVudE5hbWU7XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIHZhciBoYXNDb25zb2xlID0gdHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnO1xuXG4gIHdhcm4gPSBmdW5jdGlvbiAobXNnLCB2bSkge1xuICAgIGlmIChoYXNDb25zb2xlICYmICghY29uZmlnLnNpbGVudCkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJbVnVlIHdhcm5dOiBcIiArIG1zZyArIFwiIFwiICsgKFxuICAgICAgICB2bSA/IGZvcm1hdExvY2F0aW9uKGZvcm1hdENvbXBvbmVudE5hbWUodm0pKSA6ICcnXG4gICAgICApKTtcbiAgICB9XG4gIH07XG5cbiAgZm9ybWF0Q29tcG9uZW50TmFtZSA9IGZ1bmN0aW9uICh2bSkge1xuICAgIGlmICh2bS4kcm9vdCA9PT0gdm0pIHtcbiAgICAgIHJldHVybiAncm9vdCBpbnN0YW5jZSdcbiAgICB9XG4gICAgdmFyIG5hbWUgPSB2bS5faXNWdWVcbiAgICAgID8gdm0uJG9wdGlvbnMubmFtZSB8fCB2bS4kb3B0aW9ucy5fY29tcG9uZW50VGFnXG4gICAgICA6IHZtLm5hbWU7XG4gICAgcmV0dXJuIChcbiAgICAgIChuYW1lID8gKFwiY29tcG9uZW50IDxcIiArIG5hbWUgKyBcIj5cIikgOiBcImFub255bW91cyBjb21wb25lbnRcIikgK1xuICAgICAgKHZtLl9pc1Z1ZSAmJiB2bS4kb3B0aW9ucy5fX2ZpbGUgPyAoXCIgYXQgXCIgKyAodm0uJG9wdGlvbnMuX19maWxlKSkgOiAnJylcbiAgICApXG4gIH07XG5cbiAgdmFyIGZvcm1hdExvY2F0aW9uID0gZnVuY3Rpb24gKHN0cikge1xuICAgIGlmIChzdHIgPT09ICdhbm9ueW1vdXMgY29tcG9uZW50Jykge1xuICAgICAgc3RyICs9IFwiIC0gdXNlIHRoZSBcXFwibmFtZVxcXCIgb3B0aW9uIGZvciBiZXR0ZXIgZGVidWdnaW5nIG1lc3NhZ2VzLlwiO1xuICAgIH1cbiAgICByZXR1cm4gKFwiXFxuKGZvdW5kIGluIFwiICsgc3RyICsgXCIpXCIpXG4gIH07XG59XG5cbi8qICAqL1xuXG4vKipcbiAqIE9wdGlvbiBvdmVyd3JpdGluZyBzdHJhdGVnaWVzIGFyZSBmdW5jdGlvbnMgdGhhdCBoYW5kbGVcbiAqIGhvdyB0byBtZXJnZSBhIHBhcmVudCBvcHRpb24gdmFsdWUgYW5kIGEgY2hpbGQgb3B0aW9uXG4gKiB2YWx1ZSBpbnRvIHRoZSBmaW5hbCB2YWx1ZS5cbiAqL1xudmFyIHN0cmF0cyA9IGNvbmZpZy5vcHRpb25NZXJnZVN0cmF0ZWdpZXM7XG5cbi8qKlxuICogT3B0aW9ucyB3aXRoIHJlc3RyaWN0aW9uc1xuICovXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICBzdHJhdHMuZWwgPSBzdHJhdHMucHJvcHNEYXRhID0gZnVuY3Rpb24gKHBhcmVudCwgY2hpbGQsIHZtLCBrZXkpIHtcbiAgICBpZiAoIXZtKSB7XG4gICAgICB3YXJuKFxuICAgICAgICBcIm9wdGlvbiBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgY2FuIG9ubHkgYmUgdXNlZCBkdXJpbmcgaW5zdGFuY2UgXCIgK1xuICAgICAgICAnY3JlYXRpb24gd2l0aCB0aGUgYG5ld2Aga2V5d29yZC4nXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gZGVmYXVsdFN0cmF0KHBhcmVudCwgY2hpbGQpXG4gIH07XG59XG5cbi8qKlxuICogSGVscGVyIHRoYXQgcmVjdXJzaXZlbHkgbWVyZ2VzIHR3byBkYXRhIG9iamVjdHMgdG9nZXRoZXIuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlRGF0YSAodG8sIGZyb20pIHtcbiAgdmFyIGtleSwgdG9WYWwsIGZyb21WYWw7XG4gIGZvciAoa2V5IGluIGZyb20pIHtcbiAgICB0b1ZhbCA9IHRvW2tleV07XG4gICAgZnJvbVZhbCA9IGZyb21ba2V5XTtcbiAgICBpZiAoIWhhc093bih0bywga2V5KSkge1xuICAgICAgc2V0KHRvLCBrZXksIGZyb21WYWwpO1xuICAgIH0gZWxzZSBpZiAoaXNPYmplY3QodG9WYWwpICYmIGlzT2JqZWN0KGZyb21WYWwpKSB7XG4gICAgICBtZXJnZURhdGEodG9WYWwsIGZyb21WYWwpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdG9cbn1cblxuLyoqXG4gKiBEYXRhXG4gKi9cbnN0cmF0cy5kYXRhID0gZnVuY3Rpb24gKFxuICBwYXJlbnRWYWwsXG4gIGNoaWxkVmFsLFxuICB2bVxuKSB7XG4gIGlmICghdm0pIHtcbiAgICAvLyBpbiBhIFZ1ZS5leHRlbmQgbWVyZ2UsIGJvdGggc2hvdWxkIGJlIGZ1bmN0aW9uc1xuICAgIGlmICghY2hpbGRWYWwpIHtcbiAgICAgIHJldHVybiBwYXJlbnRWYWxcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBjaGlsZFZhbCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKFxuICAgICAgICAnVGhlIFwiZGF0YVwiIG9wdGlvbiBzaG91bGQgYmUgYSBmdW5jdGlvbiAnICtcbiAgICAgICAgJ3RoYXQgcmV0dXJucyBhIHBlci1pbnN0YW5jZSB2YWx1ZSBpbiBjb21wb25lbnQgJyArXG4gICAgICAgICdkZWZpbml0aW9ucy4nLFxuICAgICAgICB2bVxuICAgICAgKTtcbiAgICAgIHJldHVybiBwYXJlbnRWYWxcbiAgICB9XG4gICAgaWYgKCFwYXJlbnRWYWwpIHtcbiAgICAgIHJldHVybiBjaGlsZFZhbFxuICAgIH1cbiAgICAvLyB3aGVuIHBhcmVudFZhbCAmIGNoaWxkVmFsIGFyZSBib3RoIHByZXNlbnQsXG4gICAgLy8gd2UgbmVlZCB0byByZXR1cm4gYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlXG4gICAgLy8gbWVyZ2VkIHJlc3VsdCBvZiBib3RoIGZ1bmN0aW9ucy4uLiBubyBuZWVkIHRvXG4gICAgLy8gY2hlY2sgaWYgcGFyZW50VmFsIGlzIGEgZnVuY3Rpb24gaGVyZSBiZWNhdXNlXG4gICAgLy8gaXQgaGFzIHRvIGJlIGEgZnVuY3Rpb24gdG8gcGFzcyBwcmV2aW91cyBtZXJnZXMuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIG1lcmdlZERhdGFGbiAoKSB7XG4gICAgICByZXR1cm4gbWVyZ2VEYXRhKFxuICAgICAgICBjaGlsZFZhbC5jYWxsKHRoaXMpLFxuICAgICAgICBwYXJlbnRWYWwuY2FsbCh0aGlzKVxuICAgICAgKVxuICAgIH1cbiAgfSBlbHNlIGlmIChwYXJlbnRWYWwgfHwgY2hpbGRWYWwpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gbWVyZ2VkSW5zdGFuY2VEYXRhRm4gKCkge1xuICAgICAgLy8gaW5zdGFuY2UgbWVyZ2VcbiAgICAgIHZhciBpbnN0YW5jZURhdGEgPSB0eXBlb2YgY2hpbGRWYWwgPT09ICdmdW5jdGlvbidcbiAgICAgICAgPyBjaGlsZFZhbC5jYWxsKHZtKVxuICAgICAgICA6IGNoaWxkVmFsO1xuICAgICAgdmFyIGRlZmF1bHREYXRhID0gdHlwZW9mIHBhcmVudFZhbCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICA/IHBhcmVudFZhbC5jYWxsKHZtKVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgIGlmIChpbnN0YW5jZURhdGEpIHtcbiAgICAgICAgcmV0dXJuIG1lcmdlRGF0YShpbnN0YW5jZURhdGEsIGRlZmF1bHREYXRhKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHREYXRhXG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIEhvb2tzIGFuZCBwYXJhbSBhdHRyaWJ1dGVzIGFyZSBtZXJnZWQgYXMgYXJyYXlzLlxuICovXG5mdW5jdGlvbiBtZXJnZUhvb2sgKFxuICBwYXJlbnRWYWwsXG4gIGNoaWxkVmFsXG4pIHtcbiAgcmV0dXJuIGNoaWxkVmFsXG4gICAgPyBwYXJlbnRWYWxcbiAgICAgID8gcGFyZW50VmFsLmNvbmNhdChjaGlsZFZhbClcbiAgICAgIDogQXJyYXkuaXNBcnJheShjaGlsZFZhbClcbiAgICAgICAgPyBjaGlsZFZhbFxuICAgICAgICA6IFtjaGlsZFZhbF1cbiAgICA6IHBhcmVudFZhbFxufVxuXG5jb25maWcuX2xpZmVjeWNsZUhvb2tzLmZvckVhY2goZnVuY3Rpb24gKGhvb2spIHtcbiAgc3RyYXRzW2hvb2tdID0gbWVyZ2VIb29rO1xufSk7XG5cbi8qKlxuICogQXNzZXRzXG4gKlxuICogV2hlbiBhIHZtIGlzIHByZXNlbnQgKGluc3RhbmNlIGNyZWF0aW9uKSwgd2UgbmVlZCB0byBkb1xuICogYSB0aHJlZS13YXkgbWVyZ2UgYmV0d2VlbiBjb25zdHJ1Y3RvciBvcHRpb25zLCBpbnN0YW5jZVxuICogb3B0aW9ucyBhbmQgcGFyZW50IG9wdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlQXNzZXRzIChwYXJlbnRWYWwsIGNoaWxkVmFsKSB7XG4gIHZhciByZXMgPSBPYmplY3QuY3JlYXRlKHBhcmVudFZhbCB8fCBudWxsKTtcbiAgcmV0dXJuIGNoaWxkVmFsXG4gICAgPyBleHRlbmQocmVzLCBjaGlsZFZhbClcbiAgICA6IHJlc1xufVxuXG5jb25maWcuX2Fzc2V0VHlwZXMuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkge1xuICBzdHJhdHNbdHlwZSArICdzJ10gPSBtZXJnZUFzc2V0cztcbn0pO1xuXG4vKipcbiAqIFdhdGNoZXJzLlxuICpcbiAqIFdhdGNoZXJzIGhhc2hlcyBzaG91bGQgbm90IG92ZXJ3cml0ZSBvbmVcbiAqIGFub3RoZXIsIHNvIHdlIG1lcmdlIHRoZW0gYXMgYXJyYXlzLlxuICovXG5zdHJhdHMud2F0Y2ggPSBmdW5jdGlvbiAocGFyZW50VmFsLCBjaGlsZFZhbCkge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKCFjaGlsZFZhbCkgeyByZXR1cm4gcGFyZW50VmFsIH1cbiAgaWYgKCFwYXJlbnRWYWwpIHsgcmV0dXJuIGNoaWxkVmFsIH1cbiAgdmFyIHJldCA9IHt9O1xuICBleHRlbmQocmV0LCBwYXJlbnRWYWwpO1xuICBmb3IgKHZhciBrZXkgaW4gY2hpbGRWYWwpIHtcbiAgICB2YXIgcGFyZW50ID0gcmV0W2tleV07XG4gICAgdmFyIGNoaWxkID0gY2hpbGRWYWxba2V5XTtcbiAgICBpZiAocGFyZW50ICYmICFBcnJheS5pc0FycmF5KHBhcmVudCkpIHtcbiAgICAgIHBhcmVudCA9IFtwYXJlbnRdO1xuICAgIH1cbiAgICByZXRba2V5XSA9IHBhcmVudFxuICAgICAgPyBwYXJlbnQuY29uY2F0KGNoaWxkKVxuICAgICAgOiBbY2hpbGRdO1xuICB9XG4gIHJldHVybiByZXRcbn07XG5cbi8qKlxuICogT3RoZXIgb2JqZWN0IGhhc2hlcy5cbiAqL1xuc3RyYXRzLnByb3BzID1cbnN0cmF0cy5tZXRob2RzID1cbnN0cmF0cy5jb21wdXRlZCA9IGZ1bmN0aW9uIChwYXJlbnRWYWwsIGNoaWxkVmFsKSB7XG4gIGlmICghY2hpbGRWYWwpIHsgcmV0dXJuIHBhcmVudFZhbCB9XG4gIGlmICghcGFyZW50VmFsKSB7IHJldHVybiBjaGlsZFZhbCB9XG4gIHZhciByZXQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICBleHRlbmQocmV0LCBwYXJlbnRWYWwpO1xuICBleHRlbmQocmV0LCBjaGlsZFZhbCk7XG4gIHJldHVybiByZXRcbn07XG5cbi8qKlxuICogRGVmYXVsdCBzdHJhdGVneS5cbiAqL1xudmFyIGRlZmF1bHRTdHJhdCA9IGZ1bmN0aW9uIChwYXJlbnRWYWwsIGNoaWxkVmFsKSB7XG4gIHJldHVybiBjaGlsZFZhbCA9PT0gdW5kZWZpbmVkXG4gICAgPyBwYXJlbnRWYWxcbiAgICA6IGNoaWxkVmFsXG59O1xuXG4vKipcbiAqIE1ha2Ugc3VyZSBjb21wb25lbnQgb3B0aW9ucyBnZXQgY29udmVydGVkIHRvIGFjdHVhbFxuICogY29uc3RydWN0b3JzLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVDb21wb25lbnRzIChvcHRpb25zKSB7XG4gIGlmIChvcHRpb25zLmNvbXBvbmVudHMpIHtcbiAgICB2YXIgY29tcG9uZW50cyA9IG9wdGlvbnMuY29tcG9uZW50cztcbiAgICB2YXIgZGVmO1xuICAgIGZvciAodmFyIGtleSBpbiBjb21wb25lbnRzKSB7XG4gICAgICB2YXIgbG93ZXIgPSBrZXkudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChpc0J1aWx0SW5UYWcobG93ZXIpIHx8IGNvbmZpZy5pc1Jlc2VydmVkVGFnKGxvd2VyKSkge1xuICAgICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oXG4gICAgICAgICAgJ0RvIG5vdCB1c2UgYnVpbHQtaW4gb3IgcmVzZXJ2ZWQgSFRNTCBlbGVtZW50cyBhcyBjb21wb25lbnQgJyArXG4gICAgICAgICAgJ2lkOiAnICsga2V5XG4gICAgICAgICk7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBkZWYgPSBjb21wb25lbnRzW2tleV07XG4gICAgICBpZiAoaXNQbGFpbk9iamVjdChkZWYpKSB7XG4gICAgICAgIGNvbXBvbmVudHNba2V5XSA9IFZ1ZSQyLmV4dGVuZChkZWYpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEVuc3VyZSBhbGwgcHJvcHMgb3B0aW9uIHN5bnRheCBhcmUgbm9ybWFsaXplZCBpbnRvIHRoZVxuICogT2JqZWN0LWJhc2VkIGZvcm1hdC5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplUHJvcHMgKG9wdGlvbnMpIHtcbiAgdmFyIHByb3BzID0gb3B0aW9ucy5wcm9wcztcbiAgaWYgKCFwcm9wcykgeyByZXR1cm4gfVxuICB2YXIgcmVzID0ge307XG4gIHZhciBpLCB2YWwsIG5hbWU7XG4gIGlmIChBcnJheS5pc0FycmF5KHByb3BzKSkge1xuICAgIGkgPSBwcm9wcy5sZW5ndGg7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgdmFsID0gcHJvcHNbaV07XG4gICAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbmFtZSA9IGNhbWVsaXplKHZhbCk7XG4gICAgICAgIHJlc1tuYW1lXSA9IHsgdHlwZTogbnVsbCB9O1xuICAgICAgfSBlbHNlIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIHdhcm4oJ3Byb3BzIG11c3QgYmUgc3RyaW5ncyB3aGVuIHVzaW5nIGFycmF5IHN5bnRheC4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNQbGFpbk9iamVjdChwcm9wcykpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHtcbiAgICAgIHZhbCA9IHByb3BzW2tleV07XG4gICAgICBuYW1lID0gY2FtZWxpemUoa2V5KTtcbiAgICAgIHJlc1tuYW1lXSA9IGlzUGxhaW5PYmplY3QodmFsKVxuICAgICAgICA/IHZhbFxuICAgICAgICA6IHsgdHlwZTogdmFsIH07XG4gICAgfVxuICB9XG4gIG9wdGlvbnMucHJvcHMgPSByZXM7XG59XG5cbi8qKlxuICogTm9ybWFsaXplIHJhdyBmdW5jdGlvbiBkaXJlY3RpdmVzIGludG8gb2JqZWN0IGZvcm1hdC5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplRGlyZWN0aXZlcyAob3B0aW9ucykge1xuICB2YXIgZGlycyA9IG9wdGlvbnMuZGlyZWN0aXZlcztcbiAgaWYgKGRpcnMpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gZGlycykge1xuICAgICAgdmFyIGRlZiA9IGRpcnNba2V5XTtcbiAgICAgIGlmICh0eXBlb2YgZGVmID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGRpcnNba2V5XSA9IHsgYmluZDogZGVmLCB1cGRhdGU6IGRlZiB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIE1lcmdlIHR3byBvcHRpb24gb2JqZWN0cyBpbnRvIGEgbmV3IG9uZS5cbiAqIENvcmUgdXRpbGl0eSB1c2VkIGluIGJvdGggaW5zdGFudGlhdGlvbiBhbmQgaW5oZXJpdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlT3B0aW9ucyAoXG4gIHBhcmVudCxcbiAgY2hpbGQsXG4gIHZtXG4pIHtcbiAgbm9ybWFsaXplQ29tcG9uZW50cyhjaGlsZCk7XG4gIG5vcm1hbGl6ZVByb3BzKGNoaWxkKTtcbiAgbm9ybWFsaXplRGlyZWN0aXZlcyhjaGlsZCk7XG4gIHZhciBleHRlbmRzRnJvbSA9IGNoaWxkLmV4dGVuZHM7XG4gIGlmIChleHRlbmRzRnJvbSkge1xuICAgIHBhcmVudCA9IHR5cGVvZiBleHRlbmRzRnJvbSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgPyBtZXJnZU9wdGlvbnMocGFyZW50LCBleHRlbmRzRnJvbS5vcHRpb25zLCB2bSlcbiAgICAgIDogbWVyZ2VPcHRpb25zKHBhcmVudCwgZXh0ZW5kc0Zyb20sIHZtKTtcbiAgfVxuICBpZiAoY2hpbGQubWl4aW5zKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjaGlsZC5taXhpbnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICB2YXIgbWl4aW4gPSBjaGlsZC5taXhpbnNbaV07XG4gICAgICBpZiAobWl4aW4ucHJvdG90eXBlIGluc3RhbmNlb2YgVnVlJDIpIHtcbiAgICAgICAgbWl4aW4gPSBtaXhpbi5vcHRpb25zO1xuICAgICAgfVxuICAgICAgcGFyZW50ID0gbWVyZ2VPcHRpb25zKHBhcmVudCwgbWl4aW4sIHZtKTtcbiAgICB9XG4gIH1cbiAgdmFyIG9wdGlvbnMgPSB7fTtcbiAgdmFyIGtleTtcbiAgZm9yIChrZXkgaW4gcGFyZW50KSB7XG4gICAgbWVyZ2VGaWVsZChrZXkpO1xuICB9XG4gIGZvciAoa2V5IGluIGNoaWxkKSB7XG4gICAgaWYgKCFoYXNPd24ocGFyZW50LCBrZXkpKSB7XG4gICAgICBtZXJnZUZpZWxkKGtleSk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIG1lcmdlRmllbGQgKGtleSkge1xuICAgIHZhciBzdHJhdCA9IHN0cmF0c1trZXldIHx8IGRlZmF1bHRTdHJhdDtcbiAgICBvcHRpb25zW2tleV0gPSBzdHJhdChwYXJlbnRba2V5XSwgY2hpbGRba2V5XSwgdm0sIGtleSk7XG4gIH1cbiAgcmV0dXJuIG9wdGlvbnNcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGFuIGFzc2V0LlxuICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGJlY2F1c2UgY2hpbGQgaW5zdGFuY2VzIG5lZWQgYWNjZXNzXG4gKiB0byBhc3NldHMgZGVmaW5lZCBpbiBpdHMgYW5jZXN0b3IgY2hhaW4uXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVBc3NldCAoXG4gIG9wdGlvbnMsXG4gIHR5cGUsXG4gIGlkLFxuICB3YXJuTWlzc2luZ1xuKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAodHlwZW9mIGlkICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVyblxuICB9XG4gIHZhciBhc3NldHMgPSBvcHRpb25zW3R5cGVdO1xuICB2YXIgcmVzID0gYXNzZXRzW2lkXSB8fFxuICAgIC8vIGNhbWVsQ2FzZSBJRFxuICAgIGFzc2V0c1tjYW1lbGl6ZShpZCldIHx8XG4gICAgLy8gUGFzY2FsIENhc2UgSURcbiAgICBhc3NldHNbY2FwaXRhbGl6ZShjYW1lbGl6ZShpZCkpXTtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2Fybk1pc3NpbmcgJiYgIXJlcykge1xuICAgIHdhcm4oXG4gICAgICAnRmFpbGVkIHRvIHJlc29sdmUgJyArIHR5cGUuc2xpY2UoMCwgLTEpICsgJzogJyArIGlkLFxuICAgICAgb3B0aW9uc1xuICAgICk7XG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gdmFsaWRhdGVQcm9wIChcbiAga2V5LFxuICBwcm9wT3B0aW9ucyxcbiAgcHJvcHNEYXRhLFxuICB2bVxuKSB7XG4gIHZhciBwcm9wID0gcHJvcE9wdGlvbnNba2V5XTtcbiAgdmFyIGFic2VudCA9ICFoYXNPd24ocHJvcHNEYXRhLCBrZXkpO1xuICB2YXIgdmFsdWUgPSBwcm9wc0RhdGFba2V5XTtcbiAgLy8gaGFuZGxlIGJvb2xlYW4gcHJvcHNcbiAgaWYgKGlzQm9vbGVhblR5cGUocHJvcC50eXBlKSkge1xuICAgIGlmIChhYnNlbnQgJiYgIWhhc093bihwcm9wLCAnZGVmYXVsdCcpKSB7XG4gICAgICB2YWx1ZSA9IGZhbHNlO1xuICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICcnIHx8IHZhbHVlID09PSBoeXBoZW5hdGUoa2V5KSkge1xuICAgICAgdmFsdWUgPSB0cnVlO1xuICAgIH1cbiAgfVxuICAvLyBjaGVjayBkZWZhdWx0IHZhbHVlXG4gIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdmFsdWUgPSBnZXRQcm9wRGVmYXVsdFZhbHVlKHZtLCBwcm9wLCBrZXkpO1xuICAgIC8vIHNpbmNlIHRoZSBkZWZhdWx0IHZhbHVlIGlzIGEgZnJlc2ggY29weSxcbiAgICAvLyBtYWtlIHN1cmUgdG8gb2JzZXJ2ZSBpdC5cbiAgICB2YXIgcHJldlNob3VsZENvbnZlcnQgPSBvYnNlcnZlclN0YXRlLnNob3VsZENvbnZlcnQ7XG4gICAgb2JzZXJ2ZXJTdGF0ZS5zaG91bGRDb252ZXJ0ID0gdHJ1ZTtcbiAgICBvYnNlcnZlKHZhbHVlKTtcbiAgICBvYnNlcnZlclN0YXRlLnNob3VsZENvbnZlcnQgPSBwcmV2U2hvdWxkQ29udmVydDtcbiAgfVxuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIGFzc2VydFByb3AocHJvcCwga2V5LCB2YWx1ZSwgdm0sIGFic2VudCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlXG59XG5cbi8qKlxuICogR2V0IHRoZSBkZWZhdWx0IHZhbHVlIG9mIGEgcHJvcC5cbiAqL1xuZnVuY3Rpb24gZ2V0UHJvcERlZmF1bHRWYWx1ZSAodm0sIHByb3AsIG5hbWUpIHtcbiAgLy8gbm8gZGVmYXVsdCwgcmV0dXJuIHVuZGVmaW5lZFxuICBpZiAoIWhhc093bihwcm9wLCAnZGVmYXVsdCcpKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG4gIHZhciBkZWYgPSBwcm9wLmRlZmF1bHQ7XG4gIC8vIHdhcm4gYWdhaW5zdCBub24tZmFjdG9yeSBkZWZhdWx0cyBmb3IgT2JqZWN0ICYgQXJyYXlcbiAgaWYgKGlzT2JqZWN0KGRlZikpIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oXG4gICAgICAnSW52YWxpZCBkZWZhdWx0IHZhbHVlIGZvciBwcm9wIFwiJyArIG5hbWUgKyAnXCI6ICcgK1xuICAgICAgJ1Byb3BzIHdpdGggdHlwZSBPYmplY3QvQXJyYXkgbXVzdCB1c2UgYSBmYWN0b3J5IGZ1bmN0aW9uICcgK1xuICAgICAgJ3RvIHJldHVybiB0aGUgZGVmYXVsdCB2YWx1ZS4nLFxuICAgICAgdm1cbiAgICApO1xuICB9XG4gIC8vIGNhbGwgZmFjdG9yeSBmdW5jdGlvbiBmb3Igbm9uLUZ1bmN0aW9uIHR5cGVzXG4gIHJldHVybiB0eXBlb2YgZGVmID09PSAnZnVuY3Rpb24nICYmIHByb3AudHlwZSAhPT0gRnVuY3Rpb25cbiAgICA/IGRlZi5jYWxsKHZtKVxuICAgIDogZGVmXG59XG5cbi8qKlxuICogQXNzZXJ0IHdoZXRoZXIgYSBwcm9wIGlzIHZhbGlkLlxuICovXG5mdW5jdGlvbiBhc3NlcnRQcm9wIChcbiAgcHJvcCxcbiAgbmFtZSxcbiAgdmFsdWUsXG4gIHZtLFxuICBhYnNlbnRcbikge1xuICBpZiAocHJvcC5yZXF1aXJlZCAmJiBhYnNlbnQpIHtcbiAgICB3YXJuKFxuICAgICAgJ01pc3NpbmcgcmVxdWlyZWQgcHJvcDogXCInICsgbmFtZSArICdcIicsXG4gICAgICB2bVxuICAgICk7XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwgJiYgIXByb3AucmVxdWlyZWQpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgdHlwZSA9IHByb3AudHlwZTtcbiAgdmFyIHZhbGlkID0gIXR5cGUgfHwgdHlwZSA9PT0gdHJ1ZTtcbiAgdmFyIGV4cGVjdGVkVHlwZXMgPSBbXTtcbiAgaWYgKHR5cGUpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkodHlwZSkpIHtcbiAgICAgIHR5cGUgPSBbdHlwZV07XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdHlwZS5sZW5ndGggJiYgIXZhbGlkOyBpKyspIHtcbiAgICAgIHZhciBhc3NlcnRlZFR5cGUgPSBhc3NlcnRUeXBlKHZhbHVlLCB0eXBlW2ldKTtcbiAgICAgIGV4cGVjdGVkVHlwZXMucHVzaChhc3NlcnRlZFR5cGUuZXhwZWN0ZWRUeXBlKTtcbiAgICAgIHZhbGlkID0gYXNzZXJ0ZWRUeXBlLnZhbGlkO1xuICAgIH1cbiAgfVxuICBpZiAoIXZhbGlkKSB7XG4gICAgd2FybihcbiAgICAgICdJbnZhbGlkIHByb3A6IHR5cGUgY2hlY2sgZmFpbGVkIGZvciBwcm9wIFwiJyArIG5hbWUgKyAnXCIuJyArXG4gICAgICAnIEV4cGVjdGVkICcgKyBleHBlY3RlZFR5cGVzLm1hcChjYXBpdGFsaXplKS5qb2luKCcsICcpICtcbiAgICAgICcsIGdvdCAnICsgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKS5zbGljZSg4LCAtMSkgKyAnLicsXG4gICAgICB2bVxuICAgICk7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIHZhbGlkYXRvciA9IHByb3AudmFsaWRhdG9yO1xuICBpZiAodmFsaWRhdG9yKSB7XG4gICAgaWYgKCF2YWxpZGF0b3IodmFsdWUpKSB7XG4gICAgICB3YXJuKFxuICAgICAgICAnSW52YWxpZCBwcm9wOiBjdXN0b20gdmFsaWRhdG9yIGNoZWNrIGZhaWxlZCBmb3IgcHJvcCBcIicgKyBuYW1lICsgJ1wiLicsXG4gICAgICAgIHZtXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEFzc2VydCB0aGUgdHlwZSBvZiBhIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIGFzc2VydFR5cGUgKHZhbHVlLCB0eXBlKSB7XG4gIHZhciB2YWxpZDtcbiAgdmFyIGV4cGVjdGVkVHlwZSA9IGdldFR5cGUodHlwZSk7XG4gIGlmIChleHBlY3RlZFR5cGUgPT09ICdTdHJpbmcnKSB7XG4gICAgdmFsaWQgPSB0eXBlb2YgdmFsdWUgPT09IChleHBlY3RlZFR5cGUgPSAnc3RyaW5nJyk7XG4gIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAnTnVtYmVyJykge1xuICAgIHZhbGlkID0gdHlwZW9mIHZhbHVlID09PSAoZXhwZWN0ZWRUeXBlID0gJ251bWJlcicpO1xuICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ0Jvb2xlYW4nKSB7XG4gICAgdmFsaWQgPSB0eXBlb2YgdmFsdWUgPT09IChleHBlY3RlZFR5cGUgPSAnYm9vbGVhbicpO1xuICB9IGVsc2UgaWYgKGV4cGVjdGVkVHlwZSA9PT0gJ0Z1bmN0aW9uJykge1xuICAgIHZhbGlkID0gdHlwZW9mIHZhbHVlID09PSAoZXhwZWN0ZWRUeXBlID0gJ2Z1bmN0aW9uJyk7XG4gIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAnT2JqZWN0Jykge1xuICAgIHZhbGlkID0gaXNQbGFpbk9iamVjdCh2YWx1ZSk7XG4gIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSAnQXJyYXknKSB7XG4gICAgdmFsaWQgPSBBcnJheS5pc0FycmF5KHZhbHVlKTtcbiAgfSBlbHNlIHtcbiAgICB2YWxpZCA9IHZhbHVlIGluc3RhbmNlb2YgdHlwZTtcbiAgfVxuICByZXR1cm4ge1xuICAgIHZhbGlkOiB2YWxpZCxcbiAgICBleHBlY3RlZFR5cGU6IGV4cGVjdGVkVHlwZVxuICB9XG59XG5cbi8qKlxuICogVXNlIGZ1bmN0aW9uIHN0cmluZyBuYW1lIHRvIGNoZWNrIGJ1aWx0LWluIHR5cGVzLFxuICogYmVjYXVzZSBhIHNpbXBsZSBlcXVhbGl0eSBjaGVjayB3aWxsIGZhaWwgd2hlbiBydW5uaW5nXG4gKiBhY3Jvc3MgZGlmZmVyZW50IHZtcyAvIGlmcmFtZXMuXG4gKi9cbmZ1bmN0aW9uIGdldFR5cGUgKGZuKSB7XG4gIHZhciBtYXRjaCA9IGZuICYmIGZuLnRvU3RyaW5nKCkubWF0Y2goL15cXHMqZnVuY3Rpb24gKFxcdyspLyk7XG4gIHJldHVybiBtYXRjaCAmJiBtYXRjaFsxXVxufVxuXG5mdW5jdGlvbiBpc0Jvb2xlYW5UeXBlIChmbikge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoZm4pKSB7XG4gICAgcmV0dXJuIGdldFR5cGUoZm4pID09PSAnQm9vbGVhbidcbiAgfVxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gZm4ubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoZ2V0VHlwZShmbltpXSkgPT09ICdCb29sZWFuJykge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgcmV0dXJuIGZhbHNlXG59XG5cblxuXG52YXIgdXRpbCA9IE9iamVjdC5mcmVlemUoe1xuXHRkZWZpbmVSZWFjdGl2ZTogZGVmaW5lUmVhY3RpdmUkJDEsXG5cdF90b1N0cmluZzogX3RvU3RyaW5nLFxuXHR0b051bWJlcjogdG9OdW1iZXIsXG5cdG1ha2VNYXA6IG1ha2VNYXAsXG5cdGlzQnVpbHRJblRhZzogaXNCdWlsdEluVGFnLFxuXHRyZW1vdmU6IHJlbW92ZSQxLFxuXHRoYXNPd246IGhhc093bixcblx0aXNQcmltaXRpdmU6IGlzUHJpbWl0aXZlLFxuXHRjYWNoZWQ6IGNhY2hlZCxcblx0Y2FtZWxpemU6IGNhbWVsaXplLFxuXHRjYXBpdGFsaXplOiBjYXBpdGFsaXplLFxuXHRoeXBoZW5hdGU6IGh5cGhlbmF0ZSxcblx0YmluZDogYmluZCQxLFxuXHR0b0FycmF5OiB0b0FycmF5LFxuXHRleHRlbmQ6IGV4dGVuZCxcblx0aXNPYmplY3Q6IGlzT2JqZWN0LFxuXHRpc1BsYWluT2JqZWN0OiBpc1BsYWluT2JqZWN0LFxuXHR0b09iamVjdDogdG9PYmplY3QsXG5cdG5vb3A6IG5vb3AsXG5cdG5vOiBubyxcblx0Z2VuU3RhdGljS2V5czogZ2VuU3RhdGljS2V5cyxcblx0bG9vc2VFcXVhbDogbG9vc2VFcXVhbCxcblx0bG9vc2VJbmRleE9mOiBsb29zZUluZGV4T2YsXG5cdGlzUmVzZXJ2ZWQ6IGlzUmVzZXJ2ZWQsXG5cdGRlZjogZGVmLFxuXHRwYXJzZVBhdGg6IHBhcnNlUGF0aCxcblx0aGFzUHJvdG86IGhhc1Byb3RvLFxuXHRpbkJyb3dzZXI6IGluQnJvd3Nlcixcblx0VUE6IFVBLFxuXHRpc0lFOiBpc0lFLFxuXHRpc0lFOTogaXNJRTksXG5cdGlzRWRnZTogaXNFZGdlLFxuXHRpc0FuZHJvaWQ6IGlzQW5kcm9pZCxcblx0aXNJT1M6IGlzSU9TLFxuXHRkZXZ0b29sczogZGV2dG9vbHMsXG5cdG5leHRUaWNrOiBuZXh0VGljayxcblx0Z2V0IF9TZXQgKCkgeyByZXR1cm4gX1NldDsgfSxcblx0bWVyZ2VPcHRpb25zOiBtZXJnZU9wdGlvbnMsXG5cdHJlc29sdmVBc3NldDogcmVzb2x2ZUFzc2V0LFxuXHRnZXQgd2FybiAoKSB7IHJldHVybiB3YXJuOyB9LFxuXHRnZXQgZm9ybWF0Q29tcG9uZW50TmFtZSAoKSB7IHJldHVybiBmb3JtYXRDb21wb25lbnROYW1lOyB9LFxuXHR2YWxpZGF0ZVByb3A6IHZhbGlkYXRlUHJvcFxufSk7XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0VXNlIChWdWUpIHtcbiAgVnVlLnVzZSA9IGZ1bmN0aW9uIChwbHVnaW4pIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAocGx1Z2luLmluc3RhbGxlZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIC8vIGFkZGl0aW9uYWwgcGFyYW1ldGVyc1xuICAgIHZhciBhcmdzID0gdG9BcnJheShhcmd1bWVudHMsIDEpO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzKTtcbiAgICBpZiAodHlwZW9mIHBsdWdpbi5pbnN0YWxsID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwbHVnaW4uaW5zdGFsbC5hcHBseShwbHVnaW4sIGFyZ3MpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwbHVnaW4uYXBwbHkobnVsbCwgYXJncyk7XG4gICAgfVxuICAgIHBsdWdpbi5pbnN0YWxsZWQgPSB0cnVlO1xuICAgIHJldHVybiB0aGlzXG4gIH07XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0TWl4aW4kMSAoVnVlKSB7XG4gIFZ1ZS5taXhpbiA9IGZ1bmN0aW9uIChtaXhpbikge1xuICAgIFZ1ZS5vcHRpb25zID0gbWVyZ2VPcHRpb25zKFZ1ZS5vcHRpb25zLCBtaXhpbik7XG4gIH07XG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0RXh0ZW5kIChWdWUpIHtcbiAgLyoqXG4gICAqIEVhY2ggaW5zdGFuY2UgY29uc3RydWN0b3IsIGluY2x1ZGluZyBWdWUsIGhhcyBhIHVuaXF1ZVxuICAgKiBjaWQuIFRoaXMgZW5hYmxlcyB1cyB0byBjcmVhdGUgd3JhcHBlZCBcImNoaWxkXG4gICAqIGNvbnN0cnVjdG9yc1wiIGZvciBwcm90b3R5cGFsIGluaGVyaXRhbmNlIGFuZCBjYWNoZSB0aGVtLlxuICAgKi9cbiAgVnVlLmNpZCA9IDA7XG4gIHZhciBjaWQgPSAxO1xuXG4gIC8qKlxuICAgKiBDbGFzcyBpbmhlcml0YW5jZVxuICAgKi9cbiAgVnVlLmV4dGVuZCA9IGZ1bmN0aW9uIChleHRlbmRPcHRpb25zKSB7XG4gICAgZXh0ZW5kT3B0aW9ucyA9IGV4dGVuZE9wdGlvbnMgfHwge307XG4gICAgdmFyIFN1cGVyID0gdGhpcztcbiAgICB2YXIgaXNGaXJzdEV4dGVuZCA9IFN1cGVyLmNpZCA9PT0gMDtcbiAgICBpZiAoaXNGaXJzdEV4dGVuZCAmJiBleHRlbmRPcHRpb25zLl9DdG9yKSB7XG4gICAgICByZXR1cm4gZXh0ZW5kT3B0aW9ucy5fQ3RvclxuICAgIH1cbiAgICB2YXIgbmFtZSA9IGV4dGVuZE9wdGlvbnMubmFtZSB8fCBTdXBlci5vcHRpb25zLm5hbWU7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIGlmICghL15bYS16QS1aXVtcXHctXSokLy50ZXN0KG5hbWUpKSB7XG4gICAgICAgIHdhcm4oXG4gICAgICAgICAgJ0ludmFsaWQgY29tcG9uZW50IG5hbWU6IFwiJyArIG5hbWUgKyAnXCIuIENvbXBvbmVudCBuYW1lcyAnICtcbiAgICAgICAgICAnY2FuIG9ubHkgY29udGFpbiBhbHBoYW51bWVyaWMgY2hhcmFjYXRlcnMgYW5kIHRoZSBoeXBoZW4uJ1xuICAgICAgICApO1xuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIFN1YiA9IGZ1bmN0aW9uIFZ1ZUNvbXBvbmVudCAob3B0aW9ucykge1xuICAgICAgdGhpcy5faW5pdChvcHRpb25zKTtcbiAgICB9O1xuICAgIFN1Yi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFN1cGVyLnByb3RvdHlwZSk7XG4gICAgU3ViLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFN1YjtcbiAgICBTdWIuY2lkID0gY2lkKys7XG4gICAgU3ViLm9wdGlvbnMgPSBtZXJnZU9wdGlvbnMoXG4gICAgICBTdXBlci5vcHRpb25zLFxuICAgICAgZXh0ZW5kT3B0aW9uc1xuICAgICk7XG4gICAgU3ViWydzdXBlciddID0gU3VwZXI7XG4gICAgLy8gYWxsb3cgZnVydGhlciBleHRlbnNpb25cbiAgICBTdWIuZXh0ZW5kID0gU3VwZXIuZXh0ZW5kO1xuICAgIC8vIGNyZWF0ZSBhc3NldCByZWdpc3RlcnMsIHNvIGV4dGVuZGVkIGNsYXNzZXNcbiAgICAvLyBjYW4gaGF2ZSB0aGVpciBwcml2YXRlIGFzc2V0cyB0b28uXG4gICAgY29uZmlnLl9hc3NldFR5cGVzLmZvckVhY2goZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgIFN1Ylt0eXBlXSA9IFN1cGVyW3R5cGVdO1xuICAgIH0pO1xuICAgIC8vIGVuYWJsZSByZWN1cnNpdmUgc2VsZi1sb29rdXBcbiAgICBpZiAobmFtZSkge1xuICAgICAgU3ViLm9wdGlvbnMuY29tcG9uZW50c1tuYW1lXSA9IFN1YjtcbiAgICB9XG4gICAgLy8ga2VlcCBhIHJlZmVyZW5jZSB0byB0aGUgc3VwZXIgb3B0aW9ucyBhdCBleHRlbnNpb24gdGltZS5cbiAgICAvLyBsYXRlciBhdCBpbnN0YW50aWF0aW9uIHdlIGNhbiBjaGVjayBpZiBTdXBlcidzIG9wdGlvbnMgaGF2ZVxuICAgIC8vIGJlZW4gdXBkYXRlZC5cbiAgICBTdWIuc3VwZXJPcHRpb25zID0gU3VwZXIub3B0aW9ucztcbiAgICBTdWIuZXh0ZW5kT3B0aW9ucyA9IGV4dGVuZE9wdGlvbnM7XG4gICAgLy8gY2FjaGUgY29uc3RydWN0b3JcbiAgICBpZiAoaXNGaXJzdEV4dGVuZCkge1xuICAgICAgZXh0ZW5kT3B0aW9ucy5fQ3RvciA9IFN1YjtcbiAgICB9XG4gICAgcmV0dXJuIFN1YlxuICB9O1xufVxuXG4vKiAgKi9cblxuZnVuY3Rpb24gaW5pdEFzc2V0UmVnaXN0ZXJzIChWdWUpIHtcbiAgLyoqXG4gICAqIENyZWF0ZSBhc3NldCByZWdpc3RyYXRpb24gbWV0aG9kcy5cbiAgICovXG4gIGNvbmZpZy5fYXNzZXRUeXBlcy5mb3JFYWNoKGZ1bmN0aW9uICh0eXBlKSB7XG4gICAgVnVlW3R5cGVdID0gZnVuY3Rpb24gKFxuICAgICAgaWQsXG4gICAgICBkZWZpbml0aW9uXG4gICAgKSB7XG4gICAgICBpZiAoIWRlZmluaXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9uc1t0eXBlICsgJ3MnXVtpZF1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICAgIGlmICh0eXBlID09PSAnY29tcG9uZW50JyAmJiBjb25maWcuaXNSZXNlcnZlZFRhZyhpZCkpIHtcbiAgICAgICAgICAgIHdhcm4oXG4gICAgICAgICAgICAgICdEbyBub3QgdXNlIGJ1aWx0LWluIG9yIHJlc2VydmVkIEhUTUwgZWxlbWVudHMgYXMgY29tcG9uZW50ICcgK1xuICAgICAgICAgICAgICAnaWQ6ICcgKyBpZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdjb21wb25lbnQnICYmIGlzUGxhaW5PYmplY3QoZGVmaW5pdGlvbikpIHtcbiAgICAgICAgICBkZWZpbml0aW9uLm5hbWUgPSBkZWZpbml0aW9uLm5hbWUgfHwgaWQ7XG4gICAgICAgICAgZGVmaW5pdGlvbiA9IFZ1ZS5leHRlbmQoZGVmaW5pdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdkaXJlY3RpdmUnICYmIHR5cGVvZiBkZWZpbml0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgZGVmaW5pdGlvbiA9IHsgYmluZDogZGVmaW5pdGlvbiwgdXBkYXRlOiBkZWZpbml0aW9uIH07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcHRpb25zW3R5cGUgKyAncyddW2lkXSA9IGRlZmluaXRpb247XG4gICAgICAgIHJldHVybiBkZWZpbml0aW9uXG4gICAgICB9XG4gICAgfTtcbiAgfSk7XG59XG5cbnZhciBLZWVwQWxpdmUgPSB7XG4gIG5hbWU6ICdrZWVwLWFsaXZlJyxcbiAgYWJzdHJhY3Q6IHRydWUsXG4gIGNyZWF0ZWQ6IGZ1bmN0aW9uIGNyZWF0ZWQgKCkge1xuICAgIHRoaXMuY2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICB9LFxuICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlciAoKSB7XG4gICAgdmFyIHZub2RlID0gZ2V0Rmlyc3RDb21wb25lbnRDaGlsZCh0aGlzLiRzbG90cy5kZWZhdWx0KTtcbiAgICBpZiAodm5vZGUgJiYgdm5vZGUuY29tcG9uZW50T3B0aW9ucykge1xuICAgICAgdmFyIG9wdHMgPSB2bm9kZS5jb21wb25lbnRPcHRpb25zO1xuICAgICAgdmFyIGtleSA9IHZub2RlLmtleSA9PSBudWxsXG4gICAgICAgIC8vIHNhbWUgY29uc3RydWN0b3IgbWF5IGdldCByZWdpc3RlcmVkIGFzIGRpZmZlcmVudCBsb2NhbCBjb21wb25lbnRzXG4gICAgICAgIC8vIHNvIGNpZCBhbG9uZSBpcyBub3QgZW5vdWdoICgjMzI2OSlcbiAgICAgICAgPyBvcHRzLkN0b3IuY2lkICsgJzo6JyArIG9wdHMudGFnXG4gICAgICAgIDogdm5vZGUua2V5O1xuICAgICAgaWYgKHRoaXMuY2FjaGVba2V5XSkge1xuICAgICAgICB2bm9kZS5jaGlsZCA9IHRoaXMuY2FjaGVba2V5XS5jaGlsZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY2FjaGVba2V5XSA9IHZub2RlO1xuICAgICAgfVxuICAgICAgdm5vZGUuZGF0YS5rZWVwQWxpdmUgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gdm5vZGVcbiAgfSxcbiAgZGVzdHJveWVkOiBmdW5jdGlvbiBkZXN0cm95ZWQgKCkge1xuICAgIHZhciB0aGlzJDEgPSB0aGlzO1xuXG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMuY2FjaGUpIHtcbiAgICAgIHZhciB2bm9kZSA9IHRoaXMkMS5jYWNoZVtrZXldO1xuICAgICAgY2FsbEhvb2sodm5vZGUuY2hpbGQsICdkZWFjdGl2YXRlZCcpO1xuICAgICAgdm5vZGUuY2hpbGQuJGRlc3Ryb3koKTtcbiAgICB9XG4gIH1cbn07XG5cbnZhciBidWlsdEluQ29tcG9uZW50cyA9IHtcbiAgS2VlcEFsaXZlOiBLZWVwQWxpdmVcbn07XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBpbml0R2xvYmFsQVBJIChWdWUpIHtcbiAgLy8gY29uZmlnXG4gIHZhciBjb25maWdEZWYgPSB7fTtcbiAgY29uZmlnRGVmLmdldCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNvbmZpZzsgfTtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICBjb25maWdEZWYuc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgd2FybihcbiAgICAgICAgJ0RvIG5vdCByZXBsYWNlIHRoZSBWdWUuY29uZmlnIG9iamVjdCwgc2V0IGluZGl2aWR1YWwgZmllbGRzIGluc3RlYWQuJ1xuICAgICAgKTtcbiAgICB9O1xuICB9XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShWdWUsICdjb25maWcnLCBjb25maWdEZWYpO1xuICBWdWUudXRpbCA9IHV0aWw7XG4gIFZ1ZS5zZXQgPSBzZXQ7XG4gIFZ1ZS5kZWxldGUgPSBkZWw7XG4gIFZ1ZS5uZXh0VGljayA9IG5leHRUaWNrO1xuXG4gIFZ1ZS5vcHRpb25zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgY29uZmlnLl9hc3NldFR5cGVzLmZvckVhY2goZnVuY3Rpb24gKHR5cGUpIHtcbiAgICBWdWUub3B0aW9uc1t0eXBlICsgJ3MnXSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIH0pO1xuXG4gIGV4dGVuZChWdWUub3B0aW9ucy5jb21wb25lbnRzLCBidWlsdEluQ29tcG9uZW50cyk7XG5cbiAgaW5pdFVzZShWdWUpO1xuICBpbml0TWl4aW4kMShWdWUpO1xuICBpbml0RXh0ZW5kKFZ1ZSk7XG4gIGluaXRBc3NldFJlZ2lzdGVycyhWdWUpO1xufVxuXG5pbml0R2xvYmFsQVBJKFZ1ZSQyKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFZ1ZSQyLnByb3RvdHlwZSwgJyRpc1NlcnZlcicsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25maWcuX2lzU2VydmVyOyB9XG59KTtcblxuVnVlJDIudmVyc2lvbiA9ICcyLjAuMyc7XG5cbi8qICAqL1xuXG4vLyBhdHRyaWJ1dGVzIHRoYXQgc2hvdWxkIGJlIHVzaW5nIHByb3BzIGZvciBiaW5kaW5nXG52YXIgbXVzdFVzZVByb3AgPSBtYWtlTWFwKCd2YWx1ZSxzZWxlY3RlZCxjaGVja2VkLG11dGVkJyk7XG5cbnZhciBpc0VudW1lcmF0ZWRBdHRyID0gbWFrZU1hcCgnY29udGVudGVkaXRhYmxlLGRyYWdnYWJsZSxzcGVsbGNoZWNrJyk7XG5cbnZhciBpc0Jvb2xlYW5BdHRyID0gbWFrZU1hcChcbiAgJ2FsbG93ZnVsbHNjcmVlbixhc3luYyxhdXRvZm9jdXMsYXV0b3BsYXksY2hlY2tlZCxjb21wYWN0LGNvbnRyb2xzLGRlY2xhcmUsJyArXG4gICdkZWZhdWx0LGRlZmF1bHRjaGVja2VkLGRlZmF1bHRtdXRlZCxkZWZhdWx0c2VsZWN0ZWQsZGVmZXIsZGlzYWJsZWQsJyArXG4gICdlbmFibGVkLGZvcm1ub3ZhbGlkYXRlLGhpZGRlbixpbmRldGVybWluYXRlLGluZXJ0LGlzbWFwLGl0ZW1zY29wZSxsb29wLG11bHRpcGxlLCcgK1xuICAnbXV0ZWQsbm9ocmVmLG5vcmVzaXplLG5vc2hhZGUsbm92YWxpZGF0ZSxub3dyYXAsb3BlbixwYXVzZW9uZXhpdCxyZWFkb25seSwnICtcbiAgJ3JlcXVpcmVkLHJldmVyc2VkLHNjb3BlZCxzZWFtbGVzcyxzZWxlY3RlZCxzb3J0YWJsZSx0cmFuc2xhdGUsJyArXG4gICd0cnVlc3BlZWQsdHlwZW11c3RtYXRjaCx2aXNpYmxlJ1xuKTtcblxudmFyIGlzQXR0ciA9IG1ha2VNYXAoXG4gICdhY2NlcHQsYWNjZXB0LWNoYXJzZXQsYWNjZXNza2V5LGFjdGlvbixhbGlnbixhbHQsYXN5bmMsYXV0b2NvbXBsZXRlLCcgK1xuICAnYXV0b2ZvY3VzLGF1dG9wbGF5LGF1dG9zYXZlLGJnY29sb3IsYm9yZGVyLGJ1ZmZlcmVkLGNoYWxsZW5nZSxjaGFyc2V0LCcgK1xuICAnY2hlY2tlZCxjaXRlLGNsYXNzLGNvZGUsY29kZWJhc2UsY29sb3IsY29scyxjb2xzcGFuLGNvbnRlbnQsaHR0cC1lcXVpdiwnICtcbiAgJ25hbWUsY29udGVudGVkaXRhYmxlLGNvbnRleHRtZW51LGNvbnRyb2xzLGNvb3JkcyxkYXRhLGRhdGV0aW1lLGRlZmF1bHQsJyArXG4gICdkZWZlcixkaXIsZGlybmFtZSxkaXNhYmxlZCxkb3dubG9hZCxkcmFnZ2FibGUsZHJvcHpvbmUsZW5jdHlwZSxtZXRob2QsZm9yLCcgK1xuICAnZm9ybSxmb3JtYWN0aW9uLGhlYWRlcnMsPHRoPixoZWlnaHQsaGlkZGVuLGhpZ2gsaHJlZixocmVmbGFuZyxodHRwLWVxdWl2LCcgK1xuICAnaWNvbixpZCxpc21hcCxpdGVtcHJvcCxrZXl0eXBlLGtpbmQsbGFiZWwsbGFuZyxsYW5ndWFnZSxsaXN0LGxvb3AsbG93LCcgK1xuICAnbWFuaWZlc3QsbWF4LG1heGxlbmd0aCxtZWRpYSxtZXRob2QsR0VULFBPU1QsbWluLG11bHRpcGxlLGVtYWlsLGZpbGUsJyArXG4gICdtdXRlZCxuYW1lLG5vdmFsaWRhdGUsb3BlbixvcHRpbXVtLHBhdHRlcm4scGluZyxwbGFjZWhvbGRlcixwb3N0ZXIsJyArXG4gICdwcmVsb2FkLHJhZGlvZ3JvdXAscmVhZG9ubHkscmVsLHJlcXVpcmVkLHJldmVyc2VkLHJvd3Mscm93c3BhbixzYW5kYm94LCcgK1xuICAnc2NvcGUsc2NvcGVkLHNlYW1sZXNzLHNlbGVjdGVkLHNoYXBlLHNpemUsdHlwZSx0ZXh0LHBhc3N3b3JkLHNpemVzLHNwYW4sJyArXG4gICdzcGVsbGNoZWNrLHNyYyxzcmNkb2Msc3JjbGFuZyxzcmNzZXQsc3RhcnQsc3RlcCxzdHlsZSxzdW1tYXJ5LHRhYmluZGV4LCcgK1xuICAndGFyZ2V0LHRpdGxlLHR5cGUsdXNlbWFwLHZhbHVlLHdpZHRoLHdyYXAnXG4pO1xuXG5cblxudmFyIHhsaW5rTlMgPSAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayc7XG5cbnZhciBpc1hsaW5rID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIG5hbWUuY2hhckF0KDUpID09PSAnOicgJiYgbmFtZS5zbGljZSgwLCA1KSA9PT0gJ3hsaW5rJ1xufTtcblxudmFyIGdldFhsaW5rUHJvcCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiBpc1hsaW5rKG5hbWUpID8gbmFtZS5zbGljZSg2LCBuYW1lLmxlbmd0aCkgOiAnJ1xufTtcblxudmFyIGlzRmFsc3lBdHRyVmFsdWUgPSBmdW5jdGlvbiAodmFsKSB7XG4gIHJldHVybiB2YWwgPT0gbnVsbCB8fCB2YWwgPT09IGZhbHNlXG59O1xuXG4vKiAgKi9cblxuZnVuY3Rpb24gZ2VuQ2xhc3NGb3JWbm9kZSAodm5vZGUpIHtcbiAgdmFyIGRhdGEgPSB2bm9kZS5kYXRhO1xuICB2YXIgcGFyZW50Tm9kZSA9IHZub2RlO1xuICB2YXIgY2hpbGROb2RlID0gdm5vZGU7XG4gIHdoaWxlIChjaGlsZE5vZGUuY2hpbGQpIHtcbiAgICBjaGlsZE5vZGUgPSBjaGlsZE5vZGUuY2hpbGQuX3Zub2RlO1xuICAgIGlmIChjaGlsZE5vZGUuZGF0YSkge1xuICAgICAgZGF0YSA9IG1lcmdlQ2xhc3NEYXRhKGNoaWxkTm9kZS5kYXRhLCBkYXRhKTtcbiAgICB9XG4gIH1cbiAgd2hpbGUgKChwYXJlbnROb2RlID0gcGFyZW50Tm9kZS5wYXJlbnQpKSB7XG4gICAgaWYgKHBhcmVudE5vZGUuZGF0YSkge1xuICAgICAgZGF0YSA9IG1lcmdlQ2xhc3NEYXRhKGRhdGEsIHBhcmVudE5vZGUuZGF0YSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBnZW5DbGFzc0Zyb21EYXRhKGRhdGEpXG59XG5cbmZ1bmN0aW9uIG1lcmdlQ2xhc3NEYXRhIChjaGlsZCwgcGFyZW50KSB7XG4gIHJldHVybiB7XG4gICAgc3RhdGljQ2xhc3M6IGNvbmNhdChjaGlsZC5zdGF0aWNDbGFzcywgcGFyZW50LnN0YXRpY0NsYXNzKSxcbiAgICBjbGFzczogY2hpbGQuY2xhc3NcbiAgICAgID8gW2NoaWxkLmNsYXNzLCBwYXJlbnQuY2xhc3NdXG4gICAgICA6IHBhcmVudC5jbGFzc1xuICB9XG59XG5cbmZ1bmN0aW9uIGdlbkNsYXNzRnJvbURhdGEgKGRhdGEpIHtcbiAgdmFyIGR5bmFtaWNDbGFzcyA9IGRhdGEuY2xhc3M7XG4gIHZhciBzdGF0aWNDbGFzcyA9IGRhdGEuc3RhdGljQ2xhc3M7XG4gIGlmIChzdGF0aWNDbGFzcyB8fCBkeW5hbWljQ2xhc3MpIHtcbiAgICByZXR1cm4gY29uY2F0KHN0YXRpY0NsYXNzLCBzdHJpbmdpZnlDbGFzcyhkeW5hbWljQ2xhc3MpKVxuICB9XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIHJldHVybiAnJ1xufVxuXG5mdW5jdGlvbiBjb25jYXQgKGEsIGIpIHtcbiAgcmV0dXJuIGEgPyBiID8gKGEgKyAnICcgKyBiKSA6IGEgOiAoYiB8fCAnJylcbn1cblxuZnVuY3Rpb24gc3RyaW5naWZ5Q2xhc3MgKHZhbHVlKSB7XG4gIHZhciByZXMgPSAnJztcbiAgaWYgKCF2YWx1ZSkge1xuICAgIHJldHVybiByZXNcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB2YWx1ZVxuICB9XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHZhciBzdHJpbmdpZmllZDtcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgaWYgKHZhbHVlW2ldKSB7XG4gICAgICAgIGlmICgoc3RyaW5naWZpZWQgPSBzdHJpbmdpZnlDbGFzcyh2YWx1ZVtpXSkpKSB7XG4gICAgICAgICAgcmVzICs9IHN0cmluZ2lmaWVkICsgJyAnO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXMuc2xpY2UoMCwgLTEpXG4gIH1cbiAgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xuICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgICAgaWYgKHZhbHVlW2tleV0pIHsgcmVzICs9IGtleSArICcgJzsgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzLnNsaWNlKDAsIC0xKVxuICB9XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIHJldHVybiByZXNcbn1cblxuLyogICovXG5cbnZhciBuYW1lc3BhY2VNYXAgPSB7XG4gIHN2ZzogJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyxcbiAgbWF0aDogJ2h0dHA6Ly93d3cudzMub3JnLzE5OTgvTWF0aC9NYXRoTUwnXG59O1xuXG52YXIgaXNIVE1MVGFnID0gbWFrZU1hcChcbiAgJ2h0bWwsYm9keSxiYXNlLGhlYWQsbGluayxtZXRhLHN0eWxlLHRpdGxlLCcgK1xuICAnYWRkcmVzcyxhcnRpY2xlLGFzaWRlLGZvb3RlcixoZWFkZXIsaDEsaDIsaDMsaDQsaDUsaDYsaGdyb3VwLG5hdixzZWN0aW9uLCcgK1xuICAnZGl2LGRkLGRsLGR0LGZpZ2NhcHRpb24sZmlndXJlLGhyLGltZyxsaSxtYWluLG9sLHAscHJlLHVsLCcgK1xuICAnYSxiLGFiYnIsYmRpLGJkbyxicixjaXRlLGNvZGUsZGF0YSxkZm4sZW0saSxrYmQsbWFyayxxLHJwLHJ0LHJ0YyxydWJ5LCcgK1xuICAncyxzYW1wLHNtYWxsLHNwYW4sc3Ryb25nLHN1YixzdXAsdGltZSx1LHZhcix3YnIsYXJlYSxhdWRpbyxtYXAsdHJhY2ssdmlkZW8sJyArXG4gICdlbWJlZCxvYmplY3QscGFyYW0sc291cmNlLGNhbnZhcyxzY3JpcHQsbm9zY3JpcHQsZGVsLGlucywnICtcbiAgJ2NhcHRpb24sY29sLGNvbGdyb3VwLHRhYmxlLHRoZWFkLHRib2R5LHRkLHRoLHRyLCcgK1xuICAnYnV0dG9uLGRhdGFsaXN0LGZpZWxkc2V0LGZvcm0saW5wdXQsbGFiZWwsbGVnZW5kLG1ldGVyLG9wdGdyb3VwLG9wdGlvbiwnICtcbiAgJ291dHB1dCxwcm9ncmVzcyxzZWxlY3QsdGV4dGFyZWEsJyArXG4gICdkZXRhaWxzLGRpYWxvZyxtZW51LG1lbnVpdGVtLHN1bW1hcnksJyArXG4gICdjb250ZW50LGVsZW1lbnQsc2hhZG93LHRlbXBsYXRlJ1xuKTtcblxudmFyIGlzVW5hcnlUYWcgPSBtYWtlTWFwKFxuICAnYXJlYSxiYXNlLGJyLGNvbCxlbWJlZCxmcmFtZSxocixpbWcsaW5wdXQsaXNpbmRleCxrZXlnZW4sJyArXG4gICdsaW5rLG1ldGEscGFyYW0sc291cmNlLHRyYWNrLHdicicsXG4gIHRydWVcbik7XG5cbi8vIEVsZW1lbnRzIHRoYXQgeW91IGNhbiwgaW50ZW50aW9uYWxseSwgbGVhdmUgb3BlblxuLy8gKGFuZCB3aGljaCBjbG9zZSB0aGVtc2VsdmVzKVxudmFyIGNhbkJlTGVmdE9wZW5UYWcgPSBtYWtlTWFwKFxuICAnY29sZ3JvdXAsZGQsZHQsbGksb3B0aW9ucyxwLHRkLHRmb290LHRoLHRoZWFkLHRyLHNvdXJjZScsXG4gIHRydWVcbik7XG5cbi8vIEhUTUw1IHRhZ3MgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvaW5kaWNlcy5odG1sI2VsZW1lbnRzLTNcbi8vIFBocmFzaW5nIENvbnRlbnQgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvZG9tLmh0bWwjcGhyYXNpbmctY29udGVudFxudmFyIGlzTm9uUGhyYXNpbmdUYWcgPSBtYWtlTWFwKFxuICAnYWRkcmVzcyxhcnRpY2xlLGFzaWRlLGJhc2UsYmxvY2txdW90ZSxib2R5LGNhcHRpb24sY29sLGNvbGdyb3VwLGRkLCcgK1xuICAnZGV0YWlscyxkaWFsb2csZGl2LGRsLGR0LGZpZWxkc2V0LGZpZ2NhcHRpb24sZmlndXJlLGZvb3Rlcixmb3JtLCcgK1xuICAnaDEsaDIsaDMsaDQsaDUsaDYsaGVhZCxoZWFkZXIsaGdyb3VwLGhyLGh0bWwsbGVnZW5kLGxpLG1lbnVpdGVtLG1ldGEsJyArXG4gICdvcHRncm91cCxvcHRpb24scGFyYW0scnAscnQsc291cmNlLHN0eWxlLHN1bW1hcnksdGJvZHksdGQsdGZvb3QsdGgsdGhlYWQsJyArXG4gICd0aXRsZSx0cix0cmFjaycsXG4gIHRydWVcbik7XG5cbi8vIHRoaXMgbWFwIGlzIGludGVudGlvbmFsbHkgc2VsZWN0aXZlLCBvbmx5IGNvdmVyaW5nIFNWRyBlbGVtZW50cyB0aGF0IG1heVxuLy8gY29udGFpbiBjaGlsZCBlbGVtZW50cy5cbnZhciBpc1NWRyA9IG1ha2VNYXAoXG4gICdzdmcsYW5pbWF0ZSxjaXJjbGUsY2xpcHBhdGgsY3Vyc29yLGRlZnMsZGVzYyxlbGxpcHNlLGZpbHRlcixmb250LCcgK1xuICAnZm9udC1mYWNlLGcsZ2x5cGgsaW1hZ2UsbGluZSxtYXJrZXIsbWFzayxtaXNzaW5nLWdseXBoLHBhdGgscGF0dGVybiwnICtcbiAgJ3BvbHlnb24scG9seWxpbmUscmVjdCxzd2l0Y2gsc3ltYm9sLHRleHQsdGV4dHBhdGgsdHNwYW4sdXNlLHZpZXcnLFxuICB0cnVlXG4pO1xuXG5cblxudmFyIGlzUmVzZXJ2ZWRUYWcgPSBmdW5jdGlvbiAodGFnKSB7XG4gIHJldHVybiBpc0hUTUxUYWcodGFnKSB8fCBpc1NWRyh0YWcpXG59O1xuXG5mdW5jdGlvbiBnZXRUYWdOYW1lc3BhY2UgKHRhZykge1xuICBpZiAoaXNTVkcodGFnKSkge1xuICAgIHJldHVybiAnc3ZnJ1xuICB9XG4gIC8vIGJhc2ljIHN1cHBvcnQgZm9yIE1hdGhNTFxuICAvLyBub3RlIGl0IGRvZXNuJ3Qgc3VwcG9ydCBvdGhlciBNYXRoTUwgZWxlbWVudHMgYmVpbmcgY29tcG9uZW50IHJvb3RzXG4gIGlmICh0YWcgPT09ICdtYXRoJykge1xuICAgIHJldHVybiAnbWF0aCdcbiAgfVxufVxuXG52YXIgdW5rbm93bkVsZW1lbnRDYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5mdW5jdGlvbiBpc1Vua25vd25FbGVtZW50ICh0YWcpIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmICghaW5Ccm93c2VyKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuICBpZiAoaXNSZXNlcnZlZFRhZyh0YWcpKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgdGFnID0gdGFnLnRvTG93ZXJDYXNlKCk7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAodW5rbm93bkVsZW1lbnRDYWNoZVt0YWddICE9IG51bGwpIHtcbiAgICByZXR1cm4gdW5rbm93bkVsZW1lbnRDYWNoZVt0YWddXG4gIH1cbiAgdmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWcpO1xuICBpZiAodGFnLmluZGV4T2YoJy0nKSA+IC0xKSB7XG4gICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjgyMTAzNjQvMTA3MDI0NFxuICAgIHJldHVybiAodW5rbm93bkVsZW1lbnRDYWNoZVt0YWddID0gKFxuICAgICAgZWwuY29uc3RydWN0b3IgPT09IHdpbmRvdy5IVE1MVW5rbm93bkVsZW1lbnQgfHxcbiAgICAgIGVsLmNvbnN0cnVjdG9yID09PSB3aW5kb3cuSFRNTEVsZW1lbnRcbiAgICApKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiAodW5rbm93bkVsZW1lbnRDYWNoZVt0YWddID0gL0hUTUxVbmtub3duRWxlbWVudC8udGVzdChlbC50b1N0cmluZygpKSlcbiAgfVxufVxuXG4vKiAgKi9cblxuLyoqXG4gKiBRdWVyeSBhbiBlbGVtZW50IHNlbGVjdG9yIGlmIGl0J3Mgbm90IGFuIGVsZW1lbnQgYWxyZWFkeS5cbiAqL1xuZnVuY3Rpb24gcXVlcnkgKGVsKSB7XG4gIGlmICh0eXBlb2YgZWwgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFyIHNlbGVjdG9yID0gZWw7XG4gICAgZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsKTtcbiAgICBpZiAoIWVsKSB7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oXG4gICAgICAgICdDYW5ub3QgZmluZCBlbGVtZW50OiAnICsgc2VsZWN0b3JcbiAgICAgICk7XG4gICAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGVsXG59XG5cbi8qICAqL1xuXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50JDEgKHRhZ05hbWUsIHZub2RlKSB7XG4gIHZhciBlbG0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZ05hbWUpO1xuICBpZiAodGFnTmFtZSAhPT0gJ3NlbGVjdCcpIHtcbiAgICByZXR1cm4gZWxtXG4gIH1cbiAgaWYgKHZub2RlLmRhdGEgJiYgdm5vZGUuZGF0YS5hdHRycyAmJiAnbXVsdGlwbGUnIGluIHZub2RlLmRhdGEuYXR0cnMpIHtcbiAgICBlbG0uc2V0QXR0cmlidXRlKCdtdWx0aXBsZScsICdtdWx0aXBsZScpO1xuICB9XG4gIHJldHVybiBlbG1cbn1cblxuZnVuY3Rpb24gY3JlYXRlRWxlbWVudE5TIChuYW1lc3BhY2UsIHRhZ05hbWUpIHtcbiAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VNYXBbbmFtZXNwYWNlXSwgdGFnTmFtZSlcbn1cblxuZnVuY3Rpb24gY3JlYXRlVGV4dE5vZGUgKHRleHQpIHtcbiAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNvbW1lbnQgKHRleHQpIHtcbiAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUNvbW1lbnQodGV4dClcbn1cblxuZnVuY3Rpb24gaW5zZXJ0QmVmb3JlIChwYXJlbnROb2RlLCBuZXdOb2RlLCByZWZlcmVuY2VOb2RlKSB7XG4gIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5ld05vZGUsIHJlZmVyZW5jZU5vZGUpO1xufVxuXG5mdW5jdGlvbiByZW1vdmVDaGlsZCAobm9kZSwgY2hpbGQpIHtcbiAgbm9kZS5yZW1vdmVDaGlsZChjaGlsZCk7XG59XG5cbmZ1bmN0aW9uIGFwcGVuZENoaWxkIChub2RlLCBjaGlsZCkge1xuICBub2RlLmFwcGVuZENoaWxkKGNoaWxkKTtcbn1cblxuZnVuY3Rpb24gcGFyZW50Tm9kZSAobm9kZSkge1xuICByZXR1cm4gbm9kZS5wYXJlbnROb2RlXG59XG5cbmZ1bmN0aW9uIG5leHRTaWJsaW5nIChub2RlKSB7XG4gIHJldHVybiBub2RlLm5leHRTaWJsaW5nXG59XG5cbmZ1bmN0aW9uIHRhZ05hbWUgKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUudGFnTmFtZVxufVxuXG5mdW5jdGlvbiBzZXRUZXh0Q29udGVudCAobm9kZSwgdGV4dCkge1xuICBub2RlLnRleHRDb250ZW50ID0gdGV4dDtcbn1cblxuZnVuY3Rpb24gY2hpbGROb2RlcyAobm9kZSkge1xuICByZXR1cm4gbm9kZS5jaGlsZE5vZGVzXG59XG5cbmZ1bmN0aW9uIHNldEF0dHJpYnV0ZSAobm9kZSwga2V5LCB2YWwpIHtcbiAgbm9kZS5zZXRBdHRyaWJ1dGUoa2V5LCB2YWwpO1xufVxuXG5cbnZhciBub2RlT3BzID0gT2JqZWN0LmZyZWV6ZSh7XG5cdGNyZWF0ZUVsZW1lbnQ6IGNyZWF0ZUVsZW1lbnQkMSxcblx0Y3JlYXRlRWxlbWVudE5TOiBjcmVhdGVFbGVtZW50TlMsXG5cdGNyZWF0ZVRleHROb2RlOiBjcmVhdGVUZXh0Tm9kZSxcblx0Y3JlYXRlQ29tbWVudDogY3JlYXRlQ29tbWVudCxcblx0aW5zZXJ0QmVmb3JlOiBpbnNlcnRCZWZvcmUsXG5cdHJlbW92ZUNoaWxkOiByZW1vdmVDaGlsZCxcblx0YXBwZW5kQ2hpbGQ6IGFwcGVuZENoaWxkLFxuXHRwYXJlbnROb2RlOiBwYXJlbnROb2RlLFxuXHRuZXh0U2libGluZzogbmV4dFNpYmxpbmcsXG5cdHRhZ05hbWU6IHRhZ05hbWUsXG5cdHNldFRleHRDb250ZW50OiBzZXRUZXh0Q29udGVudCxcblx0Y2hpbGROb2RlczogY2hpbGROb2Rlcyxcblx0c2V0QXR0cmlidXRlOiBzZXRBdHRyaWJ1dGVcbn0pO1xuXG4vKiAgKi9cblxudmFyIHJlZiA9IHtcbiAgY3JlYXRlOiBmdW5jdGlvbiBjcmVhdGUgKF8sIHZub2RlKSB7XG4gICAgcmVnaXN0ZXJSZWYodm5vZGUpO1xuICB9LFxuICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZSAob2xkVm5vZGUsIHZub2RlKSB7XG4gICAgaWYgKG9sZFZub2RlLmRhdGEucmVmICE9PSB2bm9kZS5kYXRhLnJlZikge1xuICAgICAgcmVnaXN0ZXJSZWYob2xkVm5vZGUsIHRydWUpO1xuICAgICAgcmVnaXN0ZXJSZWYodm5vZGUpO1xuICAgIH1cbiAgfSxcbiAgZGVzdHJveTogZnVuY3Rpb24gZGVzdHJveSAodm5vZGUpIHtcbiAgICByZWdpc3RlclJlZih2bm9kZSwgdHJ1ZSk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHJlZ2lzdGVyUmVmICh2bm9kZSwgaXNSZW1vdmFsKSB7XG4gIHZhciBrZXkgPSB2bm9kZS5kYXRhLnJlZjtcbiAgaWYgKCFrZXkpIHsgcmV0dXJuIH1cblxuICB2YXIgdm0gPSB2bm9kZS5jb250ZXh0O1xuICB2YXIgcmVmID0gdm5vZGUuY2hpbGQgfHwgdm5vZGUuZWxtO1xuICB2YXIgcmVmcyA9IHZtLiRyZWZzO1xuICBpZiAoaXNSZW1vdmFsKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocmVmc1trZXldKSkge1xuICAgICAgcmVtb3ZlJDEocmVmc1trZXldLCByZWYpO1xuICAgIH0gZWxzZSBpZiAocmVmc1trZXldID09PSByZWYpIHtcbiAgICAgIHJlZnNba2V5XSA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKHZub2RlLmRhdGEucmVmSW5Gb3IpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlZnNba2V5XSkpIHtcbiAgICAgICAgcmVmc1trZXldLnB1c2gocmVmKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlZnNba2V5XSA9IFtyZWZdO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZWZzW2tleV0gPSByZWY7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVmlydHVhbCBET00gcGF0Y2hpbmcgYWxnb3JpdGhtIGJhc2VkIG9uIFNuYWJiZG9tIGJ5XG4gKiBTaW1vbiBGcmlpcyBWaW5kdW0gKEBwYWxkZXBpbmQpXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2VcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9wYWxkZXBpbmQvc25hYmJkb20vYmxvYi9tYXN0ZXIvTElDRU5TRVxuICpcbiAqIG1vZGlmaWVkIGJ5IEV2YW4gWW91IChAeXl4OTkwODAzKVxuICpcblxuLypcbiAqIE5vdCB0eXBlLWNoZWNraW5nIHRoaXMgYmVjYXVzZSB0aGlzIGZpbGUgaXMgcGVyZi1jcml0aWNhbCBhbmQgdGhlIGNvc3RcbiAqIG9mIG1ha2luZyBmbG93IHVuZGVyc3RhbmQgaXQgaXMgbm90IHdvcnRoIGl0LlxuICovXG5cbnZhciBlbXB0eU5vZGUgPSBuZXcgVk5vZGUoJycsIHt9LCBbXSk7XG5cbnZhciBob29rcyQxID0gWydjcmVhdGUnLCAndXBkYXRlJywgJ3JlbW92ZScsICdkZXN0cm95J107XG5cbmZ1bmN0aW9uIGlzVW5kZWYgKHMpIHtcbiAgcmV0dXJuIHMgPT0gbnVsbFxufVxuXG5mdW5jdGlvbiBpc0RlZiAocykge1xuICByZXR1cm4gcyAhPSBudWxsXG59XG5cbmZ1bmN0aW9uIHNhbWVWbm9kZSAodm5vZGUxLCB2bm9kZTIpIHtcbiAgcmV0dXJuIChcbiAgICB2bm9kZTEua2V5ID09PSB2bm9kZTIua2V5ICYmXG4gICAgdm5vZGUxLnRhZyA9PT0gdm5vZGUyLnRhZyAmJlxuICAgIHZub2RlMS5pc0NvbW1lbnQgPT09IHZub2RlMi5pc0NvbW1lbnQgJiZcbiAgICAhdm5vZGUxLmRhdGEgPT09ICF2bm9kZTIuZGF0YVxuICApXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUtleVRvT2xkSWR4IChjaGlsZHJlbiwgYmVnaW5JZHgsIGVuZElkeCkge1xuICB2YXIgaSwga2V5O1xuICB2YXIgbWFwID0ge307XG4gIGZvciAoaSA9IGJlZ2luSWR4OyBpIDw9IGVuZElkeDsgKytpKSB7XG4gICAga2V5ID0gY2hpbGRyZW5baV0ua2V5O1xuICAgIGlmIChpc0RlZihrZXkpKSB7IG1hcFtrZXldID0gaTsgfVxuICB9XG4gIHJldHVybiBtYXBcbn1cblxuZnVuY3Rpb24gY3JlYXRlUGF0Y2hGdW5jdGlvbiAoYmFja2VuZCkge1xuICB2YXIgaSwgajtcbiAgdmFyIGNicyA9IHt9O1xuXG4gIHZhciBtb2R1bGVzID0gYmFja2VuZC5tb2R1bGVzO1xuICB2YXIgbm9kZU9wcyA9IGJhY2tlbmQubm9kZU9wcztcblxuICBmb3IgKGkgPSAwOyBpIDwgaG9va3MkMS5sZW5ndGg7ICsraSkge1xuICAgIGNic1tob29rcyQxW2ldXSA9IFtdO1xuICAgIGZvciAoaiA9IDA7IGogPCBtb2R1bGVzLmxlbmd0aDsgKytqKSB7XG4gICAgICBpZiAobW9kdWxlc1tqXVtob29rcyQxW2ldXSAhPT0gdW5kZWZpbmVkKSB7IGNic1tob29rcyQxW2ldXS5wdXNoKG1vZHVsZXNbal1baG9va3MkMVtpXV0pOyB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZW1wdHlOb2RlQXQgKGVsbSkge1xuICAgIHJldHVybiBuZXcgVk5vZGUobm9kZU9wcy50YWdOYW1lKGVsbSkudG9Mb3dlckNhc2UoKSwge30sIFtdLCB1bmRlZmluZWQsIGVsbSlcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVJtQ2IgKGNoaWxkRWxtLCBsaXN0ZW5lcnMpIHtcbiAgICBmdW5jdGlvbiByZW1vdmUkJDEgKCkge1xuICAgICAgaWYgKC0tcmVtb3ZlJCQxLmxpc3RlbmVycyA9PT0gMCkge1xuICAgICAgICByZW1vdmVFbGVtZW50KGNoaWxkRWxtKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmVtb3ZlJCQxLmxpc3RlbmVycyA9IGxpc3RlbmVycztcbiAgICByZXR1cm4gcmVtb3ZlJCQxXG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVFbGVtZW50IChlbCkge1xuICAgIHZhciBwYXJlbnQgPSBub2RlT3BzLnBhcmVudE5vZGUoZWwpO1xuICAgIG5vZGVPcHMucmVtb3ZlQ2hpbGQocGFyZW50LCBlbCk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVFbG0gKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUsIG5lc3RlZCkge1xuICAgIHZhciBpO1xuICAgIHZhciBkYXRhID0gdm5vZGUuZGF0YTtcbiAgICB2bm9kZS5pc1Jvb3RJbnNlcnQgPSAhbmVzdGVkO1xuICAgIGlmIChpc0RlZihkYXRhKSkge1xuICAgICAgaWYgKGlzRGVmKGkgPSBkYXRhLmhvb2spICYmIGlzRGVmKGkgPSBpLmluaXQpKSB7IGkodm5vZGUpOyB9XG4gICAgICAvLyBhZnRlciBjYWxsaW5nIHRoZSBpbml0IGhvb2ssIGlmIHRoZSB2bm9kZSBpcyBhIGNoaWxkIGNvbXBvbmVudFxuICAgICAgLy8gaXQgc2hvdWxkJ3ZlIGNyZWF0ZWQgYSBjaGlsZCBpbnN0YW5jZSBhbmQgbW91bnRlZCBpdC4gdGhlIGNoaWxkXG4gICAgICAvLyBjb21wb25lbnQgYWxzbyBoYXMgc2V0IHRoZSBwbGFjZWhvbGRlciB2bm9kZSdzIGVsbS5cbiAgICAgIC8vIGluIHRoYXQgY2FzZSB3ZSBjYW4ganVzdCByZXR1cm4gdGhlIGVsZW1lbnQgYW5kIGJlIGRvbmUuXG4gICAgICBpZiAoaXNEZWYoaSA9IHZub2RlLmNoaWxkKSkge1xuICAgICAgICBpbml0Q29tcG9uZW50KHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgICByZXR1cm4gdm5vZGUuZWxtXG4gICAgICB9XG4gICAgfVxuICAgIHZhciBjaGlsZHJlbiA9IHZub2RlLmNoaWxkcmVuO1xuICAgIHZhciB0YWcgPSB2bm9kZS50YWc7XG4gICAgaWYgKGlzRGVmKHRhZykpIHtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhdm5vZGUubnMgJiZcbiAgICAgICAgICAhKGNvbmZpZy5pZ25vcmVkRWxlbWVudHMgJiYgY29uZmlnLmlnbm9yZWRFbGVtZW50cy5pbmRleE9mKHRhZykgPiAtMSkgJiZcbiAgICAgICAgICBjb25maWcuaXNVbmtub3duRWxlbWVudCh0YWcpXG4gICAgICAgICkge1xuICAgICAgICAgIHdhcm4oXG4gICAgICAgICAgICAnVW5rbm93biBjdXN0b20gZWxlbWVudDogPCcgKyB0YWcgKyAnPiAtIGRpZCB5b3UgJyArXG4gICAgICAgICAgICAncmVnaXN0ZXIgdGhlIGNvbXBvbmVudCBjb3JyZWN0bHk/IEZvciByZWN1cnNpdmUgY29tcG9uZW50cywgJyArXG4gICAgICAgICAgICAnbWFrZSBzdXJlIHRvIHByb3ZpZGUgdGhlIFwibmFtZVwiIG9wdGlvbi4nLFxuICAgICAgICAgICAgdm5vZGUuY29udGV4dFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZub2RlLmVsbSA9IHZub2RlLm5zXG4gICAgICAgID8gbm9kZU9wcy5jcmVhdGVFbGVtZW50TlModm5vZGUubnMsIHRhZylcbiAgICAgICAgOiBub2RlT3BzLmNyZWF0ZUVsZW1lbnQodGFnLCB2bm9kZSk7XG4gICAgICBzZXRTY29wZSh2bm9kZSk7XG4gICAgICBjcmVhdGVDaGlsZHJlbih2bm9kZSwgY2hpbGRyZW4sIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICBpZiAoaXNEZWYoZGF0YSkpIHtcbiAgICAgICAgaW52b2tlQ3JlYXRlSG9va3Modm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh2bm9kZS5pc0NvbW1lbnQpIHtcbiAgICAgIHZub2RlLmVsbSA9IG5vZGVPcHMuY3JlYXRlQ29tbWVudCh2bm9kZS50ZXh0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdm5vZGUuZWxtID0gbm9kZU9wcy5jcmVhdGVUZXh0Tm9kZSh2bm9kZS50ZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuIHZub2RlLmVsbVxuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlQ2hpbGRyZW4gKHZub2RlLCBjaGlsZHJlbiwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoY2hpbGRyZW4pKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIG5vZGVPcHMuYXBwZW5kQ2hpbGQodm5vZGUuZWxtLCBjcmVhdGVFbG0oY2hpbGRyZW5baV0sIGluc2VydGVkVm5vZGVRdWV1ZSwgdHJ1ZSkpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNQcmltaXRpdmUodm5vZGUudGV4dCkpIHtcbiAgICAgIG5vZGVPcHMuYXBwZW5kQ2hpbGQodm5vZGUuZWxtLCBub2RlT3BzLmNyZWF0ZVRleHROb2RlKHZub2RlLnRleHQpKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpc1BhdGNoYWJsZSAodm5vZGUpIHtcbiAgICB3aGlsZSAodm5vZGUuY2hpbGQpIHtcbiAgICAgIHZub2RlID0gdm5vZGUuY2hpbGQuX3Zub2RlO1xuICAgIH1cbiAgICByZXR1cm4gaXNEZWYodm5vZGUudGFnKVxuICB9XG5cbiAgZnVuY3Rpb24gaW52b2tlQ3JlYXRlSG9va3MgKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpIHtcbiAgICBmb3IgKHZhciBpJDEgPSAwOyBpJDEgPCBjYnMuY3JlYXRlLmxlbmd0aDsgKytpJDEpIHtcbiAgICAgIGNicy5jcmVhdGVbaSQxXShlbXB0eU5vZGUsIHZub2RlKTtcbiAgICB9XG4gICAgaSA9IHZub2RlLmRhdGEuaG9vazsgLy8gUmV1c2UgdmFyaWFibGVcbiAgICBpZiAoaXNEZWYoaSkpIHtcbiAgICAgIGlmIChpLmNyZWF0ZSkgeyBpLmNyZWF0ZShlbXB0eU5vZGUsIHZub2RlKTsgfVxuICAgICAgaWYgKGkuaW5zZXJ0KSB7IGluc2VydGVkVm5vZGVRdWV1ZS5wdXNoKHZub2RlKTsgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRDb21wb25lbnQgKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpIHtcbiAgICBpZiAodm5vZGUuZGF0YS5wZW5kaW5nSW5zZXJ0KSB7XG4gICAgICBpbnNlcnRlZFZub2RlUXVldWUucHVzaC5hcHBseShpbnNlcnRlZFZub2RlUXVldWUsIHZub2RlLmRhdGEucGVuZGluZ0luc2VydCk7XG4gICAgfVxuICAgIHZub2RlLmVsbSA9IHZub2RlLmNoaWxkLiRlbDtcbiAgICBpZiAoaXNQYXRjaGFibGUodm5vZGUpKSB7XG4gICAgICBpbnZva2VDcmVhdGVIb29rcyh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcbiAgICAgIHNldFNjb3BlKHZub2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gZW1wdHkgY29tcG9uZW50IHJvb3QuXG4gICAgICAvLyBza2lwIGFsbCBlbGVtZW50LXJlbGF0ZWQgbW9kdWxlcyBleGNlcHQgZm9yIHJlZiAoIzM0NTUpXG4gICAgICByZWdpc3RlclJlZih2bm9kZSk7XG4gICAgICAvLyBtYWtlIHN1cmUgdG8gaW52b2tlIHRoZSBpbnNlcnQgaG9va1xuICAgICAgaW5zZXJ0ZWRWbm9kZVF1ZXVlLnB1c2godm5vZGUpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHNldCBzY29wZSBpZCBhdHRyaWJ1dGUgZm9yIHNjb3BlZCBDU1MuXG4gIC8vIHRoaXMgaXMgaW1wbGVtZW50ZWQgYXMgYSBzcGVjaWFsIGNhc2UgdG8gYXZvaWQgdGhlIG92ZXJoZWFkXG4gIC8vIG9mIGdvaW5nIHRocm91Z2ggdGhlIG5vcm1hbCBhdHRyaWJ1dGUgcGF0Y2hpbmcgcHJvY2Vzcy5cbiAgZnVuY3Rpb24gc2V0U2NvcGUgKHZub2RlKSB7XG4gICAgdmFyIGk7XG4gICAgaWYgKGlzRGVmKGkgPSB2bm9kZS5jb250ZXh0KSAmJiBpc0RlZihpID0gaS4kb3B0aW9ucy5fc2NvcGVJZCkpIHtcbiAgICAgIG5vZGVPcHMuc2V0QXR0cmlidXRlKHZub2RlLmVsbSwgaSwgJycpO1xuICAgIH1cbiAgICBpZiAoaXNEZWYoaSA9IGFjdGl2ZUluc3RhbmNlKSAmJlxuICAgICAgICBpICE9PSB2bm9kZS5jb250ZXh0ICYmXG4gICAgICAgIGlzRGVmKGkgPSBpLiRvcHRpb25zLl9zY29wZUlkKSkge1xuICAgICAgbm9kZU9wcy5zZXRBdHRyaWJ1dGUodm5vZGUuZWxtLCBpLCAnJyk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gYWRkVm5vZGVzIChwYXJlbnRFbG0sIGJlZm9yZSwgdm5vZGVzLCBzdGFydElkeCwgZW5kSWR4LCBpbnNlcnRlZFZub2RlUXVldWUpIHtcbiAgICBmb3IgKDsgc3RhcnRJZHggPD0gZW5kSWR4OyArK3N0YXJ0SWR4KSB7XG4gICAgICBub2RlT3BzLmluc2VydEJlZm9yZShwYXJlbnRFbG0sIGNyZWF0ZUVsbSh2bm9kZXNbc3RhcnRJZHhdLCBpbnNlcnRlZFZub2RlUXVldWUpLCBiZWZvcmUpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGludm9rZURlc3Ryb3lIb29rICh2bm9kZSkge1xuICAgIHZhciBpLCBqO1xuICAgIHZhciBkYXRhID0gdm5vZGUuZGF0YTtcbiAgICBpZiAoaXNEZWYoZGF0YSkpIHtcbiAgICAgIGlmIChpc0RlZihpID0gZGF0YS5ob29rKSAmJiBpc0RlZihpID0gaS5kZXN0cm95KSkgeyBpKHZub2RlKTsgfVxuICAgICAgZm9yIChpID0gMDsgaSA8IGNicy5kZXN0cm95Lmxlbmd0aDsgKytpKSB7IGNicy5kZXN0cm95W2ldKHZub2RlKTsgfVxuICAgIH1cbiAgICBpZiAoaXNEZWYoaSA9IHZub2RlLmNoaWxkcmVuKSkge1xuICAgICAgZm9yIChqID0gMDsgaiA8IHZub2RlLmNoaWxkcmVuLmxlbmd0aDsgKytqKSB7XG4gICAgICAgIGludm9rZURlc3Ryb3lIb29rKHZub2RlLmNoaWxkcmVuW2pdKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVWbm9kZXMgKHBhcmVudEVsbSwgdm5vZGVzLCBzdGFydElkeCwgZW5kSWR4KSB7XG4gICAgZm9yICg7IHN0YXJ0SWR4IDw9IGVuZElkeDsgKytzdGFydElkeCkge1xuICAgICAgdmFyIGNoID0gdm5vZGVzW3N0YXJ0SWR4XTtcbiAgICAgIGlmIChpc0RlZihjaCkpIHtcbiAgICAgICAgaWYgKGlzRGVmKGNoLnRhZykpIHtcbiAgICAgICAgICByZW1vdmVBbmRJbnZva2VSZW1vdmVIb29rKGNoKTtcbiAgICAgICAgICBpbnZva2VEZXN0cm95SG9vayhjaCk7XG4gICAgICAgIH0gZWxzZSB7IC8vIFRleHQgbm9kZVxuICAgICAgICAgIG5vZGVPcHMucmVtb3ZlQ2hpbGQocGFyZW50RWxtLCBjaC5lbG0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlQW5kSW52b2tlUmVtb3ZlSG9vayAodm5vZGUsIHJtKSB7XG4gICAgaWYgKHJtIHx8IGlzRGVmKHZub2RlLmRhdGEpKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzID0gY2JzLnJlbW92ZS5sZW5ndGggKyAxO1xuICAgICAgaWYgKCFybSkge1xuICAgICAgICAvLyBkaXJlY3RseSByZW1vdmluZ1xuICAgICAgICBybSA9IGNyZWF0ZVJtQ2Iodm5vZGUuZWxtLCBsaXN0ZW5lcnMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gd2UgaGF2ZSBhIHJlY3Vyc2l2ZWx5IHBhc3NlZCBkb3duIHJtIGNhbGxiYWNrXG4gICAgICAgIC8vIGluY3JlYXNlIHRoZSBsaXN0ZW5lcnMgY291bnRcbiAgICAgICAgcm0ubGlzdGVuZXJzICs9IGxpc3RlbmVycztcbiAgICAgIH1cbiAgICAgIC8vIHJlY3Vyc2l2ZWx5IGludm9rZSBob29rcyBvbiBjaGlsZCBjb21wb25lbnQgcm9vdCBub2RlXG4gICAgICBpZiAoaXNEZWYoaSA9IHZub2RlLmNoaWxkKSAmJiBpc0RlZihpID0gaS5fdm5vZGUpICYmIGlzRGVmKGkuZGF0YSkpIHtcbiAgICAgICAgcmVtb3ZlQW5kSW52b2tlUmVtb3ZlSG9vayhpLCBybSk7XG4gICAgICB9XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgY2JzLnJlbW92ZS5sZW5ndGg7ICsraSkge1xuICAgICAgICBjYnMucmVtb3ZlW2ldKHZub2RlLCBybSk7XG4gICAgICB9XG4gICAgICBpZiAoaXNEZWYoaSA9IHZub2RlLmRhdGEuaG9vaykgJiYgaXNEZWYoaSA9IGkucmVtb3ZlKSkge1xuICAgICAgICBpKHZub2RlLCBybSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBybSgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZW1vdmVFbGVtZW50KHZub2RlLmVsbSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlQ2hpbGRyZW4gKHBhcmVudEVsbSwgb2xkQ2gsIG5ld0NoLCBpbnNlcnRlZFZub2RlUXVldWUsIHJlbW92ZU9ubHkpIHtcbiAgICB2YXIgb2xkU3RhcnRJZHggPSAwO1xuICAgIHZhciBuZXdTdGFydElkeCA9IDA7XG4gICAgdmFyIG9sZEVuZElkeCA9IG9sZENoLmxlbmd0aCAtIDE7XG4gICAgdmFyIG9sZFN0YXJ0Vm5vZGUgPSBvbGRDaFswXTtcbiAgICB2YXIgb2xkRW5kVm5vZGUgPSBvbGRDaFtvbGRFbmRJZHhdO1xuICAgIHZhciBuZXdFbmRJZHggPSBuZXdDaC5sZW5ndGggLSAxO1xuICAgIHZhciBuZXdTdGFydFZub2RlID0gbmV3Q2hbMF07XG4gICAgdmFyIG5ld0VuZFZub2RlID0gbmV3Q2hbbmV3RW5kSWR4XTtcbiAgICB2YXIgb2xkS2V5VG9JZHgsIGlkeEluT2xkLCBlbG1Ub01vdmUsIGJlZm9yZTtcblxuICAgIC8vIHJlbW92ZU9ubHkgaXMgYSBzcGVjaWFsIGZsYWcgdXNlZCBvbmx5IGJ5IDx0cmFuc2l0aW9uLWdyb3VwPlxuICAgIC8vIHRvIGVuc3VyZSByZW1vdmVkIGVsZW1lbnRzIHN0YXkgaW4gY29ycmVjdCByZWxhdGl2ZSBwb3NpdGlvbnNcbiAgICAvLyBkdXJpbmcgbGVhdmluZyB0cmFuc2l0aW9uc1xuICAgIHZhciBjYW5Nb3ZlID0gIXJlbW92ZU9ubHk7XG5cbiAgICB3aGlsZSAob2xkU3RhcnRJZHggPD0gb2xkRW5kSWR4ICYmIG5ld1N0YXJ0SWR4IDw9IG5ld0VuZElkeCkge1xuICAgICAgaWYgKGlzVW5kZWYob2xkU3RhcnRWbm9kZSkpIHtcbiAgICAgICAgb2xkU3RhcnRWbm9kZSA9IG9sZENoWysrb2xkU3RhcnRJZHhdOyAvLyBWbm9kZSBoYXMgYmVlbiBtb3ZlZCBsZWZ0XG4gICAgICB9IGVsc2UgaWYgKGlzVW5kZWYob2xkRW5kVm5vZGUpKSB7XG4gICAgICAgIG9sZEVuZFZub2RlID0gb2xkQ2hbLS1vbGRFbmRJZHhdO1xuICAgICAgfSBlbHNlIGlmIChzYW1lVm5vZGUob2xkU3RhcnRWbm9kZSwgbmV3U3RhcnRWbm9kZSkpIHtcbiAgICAgICAgcGF0Y2hWbm9kZShvbGRTdGFydFZub2RlLCBuZXdTdGFydFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgICBvbGRTdGFydFZub2RlID0gb2xkQ2hbKytvbGRTdGFydElkeF07XG4gICAgICAgIG5ld1N0YXJ0Vm5vZGUgPSBuZXdDaFsrK25ld1N0YXJ0SWR4XTtcbiAgICAgIH0gZWxzZSBpZiAoc2FtZVZub2RlKG9sZEVuZFZub2RlLCBuZXdFbmRWbm9kZSkpIHtcbiAgICAgICAgcGF0Y2hWbm9kZShvbGRFbmRWbm9kZSwgbmV3RW5kVm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICAgIG9sZEVuZFZub2RlID0gb2xkQ2hbLS1vbGRFbmRJZHhdO1xuICAgICAgICBuZXdFbmRWbm9kZSA9IG5ld0NoWy0tbmV3RW5kSWR4XTtcbiAgICAgIH0gZWxzZSBpZiAoc2FtZVZub2RlKG9sZFN0YXJ0Vm5vZGUsIG5ld0VuZFZub2RlKSkgeyAvLyBWbm9kZSBtb3ZlZCByaWdodFxuICAgICAgICBwYXRjaFZub2RlKG9sZFN0YXJ0Vm5vZGUsIG5ld0VuZFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgICBjYW5Nb3ZlICYmIG5vZGVPcHMuaW5zZXJ0QmVmb3JlKHBhcmVudEVsbSwgb2xkU3RhcnRWbm9kZS5lbG0sIG5vZGVPcHMubmV4dFNpYmxpbmcob2xkRW5kVm5vZGUuZWxtKSk7XG4gICAgICAgIG9sZFN0YXJ0Vm5vZGUgPSBvbGRDaFsrK29sZFN0YXJ0SWR4XTtcbiAgICAgICAgbmV3RW5kVm5vZGUgPSBuZXdDaFstLW5ld0VuZElkeF07XG4gICAgICB9IGVsc2UgaWYgKHNhbWVWbm9kZShvbGRFbmRWbm9kZSwgbmV3U3RhcnRWbm9kZSkpIHsgLy8gVm5vZGUgbW92ZWQgbGVmdFxuICAgICAgICBwYXRjaFZub2RlKG9sZEVuZFZub2RlLCBuZXdTdGFydFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgICBjYW5Nb3ZlICYmIG5vZGVPcHMuaW5zZXJ0QmVmb3JlKHBhcmVudEVsbSwgb2xkRW5kVm5vZGUuZWxtLCBvbGRTdGFydFZub2RlLmVsbSk7XG4gICAgICAgIG9sZEVuZFZub2RlID0gb2xkQ2hbLS1vbGRFbmRJZHhdO1xuICAgICAgICBuZXdTdGFydFZub2RlID0gbmV3Q2hbKytuZXdTdGFydElkeF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaXNVbmRlZihvbGRLZXlUb0lkeCkpIHsgb2xkS2V5VG9JZHggPSBjcmVhdGVLZXlUb09sZElkeChvbGRDaCwgb2xkU3RhcnRJZHgsIG9sZEVuZElkeCk7IH1cbiAgICAgICAgaWR4SW5PbGQgPSBpc0RlZihuZXdTdGFydFZub2RlLmtleSkgPyBvbGRLZXlUb0lkeFtuZXdTdGFydFZub2RlLmtleV0gOiBudWxsO1xuICAgICAgICBpZiAoaXNVbmRlZihpZHhJbk9sZCkpIHsgLy8gTmV3IGVsZW1lbnRcbiAgICAgICAgICBub2RlT3BzLmluc2VydEJlZm9yZShwYXJlbnRFbG0sIGNyZWF0ZUVsbShuZXdTdGFydFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpLCBvbGRTdGFydFZub2RlLmVsbSk7XG4gICAgICAgICAgbmV3U3RhcnRWbm9kZSA9IG5ld0NoWysrbmV3U3RhcnRJZHhdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVsbVRvTW92ZSA9IG9sZENoW2lkeEluT2xkXTtcbiAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiAhZWxtVG9Nb3ZlKSB7XG4gICAgICAgICAgICB3YXJuKFxuICAgICAgICAgICAgICAnSXQgc2VlbXMgdGhlcmUgYXJlIGR1cGxpY2F0ZSBrZXlzIHRoYXQgaXMgY2F1c2luZyBhbiB1cGRhdGUgZXJyb3IuICcgK1xuICAgICAgICAgICAgICAnTWFrZSBzdXJlIGVhY2ggdi1mb3IgaXRlbSBoYXMgYSB1bmlxdWUga2V5LidcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChlbG1Ub01vdmUudGFnICE9PSBuZXdTdGFydFZub2RlLnRhZykge1xuICAgICAgICAgICAgLy8gc2FtZSBrZXkgYnV0IGRpZmZlcmVudCBlbGVtZW50LiB0cmVhdCBhcyBuZXcgZWxlbWVudFxuICAgICAgICAgICAgbm9kZU9wcy5pbnNlcnRCZWZvcmUocGFyZW50RWxtLCBjcmVhdGVFbG0obmV3U3RhcnRWbm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKSwgb2xkU3RhcnRWbm9kZS5lbG0pO1xuICAgICAgICAgICAgbmV3U3RhcnRWbm9kZSA9IG5ld0NoWysrbmV3U3RhcnRJZHhdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXRjaFZub2RlKGVsbVRvTW92ZSwgbmV3U3RhcnRWbm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcbiAgICAgICAgICAgIG9sZENoW2lkeEluT2xkXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGNhbk1vdmUgJiYgbm9kZU9wcy5pbnNlcnRCZWZvcmUocGFyZW50RWxtLCBuZXdTdGFydFZub2RlLmVsbSwgb2xkU3RhcnRWbm9kZS5lbG0pO1xuICAgICAgICAgICAgbmV3U3RhcnRWbm9kZSA9IG5ld0NoWysrbmV3U3RhcnRJZHhdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAob2xkU3RhcnRJZHggPiBvbGRFbmRJZHgpIHtcbiAgICAgIGJlZm9yZSA9IGlzVW5kZWYobmV3Q2hbbmV3RW5kSWR4ICsgMV0pID8gbnVsbCA6IG5ld0NoW25ld0VuZElkeCArIDFdLmVsbTtcbiAgICAgIGFkZFZub2RlcyhwYXJlbnRFbG0sIGJlZm9yZSwgbmV3Q2gsIG5ld1N0YXJ0SWR4LCBuZXdFbmRJZHgsIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgfSBlbHNlIGlmIChuZXdTdGFydElkeCA+IG5ld0VuZElkeCkge1xuICAgICAgcmVtb3ZlVm5vZGVzKHBhcmVudEVsbSwgb2xkQ2gsIG9sZFN0YXJ0SWR4LCBvbGRFbmRJZHgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHBhdGNoVm5vZGUgKG9sZFZub2RlLCB2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCByZW1vdmVPbmx5KSB7XG4gICAgaWYgKG9sZFZub2RlID09PSB2bm9kZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIC8vIHJldXNlIGVsZW1lbnQgZm9yIHN0YXRpYyB0cmVlcy5cbiAgICAvLyBub3RlIHdlIG9ubHkgZG8gdGhpcyBpZiB0aGUgdm5vZGUgaXMgY2xvbmVkIC1cbiAgICAvLyBpZiB0aGUgbmV3IG5vZGUgaXMgbm90IGNsb25lZCBpdCBtZWFucyB0aGUgcmVuZGVyIGZ1bmN0aW9ucyBoYXZlIGJlZW5cbiAgICAvLyByZXNldCBieSB0aGUgaG90LXJlbG9hZC1hcGkgYW5kIHdlIG5lZWQgdG8gZG8gYSBwcm9wZXIgcmUtcmVuZGVyLlxuICAgIGlmICh2bm9kZS5pc1N0YXRpYyAmJlxuICAgICAgICBvbGRWbm9kZS5pc1N0YXRpYyAmJlxuICAgICAgICB2bm9kZS5rZXkgPT09IG9sZFZub2RlLmtleSAmJlxuICAgICAgICB2bm9kZS5pc0Nsb25lZCkge1xuICAgICAgdm5vZGUuZWxtID0gb2xkVm5vZGUuZWxtO1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIHZhciBpO1xuICAgIHZhciBkYXRhID0gdm5vZGUuZGF0YTtcbiAgICB2YXIgaGFzRGF0YSA9IGlzRGVmKGRhdGEpO1xuICAgIGlmIChoYXNEYXRhICYmIGlzRGVmKGkgPSBkYXRhLmhvb2spICYmIGlzRGVmKGkgPSBpLnByZXBhdGNoKSkge1xuICAgICAgaShvbGRWbm9kZSwgdm5vZGUpO1xuICAgIH1cbiAgICB2YXIgZWxtID0gdm5vZGUuZWxtID0gb2xkVm5vZGUuZWxtO1xuICAgIHZhciBvbGRDaCA9IG9sZFZub2RlLmNoaWxkcmVuO1xuICAgIHZhciBjaCA9IHZub2RlLmNoaWxkcmVuO1xuICAgIGlmIChoYXNEYXRhICYmIGlzUGF0Y2hhYmxlKHZub2RlKSkge1xuICAgICAgZm9yIChpID0gMDsgaSA8IGNicy51cGRhdGUubGVuZ3RoOyArK2kpIHsgY2JzLnVwZGF0ZVtpXShvbGRWbm9kZSwgdm5vZGUpOyB9XG4gICAgICBpZiAoaXNEZWYoaSA9IGRhdGEuaG9vaykgJiYgaXNEZWYoaSA9IGkudXBkYXRlKSkgeyBpKG9sZFZub2RlLCB2bm9kZSk7IH1cbiAgICB9XG4gICAgaWYgKGlzVW5kZWYodm5vZGUudGV4dCkpIHtcbiAgICAgIGlmIChpc0RlZihvbGRDaCkgJiYgaXNEZWYoY2gpKSB7XG4gICAgICAgIGlmIChvbGRDaCAhPT0gY2gpIHsgdXBkYXRlQ2hpbGRyZW4oZWxtLCBvbGRDaCwgY2gsIGluc2VydGVkVm5vZGVRdWV1ZSwgcmVtb3ZlT25seSk7IH1cbiAgICAgIH0gZWxzZSBpZiAoaXNEZWYoY2gpKSB7XG4gICAgICAgIGlmIChpc0RlZihvbGRWbm9kZS50ZXh0KSkgeyBub2RlT3BzLnNldFRleHRDb250ZW50KGVsbSwgJycpOyB9XG4gICAgICAgIGFkZFZub2RlcyhlbG0sIG51bGwsIGNoLCAwLCBjaC5sZW5ndGggLSAxLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgfSBlbHNlIGlmIChpc0RlZihvbGRDaCkpIHtcbiAgICAgICAgcmVtb3ZlVm5vZGVzKGVsbSwgb2xkQ2gsIDAsIG9sZENoLmxlbmd0aCAtIDEpO1xuICAgICAgfSBlbHNlIGlmIChpc0RlZihvbGRWbm9kZS50ZXh0KSkge1xuICAgICAgICBub2RlT3BzLnNldFRleHRDb250ZW50KGVsbSwgJycpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAob2xkVm5vZGUudGV4dCAhPT0gdm5vZGUudGV4dCkge1xuICAgICAgbm9kZU9wcy5zZXRUZXh0Q29udGVudChlbG0sIHZub2RlLnRleHQpO1xuICAgIH1cbiAgICBpZiAoaGFzRGF0YSkge1xuICAgICAgaWYgKGlzRGVmKGkgPSBkYXRhLmhvb2spICYmIGlzRGVmKGkgPSBpLnBvc3RwYXRjaCkpIHsgaShvbGRWbm9kZSwgdm5vZGUpOyB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW52b2tlSW5zZXJ0SG9vayAodm5vZGUsIHF1ZXVlLCBpbml0aWFsKSB7XG4gICAgLy8gZGVsYXkgaW5zZXJ0IGhvb2tzIGZvciBjb21wb25lbnQgcm9vdCBub2RlcywgaW52b2tlIHRoZW0gYWZ0ZXIgdGhlXG4gICAgLy8gZWxlbWVudCBpcyByZWFsbHkgaW5zZXJ0ZWRcbiAgICBpZiAoaW5pdGlhbCAmJiB2bm9kZS5wYXJlbnQpIHtcbiAgICAgIHZub2RlLnBhcmVudC5kYXRhLnBlbmRpbmdJbnNlcnQgPSBxdWV1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBxdWV1ZS5sZW5ndGg7ICsraSkge1xuICAgICAgICBxdWV1ZVtpXS5kYXRhLmhvb2suaW5zZXJ0KHF1ZXVlW2ldKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgYmFpbGVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGh5ZHJhdGUgKGVsbSwgdm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSkge1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICBpZiAoIWFzc2VydE5vZGVNYXRjaChlbG0sIHZub2RlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICB9XG4gICAgdm5vZGUuZWxtID0gZWxtO1xuICAgIHZhciB0YWcgPSB2bm9kZS50YWc7XG4gICAgdmFyIGRhdGEgPSB2bm9kZS5kYXRhO1xuICAgIHZhciBjaGlsZHJlbiA9IHZub2RlLmNoaWxkcmVuO1xuICAgIGlmIChpc0RlZihkYXRhKSkge1xuICAgICAgaWYgKGlzRGVmKGkgPSBkYXRhLmhvb2spICYmIGlzRGVmKGkgPSBpLmluaXQpKSB7IGkodm5vZGUsIHRydWUgLyogaHlkcmF0aW5nICovKTsgfVxuICAgICAgaWYgKGlzRGVmKGkgPSB2bm9kZS5jaGlsZCkpIHtcbiAgICAgICAgLy8gY2hpbGQgY29tcG9uZW50LiBpdCBzaG91bGQgaGF2ZSBoeWRyYXRlZCBpdHMgb3duIHRyZWUuXG4gICAgICAgIGluaXRDb21wb25lbnQodm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpc0RlZih0YWcpKSB7XG4gICAgICBpZiAoaXNEZWYoY2hpbGRyZW4pKSB7XG4gICAgICAgIHZhciBjaGlsZE5vZGVzID0gbm9kZU9wcy5jaGlsZE5vZGVzKGVsbSk7XG4gICAgICAgIC8vIGVtcHR5IGVsZW1lbnQsIGFsbG93IGNsaWVudCB0byBwaWNrIHVwIGFuZCBwb3B1bGF0ZSBjaGlsZHJlblxuICAgICAgICBpZiAoIWNoaWxkTm9kZXMubGVuZ3RoKSB7XG4gICAgICAgICAgY3JlYXRlQ2hpbGRyZW4odm5vZGUsIGNoaWxkcmVuLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBjaGlsZHJlbk1hdGNoID0gdHJ1ZTtcbiAgICAgICAgICBpZiAoY2hpbGROb2Rlcy5sZW5ndGggIT09IGNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICAgICAgY2hpbGRyZW5NYXRjaCA9IGZhbHNlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpJDEgPSAwOyBpJDEgPCBjaGlsZHJlbi5sZW5ndGg7IGkkMSsrKSB7XG4gICAgICAgICAgICAgIGlmICghaHlkcmF0ZShjaGlsZE5vZGVzW2kkMV0sIGNoaWxkcmVuW2kkMV0sIGluc2VydGVkVm5vZGVRdWV1ZSkpIHtcbiAgICAgICAgICAgICAgICBjaGlsZHJlbk1hdGNoID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWNoaWxkcmVuTWF0Y2gpIHtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgICAgICAgIWJhaWxlZCkge1xuICAgICAgICAgICAgICBiYWlsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1BhcmVudDogJywgZWxtKTtcbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdNaXNtYXRjaGluZyBjaGlsZE5vZGVzIHZzLiBWTm9kZXM6ICcsIGNoaWxkTm9kZXMsIGNoaWxkcmVuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlzRGVmKGRhdGEpKSB7XG4gICAgICAgIGludm9rZUNyZWF0ZUhvb2tzKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgZnVuY3Rpb24gYXNzZXJ0Tm9kZU1hdGNoIChub2RlLCB2bm9kZSkge1xuICAgIGlmICh2bm9kZS50YWcpIHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIHZub2RlLnRhZy5pbmRleE9mKCd2dWUtY29tcG9uZW50JykgPT09IDAgfHxcbiAgICAgICAgdm5vZGUudGFnID09PSBub2RlT3BzLnRhZ05hbWUobm9kZSkudG9Mb3dlckNhc2UoKVxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gX3RvU3RyaW5nKHZub2RlLnRleHQpID09PSBub2RlLmRhdGFcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gcGF0Y2ggKG9sZFZub2RlLCB2bm9kZSwgaHlkcmF0aW5nLCByZW1vdmVPbmx5KSB7XG4gICAgaWYgKCF2bm9kZSkge1xuICAgICAgaWYgKG9sZFZub2RlKSB7IGludm9rZURlc3Ryb3lIb29rKG9sZFZub2RlKTsgfVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdmFyIGVsbSwgcGFyZW50O1xuICAgIHZhciBpc0luaXRpYWxQYXRjaCA9IGZhbHNlO1xuICAgIHZhciBpbnNlcnRlZFZub2RlUXVldWUgPSBbXTtcblxuICAgIGlmICghb2xkVm5vZGUpIHtcbiAgICAgIC8vIGVtcHR5IG1vdW50LCBjcmVhdGUgbmV3IHJvb3QgZWxlbWVudFxuICAgICAgaXNJbml0aWFsUGF0Y2ggPSB0cnVlO1xuICAgICAgY3JlYXRlRWxtKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgaXNSZWFsRWxlbWVudCA9IGlzRGVmKG9sZFZub2RlLm5vZGVUeXBlKTtcbiAgICAgIGlmICghaXNSZWFsRWxlbWVudCAmJiBzYW1lVm5vZGUob2xkVm5vZGUsIHZub2RlKSkge1xuICAgICAgICBwYXRjaFZub2RlKG9sZFZub2RlLCB2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCByZW1vdmVPbmx5KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChpc1JlYWxFbGVtZW50KSB7XG4gICAgICAgICAgLy8gbW91bnRpbmcgdG8gYSByZWFsIGVsZW1lbnRcbiAgICAgICAgICAvLyBjaGVjayBpZiB0aGlzIGlzIHNlcnZlci1yZW5kZXJlZCBjb250ZW50IGFuZCBpZiB3ZSBjYW4gcGVyZm9ybVxuICAgICAgICAgIC8vIGEgc3VjY2Vzc2Z1bCBoeWRyYXRpb24uXG4gICAgICAgICAgaWYgKG9sZFZub2RlLm5vZGVUeXBlID09PSAxICYmIG9sZFZub2RlLmhhc0F0dHJpYnV0ZSgnc2VydmVyLXJlbmRlcmVkJykpIHtcbiAgICAgICAgICAgIG9sZFZub2RlLnJlbW92ZUF0dHJpYnV0ZSgnc2VydmVyLXJlbmRlcmVkJyk7XG4gICAgICAgICAgICBoeWRyYXRpbmcgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaHlkcmF0aW5nKSB7XG4gICAgICAgICAgICBpZiAoaHlkcmF0ZShvbGRWbm9kZSwgdm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSkpIHtcbiAgICAgICAgICAgICAgaW52b2tlSW5zZXJ0SG9vayh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCB0cnVlKTtcbiAgICAgICAgICAgICAgcmV0dXJuIG9sZFZub2RlXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgICAgICAgd2FybihcbiAgICAgICAgICAgICAgICAnVGhlIGNsaWVudC1zaWRlIHJlbmRlcmVkIHZpcnR1YWwgRE9NIHRyZWUgaXMgbm90IG1hdGNoaW5nICcgK1xuICAgICAgICAgICAgICAgICdzZXJ2ZXItcmVuZGVyZWQgY29udGVudC4gVGhpcyBpcyBsaWtlbHkgY2F1c2VkIGJ5IGluY29ycmVjdCAnICtcbiAgICAgICAgICAgICAgICAnSFRNTCBtYXJrdXAsIGZvciBleGFtcGxlIG5lc3RpbmcgYmxvY2stbGV2ZWwgZWxlbWVudHMgaW5zaWRlICcgK1xuICAgICAgICAgICAgICAgICc8cD4sIG9yIG1pc3NpbmcgPHRib2R5Pi4gQmFpbGluZyBoeWRyYXRpb24gYW5kIHBlcmZvcm1pbmcgJyArXG4gICAgICAgICAgICAgICAgJ2Z1bGwgY2xpZW50LXNpZGUgcmVuZGVyLidcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gZWl0aGVyIG5vdCBzZXJ2ZXItcmVuZGVyZWQsIG9yIGh5ZHJhdGlvbiBmYWlsZWQuXG4gICAgICAgICAgLy8gY3JlYXRlIGFuIGVtcHR5IG5vZGUgYW5kIHJlcGxhY2UgaXRcbiAgICAgICAgICBvbGRWbm9kZSA9IGVtcHR5Tm9kZUF0KG9sZFZub2RlKTtcbiAgICAgICAgfVxuICAgICAgICBlbG0gPSBvbGRWbm9kZS5lbG07XG4gICAgICAgIHBhcmVudCA9IG5vZGVPcHMucGFyZW50Tm9kZShlbG0pO1xuXG4gICAgICAgIGNyZWF0ZUVsbSh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcblxuICAgICAgICAvLyBjb21wb25lbnQgcm9vdCBlbGVtZW50IHJlcGxhY2VkLlxuICAgICAgICAvLyB1cGRhdGUgcGFyZW50IHBsYWNlaG9sZGVyIG5vZGUgZWxlbWVudC5cbiAgICAgICAgaWYgKHZub2RlLnBhcmVudCkge1xuICAgICAgICAgIHZub2RlLnBhcmVudC5lbG0gPSB2bm9kZS5lbG07XG4gICAgICAgICAgaWYgKGlzUGF0Y2hhYmxlKHZub2RlKSkge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYnMuY3JlYXRlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgIGNicy5jcmVhdGVbaV0oZW1wdHlOb2RlLCB2bm9kZS5wYXJlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICBub2RlT3BzLmluc2VydEJlZm9yZShwYXJlbnQsIHZub2RlLmVsbSwgbm9kZU9wcy5uZXh0U2libGluZyhlbG0pKTtcbiAgICAgICAgICByZW1vdmVWbm9kZXMocGFyZW50LCBbb2xkVm5vZGVdLCAwLCAwKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc0RlZihvbGRWbm9kZS50YWcpKSB7XG4gICAgICAgICAgaW52b2tlRGVzdHJveUhvb2sob2xkVm5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaW52b2tlSW5zZXJ0SG9vayh2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlLCBpc0luaXRpYWxQYXRjaCk7XG4gICAgcmV0dXJuIHZub2RlLmVsbVxuICB9XG59XG5cbi8qICAqL1xuXG52YXIgZGlyZWN0aXZlcyA9IHtcbiAgY3JlYXRlOiB1cGRhdGVEaXJlY3RpdmVzLFxuICB1cGRhdGU6IHVwZGF0ZURpcmVjdGl2ZXMsXG4gIGRlc3Ryb3k6IGZ1bmN0aW9uIHVuYmluZERpcmVjdGl2ZXMgKHZub2RlKSB7XG4gICAgdXBkYXRlRGlyZWN0aXZlcyh2bm9kZSwgZW1wdHlOb2RlKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gdXBkYXRlRGlyZWN0aXZlcyAoXG4gIG9sZFZub2RlLFxuICB2bm9kZVxuKSB7XG4gIGlmICghb2xkVm5vZGUuZGF0YS5kaXJlY3RpdmVzICYmICF2bm9kZS5kYXRhLmRpcmVjdGl2ZXMpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgaXNDcmVhdGUgPSBvbGRWbm9kZSA9PT0gZW1wdHlOb2RlO1xuICB2YXIgb2xkRGlycyA9IG5vcm1hbGl6ZURpcmVjdGl2ZXMkMShvbGRWbm9kZS5kYXRhLmRpcmVjdGl2ZXMsIG9sZFZub2RlLmNvbnRleHQpO1xuICB2YXIgbmV3RGlycyA9IG5vcm1hbGl6ZURpcmVjdGl2ZXMkMSh2bm9kZS5kYXRhLmRpcmVjdGl2ZXMsIHZub2RlLmNvbnRleHQpO1xuXG4gIHZhciBkaXJzV2l0aEluc2VydCA9IFtdO1xuICB2YXIgZGlyc1dpdGhQb3N0cGF0Y2ggPSBbXTtcblxuICB2YXIga2V5LCBvbGREaXIsIGRpcjtcbiAgZm9yIChrZXkgaW4gbmV3RGlycykge1xuICAgIG9sZERpciA9IG9sZERpcnNba2V5XTtcbiAgICBkaXIgPSBuZXdEaXJzW2tleV07XG4gICAgaWYgKCFvbGREaXIpIHtcbiAgICAgIC8vIG5ldyBkaXJlY3RpdmUsIGJpbmRcbiAgICAgIGNhbGxIb29rJDEoZGlyLCAnYmluZCcsIHZub2RlLCBvbGRWbm9kZSk7XG4gICAgICBpZiAoZGlyLmRlZiAmJiBkaXIuZGVmLmluc2VydGVkKSB7XG4gICAgICAgIGRpcnNXaXRoSW5zZXJ0LnB1c2goZGlyKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gZXhpc3RpbmcgZGlyZWN0aXZlLCB1cGRhdGVcbiAgICAgIGRpci5vbGRWYWx1ZSA9IG9sZERpci52YWx1ZTtcbiAgICAgIGNhbGxIb29rJDEoZGlyLCAndXBkYXRlJywgdm5vZGUsIG9sZFZub2RlKTtcbiAgICAgIGlmIChkaXIuZGVmICYmIGRpci5kZWYuY29tcG9uZW50VXBkYXRlZCkge1xuICAgICAgICBkaXJzV2l0aFBvc3RwYXRjaC5wdXNoKGRpcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGRpcnNXaXRoSW5zZXJ0Lmxlbmd0aCkge1xuICAgIHZhciBjYWxsSW5zZXJ0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgZGlyc1dpdGhJbnNlcnQuZm9yRWFjaChmdW5jdGlvbiAoZGlyKSB7XG4gICAgICAgIGNhbGxIb29rJDEoZGlyLCAnaW5zZXJ0ZWQnLCB2bm9kZSwgb2xkVm5vZGUpO1xuICAgICAgfSk7XG4gICAgfTtcbiAgICBpZiAoaXNDcmVhdGUpIHtcbiAgICAgIG1lcmdlVk5vZGVIb29rKHZub2RlLmRhdGEuaG9vayB8fCAodm5vZGUuZGF0YS5ob29rID0ge30pLCAnaW5zZXJ0JywgY2FsbEluc2VydCwgJ2Rpci1pbnNlcnQnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2FsbEluc2VydCgpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChkaXJzV2l0aFBvc3RwYXRjaC5sZW5ndGgpIHtcbiAgICBtZXJnZVZOb2RlSG9vayh2bm9kZS5kYXRhLmhvb2sgfHwgKHZub2RlLmRhdGEuaG9vayA9IHt9KSwgJ3Bvc3RwYXRjaCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGRpcnNXaXRoUG9zdHBhdGNoLmZvckVhY2goZnVuY3Rpb24gKGRpcikge1xuICAgICAgICBjYWxsSG9vayQxKGRpciwgJ2NvbXBvbmVudFVwZGF0ZWQnLCB2bm9kZSwgb2xkVm5vZGUpO1xuICAgICAgfSk7XG4gICAgfSwgJ2Rpci1wb3N0cGF0Y2gnKTtcbiAgfVxuXG4gIGlmICghaXNDcmVhdGUpIHtcbiAgICBmb3IgKGtleSBpbiBvbGREaXJzKSB7XG4gICAgICBpZiAoIW5ld0RpcnNba2V5XSkge1xuICAgICAgICAvLyBubyBsb25nZXIgcHJlc2VudCwgdW5iaW5kXG4gICAgICAgIGNhbGxIb29rJDEob2xkRGlyc1trZXldLCAndW5iaW5kJywgb2xkVm5vZGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG52YXIgZW1wdHlNb2RpZmllcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG5mdW5jdGlvbiBub3JtYWxpemVEaXJlY3RpdmVzJDEgKFxuICBkaXJzLFxuICB2bVxuKSB7XG4gIHZhciByZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICBpZiAoIWRpcnMpIHtcbiAgICByZXR1cm4gcmVzXG4gIH1cbiAgdmFyIGksIGRpcjtcbiAgZm9yIChpID0gMDsgaSA8IGRpcnMubGVuZ3RoOyBpKyspIHtcbiAgICBkaXIgPSBkaXJzW2ldO1xuICAgIGlmICghZGlyLm1vZGlmaWVycykge1xuICAgICAgZGlyLm1vZGlmaWVycyA9IGVtcHR5TW9kaWZpZXJzO1xuICAgIH1cbiAgICByZXNbZ2V0UmF3RGlyTmFtZShkaXIpXSA9IGRpcjtcbiAgICBkaXIuZGVmID0gcmVzb2x2ZUFzc2V0KHZtLiRvcHRpb25zLCAnZGlyZWN0aXZlcycsIGRpci5uYW1lLCB0cnVlKTtcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbmZ1bmN0aW9uIGdldFJhd0Rpck5hbWUgKGRpcikge1xuICByZXR1cm4gZGlyLnJhd05hbWUgfHwgKChkaXIubmFtZSkgKyBcIi5cIiArIChPYmplY3Qua2V5cyhkaXIubW9kaWZpZXJzIHx8IHt9KS5qb2luKCcuJykpKVxufVxuXG5mdW5jdGlvbiBjYWxsSG9vayQxIChkaXIsIGhvb2ssIHZub2RlLCBvbGRWbm9kZSkge1xuICB2YXIgZm4gPSBkaXIuZGVmICYmIGRpci5kZWZbaG9va107XG4gIGlmIChmbikge1xuICAgIGZuKHZub2RlLmVsbSwgZGlyLCB2bm9kZSwgb2xkVm5vZGUpO1xuICB9XG59XG5cbnZhciBiYXNlTW9kdWxlcyA9IFtcbiAgcmVmLFxuICBkaXJlY3RpdmVzXG5dO1xuXG4vKiAgKi9cblxuZnVuY3Rpb24gdXBkYXRlQXR0cnMgKG9sZFZub2RlLCB2bm9kZSkge1xuICBpZiAoIW9sZFZub2RlLmRhdGEuYXR0cnMgJiYgIXZub2RlLmRhdGEuYXR0cnMpIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIga2V5LCBjdXIsIG9sZDtcbiAgdmFyIGVsbSA9IHZub2RlLmVsbTtcbiAgdmFyIG9sZEF0dHJzID0gb2xkVm5vZGUuZGF0YS5hdHRycyB8fCB7fTtcbiAgdmFyIGF0dHJzID0gdm5vZGUuZGF0YS5hdHRycyB8fCB7fTtcbiAgLy8gY2xvbmUgb2JzZXJ2ZWQgb2JqZWN0cywgYXMgdGhlIHVzZXIgcHJvYmFibHkgd2FudHMgdG8gbXV0YXRlIGl0XG4gIGlmIChhdHRycy5fX29iX18pIHtcbiAgICBhdHRycyA9IHZub2RlLmRhdGEuYXR0cnMgPSBleHRlbmQoe30sIGF0dHJzKTtcbiAgfVxuXG4gIGZvciAoa2V5IGluIGF0dHJzKSB7XG4gICAgY3VyID0gYXR0cnNba2V5XTtcbiAgICBvbGQgPSBvbGRBdHRyc1trZXldO1xuICAgIGlmIChvbGQgIT09IGN1cikge1xuICAgICAgc2V0QXR0cihlbG0sIGtleSwgY3VyKTtcbiAgICB9XG4gIH1cbiAgZm9yIChrZXkgaW4gb2xkQXR0cnMpIHtcbiAgICBpZiAoYXR0cnNba2V5XSA9PSBudWxsKSB7XG4gICAgICBpZiAoaXNYbGluayhrZXkpKSB7XG4gICAgICAgIGVsbS5yZW1vdmVBdHRyaWJ1dGVOUyh4bGlua05TLCBnZXRYbGlua1Byb3Aoa2V5KSk7XG4gICAgICB9IGVsc2UgaWYgKCFpc0VudW1lcmF0ZWRBdHRyKGtleSkpIHtcbiAgICAgICAgZWxtLnJlbW92ZUF0dHJpYnV0ZShrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzZXRBdHRyIChlbCwga2V5LCB2YWx1ZSkge1xuICBpZiAoaXNCb29sZWFuQXR0cihrZXkpKSB7XG4gICAgLy8gc2V0IGF0dHJpYnV0ZSBmb3IgYmxhbmsgdmFsdWVcbiAgICAvLyBlLmcuIDxvcHRpb24gZGlzYWJsZWQ+U2VsZWN0IG9uZTwvb3B0aW9uPlxuICAgIGlmIChpc0ZhbHN5QXR0clZhbHVlKHZhbHVlKSkge1xuICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKGtleSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZShrZXksIGtleSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzRW51bWVyYXRlZEF0dHIoa2V5KSkge1xuICAgIGVsLnNldEF0dHJpYnV0ZShrZXksIGlzRmFsc3lBdHRyVmFsdWUodmFsdWUpIHx8IHZhbHVlID09PSAnZmFsc2UnID8gJ2ZhbHNlJyA6ICd0cnVlJyk7XG4gIH0gZWxzZSBpZiAoaXNYbGluayhrZXkpKSB7XG4gICAgaWYgKGlzRmFsc3lBdHRyVmFsdWUodmFsdWUpKSB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGVOUyh4bGlua05TLCBnZXRYbGlua1Byb3Aoa2V5KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZU5TKHhsaW5rTlMsIGtleSwgdmFsdWUpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoaXNGYWxzeUF0dHJWYWx1ZSh2YWx1ZSkpIHtcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShrZXkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoa2V5LCB2YWx1ZSk7XG4gICAgfVxuICB9XG59XG5cbnZhciBhdHRycyA9IHtcbiAgY3JlYXRlOiB1cGRhdGVBdHRycyxcbiAgdXBkYXRlOiB1cGRhdGVBdHRyc1xufTtcblxuLyogICovXG5cbmZ1bmN0aW9uIHVwZGF0ZUNsYXNzIChvbGRWbm9kZSwgdm5vZGUpIHtcbiAgdmFyIGVsID0gdm5vZGUuZWxtO1xuICB2YXIgZGF0YSA9IHZub2RlLmRhdGE7XG4gIHZhciBvbGREYXRhID0gb2xkVm5vZGUuZGF0YTtcbiAgaWYgKCFkYXRhLnN0YXRpY0NsYXNzICYmICFkYXRhLmNsYXNzICYmXG4gICAgICAoIW9sZERhdGEgfHwgKCFvbGREYXRhLnN0YXRpY0NsYXNzICYmICFvbGREYXRhLmNsYXNzKSkpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIHZhciBjbHMgPSBnZW5DbGFzc0ZvclZub2RlKHZub2RlKTtcblxuICAvLyBoYW5kbGUgdHJhbnNpdGlvbiBjbGFzc2VzXG4gIHZhciB0cmFuc2l0aW9uQ2xhc3MgPSBlbC5fdHJhbnNpdGlvbkNsYXNzZXM7XG4gIGlmICh0cmFuc2l0aW9uQ2xhc3MpIHtcbiAgICBjbHMgPSBjb25jYXQoY2xzLCBzdHJpbmdpZnlDbGFzcyh0cmFuc2l0aW9uQ2xhc3MpKTtcbiAgfVxuXG4gIC8vIHNldCB0aGUgY2xhc3NcbiAgaWYgKGNscyAhPT0gZWwuX3ByZXZDbGFzcykge1xuICAgIGVsLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCBjbHMpO1xuICAgIGVsLl9wcmV2Q2xhc3MgPSBjbHM7XG4gIH1cbn1cblxudmFyIGtsYXNzID0ge1xuICBjcmVhdGU6IHVwZGF0ZUNsYXNzLFxuICB1cGRhdGU6IHVwZGF0ZUNsYXNzXG59O1xuXG4vLyBza2lwIHR5cGUgY2hlY2tpbmcgdGhpcyBmaWxlIGJlY2F1c2Ugd2UgbmVlZCB0byBhdHRhY2ggcHJpdmF0ZSBwcm9wZXJ0aWVzXG4vLyB0byBlbGVtZW50c1xuXG5mdW5jdGlvbiB1cGRhdGVET01MaXN0ZW5lcnMgKG9sZFZub2RlLCB2bm9kZSkge1xuICBpZiAoIW9sZFZub2RlLmRhdGEub24gJiYgIXZub2RlLmRhdGEub24pIHtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgb24gPSB2bm9kZS5kYXRhLm9uIHx8IHt9O1xuICB2YXIgb2xkT24gPSBvbGRWbm9kZS5kYXRhLm9uIHx8IHt9O1xuICB2YXIgYWRkID0gdm5vZGUuZWxtLl92X2FkZCB8fCAodm5vZGUuZWxtLl92X2FkZCA9IGZ1bmN0aW9uIChldmVudCwgaGFuZGxlciwgY2FwdHVyZSkge1xuICAgIHZub2RlLmVsbS5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBoYW5kbGVyLCBjYXB0dXJlKTtcbiAgfSk7XG4gIHZhciByZW1vdmUgPSB2bm9kZS5lbG0uX3ZfcmVtb3ZlIHx8ICh2bm9kZS5lbG0uX3ZfcmVtb3ZlID0gZnVuY3Rpb24gKGV2ZW50LCBoYW5kbGVyKSB7XG4gICAgdm5vZGUuZWxtLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIGhhbmRsZXIpO1xuICB9KTtcbiAgdXBkYXRlTGlzdGVuZXJzKG9uLCBvbGRPbiwgYWRkLCByZW1vdmUsIHZub2RlLmNvbnRleHQpO1xufVxuXG52YXIgZXZlbnRzID0ge1xuICBjcmVhdGU6IHVwZGF0ZURPTUxpc3RlbmVycyxcbiAgdXBkYXRlOiB1cGRhdGVET01MaXN0ZW5lcnNcbn07XG5cbi8qICAqL1xuXG5mdW5jdGlvbiB1cGRhdGVET01Qcm9wcyAob2xkVm5vZGUsIHZub2RlKSB7XG4gIGlmICghb2xkVm5vZGUuZGF0YS5kb21Qcm9wcyAmJiAhdm5vZGUuZGF0YS5kb21Qcm9wcykge1xuICAgIHJldHVyblxuICB9XG4gIHZhciBrZXksIGN1cjtcbiAgdmFyIGVsbSA9IHZub2RlLmVsbTtcbiAgdmFyIG9sZFByb3BzID0gb2xkVm5vZGUuZGF0YS5kb21Qcm9wcyB8fCB7fTtcbiAgdmFyIHByb3BzID0gdm5vZGUuZGF0YS5kb21Qcm9wcyB8fCB7fTtcbiAgLy8gY2xvbmUgb2JzZXJ2ZWQgb2JqZWN0cywgYXMgdGhlIHVzZXIgcHJvYmFibHkgd2FudHMgdG8gbXV0YXRlIGl0XG4gIGlmIChwcm9wcy5fX29iX18pIHtcbiAgICBwcm9wcyA9IHZub2RlLmRhdGEuZG9tUHJvcHMgPSBleHRlbmQoe30sIHByb3BzKTtcbiAgfVxuXG4gIGZvciAoa2V5IGluIG9sZFByb3BzKSB7XG4gICAgaWYgKHByb3BzW2tleV0gPT0gbnVsbCkge1xuICAgICAgZWxtW2tleV0gPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIGZvciAoa2V5IGluIHByb3BzKSB7XG4gICAgLy8gaWdub3JlIGNoaWxkcmVuIGlmIHRoZSBub2RlIGhhcyB0ZXh0Q29udGVudCBvciBpbm5lckhUTUwsXG4gICAgLy8gYXMgdGhlc2Ugd2lsbCB0aHJvdyBhd2F5IGV4aXN0aW5nIERPTSBub2RlcyBhbmQgY2F1c2UgcmVtb3ZhbCBlcnJvcnNcbiAgICAvLyBvbiBzdWJzZXF1ZW50IHBhdGNoZXMgKCMzMzYwKVxuICAgIGlmICgoa2V5ID09PSAndGV4dENvbnRlbnQnIHx8IGtleSA9PT0gJ2lubmVySFRNTCcpICYmIHZub2RlLmNoaWxkcmVuKSB7XG4gICAgICB2bm9kZS5jaGlsZHJlbi5sZW5ndGggPSAwO1xuICAgIH1cbiAgICBjdXIgPSBwcm9wc1trZXldO1xuICAgIGlmIChrZXkgPT09ICd2YWx1ZScpIHtcbiAgICAgIC8vIHN0b3JlIHZhbHVlIGFzIF92YWx1ZSBhcyB3ZWxsIHNpbmNlXG4gICAgICAvLyBub24tc3RyaW5nIHZhbHVlcyB3aWxsIGJlIHN0cmluZ2lmaWVkXG4gICAgICBlbG0uX3ZhbHVlID0gY3VyO1xuICAgICAgLy8gYXZvaWQgcmVzZXR0aW5nIGN1cnNvciBwb3NpdGlvbiB3aGVuIHZhbHVlIGlzIHRoZSBzYW1lXG4gICAgICB2YXIgc3RyQ3VyID0gY3VyID09IG51bGwgPyAnJyA6IFN0cmluZyhjdXIpO1xuICAgICAgaWYgKGVsbS52YWx1ZSAhPT0gc3RyQ3VyICYmICFlbG0uY29tcG9zaW5nKSB7XG4gICAgICAgIGVsbS52YWx1ZSA9IHN0ckN1cjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZWxtW2tleV0gPSBjdXI7XG4gICAgfVxuICB9XG59XG5cbnZhciBkb21Qcm9wcyA9IHtcbiAgY3JlYXRlOiB1cGRhdGVET01Qcm9wcyxcbiAgdXBkYXRlOiB1cGRhdGVET01Qcm9wc1xufTtcblxuLyogICovXG5cbnZhciBwcmVmaXhlcyA9IFsnV2Via2l0JywgJ01veicsICdtcyddO1xuXG52YXIgdGVzdEVsO1xudmFyIG5vcm1hbGl6ZSA9IGNhY2hlZChmdW5jdGlvbiAocHJvcCkge1xuICB0ZXN0RWwgPSB0ZXN0RWwgfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIHByb3AgPSBjYW1lbGl6ZShwcm9wKTtcbiAgaWYgKHByb3AgIT09ICdmaWx0ZXInICYmIChwcm9wIGluIHRlc3RFbC5zdHlsZSkpIHtcbiAgICByZXR1cm4gcHJvcFxuICB9XG4gIHZhciB1cHBlciA9IHByb3AuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBwcm9wLnNsaWNlKDEpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHByZWZpeGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHByZWZpeGVkID0gcHJlZml4ZXNbaV0gKyB1cHBlcjtcbiAgICBpZiAocHJlZml4ZWQgaW4gdGVzdEVsLnN0eWxlKSB7XG4gICAgICByZXR1cm4gcHJlZml4ZWRcbiAgICB9XG4gIH1cbn0pO1xuXG5mdW5jdGlvbiB1cGRhdGVTdHlsZSAob2xkVm5vZGUsIHZub2RlKSB7XG4gIGlmICgoIW9sZFZub2RlLmRhdGEgfHwgIW9sZFZub2RlLmRhdGEuc3R5bGUpICYmICF2bm9kZS5kYXRhLnN0eWxlKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgdmFyIGN1ciwgbmFtZTtcbiAgdmFyIGVsID0gdm5vZGUuZWxtO1xuICB2YXIgb2xkU3R5bGUgPSBvbGRWbm9kZS5kYXRhLnN0eWxlIHx8IHt9O1xuICB2YXIgc3R5bGUgPSB2bm9kZS5kYXRhLnN0eWxlIHx8IHt9O1xuXG4gIC8vIGhhbmRsZSBzdHJpbmdcbiAgaWYgKHR5cGVvZiBzdHlsZSA9PT0gJ3N0cmluZycpIHtcbiAgICBlbC5zdHlsZS5jc3NUZXh0ID0gc3R5bGU7XG4gICAgcmV0dXJuXG4gIH1cblxuICB2YXIgbmVlZENsb25lID0gc3R5bGUuX19vYl9fO1xuXG4gIC8vIGhhbmRsZSBhcnJheSBzeW50YXhcbiAgaWYgKEFycmF5LmlzQXJyYXkoc3R5bGUpKSB7XG4gICAgc3R5bGUgPSB2bm9kZS5kYXRhLnN0eWxlID0gdG9PYmplY3Qoc3R5bGUpO1xuICB9XG5cbiAgLy8gY2xvbmUgdGhlIHN0eWxlIGZvciBmdXR1cmUgdXBkYXRlcyxcbiAgLy8gaW4gY2FzZSB0aGUgdXNlciBtdXRhdGVzIHRoZSBzdHlsZSBvYmplY3QgaW4tcGxhY2UuXG4gIGlmIChuZWVkQ2xvbmUpIHtcbiAgICBzdHlsZSA9IHZub2RlLmRhdGEuc3R5bGUgPSBleHRlbmQoe30sIHN0eWxlKTtcbiAgfVxuXG4gIGZvciAobmFtZSBpbiBvbGRTdHlsZSkge1xuICAgIGlmIChzdHlsZVtuYW1lXSA9PSBudWxsKSB7XG4gICAgICBlbC5zdHlsZVtub3JtYWxpemUobmFtZSldID0gJyc7XG4gICAgfVxuICB9XG4gIGZvciAobmFtZSBpbiBzdHlsZSkge1xuICAgIGN1ciA9IHN0eWxlW25hbWVdO1xuICAgIGlmIChjdXIgIT09IG9sZFN0eWxlW25hbWVdKSB7XG4gICAgICAvLyBpZTkgc2V0dGluZyB0byBudWxsIGhhcyBubyBlZmZlY3QsIG11c3QgdXNlIGVtcHR5IHN0cmluZ1xuICAgICAgZWwuc3R5bGVbbm9ybWFsaXplKG5hbWUpXSA9IGN1ciA9PSBudWxsID8gJycgOiBjdXI7XG4gICAgfVxuICB9XG59XG5cbnZhciBzdHlsZSA9IHtcbiAgY3JlYXRlOiB1cGRhdGVTdHlsZSxcbiAgdXBkYXRlOiB1cGRhdGVTdHlsZVxufTtcblxuLyogICovXG5cbi8qKlxuICogQWRkIGNsYXNzIHdpdGggY29tcGF0aWJpbGl0eSBmb3IgU1ZHIHNpbmNlIGNsYXNzTGlzdCBpcyBub3Qgc3VwcG9ydGVkIG9uXG4gKiBTVkcgZWxlbWVudHMgaW4gSUVcbiAqL1xuZnVuY3Rpb24gYWRkQ2xhc3MgKGVsLCBjbHMpIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgaWYgKGVsLmNsYXNzTGlzdCkge1xuICAgIGlmIChjbHMuaW5kZXhPZignICcpID4gLTEpIHtcbiAgICAgIGNscy5zcGxpdCgvXFxzKy8pLmZvckVhY2goZnVuY3Rpb24gKGMpIHsgcmV0dXJuIGVsLmNsYXNzTGlzdC5hZGQoYyk7IH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbC5jbGFzc0xpc3QuYWRkKGNscyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBjdXIgPSAnICcgKyBlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykgKyAnICc7XG4gICAgaWYgKGN1ci5pbmRleE9mKCcgJyArIGNscyArICcgJykgPCAwKSB7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgKGN1ciArIGNscykudHJpbSgpKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZW1vdmUgY2xhc3Mgd2l0aCBjb21wYXRpYmlsaXR5IGZvciBTVkcgc2luY2UgY2xhc3NMaXN0IGlzIG5vdCBzdXBwb3J0ZWQgb25cbiAqIFNWRyBlbGVtZW50cyBpbiBJRVxuICovXG5mdW5jdGlvbiByZW1vdmVDbGFzcyAoZWwsIGNscykge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICBpZiAoZWwuY2xhc3NMaXN0KSB7XG4gICAgaWYgKGNscy5pbmRleE9mKCcgJykgPiAtMSkge1xuICAgICAgY2xzLnNwbGl0KC9cXHMrLykuZm9yRWFjaChmdW5jdGlvbiAoYykgeyByZXR1cm4gZWwuY2xhc3NMaXN0LnJlbW92ZShjKTsgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoY2xzKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGN1ciA9ICcgJyArIGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSArICcgJztcbiAgICB2YXIgdGFyID0gJyAnICsgY2xzICsgJyAnO1xuICAgIHdoaWxlIChjdXIuaW5kZXhPZih0YXIpID49IDApIHtcbiAgICAgIGN1ciA9IGN1ci5yZXBsYWNlKHRhciwgJyAnKTtcbiAgICB9XG4gICAgZWwuc2V0QXR0cmlidXRlKCdjbGFzcycsIGN1ci50cmltKCkpO1xuICB9XG59XG5cbi8qICAqL1xuXG52YXIgaGFzVHJhbnNpdGlvbiA9IGluQnJvd3NlciAmJiAhaXNJRTk7XG52YXIgVFJBTlNJVElPTiA9ICd0cmFuc2l0aW9uJztcbnZhciBBTklNQVRJT04gPSAnYW5pbWF0aW9uJztcblxuLy8gVHJhbnNpdGlvbiBwcm9wZXJ0eS9ldmVudCBzbmlmZmluZ1xudmFyIHRyYW5zaXRpb25Qcm9wID0gJ3RyYW5zaXRpb24nO1xudmFyIHRyYW5zaXRpb25FbmRFdmVudCA9ICd0cmFuc2l0aW9uZW5kJztcbnZhciBhbmltYXRpb25Qcm9wID0gJ2FuaW1hdGlvbic7XG52YXIgYW5pbWF0aW9uRW5kRXZlbnQgPSAnYW5pbWF0aW9uZW5kJztcbmlmIChoYXNUcmFuc2l0aW9uKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAod2luZG93Lm9udHJhbnNpdGlvbmVuZCA9PT0gdW5kZWZpbmVkICYmXG4gICAgd2luZG93Lm9ud2Via2l0dHJhbnNpdGlvbmVuZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdHJhbnNpdGlvblByb3AgPSAnV2Via2l0VHJhbnNpdGlvbic7XG4gICAgdHJhbnNpdGlvbkVuZEV2ZW50ID0gJ3dlYmtpdFRyYW5zaXRpb25FbmQnO1xuICB9XG4gIGlmICh3aW5kb3cub25hbmltYXRpb25lbmQgPT09IHVuZGVmaW5lZCAmJlxuICAgIHdpbmRvdy5vbndlYmtpdGFuaW1hdGlvbmVuZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgYW5pbWF0aW9uUHJvcCA9ICdXZWJraXRBbmltYXRpb24nO1xuICAgIGFuaW1hdGlvbkVuZEV2ZW50ID0gJ3dlYmtpdEFuaW1hdGlvbkVuZCc7XG4gIH1cbn1cblxudmFyIHJhZiA9IChpbkJyb3dzZXIgJiYgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSkgfHwgc2V0VGltZW91dDtcbmZ1bmN0aW9uIG5leHRGcmFtZSAoZm4pIHtcbiAgcmFmKGZ1bmN0aW9uICgpIHtcbiAgICByYWYoZm4pO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gYWRkVHJhbnNpdGlvbkNsYXNzIChlbCwgY2xzKSB7XG4gIChlbC5fdHJhbnNpdGlvbkNsYXNzZXMgfHwgKGVsLl90cmFuc2l0aW9uQ2xhc3NlcyA9IFtdKSkucHVzaChjbHMpO1xuICBhZGRDbGFzcyhlbCwgY2xzKTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlVHJhbnNpdGlvbkNsYXNzIChlbCwgY2xzKSB7XG4gIGlmIChlbC5fdHJhbnNpdGlvbkNsYXNzZXMpIHtcbiAgICByZW1vdmUkMShlbC5fdHJhbnNpdGlvbkNsYXNzZXMsIGNscyk7XG4gIH1cbiAgcmVtb3ZlQ2xhc3MoZWwsIGNscyk7XG59XG5cbmZ1bmN0aW9uIHdoZW5UcmFuc2l0aW9uRW5kcyAoXG4gIGVsLFxuICBleHBlY3RlZFR5cGUsXG4gIGNiXG4pIHtcbiAgdmFyIHJlZiA9IGdldFRyYW5zaXRpb25JbmZvKGVsLCBleHBlY3RlZFR5cGUpO1xuICB2YXIgdHlwZSA9IHJlZi50eXBlO1xuICB2YXIgdGltZW91dCA9IHJlZi50aW1lb3V0O1xuICB2YXIgcHJvcENvdW50ID0gcmVmLnByb3BDb3VudDtcbiAgaWYgKCF0eXBlKSB7IHJldHVybiBjYigpIH1cbiAgdmFyIGV2ZW50ID0gdHlwZSA9PT0gVFJBTlNJVElPTiA/IHRyYW5zaXRpb25FbmRFdmVudCA6IGFuaW1hdGlvbkVuZEV2ZW50O1xuICB2YXIgZW5kZWQgPSAwO1xuICB2YXIgZW5kID0gZnVuY3Rpb24gKCkge1xuICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIG9uRW5kKTtcbiAgICBjYigpO1xuICB9O1xuICB2YXIgb25FbmQgPSBmdW5jdGlvbiAoZSkge1xuICAgIGlmIChlLnRhcmdldCA9PT0gZWwpIHtcbiAgICAgIGlmICgrK2VuZGVkID49IHByb3BDb3VudCkge1xuICAgICAgICBlbmQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGlmIChlbmRlZCA8IHByb3BDb3VudCkge1xuICAgICAgZW5kKCk7XG4gICAgfVxuICB9LCB0aW1lb3V0ICsgMSk7XG4gIGVsLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIG9uRW5kKTtcbn1cblxudmFyIHRyYW5zZm9ybVJFID0gL1xcYih0cmFuc2Zvcm18YWxsKSgsfCQpLztcblxuZnVuY3Rpb24gZ2V0VHJhbnNpdGlvbkluZm8gKGVsLCBleHBlY3RlZFR5cGUpIHtcbiAgdmFyIHN0eWxlcyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKTtcbiAgdmFyIHRyYW5zaXRpb25lRGVsYXlzID0gc3R5bGVzW3RyYW5zaXRpb25Qcm9wICsgJ0RlbGF5J10uc3BsaXQoJywgJyk7XG4gIHZhciB0cmFuc2l0aW9uRHVyYXRpb25zID0gc3R5bGVzW3RyYW5zaXRpb25Qcm9wICsgJ0R1cmF0aW9uJ10uc3BsaXQoJywgJyk7XG4gIHZhciB0cmFuc2l0aW9uVGltZW91dCA9IGdldFRpbWVvdXQodHJhbnNpdGlvbmVEZWxheXMsIHRyYW5zaXRpb25EdXJhdGlvbnMpO1xuICB2YXIgYW5pbWF0aW9uRGVsYXlzID0gc3R5bGVzW2FuaW1hdGlvblByb3AgKyAnRGVsYXknXS5zcGxpdCgnLCAnKTtcbiAgdmFyIGFuaW1hdGlvbkR1cmF0aW9ucyA9IHN0eWxlc1thbmltYXRpb25Qcm9wICsgJ0R1cmF0aW9uJ10uc3BsaXQoJywgJyk7XG4gIHZhciBhbmltYXRpb25UaW1lb3V0ID0gZ2V0VGltZW91dChhbmltYXRpb25EZWxheXMsIGFuaW1hdGlvbkR1cmF0aW9ucyk7XG5cbiAgdmFyIHR5cGU7XG4gIHZhciB0aW1lb3V0ID0gMDtcbiAgdmFyIHByb3BDb3VudCA9IDA7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoZXhwZWN0ZWRUeXBlID09PSBUUkFOU0lUSU9OKSB7XG4gICAgaWYgKHRyYW5zaXRpb25UaW1lb3V0ID4gMCkge1xuICAgICAgdHlwZSA9IFRSQU5TSVRJT047XG4gICAgICB0aW1lb3V0ID0gdHJhbnNpdGlvblRpbWVvdXQ7XG4gICAgICBwcm9wQ291bnQgPSB0cmFuc2l0aW9uRHVyYXRpb25zLmxlbmd0aDtcbiAgICB9XG4gIH0gZWxzZSBpZiAoZXhwZWN0ZWRUeXBlID09PSBBTklNQVRJT04pIHtcbiAgICBpZiAoYW5pbWF0aW9uVGltZW91dCA+IDApIHtcbiAgICAgIHR5cGUgPSBBTklNQVRJT047XG4gICAgICB0aW1lb3V0ID0gYW5pbWF0aW9uVGltZW91dDtcbiAgICAgIHByb3BDb3VudCA9IGFuaW1hdGlvbkR1cmF0aW9ucy5sZW5ndGg7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRpbWVvdXQgPSBNYXRoLm1heCh0cmFuc2l0aW9uVGltZW91dCwgYW5pbWF0aW9uVGltZW91dCk7XG4gICAgdHlwZSA9IHRpbWVvdXQgPiAwXG4gICAgICA/IHRyYW5zaXRpb25UaW1lb3V0ID4gYW5pbWF0aW9uVGltZW91dFxuICAgICAgICA/IFRSQU5TSVRJT05cbiAgICAgICAgOiBBTklNQVRJT05cbiAgICAgIDogbnVsbDtcbiAgICBwcm9wQ291bnQgPSB0eXBlXG4gICAgICA/IHR5cGUgPT09IFRSQU5TSVRJT05cbiAgICAgICAgPyB0cmFuc2l0aW9uRHVyYXRpb25zLmxlbmd0aFxuICAgICAgICA6IGFuaW1hdGlvbkR1cmF0aW9ucy5sZW5ndGhcbiAgICAgIDogMDtcbiAgfVxuICB2YXIgaGFzVHJhbnNmb3JtID1cbiAgICB0eXBlID09PSBUUkFOU0lUSU9OICYmXG4gICAgdHJhbnNmb3JtUkUudGVzdChzdHlsZXNbdHJhbnNpdGlvblByb3AgKyAnUHJvcGVydHknXSk7XG4gIHJldHVybiB7XG4gICAgdHlwZTogdHlwZSxcbiAgICB0aW1lb3V0OiB0aW1lb3V0LFxuICAgIHByb3BDb3VudDogcHJvcENvdW50LFxuICAgIGhhc1RyYW5zZm9ybTogaGFzVHJhbnNmb3JtXG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0VGltZW91dCAoZGVsYXlzLCBkdXJhdGlvbnMpIHtcbiAgcmV0dXJuIE1hdGgubWF4LmFwcGx5KG51bGwsIGR1cmF0aW9ucy5tYXAoZnVuY3Rpb24gKGQsIGkpIHtcbiAgICByZXR1cm4gdG9NcyhkKSArIHRvTXMoZGVsYXlzW2ldKVxuICB9KSlcbn1cblxuZnVuY3Rpb24gdG9NcyAocykge1xuICByZXR1cm4gTnVtYmVyKHMuc2xpY2UoMCwgLTEpKSAqIDEwMDBcbn1cblxuLyogICovXG5cbmZ1bmN0aW9uIGVudGVyICh2bm9kZSkge1xuICB2YXIgZWwgPSB2bm9kZS5lbG07XG5cbiAgLy8gY2FsbCBsZWF2ZSBjYWxsYmFjayBub3dcbiAgaWYgKGVsLl9sZWF2ZUNiKSB7XG4gICAgZWwuX2xlYXZlQ2IuY2FuY2VsbGVkID0gdHJ1ZTtcbiAgICBlbC5fbGVhdmVDYigpO1xuICB9XG5cbiAgdmFyIGRhdGEgPSByZXNvbHZlVHJhbnNpdGlvbih2bm9kZS5kYXRhLnRyYW5zaXRpb24pO1xuICBpZiAoIWRhdGEpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoZWwuX2VudGVyQ2IgfHwgZWwubm9kZVR5cGUgIT09IDEpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIHZhciBjc3MgPSBkYXRhLmNzcztcbiAgdmFyIHR5cGUgPSBkYXRhLnR5cGU7XG4gIHZhciBlbnRlckNsYXNzID0gZGF0YS5lbnRlckNsYXNzO1xuICB2YXIgZW50ZXJBY3RpdmVDbGFzcyA9IGRhdGEuZW50ZXJBY3RpdmVDbGFzcztcbiAgdmFyIGFwcGVhckNsYXNzID0gZGF0YS5hcHBlYXJDbGFzcztcbiAgdmFyIGFwcGVhckFjdGl2ZUNsYXNzID0gZGF0YS5hcHBlYXJBY3RpdmVDbGFzcztcbiAgdmFyIGJlZm9yZUVudGVyID0gZGF0YS5iZWZvcmVFbnRlcjtcbiAgdmFyIGVudGVyID0gZGF0YS5lbnRlcjtcbiAgdmFyIGFmdGVyRW50ZXIgPSBkYXRhLmFmdGVyRW50ZXI7XG4gIHZhciBlbnRlckNhbmNlbGxlZCA9IGRhdGEuZW50ZXJDYW5jZWxsZWQ7XG4gIHZhciBiZWZvcmVBcHBlYXIgPSBkYXRhLmJlZm9yZUFwcGVhcjtcbiAgdmFyIGFwcGVhciA9IGRhdGEuYXBwZWFyO1xuICB2YXIgYWZ0ZXJBcHBlYXIgPSBkYXRhLmFmdGVyQXBwZWFyO1xuICB2YXIgYXBwZWFyQ2FuY2VsbGVkID0gZGF0YS5hcHBlYXJDYW5jZWxsZWQ7XG5cbiAgLy8gYWN0aXZlSW5zdGFuY2Ugd2lsbCBhbHdheXMgYmUgdGhlIDx0cmFuc2l0aW9uPiBjb21wb25lbnQgbWFuYWdpbmcgdGhpc1xuICAvLyB0cmFuc2l0aW9uLiBPbmUgZWRnZSBjYXNlIHRvIGNoZWNrIGlzIHdoZW4gdGhlIDx0cmFuc2l0aW9uPiBpcyBwbGFjZWRcbiAgLy8gYXMgdGhlIHJvb3Qgbm9kZSBvZiBhIGNoaWxkIGNvbXBvbmVudC4gSW4gdGhhdCBjYXNlIHdlIG5lZWQgdG8gY2hlY2tcbiAgLy8gPHRyYW5zaXRpb24+J3MgcGFyZW50IGZvciBhcHBlYXIgY2hlY2suXG4gIHZhciB0cmFuc2l0aW9uTm9kZSA9IGFjdGl2ZUluc3RhbmNlLiR2bm9kZTtcbiAgdmFyIGNvbnRleHQgPSB0cmFuc2l0aW9uTm9kZSAmJiB0cmFuc2l0aW9uTm9kZS5wYXJlbnRcbiAgICA/IHRyYW5zaXRpb25Ob2RlLnBhcmVudC5jb250ZXh0XG4gICAgOiBhY3RpdmVJbnN0YW5jZTtcblxuICB2YXIgaXNBcHBlYXIgPSAhY29udGV4dC5faXNNb3VudGVkIHx8ICF2bm9kZS5pc1Jvb3RJbnNlcnQ7XG5cbiAgaWYgKGlzQXBwZWFyICYmICFhcHBlYXIgJiYgYXBwZWFyICE9PSAnJykge1xuICAgIHJldHVyblxuICB9XG5cbiAgdmFyIHN0YXJ0Q2xhc3MgPSBpc0FwcGVhciA/IGFwcGVhckNsYXNzIDogZW50ZXJDbGFzcztcbiAgdmFyIGFjdGl2ZUNsYXNzID0gaXNBcHBlYXIgPyBhcHBlYXJBY3RpdmVDbGFzcyA6IGVudGVyQWN0aXZlQ2xhc3M7XG4gIHZhciBiZWZvcmVFbnRlckhvb2sgPSBpc0FwcGVhciA/IChiZWZvcmVBcHBlYXIgfHwgYmVmb3JlRW50ZXIpIDogYmVmb3JlRW50ZXI7XG4gIHZhciBlbnRlckhvb2sgPSBpc0FwcGVhciA/ICh0eXBlb2YgYXBwZWFyID09PSAnZnVuY3Rpb24nID8gYXBwZWFyIDogZW50ZXIpIDogZW50ZXI7XG4gIHZhciBhZnRlckVudGVySG9vayA9IGlzQXBwZWFyID8gKGFmdGVyQXBwZWFyIHx8IGFmdGVyRW50ZXIpIDogYWZ0ZXJFbnRlcjtcbiAgdmFyIGVudGVyQ2FuY2VsbGVkSG9vayA9IGlzQXBwZWFyID8gKGFwcGVhckNhbmNlbGxlZCB8fCBlbnRlckNhbmNlbGxlZCkgOiBlbnRlckNhbmNlbGxlZDtcblxuICB2YXIgZXhwZWN0c0NTUyA9IGNzcyAhPT0gZmFsc2UgJiYgIWlzSUU5O1xuICB2YXIgdXNlcldhbnRzQ29udHJvbCA9XG4gICAgZW50ZXJIb29rICYmXG4gICAgLy8gZW50ZXJIb29rIG1heSBiZSBhIGJvdW5kIG1ldGhvZCB3aGljaCBleHBvc2VzXG4gICAgLy8gdGhlIGxlbmd0aCBvZiBvcmlnaW5hbCBmbiBhcyBfbGVuZ3RoXG4gICAgKGVudGVySG9vay5fbGVuZ3RoIHx8IGVudGVySG9vay5sZW5ndGgpID4gMTtcblxuICB2YXIgY2IgPSBlbC5fZW50ZXJDYiA9IG9uY2UoZnVuY3Rpb24gKCkge1xuICAgIGlmIChleHBlY3RzQ1NTKSB7XG4gICAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIGFjdGl2ZUNsYXNzKTtcbiAgICB9XG4gICAgaWYgKGNiLmNhbmNlbGxlZCkge1xuICAgICAgaWYgKGV4cGVjdHNDU1MpIHtcbiAgICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBzdGFydENsYXNzKTtcbiAgICAgIH1cbiAgICAgIGVudGVyQ2FuY2VsbGVkSG9vayAmJiBlbnRlckNhbmNlbGxlZEhvb2soZWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhZnRlckVudGVySG9vayAmJiBhZnRlckVudGVySG9vayhlbCk7XG4gICAgfVxuICAgIGVsLl9lbnRlckNiID0gbnVsbDtcbiAgfSk7XG5cbiAgaWYgKCF2bm9kZS5kYXRhLnNob3cpIHtcbiAgICAvLyByZW1vdmUgcGVuZGluZyBsZWF2ZSBlbGVtZW50IG9uIGVudGVyIGJ5IGluamVjdGluZyBhbiBpbnNlcnQgaG9va1xuICAgIG1lcmdlVk5vZGVIb29rKHZub2RlLmRhdGEuaG9vayB8fCAodm5vZGUuZGF0YS5ob29rID0ge30pLCAnaW5zZXJ0JywgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHBhcmVudCA9IGVsLnBhcmVudE5vZGU7XG4gICAgICB2YXIgcGVuZGluZ05vZGUgPSBwYXJlbnQgJiYgcGFyZW50Ll9wZW5kaW5nICYmIHBhcmVudC5fcGVuZGluZ1t2bm9kZS5rZXldO1xuICAgICAgaWYgKHBlbmRpbmdOb2RlICYmIHBlbmRpbmdOb2RlLnRhZyA9PT0gdm5vZGUudGFnICYmIHBlbmRpbmdOb2RlLmVsbS5fbGVhdmVDYikge1xuICAgICAgICBwZW5kaW5nTm9kZS5lbG0uX2xlYXZlQ2IoKTtcbiAgICAgIH1cbiAgICAgIGVudGVySG9vayAmJiBlbnRlckhvb2soZWwsIGNiKTtcbiAgICB9LCAndHJhbnNpdGlvbi1pbnNlcnQnKTtcbiAgfVxuXG4gIC8vIHN0YXJ0IGVudGVyIHRyYW5zaXRpb25cbiAgYmVmb3JlRW50ZXJIb29rICYmIGJlZm9yZUVudGVySG9vayhlbCk7XG4gIGlmIChleHBlY3RzQ1NTKSB7XG4gICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBzdGFydENsYXNzKTtcbiAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIGFjdGl2ZUNsYXNzKTtcbiAgICBuZXh0RnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBzdGFydENsYXNzKTtcbiAgICAgIGlmICghY2IuY2FuY2VsbGVkICYmICF1c2VyV2FudHNDb250cm9sKSB7XG4gICAgICAgIHdoZW5UcmFuc2l0aW9uRW5kcyhlbCwgdHlwZSwgY2IpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaWYgKHZub2RlLmRhdGEuc2hvdykge1xuICAgIGVudGVySG9vayAmJiBlbnRlckhvb2soZWwsIGNiKTtcbiAgfVxuXG4gIGlmICghZXhwZWN0c0NTUyAmJiAhdXNlcldhbnRzQ29udHJvbCkge1xuICAgIGNiKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbGVhdmUgKHZub2RlLCBybSkge1xuICB2YXIgZWwgPSB2bm9kZS5lbG07XG5cbiAgLy8gY2FsbCBlbnRlciBjYWxsYmFjayBub3dcbiAgaWYgKGVsLl9lbnRlckNiKSB7XG4gICAgZWwuX2VudGVyQ2IuY2FuY2VsbGVkID0gdHJ1ZTtcbiAgICBlbC5fZW50ZXJDYigpO1xuICB9XG5cbiAgdmFyIGRhdGEgPSByZXNvbHZlVHJhbnNpdGlvbih2bm9kZS5kYXRhLnRyYW5zaXRpb24pO1xuICBpZiAoIWRhdGEpIHtcbiAgICByZXR1cm4gcm0oKVxuICB9XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChlbC5fbGVhdmVDYiB8fCBlbC5ub2RlVHlwZSAhPT0gMSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgdmFyIGNzcyA9IGRhdGEuY3NzO1xuICB2YXIgdHlwZSA9IGRhdGEudHlwZTtcbiAgdmFyIGxlYXZlQ2xhc3MgPSBkYXRhLmxlYXZlQ2xhc3M7XG4gIHZhciBsZWF2ZUFjdGl2ZUNsYXNzID0gZGF0YS5sZWF2ZUFjdGl2ZUNsYXNzO1xuICB2YXIgYmVmb3JlTGVhdmUgPSBkYXRhLmJlZm9yZUxlYXZlO1xuICB2YXIgbGVhdmUgPSBkYXRhLmxlYXZlO1xuICB2YXIgYWZ0ZXJMZWF2ZSA9IGRhdGEuYWZ0ZXJMZWF2ZTtcbiAgdmFyIGxlYXZlQ2FuY2VsbGVkID0gZGF0YS5sZWF2ZUNhbmNlbGxlZDtcbiAgdmFyIGRlbGF5TGVhdmUgPSBkYXRhLmRlbGF5TGVhdmU7XG5cbiAgdmFyIGV4cGVjdHNDU1MgPSBjc3MgIT09IGZhbHNlICYmICFpc0lFOTtcbiAgdmFyIHVzZXJXYW50c0NvbnRyb2wgPVxuICAgIGxlYXZlICYmXG4gICAgLy8gbGVhdmUgaG9vayBtYXkgYmUgYSBib3VuZCBtZXRob2Qgd2hpY2ggZXhwb3Nlc1xuICAgIC8vIHRoZSBsZW5ndGggb2Ygb3JpZ2luYWwgZm4gYXMgX2xlbmd0aFxuICAgIChsZWF2ZS5fbGVuZ3RoIHx8IGxlYXZlLmxlbmd0aCkgPiAxO1xuXG4gIHZhciBjYiA9IGVsLl9sZWF2ZUNiID0gb25jZShmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGVsLnBhcmVudE5vZGUgJiYgZWwucGFyZW50Tm9kZS5fcGVuZGluZykge1xuICAgICAgZWwucGFyZW50Tm9kZS5fcGVuZGluZ1t2bm9kZS5rZXldID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKGV4cGVjdHNDU1MpIHtcbiAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVBY3RpdmVDbGFzcyk7XG4gICAgfVxuICAgIGlmIChjYi5jYW5jZWxsZWQpIHtcbiAgICAgIGlmIChleHBlY3RzQ1NTKSB7XG4gICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVDbGFzcyk7XG4gICAgICB9XG4gICAgICBsZWF2ZUNhbmNlbGxlZCAmJiBsZWF2ZUNhbmNlbGxlZChlbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJtKCk7XG4gICAgICBhZnRlckxlYXZlICYmIGFmdGVyTGVhdmUoZWwpO1xuICAgIH1cbiAgICBlbC5fbGVhdmVDYiA9IG51bGw7XG4gIH0pO1xuXG4gIGlmIChkZWxheUxlYXZlKSB7XG4gICAgZGVsYXlMZWF2ZShwZXJmb3JtTGVhdmUpO1xuICB9IGVsc2Uge1xuICAgIHBlcmZvcm1MZWF2ZSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gcGVyZm9ybUxlYXZlICgpIHtcbiAgICAvLyB0aGUgZGVsYXllZCBsZWF2ZSBtYXkgaGF2ZSBhbHJlYWR5IGJlZW4gY2FuY2VsbGVkXG4gICAgaWYgKGNiLmNhbmNlbGxlZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIC8vIHJlY29yZCBsZWF2aW5nIGVsZW1lbnRcbiAgICBpZiAoIXZub2RlLmRhdGEuc2hvdykge1xuICAgICAgKGVsLnBhcmVudE5vZGUuX3BlbmRpbmcgfHwgKGVsLnBhcmVudE5vZGUuX3BlbmRpbmcgPSB7fSkpW3Zub2RlLmtleV0gPSB2bm9kZTtcbiAgICB9XG4gICAgYmVmb3JlTGVhdmUgJiYgYmVmb3JlTGVhdmUoZWwpO1xuICAgIGlmIChleHBlY3RzQ1NTKSB7XG4gICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIGxlYXZlQ2xhc3MpO1xuICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZUFjdGl2ZUNsYXNzKTtcbiAgICAgIG5leHRGcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVDbGFzcyk7XG4gICAgICAgIGlmICghY2IuY2FuY2VsbGVkICYmICF1c2VyV2FudHNDb250cm9sKSB7XG4gICAgICAgICAgd2hlblRyYW5zaXRpb25FbmRzKGVsLCB0eXBlLCBjYik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICBsZWF2ZSAmJiBsZWF2ZShlbCwgY2IpO1xuICAgIGlmICghZXhwZWN0c0NTUyAmJiAhdXNlcldhbnRzQ29udHJvbCkge1xuICAgICAgY2IoKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzb2x2ZVRyYW5zaXRpb24gKGRlZiQkMSkge1xuICBpZiAoIWRlZiQkMSkge1xuICAgIHJldHVyblxuICB9XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gIGlmICh0eXBlb2YgZGVmJCQxID09PSAnb2JqZWN0Jykge1xuICAgIHZhciByZXMgPSB7fTtcbiAgICBpZiAoZGVmJCQxLmNzcyAhPT0gZmFsc2UpIHtcbiAgICAgIGV4dGVuZChyZXMsIGF1dG9Dc3NUcmFuc2l0aW9uKGRlZiQkMS5uYW1lIHx8ICd2JykpO1xuICAgIH1cbiAgICBleHRlbmQocmVzLCBkZWYkJDEpO1xuICAgIHJldHVybiByZXNcbiAgfSBlbHNlIGlmICh0eXBlb2YgZGVmJCQxID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBhdXRvQ3NzVHJhbnNpdGlvbihkZWYkJDEpXG4gIH1cbn1cblxudmFyIGF1dG9Dc3NUcmFuc2l0aW9uID0gY2FjaGVkKGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiB7XG4gICAgZW50ZXJDbGFzczogKG5hbWUgKyBcIi1lbnRlclwiKSxcbiAgICBsZWF2ZUNsYXNzOiAobmFtZSArIFwiLWxlYXZlXCIpLFxuICAgIGFwcGVhckNsYXNzOiAobmFtZSArIFwiLWVudGVyXCIpLFxuICAgIGVudGVyQWN0aXZlQ2xhc3M6IChuYW1lICsgXCItZW50ZXItYWN0aXZlXCIpLFxuICAgIGxlYXZlQWN0aXZlQ2xhc3M6IChuYW1lICsgXCItbGVhdmUtYWN0aXZlXCIpLFxuICAgIGFwcGVhckFjdGl2ZUNsYXNzOiAobmFtZSArIFwiLWVudGVyLWFjdGl2ZVwiKVxuICB9XG59KTtcblxuZnVuY3Rpb24gb25jZSAoZm4pIHtcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGlmICghY2FsbGVkKSB7XG4gICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgZm4oKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIHRyYW5zaXRpb24gPSBpbkJyb3dzZXIgPyB7XG4gIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlIChfLCB2bm9kZSkge1xuICAgIGlmICghdm5vZGUuZGF0YS5zaG93KSB7XG4gICAgICBlbnRlcih2bm9kZSk7XG4gICAgfVxuICB9LFxuICByZW1vdmU6IGZ1bmN0aW9uIHJlbW92ZSAodm5vZGUsIHJtKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAoIXZub2RlLmRhdGEuc2hvdykge1xuICAgICAgbGVhdmUodm5vZGUsIHJtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcm0oKTtcbiAgICB9XG4gIH1cbn0gOiB7fTtcblxudmFyIHBsYXRmb3JtTW9kdWxlcyA9IFtcbiAgYXR0cnMsXG4gIGtsYXNzLFxuICBldmVudHMsXG4gIGRvbVByb3BzLFxuICBzdHlsZSxcbiAgdHJhbnNpdGlvblxuXTtcblxuLyogICovXG5cbi8vIHRoZSBkaXJlY3RpdmUgbW9kdWxlIHNob3VsZCBiZSBhcHBsaWVkIGxhc3QsIGFmdGVyIGFsbFxuLy8gYnVpbHQtaW4gbW9kdWxlcyBoYXZlIGJlZW4gYXBwbGllZC5cbnZhciBtb2R1bGVzID0gcGxhdGZvcm1Nb2R1bGVzLmNvbmNhdChiYXNlTW9kdWxlcyk7XG5cbnZhciBwYXRjaCQxID0gY3JlYXRlUGF0Y2hGdW5jdGlvbih7IG5vZGVPcHM6IG5vZGVPcHMsIG1vZHVsZXM6IG1vZHVsZXMgfSk7XG5cbi8qKlxuICogTm90IHR5cGUgY2hlY2tpbmcgdGhpcyBmaWxlIGJlY2F1c2UgZmxvdyBkb2Vzbid0IGxpa2UgYXR0YWNoaW5nXG4gKiBwcm9wZXJ0aWVzIHRvIEVsZW1lbnRzLlxuICovXG5cbnZhciBtb2RlbGFibGVUYWdSRSA9IC9eaW5wdXR8c2VsZWN0fHRleHRhcmVhfHZ1ZS1jb21wb25lbnQtWzAtOV0rKC1bMC05YS16QS1aX1xcLV0qKT8kLztcblxuLyogaXN0YW5idWwgaWdub3JlIGlmICovXG5pZiAoaXNJRTkpIHtcbiAgLy8gaHR0cDovL3d3dy5tYXR0czQxMS5jb20vcG9zdC9pbnRlcm5ldC1leHBsb3Jlci05LW9uaW5wdXQvXG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3NlbGVjdGlvbmNoYW5nZScsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZWwgPSBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuICAgIGlmIChlbCAmJiBlbC52bW9kZWwpIHtcbiAgICAgIHRyaWdnZXIoZWwsICdpbnB1dCcpO1xuICAgIH1cbiAgfSk7XG59XG5cbnZhciBtb2RlbCA9IHtcbiAgaW5zZXJ0ZWQ6IGZ1bmN0aW9uIGluc2VydGVkIChlbCwgYmluZGluZywgdm5vZGUpIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgaWYgKCFtb2RlbGFibGVUYWdSRS50ZXN0KHZub2RlLnRhZykpIHtcbiAgICAgICAgd2FybihcbiAgICAgICAgICBcInYtbW9kZWwgaXMgbm90IHN1cHBvcnRlZCBvbiBlbGVtZW50IHR5cGU6IDxcIiArICh2bm9kZS50YWcpICsgXCI+LiBcIiArXG4gICAgICAgICAgJ0lmIHlvdSBhcmUgd29ya2luZyB3aXRoIGNvbnRlbnRlZGl0YWJsZSwgaXRcXCdzIHJlY29tbWVuZGVkIHRvICcgK1xuICAgICAgICAgICd3cmFwIGEgbGlicmFyeSBkZWRpY2F0ZWQgZm9yIHRoYXQgcHVycG9zZSBpbnNpZGUgYSBjdXN0b20gY29tcG9uZW50LicsXG4gICAgICAgICAgdm5vZGUuY29udGV4dFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodm5vZGUudGFnID09PSAnc2VsZWN0Jykge1xuICAgICAgdmFyIGNiID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBzZXRTZWxlY3RlZChlbCwgYmluZGluZywgdm5vZGUuY29udGV4dCk7XG4gICAgICB9O1xuICAgICAgY2IoKTtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgaWYgKGlzSUUgfHwgaXNFZGdlKSB7XG4gICAgICAgIHNldFRpbWVvdXQoY2IsIDApO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoXG4gICAgICAodm5vZGUudGFnID09PSAndGV4dGFyZWEnIHx8IGVsLnR5cGUgPT09ICd0ZXh0JykgJiZcbiAgICAgICFiaW5kaW5nLm1vZGlmaWVycy5sYXp5XG4gICAgKSB7XG4gICAgICBpZiAoIWlzQW5kcm9pZCkge1xuICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKCdjb21wb3NpdGlvbnN0YXJ0Jywgb25Db21wb3NpdGlvblN0YXJ0KTtcbiAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcignY29tcG9zaXRpb25lbmQnLCBvbkNvbXBvc2l0aW9uRW5kKTtcbiAgICAgIH1cbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgaWYgKGlzSUU5KSB7XG4gICAgICAgIGVsLnZtb2RlbCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBjb21wb25lbnRVcGRhdGVkOiBmdW5jdGlvbiBjb21wb25lbnRVcGRhdGVkIChlbCwgYmluZGluZywgdm5vZGUpIHtcbiAgICBpZiAodm5vZGUudGFnID09PSAnc2VsZWN0Jykge1xuICAgICAgc2V0U2VsZWN0ZWQoZWwsIGJpbmRpbmcsIHZub2RlLmNvbnRleHQpO1xuICAgICAgLy8gaW4gY2FzZSB0aGUgb3B0aW9ucyByZW5kZXJlZCBieSB2LWZvciBoYXZlIGNoYW5nZWQsXG4gICAgICAvLyBpdCdzIHBvc3NpYmxlIHRoYXQgdGhlIHZhbHVlIGlzIG91dC1vZi1zeW5jIHdpdGggdGhlIHJlbmRlcmVkIG9wdGlvbnMuXG4gICAgICAvLyBkZXRlY3Qgc3VjaCBjYXNlcyBhbmQgZmlsdGVyIG91dCB2YWx1ZXMgdGhhdCBubyBsb25nZXIgaGFzIGEgbWF0Y2hpZ1xuICAgICAgLy8gb3B0aW9uIGluIHRoZSBET00uXG4gICAgICB2YXIgbmVlZFJlc2V0ID0gZWwubXVsdGlwbGVcbiAgICAgICAgPyBiaW5kaW5nLnZhbHVlLnNvbWUoZnVuY3Rpb24gKHYpIHsgcmV0dXJuIGhhc05vTWF0Y2hpbmdPcHRpb24odiwgZWwub3B0aW9ucyk7IH0pXG4gICAgICAgIDogYmluZGluZy52YWx1ZSAhPT0gYmluZGluZy5vbGRWYWx1ZSAmJiBoYXNOb01hdGNoaW5nT3B0aW9uKGJpbmRpbmcudmFsdWUsIGVsLm9wdGlvbnMpO1xuICAgICAgaWYgKG5lZWRSZXNldCkge1xuICAgICAgICB0cmlnZ2VyKGVsLCAnY2hhbmdlJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiBzZXRTZWxlY3RlZCAoZWwsIGJpbmRpbmcsIHZtKSB7XG4gIHZhciB2YWx1ZSA9IGJpbmRpbmcudmFsdWU7XG4gIHZhciBpc011bHRpcGxlID0gZWwubXVsdGlwbGU7XG4gIGlmIChpc011bHRpcGxlICYmICFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybihcbiAgICAgIFwiPHNlbGVjdCBtdWx0aXBsZSB2LW1vZGVsPVxcXCJcIiArIChiaW5kaW5nLmV4cHJlc3Npb24pICsgXCJcXFwiPiBcIiArXG4gICAgICBcImV4cGVjdHMgYW4gQXJyYXkgdmFsdWUgZm9yIGl0cyBiaW5kaW5nLCBidXQgZ290IFwiICsgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpKSxcbiAgICAgIHZtXG4gICAgKTtcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgc2VsZWN0ZWQsIG9wdGlvbjtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBlbC5vcHRpb25zLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIG9wdGlvbiA9IGVsLm9wdGlvbnNbaV07XG4gICAgaWYgKGlzTXVsdGlwbGUpIHtcbiAgICAgIHNlbGVjdGVkID0gbG9vc2VJbmRleE9mKHZhbHVlLCBnZXRWYWx1ZShvcHRpb24pKSA+IC0xO1xuICAgICAgaWYgKG9wdGlvbi5zZWxlY3RlZCAhPT0gc2VsZWN0ZWQpIHtcbiAgICAgICAgb3B0aW9uLnNlbGVjdGVkID0gc2VsZWN0ZWQ7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChsb29zZUVxdWFsKGdldFZhbHVlKG9wdGlvbiksIHZhbHVlKSkge1xuICAgICAgICBpZiAoZWwuc2VsZWN0ZWRJbmRleCAhPT0gaSkge1xuICAgICAgICAgIGVsLnNlbGVjdGVkSW5kZXggPSBpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoIWlzTXVsdGlwbGUpIHtcbiAgICBlbC5zZWxlY3RlZEluZGV4ID0gLTE7XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFzTm9NYXRjaGluZ09wdGlvbiAodmFsdWUsIG9wdGlvbnMpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBvcHRpb25zLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGlmIChsb29zZUVxdWFsKGdldFZhbHVlKG9wdGlvbnNbaV0pLCB2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG5mdW5jdGlvbiBnZXRWYWx1ZSAob3B0aW9uKSB7XG4gIHJldHVybiAnX3ZhbHVlJyBpbiBvcHRpb25cbiAgICA/IG9wdGlvbi5fdmFsdWVcbiAgICA6IG9wdGlvbi52YWx1ZVxufVxuXG5mdW5jdGlvbiBvbkNvbXBvc2l0aW9uU3RhcnQgKGUpIHtcbiAgZS50YXJnZXQuY29tcG9zaW5nID0gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gb25Db21wb3NpdGlvbkVuZCAoZSkge1xuICBlLnRhcmdldC5jb21wb3NpbmcgPSBmYWxzZTtcbiAgdHJpZ2dlcihlLnRhcmdldCwgJ2lucHV0Jyk7XG59XG5cbmZ1bmN0aW9uIHRyaWdnZXIgKGVsLCB0eXBlKSB7XG4gIHZhciBlID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0hUTUxFdmVudHMnKTtcbiAgZS5pbml0RXZlbnQodHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIGVsLmRpc3BhdGNoRXZlbnQoZSk7XG59XG5cbi8qICAqL1xuXG4vLyByZWN1cnNpdmVseSBzZWFyY2ggZm9yIHBvc3NpYmxlIHRyYW5zaXRpb24gZGVmaW5lZCBpbnNpZGUgdGhlIGNvbXBvbmVudCByb290XG5mdW5jdGlvbiBsb2NhdGVOb2RlICh2bm9kZSkge1xuICByZXR1cm4gdm5vZGUuY2hpbGQgJiYgKCF2bm9kZS5kYXRhIHx8ICF2bm9kZS5kYXRhLnRyYW5zaXRpb24pXG4gICAgPyBsb2NhdGVOb2RlKHZub2RlLmNoaWxkLl92bm9kZSlcbiAgICA6IHZub2RlXG59XG5cbnZhciBzaG93ID0ge1xuICBiaW5kOiBmdW5jdGlvbiBiaW5kIChlbCwgcmVmLCB2bm9kZSkge1xuICAgIHZhciB2YWx1ZSA9IHJlZi52YWx1ZTtcblxuICAgIHZub2RlID0gbG9jYXRlTm9kZSh2bm9kZSk7XG4gICAgdmFyIHRyYW5zaXRpb24gPSB2bm9kZS5kYXRhICYmIHZub2RlLmRhdGEudHJhbnNpdGlvbjtcbiAgICBpZiAodmFsdWUgJiYgdHJhbnNpdGlvbiAmJiAhaXNJRTkpIHtcbiAgICAgIGVudGVyKHZub2RlKTtcbiAgICB9XG4gICAgdmFyIG9yaWdpbmFsRGlzcGxheSA9IGVsLnN0eWxlLmRpc3BsYXkgPT09ICdub25lJyA/ICcnIDogZWwuc3R5bGUuZGlzcGxheTtcbiAgICBlbC5zdHlsZS5kaXNwbGF5ID0gdmFsdWUgPyBvcmlnaW5hbERpc3BsYXkgOiAnbm9uZSc7XG4gICAgZWwuX192T3JpZ2luYWxEaXNwbGF5ID0gb3JpZ2luYWxEaXNwbGF5O1xuICB9LFxuICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZSAoZWwsIHJlZiwgdm5vZGUpIHtcbiAgICB2YXIgdmFsdWUgPSByZWYudmFsdWU7XG4gICAgdmFyIG9sZFZhbHVlID0gcmVmLm9sZFZhbHVlO1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHZhbHVlID09PSBvbGRWYWx1ZSkgeyByZXR1cm4gfVxuICAgIHZub2RlID0gbG9jYXRlTm9kZSh2bm9kZSk7XG4gICAgdmFyIHRyYW5zaXRpb24gPSB2bm9kZS5kYXRhICYmIHZub2RlLmRhdGEudHJhbnNpdGlvbjtcbiAgICBpZiAodHJhbnNpdGlvbiAmJiAhaXNJRTkpIHtcbiAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICBlbnRlcih2bm9kZSk7XG4gICAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSBlbC5fX3ZPcmlnaW5hbERpc3BsYXk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZWF2ZSh2bm9kZSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gdmFsdWUgPyBlbC5fX3ZPcmlnaW5hbERpc3BsYXkgOiAnbm9uZSc7XG4gICAgfVxuICB9XG59O1xuXG52YXIgcGxhdGZvcm1EaXJlY3RpdmVzID0ge1xuICBtb2RlbDogbW9kZWwsXG4gIHNob3c6IHNob3dcbn07XG5cbi8qICAqL1xuXG4vLyBQcm92aWRlcyB0cmFuc2l0aW9uIHN1cHBvcnQgZm9yIGEgc2luZ2xlIGVsZW1lbnQvY29tcG9uZW50LlxuLy8gc3VwcG9ydHMgdHJhbnNpdGlvbiBtb2RlIChvdXQtaW4gLyBpbi1vdXQpXG5cbnZhciB0cmFuc2l0aW9uUHJvcHMgPSB7XG4gIG5hbWU6IFN0cmluZyxcbiAgYXBwZWFyOiBCb29sZWFuLFxuICBjc3M6IEJvb2xlYW4sXG4gIG1vZGU6IFN0cmluZyxcbiAgdHlwZTogU3RyaW5nLFxuICBlbnRlckNsYXNzOiBTdHJpbmcsXG4gIGxlYXZlQ2xhc3M6IFN0cmluZyxcbiAgZW50ZXJBY3RpdmVDbGFzczogU3RyaW5nLFxuICBsZWF2ZUFjdGl2ZUNsYXNzOiBTdHJpbmcsXG4gIGFwcGVhckNsYXNzOiBTdHJpbmcsXG4gIGFwcGVhckFjdGl2ZUNsYXNzOiBTdHJpbmdcbn07XG5cbi8vIGluIGNhc2UgdGhlIGNoaWxkIGlzIGFsc28gYW4gYWJzdHJhY3QgY29tcG9uZW50LCBlLmcuIDxrZWVwLWFsaXZlPlxuLy8gd2Ugd2FudCB0byByZWNydXNpdmVseSByZXRyaWV2ZSB0aGUgcmVhbCBjb21wb25lbnQgdG8gYmUgcmVuZGVyZWRcbmZ1bmN0aW9uIGdldFJlYWxDaGlsZCAodm5vZGUpIHtcbiAgdmFyIGNvbXBPcHRpb25zID0gdm5vZGUgJiYgdm5vZGUuY29tcG9uZW50T3B0aW9ucztcbiAgaWYgKGNvbXBPcHRpb25zICYmIGNvbXBPcHRpb25zLkN0b3Iub3B0aW9ucy5hYnN0cmFjdCkge1xuICAgIHJldHVybiBnZXRSZWFsQ2hpbGQoZ2V0Rmlyc3RDb21wb25lbnRDaGlsZChjb21wT3B0aW9ucy5jaGlsZHJlbikpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHZub2RlXG4gIH1cbn1cblxuZnVuY3Rpb24gZXh0cmFjdFRyYW5zaXRpb25EYXRhIChjb21wKSB7XG4gIHZhciBkYXRhID0ge307XG4gIHZhciBvcHRpb25zID0gY29tcC4kb3B0aW9ucztcbiAgLy8gcHJvcHNcbiAgZm9yICh2YXIga2V5IGluIG9wdGlvbnMucHJvcHNEYXRhKSB7XG4gICAgZGF0YVtrZXldID0gY29tcFtrZXldO1xuICB9XG4gIC8vIGV2ZW50cy5cbiAgLy8gZXh0cmFjdCBsaXN0ZW5lcnMgYW5kIHBhc3MgdGhlbSBkaXJlY3RseSB0byB0aGUgdHJhbnNpdGlvbiBtZXRob2RzXG4gIHZhciBsaXN0ZW5lcnMgPSBvcHRpb25zLl9wYXJlbnRMaXN0ZW5lcnM7XG4gIGZvciAodmFyIGtleSQxIGluIGxpc3RlbmVycykge1xuICAgIGRhdGFbY2FtZWxpemUoa2V5JDEpXSA9IGxpc3RlbmVyc1trZXkkMV0uZm47XG4gIH1cbiAgcmV0dXJuIGRhdGFcbn1cblxuZnVuY3Rpb24gcGxhY2Vob2xkZXIgKGgsIHJhd0NoaWxkKSB7XG4gIHJldHVybiAvXFxkLWtlZXAtYWxpdmUkLy50ZXN0KHJhd0NoaWxkLnRhZylcbiAgICA/IGgoJ2tlZXAtYWxpdmUnKVxuICAgIDogbnVsbFxufVxuXG5mdW5jdGlvbiBoYXNQYXJlbnRUcmFuc2l0aW9uICh2bm9kZSkge1xuICB3aGlsZSAoKHZub2RlID0gdm5vZGUucGFyZW50KSkge1xuICAgIGlmICh2bm9kZS5kYXRhLnRyYW5zaXRpb24pIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG59XG5cbnZhciBUcmFuc2l0aW9uID0ge1xuICBuYW1lOiAndHJhbnNpdGlvbicsXG4gIHByb3BzOiB0cmFuc2l0aW9uUHJvcHMsXG4gIGFic3RyYWN0OiB0cnVlLFxuICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlciAoaCkge1xuICAgIHZhciB0aGlzJDEgPSB0aGlzO1xuXG4gICAgdmFyIGNoaWxkcmVuID0gdGhpcy4kc2xvdHMuZGVmYXVsdDtcbiAgICBpZiAoIWNoaWxkcmVuKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBmaWx0ZXIgb3V0IHRleHQgbm9kZXMgKHBvc3NpYmxlIHdoaXRlc3BhY2VzKVxuICAgIGNoaWxkcmVuID0gY2hpbGRyZW4uZmlsdGVyKGZ1bmN0aW9uIChjKSB7IHJldHVybiBjLnRhZzsgfSk7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKCFjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIHdhcm4gbXVsdGlwbGUgZWxlbWVudHNcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBjaGlsZHJlbi5sZW5ndGggPiAxKSB7XG4gICAgICB3YXJuKFxuICAgICAgICAnPHRyYW5zaXRpb24+IGNhbiBvbmx5IGJlIHVzZWQgb24gYSBzaW5nbGUgZWxlbWVudC4gVXNlICcgK1xuICAgICAgICAnPHRyYW5zaXRpb24tZ3JvdXA+IGZvciBsaXN0cy4nLFxuICAgICAgICB0aGlzLiRwYXJlbnRcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdmFyIG1vZGUgPSB0aGlzLm1vZGU7XG5cbiAgICAvLyB3YXJuIGludmFsaWQgbW9kZVxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmXG4gICAgICAgIG1vZGUgJiYgbW9kZSAhPT0gJ2luLW91dCcgJiYgbW9kZSAhPT0gJ291dC1pbicpIHtcbiAgICAgIHdhcm4oXG4gICAgICAgICdpbnZhbGlkIDx0cmFuc2l0aW9uPiBtb2RlOiAnICsgbW9kZSxcbiAgICAgICAgdGhpcy4kcGFyZW50XG4gICAgICApO1xuICAgIH1cblxuICAgIHZhciByYXdDaGlsZCA9IGNoaWxkcmVuWzBdO1xuXG4gICAgLy8gaWYgdGhpcyBpcyBhIGNvbXBvbmVudCByb290IG5vZGUgYW5kIHRoZSBjb21wb25lbnQnc1xuICAgIC8vIHBhcmVudCBjb250YWluZXIgbm9kZSBhbHNvIGhhcyB0cmFuc2l0aW9uLCBza2lwLlxuICAgIGlmIChoYXNQYXJlbnRUcmFuc2l0aW9uKHRoaXMuJHZub2RlKSkge1xuICAgICAgcmV0dXJuIHJhd0NoaWxkXG4gICAgfVxuXG4gICAgLy8gYXBwbHkgdHJhbnNpdGlvbiBkYXRhIHRvIGNoaWxkXG4gICAgLy8gdXNlIGdldFJlYWxDaGlsZCgpIHRvIGlnbm9yZSBhYnN0cmFjdCBjb21wb25lbnRzIGUuZy4ga2VlcC1hbGl2ZVxuICAgIHZhciBjaGlsZCA9IGdldFJlYWxDaGlsZChyYXdDaGlsZCk7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKCFjaGlsZCkge1xuICAgICAgcmV0dXJuIHJhd0NoaWxkXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2xlYXZpbmcpIHtcbiAgICAgIHJldHVybiBwbGFjZWhvbGRlcihoLCByYXdDaGlsZClcbiAgICB9XG5cbiAgICB2YXIga2V5ID0gY2hpbGQua2V5ID0gY2hpbGQua2V5ID09IG51bGwgfHwgY2hpbGQuaXNTdGF0aWNcbiAgICAgID8gKFwiX192XCIgKyAoY2hpbGQudGFnICsgdGhpcy5fdWlkKSArIFwiX19cIilcbiAgICAgIDogY2hpbGQua2V5O1xuICAgIHZhciBkYXRhID0gKGNoaWxkLmRhdGEgfHwgKGNoaWxkLmRhdGEgPSB7fSkpLnRyYW5zaXRpb24gPSBleHRyYWN0VHJhbnNpdGlvbkRhdGEodGhpcyk7XG4gICAgdmFyIG9sZFJhd0NoaWxkID0gdGhpcy5fdm5vZGU7XG4gICAgdmFyIG9sZENoaWxkID0gZ2V0UmVhbENoaWxkKG9sZFJhd0NoaWxkKTtcblxuICAgIC8vIG1hcmsgdi1zaG93XG4gICAgLy8gc28gdGhhdCB0aGUgdHJhbnNpdGlvbiBtb2R1bGUgY2FuIGhhbmQgb3ZlciB0aGUgY29udHJvbCB0byB0aGUgZGlyZWN0aXZlXG4gICAgaWYgKGNoaWxkLmRhdGEuZGlyZWN0aXZlcyAmJiBjaGlsZC5kYXRhLmRpcmVjdGl2ZXMuc29tZShmdW5jdGlvbiAoZCkgeyByZXR1cm4gZC5uYW1lID09PSAnc2hvdyc7IH0pKSB7XG4gICAgICBjaGlsZC5kYXRhLnNob3cgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChvbGRDaGlsZCAmJiBvbGRDaGlsZC5kYXRhICYmIG9sZENoaWxkLmtleSAhPT0ga2V5KSB7XG4gICAgICAvLyByZXBsYWNlIG9sZCBjaGlsZCB0cmFuc2l0aW9uIGRhdGEgd2l0aCBmcmVzaCBvbmVcbiAgICAgIC8vIGltcG9ydGFudCBmb3IgZHluYW1pYyB0cmFuc2l0aW9ucyFcbiAgICAgIHZhciBvbGREYXRhID0gb2xkQ2hpbGQuZGF0YS50cmFuc2l0aW9uID0gZXh0ZW5kKHt9LCBkYXRhKTtcblxuICAgICAgLy8gaGFuZGxlIHRyYW5zaXRpb24gbW9kZVxuICAgICAgaWYgKG1vZGUgPT09ICdvdXQtaW4nKSB7XG4gICAgICAgIC8vIHJldHVybiBwbGFjZWhvbGRlciBub2RlIGFuZCBxdWV1ZSB1cGRhdGUgd2hlbiBsZWF2ZSBmaW5pc2hlc1xuICAgICAgICB0aGlzLl9sZWF2aW5nID0gdHJ1ZTtcbiAgICAgICAgbWVyZ2VWTm9kZUhvb2sob2xkRGF0YSwgJ2FmdGVyTGVhdmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdGhpcyQxLl9sZWF2aW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcyQxLiRmb3JjZVVwZGF0ZSgpO1xuICAgICAgICB9LCBrZXkpO1xuICAgICAgICByZXR1cm4gcGxhY2Vob2xkZXIoaCwgcmF3Q2hpbGQpXG4gICAgICB9IGVsc2UgaWYgKG1vZGUgPT09ICdpbi1vdXQnKSB7XG4gICAgICAgIHZhciBkZWxheWVkTGVhdmU7XG4gICAgICAgIHZhciBwZXJmb3JtTGVhdmUgPSBmdW5jdGlvbiAoKSB7IGRlbGF5ZWRMZWF2ZSgpOyB9O1xuICAgICAgICBtZXJnZVZOb2RlSG9vayhkYXRhLCAnYWZ0ZXJFbnRlcicsIHBlcmZvcm1MZWF2ZSwga2V5KTtcbiAgICAgICAgbWVyZ2VWTm9kZUhvb2soZGF0YSwgJ2VudGVyQ2FuY2VsbGVkJywgcGVyZm9ybUxlYXZlLCBrZXkpO1xuICAgICAgICBtZXJnZVZOb2RlSG9vayhvbGREYXRhLCAnZGVsYXlMZWF2ZScsIGZ1bmN0aW9uIChsZWF2ZSkge1xuICAgICAgICAgIGRlbGF5ZWRMZWF2ZSA9IGxlYXZlO1xuICAgICAgICB9LCBrZXkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByYXdDaGlsZFxuICB9XG59O1xuXG4vKiAgKi9cblxuLy8gUHJvdmlkZXMgdHJhbnNpdGlvbiBzdXBwb3J0IGZvciBsaXN0IGl0ZW1zLlxuLy8gc3VwcG9ydHMgbW92ZSB0cmFuc2l0aW9ucyB1c2luZyB0aGUgRkxJUCB0ZWNobmlxdWUuXG5cbi8vIEJlY2F1c2UgdGhlIHZkb20ncyBjaGlsZHJlbiB1cGRhdGUgYWxnb3JpdGhtIGlzIFwidW5zdGFibGVcIiAtIGkuZS5cbi8vIGl0IGRvZXNuJ3QgZ3VhcmFudGVlIHRoZSByZWxhdGl2ZSBwb3NpdGlvbmluZyBvZiByZW1vdmVkIGVsZW1lbnRzLFxuLy8gd2UgZm9yY2UgdHJhbnNpdGlvbi1ncm91cCB0byB1cGRhdGUgaXRzIGNoaWxkcmVuIGludG8gdHdvIHBhc3Nlczpcbi8vIGluIHRoZSBmaXJzdCBwYXNzLCB3ZSByZW1vdmUgYWxsIG5vZGVzIHRoYXQgbmVlZCB0byBiZSByZW1vdmVkLFxuLy8gdHJpZ2dlcmluZyB0aGVpciBsZWF2aW5nIHRyYW5zaXRpb247IGluIHRoZSBzZWNvbmQgcGFzcywgd2UgaW5zZXJ0L21vdmVcbi8vIGludG8gdGhlIGZpbmFsIGRpc2lyZWQgc3RhdGUuIFRoaXMgd2F5IGluIHRoZSBzZWNvbmQgcGFzcyByZW1vdmVkXG4vLyBub2RlcyB3aWxsIHJlbWFpbiB3aGVyZSB0aGV5IHNob3VsZCBiZS5cblxudmFyIHByb3BzID0gZXh0ZW5kKHtcbiAgdGFnOiBTdHJpbmcsXG4gIG1vdmVDbGFzczogU3RyaW5nXG59LCB0cmFuc2l0aW9uUHJvcHMpO1xuXG5kZWxldGUgcHJvcHMubW9kZTtcblxudmFyIFRyYW5zaXRpb25Hcm91cCA9IHtcbiAgcHJvcHM6IHByb3BzLFxuXG4gIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyIChoKSB7XG4gICAgdmFyIHRhZyA9IHRoaXMudGFnIHx8IHRoaXMuJHZub2RlLmRhdGEudGFnIHx8ICdzcGFuJztcbiAgICB2YXIgbWFwID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB2YXIgcHJldkNoaWxkcmVuID0gdGhpcy5wcmV2Q2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuO1xuICAgIHZhciByYXdDaGlsZHJlbiA9IHRoaXMuJHNsb3RzLmRlZmF1bHQgfHwgW107XG4gICAgdmFyIGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlbiA9IFtdO1xuICAgIHZhciB0cmFuc2l0aW9uRGF0YSA9IGV4dHJhY3RUcmFuc2l0aW9uRGF0YSh0aGlzKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmF3Q2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBjID0gcmF3Q2hpbGRyZW5baV07XG4gICAgICBpZiAoYy50YWcpIHtcbiAgICAgICAgaWYgKGMua2V5ICE9IG51bGwgJiYgU3RyaW5nKGMua2V5KS5pbmRleE9mKCdfX3ZsaXN0JykgIT09IDApIHtcbiAgICAgICAgICBjaGlsZHJlbi5wdXNoKGMpO1xuICAgICAgICAgIG1hcFtjLmtleV0gPSBjXG4gICAgICAgICAgOyhjLmRhdGEgfHwgKGMuZGF0YSA9IHt9KSkudHJhbnNpdGlvbiA9IHRyYW5zaXRpb25EYXRhO1xuICAgICAgICB9IGVsc2UgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgICB2YXIgb3B0cyA9IGMuY29tcG9uZW50T3B0aW9ucztcbiAgICAgICAgICB2YXIgbmFtZSA9IG9wdHNcbiAgICAgICAgICAgID8gKG9wdHMuQ3Rvci5vcHRpb25zLm5hbWUgfHwgb3B0cy50YWcpXG4gICAgICAgICAgICA6IGMudGFnO1xuICAgICAgICAgIHdhcm4oKFwiPHRyYW5zaXRpb24tZ3JvdXA+IGNoaWxkcmVuIG11c3QgYmUga2V5ZWQ6IDxcIiArIG5hbWUgKyBcIj5cIikpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHByZXZDaGlsZHJlbikge1xuICAgICAgdmFyIGtlcHQgPSBbXTtcbiAgICAgIHZhciByZW1vdmVkID0gW107XG4gICAgICBmb3IgKHZhciBpJDEgPSAwOyBpJDEgPCBwcmV2Q2hpbGRyZW4ubGVuZ3RoOyBpJDErKykge1xuICAgICAgICB2YXIgYyQxID0gcHJldkNoaWxkcmVuW2kkMV07XG4gICAgICAgIGMkMS5kYXRhLnRyYW5zaXRpb24gPSB0cmFuc2l0aW9uRGF0YTtcbiAgICAgICAgYyQxLmRhdGEucG9zID0gYyQxLmVsbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgaWYgKG1hcFtjJDEua2V5XSkge1xuICAgICAgICAgIGtlcHQucHVzaChjJDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlbW92ZWQucHVzaChjJDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmtlcHQgPSBoKHRhZywgbnVsbCwga2VwdCk7XG4gICAgICB0aGlzLnJlbW92ZWQgPSByZW1vdmVkO1xuICAgIH1cblxuICAgIHJldHVybiBoKHRhZywgbnVsbCwgY2hpbGRyZW4pXG4gIH0sXG5cbiAgYmVmb3JlVXBkYXRlOiBmdW5jdGlvbiBiZWZvcmVVcGRhdGUgKCkge1xuICAgIC8vIGZvcmNlIHJlbW92aW5nIHBhc3NcbiAgICB0aGlzLl9fcGF0Y2hfXyhcbiAgICAgIHRoaXMuX3Zub2RlLFxuICAgICAgdGhpcy5rZXB0LFxuICAgICAgZmFsc2UsIC8vIGh5ZHJhdGluZ1xuICAgICAgdHJ1ZSAvLyByZW1vdmVPbmx5ICghaW1wb3J0YW50LCBhdm9pZHMgdW5uZWNlc3NhcnkgbW92ZXMpXG4gICAgKTtcbiAgICB0aGlzLl92bm9kZSA9IHRoaXMua2VwdDtcbiAgfSxcblxuICB1cGRhdGVkOiBmdW5jdGlvbiB1cGRhdGVkICgpIHtcbiAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLnByZXZDaGlsZHJlbjtcbiAgICB2YXIgbW92ZUNsYXNzID0gdGhpcy5tb3ZlQ2xhc3MgfHwgKHRoaXMubmFtZSArICctbW92ZScpO1xuICAgIGlmICghY2hpbGRyZW4ubGVuZ3RoIHx8ICF0aGlzLmhhc01vdmUoY2hpbGRyZW5bMF0uZWxtLCBtb3ZlQ2xhc3MpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyB3ZSBkaXZpZGUgdGhlIHdvcmsgaW50byB0aHJlZSBsb29wcyB0byBhdm9pZCBtaXhpbmcgRE9NIHJlYWRzIGFuZCB3cml0ZXNcbiAgICAvLyBpbiBlYWNoIGl0ZXJhdGlvbiAtIHdoaWNoIGhlbHBzIHByZXZlbnQgbGF5b3V0IHRocmFzaGluZy5cbiAgICBjaGlsZHJlbi5mb3JFYWNoKGNhbGxQZW5kaW5nQ2JzKTtcbiAgICBjaGlsZHJlbi5mb3JFYWNoKHJlY29yZFBvc2l0aW9uKTtcbiAgICBjaGlsZHJlbi5mb3JFYWNoKGFwcGx5VHJhbnNsYXRpb24pO1xuXG4gICAgLy8gZm9yY2UgcmVmbG93IHRvIHB1dCBldmVyeXRoaW5nIGluIHBvc2l0aW9uXG4gICAgdmFyIGYgPSBkb2N1bWVudC5ib2R5Lm9mZnNldEhlaWdodDsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG4gICAgY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbiAoYykge1xuICAgICAgaWYgKGMuZGF0YS5tb3ZlZCkge1xuICAgICAgICB2YXIgZWwgPSBjLmVsbTtcbiAgICAgICAgdmFyIHMgPSBlbC5zdHlsZTtcbiAgICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBtb3ZlQ2xhc3MpO1xuICAgICAgICBzLnRyYW5zZm9ybSA9IHMuV2Via2l0VHJhbnNmb3JtID0gcy50cmFuc2l0aW9uRHVyYXRpb24gPSAnJztcbiAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcih0cmFuc2l0aW9uRW5kRXZlbnQsIGVsLl9tb3ZlQ2IgPSBmdW5jdGlvbiBjYiAoZSkge1xuICAgICAgICAgIGlmICghZSB8fCAvdHJhbnNmb3JtJC8udGVzdChlLnByb3BlcnR5TmFtZSkpIHtcbiAgICAgICAgICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIodHJhbnNpdGlvbkVuZEV2ZW50LCBjYik7XG4gICAgICAgICAgICBlbC5fbW92ZUNiID0gbnVsbDtcbiAgICAgICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbW92ZUNsYXNzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9LFxuXG4gIG1ldGhvZHM6IHtcbiAgICBoYXNNb3ZlOiBmdW5jdGlvbiBoYXNNb3ZlIChlbCwgbW92ZUNsYXNzKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgIGlmICghaGFzVHJhbnNpdGlvbikge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9oYXNNb3ZlICE9IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hhc01vdmVcbiAgICAgIH1cbiAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgbW92ZUNsYXNzKTtcbiAgICAgIHZhciBpbmZvID0gZ2V0VHJhbnNpdGlvbkluZm8oZWwpO1xuICAgICAgcmVtb3ZlVHJhbnNpdGlvbkNsYXNzKGVsLCBtb3ZlQ2xhc3MpO1xuICAgICAgcmV0dXJuICh0aGlzLl9oYXNNb3ZlID0gaW5mby5oYXNUcmFuc2Zvcm0pXG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiBjYWxsUGVuZGluZ0NicyAoYykge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKGMuZWxtLl9tb3ZlQ2IpIHtcbiAgICBjLmVsbS5fbW92ZUNiKCk7XG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChjLmVsbS5fZW50ZXJDYikge1xuICAgIGMuZWxtLl9lbnRlckNiKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVjb3JkUG9zaXRpb24gKGMpIHtcbiAgYy5kYXRhLm5ld1BvcyA9IGMuZWxtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xufVxuXG5mdW5jdGlvbiBhcHBseVRyYW5zbGF0aW9uIChjKSB7XG4gIHZhciBvbGRQb3MgPSBjLmRhdGEucG9zO1xuICB2YXIgbmV3UG9zID0gYy5kYXRhLm5ld1BvcztcbiAgdmFyIGR4ID0gb2xkUG9zLmxlZnQgLSBuZXdQb3MubGVmdDtcbiAgdmFyIGR5ID0gb2xkUG9zLnRvcCAtIG5ld1Bvcy50b3A7XG4gIGlmIChkeCB8fCBkeSkge1xuICAgIGMuZGF0YS5tb3ZlZCA9IHRydWU7XG4gICAgdmFyIHMgPSBjLmVsbS5zdHlsZTtcbiAgICBzLnRyYW5zZm9ybSA9IHMuV2Via2l0VHJhbnNmb3JtID0gXCJ0cmFuc2xhdGUoXCIgKyBkeCArIFwicHgsXCIgKyBkeSArIFwicHgpXCI7XG4gICAgcy50cmFuc2l0aW9uRHVyYXRpb24gPSAnMHMnO1xuICB9XG59XG5cbnZhciBwbGF0Zm9ybUNvbXBvbmVudHMgPSB7XG4gIFRyYW5zaXRpb246IFRyYW5zaXRpb24sXG4gIFRyYW5zaXRpb25Hcm91cDogVHJhbnNpdGlvbkdyb3VwXG59O1xuXG4vKiAgKi9cblxuLy8gaW5zdGFsbCBwbGF0Zm9ybSBzcGVjaWZpYyB1dGlsc1xuVnVlJDIuY29uZmlnLmlzVW5rbm93bkVsZW1lbnQgPSBpc1Vua25vd25FbGVtZW50O1xuVnVlJDIuY29uZmlnLmlzUmVzZXJ2ZWRUYWcgPSBpc1Jlc2VydmVkVGFnO1xuVnVlJDIuY29uZmlnLmdldFRhZ05hbWVzcGFjZSA9IGdldFRhZ05hbWVzcGFjZTtcblZ1ZSQyLmNvbmZpZy5tdXN0VXNlUHJvcCA9IG11c3RVc2VQcm9wO1xuXG4vLyBpbnN0YWxsIHBsYXRmb3JtIHJ1bnRpbWUgZGlyZWN0aXZlcyAmIGNvbXBvbmVudHNcbmV4dGVuZChWdWUkMi5vcHRpb25zLmRpcmVjdGl2ZXMsIHBsYXRmb3JtRGlyZWN0aXZlcyk7XG5leHRlbmQoVnVlJDIub3B0aW9ucy5jb21wb25lbnRzLCBwbGF0Zm9ybUNvbXBvbmVudHMpO1xuXG4vLyBpbnN0YWxsIHBsYXRmb3JtIHBhdGNoIGZ1bmN0aW9uXG5WdWUkMi5wcm90b3R5cGUuX19wYXRjaF9fID0gY29uZmlnLl9pc1NlcnZlciA/IG5vb3AgOiBwYXRjaCQxO1xuXG4vLyB3cmFwIG1vdW50XG5WdWUkMi5wcm90b3R5cGUuJG1vdW50ID0gZnVuY3Rpb24gKFxuICBlbCxcbiAgaHlkcmF0aW5nXG4pIHtcbiAgZWwgPSBlbCAmJiAhY29uZmlnLl9pc1NlcnZlciA/IHF1ZXJ5KGVsKSA6IHVuZGVmaW5lZDtcbiAgcmV0dXJuIHRoaXMuX21vdW50KGVsLCBoeWRyYXRpbmcpXG59O1xuXG4vLyBkZXZ0b29scyBnbG9iYWwgaG9va1xuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICBpZiAoY29uZmlnLmRldnRvb2xzKSB7XG4gICAgaWYgKGRldnRvb2xzKSB7XG4gICAgICBkZXZ0b29scy5lbWl0KCdpbml0JywgVnVlJDIpO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmXG4gICAgICBpbkJyb3dzZXIgJiYgL0Nocm9tZVxcL1xcZCsvLnRlc3Qod2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQpXG4gICAgKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgJ0Rvd25sb2FkIHRoZSBWdWUgRGV2dG9vbHMgZm9yIGEgYmV0dGVyIGRldmVsb3BtZW50IGV4cGVyaWVuY2U6XFxuJyArXG4gICAgICAgICdodHRwczovL2dpdGh1Yi5jb20vdnVlanMvdnVlLWRldnRvb2xzJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cbn0sIDApO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFZ1ZSQyO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Z1ZS9kaXN0L3Z1ZS5jb21tb24uanNcbi8vIG1vZHVsZSBpZCA9IDEyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=");
},function(module,exports,__webpack_require__){"use strict";eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__components_view_school_main__ = __webpack_require__(35);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__components_view_school_main___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__components_view_school_main__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__components_navbar__ = __webpack_require__(32);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__components_navbar___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__components_navbar__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_n_zepto__ = __webpack_require__(2);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_n_zepto___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_n_zepto__);\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n\n\n/* harmony default export */ exports[\"default\"] = {\n    data: function data() {\n        return {};\n    },\n    ready: function ready() {},\n\n    computed: {},\n    mounted: function mounted() {},\n\n    methods: {},\n    components: {\n        'school': __WEBPACK_IMPORTED_MODULE_0__components_view_school_main___default.a,\n        'navbar': __WEBPACK_IMPORTED_MODULE_1__components_navbar___default.a\n    }\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vQXBwLnZ1ZT9mNGYxIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBV0E7QUFDQTtBQUNBOztBQUVBOzBCQUVBO2VBR0E7QUFDQTs0QkFFQSxDQUNBOztjQUNBO2lDQUNBOzthQUNBOztrQkFFQTtrQkFFQTtBQUhBO0FBWkEiLCJmaWxlIjoiMTMuanMiLCJzb3VyY2VzQ29udGVudCI6WyI8dGVtcGxhdGU+XG48ZGl2IGlkPVwiYXBwXCIgY2xhc3M9XCJwYWdlLWdyb3VwXCI+XG4gIDxkaXYgY2xhc3M9XCJwYWdlXCI+XG4gICAgPHNjaG9vbD48L3NjaG9vbD5cbiAgICA8bmF2YmFyPjwvbmF2YmFyPlxuICA8L2Rpdj5cblxuPC9kaXY+XG48L3RlbXBsYXRlPlxuXG48c2NyaXB0PlxuaW1wb3J0IHNjaG9vbCBmcm9tICcuL2NvbXBvbmVudHMvdmlldy9zY2hvb2wvbWFpbic7XG5pbXBvcnQgbmF2YmFyIGZyb20gJy4vY29tcG9uZW50cy9uYXZiYXInO1xuaW1wb3J0ICQgZnJvbSAnbi16ZXB0byc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBkYXRhKCkge1xuICAgICAgICByZXR1cm4ge1xuXG4gICAgICAgIH1cbiAgICB9LFxuICAgIHJlYWR5KCl7XG5cbiAgICB9LFxuICAgIGNvbXB1dGVkOiB7fSxcbiAgICBtb3VudGVkKCkge30sXG4gICAgbWV0aG9kczoge30sXG4gICAgY29tcG9uZW50czoge1xuICAgICAgICAnc2Nob29sJzogc2Nob29sLFxuICAgICAgICAnbmF2YmFyJzogbmF2YmFyXG4gICAgfVxufVxuPC9zY3JpcHQ+XG5cbjxzdHlsZT5cblxuPC9zdHlsZT5cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBBcHAudnVlPzc5OGNkNGVlIl0sInNvdXJjZVJvb3QiOiIifQ==")},function(module,exports,__webpack_require__){"use strict";eval("//\n//\n//\n//\n//\n//\n//\n//\n//\n\n/* harmony default export */ exports[\"default\"] = {\n  data: function data() {\n    return {\n      path: this.$route.path || window.location.pathname\n    };\n  },\n\n  watch: {\n    $route: 'fetchData'\n  },\n  computed: {},\n  mounted: function mounted() {},\n\n  methods: {\n    fetchData: function fetchData() {\n      this.path = this.$route.path || window.location.pathname;\n    }\n  },\n  components: {}\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vbmF2YmFyLnZ1ZT81M2ZlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFVQTt3QkFFQTs7Z0RBR0E7QUFGQTtBQUdBOzs7WUFHQTtBQUZBO1lBR0E7K0JBQ0E7OztvQ0FFQTtzREFDQTtBQUVBO0FBSkE7Y0FLQTtBQWhCQSIsImZpbGUiOiIxNC5qcyIsInNvdXJjZXNDb250ZW50IjpbIjx0ZW1wbGF0ZSBsYW5nPVwiaHRtbFwiPlxuICA8bmF2IGNsYXNzPVwiYmFyIGJhci10YWJcIj5cbiAgICAgIDxyb3V0ZXItbGluayB0bz1cIi9zY2hvb2xJbnRyb1wiIGNsYXNzPVwidGFiLWl0ZW0gZXh0ZXJuYWxcIiA6Y2xhc3M9XCJ7YWN0aXZlOiBwYXRoPT09Jy9zY2hvb2xJbnRybycgfHwgcGF0aD09PScvJ31cIj4g6LWE5paZPC9yb3V0ZXItbGluaz5cbiAgICAgIDxyb3V0ZXItbGluayB0bz1cIi9zY2hvb2xJbnRyb0NvbnN1bHRhbnRcIiBjbGFzcz1cInRhYi1pdGVtIGV4dGVybmFsXCIgOmNsYXNzPVwie2FjdGl2ZTogcGF0aD09PScvc2Nob29sSW50cm9Db25zdWx0YW50J31cIj7pob7pl648L3JvdXRlci1saW5rPlxuICAgICAgPHJvdXRlci1saW5rIHRvPVwiL3NjaG9vbEludHJvVmlkZW9cIiBjbGFzcz1cInRhYi1pdGVtIGV4dGVybmFsXCIgOmNsYXNzPVwie2FjdGl2ZTogcGF0aD09PScvc2Nob29sSW50cm9WaWRlbyd9XCI+6KeG6aKRPC9yb3V0ZXItbGluaz5cbiAgICAgIDxyb3V0ZXItbGluayB0bz1cIi9zY2hvb2xJbnRyb1F1ZXN0aW9uXCIgY2xhc3M9XCJ0YWItaXRlbSBleHRlcm5hbFwiIDpjbGFzcz1cInthY3RpdmU6IHBhdGg9PT0nL3NjaG9vbEludHJvUXVlc3Rpb24nfVwiPumXrumimDwvcm91dGVyLWxpbms+XG4gIDwvbmF2PlxuPC90ZW1wbGF0ZT5cblxuPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHBhdGg6IHRoaXMuJHJvdXRlLnBhdGggfHwgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lXG4gICAgfVxuICB9LFxuICB3YXRjaDoge1xuICAgICAgJHJvdXRlOiAnZmV0Y2hEYXRhJ1xuICB9LFxuICBjb21wdXRlZDoge30sXG4gIG1vdW50ZWQgKCkge30sXG4gIG1ldGhvZHM6IHtcbiAgICBmZXRjaERhdGE6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5wYXRoID0gdGhpcy4kcm91dGUucGF0aCB8fCB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWVcbiAgICB9XG4gIH0sXG4gIGNvbXBvbmVudHM6IHt9XG59XG48L3NjcmlwdD5cblxuPHN0eWxlIGxhbmc9XCJjc3NcIj5cbjwvc3R5bGU+XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gbmF2YmFyLnZ1ZT80YjE1N2JhNCJdLCJzb3VyY2VSb290IjoiIn0=")},function(module,exports,__webpack_require__){"use strict";eval("//\n//\n//\n//\n//\n//\n//\n\n/* harmony default export */ exports[\"default\"] = {\n  data: function data() {\n    return {\n      text: '收藏'\n    };\n  },\n\n  computed: {},\n  mounted: function mounted() {},\n\n  methods: {},\n  components: {}\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vY29sbGVjdC52dWU/YTk5YSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQVFBO3dCQUVBOztZQUdBO0FBRkE7QUFHQTs7WUFDQTsrQkFDQTs7V0FDQTtjQUNBO0FBVEEiLCJmaWxlIjoiMTUuanMiLCJzb3VyY2VzQ29udGVudCI6WyI8dGVtcGxhdGUgbGFuZz1cImh0bWxcIj5cbiAgICA8c3BhbiBjbGFzcz1cImNvbGxlY3RcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJpY29uIGljb24tc3RhclwiIHN0eWxlPVwibWFyZ2luLWJvdHRvbTogLjFyZW07XCI+PC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInRleHRcIj57e3RleHR9fTwvc3Bhbj5cbiAgICA8L3NwYW4+XG48L3RlbXBsYXRlPlxuXG48c2NyaXB0PlxuZXhwb3J0IGRlZmF1bHQge1xuICBkYXRhICgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdGV4dDogJ+aUtuiXjydcbiAgICB9XG4gIH0sXG4gIGNvbXB1dGVkOiB7fSxcbiAgbW91bnRlZCAoKSB7fSxcbiAgbWV0aG9kczoge30sXG4gIGNvbXBvbmVudHM6IHt9XG59XG48L3NjcmlwdD5cblxuPHN0eWxlIGxhbmc9XCJjc3NcIj5cbjwvc3R5bGU+XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gY29sbGVjdC52dWU/NDg3YzdhZmUiXSwic291cmNlUm9vdCI6IiJ9")},function(module,exports,__webpack_require__){"use strict";eval("//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n/* harmony default export */ exports[\"default\"] = {\n    data: function data() {\n        return {\n            infos: [{\n                src: 'https://unsplash.it/250',\n                style: 'width: 2.2rem',\n                name: '老王',\n                rank: '资深美国留学顾问',\n                experience: '服务经验1年'\n            }, {\n                src: 'https://unsplash.it/250',\n                style: 'width: 2.2rem',\n                name: '老李',\n                rank: '资深美国留学顾问',\n                experience: '服务经验2年'\n            }, {\n                src: 'https://unsplash.it/250',\n                style: 'width: 2.2rem',\n                name: '老张',\n                rank: '资深美国留学顾问',\n                experience: '服务经验3年'\n            }]\n        };\n    },\n\n    computed: {},\n    mounted: function mounted() {},\n\n    methods: {},\n    components: {}\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vY29uc3VsdGFudC52dWU/ODliOSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE4QkE7MEJBRUE7OztxQkFJQTt1QkFDQTtzQkFDQTtzQkFDQTs0QkFFQTtBQU5BLGFBREE7cUJBU0E7dUJBQ0E7c0JBQ0E7c0JBQ0E7NEJBRUE7QUFOQTtxQkFRQTt1QkFDQTtzQkFDQTtzQkFDQTs0QkFJQTtBQVJBO0FBaEJBO0FBeUJBOztjQUNBO2lDQUNBOzthQUNBO2dCQUNBO0FBL0JBIiwiZmlsZSI6IjE2LmpzIiwic291cmNlc0NvbnRlbnQiOlsiPHRlbXBsYXRlIGxhbmc9XCJodG1sXCI+XG4gIDxkaXYgY2xhc3M9XCJsaXN0LWJsb2NrIG1lZGlhLWxpc3RcIj5cbiAgICAgIDx1bD5cbiAgICAgICAgICA8bGkgdi1mb3I9XCJpbmZvIGluIGluZm9zXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLW1lZGlhXCI+PGltZyA6c3JjPVwiaW5mby5zcmNcIiA6c3R5bGU9XCJpbmZvLnN0eWxlXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbS1pbm5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLXRpdGxlLXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbS10aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3tpbmZvLm5hbWV9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwic2V4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpY29uIGljb24tZG93bmxvYWRcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aSBzdHlsZT1cImNvbG9yOiBvcmFuZ2VcIj48c3BhbiBjbGFzcz1cImljb24gaWNvbi1zdGFyXCI+PC9zcGFuPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIHN0eWxlPVwiY29sb3I6IG9yYW5nZVwiPjxzcGFuIGNsYXNzPVwiaWNvbiBpY29uLXN0YXJcIj48L3NwYW4+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGk+PHNwYW4gY2xhc3M9XCJpY29uIGljb24tc3RhclwiPjwvc3Bhbj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtLXN1YnRpdGxlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7aW5mby5yYW5rfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7aW5mby5leHBlcmllbmNlfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9saT5cbiAgICAgIDwvdWw+XG4gIDwvZGl2PlxuPC90ZW1wbGF0ZT5cblxuPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGluZm9zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgICBzcmM6ICdodHRwczovL3Vuc3BsYXNoLml0LzI1MCcsXG4gICAgICAgICAgICAgIHN0eWxlOiAnd2lkdGg6IDIuMnJlbScsXG4gICAgICAgICAgICAgIG5hbWU6ICfogIHnjosnLFxuICAgICAgICAgICAgICByYW5rOiAn6LWE5rex576O5Zu955WZ5a2m6aG+6ZeuJyxcbiAgICAgICAgICAgICAgZXhwZXJpZW5jZTogJ+acjeWKoee7j+mqjDHlubQnXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICAgIHNyYzogJ2h0dHBzOi8vdW5zcGxhc2guaXQvMjUwJyxcbiAgICAgICAgICAgICAgc3R5bGU6ICd3aWR0aDogMi4ycmVtJyxcbiAgICAgICAgICAgICAgbmFtZTogJ+iAgeadjicsXG4gICAgICAgICAgICAgIHJhbms6ICfotYTmt7Hnvo7lm73nlZnlrabpob7pl64nLFxuICAgICAgICAgICAgICBleHBlcmllbmNlOiAn5pyN5Yqh57uP6aqMMuW5tCdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgICAgc3JjOiAnaHR0cHM6Ly91bnNwbGFzaC5pdC8yNTAnLFxuICAgICAgICAgICAgICBzdHlsZTogJ3dpZHRoOiAyLjJyZW0nLFxuICAgICAgICAgICAgICBuYW1lOiAn6ICB5bygJyxcbiAgICAgICAgICAgICAgcmFuazogJ+i1hOa3see+juWbveeVmeWtpumhvumXricsXG4gICAgICAgICAgICAgIGV4cGVyaWVuY2U6ICfmnI3liqHnu4/pqowz5bm0J1xuICAgICAgICAgIH1cbiAgICAgIF1cbiAgICB9XG4gIH0sXG4gIGNvbXB1dGVkOiB7fSxcbiAgbW91bnRlZCAoKSB7fSxcbiAgbWV0aG9kczoge30sXG4gIGNvbXBvbmVudHM6IHt9XG59XG48L3NjcmlwdD5cblxuPHN0eWxlIGxhbmc9XCJjc3NcIj5cbjwvc3R5bGU+XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gY29uc3VsdGFudC52dWU/M2I3Y2UyNGYiXSwic291cmNlUm9vdCI6IiJ9")},function(module,exports,__webpack_require__){"use strict";eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__collect_vue__ = __webpack_require__(33);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__collect_vue___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__collect_vue__);\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n\n\n/* harmony default export */ exports[\"default\"] = {\n  data: function data() {\n    return {\n      src: \"background-image: url('https://unsplash.it/400')\",\n      name: '麻省理工学院(剑桥)',\n      intro: '麻省理工学院成立于1860年,是美国一所综合性私立大学,有“世界理工大学之最”的美名。美国国家研究协会会员',\n      iSrc: 'https://unsplash.it/500'\n    };\n  },\n\n  computed: {},\n  mounted: function mounted() {},\n\n  methods: {},\n  components: {\n    'collect': __WEBPACK_IMPORTED_MODULE_0__collect_vue___default.a\n  }\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vaGVhZGVyLnZ1ZT9mMDBmIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFjQTs7QUFFQTt3QkFFQTs7V0FFQTtZQUNBO2FBQ0E7WUFFQTtBQUxBO0FBTUE7O1lBQ0E7K0JBQ0E7O1dBQ0E7O2VBR0E7QUFGQTtBQVpBIiwiZmlsZSI6IjE3LmpzIiwic291cmNlc0NvbnRlbnQiOlsiPHRlbXBsYXRlIGxhbmc9XCJodG1sXCI+XG4gIDxkaXYgaWQ9XCJpbmZvSGVhZGVyXCI+XG4gICAgPGRpdiBjbGFzcz1cImhlYWRlci13cmFwcGVyIGJsdXJcIiA6c3R5bGU9XCJzcmNcIj48L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiZ28tYmFja1wiPjxzcGFuIGNsYXNzPVwiaWNvbiBpY29uLWxlZnRcIj48L3NwYW4+PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInNjaG9vbF9iYWRnZVwiPjxpbWcgOnNyYz1cImlTcmNcIj48L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwic2Nob29sX2luZm9cIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0XCI+e3tuYW1lfX08L3NwYW4+XG4gICAgICAgIDxjb2xsZWN0PjwvY29sbGVjdD5cbiAgICAgICAgPGRpdiBjbGFzcz1cImludHJvIG9taXQgb21pdDJcIj57e2ludHJvfX08L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L3RlbXBsYXRlPlxuXG48c2NyaXB0PlxuaW1wb3J0IGNvbGxlY3QgZnJvbSAnLi9jb2xsZWN0LnZ1ZSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNyYzogXCJiYWNrZ3JvdW5kLWltYWdlOiB1cmwoJ2h0dHBzOi8vdW5zcGxhc2guaXQvNDAwJylcIixcbiAgICAgIG5hbWU6ICfpurvnnIHnkIblt6XlrabpmaIo5YmR5qGlKScsXG4gICAgICBpbnRybzogJ+m6u+ecgeeQhuW3peWtpumZouaIkOeri+S6jjE4NjDlubTvvIzmmK/nvo7lm73kuIDmiYDnu7zlkIjmgKfnp4Hnq4vlpKflraYs5pyJ4oCc5LiW55WM55CG5bel5aSn5a2m5LmL5pyA4oCd55qE576O5ZCN44CC576O5Zu95Zu95a6256CU56m25Y2P5Lya5Lya5ZGYJyxcbiAgICAgIGlTcmM6ICdodHRwczovL3Vuc3BsYXNoLml0LzUwMCdcbiAgICB9XG4gIH0sXG4gIGNvbXB1dGVkOiB7fSxcbiAgbW91bnRlZCAoKSB7fSxcbiAgbWV0aG9kczoge30sXG4gIGNvbXBvbmVudHM6IHtcbiAgICAnY29sbGVjdCc6IGNvbGxlY3RcbiAgfVxufVxuPC9zY3JpcHQ+XG5cbjxzdHlsZSBsYW5nPVwiY3NzXCI+XG48L3N0eWxlPlxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIGhlYWRlci52dWU/NWZjODk2NjYiXSwic291cmNlUm9vdCI6IiJ9")},function(module,exports,__webpack_require__){"use strict";eval("//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n/* harmony default export */ exports[\"default\"] = {\n    data: function data() {\n        return {\n            infos: [{\n                title: '学校概述',\n                p1: '麻省理工学院于1861年由一位毕业于老牌南方名校威廉玛丽学院的著名自然科学家威廉·巴顿·罗杰斯创立,他希望能够创建一个自由的学院来迎合快速发展时期的美国。由于南北战争,直到1865年MIT才迎来了第一批学生,随后其在自然及工程领域迅速发展。在大萧条时期,MIT曾一度被认为会同哈佛大学合并,但在该校学生的抗议之下,被迫取消了这一计划。',\n                p2: '就在有关草议获批两天后,美国内战的第一场战役就展开了。为时数年的战争使学校的教研工作延误。1865年,麻省理工正式在位于波士顿的校园内开班。这所新院校的使命符合《土地拨赠法案》的要求,故获赠地作进一步发展。1866年,由土地销售带来的利益使学校得以在后湾区发展。'\n            }, {\n                title: '申请条件',\n                school: '麻省理工学院',\n                rank: {\n                    undergraduate: {\n                        ibt: 70,\n                        sat: '1660-2200'\n                    },\n                    master: {\n                        ibt: 50,\n                        gre: '1770'\n                    },\n                    doctor: {\n                        ibt: 40,\n                        gre: '1234'\n                    }\n                }\n            }]\n        };\n    },\n\n    computed: {},\n    mounted: function mounted() {},\n\n    methods: {},\n    components: {}\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vaW50cm8udnVlPzBiZGMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFnQ0E7MEJBRUE7Ozt1QkFJQTtvQkFDQTtvQkFFQTtBQUpBLGFBREE7dUJBT0E7d0JBQ0E7Ozs2QkFHQTs2QkFFQTtBQUhBOzs2QkFLQTs2QkFFQTtBQUhBOzs2QkFLQTs2QkFNQTtBQVBBO0FBVEE7QUFIQTtBQVBBO0FBMkJBOztjQUNBO2lDQUNBOzthQUNBO2dCQUNBO0FBakNBIiwiZmlsZSI6IjE4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiPHRlbXBsYXRlIGxhbmc9XCJodG1sXCI+XG48ZGl2PlxuICA8ZGl2IHYtZm9yPVwiKGluZm8saW5kZXgpIG9mIGluZm9zXCIgY2xhc3M9XCJpbnRyby1ib3hcIj5cbiAgICAgIDxkaXYgdi1pZj1cImluZGV4ID09PSAwXCI+XG4gICAgICAgICAgPGgyIGNsYXNzPVwidGl0bGVcIj48c3Bhbj57e2luZm8udGl0bGV9fTwvc3Bhbj48L2gyPlxuICAgICAgICAgIDxwPnt7aW5mby5wMX19PC9wPlxuICAgICAgICAgIDxwIGNsYXNzPVwib21pdCBvbWl0MlwiPnt7aW5mby5wMn19PC9wPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb3JlXCI+XG4gICAgICAgICAgICAgIDxhIGhyZWY9XCIjXCI+TU9SRTwvYT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vcmUtbGlua1wiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpY29uIGljb24tcmlnaHRcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IHYtZWxzZT5cbiAgICAgICAgICA8aDIgY2xhc3M9XCJ0aXRsZVwiPjxzcGFuPnt7aW5mby50aXRsZX19PC9zcGFuPjwvaDI+XG4gICAgICAgICAgPHAgY2xhc3M9XCJuby1pbmRlbnRcIj48c3Bhbj57e2luZm8uc2Nob29sfX08L3NwYW4+57u85ZCI5YWl5a2m5p2h5Lu277yaPHNwYW4gY2xhc3M9XCJ0ZXh0LWluZm9cIj4o5pyA5L2O5qCH5YeGKTwvc3Bhbj48L3A+XG4gICAgICAgICAgPHA+5pys56eR77yaVE9FRkwmbmJzcDsmbmJzcDtpQlTvvJo8c3BhbiBjbGFzcz1cInRleHQtaW1wb3J0YW50XCI+e3tpbmZvLnJhbmsudW5kZXJncmFkdWF0ZS5pYnR9fTwvc3Bhbj7liIYmbmJzcDsmbmJzcDtTQVTlsYXkuK3miJDnu6nvvJo8c3BhblxuICAgICAgICAgICAgICBjbGFzcz1cInRleHQtaW1wb3J0YW50XCI+e3tpbmZvLnJhbmsudW5kZXJncmFkdWF0ZS5zYXR9fTwvc3Bhbj7vvIzlj6bpmYTpq5jkuK3miJDnu6nljZXvvIzoi7HmlofotKLlipvor4HmmI7nrYnnm7jlhbPotYTmlpnvvJs8L3A+XG4gICAgICAgICAgPHA+56GV5aOr77yaVE9FRkwmbmJzcDsmbmJzcDtpQlTvvJo8c3BhbiBjbGFzcz1cInRleHQtaW1wb3J0YW50XCI+e3tpbmZvLnJhbmsubWFzdGVyLmlidH19PC9zcGFuPuWIhiZuYnNwOyZuYnNwO0dSReaIkOe7qe+8mjxzcGFuXG4gICAgICAgICAgICAgIGNsYXNzPVwidGV4dC1pbXBvcnRhbnRcIj57e2luZm8ucmFuay5tYXN0ZXIuZ3JlfX08L3NwYW4+77yMR1BB77yaMy4z77yM5Y+m6ZmE5pys56eR5oiQ57up5Y2V77yM6Iux5paH6LSi5Yqb6K+B5piO562J55u45YWz6LWE5paZ77ybPC9wPlxuICAgICAgICAgIDxwPuWNmuWjq++8mlRPRUZMJm5ic3A7Jm5ic3A7aUJU77yaPHNwYW4gY2xhc3M9XCJ0ZXh0LWltcG9ydGFudFwiPnt7aW5mby5yYW5rLmRvY3Rvci5pYnR9fTwvc3Bhbj7liIYmbmJzcDsmbmJzcDtHUkXmiJDnu6nvvJo8c3BhblxuICAgICAgICAgICAgICBjbGFzcz1cInRleHQtaW1wb3J0YW50XCI+e3tpbmZvLnJhbmsuZG9jdG9yLmdyZX19PC9zcGFuPu+8jEdQQe+8mjMuM++8jOWPpumZhOacrOenkeaIkOe7qeWNle+8jOiLseaWh+i0ouWKm+ivgeaYjuetieebuOWFs+i1hOaWme+8mzwvcD5cbiAgICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cInRlc3QtaW1nXCI+XG4xMTFcbiAgPC9kaXY+XG48L2Rpdj5cbjwvdGVtcGxhdGU+XG5cbjxzY3JpcHQ+XG5leHBvcnQgZGVmYXVsdCB7XG4gIGRhdGEgKCkge1xuICAgIHJldHVybiB7XG4gICAgICBpbmZvczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdGl0bGU6ICflrabmoKHmpoLov7AnLFxuICAgICAgICAgICAgICBwMTogJ+m6u+ecgeeQhuW3peWtpumZouS6jjE4NjHlubTnlLHkuIDkvY3mr5XkuJrkuo7ogIHniYzljZfmlrnlkI3moKHlqIHlu4nnjpvkuL3lrabpmaLnmoTokZflkI3oh6rnhLbnp5HlrablrrblqIHlu4nCt+W3tOmhv8K3572X5p2w5pav5Yib56uL77yM5LuW5biM5pyb6IO95aSf5Yib5bu65LiA5Liq6Ieq55Sx55qE5a2m6Zmi5p2l6L+O5ZCI5b+r6YCf5Y+R5bGV5pe25pyf55qE576O5Zu944CC55Sx5LqO5Y2X5YyX5oiY5LqJ77yM55u05YiwMTg2NeW5tE1JVOaJjei/juadpeS6huesrOS4gOaJueWtpueUn++8jOmaj+WQjuWFtuWcqOiHqueEtuWPiuW3peeoi+mihuWfn+i/hemAn+WPkeWxleOAguWcqOWkp+iQp+adoeaXtuacn++8jE1JVOabvuS4gOW6puiiq+iupOS4uuS8muWQjOWTiOS9m+Wkp+WtpuWQiOW5tu+8jOS9huWcqOivpeagoeWtpueUn+eahOaKl+iuruS5i+S4i++8jOiiq+i/q+WPlua2iOS6hui/meS4gOiuoeWIkuOAgicsXG4gICAgICAgICAgICAgIHAyOiAn5bCx5Zyo5pyJ5YWz6I2J6K6u6I635om55Lik5aSp5ZCO77yM576O5Zu95YaF5oiY55qE56ys5LiA5Zy65oiY5b255bCx5bGV5byA5LqG44CC5Li65pe25pWw5bm055qE5oiY5LqJ5L2/5a2m5qCh55qE5pWZ56CU5bel5L2c5bu26K+v44CCMTg2NeW5tO+8jOm6u+ecgeeQhuW3peato+W8j+WcqOS9jeS6juazouWjq+mhv+eahOagoeWbreWGheW8gOePreOAgui/meaJgOaWsOmZouagoeeahOS9v+WRveespuWQiOOAiuWcn+WcsOaLqOi1oOazleahiOOAi+eahOimgeaxgu+8jOaVheiOt+i1oOWcsOS9nOi/m+S4gOatpeWPkeWxleOAgjE4NjblubTvvIznlLHlnJ/lnLDplIDllK7luKbmnaXnmoTliKnnm4rkvb/lrabmoKHlvpfku6XlnKjlkI7mub7ljLrlj5HlsZXjgIInXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICAgIHRpdGxlOiAn55Sz6K+35p2h5Lu2JyxcbiAgICAgICAgICAgICAgc2Nob29sOiAn6bq755yB55CG5bel5a2m6ZmiJyxcbiAgICAgICAgICAgICAgcmFuazoge1xuICAgICAgICAgICAgICAgICAgdW5kZXJncmFkdWF0ZToge1xuICAgICAgICAgICAgICAgICAgICAgIGlidDogNzAsXG4gICAgICAgICAgICAgICAgICAgICAgc2F0OiAnMTY2MC0yMjAwJ1xuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIG1hc3Rlcjoge1xuICAgICAgICAgICAgICAgICAgICAgIGlidDogNTAsXG4gICAgICAgICAgICAgICAgICAgICAgZ3JlOiAnMTc3MCdcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBkb2N0b3I6IHtcbiAgICAgICAgICAgICAgICAgICAgICBpYnQ6IDQwLFxuICAgICAgICAgICAgICAgICAgICAgIGdyZTogJzEyMzQnXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICBdXG4gICAgfVxuICB9LFxuICBjb21wdXRlZDoge30sXG4gIG1vdW50ZWQgKCkge30sXG4gIG1ldGhvZHM6IHt9LFxuICBjb21wb25lbnRzOiB7fVxufVxuPC9zY3JpcHQ+XG5cbjxzdHlsZSBsYW5nPVwibGVzc1wiPlxuXG48L3N0eWxlPlxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIGludHJvLnZ1ZT82YThiZjQ2YSJdLCJzb3VyY2VSb290IjoiIn0=")},function(module,exports,__webpack_require__){"use strict";eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__header_vue__ = __webpack_require__(34);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__header_vue___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__header_vue__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_n_zepto__ = __webpack_require__(2);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_n_zepto___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_n_zepto__);\n//\n//\n//\n//\n//\n//\n//\n\n\n\n\n/* harmony default export */ exports[\"default\"] = {\n  data: function data() {\n    return {};\n  },\n\n  computed: {},\n  mounted: function mounted() {},\n\n  methods: {},\n  components: {\n    'infoHeader': __WEBPACK_IMPORTED_MODULE_0__header_vue___default.a\n  }\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vbWFpbi52dWU/NzYzNiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFRQTtBQUNBOztBQUVBO3dCQUVBO1dBQ0E7QUFDQTs7WUFDQTsrQkFDQTs7V0FDQTs7a0JBR0E7QUFGQTtBQVBBIiwiZmlsZSI6IjE5LmpzIiwic291cmNlc0NvbnRlbnQiOlsiPHRlbXBsYXRlIGxhbmc9XCJodG1sXCI+XG4gIDxkaXYgY2xhc3M9XCJjb250ZW50XCI+XG4gICAgICA8aW5mby1oZWFkZXI+PC9pbmZvLWhlYWRlcj5cbiAgICAgIDxyb3V0ZXItdmlldz48L3JvdXRlci12aWV3PlxuICA8L2Rpdj5cbjwvdGVtcGxhdGU+XG5cbjxzY3JpcHQ+XG5pbXBvcnQgaW5mb0hlYWRlciBmcm9tICcuL2hlYWRlci52dWUnO1xuaW1wb3J0ICQgZnJvbSAnbi16ZXB0byc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSAoKSB7XG4gICAgcmV0dXJuIHt9XG4gIH0sXG4gIGNvbXB1dGVkOiB7fSxcbiAgbW91bnRlZCAoKSB7fSxcbiAgbWV0aG9kczoge30sXG4gIGNvbXBvbmVudHM6IHtcbiAgICAnaW5mb0hlYWRlcic6IGluZm9IZWFkZXJcbiAgfVxufVxuPC9zY3JpcHQ+XG5cbjxzdHlsZSBsYW5nPVwiY3NzXCI+XG48L3N0eWxlPlxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIG1haW4udnVlPzdkOGU2OTUyIl0sInNvdXJjZVJvb3QiOiIifQ==")},function(module,exports,__webpack_require__){"use strict";eval("//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n/* harmony default export */ exports[\"default\"] = {\n    data: function data() {\n        return {\n            infos: [{\n                title: '美国留学,如果想拿到美国的永久居住身份,需要达到什么条件?',\n                tags: ['美国留学', '美国身份'],\n                uSrc: 'https://unsplash.it/40',\n                name: '老李',\n                status: {\n                    pay: true,\n                    text: '1元付费听'\n                },\n                rSrc: '../../../src/assets/res/Battle_Without_Honor_Or_Humanity.mp3',\n                datetime: '2016-09-08'\n            }, {\n                title: '美国留学,如果想拿到美国的永久居住身份,需要达到什么条件?',\n                tags: ['美国留学', '美国身份'],\n                uSrc: 'https://unsplash.it/40',\n                name: '老张',\n                status: {\n                    free: true,\n                    text: '限时免费听'\n                },\n                rSrc: '../../../src/assets/res/Battle_Without_Honor_Or_Humanity.mp3',\n                datetime: '2016-09-08'\n            }, {\n                title: '美国留学,如果想拿到美国的永久居住身份,需要达到什么条件?',\n                tags: ['美国留学', '美国身份'],\n                uSrc: 'https://unsplash.it/40',\n                name: '老王',\n                status: {\n                    expire: true,\n                    text: '已失效无法收听'\n                },\n                rSrc: '../../../src/assets/res/Battle_Without_Honor_Or_Humanity.mp3',\n                datetime: '2016-09-08'\n            }]\n        };\n    },\n\n    computed: {},\n    mounted: function mounted() {\n        // audio list\n        var audios = $('audio');\n        // insert audio duration into html\n        audios.each(function (index, item) {\n            var audio = item;\n            var duration = 0;\n            var i = $(audio).parent().siblings('.ms').find('i');\n\n            // 如果音频失效不获取值\n            if (!$(audio).parent().hasClass('expire')) {\n                var delay;\n\n                (function () {\n                    // 获取设置秒数\n                    var setTime = function setTime() {\n                        var now = +new Date();\n                        // 定时3分钟,获取不到就不获取了\n                        if (delay - now < 3 * 60 * 1000) {\n                            setTimeout(function () {\n                                duration = audio.duration;\n                                if (isNaN(duration)) {\n                                    setTime();\n                                } else {\n                                    i.html(duration.toFixed(0));\n                                }\n                            }, 10);\n                        }\n                    };\n\n                    // 设置延时\n                    delay = +new Date();\n\n                    // 默认值\n\n                    i.html(0);\n\n                    setTime();\n                })();\n            } else {\n                i.parent().html(''); // 清空时间\n            }\n        });\n        var timer = null;\n        var player = $('.plug').find('.plug-box'); // all audio wrapper\n\n        player.each(function (index, item) {\n            // 过滤失效音频,点击无效\n            if (!$(item).hasClass('expire')) {\n                $(item).on('click', function () {\n                    var audio = this.getElementsByTagName('audio')[0]; // 当前播放器\n                    // 音频不可播放\n                    if (!isNaN(audio.duration)) {\n                        stopOtherAudio(audio); // 停止当前页面其他播放器\n                        playAudio(audio); // 播放当前播放器\n                    } else {\n                        alert('对不起,该音频不可播放!');\n                    }\n                });\n            }\n        });\n\n        // 停止其他播放器\n        function stopOtherAudio(audio) {\n            var current = audio; // 当前播放器\n            var audios = $('audio'); // 所有播放器\n            // insert audio duration into html\n            audios.each(function (index, item) {\n                if (item !== current) {\n                    item.pause(); // stop other audios\n                }\n                if (item === current) {\n                    msCount(item);\n                }\n            });\n        }\n\n        // 播放当前播放器\n        function playAudio(audio) {\n            if (audio.paused) {\n                audio.play();\n                startCount(audio);\n            } else {\n                audio.pause();\n                stopCount();\n            }\n        }\n\n        // start count\n        function startCount(audio) {\n            msCount(audio);\n        }\n\n        // stop count\n        function stopCount() {\n            clearTimeout(timer);\n        }\n\n        // 计数器\n        function msCount(audio) {\n            var currentTime = audio.currentTime; // 播放器当前位置\n            var totalTime = audio.duration; // 播放器总时长\n            var remainTime = Math.floor(totalTime - currentTime); // 剩余时间\n            $(audio).parent().siblings('.ms').find('i').html(remainTime); // 插入时间\n            timer = setTimeout(function () {\n                msCount(audio);\n            }, 1000);\n        }\n    },\n\n    methods: {},\n    components: {}\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vcXVlc3Rpb24udnVlP2QyZDEiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0RBOzBCQUVBOzs7dUJBSUE7K0JBQ0E7c0JBQ0E7c0JBQ0E7O3lCQUVBOzBCQUVBO0FBSEE7c0JBSUE7MEJBRUE7QUFYQSxhQURBO3VCQWNBOytCQUNBO3NCQUNBO3NCQUNBOzswQkFFQTswQkFFQTtBQUhBO3NCQUlBOzBCQUVBO0FBWEE7dUJBYUE7K0JBQ0E7c0JBQ0E7c0JBQ0E7OzRCQUVBOzBCQUVBO0FBSEE7c0JBSUE7MEJBSUE7QUFiQTtBQTFCQTtBQXdDQTs7Y0FDQTtnQ0FDQTtBQUNBO3VCQUNBO0FBQ0E7MkNBQ0E7d0JBQ0E7MkJBQ0E7MkRBRUE7O0FBQ0E7O0FBQ0E7OztBQU1BO3FEQUNBO3VDQUNBO0FBQ0E7eURBQ0E7bURBQ0E7aURBQ0E7cURBQ0E7QUFDQTtBQUNBLHVDQUNBOzREQUNBO0FBQ0E7K0JBQ0E7QUFDQTtBQUVBOztBQXJCQTtpQ0FFQTs7QUFDQTs7MkJBQ0E7O0FBbUJBOzttQkFDQTtxQ0FDQTtBQUNBO0FBQ0E7b0JBQ0E7bURBRUE7OzJDQUNBO0FBQ0E7NkNBQ0E7Z0RBQ0E7dUVBQ0E7QUFDQTs7K0NBRUE7eUNBREEsQ0FFQTsyQkFDQTs4QkFDQTtBQUVBO0FBQ0E7QUFDQTtBQUVBOztBQUNBOztnQ0FDQSxDQUNBO3FDQUNBO0FBQ0E7K0NBQ0E7O2lDQUNBLENBQ0E7QUFDQTtzQ0FDQTs0QkFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFDQTtrQ0FDQTs4QkFDQTtzQkFDQTsyQkFDQTttQkFDQTtzQkFDQTtBQUNBO0FBQ0E7QUFFQTs7QUFDQTttQ0FDQTtvQkFDQTtBQUVBOztBQUNBOzZCQUNBO3lCQUNBO0FBRUE7O0FBQ0E7Z0NBQ0E7aURBQ0E7NENBQ0E7a0VBQ0E7MEVBQ0E7MkNBQ0E7d0JBQ0E7ZUFDQTtBQUNBO0FBQ0E7O2FBQ0E7Z0JBQ0E7QUF2SkEiLCJmaWxlIjoiMjAuanMiLCJzb3VyY2VzQ29udGVudCI6WyI8dGVtcGxhdGUgbGFuZz1cImh0bWxcIj5cbiAgPGRpdj5cbiAgICA8ZGl2IHYtZm9yPVwiaW5mbyBvZiBpbmZvc1wiIGNsYXNzPVwibWl4LWluZm8td3JhcHBlclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibWl4LWluZm8tY29udGVudFwiPlxuICAgICAgICAgICAgPHA+e3tpbmZvLnRpdGxlfX08L3A+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFnXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gdi1mb3I9XCJ0YWcgb2YgaW5mby50YWdzXCI+e3t0YWd9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1peC1pbmZvLW1lZGlhXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVkaWFcIj5cbiAgICAgICAgICAgICAgICA8aW1nIDpzcmM9XCJpbmZvLnVTcmNcIiBhbHQ9XCJcIj5cbiAgICAgICAgICAgICAgICA8c3Bhbj57e2luZm8ubmFtZX19PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicGx1Z1wiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibXNcIj48aT48L2k+Jyc8L3NwYW4+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBsdWctYm94XCIgOmNsYXNzPVwieydwYXknOmluZm8uc3RhdHVzLnBheSwnZnJlZSc6aW5mby5zdGF0dXMuZnJlZSwnZXhwaXJlJzppbmZvLnN0YXR1cy5leHBpcmV9XCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXJyb3ctbGVmdFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpY29uIGljb24tcmlnaHRcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dFwiIHYtaWY9XCJpbmZvLnN0YXR1cy5wYXlcIj57e2luZm8uc3RhdHVzLnRleHR9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0XCIgdi1pZj1cImluZm8uc3RhdHVzLmZyZWVcIj57e2luZm8uc3RhdHVzLnRleHR9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0XCIgdi1pZj1cImluZm8uc3RhdHVzLmV4cGlyZVwiPnt7aW5mby5zdGF0dXMudGV4dH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8YXVkaW8gOnNyYz1cImluZm8uclNyY1wiPjwvYXVkaW8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0aW1lXCI+e3tpbmZvLmRhdGV0aW1lfX08L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtaXgtaW5mby1hY3Rpb25cIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTMzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaWNvbiBpY29uLWFwcFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPGk+MTE1MDwvaT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTMzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaWNvbiBpY29uLWFwcFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPGk+MTE1MDwvaT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTMzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaWNvbiBpY29uLWFwcFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPGk+MTE1MDwvaT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L3RlbXBsYXRlPlxuXG48c2NyaXB0PlxuZXhwb3J0IGRlZmF1bHQge1xuICBkYXRhICgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaW5mb3M6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICAgIHRpdGxlOiAn576O5Zu955WZ5a2mLOWmguaenOaDs+aLv+WIsOe+juWbveeahOawuOS5heWxheS9j+i6q+S7vSzpnIDopoHovr7liLDku4DkuYjmnaHku7Y/JyxcbiAgICAgICAgICAgICAgdGFnczogWyfnvo7lm73nlZnlraYnLCfnvo7lm73ouqvku70nXSxcbiAgICAgICAgICAgICAgdVNyYzogJ2h0dHBzOi8vdW5zcGxhc2guaXQvNDAnLFxuICAgICAgICAgICAgICBuYW1lOiAn6ICB5p2OJyxcbiAgICAgICAgICAgICAgc3RhdHVzOiB7XG4gICAgICAgICAgICAgICAgICBwYXk6IHRydWUsXG4gICAgICAgICAgICAgICAgICB0ZXh0OiAnMeWFg+S7mOi0ueWQrCdcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgclNyYzogJy4uLy4uLy4uL3NyYy9hc3NldHMvcmVzL0JhdHRsZV9XaXRob3V0X0hvbm9yX09yX0h1bWFuaXR5Lm1wMycsXG4gICAgICAgICAgICAgIGRhdGV0aW1lOiAnMjAxNi0wOS0wOCdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdGl0bGU6ICfnvo7lm73nlZnlraYs5aaC5p6c5oOz5ou/5Yiw576O5Zu955qE5rC45LmF5bGF5L2P6Lqr5Lu9LOmcgOimgei+vuWIsOS7gOS5iOadoeS7tj8nLFxuICAgICAgICAgICAgICB0YWdzOiBbJ+e+juWbveeVmeWtpicsJ+e+juWbvei6q+S7vSddLFxuICAgICAgICAgICAgICB1U3JjOiAnaHR0cHM6Ly91bnNwbGFzaC5pdC80MCcsXG4gICAgICAgICAgICAgIG5hbWU6ICfogIHlvKAnLFxuICAgICAgICAgICAgICBzdGF0dXM6IHtcbiAgICAgICAgICAgICAgICAgIGZyZWU6IHRydWUsXG4gICAgICAgICAgICAgICAgICB0ZXh0OiAn6ZmQ5pe25YWN6LS55ZCsJ1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICByU3JjOiAnLi4vLi4vLi4vc3JjL2Fzc2V0cy9yZXMvQmF0dGxlX1dpdGhvdXRfSG9ub3JfT3JfSHVtYW5pdHkubXAzJyxcbiAgICAgICAgICAgICAgZGF0ZXRpbWU6ICcyMDE2LTA5LTA4J1xuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgICB0aXRsZTogJ+e+juWbveeVmeWtpizlpoLmnpzmg7Pmi7/liLDnvo7lm73nmoTmsLjkuYXlsYXkvY/ouqvku70s6ZyA6KaB6L6+5Yiw5LuA5LmI5p2h5Lu2PycsXG4gICAgICAgICAgICAgIHRhZ3M6IFsn576O5Zu955WZ5a2mJywn576O5Zu96Lqr5Lu9J10sXG4gICAgICAgICAgICAgIHVTcmM6ICdodHRwczovL3Vuc3BsYXNoLml0LzQwJyxcbiAgICAgICAgICAgICAgbmFtZTogJ+iAgeeOiycsXG4gICAgICAgICAgICAgIHN0YXR1czoge1xuICAgICAgICAgICAgICAgICAgZXhwaXJlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgdGV4dDogJ+W3suWkseaViOaXoOazleaUtuWQrCdcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgclNyYzogJy4uLy4uLy4uL3NyYy9hc3NldHMvcmVzL0JhdHRsZV9XaXRob3V0X0hvbm9yX09yX0h1bWFuaXR5Lm1wMycsXG4gICAgICAgICAgICAgIGRhdGV0aW1lOiAnMjAxNi0wOS0wOCdcbiAgICAgICAgICB9XG4gICAgICBdXG4gICAgfVxuICB9LFxuICBjb21wdXRlZDoge30sXG4gIG1vdW50ZWQgKCkge1xuICAgIC8vIGF1ZGlvIGxpc3RcbiAgICB2YXIgYXVkaW9zID0gJCgnYXVkaW8nKTtcbiAgICAvLyBpbnNlcnQgYXVkaW8gZHVyYXRpb24gaW50byBodG1sXG4gICAgYXVkaW9zLmVhY2goZnVuY3Rpb24gKGluZGV4LCBpdGVtKSB7XG4gICAgICAgIHZhciBhdWRpbyA9IGl0ZW07XG4gICAgICAgIHZhciBkdXJhdGlvbiA9IDA7XG4gICAgICAgIHZhciBpID0gJChhdWRpbykucGFyZW50KCkuc2libGluZ3MoJy5tcycpLmZpbmQoJ2knKTtcblxuICAgICAgICAvLyDlpoLmnpzpn7PpopHlpLHmlYjkuI3ojrflj5blgLxcbiAgICAgICAgaWYgKCEoJChhdWRpbykucGFyZW50KCkuaGFzQ2xhc3MoJ2V4cGlyZScpKSkge1xuICAgICAgICAgICAgLy8g6K6+572u5bu25pe2XG4gICAgICAgICAgICB2YXIgZGVsYXkgPSArbmV3IERhdGUoKTtcblxuICAgICAgICAgICAgLy8g6buY6K6k5YC8XG4gICAgICAgICAgICBpLmh0bWwoMCk7XG4gICAgICAgICAgICAvLyDojrflj5borr7nva7np5LmlbBcbiAgICAgICAgICAgIGZ1bmN0aW9uIHNldFRpbWUoKSB7XG4gICAgICAgICAgICAgICAgdmFyIG5vdyA9ICtuZXcgRGF0ZSgpO1xuICAgICAgICAgICAgICAgIC8vIOWumuaXtjPliIbpkp8s6I635Y+W5LiN5Yiw5bCx5LiN6I635Y+W5LqGXG4gICAgICAgICAgICAgICAgaWYgKGRlbGF5IC0gbm93IDwgMyAqIDYwICogMTAwMCkge1xuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gYXVkaW8uZHVyYXRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNOYU4oZHVyYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaS5odG1sKGR1cmF0aW9uLnRvRml4ZWQoMCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LCAxMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzZXRUaW1lKCk7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGkucGFyZW50KCkuaHRtbCgnJyk7IC8vIOa4heepuuaXtumXtFxuICAgICAgICB9XG4gICAgfSk7XG4gICAgdmFyIHRpbWVyID0gbnVsbDtcbiAgICB2YXIgcGxheWVyID0gJCgnLnBsdWcnKS5maW5kKCcucGx1Zy1ib3gnKTsgLy8gYWxsIGF1ZGlvIHdyYXBwZXJcblxuICAgIHBsYXllci5lYWNoKGZ1bmN0aW9uIChpbmRleCwgaXRlbSkge1xuICAgICAgICAvLyDov4fmu6TlpLHmlYjpn7PpopEs54K55Ye75peg5pWIXG4gICAgICAgIGlmICghJChpdGVtKS5oYXNDbGFzcygnZXhwaXJlJykpIHtcbiAgICAgICAgICAgICQoaXRlbSkub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBhdWRpbyA9IHRoaXMuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2F1ZGlvJylbMF07IC8vIOW9k+WJjeaSreaUvuWZqFxuICAgICAgICAgICAgICAgIC8vIOmfs+mikeS4jeWPr+aSreaUvlxuICAgICAgICAgICAgICAgIGlmICghaXNOYU4oYXVkaW8uZHVyYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0b3BPdGhlckF1ZGlvKGF1ZGlvKTsgLy8g5YGc5q2i5b2T5YmN6aG16Z2i5YW25LuW5pKt5pS+5ZmoXG4gICAgICAgICAgICAgICAgICAgIHBsYXlBdWRpbyhhdWRpbyk7IC8vIOaSreaUvuW9k+WJjeaSreaUvuWZqFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFsZXJ0KCflr7nkuI3otbcs6K+l6Z+z6aKR5LiN5Y+v5pKt5pS+IScpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIOWBnOatouWFtuS7luaSreaUvuWZqFxuICAgIGZ1bmN0aW9uIHN0b3BPdGhlckF1ZGlvKGF1ZGlvKSB7XG4gICAgICAgIHZhciBjdXJyZW50ID0gYXVkaW87IC8vIOW9k+WJjeaSreaUvuWZqFxuICAgICAgICB2YXIgYXVkaW9zID0gJCgnYXVkaW8nKTsgLy8g5omA5pyJ5pKt5pS+5ZmoXG4gICAgICAgIC8vIGluc2VydCBhdWRpbyBkdXJhdGlvbiBpbnRvIGh0bWxcbiAgICAgICAgYXVkaW9zLmVhY2goZnVuY3Rpb24gKGluZGV4LCBpdGVtKSB7XG4gICAgICAgICAgICBpZiAoaXRlbSAhPT0gY3VycmVudCkge1xuICAgICAgICAgICAgICAgIGl0ZW0ucGF1c2UoKTsgLy8gc3RvcCBvdGhlciBhdWRpb3NcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpdGVtID09PSBjdXJyZW50KSB7XG4gICAgICAgICAgICAgICAgbXNDb3VudChpdGVtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICAvLyDmkq3mlL7lvZPliY3mkq3mlL7lmahcbiAgICBmdW5jdGlvbiBwbGF5QXVkaW8oYXVkaW8pIHtcbiAgICAgICAgaWYgKGF1ZGlvLnBhdXNlZCkge1xuICAgICAgICAgICAgYXVkaW8ucGxheSgpO1xuICAgICAgICAgICAgc3RhcnRDb3VudChhdWRpbyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhdWRpby5wYXVzZSgpO1xuICAgICAgICAgICAgc3RvcENvdW50KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzdGFydCBjb3VudFxuICAgIGZ1bmN0aW9uIHN0YXJ0Q291bnQoYXVkaW8pIHtcbiAgICAgICAgbXNDb3VudChhdWRpbyk7XG4gICAgfVxuXG4gICAgLy8gc3RvcCBjb3VudFxuICAgIGZ1bmN0aW9uIHN0b3BDb3VudCgpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICB9XG5cbiAgICAvLyDorqHmlbDlmahcbiAgICBmdW5jdGlvbiBtc0NvdW50KGF1ZGlvKSB7XG4gICAgICAgIHZhciBjdXJyZW50VGltZSA9IGF1ZGlvLmN1cnJlbnRUaW1lOyAvLyDmkq3mlL7lmajlvZPliY3kvY3nva5cbiAgICAgICAgdmFyIHRvdGFsVGltZSA9IGF1ZGlvLmR1cmF0aW9uOyAvLyDmkq3mlL7lmajmgLvml7bplb9cbiAgICAgICAgdmFyIHJlbWFpblRpbWUgPSBNYXRoLmZsb29yKHRvdGFsVGltZSAtIGN1cnJlbnRUaW1lKTsgLy8g5Ymp5L2Z5pe26Ze0XG4gICAgICAgICQoYXVkaW8pLnBhcmVudCgpLnNpYmxpbmdzKCcubXMnKS5maW5kKCdpJykuaHRtbChyZW1haW5UaW1lKTsgLy8g5o+S5YWl5pe26Ze0XG4gICAgICAgIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBtc0NvdW50KGF1ZGlvKTtcbiAgICAgICAgfSwgMTAwMCk7XG4gICAgfVxuICB9LFxuICBtZXRob2RzOiB7fSxcbiAgY29tcG9uZW50czoge31cbn1cbjwvc2NyaXB0PlxuXG48c3R5bGUgbGFuZz1cImxlc3NcIj5cbi5hIHtcbiAgICBkaXNwbGF5OiBibG9jaztcbn1cbjwvc3R5bGU+XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gcXVlc3Rpb24udnVlPzA1MzBlODJlIl0sInNvdXJjZVJvb3QiOiIifQ==");
},function(module,exports,__webpack_require__){"use strict";eval("//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n/* harmony default export */ exports[\"default\"] = {\n  data: function data() {\n    return {\n      notice: '【麻省理工学院(剑桥)】快速申请,正在直播大家快进来啊',\n      infos: [{\n        uSrc: 'https://unsplash.it/40',\n        name: '老王',\n        time: '2016-09-08',\n        pSrc: 'https://unsplash.it/350/230',\n        vSrc: '../../../src/assets/res/BigBuckBunny_320x180.mp4',\n        lookedNum: '21566',\n        title: '麻省理工学院(剑桥大学)研究生热门专业以及本科院校有哪些?',\n        tags: ['剑桥大学', '热门专业', '本科院校']\n      }]\n    };\n  },\n\n  computed: {},\n  mounted: function mounted() {},\n\n  methods: {},\n  components: {}\n};\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vdmlkZW8udnVlPzkzNWUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFrREE7d0JBRUE7O2NBRUE7O2NBR0E7Y0FDQTtjQUNBO2NBQ0E7Y0FDQTttQkFDQTtlQUNBOytCQUlBO0FBWEEsT0FEQTtBQUZBO0FBZUE7O1lBQ0E7K0JBQ0E7O1dBQ0E7Y0FDQTtBQXJCQSIsImZpbGUiOiIyMS5qcyIsInNvdXJjZXNDb250ZW50IjpbIjx0ZW1wbGF0ZSBsYW5nPVwiaHRtbFwiPlxuICA8ZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cIm5vdGljZVwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwib21pdCBvbWl0MVwiPjxzcGFuIGNsYXNzPVwiaWNvbiBpY29uLW1lc3NhZ2VcIj57e25vdGljZX19PC9zcGFuPjwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiB2LWZvcj1cImluZm8gaW4gaW5mb3NcIiBjbGFzcz1cIm1peC1pbmZvLXdyYXBwZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibWl4LWluZm8tbWVkaWFcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lZGlhXCI+XG4gICAgICAgICAgICAgICAgICA8aW1nIDpzcmM9XCJpbmZvLnVTcmNcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPnt7aW5mby5uYW1lfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGltZVwiPnt7aW5mby50aW1lfX08L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibWl4LWluZm8tb3RoZXJcIj5cbiAgICAgICAgICAgICAgPHZpZGVvIGNvbnRyb2xzIDpwb3N0ZXI9XCJpbmZvLnBTcmNcIiB3aWR0aD1cIjM1MFwiIGhlaWdodD1cIjIzMFwiPlxuICAgICAgICAgICAgICAgICAgPHNvdXJjZSA6c3JjPVwiaW5mby52U3JjXCIgdHlwZT1cInZpZGVvL21wNFwiPlxuICAgICAgICAgICAgICAgICAgPHA+WW91ciBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgSC4yNjQvTVA0LjwvcD5cbiAgICAgICAgICAgICAgPC92aWRlbz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIndpZGdldFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdj48c3Bhbj57e2luZm8ubG9va2VkTnVtfX08L3NwYW4+5Lq6Jm5ic3A75bey55yLPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8ZGl2PuWbnuaUvjwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibWl4LWluZm8tY29udGVudFwiPlxuICAgICAgICAgICAgICA8cD57e2luZm8udGl0bGV9fTwvcD5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRhZ1wiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gdi1mb3I9XCJ0YWcgb2YgaW5mby50YWdzXCI+e3t0YWd9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cIm1peC1pbmZvLWFjdGlvblwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTMzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpY29uIGljb24tYXBwXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIDxpPjExNTA8L2k+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtMzNcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImljb24gaWNvbi1hcHBcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPGk+MTE1MDwvaT5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC0zM1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaWNvbiBpY29uLWFwcFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8aT4xMTUwPC9pPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gIDwvZGl2PlxuPC90ZW1wbGF0ZT5cblxuPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5vdGljZTogJ+OAkOm6u+ecgeeQhuW3peWtpumZou+8iOWJkeahpe+8ieOAkeW/q+mAn+eUs+ivtyzmraPlnKjnm7Tmkq3lpKflrrblv6vov5vmnaXllYonLFxuICAgICAgaW5mb3M6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICAgIHVTcmM6ICdodHRwczovL3Vuc3BsYXNoLml0LzQwJyxcbiAgICAgICAgICAgICAgbmFtZTogJ+iAgeeOiycsXG4gICAgICAgICAgICAgIHRpbWU6ICcyMDE2LTA5LTA4JyxcbiAgICAgICAgICAgICAgcFNyYzogJ2h0dHBzOi8vdW5zcGxhc2guaXQvMzUwLzIzMCcsXG4gICAgICAgICAgICAgIHZTcmM6ICcuLi8uLi8uLi9zcmMvYXNzZXRzL3Jlcy9CaWdCdWNrQnVubnlfMzIweDE4MC5tcDQnLFxuICAgICAgICAgICAgICBsb29rZWROdW06ICcyMTU2NicsXG4gICAgICAgICAgICAgIHRpdGxlOiAn6bq755yB55CG5bel5a2m6ZmiKOWJkeahpeWkp+WtpinnoJTnqbbnlJ/ng63pl6jkuJPkuJrku6Xlj4rmnKznp5HpmaLmoKHmnInlk6rkups/JyxcbiAgICAgICAgICAgICAgdGFnczogWyfliZHmoaXlpKflraYnLCfng63pl6jkuJPkuJonLCfmnKznp5HpmaLmoKEnXVxuICAgICAgICAgIH1cbiAgICAgIF1cbiAgICB9XG4gIH0sXG4gIGNvbXB1dGVkOiB7fSxcbiAgbW91bnRlZCAoKSB7fSxcbiAgbWV0aG9kczoge30sXG4gIGNvbXBvbmVudHM6IHt9XG59XG5cblxuPC9zY3JpcHQ+XG5cbjxzdHlsZSBsYW5nPVwiY3NzXCI+XG48L3N0eWxlPlxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIHZpZGVvLnZ1ZT82NGIxMjJlYSJdLCJzb3VyY2VSb290IjoiIn0=")},function(module,exports,__webpack_require__){eval('exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n", "", {"version":3,"sources":[],"names":[],"mappings":"","file":"header.vue","sourceRoot":"webpack://"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9oZWFkZXIudnVlP2U0YmYiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTs7O0FBR0E7QUFDQSx1R0FBd0csZ0dBQWdHOztBQUV4TSIsImZpbGUiOiIyMi5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJcIixcImZpbGVcIjpcImhlYWRlci52dWVcIixcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtMDAyMWE3NzAhLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9oZWFkZXIudnVlXG4vLyBtb2R1bGUgaWQgPSAyMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n", "", {"version":3,"sources":[],"names":[],"mappings":"","file":"consultant.vue","sourceRoot":"webpack://"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9jb25zdWx0YW50LnZ1ZT8yN2FkIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7OztBQUdBO0FBQ0EscUtBQXNLLG9HQUFvRzs7QUFFMVEiLCJmaWxlIjoiMjMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiXCIsXCJmaWxlXCI6XCJjb25zdWx0YW50LnZ1ZVwiLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0xNGY5YTZkZSEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL2NvbnN1bHRhbnQudnVlXG4vLyBtb2R1bGUgaWQgPSAyM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n", "", {"version":3,"sources":[],"names":[],"mappings":"","file":"App.vue","sourceRoot":"webpack://"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvQXBwLnZ1ZT9jZjU5Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7OztBQUdBO0FBQ0EseUdBQTBHLDZGQUE2Rjs7QUFFdk0iLCJmaWxlIjoiMjQuanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiXCIsXCJmaWxlXCI6XCJBcHAudnVlXCIsXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTJhNTU2ZjBjIS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vc3JjL0FwcC52dWVcbi8vIG1vZHVsZSBpZCA9IDI0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=')},function(module,exports,__webpack_require__){eval('exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n", "", {"version":3,"sources":[],"names":[],"mappings":"","file":"collect.vue","sourceRoot":"webpack://"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9jb2xsZWN0LnZ1ZT9hMjUwIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7OztBQUdBO0FBQ0EsNkVBQThFLGlHQUFpRzs7QUFFL0siLCJmaWxlIjoiMjUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiXCIsXCJmaWxlXCI6XCJjb2xsZWN0LnZ1ZVwiLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0yZTk1Njc1NyEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL2NvbGxlY3QudnVlXG4vLyBtb2R1bGUgaWQgPSAyNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n", "", {"version":3,"sources":[],"names":[],"mappings":"","file":"navbar.vue","sourceRoot":"webpack://"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy9uYXZiYXIudnVlPzg5YzYiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTs7O0FBR0E7QUFDQSwrRkFBZ0csZ0dBQWdHOztBQUVoTSIsImZpbGUiOiIyNi5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJcIixcImZpbGVcIjpcIm5hdmJhci52dWVcIixcInNvdXJjZVJvb3RcIjpcIndlYnBhY2s6Ly9cIn1dKTtcblxuLy8gZXhwb3J0c1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtM2ExNmFjM2MhLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9zcmMvY29tcG9uZW50cy9uYXZiYXIudnVlXG4vLyBtb2R1bGUgaWQgPSAyNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, "\\n.a {\\n  display: block;\\n}\\n", "", {"version":3,"sources":["/./src/components/view/school/question.vue"],"names":[],"mappings":";AAAA;EACE,eAAe;CAChB","file":"question.vue","sourcesContent":[".a {\\n  display: block;\\n}\\n"],"sourceRoot":"webpack://"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9xdWVzdGlvbi52dWU/ZmUxNiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOzs7QUFHQTtBQUNBLCtCQUFnQyxtQkFBbUIsR0FBRyxVQUFVLDZGQUE2RixLQUFLLFVBQVUsb0RBQW9ELG1CQUFtQixHQUFHLCtCQUErQjs7QUFFclIiLCJmaWxlIjoiMjcuanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcbi5hIHtcXG4gIGRpc3BsYXk6IGJsb2NrO1xcbn1cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wiLy4vc3JjL2NvbXBvbmVudHMvdmlldy9zY2hvb2wvcXVlc3Rpb24udnVlXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFBQTtFQUNFLGVBQWU7Q0FDaEJcIixcImZpbGVcIjpcInF1ZXN0aW9uLnZ1ZVwiLFwic291cmNlc0NvbnRlbnRcIjpbXCIuYSB7XFxuICBkaXNwbGF5OiBibG9jaztcXG59XFxuXCJdLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0zYjdiYTU4OSEuL34vbGVzcy1sb2FkZXIhLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9xdWVzdGlvbi52dWVcbi8vIG1vZHVsZSBpZCA9IDI3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=')},function(module,exports,__webpack_require__){eval('exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n", "", {"version":3,"sources":[],"names":[],"mappings":"","file":"main.vue","sourceRoot":"webpack://"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9tYWluLnZ1ZT9jMTJlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7OztBQUdBO0FBQ0EsbUZBQW9GLDhGQUE4Rjs7QUFFbEwiLCJmaWxlIjoiMjguanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9saWIvY3NzLWJhc2UuanNcIikoKTtcbi8vIGltcG9ydHNcblxuXG4vLyBtb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIlxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblxcblwiLCBcIlwiLCB7XCJ2ZXJzaW9uXCI6MyxcInNvdXJjZXNcIjpbXSxcIm5hbWVzXCI6W10sXCJtYXBwaW5nc1wiOlwiXCIsXCJmaWxlXCI6XCJtYWluLnZ1ZVwiLFwic291cmNlUm9vdFwiOlwid2VicGFjazovL1wifV0pO1xuXG4vLyBleHBvcnRzXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi01NTVhMGI1YyEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL21haW4udnVlXG4vLyBtb2R1bGUgaWQgPSAyOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n", "", {"version":3,"sources":[],"names":[],"mappings":"","file":"video.vue","sourceRoot":"webpack://"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC92aWRlby52dWU/OTAzOCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOzs7QUFHQTtBQUNBLDZMQUE4TCwrRkFBK0Y7O0FBRTdSIiwiZmlsZSI6IjI5LmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cXG5cIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W10sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIlwiLFwiZmlsZVwiOlwidmlkZW8udnVlXCIsXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTkyMWRhOTMwIS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vc3JjL2NvbXBvbmVudHMvdmlldy9zY2hvb2wvdmlkZW8udnVlXG4vLyBtb2R1bGUgaWQgPSAyOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('exports = module.exports = __webpack_require__(0)();\n// imports\n\n\n// module\nexports.push([module.i, "", "", {"version":3,"sources":[],"names":[],"mappings":"","file":"intro.vue","sourceRoot":"webpack://"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9pbnRyby52dWU/YjcyYSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOzs7QUFHQTtBQUNBLGlDQUFrQywrRkFBK0Y7O0FBRWpJIiwiZmlsZSI6IjMwLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzXCIpKCk7XG4vLyBpbXBvcnRzXG5cblxuLy8gbW9kdWxlXG5leHBvcnRzLnB1c2goW21vZHVsZS5pZCwgXCJcIiwgXCJcIiwge1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W10sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIlwiLFwiZmlsZVwiOlwiaW50cm8udnVlXCIsXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LWM5MWZjNjRlIS4vfi9sZXNzLWxvYWRlciEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL2ludHJvLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMzBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==')},function(module,exports){eval("// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things.  But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals.  It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n    throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n    throw new Error('clearTimeout has not been defined');\n}\n(function () {\n    try {\n        if (typeof setTimeout === 'function') {\n            cachedSetTimeout = setTimeout;\n        } else {\n            cachedSetTimeout = defaultSetTimout;\n        }\n    } catch (e) {\n        cachedSetTimeout = defaultSetTimout;\n    }\n    try {\n        if (typeof clearTimeout === 'function') {\n            cachedClearTimeout = clearTimeout;\n        } else {\n            cachedClearTimeout = defaultClearTimeout;\n        }\n    } catch (e) {\n        cachedClearTimeout = defaultClearTimeout;\n    }\n} ())\nfunction runTimeout(fun) {\n    if (cachedSetTimeout === setTimeout) {\n        //normal enviroments in sane situations\n        return setTimeout(fun, 0);\n    }\n    // if setTimeout wasn't available but was latter defined\n    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n        cachedSetTimeout = setTimeout;\n        return setTimeout(fun, 0);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedSetTimeout(fun, 0);\n    } catch(e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n            return cachedSetTimeout.call(null, fun, 0);\n        } catch(e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n            return cachedSetTimeout.call(this, fun, 0);\n        }\n    }\n\n\n}\nfunction runClearTimeout(marker) {\n    if (cachedClearTimeout === clearTimeout) {\n        //normal enviroments in sane situations\n        return clearTimeout(marker);\n    }\n    // if clearTimeout wasn't available but was latter defined\n    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n        cachedClearTimeout = clearTimeout;\n        return clearTimeout(marker);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedClearTimeout(marker);\n    } catch (e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally\n            return cachedClearTimeout.call(null, marker);\n        } catch (e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n            // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n            return cachedClearTimeout.call(this, marker);\n        }\n    }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    if (!draining || !currentQueue) {\n        return;\n    }\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = runTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        runTimeout(drainQueue);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L3Byb2Nlc3MvYnJvd3Nlci5qcz84MmU0Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsc0JBQXNCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSwyQkFBMkI7QUFDM0I7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLFVBQVUiLCJmaWxlIjoiMzEuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Byb2Nlc3MvYnJvd3Nlci5qc1xuLy8gbW9kdWxlIGlkID0gMzFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==");
},function(module,exports,__webpack_require__){eval('var __vue_exports__, __vue_options__\n\n/* styles */\n__webpack_require__(49)\n\n/* script */\n__vue_exports__ = __webpack_require__(14)\n\n/* template */\nvar __vue_template__ = __webpack_require__(40)\n__vue_options__ = __vue_exports__ = __vue_exports__ || {}\nif (\n  typeof __vue_exports__.default === "object" ||\n  typeof __vue_exports__.default === "function"\n) {\nif (Object.keys(__vue_exports__).some(function (key) { return key !== "default" && key !== "__esModule" })) {console.error("named exports are not supported in *.vue files.")}\n__vue_options__ = __vue_exports__ = __vue_exports__.default\n}\nif (typeof __vue_options__ === "function") {\n  __vue_options__ = __vue_options__.options\n}\n__vue_options__.__file = "/Users/huyirui/Documents/itomix/canada_life_demo/canada-life/src/components/navbar.vue"\n__vue_options__.render = __vue_template__.render\n__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\n/* hot reload */\nif (false) {(function () {\n  var hotAPI = require("vue-hot-reload-api")\n  hotAPI.install(require("vue"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord("data-v-3a16ac3c", __vue_options__)\n  } else {\n    hotAPI.reload("data-v-3a16ac3c", __vue_options__)\n  }\n})()}\nif (__vue_options__.functional) {console.error("[vue-loader] navbar.vue: functional components are not supported and should be defined in plain js files using render functions.")}\n\nmodule.exports = __vue_exports__\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy9uYXZiYXIudnVlPzc4MGUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0RBQXNELG1EQUFtRCxJQUFJO0FBQzdHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxZQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLENBQUM7QUFDRCxpQ0FBaUM7O0FBRWpDIiwiZmlsZSI6IjMyLmpzIiwic291cmNlc0NvbnRlbnQiOlsidmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cbi8qIHN0eWxlcyAqL1xucmVxdWlyZShcIiEhdnVlLXN0eWxlLWxvYWRlciFjc3MtbG9hZGVyP3NvdXJjZU1hcCF2dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlcj9pZD1kYXRhLXYtM2ExNmFjM2MhdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL25hdmJhci52dWVcIilcblxuLyogc2NyaXB0ICovXG5fX3Z1ZV9leHBvcnRzX18gPSByZXF1aXJlKFwiISFiYWJlbC1sb2FkZXIhdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zY3JpcHQmaW5kZXg9MCEuL25hdmJhci52dWVcIilcblxuLyogdGVtcGxhdGUgKi9cbnZhciBfX3Z1ZV90ZW1wbGF0ZV9fID0gcmVxdWlyZShcIiEhdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXI/aWQ9ZGF0YS12LTNhMTZhYzNjIXZ1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL25hdmJhci52dWVcIilcbl9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXyB8fCB7fVxuaWYgKFxuICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcbiAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcImZ1bmN0aW9uXCJcbikge1xuaWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5fX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdFxufVxuaWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuICBfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9vcHRpb25zX18ub3B0aW9uc1xufVxuX192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiL1VzZXJzL2h1eWlydWkvRG9jdW1lbnRzL2l0b21peC9jYW5hZGFfbGlmZV9kZW1vL2NhbmFkYS1saWZlL3NyYy9jb21wb25lbnRzL25hdmJhci52dWVcIlxuX192dWVfb3B0aW9uc19fLnJlbmRlciA9IF9fdnVlX3RlbXBsYXRlX18ucmVuZGVyXG5fX3Z1ZV9vcHRpb25zX18uc3RhdGljUmVuZGVyRm5zID0gX192dWVfdGVtcGxhdGVfXy5zdGF0aWNSZW5kZXJGbnNcblxuLyogaG90IHJlbG9hZCAqL1xuaWYgKG1vZHVsZS5ob3QpIHsoZnVuY3Rpb24gKCkge1xuICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcbiAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG4gIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcbiAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LTNhMTZhYzNjXCIsIF9fdnVlX29wdGlvbnNfXylcbiAgfSBlbHNlIHtcbiAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTNhMTZhYzNjXCIsIF9fdnVlX29wdGlvbnNfXylcbiAgfVxufSkoKX1cbmlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gbmF2YmFyLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblxubW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2NvbXBvbmVudHMvbmF2YmFyLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMzJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==')},function(module,exports,__webpack_require__){eval('var __vue_exports__, __vue_options__\n\n/* styles */\n__webpack_require__(48)\n\n/* script */\n__vue_exports__ = __webpack_require__(15)\n\n/* template */\nvar __vue_template__ = __webpack_require__(39)\n__vue_options__ = __vue_exports__ = __vue_exports__ || {}\nif (\n  typeof __vue_exports__.default === "object" ||\n  typeof __vue_exports__.default === "function"\n) {\nif (Object.keys(__vue_exports__).some(function (key) { return key !== "default" && key !== "__esModule" })) {console.error("named exports are not supported in *.vue files.")}\n__vue_options__ = __vue_exports__ = __vue_exports__.default\n}\nif (typeof __vue_options__ === "function") {\n  __vue_options__ = __vue_options__.options\n}\n__vue_options__.__file = "/Users/huyirui/Documents/itomix/canada_life_demo/canada-life/src/components/view/school/collect.vue"\n__vue_options__.render = __vue_template__.render\n__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\n/* hot reload */\nif (false) {(function () {\n  var hotAPI = require("vue-hot-reload-api")\n  hotAPI.install(require("vue"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord("data-v-2e956757", __vue_options__)\n  } else {\n    hotAPI.reload("data-v-2e956757", __vue_options__)\n  }\n})()}\nif (__vue_options__.functional) {console.error("[vue-loader] collect.vue: functional components are not supported and should be defined in plain js files using render functions.")}\n\nmodule.exports = __vue_exports__\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9jb2xsZWN0LnZ1ZT82ZTY2Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxtREFBbUQsSUFBSTtBQUM3RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsWUFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxDQUFDO0FBQ0QsaUNBQWlDOztBQUVqQyIsImZpbGUiOiIzMy5qcyIsInNvdXJjZXNDb250ZW50IjpbInZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXG4vKiBzdHlsZXMgKi9cbnJlcXVpcmUoXCIhIXZ1ZS1zdHlsZS1sb2FkZXIhY3NzLWxvYWRlcj9zb3VyY2VNYXAhdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXI/aWQ9ZGF0YS12LTJlOTU2NzU3IXZ1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9jb2xsZWN0LnZ1ZVwiKVxuXG4vKiBzY3JpcHQgKi9cbl9fdnVlX2V4cG9ydHNfXyA9IHJlcXVpcmUoXCIhIWJhYmVsLWxvYWRlciF2dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXNjcmlwdCZpbmRleD0wIS4vY29sbGVjdC52dWVcIilcblxuLyogdGVtcGxhdGUgKi9cbnZhciBfX3Z1ZV90ZW1wbGF0ZV9fID0gcmVxdWlyZShcIiEhdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXI/aWQ9ZGF0YS12LTJlOTU2NzU3IXZ1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL2NvbGxlY3QudnVlXCIpXG5fX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cbmlmIChcbiAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcIm9iamVjdFwiIHx8XG4gIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG4pIHtcbmlmIChPYmplY3Qua2V5cyhfX3Z1ZV9leHBvcnRzX18pLnNvbWUoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkgIT09IFwiX19lc01vZHVsZVwiIH0pKSB7Y29uc29sZS5lcnJvcihcIm5hbWVkIGV4cG9ydHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gKi52dWUgZmlsZXMuXCIpfVxuX192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcbn1cbmlmICh0eXBlb2YgX192dWVfb3B0aW9uc19fID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcbn1cbl9fdnVlX29wdGlvbnNfXy5fX2ZpbGUgPSBcIi9Vc2Vycy9odXlpcnVpL0RvY3VtZW50cy9pdG9taXgvY2FuYWRhX2xpZmVfZGVtby9jYW5hZGEtbGlmZS9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9jb2xsZWN0LnZ1ZVwiXG5fX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcbl9fdnVlX29wdGlvbnNfXy5zdGF0aWNSZW5kZXJGbnMgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnN0YXRpY1JlbmRlckZuc1xuXG4vKiBob3QgcmVsb2FkICovXG5pZiAobW9kdWxlLmhvdCkgeyhmdW5jdGlvbiAoKSB7XG4gIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG4gIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtMmU5NTY3NTdcIiwgX192dWVfb3B0aW9uc19fKVxuICB9IGVsc2Uge1xuICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtMmU5NTY3NTdcIiwgX192dWVfb3B0aW9uc19fKVxuICB9XG59KSgpfVxuaWYgKF9fdnVlX29wdGlvbnNfXy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBjb2xsZWN0LnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblxubW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2NvbXBvbmVudHMvdmlldy9zY2hvb2wvY29sbGVjdC52dWVcbi8vIG1vZHVsZSBpZCA9IDMzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=')},function(module,exports,__webpack_require__){eval('var __vue_exports__, __vue_options__\n\n/* styles */\n__webpack_require__(45)\n\n/* script */\n__vue_exports__ = __webpack_require__(17)\n\n/* template */\nvar __vue_template__ = __webpack_require__(36)\n__vue_options__ = __vue_exports__ = __vue_exports__ || {}\nif (\n  typeof __vue_exports__.default === "object" ||\n  typeof __vue_exports__.default === "function"\n) {\nif (Object.keys(__vue_exports__).some(function (key) { return key !== "default" && key !== "__esModule" })) {console.error("named exports are not supported in *.vue files.")}\n__vue_options__ = __vue_exports__ = __vue_exports__.default\n}\nif (typeof __vue_options__ === "function") {\n  __vue_options__ = __vue_options__.options\n}\n__vue_options__.__file = "/Users/huyirui/Documents/itomix/canada_life_demo/canada-life/src/components/view/school/header.vue"\n__vue_options__.render = __vue_template__.render\n__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\n/* hot reload */\nif (false) {(function () {\n  var hotAPI = require("vue-hot-reload-api")\n  hotAPI.install(require("vue"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord("data-v-0021a770", __vue_options__)\n  } else {\n    hotAPI.reload("data-v-0021a770", __vue_options__)\n  }\n})()}\nif (__vue_options__.functional) {console.error("[vue-loader] header.vue: functional components are not supported and should be defined in plain js files using render functions.")}\n\nmodule.exports = __vue_exports__\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9oZWFkZXIudnVlPzZkZWQiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0RBQXNELG1EQUFtRCxJQUFJO0FBQzdHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxZQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLENBQUM7QUFDRCxpQ0FBaUM7O0FBRWpDIiwiZmlsZSI6IjM0LmpzIiwic291cmNlc0NvbnRlbnQiOlsidmFyIF9fdnVlX2V4cG9ydHNfXywgX192dWVfb3B0aW9uc19fXG5cbi8qIHN0eWxlcyAqL1xucmVxdWlyZShcIiEhdnVlLXN0eWxlLWxvYWRlciFjc3MtbG9hZGVyP3NvdXJjZU1hcCF2dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlcj9pZD1kYXRhLXYtMDAyMWE3NzAhdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL2hlYWRlci52dWVcIilcblxuLyogc2NyaXB0ICovXG5fX3Z1ZV9leHBvcnRzX18gPSByZXF1aXJlKFwiISFiYWJlbC1sb2FkZXIhdnVlLWxvYWRlci9saWIvc2VsZWN0b3I/dHlwZT1zY3JpcHQmaW5kZXg9MCEuL2hlYWRlci52dWVcIilcblxuLyogdGVtcGxhdGUgKi9cbnZhciBfX3Z1ZV90ZW1wbGF0ZV9fID0gcmVxdWlyZShcIiEhdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXI/aWQ9ZGF0YS12LTAwMjFhNzcwIXZ1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL2hlYWRlci52dWVcIilcbl9fdnVlX29wdGlvbnNfXyA9IF9fdnVlX2V4cG9ydHNfXyA9IF9fdnVlX2V4cG9ydHNfXyB8fCB7fVxuaWYgKFxuICB0eXBlb2YgX192dWVfZXhwb3J0c19fLmRlZmF1bHQgPT09IFwib2JqZWN0XCIgfHxcbiAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcImZ1bmN0aW9uXCJcbikge1xuaWYgKE9iamVjdC5rZXlzKF9fdnVlX2V4cG9ydHNfXykuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBrZXkgIT09IFwiZGVmYXVsdFwiICYmIGtleSAhPT0gXCJfX2VzTW9kdWxlXCIgfSkpIHtjb25zb2xlLmVycm9yKFwibmFtZWQgZXhwb3J0cyBhcmUgbm90IHN1cHBvcnRlZCBpbiAqLnZ1ZSBmaWxlcy5cIil9XG5fX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdFxufVxuaWYgKHR5cGVvZiBfX3Z1ZV9vcHRpb25zX18gPT09IFwiZnVuY3Rpb25cIikge1xuICBfX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9vcHRpb25zX18ub3B0aW9uc1xufVxuX192dWVfb3B0aW9uc19fLl9fZmlsZSA9IFwiL1VzZXJzL2h1eWlydWkvRG9jdW1lbnRzL2l0b21peC9jYW5hZGFfbGlmZV9kZW1vL2NhbmFkYS1saWZlL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL2hlYWRlci52dWVcIlxuX192dWVfb3B0aW9uc19fLnJlbmRlciA9IF9fdnVlX3RlbXBsYXRlX18ucmVuZGVyXG5fX3Z1ZV9vcHRpb25zX18uc3RhdGljUmVuZGVyRm5zID0gX192dWVfdGVtcGxhdGVfXy5zdGF0aWNSZW5kZXJGbnNcblxuLyogaG90IHJlbG9hZCAqL1xuaWYgKG1vZHVsZS5ob3QpIHsoZnVuY3Rpb24gKCkge1xuICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCBmYWxzZSlcbiAgaWYgKCFob3RBUEkuY29tcGF0aWJsZSkgcmV0dXJuXG4gIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgaWYgKCFtb2R1bGUuaG90LmRhdGEpIHtcbiAgICBob3RBUEkuY3JlYXRlUmVjb3JkKFwiZGF0YS12LTAwMjFhNzcwXCIsIF9fdnVlX29wdGlvbnNfXylcbiAgfSBlbHNlIHtcbiAgICBob3RBUEkucmVsb2FkKFwiZGF0YS12LTAwMjFhNzcwXCIsIF9fdnVlX29wdGlvbnNfXylcbiAgfVxufSkoKX1cbmlmIChfX3Z1ZV9vcHRpb25zX18uZnVuY3Rpb25hbCkge2NvbnNvbGUuZXJyb3IoXCJbdnVlLWxvYWRlcl0gaGVhZGVyLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblxubW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2NvbXBvbmVudHMvdmlldy9zY2hvb2wvaGVhZGVyLnZ1ZVxuLy8gbW9kdWxlIGlkID0gMzRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==')},function(module,exports,__webpack_require__){eval('var __vue_exports__, __vue_options__\n\n/* styles */\n__webpack_require__(51)\n\n/* script */\n__vue_exports__ = __webpack_require__(19)\n\n/* template */\nvar __vue_template__ = __webpack_require__(42)\n__vue_options__ = __vue_exports__ = __vue_exports__ || {}\nif (\n  typeof __vue_exports__.default === "object" ||\n  typeof __vue_exports__.default === "function"\n) {\nif (Object.keys(__vue_exports__).some(function (key) { return key !== "default" && key !== "__esModule" })) {console.error("named exports are not supported in *.vue files.")}\n__vue_options__ = __vue_exports__ = __vue_exports__.default\n}\nif (typeof __vue_options__ === "function") {\n  __vue_options__ = __vue_options__.options\n}\n__vue_options__.__file = "/Users/huyirui/Documents/itomix/canada_life_demo/canada-life/src/components/view/school/main.vue"\n__vue_options__.render = __vue_template__.render\n__vue_options__.staticRenderFns = __vue_template__.staticRenderFns\n\n/* hot reload */\nif (false) {(function () {\n  var hotAPI = require("vue-hot-reload-api")\n  hotAPI.install(require("vue"), false)\n  if (!hotAPI.compatible) return\n  module.hot.accept()\n  if (!module.hot.data) {\n    hotAPI.createRecord("data-v-555a0b5c", __vue_options__)\n  } else {\n    hotAPI.reload("data-v-555a0b5c", __vue_options__)\n  }\n})()}\nif (__vue_options__.functional) {console.error("[vue-loader] main.vue: functional components are not supported and should be defined in plain js files using render functions.")}\n\nmodule.exports = __vue_exports__\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9tYWluLnZ1ZT9lZjg3Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxtREFBbUQsSUFBSTtBQUM3RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsWUFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxDQUFDO0FBQ0QsaUNBQWlDOztBQUVqQyIsImZpbGUiOiIzNS5qcyIsInNvdXJjZXNDb250ZW50IjpbInZhciBfX3Z1ZV9leHBvcnRzX18sIF9fdnVlX29wdGlvbnNfX1xuXG4vKiBzdHlsZXMgKi9cbnJlcXVpcmUoXCIhIXZ1ZS1zdHlsZS1sb2FkZXIhY3NzLWxvYWRlcj9zb3VyY2VNYXAhdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXI/aWQ9ZGF0YS12LTU1NWEwYjVjIXZ1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9tYWluLnZ1ZVwiKVxuXG4vKiBzY3JpcHQgKi9cbl9fdnVlX2V4cG9ydHNfXyA9IHJlcXVpcmUoXCIhIWJhYmVsLWxvYWRlciF2dWUtbG9hZGVyL2xpYi9zZWxlY3Rvcj90eXBlPXNjcmlwdCZpbmRleD0wIS4vbWFpbi52dWVcIilcblxuLyogdGVtcGxhdGUgKi9cbnZhciBfX3Z1ZV90ZW1wbGF0ZV9fID0gcmVxdWlyZShcIiEhdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXI/aWQ9ZGF0YS12LTU1NWEwYjVjIXZ1ZS1sb2FkZXIvbGliL3NlbGVjdG9yP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL21haW4udnVlXCIpXG5fX3Z1ZV9vcHRpb25zX18gPSBfX3Z1ZV9leHBvcnRzX18gPSBfX3Z1ZV9leHBvcnRzX18gfHwge31cbmlmIChcbiAgdHlwZW9mIF9fdnVlX2V4cG9ydHNfXy5kZWZhdWx0ID09PSBcIm9iamVjdFwiIHx8XG4gIHR5cGVvZiBfX3Z1ZV9leHBvcnRzX18uZGVmYXVsdCA9PT0gXCJmdW5jdGlvblwiXG4pIHtcbmlmIChPYmplY3Qua2V5cyhfX3Z1ZV9leHBvcnRzX18pLnNvbWUoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4ga2V5ICE9PSBcImRlZmF1bHRcIiAmJiBrZXkgIT09IFwiX19lc01vZHVsZVwiIH0pKSB7Y29uc29sZS5lcnJvcihcIm5hbWVkIGV4cG9ydHMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gKi52dWUgZmlsZXMuXCIpfVxuX192dWVfb3B0aW9uc19fID0gX192dWVfZXhwb3J0c19fID0gX192dWVfZXhwb3J0c19fLmRlZmF1bHRcbn1cbmlmICh0eXBlb2YgX192dWVfb3B0aW9uc19fID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgX192dWVfb3B0aW9uc19fID0gX192dWVfb3B0aW9uc19fLm9wdGlvbnNcbn1cbl9fdnVlX29wdGlvbnNfXy5fX2ZpbGUgPSBcIi9Vc2Vycy9odXlpcnVpL0RvY3VtZW50cy9pdG9taXgvY2FuYWRhX2xpZmVfZGVtby9jYW5hZGEtbGlmZS9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9tYWluLnZ1ZVwiXG5fX3Z1ZV9vcHRpb25zX18ucmVuZGVyID0gX192dWVfdGVtcGxhdGVfXy5yZW5kZXJcbl9fdnVlX29wdGlvbnNfXy5zdGF0aWNSZW5kZXJGbnMgPSBfX3Z1ZV90ZW1wbGF0ZV9fLnN0YXRpY1JlbmRlckZuc1xuXG4vKiBob3QgcmVsb2FkICovXG5pZiAobW9kdWxlLmhvdCkgeyhmdW5jdGlvbiAoKSB7XG4gIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG4gIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIGZhbHNlKVxuICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoXCJkYXRhLXYtNTU1YTBiNWNcIiwgX192dWVfb3B0aW9uc19fKVxuICB9IGVsc2Uge1xuICAgIGhvdEFQSS5yZWxvYWQoXCJkYXRhLXYtNTU1YTBiNWNcIiwgX192dWVfb3B0aW9uc19fKVxuICB9XG59KSgpfVxuaWYgKF9fdnVlX29wdGlvbnNfXy5mdW5jdGlvbmFsKSB7Y29uc29sZS5lcnJvcihcIlt2dWUtbG9hZGVyXSBtYWluLnZ1ZTogZnVuY3Rpb25hbCBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGFuZCBzaG91bGQgYmUgZGVmaW5lZCBpbiBwbGFpbiBqcyBmaWxlcyB1c2luZyByZW5kZXIgZnVuY3Rpb25zLlwiKX1cblxubW9kdWxlLmV4cG9ydHMgPSBfX3Z1ZV9leHBvcnRzX19cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2NvbXBvbmVudHMvdmlldy9zY2hvb2wvbWFpbi52dWVcbi8vIG1vZHVsZSBpZCA9IDM1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=')},function(module,exports,__webpack_require__){eval('module.exports={render:function (){with(this) {\n  return _h(\'div\', {\n    attrs: {\n      "id": "infoHeader"\n    }\n  }, [_h(\'div\', {\n    staticClass: "header-wrapper blur",\n    style: (src)\n  }), " ", _m(0), " ", _h(\'div\', {\n    staticClass: "school_badge"\n  }, [_h(\'img\', {\n    attrs: {\n      "src": iSrc\n    }\n  })]), " ", _h(\'div\', {\n    staticClass: "school_info"\n  }, [_h(\'span\', {\n    staticClass: "text"\n  }, [_s(name)]), " ", _h(\'collect\'), " ", _h(\'div\', {\n    staticClass: "intro omit omit2"\n  }, [_s(intro)])])])\n}},staticRenderFns: [function (){with(this) {\n  return _h(\'div\', {\n    staticClass: "go-back"\n  }, [_h(\'span\', {\n    staticClass: "icon icon-left"\n  })])\n}}]}\nif (false) {\n  module.hot.accept()\n  if (module.hot.data) {\n     require("vue-hot-reload-api").rerender("data-v-0021a770", module.exports)\n  }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9oZWFkZXIudnVlPzVkNWMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsZ0JBQWdCLG1CQUFtQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSCxFQUFFLCtCQUErQjtBQUNqQztBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNILEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMzYuanMiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3dpdGgodGhpcykge1xuICByZXR1cm4gX2goJ2RpdicsIHtcbiAgICBhdHRyczoge1xuICAgICAgXCJpZFwiOiBcImluZm9IZWFkZXJcIlxuICAgIH1cbiAgfSwgW19oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiaGVhZGVyLXdyYXBwZXIgYmx1clwiLFxuICAgIHN0eWxlOiAoc3JjKVxuICB9KSwgXCIgXCIsIF9tKDApLCBcIiBcIiwgX2goJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJzY2hvb2xfYmFkZ2VcIlxuICB9LCBbX2goJ2ltZycsIHtcbiAgICBhdHRyczoge1xuICAgICAgXCJzcmNcIjogaVNyY1xuICAgIH1cbiAgfSldKSwgXCIgXCIsIF9oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwic2Nob29sX2luZm9cIlxuICB9LCBbX2goJ3NwYW4nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwidGV4dFwiXG4gIH0sIFtfcyhuYW1lKV0pLCBcIiBcIiwgX2goJ2NvbGxlY3QnKSwgXCIgXCIsIF9oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiaW50cm8gb21pdCBvbWl0MlwiXG4gIH0sIFtfcyhpbnRybyldKV0pXSlcbn19LHN0YXRpY1JlbmRlckZuczogW2Z1bmN0aW9uICgpe3dpdGgodGhpcykge1xuICByZXR1cm4gX2goJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJnby1iYWNrXCJcbiAgfSwgW19oKCdzcGFuJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImljb24gaWNvbi1sZWZ0XCJcbiAgfSldKVxufX1dfVxuaWYgKG1vZHVsZS5ob3QpIHtcbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtMDAyMWE3NzBcIiwgbW9kdWxlLmV4cG9ydHMpXG4gIH1cbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXIuanM/aWQ9ZGF0YS12LTAwMjFhNzcwIS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXRlbXBsYXRlJmluZGV4PTAhLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9oZWFkZXIudnVlXG4vLyBtb2R1bGUgaWQgPSAzNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('module.exports={render:function (){with(this) {\n  return _h(\'div\', {\n    staticClass: "list-block media-list"\n  }, [_h(\'ul\', [_l((infos), function(info) {\n    return _h(\'li\', [_h(\'div\', {\n      staticClass: "item-content"\n    }, [_h(\'div\', {\n      staticClass: "item-media"\n    }, [_h(\'img\', {\n      style: (info.style),\n      attrs: {\n        "src": info.src\n      }\n    })]), " ", _h(\'div\', {\n      staticClass: "item-inner"\n    }, [_h(\'div\', {\n      staticClass: "item-title-row"\n    }, [_h(\'div\', {\n      staticClass: "item-title"\n    }, [_h(\'span\', [_s(info.name)]), " ", _m(0, true), " ", _m(1, true), " ", _m(2, true), " ", _m(3, true)])]), " ", _h(\'div\', {\n      staticClass: "item-subtitle"\n    }, [_h(\'span\', [_s(info.rank)]), " ", _h(\'span\', [_s(info.experience)])])])])])\n  })])])\n}},staticRenderFns: [function (){with(this) {\n  return _h(\'i\', {\n    staticClass: "sex"\n  }, [_h(\'span\', {\n    staticClass: "icon icon-download"\n  })])\n}},function (){with(this) {\n  return _h(\'i\', {\n    attrs: {\n      "style": "color: orange"\n    }\n  }, [_h(\'span\', {\n    staticClass: "icon icon-star"\n  })])\n}},function (){with(this) {\n  return _h(\'i\', {\n    attrs: {\n      "style": "color: orange"\n    }\n  }, [_h(\'span\', {\n    staticClass: "icon icon-star"\n  })])\n}},function (){with(this) {\n  return _h(\'i\', [_h(\'span\', {\n    staticClass: "icon icon-star"\n  })])\n}}]}\nif (false) {\n  module.hot.accept()\n  if (module.hot.data) {\n     require("vue-hot-reload-api").rerender("data-v-14f9a6de", module.exports)\n  }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9jb25zdWx0YW50LnZ1ZT9mZjllIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGdCQUFnQixtQkFBbUI7QUFDbkM7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSCxFQUFFLCtCQUErQjtBQUNqQztBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNILEVBQUUsYUFBYTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNILEVBQUUsYUFBYTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNILEVBQUUsYUFBYTtBQUNmO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiIzNy5qcyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzPXtyZW5kZXI6ZnVuY3Rpb24gKCl7d2l0aCh0aGlzKSB7XG4gIHJldHVybiBfaCgnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcImxpc3QtYmxvY2sgbWVkaWEtbGlzdFwiXG4gIH0sIFtfaCgndWwnLCBbX2woKGluZm9zKSwgZnVuY3Rpb24oaW5mbykge1xuICAgIHJldHVybiBfaCgnbGknLCBbX2goJ2RpdicsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcIml0ZW0tY29udGVudFwiXG4gICAgfSwgW19oKCdkaXYnLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJpdGVtLW1lZGlhXCJcbiAgICB9LCBbX2goJ2ltZycsIHtcbiAgICAgIHN0eWxlOiAoaW5mby5zdHlsZSksXG4gICAgICBhdHRyczoge1xuICAgICAgICBcInNyY1wiOiBpbmZvLnNyY1xuICAgICAgfVxuICAgIH0pXSksIFwiIFwiLCBfaCgnZGl2Jywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwiaXRlbS1pbm5lclwiXG4gICAgfSwgW19oKCdkaXYnLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJpdGVtLXRpdGxlLXJvd1wiXG4gICAgfSwgW19oKCdkaXYnLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJpdGVtLXRpdGxlXCJcbiAgICB9LCBbX2goJ3NwYW4nLCBbX3MoaW5mby5uYW1lKV0pLCBcIiBcIiwgX20oMCwgdHJ1ZSksIFwiIFwiLCBfbSgxLCB0cnVlKSwgXCIgXCIsIF9tKDIsIHRydWUpLCBcIiBcIiwgX20oMywgdHJ1ZSldKV0pLCBcIiBcIiwgX2goJ2RpdicsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcIml0ZW0tc3VidGl0bGVcIlxuICAgIH0sIFtfaCgnc3BhbicsIFtfcyhpbmZvLnJhbmspXSksIFwiIFwiLCBfaCgnc3BhbicsIFtfcyhpbmZvLmV4cGVyaWVuY2UpXSldKV0pXSldKVxuICB9KV0pXSlcbn19LHN0YXRpY1JlbmRlckZuczogW2Z1bmN0aW9uICgpe3dpdGgodGhpcykge1xuICByZXR1cm4gX2goJ2knLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwic2V4XCJcbiAgfSwgW19oKCdzcGFuJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImljb24gaWNvbi1kb3dubG9hZFwiXG4gIH0pXSlcbn19LGZ1bmN0aW9uICgpe3dpdGgodGhpcykge1xuICByZXR1cm4gX2goJ2knLCB7XG4gICAgYXR0cnM6IHtcbiAgICAgIFwic3R5bGVcIjogXCJjb2xvcjogb3JhbmdlXCJcbiAgICB9XG4gIH0sIFtfaCgnc3BhbicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJpY29uIGljb24tc3RhclwiXG4gIH0pXSlcbn19LGZ1bmN0aW9uICgpe3dpdGgodGhpcykge1xuICByZXR1cm4gX2goJ2knLCB7XG4gICAgYXR0cnM6IHtcbiAgICAgIFwic3R5bGVcIjogXCJjb2xvcjogb3JhbmdlXCJcbiAgICB9XG4gIH0sIFtfaCgnc3BhbicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJpY29uIGljb24tc3RhclwiXG4gIH0pXSlcbn19LGZ1bmN0aW9uICgpe3dpdGgodGhpcykge1xuICByZXR1cm4gX2goJ2knLCBbX2goJ3NwYW4nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiaWNvbiBpY29uLXN0YXJcIlxuICB9KV0pXG59fV19XG5pZiAobW9kdWxlLmhvdCkge1xuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcbiAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi0xNGY5YTZkZVwiLCBtb2R1bGUuZXhwb3J0cylcbiAgfVxufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlci5qcz9pZD1kYXRhLXYtMTRmOWE2ZGUhLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL2NvbnN1bHRhbnQudnVlXG4vLyBtb2R1bGUgaWQgPSAzN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('module.exports={render:function (){with(this) {\n  return _h(\'div\', {\n    staticClass: "page-group",\n    attrs: {\n      "id": "app"\n    }\n  }, [_h(\'div\', {\n    staticClass: "page"\n  }, [_h(\'school\'), " ", _h(\'navbar\')])])\n}},staticRenderFns: []}\nif (false) {\n  module.hot.accept()\n  if (module.hot.data) {\n     require("vue-hot-reload-api").rerender("data-v-2a556f0c", module.exports)\n  }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvQXBwLnZ1ZT9iNTZiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGdCQUFnQixtQkFBbUI7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjM4LmpzIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt3aXRoKHRoaXMpIHtcbiAgcmV0dXJuIF9oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwicGFnZS1ncm91cFwiLFxuICAgIGF0dHJzOiB7XG4gICAgICBcImlkXCI6IFwiYXBwXCJcbiAgICB9XG4gIH0sIFtfaCgnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcInBhZ2VcIlxuICB9LCBbX2goJ3NjaG9vbCcpLCBcIiBcIiwgX2goJ25hdmJhcicpXSldKVxufX0sc3RhdGljUmVuZGVyRm5zOiBbXX1cbmlmIChtb2R1bGUuaG90KSB7XG4gIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuICAgICByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpLnJlcmVuZGVyKFwiZGF0YS12LTJhNTU2ZjBjXCIsIG1vZHVsZS5leHBvcnRzKVxuICB9XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Z1ZS1sb2FkZXIvbGliL3RlbXBsYXRlLWNvbXBpbGVyLmpzP2lkPWRhdGEtdi0yYTU1NmYwYyEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT10ZW1wbGF0ZSZpbmRleD0wIS4vc3JjL0FwcC52dWVcbi8vIG1vZHVsZSBpZCA9IDM4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=')},function(module,exports,__webpack_require__){eval('module.exports={render:function (){with(this) {\n  return _h(\'span\', {\n    staticClass: "collect"\n  }, [_m(0), " ", _h(\'span\', {\n    staticClass: "text"\n  }, [_s(text)])])\n}},staticRenderFns: [function (){with(this) {\n  return _h(\'span\', {\n    staticClass: "icon icon-star",\n    attrs: {\n      "style": "margin-bottom: .1rem;"\n    }\n  })\n}}]}\nif (false) {\n  module.hot.accept()\n  if (module.hot.data) {\n     require("vue-hot-reload-api").rerender("data-v-2e956757", module.exports)\n  }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9jb2xsZWN0LnZ1ZT8zYjc2Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGdCQUFnQixtQkFBbUI7QUFDbkM7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSCxFQUFFLCtCQUErQjtBQUNqQztBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckM7QUFDQSxHQUFHO0FBQ0gsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiIzOS5qcyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzPXtyZW5kZXI6ZnVuY3Rpb24gKCl7d2l0aCh0aGlzKSB7XG4gIHJldHVybiBfaCgnc3BhbicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJjb2xsZWN0XCJcbiAgfSwgW19tKDApLCBcIiBcIiwgX2goJ3NwYW4nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwidGV4dFwiXG4gIH0sIFtfcyh0ZXh0KV0pXSlcbn19LHN0YXRpY1JlbmRlckZuczogW2Z1bmN0aW9uICgpe3dpdGgodGhpcykge1xuICByZXR1cm4gX2goJ3NwYW4nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiaWNvbiBpY29uLXN0YXJcIixcbiAgICBhdHRyczoge1xuICAgICAgXCJzdHlsZVwiOiBcIm1hcmdpbi1ib3R0b206IC4xcmVtO1wiXG4gICAgfVxuICB9KVxufX1dfVxuaWYgKG1vZHVsZS5ob3QpIHtcbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtMmU5NTY3NTdcIiwgbW9kdWxlLmV4cG9ydHMpXG4gIH1cbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXIuanM/aWQ9ZGF0YS12LTJlOTU2NzU3IS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXRlbXBsYXRlJmluZGV4PTAhLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9jb2xsZWN0LnZ1ZVxuLy8gbW9kdWxlIGlkID0gMzlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==')},function(module,exports,__webpack_require__){eval('module.exports={render:function (){with(this) {\n  return _h(\'nav\', {\n    staticClass: "bar bar-tab"\n  }, [_h(\'router-link\', {\n    staticClass: "tab-item external",\n    class: {\n      active: path === \'/schoolIntro\' || path === \'/\'\n    },\n    attrs: {\n      "to": "/schoolIntro"\n    }\n  }, [" 资料"]), " ", _h(\'router-link\', {\n    staticClass: "tab-item external",\n    class: {\n      active: path === \'/schoolIntroConsultant\'\n    },\n    attrs: {\n      "to": "/schoolIntroConsultant"\n    }\n  }, ["顾问"]), " ", _h(\'router-link\', {\n    staticClass: "tab-item external",\n    class: {\n      active: path === \'/schoolIntroVideo\'\n    },\n    attrs: {\n      "to": "/schoolIntroVideo"\n    }\n  }, ["视频"]), " ", _h(\'router-link\', {\n    staticClass: "tab-item external",\n    class: {\n      active: path === \'/schoolIntroQuestion\'\n    },\n    attrs: {\n      "to": "/schoolIntroQuestion"\n    }\n  }, ["问题"])])\n}},staticRenderFns: []}\nif (false) {\n  module.hot.accept()\n  if (module.hot.data) {\n     require("vue-hot-reload-api").rerender("data-v-3a16ac3c", module.exports)\n  }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy9uYXZiYXIudnVlP2RjYWEiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsZ0JBQWdCLG1CQUFtQjtBQUNuQztBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiI0MC5qcyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzPXtyZW5kZXI6ZnVuY3Rpb24gKCl7d2l0aCh0aGlzKSB7XG4gIHJldHVybiBfaCgnbmF2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcImJhciBiYXItdGFiXCJcbiAgfSwgW19oKCdyb3V0ZXItbGluaycsIHtcbiAgICBzdGF0aWNDbGFzczogXCJ0YWItaXRlbSBleHRlcm5hbFwiLFxuICAgIGNsYXNzOiB7XG4gICAgICBhY3RpdmU6IHBhdGggPT09ICcvc2Nob29sSW50cm8nIHx8IHBhdGggPT09ICcvJ1xuICAgIH0sXG4gICAgYXR0cnM6IHtcbiAgICAgIFwidG9cIjogXCIvc2Nob29sSW50cm9cIlxuICAgIH1cbiAgfSwgW1wiIOi1hOaWmVwiXSksIFwiIFwiLCBfaCgncm91dGVyLWxpbmsnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwidGFiLWl0ZW0gZXh0ZXJuYWxcIixcbiAgICBjbGFzczoge1xuICAgICAgYWN0aXZlOiBwYXRoID09PSAnL3NjaG9vbEludHJvQ29uc3VsdGFudCdcbiAgICB9LFxuICAgIGF0dHJzOiB7XG4gICAgICBcInRvXCI6IFwiL3NjaG9vbEludHJvQ29uc3VsdGFudFwiXG4gICAgfVxuICB9LCBbXCLpob7pl65cIl0pLCBcIiBcIiwgX2goJ3JvdXRlci1saW5rJywge1xuICAgIHN0YXRpY0NsYXNzOiBcInRhYi1pdGVtIGV4dGVybmFsXCIsXG4gICAgY2xhc3M6IHtcbiAgICAgIGFjdGl2ZTogcGF0aCA9PT0gJy9zY2hvb2xJbnRyb1ZpZGVvJ1xuICAgIH0sXG4gICAgYXR0cnM6IHtcbiAgICAgIFwidG9cIjogXCIvc2Nob29sSW50cm9WaWRlb1wiXG4gICAgfVxuICB9LCBbXCLop4bpopFcIl0pLCBcIiBcIiwgX2goJ3JvdXRlci1saW5rJywge1xuICAgIHN0YXRpY0NsYXNzOiBcInRhYi1pdGVtIGV4dGVybmFsXCIsXG4gICAgY2xhc3M6IHtcbiAgICAgIGFjdGl2ZTogcGF0aCA9PT0gJy9zY2hvb2xJbnRyb1F1ZXN0aW9uJ1xuICAgIH0sXG4gICAgYXR0cnM6IHtcbiAgICAgIFwidG9cIjogXCIvc2Nob29sSW50cm9RdWVzdGlvblwiXG4gICAgfVxuICB9LCBbXCLpl67pophcIl0pXSlcbn19LHN0YXRpY1JlbmRlckZuczogW119XG5pZiAobW9kdWxlLmhvdCkge1xuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcbiAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi0zYTE2YWMzY1wiLCBtb2R1bGUuZXhwb3J0cylcbiAgfVxufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlci5qcz9pZD1kYXRhLXYtM2ExNmFjM2MhLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL3NyYy9jb21wb25lbnRzL25hdmJhci52dWVcbi8vIG1vZHVsZSBpZCA9IDQwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=');
},function(module,exports,__webpack_require__){eval('module.exports={render:function (){with(this) {\n  return _h(\'div\', [_l((infos), function(info) {\n    return _h(\'div\', {\n      staticClass: "mix-info-wrapper"\n    }, [_h(\'div\', {\n      staticClass: "mix-info-content"\n    }, [_h(\'p\', [_s(info.title)]), " ", _h(\'div\', {\n      staticClass: "tag"\n    }, [_l((info.tags), function(tag) {\n      return _h(\'span\', [_s(tag)])\n    })])]), " ", _h(\'div\', {\n      staticClass: "mix-info-media"\n    }, [_h(\'div\', {\n      staticClass: "media"\n    }, [_h(\'img\', {\n      attrs: {\n        "src": info.uSrc,\n        "alt": ""\n      }\n    }), " ", _h(\'span\', [_s(info.name)])]), " ", _h(\'div\', {\n      staticClass: "plug"\n    }, [_m(0, true), " ", _h(\'div\', {\n      staticClass: "plug-box",\n      class: {\n        \'pay\': info.status.pay, \'free\': info.status.free, \'expire\': info.status.expire\n      }\n    }, [_m(1, true), " ", _m(2, true), " ", (info.status.pay) ? _h(\'span\', {\n      staticClass: "text"\n    }, [_s(info.status.text)]) : _e(), " ", (info.status.free) ? _h(\'span\', {\n      staticClass: "text"\n    }, [_s(info.status.text)]) : _e(), " ", (info.status.expire) ? _h(\'span\', {\n      staticClass: "text"\n    }, [_s(info.status.text)]) : _e(), " ", _h(\'audio\', {\n      attrs: {\n        "src": info.rSrc\n      }\n    })])]), " ", _h(\'div\', {\n      staticClass: "time"\n    }, [_s(info.datetime)])]), " ", _m(3, true)])\n  })])\n}},staticRenderFns: [function (){with(this) {\n  return _h(\'span\', {\n    staticClass: "ms"\n  }, [_h(\'i\'), "\'\'"])\n}},function (){with(this) {\n  return _h(\'span\', {\n    staticClass: "arrow-left"\n  })\n}},function (){with(this) {\n  return _h(\'span\', {\n    staticClass: "icon icon-right"\n  })\n}},function (){with(this) {\n  return _h(\'div\', {\n    staticClass: "mix-info-action"\n  }, [_h(\'div\', {\n    staticClass: "row"\n  }, [_h(\'div\', {\n    staticClass: "col-33"\n  }, [_h(\'span\', {\n    staticClass: "icon icon-app"\n  }), " ", _h(\'i\', ["1150"])]), " ", _h(\'div\', {\n    staticClass: "col-33"\n  }, [_h(\'span\', {\n    staticClass: "icon icon-app"\n  }), " ", _h(\'i\', ["1150"])]), " ", _h(\'div\', {\n    staticClass: "col-33"\n  }, [_h(\'span\', {\n    staticClass: "icon icon-app"\n  }), " ", _h(\'i\', ["1150"])])])])\n}}]}\nif (false) {\n  module.hot.accept()\n  if (module.hot.data) {\n     require("vue-hot-reload-api").rerender("data-v-3b7ba589", module.exports)\n  }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9xdWVzdGlvbi52dWU/YzM2YiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxnQkFBZ0IsbUJBQW1CO0FBQ25DO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNILEVBQUUsK0JBQStCO0FBQ2pDO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRSxhQUFhO0FBQ2Y7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFLGFBQWE7QUFDZjtBQUNBO0FBQ0EsR0FBRztBQUNILEVBQUUsYUFBYTtBQUNmO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0gsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiI0MS5qcyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzPXtyZW5kZXI6ZnVuY3Rpb24gKCl7d2l0aCh0aGlzKSB7XG4gIHJldHVybiBfaCgnZGl2JywgW19sKChpbmZvcyksIGZ1bmN0aW9uKGluZm8pIHtcbiAgICByZXR1cm4gX2goJ2RpdicsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcIm1peC1pbmZvLXdyYXBwZXJcIlxuICAgIH0sIFtfaCgnZGl2Jywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwibWl4LWluZm8tY29udGVudFwiXG4gICAgfSwgW19oKCdwJywgW19zKGluZm8udGl0bGUpXSksIFwiIFwiLCBfaCgnZGl2Jywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwidGFnXCJcbiAgICB9LCBbX2woKGluZm8udGFncyksIGZ1bmN0aW9uKHRhZykge1xuICAgICAgcmV0dXJuIF9oKCdzcGFuJywgW19zKHRhZyldKVxuICAgIH0pXSldKSwgXCIgXCIsIF9oKCdkaXYnLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJtaXgtaW5mby1tZWRpYVwiXG4gICAgfSwgW19oKCdkaXYnLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJtZWRpYVwiXG4gICAgfSwgW19oKCdpbWcnLCB7XG4gICAgICBhdHRyczoge1xuICAgICAgICBcInNyY1wiOiBpbmZvLnVTcmMsXG4gICAgICAgIFwiYWx0XCI6IFwiXCJcbiAgICAgIH1cbiAgICB9KSwgXCIgXCIsIF9oKCdzcGFuJywgW19zKGluZm8ubmFtZSldKV0pLCBcIiBcIiwgX2goJ2RpdicsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcInBsdWdcIlxuICAgIH0sIFtfbSgwLCB0cnVlKSwgXCIgXCIsIF9oKCdkaXYnLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJwbHVnLWJveFwiLFxuICAgICAgY2xhc3M6IHtcbiAgICAgICAgJ3BheSc6IGluZm8uc3RhdHVzLnBheSwgJ2ZyZWUnOiBpbmZvLnN0YXR1cy5mcmVlLCAnZXhwaXJlJzogaW5mby5zdGF0dXMuZXhwaXJlXG4gICAgICB9XG4gICAgfSwgW19tKDEsIHRydWUpLCBcIiBcIiwgX20oMiwgdHJ1ZSksIFwiIFwiLCAoaW5mby5zdGF0dXMucGF5KSA/IF9oKCdzcGFuJywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwidGV4dFwiXG4gICAgfSwgW19zKGluZm8uc3RhdHVzLnRleHQpXSkgOiBfZSgpLCBcIiBcIiwgKGluZm8uc3RhdHVzLmZyZWUpID8gX2goJ3NwYW4nLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJ0ZXh0XCJcbiAgICB9LCBbX3MoaW5mby5zdGF0dXMudGV4dCldKSA6IF9lKCksIFwiIFwiLCAoaW5mby5zdGF0dXMuZXhwaXJlKSA/IF9oKCdzcGFuJywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwidGV4dFwiXG4gICAgfSwgW19zKGluZm8uc3RhdHVzLnRleHQpXSkgOiBfZSgpLCBcIiBcIiwgX2goJ2F1ZGlvJywge1xuICAgICAgYXR0cnM6IHtcbiAgICAgICAgXCJzcmNcIjogaW5mby5yU3JjXG4gICAgICB9XG4gICAgfSldKV0pLCBcIiBcIiwgX2goJ2RpdicsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcInRpbWVcIlxuICAgIH0sIFtfcyhpbmZvLmRhdGV0aW1lKV0pXSksIFwiIFwiLCBfbSgzLCB0cnVlKV0pXG4gIH0pXSlcbn19LHN0YXRpY1JlbmRlckZuczogW2Z1bmN0aW9uICgpe3dpdGgodGhpcykge1xuICByZXR1cm4gX2goJ3NwYW4nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibXNcIlxuICB9LCBbX2goJ2knKSwgXCInJ1wiXSlcbn19LGZ1bmN0aW9uICgpe3dpdGgodGhpcykge1xuICByZXR1cm4gX2goJ3NwYW4nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiYXJyb3ctbGVmdFwiXG4gIH0pXG59fSxmdW5jdGlvbiAoKXt3aXRoKHRoaXMpIHtcbiAgcmV0dXJuIF9oKCdzcGFuJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImljb24gaWNvbi1yaWdodFwiXG4gIH0pXG59fSxmdW5jdGlvbiAoKXt3aXRoKHRoaXMpIHtcbiAgcmV0dXJuIF9oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibWl4LWluZm8tYWN0aW9uXCJcbiAgfSwgW19oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwicm93XCJcbiAgfSwgW19oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiY29sLTMzXCJcbiAgfSwgW19oKCdzcGFuJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImljb24gaWNvbi1hcHBcIlxuICB9KSwgXCIgXCIsIF9oKCdpJywgW1wiMTE1MFwiXSldKSwgXCIgXCIsIF9oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiY29sLTMzXCJcbiAgfSwgW19oKCdzcGFuJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImljb24gaWNvbi1hcHBcIlxuICB9KSwgXCIgXCIsIF9oKCdpJywgW1wiMTE1MFwiXSldKSwgXCIgXCIsIF9oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiY29sLTMzXCJcbiAgfSwgW19oKCdzcGFuJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImljb24gaWNvbi1hcHBcIlxuICB9KSwgXCIgXCIsIF9oKCdpJywgW1wiMTE1MFwiXSldKV0pXSlcbn19XX1cbmlmIChtb2R1bGUuaG90KSB7XG4gIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuICAgICByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpLnJlcmVuZGVyKFwiZGF0YS12LTNiN2JhNTg5XCIsIG1vZHVsZS5leHBvcnRzKVxuICB9XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Z1ZS1sb2FkZXIvbGliL3RlbXBsYXRlLWNvbXBpbGVyLmpzP2lkPWRhdGEtdi0zYjdiYTU4OSEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT10ZW1wbGF0ZSZpbmRleD0wIS4vc3JjL2NvbXBvbmVudHMvdmlldy9zY2hvb2wvcXVlc3Rpb24udnVlXG4vLyBtb2R1bGUgaWQgPSA0MVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('module.exports={render:function (){with(this) {\n  return _h(\'div\', {\n    staticClass: "content"\n  }, [_h(\'info-header\'), " ", _h(\'router-view\')])\n}},staticRenderFns: []}\nif (false) {\n  module.hot.accept()\n  if (module.hot.data) {\n     require("vue-hot-reload-api").rerender("data-v-555a0b5c", module.exports)\n  }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9tYWluLnZ1ZT8xMTRkIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGdCQUFnQixtQkFBbUI7QUFDbkM7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjQyLmpzIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt3aXRoKHRoaXMpIHtcbiAgcmV0dXJuIF9oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiY29udGVudFwiXG4gIH0sIFtfaCgnaW5mby1oZWFkZXInKSwgXCIgXCIsIF9oKCdyb3V0ZXItdmlldycpXSlcbn19LHN0YXRpY1JlbmRlckZuczogW119XG5pZiAobW9kdWxlLmhvdCkge1xuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcbiAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi01NTVhMGI1Y1wiLCBtb2R1bGUuZXhwb3J0cylcbiAgfVxufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlci5qcz9pZD1kYXRhLXYtNTU1YTBiNWMhLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL21haW4udnVlXG4vLyBtb2R1bGUgaWQgPSA0MlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('module.exports={render:function (){with(this) {\n  return _h(\'div\', [_h(\'div\', {\n    staticClass: "notice"\n  }, [_h(\'span\', {\n    staticClass: "omit omit1"\n  }, [_h(\'span\', {\n    staticClass: "icon icon-message"\n  }, [_s(notice)])])]), " ", _l((infos), function(info) {\n    return _h(\'div\', {\n      staticClass: "mix-info-wrapper"\n    }, [_h(\'div\', {\n      staticClass: "mix-info-media"\n    }, [_h(\'div\', {\n      staticClass: "media"\n    }, [_h(\'img\', {\n      attrs: {\n        "src": info.uSrc\n      }\n    }), " ", _h(\'span\', [_s(info.name)])]), " ", _h(\'div\', {\n      staticClass: "time"\n    }, [_s(info.time)])]), " ", _h(\'div\', {\n      staticClass: "mix-info-other"\n    }, [_h(\'video\', {\n      attrs: {\n        "controls": "",\n        "poster": info.pSrc,\n        "width": "350",\n        "height": "230"\n      }\n    }, [_h(\'source\', {\n      attrs: {\n        "src": info.vSrc,\n        "type": "video/mp4"\n      }\n    }), " ", _m(0, true)]), " ", _h(\'div\', {\n      staticClass: "widget"\n    }, [_h(\'div\', [_h(\'span\', [_s(info.lookedNum)]), "人 已看"]), " ", _m(1, true)])]), " ", _h(\'div\', {\n      staticClass: "mix-info-content"\n    }, [_h(\'p\', [_s(info.title)]), " ", _h(\'div\', {\n      staticClass: "tag"\n    }, [_l((info.tags), function(tag) {\n      return _h(\'span\', [_s(tag)])\n    })])]), " ", _m(2, true)])\n  })])\n}},staticRenderFns: [function (){with(this) {\n  return _h(\'p\', ["Your browser does not support H.264/MP4."])\n}},function (){with(this) {\n  return _h(\'div\', ["回放"])\n}},function (){with(this) {\n  return _h(\'div\', {\n    staticClass: "mix-info-action"\n  }, [_h(\'div\', {\n    staticClass: "row"\n  }, [_h(\'div\', {\n    staticClass: "col-33"\n  }, [_h(\'span\', {\n    staticClass: "icon icon-app"\n  }), " ", _h(\'i\', ["1150"])]), " ", _h(\'div\', {\n    staticClass: "col-33"\n  }, [_h(\'span\', {\n    staticClass: "icon icon-app"\n  }), " ", _h(\'i\', ["1150"])]), " ", _h(\'div\', {\n    staticClass: "col-33"\n  }, [_h(\'span\', {\n    staticClass: "icon icon-app"\n  }), " ", _h(\'i\', ["1150"])])])])\n}}]}\nif (false) {\n  module.hot.accept()\n  if (module.hot.data) {\n     require("vue-hot-reload-api").rerender("data-v-921da930", module.exports)\n  }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC92aWRlby52dWU/ZDlhMyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxnQkFBZ0IsbUJBQW1CO0FBQ25DO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSCxFQUFFLCtCQUErQjtBQUNqQztBQUNBLEVBQUUsYUFBYTtBQUNmO0FBQ0EsRUFBRSxhQUFhO0FBQ2Y7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjQzLmpzIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt3aXRoKHRoaXMpIHtcbiAgcmV0dXJuIF9oKCdkaXYnLCBbX2goJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJub3RpY2VcIlxuICB9LCBbX2goJ3NwYW4nLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwib21pdCBvbWl0MVwiXG4gIH0sIFtfaCgnc3BhbicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJpY29uIGljb24tbWVzc2FnZVwiXG4gIH0sIFtfcyhub3RpY2UpXSldKV0pLCBcIiBcIiwgX2woKGluZm9zKSwgZnVuY3Rpb24oaW5mbykge1xuICAgIHJldHVybiBfaCgnZGl2Jywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwibWl4LWluZm8td3JhcHBlclwiXG4gICAgfSwgW19oKCdkaXYnLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJtaXgtaW5mby1tZWRpYVwiXG4gICAgfSwgW19oKCdkaXYnLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJtZWRpYVwiXG4gICAgfSwgW19oKCdpbWcnLCB7XG4gICAgICBhdHRyczoge1xuICAgICAgICBcInNyY1wiOiBpbmZvLnVTcmNcbiAgICAgIH1cbiAgICB9KSwgXCIgXCIsIF9oKCdzcGFuJywgW19zKGluZm8ubmFtZSldKV0pLCBcIiBcIiwgX2goJ2RpdicsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcInRpbWVcIlxuICAgIH0sIFtfcyhpbmZvLnRpbWUpXSldKSwgXCIgXCIsIF9oKCdkaXYnLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJtaXgtaW5mby1vdGhlclwiXG4gICAgfSwgW19oKCd2aWRlbycsIHtcbiAgICAgIGF0dHJzOiB7XG4gICAgICAgIFwiY29udHJvbHNcIjogXCJcIixcbiAgICAgICAgXCJwb3N0ZXJcIjogaW5mby5wU3JjLFxuICAgICAgICBcIndpZHRoXCI6IFwiMzUwXCIsXG4gICAgICAgIFwiaGVpZ2h0XCI6IFwiMjMwXCJcbiAgICAgIH1cbiAgICB9LCBbX2goJ3NvdXJjZScsIHtcbiAgICAgIGF0dHJzOiB7XG4gICAgICAgIFwic3JjXCI6IGluZm8udlNyYyxcbiAgICAgICAgXCJ0eXBlXCI6IFwidmlkZW8vbXA0XCJcbiAgICAgIH1cbiAgICB9KSwgXCIgXCIsIF9tKDAsIHRydWUpXSksIFwiIFwiLCBfaCgnZGl2Jywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwid2lkZ2V0XCJcbiAgICB9LCBbX2goJ2RpdicsIFtfaCgnc3BhbicsIFtfcyhpbmZvLmxvb2tlZE51bSldKSwgXCLkurrCoOW3sueci1wiXSksIFwiIFwiLCBfbSgxLCB0cnVlKV0pXSksIFwiIFwiLCBfaCgnZGl2Jywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwibWl4LWluZm8tY29udGVudFwiXG4gICAgfSwgW19oKCdwJywgW19zKGluZm8udGl0bGUpXSksIFwiIFwiLCBfaCgnZGl2Jywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwidGFnXCJcbiAgICB9LCBbX2woKGluZm8udGFncyksIGZ1bmN0aW9uKHRhZykge1xuICAgICAgcmV0dXJuIF9oKCdzcGFuJywgW19zKHRhZyldKVxuICAgIH0pXSldKSwgXCIgXCIsIF9tKDIsIHRydWUpXSlcbiAgfSldKVxufX0sc3RhdGljUmVuZGVyRm5zOiBbZnVuY3Rpb24gKCl7d2l0aCh0aGlzKSB7XG4gIHJldHVybiBfaCgncCcsIFtcIllvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IEguMjY0L01QNC5cIl0pXG59fSxmdW5jdGlvbiAoKXt3aXRoKHRoaXMpIHtcbiAgcmV0dXJuIF9oKCdkaXYnLCBbXCLlm57mlL5cIl0pXG59fSxmdW5jdGlvbiAoKXt3aXRoKHRoaXMpIHtcbiAgcmV0dXJuIF9oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibWl4LWluZm8tYWN0aW9uXCJcbiAgfSwgW19oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwicm93XCJcbiAgfSwgW19oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiY29sLTMzXCJcbiAgfSwgW19oKCdzcGFuJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImljb24gaWNvbi1hcHBcIlxuICB9KSwgXCIgXCIsIF9oKCdpJywgW1wiMTE1MFwiXSldKSwgXCIgXCIsIF9oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiY29sLTMzXCJcbiAgfSwgW19oKCdzcGFuJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImljb24gaWNvbi1hcHBcIlxuICB9KSwgXCIgXCIsIF9oKCdpJywgW1wiMTE1MFwiXSldKSwgXCIgXCIsIF9oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwiY29sLTMzXCJcbiAgfSwgW19oKCdzcGFuJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImljb24gaWNvbi1hcHBcIlxuICB9KSwgXCIgXCIsIF9oKCdpJywgW1wiMTE1MFwiXSldKV0pXSlcbn19XX1cbmlmIChtb2R1bGUuaG90KSB7XG4gIG1vZHVsZS5ob3QuYWNjZXB0KClcbiAgaWYgKG1vZHVsZS5ob3QuZGF0YSkge1xuICAgICByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpLnJlcmVuZGVyKFwiZGF0YS12LTkyMWRhOTMwXCIsIG1vZHVsZS5leHBvcnRzKVxuICB9XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Z1ZS1sb2FkZXIvbGliL3RlbXBsYXRlLWNvbXBpbGVyLmpzP2lkPWRhdGEtdi05MjFkYTkzMCEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT10ZW1wbGF0ZSZpbmRleD0wIS4vc3JjL2NvbXBvbmVudHMvdmlldy9zY2hvb2wvdmlkZW8udnVlXG4vLyBtb2R1bGUgaWQgPSA0M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){eval('module.exports={render:function (){with(this) {\n  return _h(\'div\', [_l((infos), function(info, index) {\n    return _h(\'div\', {\n      staticClass: "intro-box"\n    }, [(index === 0) ? _h(\'div\', [_h(\'h2\', {\n      staticClass: "title"\n    }, [_h(\'span\', [_s(info.title)])]), " ", _h(\'p\', [_s(info.p1)]), " ", _h(\'p\', {\n      staticClass: "omit omit2"\n    }, [_s(info.p2)]), " ", _m(0, true)]) : _h(\'div\', [_h(\'h2\', {\n      staticClass: "title"\n    }, [_h(\'span\', [_s(info.title)])]), " ", _h(\'p\', {\n      staticClass: "no-indent"\n    }, [_h(\'span\', [_s(info.school)]), "综合入学条件:", _h(\'span\', {\n      staticClass: "text-info"\n    }, ["(最低标准)"])]), " ", _h(\'p\', ["本科:TOEFL  iBT:", _h(\'span\', {\n      staticClass: "text-important"\n    }, [_s(info.rank.undergraduate.ibt)]), "分  SAT居中成绩:", _h(\'span\', {\n      staticClass: "text-important"\n    }, [_s(info.rank.undergraduate.sat)]), ",另附高中成绩单,英文财力证明等相关资料;"]), " ", _h(\'p\', ["硕士:TOEFL  iBT:", _h(\'span\', {\n      staticClass: "text-important"\n    }, [_s(info.rank.master.ibt)]), "分  GRE成绩:", _h(\'span\', {\n      staticClass: "text-important"\n    }, [_s(info.rank.master.gre)]), ",GPA:3.3,另附本科成绩单,英文财力证明等相关资料;"]), " ", _h(\'p\', ["博士:TOEFL  iBT:", _h(\'span\', {\n      staticClass: "text-important"\n    }, [_s(info.rank.doctor.ibt)]), "分  GRE成绩:", _h(\'span\', {\n      staticClass: "text-important"\n    }, [_s(info.rank.doctor.gre)]), ",GPA:3.3,另附本科成绩单,英文财力证明等相关资料;"])]), " "])\n  }), " ", _m(1)])\n}},staticRenderFns: [function (){with(this) {\n  return _h(\'div\', {\n    staticClass: "more"\n  }, [_h(\'a\', {\n    attrs: {\n      "href": "#"\n    }\n  }, ["MORE"]), " ", _h(\'div\', {\n    staticClass: "more-link"\n  }, [_h(\'span\', {\n    staticClass: "icon icon-right"\n  })])])\n}},function (){with(this) {\n  return _h(\'div\', {\n    staticClass: "test-img"\n  }, ["\\n111\\n  "])\n}}]}\nif (false) {\n  module.hot.accept()\n  if (module.hot.data) {\n     require("vue-hot-reload-api").rerender("data-v-c91fc64e", module.exports)\n  }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9pbnRyby52dWU/ZTA4NCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxnQkFBZ0IsbUJBQW1CO0FBQ25DO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0gsRUFBRSwrQkFBK0I7QUFDakM7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0gsRUFBRSxhQUFhO0FBQ2Y7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjQ0LmpzIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHM9e3JlbmRlcjpmdW5jdGlvbiAoKXt3aXRoKHRoaXMpIHtcbiAgcmV0dXJuIF9oKCdkaXYnLCBbX2woKGluZm9zKSwgZnVuY3Rpb24oaW5mbywgaW5kZXgpIHtcbiAgICByZXR1cm4gX2goJ2RpdicsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcImludHJvLWJveFwiXG4gICAgfSwgWyhpbmRleCA9PT0gMCkgPyBfaCgnZGl2JywgW19oKCdoMicsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcInRpdGxlXCJcbiAgICB9LCBbX2goJ3NwYW4nLCBbX3MoaW5mby50aXRsZSldKV0pLCBcIiBcIiwgX2goJ3AnLCBbX3MoaW5mby5wMSldKSwgXCIgXCIsIF9oKCdwJywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwib21pdCBvbWl0MlwiXG4gICAgfSwgW19zKGluZm8ucDIpXSksIFwiIFwiLCBfbSgwLCB0cnVlKV0pIDogX2goJ2RpdicsIFtfaCgnaDInLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJ0aXRsZVwiXG4gICAgfSwgW19oKCdzcGFuJywgW19zKGluZm8udGl0bGUpXSldKSwgXCIgXCIsIF9oKCdwJywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwibm8taW5kZW50XCJcbiAgICB9LCBbX2goJ3NwYW4nLCBbX3MoaW5mby5zY2hvb2wpXSksIFwi57u85ZCI5YWl5a2m5p2h5Lu277yaXCIsIF9oKCdzcGFuJywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwidGV4dC1pbmZvXCJcbiAgICB9LCBbXCIo5pyA5L2O5qCH5YeGKVwiXSldKSwgXCIgXCIsIF9oKCdwJywgW1wi5pys56eR77yaVE9FRkzCoMKgaUJU77yaXCIsIF9oKCdzcGFuJywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwidGV4dC1pbXBvcnRhbnRcIlxuICAgIH0sIFtfcyhpbmZvLnJhbmsudW5kZXJncmFkdWF0ZS5pYnQpXSksIFwi5YiGwqDCoFNBVOWxheS4reaIkOe7qe+8mlwiLCBfaCgnc3BhbicsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcInRleHQtaW1wb3J0YW50XCJcbiAgICB9LCBbX3MoaW5mby5yYW5rLnVuZGVyZ3JhZHVhdGUuc2F0KV0pLCBcIu+8jOWPpumZhOmrmOS4reaIkOe7qeWNle+8jOiLseaWh+i0ouWKm+ivgeaYjuetieebuOWFs+i1hOaWme+8m1wiXSksIFwiIFwiLCBfaCgncCcsIFtcIuehleWjq++8mlRPRUZMwqDCoGlCVO+8mlwiLCBfaCgnc3BhbicsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcInRleHQtaW1wb3J0YW50XCJcbiAgICB9LCBbX3MoaW5mby5yYW5rLm1hc3Rlci5pYnQpXSksIFwi5YiGwqDCoEdSReaIkOe7qe+8mlwiLCBfaCgnc3BhbicsIHtcbiAgICAgIHN0YXRpY0NsYXNzOiBcInRleHQtaW1wb3J0YW50XCJcbiAgICB9LCBbX3MoaW5mby5yYW5rLm1hc3Rlci5ncmUpXSksIFwi77yMR1BB77yaMy4z77yM5Y+m6ZmE5pys56eR5oiQ57up5Y2V77yM6Iux5paH6LSi5Yqb6K+B5piO562J55u45YWz6LWE5paZ77ybXCJdKSwgXCIgXCIsIF9oKCdwJywgW1wi5Y2a5aOr77yaVE9FRkzCoMKgaUJU77yaXCIsIF9oKCdzcGFuJywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwidGV4dC1pbXBvcnRhbnRcIlxuICAgIH0sIFtfcyhpbmZvLnJhbmsuZG9jdG9yLmlidCldKSwgXCLliIbCoMKgR1JF5oiQ57up77yaXCIsIF9oKCdzcGFuJywge1xuICAgICAgc3RhdGljQ2xhc3M6IFwidGV4dC1pbXBvcnRhbnRcIlxuICAgIH0sIFtfcyhpbmZvLnJhbmsuZG9jdG9yLmdyZSldKSwgXCLvvIxHUEHvvJozLjPvvIzlj6bpmYTmnKznp5HmiJDnu6nljZXvvIzoi7HmlofotKLlipvor4HmmI7nrYnnm7jlhbPotYTmlpnvvJtcIl0pXSksIFwiIFwiXSlcbiAgfSksIFwiIFwiLCBfbSgxKV0pXG59fSxzdGF0aWNSZW5kZXJGbnM6IFtmdW5jdGlvbiAoKXt3aXRoKHRoaXMpIHtcbiAgcmV0dXJuIF9oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibW9yZVwiXG4gIH0sIFtfaCgnYScsIHtcbiAgICBhdHRyczoge1xuICAgICAgXCJocmVmXCI6IFwiI1wiXG4gICAgfVxuICB9LCBbXCJNT1JFXCJdKSwgXCIgXCIsIF9oKCdkaXYnLCB7XG4gICAgc3RhdGljQ2xhc3M6IFwibW9yZS1saW5rXCJcbiAgfSwgW19oKCdzcGFuJywge1xuICAgIHN0YXRpY0NsYXNzOiBcImljb24gaWNvbi1yaWdodFwiXG4gIH0pXSldKVxufX0sZnVuY3Rpb24gKCl7d2l0aCh0aGlzKSB7XG4gIHJldHVybiBfaCgnZGl2Jywge1xuICAgIHN0YXRpY0NsYXNzOiBcInRlc3QtaW1nXCJcbiAgfSwgW1wiXFxuMTExXFxuICBcIl0pXG59fV19XG5pZiAobW9kdWxlLmhvdCkge1xuICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIGlmIChtb2R1bGUuaG90LmRhdGEpIHtcbiAgICAgcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKS5yZXJlbmRlcihcImRhdGEtdi1jOTFmYzY0ZVwiLCBtb2R1bGUuZXhwb3J0cylcbiAgfVxufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi92dWUtbG9hZGVyL2xpYi90ZW1wbGF0ZS1jb21waWxlci5qcz9pZD1kYXRhLXYtYzkxZmM2NGUhLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9dGVtcGxhdGUmaW5kZXg9MCEuL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL2ludHJvLnZ1ZVxuLy8gbW9kdWxlIGlkID0gNDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==')},function(module,exports,__webpack_require__){eval("// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = __webpack_require__(22);\nif(typeof content === 'string') content = [[module.i, content, '']];\n// add the styles to the DOM\nvar update = __webpack_require__(1)(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(false) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-0021a770!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./header.vue\", function() {\n\t\t\tvar newContent = require(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-0021a770!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./header.vue\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9oZWFkZXIudnVlP2Y5ZTciXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBNkY7QUFDN0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxnQ0FBZ0MsVUFBVSxFQUFFO0FBQzVDIiwiZmlsZSI6IjQ1LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0wMDIxYTc3MCEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vaGVhZGVyLnZ1ZVwiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLXN0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcIikoY29udGVudCwge30pO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG5cdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtMDAyMWE3NzAhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL2hlYWRlci52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0wMDIxYTc3MCEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vaGVhZGVyLnZ1ZVwiKTtcblx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0dXBkYXRlKG5ld0NvbnRlbnQpO1xuXHRcdH0pO1xuXHR9XG5cdC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Z1ZS1zdHlsZS1sb2FkZXIhLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtMDAyMWE3NzAhLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9oZWFkZXIudnVlXG4vLyBtb2R1bGUgaWQgPSA0NVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9")},function(module,exports,__webpack_require__){eval("// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = __webpack_require__(23);\nif(typeof content === 'string') content = [[module.i, content, '']];\n// add the styles to the DOM\nvar update = __webpack_require__(1)(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(false) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-14f9a6de!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./consultant.vue\", function() {\n\t\t\tvar newContent = require(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-14f9a6de!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./consultant.vue\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9jb25zdWx0YW50LnZ1ZT82OTU3Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0NBQTZGO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsZ0NBQWdDLFVBQVUsRUFBRTtBQUM1QyIsImZpbGUiOiI0Ni5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cbi8vIGxvYWQgdGhlIHN0eWxlc1xudmFyIGNvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtMTRmOWE2ZGUhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL2NvbnN1bHRhbnQudnVlXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyL2FkZFN0eWxlcy5qc1wiKShjb250ZW50LCB7fSk7XG5pZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcbi8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcbmlmKG1vZHVsZS5ob3QpIHtcblx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0xNGY5YTZkZSEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vY29uc3VsdGFudC52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0xNGY5YTZkZSEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vY29uc3VsdGFudC52dWVcIik7XG5cdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHR9KTtcblx0fVxuXHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi92dWUtc3R5bGUtbG9hZGVyIS4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTE0ZjlhNmRlIS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vc3JjL2NvbXBvbmVudHMvdmlldy9zY2hvb2wvY29uc3VsdGFudC52dWVcbi8vIG1vZHVsZSBpZCA9IDQ2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=")},function(module,exports,__webpack_require__){eval("// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = __webpack_require__(24);\nif(typeof content === 'string') content = [[module.i, content, '']];\n// add the styles to the DOM\nvar update = __webpack_require__(1)(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(false) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../node_modules/css-loader/index.js?sourceMap!./../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-2a556f0c!./../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./App.vue\", function() {\n\t\t\tvar newContent = require(\"!!./../node_modules/css-loader/index.js?sourceMap!./../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-2a556f0c!./../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./App.vue\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvQXBwLnZ1ZT82NDUyIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0NBQW9GO0FBQ3BGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsZ0NBQWdDLFVBQVUsRUFBRTtBQUM1QyIsImZpbGUiOiI0Ny5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cbi8vIGxvYWQgdGhlIHN0eWxlc1xudmFyIGNvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtMmE1NTZmMGMhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0FwcC52dWVcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTJhNTU2ZjBjIS4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9BcHAudnVlXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIG5ld0NvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtMmE1NTZmMGMhLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL0FwcC52dWVcIik7XG5cdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHR9KTtcblx0fVxuXHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi92dWUtc3R5bGUtbG9hZGVyIS4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTJhNTU2ZjBjIS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vc3JjL0FwcC52dWVcbi8vIG1vZHVsZSBpZCA9IDQ3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=");
},function(module,exports,__webpack_require__){eval("// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = __webpack_require__(25);\nif(typeof content === 'string') content = [[module.i, content, '']];\n// add the styles to the DOM\nvar update = __webpack_require__(1)(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(false) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-2e956757!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./collect.vue\", function() {\n\t\t\tvar newContent = require(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-2e956757!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./collect.vue\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9jb2xsZWN0LnZ1ZT8xOWVkIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0NBQTZGO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsZ0NBQWdDLFVBQVUsRUFBRTtBQUM1QyIsImZpbGUiOiI0OC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cbi8vIGxvYWQgdGhlIHN0eWxlc1xudmFyIGNvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtMmU5NTY3NTchLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL2NvbGxlY3QudnVlXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyL2FkZFN0eWxlcy5qc1wiKShjb250ZW50LCB7fSk7XG5pZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcbi8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcbmlmKG1vZHVsZS5ob3QpIHtcblx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0yZTk1Njc1NyEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vY29sbGVjdC52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0yZTk1Njc1NyEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vY29sbGVjdC52dWVcIik7XG5cdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHR9KTtcblx0fVxuXHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi92dWUtc3R5bGUtbG9hZGVyIS4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTJlOTU2NzU3IS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vc3JjL2NvbXBvbmVudHMvdmlldy9zY2hvb2wvY29sbGVjdC52dWVcbi8vIG1vZHVsZSBpZCA9IDQ4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=")},function(module,exports,__webpack_require__){eval("// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = __webpack_require__(26);\nif(typeof content === 'string') content = [[module.i, content, '']];\n// add the styles to the DOM\nvar update = __webpack_require__(1)(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(false) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-3a16ac3c!./../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./navbar.vue\", function() {\n\t\t\tvar newContent = require(\"!!./../../node_modules/css-loader/index.js?sourceMap!./../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-3a16ac3c!./../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./navbar.vue\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy9uYXZiYXIudnVlP2MwOWQiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBdUY7QUFDdkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxnQ0FBZ0MsVUFBVSxFQUFFO0FBQzVDIiwiZmlsZSI6IjQ5LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gc3R5bGUtbG9hZGVyOiBBZGRzIHNvbWUgY3NzIHRvIHRoZSBET00gYnkgYWRkaW5nIGEgPHN0eWxlPiB0YWdcblxuLy8gbG9hZCB0aGUgc3R5bGVzXG52YXIgY29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0zYTE2YWMzYyEuLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vbmF2YmFyLnZ1ZVwiKTtcbmlmKHR5cGVvZiBjb250ZW50ID09PSAnc3RyaW5nJykgY29udGVudCA9IFtbbW9kdWxlLmlkLCBjb250ZW50LCAnJ11dO1xuLy8gYWRkIHRoZSBzdHlsZXMgdG8gdGhlIERPTVxudmFyIHVwZGF0ZSA9IHJlcXVpcmUoXCIhLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLXN0eWxlLWxvYWRlci9hZGRTdHlsZXMuanNcIikoY29udGVudCwge30pO1xuaWYoY29udGVudC5sb2NhbHMpIG1vZHVsZS5leHBvcnRzID0gY29udGVudC5sb2NhbHM7XG4vLyBIb3QgTW9kdWxlIFJlcGxhY2VtZW50XG5pZihtb2R1bGUuaG90KSB7XG5cdC8vIFdoZW4gdGhlIHN0eWxlcyBjaGFuZ2UsIHVwZGF0ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdGlmKCFjb250ZW50LmxvY2Fscykge1xuXHRcdG1vZHVsZS5ob3QuYWNjZXB0KFwiISEuLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtM2ExNmFjM2MhLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL25hdmJhci52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0zYTE2YWMzYyEuLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vbmF2YmFyLnZ1ZVwiKTtcblx0XHRcdGlmKHR5cGVvZiBuZXdDb250ZW50ID09PSAnc3RyaW5nJykgbmV3Q29udGVudCA9IFtbbW9kdWxlLmlkLCBuZXdDb250ZW50LCAnJ11dO1xuXHRcdFx0dXBkYXRlKG5ld0NvbnRlbnQpO1xuXHRcdH0pO1xuXHR9XG5cdC8vIFdoZW4gdGhlIG1vZHVsZSBpcyBkaXNwb3NlZCwgcmVtb3ZlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0bW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uKCkgeyB1cGRhdGUoKTsgfSk7XG59XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Z1ZS1zdHlsZS1sb2FkZXIhLi9+L2Nzcy1sb2FkZXI/c291cmNlTWFwIS4vfi92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtM2ExNmFjM2MhLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9zcmMvY29tcG9uZW50cy9uYXZiYXIudnVlXG4vLyBtb2R1bGUgaWQgPSA0OVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9")},function(module,exports,__webpack_require__){eval("// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = __webpack_require__(27);\nif(typeof content === 'string') content = [[module.i, content, '']];\n// add the styles to the DOM\nvar update = __webpack_require__(1)(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(false) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-3b7ba589!./../../../../node_modules/less-loader/index.js!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./question.vue\", function() {\n\t\t\tvar newContent = require(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-3b7ba589!./../../../../node_modules/less-loader/index.js!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./question.vue\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9xdWVzdGlvbi52dWU/ODE3ZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUE2RjtBQUM3RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLGdDQUFnQyxVQUFVLEVBQUU7QUFDNUMiLCJmaWxlIjoiNTAuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTNiN2JhNTg5IS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2xlc3MtbG9hZGVyL2luZGV4LmpzIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9xdWVzdGlvbi52dWVcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTNiN2JhNTg5IS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2xlc3MtbG9hZGVyL2luZGV4LmpzIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9xdWVzdGlvbi52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0zYjdiYTU4OSEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9sZXNzLWxvYWRlci9pbmRleC5qcyEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vcXVlc3Rpb24udnVlXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vdnVlLXN0eWxlLWxvYWRlciEuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi0zYjdiYTU4OSEuL34vbGVzcy1sb2FkZXIhLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9xdWVzdGlvbi52dWVcbi8vIG1vZHVsZSBpZCA9IDUwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=")},function(module,exports,__webpack_require__){eval("// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = __webpack_require__(28);\nif(typeof content === 'string') content = [[module.i, content, '']];\n// add the styles to the DOM\nvar update = __webpack_require__(1)(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(false) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-555a0b5c!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./main.vue\", function() {\n\t\t\tvar newContent = require(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-555a0b5c!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./main.vue\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9tYWluLnZ1ZT84MDg2Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0NBQTZGO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsZ0NBQWdDLFVBQVUsRUFBRTtBQUM1QyIsImZpbGUiOiI1MS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHN0eWxlLWxvYWRlcjogQWRkcyBzb21lIGNzcyB0byB0aGUgRE9NIGJ5IGFkZGluZyBhIDxzdHlsZT4gdGFnXG5cbi8vIGxvYWQgdGhlIHN0eWxlc1xudmFyIGNvbnRlbnQgPSByZXF1aXJlKFwiISEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2luZGV4LmpzP3NvdXJjZU1hcCEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zdHlsZS1yZXdyaXRlci5qcz9pZD1kYXRhLXYtNTU1YTBiNWMhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL21haW4udnVlXCIpO1xuaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSBjb250ZW50ID0gW1ttb2R1bGUuaWQsIGNvbnRlbnQsICcnXV07XG4vLyBhZGQgdGhlIHN0eWxlcyB0byB0aGUgRE9NXG52YXIgdXBkYXRlID0gcmVxdWlyZShcIiEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtc3R5bGUtbG9hZGVyL2FkZFN0eWxlcy5qc1wiKShjb250ZW50LCB7fSk7XG5pZihjb250ZW50LmxvY2FscykgbW9kdWxlLmV4cG9ydHMgPSBjb250ZW50LmxvY2Fscztcbi8vIEhvdCBNb2R1bGUgUmVwbGFjZW1lbnRcbmlmKG1vZHVsZS5ob3QpIHtcblx0Ly8gV2hlbiB0aGUgc3R5bGVzIGNoYW5nZSwgdXBkYXRlIHRoZSA8c3R5bGU+IHRhZ3Ncblx0aWYoIWNvbnRlbnQubG9jYWxzKSB7XG5cdFx0bW9kdWxlLmhvdC5hY2NlcHQoXCIhIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi01NTVhMGI1YyEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vbWFpbi52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi01NTVhMGI1YyEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vbWFpbi52dWVcIik7XG5cdFx0XHRpZih0eXBlb2YgbmV3Q29udGVudCA9PT0gJ3N0cmluZycpIG5ld0NvbnRlbnQgPSBbW21vZHVsZS5pZCwgbmV3Q29udGVudCwgJyddXTtcblx0XHRcdHVwZGF0ZShuZXdDb250ZW50KTtcblx0XHR9KTtcblx0fVxuXHQvLyBXaGVuIHRoZSBtb2R1bGUgaXMgZGlzcG9zZWQsIHJlbW92ZSB0aGUgPHN0eWxlPiB0YWdzXG5cdG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbigpIHsgdXBkYXRlKCk7IH0pO1xufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi92dWUtc3R5bGUtbG9hZGVyIS4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTU1NWEwYjVjIS4vfi92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vc3JjL2NvbXBvbmVudHMvdmlldy9zY2hvb2wvbWFpbi52dWVcbi8vIG1vZHVsZSBpZCA9IDUxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=")},function(module,exports,__webpack_require__){eval("// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = __webpack_require__(29);\nif(typeof content === 'string') content = [[module.i, content, '']];\n// add the styles to the DOM\nvar update = __webpack_require__(1)(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(false) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-921da930!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./video.vue\", function() {\n\t\t\tvar newContent = require(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-921da930!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./video.vue\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC92aWRlby52dWU/YzU3ZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUE2RjtBQUM3RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLGdDQUFnQyxVQUFVLEVBQUU7QUFDNUMiLCJmaWxlIjoiNTIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTkyMWRhOTMwIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi92aWRlby52dWVcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LTkyMWRhOTMwIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi92aWRlby52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi05MjFkYTkzMCEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vdmlkZW8udnVlXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vdnVlLXN0eWxlLWxvYWRlciEuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi05MjFkYTkzMCEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3NyYy9jb21wb25lbnRzL3ZpZXcvc2Nob29sL3ZpZGVvLnZ1ZVxuLy8gbW9kdWxlIGlkID0gNTJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==")},function(module,exports,__webpack_require__){eval("// style-loader: Adds some css to the DOM by adding a <style> tag\n\n// load the styles\nvar content = __webpack_require__(30);\nif(typeof content === 'string') content = [[module.i, content, '']];\n// add the styles to the DOM\nvar update = __webpack_require__(1)(content, {});\nif(content.locals) module.exports = content.locals;\n// Hot Module Replacement\nif(false) {\n\t// When the styles change, update the <style> tags\n\tif(!content.locals) {\n\t\tmodule.hot.accept(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-c91fc64e!./../../../../node_modules/less-loader/index.js!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./intro.vue\", function() {\n\t\t\tvar newContent = require(\"!!./../../../../node_modules/css-loader/index.js?sourceMap!./../../../../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-c91fc64e!./../../../../node_modules/less-loader/index.js!./../../../../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./intro.vue\");\n\t\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\t\t\tupdate(newContent);\n\t\t});\n\t}\n\t// When the module is disposed, remove the <style> tags\n\tmodule.hot.dispose(function() { update(); });\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9pbnRyby52dWU/OWE3YyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtDQUE2RjtBQUM3RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLGdDQUFnQyxVQUFVLEVBQUU7QUFDNUMiLCJmaWxlIjoiNTMuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBzdHlsZS1sb2FkZXI6IEFkZHMgc29tZSBjc3MgdG8gdGhlIERPTSBieSBhZGRpbmcgYSA8c3R5bGU+IHRhZ1xuXG4vLyBsb2FkIHRoZSBzdHlsZXNcbnZhciBjb250ZW50ID0gcmVxdWlyZShcIiEhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LWM5MWZjNjRlIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2xlc3MtbG9hZGVyL2luZGV4LmpzIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9pbnRyby52dWVcIik7XG5pZih0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIGNvbnRlbnQgPSBbW21vZHVsZS5pZCwgY29udGVudCwgJyddXTtcbi8vIGFkZCB0aGUgc3R5bGVzIHRvIHRoZSBET01cbnZhciB1cGRhdGUgPSByZXF1aXJlKFwiIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1zdHlsZS1sb2FkZXIvYWRkU3R5bGVzLmpzXCIpKGNvbnRlbnQsIHt9KTtcbmlmKGNvbnRlbnQubG9jYWxzKSBtb2R1bGUuZXhwb3J0cyA9IGNvbnRlbnQubG9jYWxzO1xuLy8gSG90IE1vZHVsZSBSZXBsYWNlbWVudFxuaWYobW9kdWxlLmhvdCkge1xuXHQvLyBXaGVuIHRoZSBzdHlsZXMgY2hhbmdlLCB1cGRhdGUgdGhlIDxzdHlsZT4gdGFnc1xuXHRpZighY29udGVudC5sb2NhbHMpIHtcblx0XHRtb2R1bGUuaG90LmFjY2VwdChcIiEhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9pbmRleC5qcz9zb3VyY2VNYXAhLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvdnVlLWxvYWRlci9saWIvc3R5bGUtcmV3cml0ZXIuanM/aWQ9ZGF0YS12LWM5MWZjNjRlIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2xlc3MtbG9hZGVyL2luZGV4LmpzIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9pbnRyby52dWVcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgbmV3Q29udGVudCA9IHJlcXVpcmUoXCIhIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvaW5kZXguanM/c291cmNlTWFwIS4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi1jOTFmYzY0ZSEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9sZXNzLWxvYWRlci9pbmRleC5qcyEuLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXN0eWxlcyZpbmRleD0wIS4vaW50cm8udnVlXCIpO1xuXHRcdFx0aWYodHlwZW9mIG5ld0NvbnRlbnQgPT09ICdzdHJpbmcnKSBuZXdDb250ZW50ID0gW1ttb2R1bGUuaWQsIG5ld0NvbnRlbnQsICcnXV07XG5cdFx0XHR1cGRhdGUobmV3Q29udGVudCk7XG5cdFx0fSk7XG5cdH1cblx0Ly8gV2hlbiB0aGUgbW9kdWxlIGlzIGRpc3Bvc2VkLCByZW1vdmUgdGhlIDxzdHlsZT4gdGFnc1xuXHRtb2R1bGUuaG90LmRpc3Bvc2UoZnVuY3Rpb24oKSB7IHVwZGF0ZSgpOyB9KTtcbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vdnVlLXN0eWxlLWxvYWRlciEuL34vY3NzLWxvYWRlcj9zb3VyY2VNYXAhLi9+L3Z1ZS1sb2FkZXIvbGliL3N0eWxlLXJld3JpdGVyLmpzP2lkPWRhdGEtdi1jOTFmYzY0ZSEuL34vbGVzcy1sb2FkZXIhLi9+L3Z1ZS1sb2FkZXIvbGliL3NlbGVjdG9yLmpzP3R5cGU9c3R5bGVzJmluZGV4PTAhLi9zcmMvY29tcG9uZW50cy92aWV3L3NjaG9vbC9pbnRyby52dWVcbi8vIG1vZHVsZSBpZCA9IDUzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=")},function(module,exports){eval('var g;\r\n\r\n// This works in non-strict mode\r\ng = (function() { return this; })();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function("return this")() || (1,eval)("this");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === "object")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it\'s\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vKHdlYnBhY2spL2J1aWxkaW4vZ2xvYmFsLmpzPzM2OTgiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FBRUE7QUFDQSxpQkFBaUIsYUFBYSxFQUFFOztBQUVoQztBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDRDQUE0Qzs7QUFFNUMiLCJmaWxlIjoiNTQuanMiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZztcclxuXHJcbi8vIFRoaXMgd29ya3MgaW4gbm9uLXN0cmljdCBtb2RlXHJcbmcgPSAoZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSgpO1xyXG5cclxudHJ5IHtcclxuXHQvLyBUaGlzIHdvcmtzIGlmIGV2YWwgaXMgYWxsb3dlZCAoc2VlIENTUClcclxuXHRnID0gZyB8fCBGdW5jdGlvbihcInJldHVybiB0aGlzXCIpKCkgfHwgKDEsZXZhbCkoXCJ0aGlzXCIpO1xyXG59IGNhdGNoKGUpIHtcclxuXHQvLyBUaGlzIHdvcmtzIGlmIHRoZSB3aW5kb3cgcmVmZXJlbmNlIGlzIGF2YWlsYWJsZVxyXG5cdGlmKHR5cGVvZiB3aW5kb3cgPT09IFwib2JqZWN0XCIpXHJcblx0XHRnID0gd2luZG93O1xyXG59XHJcblxyXG4vLyBnIGNhbiBzdGlsbCBiZSB1bmRlZmluZWQsIGJ1dCBub3RoaW5nIHRvIGRvIGFib3V0IGl0Li4uXHJcbi8vIFdlIHJldHVybiB1bmRlZmluZWQsIGluc3RlYWQgb2Ygbm90aGluZyBoZXJlLCBzbyBpdCdzXHJcbi8vIGVhc2llciB0byBoYW5kbGUgdGhpcyBjYXNlLiBpZighZ2xvYmFsKSB7IC4uLn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZztcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gKHdlYnBhY2spL2J1aWxkaW4vZ2xvYmFsLmpzXG4vLyBtb2R1bGUgaWQgPSA1NFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9')},function(module,exports,__webpack_require__){"use strict";eval("/* WEBPACK VAR INJECTION */(function(__dirname) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_vue__ = __webpack_require__(12);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_vue___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_vue__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__App_vue__ = __webpack_require__(5);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__App_vue___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__App_vue__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_vue_router__ = __webpack_require__(11);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_vue_router___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_vue_router__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_vue_resource__ = __webpack_require__(10);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_vue_resource___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_vue_resource__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_less__ = __webpack_require__(4);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_less___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_less__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__components_view_school_intro_vue__ = __webpack_require__(7);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__components_view_school_intro_vue___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5__components_view_school_intro_vue__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__components_view_school_consultant_vue__ = __webpack_require__(6);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__components_view_school_consultant_vue___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6__components_view_school_consultant_vue__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__components_view_school_video_vue__ = __webpack_require__(9);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__components_view_school_video_vue___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7__components_view_school_video_vue__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__components_view_school_question_vue__ = __webpack_require__(8);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__components_view_school_question_vue___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8__components_view_school_question_vue__);\n\n\n\n\n\n\n// 开启debug模式\n__WEBPACK_IMPORTED_MODULE_0_vue___default.a.config.debug = true;\n\n__WEBPACK_IMPORTED_MODULE_0_vue___default.a.use(__WEBPACK_IMPORTED_MODULE_2_vue_router___default.a);\n__WEBPACK_IMPORTED_MODULE_0_vue___default.a.use(__WEBPACK_IMPORTED_MODULE_3_vue_resource___default.a);\n\n// 引入组件\n\n\n\n\n\n// 引入样式\n__webpack_require__(3);\n\n// 创建路由实例\n// 配置路由规则\nvar router = new __WEBPACK_IMPORTED_MODULE_2_vue_router___default.a({\n    mode: 'history',\n    base: __dirname,\n    routes: [{\n        path: '/',\n        component: __WEBPACK_IMPORTED_MODULE_5__components_view_school_intro_vue___default.a\n    }, {\n        path: '/schoolIntro',\n        component: __WEBPACK_IMPORTED_MODULE_5__components_view_school_intro_vue___default.a\n    }, {\n        path: '/schoolIntroConsultant',\n        component: __WEBPACK_IMPORTED_MODULE_6__components_view_school_consultant_vue___default.a\n    }, {\n        path: '/schoolIntroVideo',\n        component: __WEBPACK_IMPORTED_MODULE_7__components_view_school_video_vue___default.a\n    }, {\n        path: '/schoolIntroQuestion',\n        component: __WEBPACK_IMPORTED_MODULE_8__components_view_school_question_vue___default.a\n    }]\n});\n\nvar app = new __WEBPACK_IMPORTED_MODULE_0_vue___default.a({\n    router: router,\n    render: function render(h) {\n        return h(__WEBPACK_IMPORTED_MODULE_1__App_vue___default.a);\n    }\n}).$mount('#app');\n/* WEBPACK VAR INJECTION */}.call(exports, \"/\"))\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvZW50cnkuanM/OGQyNCJdLCJuYW1lcyI6WyJWdWUiLCJjb25maWciLCJkZWJ1ZyIsInVzZSIsInJlcXVpcmUiLCJyb3V0ZXIiLCJtb2RlIiwiYmFzZSIsIl9fZGlybmFtZSIsInJvdXRlcyIsInBhdGgiLCJjb21wb25lbnQiLCJzY2hvb2xJbnRybyIsInNjaG9vbEludHJvQ29uc3VsdGFudCIsInNjaG9vbEludHJvVmlkZW8iLCJzY2hvb2xJbnRyb1F1ZXN0aW9uIiwiYXBwIiwicmVuZGVyIiwiaCIsIiRtb3VudCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJDQUFBQSxDQUFJQyxNQUFKLENBQVdDLEtBQVgsR0FBbUIsSUFBbkI7O0FBRUEsMkNBQUFGLENBQUlHLEdBQUosQ0FBUSxrREFBUjtBQUNBLDJDQUFBSCxDQUFJRyxHQUFKLENBQVEsb0RBQVI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFBQyxDQUFRLENBQVI7O0FBRUE7QUFDQTtBQUNBLElBQU1DLFNBQVMsSUFBSSxrREFBSixDQUFjO0FBQ3pCQyxVQUFNLFNBRG1CO0FBRXpCQyxVQUFNQyxTQUZtQjtBQUd6QkMsWUFBUSxDQUFDO0FBQ0xDLGNBQU0sR0FERDtBQUVMQyxtQkFBVyx5RUFBQUM7QUFGTixLQUFELEVBR0w7QUFDQ0YsY0FBTSxjQURQO0FBRUNDLG1CQUFXLHlFQUFBQztBQUZaLEtBSEssRUFNTDtBQUNDRixjQUFNLHdCQURQO0FBRUNDLG1CQUFXLDhFQUFBRTtBQUZaLEtBTkssRUFTTDtBQUNDSCxjQUFNLG1CQURQO0FBRUNDLG1CQUFXLHlFQUFBRztBQUZaLEtBVEssRUFZTDtBQUNDSixjQUFNLHNCQURQO0FBRUNDLG1CQUFXLDRFQUFBSTtBQUZaLEtBWks7QUFIaUIsQ0FBZCxDQUFmOztBQXFCQSxJQUFNQyxNQUFNLElBQUksMkNBQUosQ0FBUTtBQUNoQlgsWUFBUUEsTUFEUTtBQUVoQlksWUFBUTtBQUFBLGVBQUtDLEVBQUUsZ0RBQUYsQ0FBTDtBQUFBO0FBRlEsQ0FBUixFQUdUQyxNQUhTLENBR0YsTUFIRSxDQUFaLEMiLCJmaWxlIjoiNTUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgVnVlIGZyb20gJ3Z1ZSc7XG5pbXBvcnQgQXBwIGZyb20gJy4vQXBwLnZ1ZSc7XG5pbXBvcnQgVnVlUm91dGVyIGZyb20gJ3Z1ZS1yb3V0ZXInO1xuaW1wb3J0IFZ1ZVJlc291cmNlIGZyb20gJ3Z1ZS1yZXNvdXJjZSc7XG5pbXBvcnQgbGVzcyBmcm9tICdsZXNzJztcblxuLy8g5byA5ZCvZGVidWfmqKHlvI9cblZ1ZS5jb25maWcuZGVidWcgPSB0cnVlO1xuXG5WdWUudXNlKFZ1ZVJvdXRlcik7XG5WdWUudXNlKFZ1ZVJlc291cmNlKTtcblxuLy8g5byV5YWl57uE5Lu2XG5pbXBvcnQgc2Nob29sSW50cm8gZnJvbSAnLi9jb21wb25lbnRzL3ZpZXcvc2Nob29sL2ludHJvLnZ1ZSc7XG5pbXBvcnQgc2Nob29sSW50cm9Db25zdWx0YW50IGZyb20gJy4vY29tcG9uZW50cy92aWV3L3NjaG9vbC9jb25zdWx0YW50LnZ1ZSc7XG5pbXBvcnQgc2Nob29sSW50cm9WaWRlbyBmcm9tICcuL2NvbXBvbmVudHMvdmlldy9zY2hvb2wvdmlkZW8udnVlJztcbmltcG9ydCBzY2hvb2xJbnRyb1F1ZXN0aW9uIGZyb20gJy4vY29tcG9uZW50cy92aWV3L3NjaG9vbC9xdWVzdGlvbi52dWUnO1xuXG4vLyDlvJXlhaXmoLflvI9cbnJlcXVpcmUoJy4vYXNzZXRzL2xlc3Mvc2Nob29sX2ludHJvLmxlc3MnKTtcblxuLy8g5Yib5bu66Lev55Sx5a6e5L6LXG4vLyDphY3nva7ot6/nlLHop4TliJlcbmNvbnN0IHJvdXRlciA9IG5ldyBWdWVSb3V0ZXIoe1xuICAgIG1vZGU6ICdoaXN0b3J5JyxcbiAgICBiYXNlOiBfX2Rpcm5hbWUsXG4gICAgcm91dGVzOiBbe1xuICAgICAgICBwYXRoOiAnLycsXG4gICAgICAgIGNvbXBvbmVudDogc2Nob29sSW50cm9cbiAgICB9LCB7XG4gICAgICAgIHBhdGg6ICcvc2Nob29sSW50cm8nLFxuICAgICAgICBjb21wb25lbnQ6IHNjaG9vbEludHJvXG4gICAgfSwge1xuICAgICAgICBwYXRoOiAnL3NjaG9vbEludHJvQ29uc3VsdGFudCcsXG4gICAgICAgIGNvbXBvbmVudDogc2Nob29sSW50cm9Db25zdWx0YW50XG4gICAgfSwge1xuICAgICAgICBwYXRoOiAnL3NjaG9vbEludHJvVmlkZW8nLFxuICAgICAgICBjb21wb25lbnQ6IHNjaG9vbEludHJvVmlkZW9cbiAgICB9LCB7XG4gICAgICAgIHBhdGg6ICcvc2Nob29sSW50cm9RdWVzdGlvbicsXG4gICAgICAgIGNvbXBvbmVudDogc2Nob29sSW50cm9RdWVzdGlvblxuICAgIH1dXG59KTtcblxuY29uc3QgYXBwID0gbmV3IFZ1ZSh7XG4gICAgcm91dGVyOiByb3V0ZXIsXG4gICAgcmVuZGVyOiBoID0+IGgoQXBwKVxufSkuJG1vdW50KCcjYXBwJyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvZW50cnkuanMiXSwic291cmNlUm9vdCI6IiJ9");
}]);