@preply/ds-docs 0.4.3-beta.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/README.md +92 -0
- package/config/main.js +23 -0
- package/config/manager-head.html +1 -0
- package/config/manager.js +16 -0
- package/config/packages.js +21 -0
- package/config/preview-head.html +1 -0
- package/config/preview.js +16 -0
- package/config/webpack.config.js +97 -0
- package/dist/0.338f6ec8c298c14e9987.manager.bundle.js +1 -0
- package/dist/0.3fa9c511.iframe.bundle.js +1 -0
- package/dist/10.cbab8b16.iframe.bundle.js +1 -0
- package/dist/11.eb6590ee.iframe.bundle.js +1 -0
- package/dist/12.14fcbdc9.iframe.bundle.js +1 -0
- package/dist/4.ca91571aa289a44fd646.manager.bundle.js +2 -0
- package/dist/4.ca91571aa289a44fd646.manager.bundle.js.LICENSE.txt +8 -0
- package/dist/5.09384b194ae4afd5b83d.manager.bundle.js +1 -0
- package/dist/6.32fc62c8a6ce2df04956.manager.bundle.js +2 -0
- package/dist/6.32fc62c8a6ce2df04956.manager.bundle.js.LICENSE.txt +12 -0
- package/dist/7.caafbbb780553290f515.manager.bundle.js +1 -0
- package/dist/8.66293b7ba6e3ca90f9ef.manager.bundle.js +1 -0
- package/dist/9.50d8be07.iframe.bundle.js +1 -0
- package/dist/docs-pages/docs/pages/00.welcome/static/andre.jpg +0 -0
- package/dist/docs-pages/docs/pages/00.welcome/static/designers.svg +5 -0
- package/dist/docs-pages/docs/pages/00.welcome/static/developers.svg +5 -0
- package/dist/docs-pages/docs/pages/00.welcome/static/header.png +0 -0
- package/dist/docs-pages/docs/pages/00.welcome/static/vadim.jpg +0 -0
- package/dist/docs-pages/docs/pages/04.contributing/static/flowchart.png +0 -0
- package/dist/favicon.ico +0 -0
- package/dist/global/docs/static/favicon.svg +4 -0
- package/dist/global/docs/static/logo.svg +1 -0
- package/dist/iframe.html +138 -0
- package/dist/index.html +55 -0
- package/dist/main.515f4f3f1dbf7ce958bc.manager.bundle.js +1 -0
- package/dist/main~493df0b3.c053cefd.iframe.bundle.js +1 -0
- package/dist/runtime~main.b422f1cd6ad7b4837a59.manager.bundle.js +1 -0
- package/dist/runtime~main.b9288cbc.iframe.bundle.js +1 -0
- package/dist/vendors~main.a298dbf4b4228db7a7c0.manager.bundle.js +2 -0
- package/dist/vendors~main.a298dbf4b4228db7a7c0.manager.bundle.js.LICENSE.txt +82 -0
- package/dist/vendors~main~253ae210.2cd1feec.iframe.bundle.js +1 -0
- package/dist/vendors~main~4134d62c.806278b4.iframe.bundle.js +1 -0
- package/dist/vendors~main~678f84af.83492059.iframe.bundle.js +1 -0
- package/dist/vendors~main~a353122d.312fbc2d.iframe.bundle.js +1 -0
- package/dist/vendors~main~bdc480fb.2ad5d7bf.iframe.bundle.js +1 -0
- package/dist/vendors~main~d88e64ba.a117b568.iframe.bundle.js +1 -0
- package/dist/web-lib/src/components/Avatar/docs/static/avatar.png +0 -0
- package/docs/static/favicon.svg +4 -0
- package/docs/static/logo.svg +1 -0
- package/package.json +47 -0
- package/scripts/copy-metadata-and-assets.js +87 -0
- package/scripts/copy-statics.js +10 -0
- package/tsconfig.json +3 -0
- package/utils/globs.js +16 -0
- package/utils/statics.js +30 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(window.webpackJsonp=window.webpackJsonp||[]).push([[11],{1005:function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OverlayScrollbarsComponent", function() { return OverlayScrollbarsComponent; });\n/* harmony import */ var core_js_modules_es_regexp_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(573);\n/* harmony import */ var core_js_modules_es_regexp_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_regexp_constructor_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var core_js_modules_es_regexp_exec_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30);\n/* harmony import */ var core_js_modules_es_regexp_exec_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_regexp_exec_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var core_js_modules_es_regexp_to_string_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(118);\n/* harmony import */ var core_js_modules_es_regexp_to_string_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_regexp_to_string_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(47);\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var core_js_modules_es_array_join_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(29);\n/* harmony import */ var core_js_modules_es_array_join_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_join_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var core_js_modules_es_array_filter_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(51);\n/* harmony import */ var core_js_modules_es_array_filter_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_filter_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var core_js_modules_es_string_split_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(67);\n/* harmony import */ var core_js_modules_es_string_split_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_split_js__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var core_js_modules_es_string_match_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(116);\n/* harmony import */ var core_js_modules_es_string_match_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_match_js__WEBPACK_IMPORTED_MODULE_7__);\n/* harmony import */ var core_js_modules_es_array_concat_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(21);\n/* harmony import */ var core_js_modules_es_array_concat_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_concat_js__WEBPACK_IMPORTED_MODULE_8__);\n/* harmony import */ var core_js_modules_es_object_keys_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(18);\n/* harmony import */ var core_js_modules_es_object_keys_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_object_keys_js__WEBPACK_IMPORTED_MODULE_9__);\n/* harmony import */ var core_js_modules_es_symbol_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(4);\n/* harmony import */ var core_js_modules_es_symbol_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_symbol_js__WEBPACK_IMPORTED_MODULE_10__);\n/* harmony import */ var core_js_modules_es_object_assign_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(8);\n/* harmony import */ var core_js_modules_es_object_assign_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_object_assign_js__WEBPACK_IMPORTED_MODULE_11__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(1);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_12__);\n/* harmony import */ var overlayscrollbars__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(1084);\n/* harmony import */ var overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(overlayscrollbars__WEBPACK_IMPORTED_MODULE_13__);\n\n\n\n\n\n\n\n\n\n\n\n\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n\n\n\n/**\n * Using overlayscrollbars-react component results use the esm modules\n * which doesn\'t go through babel leading to IE 11 uncompatibility\n * A PR is submitted that may fix this:\n * https://github.com/KingSora/OverlayScrollbars/pull/218\n * */\nvar OverlayScrollbarsComponent = function OverlayScrollbarsComponent(_ref) {\n var _ref$options = _ref.options,\n options = _ref$options === void 0 ? {} : _ref$options,\n extensions = _ref.extensions,\n className = _ref.className,\n children = _ref.children,\n rest = _objectWithoutProperties(_ref, ["options", "extensions", "className", "children"]);\n\n var osTargetRef = react__WEBPACK_IMPORTED_MODULE_12___default.a.useRef();\n var osInstance = react__WEBPACK_IMPORTED_MODULE_12___default.a.useRef();\n react__WEBPACK_IMPORTED_MODULE_12___default.a.useEffect(function () {\n osInstance.current = overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default()(osTargetRef.current, options, extensions);\n mergeHostClassNames(osInstance.current, className);\n return function () {\n if (overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default.a.valid(osInstance.current)) {\n osInstance.current.destroy();\n osInstance.current = null;\n }\n };\n }, []);\n react__WEBPACK_IMPORTED_MODULE_12___default.a.useEffect(function () {\n if (overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default.a.valid(osInstance.current)) {\n osInstance.current.options(options);\n }\n }, [options]);\n react__WEBPACK_IMPORTED_MODULE_12___default.a.useEffect(function () {\n if (overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default.a.valid(osInstance.current)) {\n mergeHostClassNames(osInstance.current, className);\n }\n }, [className]);\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", _extends({\n className: "os-host"\n }, rest, {\n ref: osTargetRef\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-resize-observer-host"\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-padding"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-viewport"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-content"\n }, children))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar os-scrollbar-horizontal "\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-track"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-handle"\n }))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar os-scrollbar-vertical"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-track"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-handle"\n }))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-corner"\n }));\n};\nOverlayScrollbarsComponent.displayName = "OverlayScrollbarsComponent";\n\nfunction mergeHostClassNames(osInstance, className) {\n if (overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default.a.valid(osInstance)) {\n var _osInstance$getElemen = osInstance.getElements(),\n host = _osInstance$getElemen.host;\n\n var regex = new RegExp("(^os-host([-_].+|)$)|".concat(osInstance.options().className.replace(/\\s/g, \'$|\'), "$"), \'g\');\n var osClassNames = host.className.split(\' \').filter(function (name) {\n return name.match(regex);\n }).join(\' \');\n host.className = "".concat(osClassNames, " ").concat(className || \'\');\n }\n}\n\n/* harmony default export */ __webpack_exports__["default"] = (OverlayScrollbarsComponent);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQHN0b3J5Ym9vay9jb21wb25lbnRzL2Rpc3QvZXNtL1Njcm9sbEFyZWEvT3ZlcmxheVNjcm9sbGJhcnMuanM/NjA3NSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBa0Q7QUFDUDtBQUNLO0FBQ0Y7QUFDSjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0Q7QUFDTDtBQUNPOztBQUU3QyxxQkFBcUIsZ0RBQWdELGdCQUFnQixzQkFBc0IsT0FBTywyQkFBMkIsMEJBQTBCLHlEQUF5RCwyQkFBMkIsRUFBRSxFQUFFLEVBQUUsZUFBZSxHQUFHLHdDQUF3Qzs7QUFFM1QscURBQXFELCtCQUErQiw4REFBOEQsWUFBWSxvQ0FBb0MsNkRBQTZELFlBQVksNkJBQTZCLE9BQU8sMkJBQTJCLDBDQUEwQyx3RUFBd0UsMkJBQTJCLEVBQUUsRUFBRSxlQUFlOztBQUUxZSwwREFBMEQsK0JBQStCLGlCQUFpQixzQ0FBc0MsWUFBWSxZQUFZLHVCQUF1QixPQUFPLHFCQUFxQiwwQ0FBMEMsMkJBQTJCLEVBQUUsZUFBZTs7QUFFdlI7QUFDd0I7O0FBRWxEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQSw0Q0FBNEM7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0JBQW9CLDZDQUFLO0FBQ3pCLG1CQUFtQiw2Q0FBSztBQUN4QixFQUFFLDZDQUFLO0FBQ1AseUJBQXlCLHlEQUFpQjtBQUMxQztBQUNBO0FBQ0EsVUFBVSx5REFBaUI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRSw2Q0FBSztBQUNQLFFBQVEseURBQWlCO0FBQ3pCO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRSw2Q0FBSztBQUNQLFFBQVEseURBQWlCO0FBQ3pCO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsc0JBQXNCLDZDQUFLO0FBQzNCO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRyxnQkFBZ0IsNkNBQUs7QUFDeEI7QUFDQSxHQUFHLGdCQUFnQiw2Q0FBSztBQUN4QjtBQUNBLEdBQUcsZUFBZSw2Q0FBSztBQUN2QjtBQUNBLEdBQUcsZUFBZSw2Q0FBSztBQUN2QjtBQUNBLEdBQUcsNEJBQTRCLDZDQUFLO0FBQ3BDO0FBQ0EsR0FBRyxlQUFlLDZDQUFLO0FBQ3ZCO0FBQ0EsR0FBRyxlQUFlLDZDQUFLO0FBQ3ZCO0FBQ0EsR0FBRyxrQkFBa0IsNkNBQUs7QUFDMUI7QUFDQSxHQUFHLGVBQWUsNkNBQUs7QUFDdkI7QUFDQSxHQUFHLGVBQWUsNkNBQUs7QUFDdkI7QUFDQSxHQUFHLGtCQUFrQiw2Q0FBSztBQUMxQjtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0EsTUFBTSx5REFBaUI7QUFDdkI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVlLHlGQUEwQiIsImZpbGUiOiIxMDA1LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnJlZ2V4cC5jb25zdHJ1Y3Rvci5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnJlZ2V4cC5leGVjLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMucmVnZXhwLnRvLXN0cmluZy5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5yZXBsYWNlLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMuYXJyYXkuam9pbi5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5LmZpbHRlci5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5zcGxpdC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5tYXRjaC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5LmNvbmNhdC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLm9iamVjdC5rZXlzLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMuc3ltYm9sLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMub2JqZWN0LmFzc2lnbi5qc1wiO1xuXG5mdW5jdGlvbiBfZXh0ZW5kcygpIHsgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9OyByZXR1cm4gX2V4dGVuZHMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfVxuXG5mdW5jdGlvbiBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMoc291cmNlLCBleGNsdWRlZCkgeyBpZiAoc291cmNlID09IG51bGwpIHJldHVybiB7fTsgdmFyIHRhcmdldCA9IF9vYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlKHNvdXJjZSwgZXhjbHVkZWQpOyB2YXIga2V5LCBpOyBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykgeyB2YXIgc291cmNlU3ltYm9sS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoc291cmNlKTsgZm9yIChpID0gMDsgaSA8IHNvdXJjZVN5bWJvbEtleXMubGVuZ3RoOyBpKyspIHsga2V5ID0gc291cmNlU3ltYm9sS2V5c1tpXTsgaWYgKGV4Y2x1ZGVkLmluZGV4T2Yoa2V5KSA+PSAwKSBjb250aW51ZTsgaWYgKCFPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwoc291cmNlLCBrZXkpKSBjb250aW51ZTsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IHJldHVybiB0YXJnZXQ7IH1cblxuZnVuY3Rpb24gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2Uoc291cmNlLCBleGNsdWRlZCkgeyBpZiAoc291cmNlID09IG51bGwpIHJldHVybiB7fTsgdmFyIHRhcmdldCA9IHt9OyB2YXIgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7IHZhciBrZXksIGk7IGZvciAoaSA9IDA7IGkgPCBzb3VyY2VLZXlzLmxlbmd0aDsgaSsrKSB7IGtleSA9IHNvdXJjZUtleXNbaV07IGlmIChleGNsdWRlZC5pbmRleE9mKGtleSkgPj0gMCkgY29udGludWU7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gcmV0dXJuIHRhcmdldDsgfVxuXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IE92ZXJsYXlTY3JvbGxiYXJzIGZyb20gJ292ZXJsYXlzY3JvbGxiYXJzJztcblxuLyoqXG4gKiBVc2luZyBvdmVybGF5c2Nyb2xsYmFycy1yZWFjdCBjb21wb25lbnQgcmVzdWx0cyB1c2UgdGhlIGVzbSBtb2R1bGVzXG4gKiB3aGljaCBkb2Vzbid0IGdvIHRocm91Z2ggYmFiZWwgbGVhZGluZyB0byBJRSAxMSB1bmNvbXBhdGliaWxpdHlcbiAqIEEgUFIgaXMgc3VibWl0dGVkIHRoYXQgbWF5IGZpeCB0aGlzOlxuICogaHR0cHM6Ly9naXRodWIuY29tL0tpbmdTb3JhL092ZXJsYXlTY3JvbGxiYXJzL3B1bGwvMjE4XG4gKiAqL1xuZXhwb3J0IHZhciBPdmVybGF5U2Nyb2xsYmFyc0NvbXBvbmVudCA9IGZ1bmN0aW9uIE92ZXJsYXlTY3JvbGxiYXJzQ29tcG9uZW50KF9yZWYpIHtcbiAgdmFyIF9yZWYkb3B0aW9ucyA9IF9yZWYub3B0aW9ucyxcbiAgICAgIG9wdGlvbnMgPSBfcmVmJG9wdGlvbnMgPT09IHZvaWQgMCA/IHt9IDogX3JlZiRvcHRpb25zLFxuICAgICAgZXh0ZW5zaW9ucyA9IF9yZWYuZXh0ZW5zaW9ucyxcbiAgICAgIGNsYXNzTmFtZSA9IF9yZWYuY2xhc3NOYW1lLFxuICAgICAgY2hpbGRyZW4gPSBfcmVmLmNoaWxkcmVuLFxuICAgICAgcmVzdCA9IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyhfcmVmLCBbXCJvcHRpb25zXCIsIFwiZXh0ZW5zaW9uc1wiLCBcImNsYXNzTmFtZVwiLCBcImNoaWxkcmVuXCJdKTtcblxuICB2YXIgb3NUYXJnZXRSZWYgPSBSZWFjdC51c2VSZWYoKTtcbiAgdmFyIG9zSW5zdGFuY2UgPSBSZWFjdC51c2VSZWYoKTtcbiAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBvc0luc3RhbmNlLmN1cnJlbnQgPSBPdmVybGF5U2Nyb2xsYmFycyhvc1RhcmdldFJlZi5jdXJyZW50LCBvcHRpb25zLCBleHRlbnNpb25zKTtcbiAgICBtZXJnZUhvc3RDbGFzc05hbWVzKG9zSW5zdGFuY2UuY3VycmVudCwgY2xhc3NOYW1lKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKE92ZXJsYXlTY3JvbGxiYXJzLnZhbGlkKG9zSW5zdGFuY2UuY3VycmVudCkpIHtcbiAgICAgICAgb3NJbnN0YW5jZS5jdXJyZW50LmRlc3Ryb3koKTtcbiAgICAgICAgb3NJbnN0YW5jZS5jdXJyZW50ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9O1xuICB9LCBbXSk7XG4gIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKE92ZXJsYXlTY3JvbGxiYXJzLnZhbGlkKG9zSW5zdGFuY2UuY3VycmVudCkpIHtcbiAgICAgIG9zSW5zdGFuY2UuY3VycmVudC5vcHRpb25zKG9wdGlvbnMpO1xuICAgIH1cbiAgfSwgW29wdGlvbnNdKTtcbiAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoT3ZlcmxheVNjcm9sbGJhcnMudmFsaWQob3NJbnN0YW5jZS5jdXJyZW50KSkge1xuICAgICAgbWVyZ2VIb3N0Q2xhc3NOYW1lcyhvc0luc3RhbmNlLmN1cnJlbnQsIGNsYXNzTmFtZSk7XG4gICAgfVxuICB9LCBbY2xhc3NOYW1lXSk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCBfZXh0ZW5kcyh7XG4gICAgY2xhc3NOYW1lOiBcIm9zLWhvc3RcIlxuICB9LCByZXN0LCB7XG4gICAgcmVmOiBvc1RhcmdldFJlZlxuICB9KSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1yZXNpemUtb2JzZXJ2ZXItaG9zdFwiXG4gIH0pLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIm9zLXBhZGRpbmdcIlxuICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIm9zLXZpZXdwb3J0XCJcbiAgfSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1jb250ZW50XCJcbiAgfSwgY2hpbGRyZW4pKSksIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICBjbGFzc05hbWU6IFwib3Mtc2Nyb2xsYmFyIG9zLXNjcm9sbGJhci1ob3Jpem9udGFsIFwiXG4gIH0sIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICBjbGFzc05hbWU6IFwib3Mtc2Nyb2xsYmFyLXRyYWNrXCJcbiAgfSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1zY3JvbGxiYXItaGFuZGxlXCJcbiAgfSkpKSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1zY3JvbGxiYXIgb3Mtc2Nyb2xsYmFyLXZlcnRpY2FsXCJcbiAgfSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1zY3JvbGxiYXItdHJhY2tcIlxuICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIm9zLXNjcm9sbGJhci1oYW5kbGVcIlxuICB9KSkpLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIm9zLXNjcm9sbGJhci1jb3JuZXJcIlxuICB9KSk7XG59O1xuT3ZlcmxheVNjcm9sbGJhcnNDb21wb25lbnQuZGlzcGxheU5hbWUgPSBcIk92ZXJsYXlTY3JvbGxiYXJzQ29tcG9uZW50XCI7XG5cbmZ1bmN0aW9uIG1lcmdlSG9zdENsYXNzTmFtZXMob3NJbnN0YW5jZSwgY2xhc3NOYW1lKSB7XG4gIGlmIChPdmVybGF5U2Nyb2xsYmFycy52YWxpZChvc0luc3RhbmNlKSkge1xuICAgIHZhciBfb3NJbnN0YW5jZSRnZXRFbGVtZW4gPSBvc0luc3RhbmNlLmdldEVsZW1lbnRzKCksXG4gICAgICAgIGhvc3QgPSBfb3NJbnN0YW5jZSRnZXRFbGVtZW4uaG9zdDtcblxuICAgIHZhciByZWdleCA9IG5ldyBSZWdFeHAoXCIoXm9zLWhvc3QoWy1fXS4rfCkkKXxcIi5jb25jYXQob3NJbnN0YW5jZS5vcHRpb25zKCkuY2xhc3NOYW1lLnJlcGxhY2UoL1xccy9nLCAnJHwnKSwgXCIkXCIpLCAnZycpO1xuICAgIHZhciBvc0NsYXNzTmFtZXMgPSBob3N0LmNsYXNzTmFtZS5zcGxpdCgnICcpLmZpbHRlcihmdW5jdGlvbiAobmFtZSkge1xuICAgICAgcmV0dXJuIG5hbWUubWF0Y2gocmVnZXgpO1xuICAgIH0pLmpvaW4oJyAnKTtcbiAgICBob3N0LmNsYXNzTmFtZSA9IFwiXCIuY29uY2F0KG9zQ2xhc3NOYW1lcywgXCIgXCIpLmNvbmNhdChjbGFzc05hbWUgfHwgJycpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE92ZXJsYXlTY3JvbGxiYXJzQ29tcG9uZW50OyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1005\n')},1084:function(module,exports,__webpack_require__){eval("var __WEBPACK_AMD_DEFINE_RESULT__;/*!\r\n * OverlayScrollbars\r\n * https://github.com/KingSora/OverlayScrollbars\r\n *\r\n * Version: 1.13.0\r\n *\r\n * Copyright KingSora | Rene Haas.\r\n * https://github.com/KingSora\r\n *\r\n * Released under the MIT license.\r\n * Date: 02.08.2020\r\n */\r\n\r\n(function (global, factory) {\r\n if (true)\r\n !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () { return factory(global, global.document, undefined); }).call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\r\n else {}\r\n}(typeof window !== 'undefined' ? window : this,\r\n function (window, document, undefined) {\r\n 'use strict';\r\n var PLUGINNAME = 'OverlayScrollbars';\r\n var TYPES = {\r\n o: 'object',\r\n f: 'function',\r\n a: 'array',\r\n s: 'string',\r\n b: 'boolean',\r\n n: 'number',\r\n u: 'undefined',\r\n z: 'null'\r\n //d : 'date',\r\n //e : 'error',\r\n //r : 'regexp',\r\n //y : 'symbol'\r\n };\r\n var LEXICON = {\r\n c: 'class',\r\n s: 'style',\r\n i: 'id',\r\n l: 'length',\r\n p: 'prototype',\r\n ti: 'tabindex',\r\n oH: 'offsetHeight',\r\n cH: 'clientHeight',\r\n sH: 'scrollHeight',\r\n oW: 'offsetWidth',\r\n cW: 'clientWidth',\r\n sW: 'scrollWidth',\r\n hOP: 'hasOwnProperty',\r\n bCR: 'getBoundingClientRect'\r\n };\r\n var VENDORS = (function () {\r\n //https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix\r\n var jsCache = {};\r\n var cssCache = {};\r\n var cssPrefixes = ['-webkit-', '-moz-', '-o-', '-ms-'];\r\n var jsPrefixes = ['WebKit', 'Moz', 'O', 'MS'];\r\n function firstLetterToUpper(str) {\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n }\r\n\r\n return {\r\n _cssPrefixes: cssPrefixes,\r\n _jsPrefixes: jsPrefixes,\r\n _cssProperty: function (name) {\r\n var result = cssCache[name];\r\n\r\n if (cssCache[LEXICON.hOP](name))\r\n return result;\r\n\r\n var uppercasedName = firstLetterToUpper(name);\r\n var elmStyle = document.createElement('div')[LEXICON.s];\r\n var resultPossibilities;\r\n var i = 0;\r\n var v;\r\n var currVendorWithoutDashes;\r\n\r\n for (; i < cssPrefixes.length; i++) {\r\n currVendorWithoutDashes = cssPrefixes[i].replace(/-/g, '');\r\n resultPossibilities = [\r\n name, //transition\r\n cssPrefixes[i] + name, //-webkit-transition\r\n currVendorWithoutDashes + uppercasedName, //webkitTransition\r\n firstLetterToUpper(currVendorWithoutDashes) + uppercasedName //WebkitTransition\r\n ];\r\n for (v = 0; v < resultPossibilities[LEXICON.l]; v++) {\r\n if (elmStyle[resultPossibilities[v]] !== undefined) {\r\n result = resultPossibilities[v];\r\n break;\r\n }\r\n }\r\n }\r\n\r\n cssCache[name] = result;\r\n return result;\r\n },\r\n _cssPropertyValue: function (property, values, suffix) {\r\n var name = property + ' ' + values;\r\n var result = cssCache[name];\r\n\r\n if (cssCache[LEXICON.hOP](name))\r\n return result;\r\n\r\n var dummyStyle = document.createElement('div')[LEXICON.s];\r\n var possbleValues = values.split(' ');\r\n var preparedSuffix = suffix || '';\r\n var i = 0;\r\n var v = -1;\r\n var prop;\r\n\r\n for (; i < possbleValues[LEXICON.l]; i++) {\r\n for (; v < VENDORS._cssPrefixes[LEXICON.l]; v++) {\r\n prop = v < 0 ? possbleValues[i] : VENDORS._cssPrefixes[v] + possbleValues[i];\r\n dummyStyle.cssText = property + ':' + prop + preparedSuffix;\r\n if (dummyStyle[LEXICON.l]) {\r\n result = prop;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n cssCache[name] = result;\r\n return result;\r\n },\r\n _jsAPI: function (name, isInterface, fallback) {\r\n var i = 0;\r\n var result = jsCache[name];\r\n\r\n if (!jsCache[LEXICON.hOP](name)) {\r\n result = window[name];\r\n for (; i < jsPrefixes[LEXICON.l]; i++)\r\n result = result || window[(isInterface ? jsPrefixes[i] : jsPrefixes[i].toLowerCase()) + firstLetterToUpper(name)];\r\n jsCache[name] = result;\r\n }\r\n return result || fallback;\r\n }\r\n }\r\n })();\r\n var COMPATIBILITY = (function () {\r\n function windowSize(x) {\r\n return x ? window.innerWidth || document.documentElement[LEXICON.cW] || document.body[LEXICON.cW] : window.innerHeight || document.documentElement[LEXICON.cH] || document.body[LEXICON.cH];\r\n }\r\n function bind(func, thisObj) {\r\n if (typeof func != TYPES.f) {\r\n throw \"Can't bind function!\";\r\n // closest thing possible to the ECMAScript 5\r\n // internal IsCallable function\r\n //throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');\r\n }\r\n var proto = LEXICON.p;\r\n var aArgs = Array[proto].slice.call(arguments, 2);\r\n var fNOP = function () { };\r\n var fBound = function () { return func.apply(this instanceof fNOP ? this : thisObj, aArgs.concat(Array[proto].slice.call(arguments))); };\r\n\r\n if (func[proto])\r\n fNOP[proto] = func[proto]; // Function.prototype doesn't have a prototype property\r\n fBound[proto] = new fNOP();\r\n\r\n return fBound;\r\n }\r\n\r\n return {\r\n /**\r\n * Gets the current window width.\r\n * @returns {Number|number} The current window width in pixel.\r\n */\r\n wW: bind(windowSize, 0, true),\r\n\r\n /**\r\n * Gets the current window height.\r\n * @returns {Number|number} The current window height in pixel.\r\n */\r\n wH: bind(windowSize, 0),\r\n\r\n /**\r\n * Gets the MutationObserver Object or undefined if not supported.\r\n * @returns {MutationObserver|*|undefined} The MutationsObserver Object or undefined.\r\n */\r\n mO: bind(VENDORS._jsAPI, 0, 'MutationObserver', true),\r\n\r\n /**\r\n * Gets the ResizeObserver Object or undefined if not supported.\r\n * @returns {MutationObserver|*|undefined} The ResizeObserver Object or undefined.\r\n */\r\n rO: bind(VENDORS._jsAPI, 0, 'ResizeObserver', true),\r\n\r\n /**\r\n * Gets the RequestAnimationFrame method or it's corresponding polyfill.\r\n * @returns {*|Function} The RequestAnimationFrame method or it's corresponding polyfill.\r\n */\r\n rAF: bind(VENDORS._jsAPI, 0, 'requestAnimationFrame', false, function (func) { return window.setTimeout(func, 1000 / 60); }),\r\n\r\n /**\r\n * Gets the CancelAnimationFrame method or it's corresponding polyfill.\r\n * @returns {*|Function} The CancelAnimationFrame method or it's corresponding polyfill.\r\n */\r\n cAF: bind(VENDORS._jsAPI, 0, 'cancelAnimationFrame', false, function (id) { return window.clearTimeout(id); }),\r\n\r\n /**\r\n * Gets the current time.\r\n * @returns {number} The current time.\r\n */\r\n now: function () {\r\n return Date.now && Date.now() || new Date().getTime();\r\n },\r\n\r\n /**\r\n * Stops the propagation of the given event.\r\n * @param event The event of which the propagation shall be stoped.\r\n */\r\n stpP: function (event) {\r\n if (event.stopPropagation)\r\n event.stopPropagation();\r\n else\r\n event.cancelBubble = true;\r\n },\r\n\r\n /**\r\n * Prevents the default action of the given event.\r\n * @param event The event of which the default action shall be prevented.\r\n */\r\n prvD: function (event) {\r\n if (event.preventDefault && event.cancelable)\r\n event.preventDefault();\r\n else\r\n event.returnValue = false;\r\n },\r\n\r\n /**\r\n * Gets the pageX and pageY values of the given mouse event.\r\n * @param event The mouse event of which the pageX and pageX shall be got.\r\n * @returns {{x: number, y: number}} x = pageX value, y = pageY value.\r\n */\r\n page: function (event) {\r\n event = event.originalEvent || event;\r\n\r\n var strPage = 'page';\r\n var strClient = 'client';\r\n var strX = 'X';\r\n var strY = 'Y';\r\n var target = event.target || event.srcElement || document;\r\n var eventDoc = target.ownerDocument || document;\r\n var doc = eventDoc.documentElement;\r\n var body = eventDoc.body;\r\n\r\n //if touch event return return pageX/Y of it\r\n if (event.touches !== undefined) {\r\n var touch = event.touches[0];\r\n return {\r\n x: touch[strPage + strX],\r\n y: touch[strPage + strY]\r\n }\r\n }\r\n\r\n // Calculate pageX/Y if not native supported\r\n if (!event[strPage + strX] && event[strClient + strX] && event[strClient + strX] != null) {\r\n\r\n return {\r\n x: event[strClient + strX] +\r\n (doc && doc.scrollLeft || body && body.scrollLeft || 0) -\r\n (doc && doc.clientLeft || body && body.clientLeft || 0),\r\n y: event[strClient + strY] +\r\n (doc && doc.scrollTop || body && body.scrollTop || 0) -\r\n (doc && doc.clientTop || body && body.clientTop || 0)\r\n }\r\n }\r\n return {\r\n x: event[strPage + strX],\r\n y: event[strPage + strY]\r\n };\r\n },\r\n\r\n /**\r\n * Gets the clicked mouse button of the given mouse event.\r\n * @param event The mouse event of which the clicked button shal be got.\r\n * @returns {number} The number of the clicked mouse button. (0 : none | 1 : leftButton | 2 : middleButton | 3 : rightButton)\r\n */\r\n mBtn: function (event) {\r\n var button = event.button;\r\n if (!event.which && button !== undefined)\r\n return (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0)));\r\n else\r\n return event.which;\r\n },\r\n\r\n /**\r\n * Checks whether a item is in the given array and returns its index.\r\n * @param item The item of which the position in the array shall be determined.\r\n * @param arr The array.\r\n * @returns {number} The zero based index of the item or -1 if the item isn't in the array.\r\n */\r\n inA: function (item, arr) {\r\n for (var i = 0; i < arr[LEXICON.l]; i++)\r\n //Sometiems in IE a \"SCRIPT70\" Permission denied error occurs if HTML elements in a iFrame are compared\r\n try {\r\n if (arr[i] === item)\r\n return i;\r\n }\r\n catch (e) { }\r\n return -1;\r\n },\r\n\r\n /**\r\n * Returns true if the given value is a array.\r\n * @param arr The potential array.\r\n * @returns {boolean} True if the given value is a array, false otherwise.\r\n */\r\n isA: function (arr) {\r\n var def = Array.isArray;\r\n return def ? def(arr) : this.type(arr) == TYPES.a;\r\n },\r\n\r\n /**\r\n * Determine the internal JavaScript [[Class]] of the given object.\r\n * @param obj The object of which the type shall be determined.\r\n * @returns {string} The type of the given object.\r\n */\r\n type: function (obj) {\r\n if (obj === undefined)\r\n return obj + '';\r\n if (obj === null)\r\n return obj + '';\r\n return Object[LEXICON.p].toString.call(obj).replace(/^\\[object (.+)\\]$/, '$1').toLowerCase();\r\n },\r\n\r\n\r\n bind: bind\r\n\r\n /**\r\n * Gets the vendor-prefixed CSS property by the given name.\r\n * For example the given name is \"transform\" and you're using a old Firefox browser then the returned value would be \"-moz-transform\".\r\n * If the browser doesn't need a vendor-prefix, then the returned string is the given name.\r\n * If the browser doesn't support the given property name at all (not even with a vendor-prefix) the returned value is null.\r\n * @param propName The unprefixed CSS property name.\r\n * @returns {string|null} The vendor-prefixed CSS property or null if the browser doesn't support the given CSS property.\r\n\r\n cssProp: function(propName) {\r\n return VENDORS._cssProperty(propName);\r\n }\r\n */\r\n }\r\n })();\r\n\r\n\r\n var MATH = Math;\r\n var JQUERY = window.jQuery;\r\n var EASING = (function () {\r\n var _easingsMath = {\r\n p: MATH.PI,\r\n c: MATH.cos,\r\n s: MATH.sin,\r\n w: MATH.pow,\r\n t: MATH.sqrt,\r\n n: MATH.asin,\r\n a: MATH.abs,\r\n o: 1.70158\r\n };\r\n\r\n /*\r\n x : current percent (0 - 1),\r\n t : current time (duration * percent),\r\n b : start value (from),\r\n c : end value (to),\r\n d : duration\r\n\r\n easingName : function(x, t, b, c, d) { return easedValue; }\r\n */\r\n\r\n return {\r\n swing: function (x, t, b, c, d) {\r\n return 0.5 - _easingsMath.c(x * _easingsMath.p) / 2;\r\n },\r\n linear: function (x, t, b, c, d) {\r\n return x;\r\n },\r\n easeInQuad: function (x, t, b, c, d) {\r\n return c * (t /= d) * t + b;\r\n },\r\n easeOutQuad: function (x, t, b, c, d) {\r\n return -c * (t /= d) * (t - 2) + b;\r\n },\r\n easeInOutQuad: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? c / 2 * t * t + b : -c / 2 * ((--t) * (t - 2) - 1) + b;\r\n },\r\n easeInCubic: function (x, t, b, c, d) {\r\n return c * (t /= d) * t * t + b;\r\n },\r\n easeOutCubic: function (x, t, b, c, d) {\r\n return c * ((t = t / d - 1) * t * t + 1) + b;\r\n },\r\n easeInOutCubic: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? c / 2 * t * t * t + b : c / 2 * ((t -= 2) * t * t + 2) + b;\r\n },\r\n easeInQuart: function (x, t, b, c, d) {\r\n return c * (t /= d) * t * t * t + b;\r\n },\r\n easeOutQuart: function (x, t, b, c, d) {\r\n return -c * ((t = t / d - 1) * t * t * t - 1) + b;\r\n },\r\n easeInOutQuart: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t + b : -c / 2 * ((t -= 2) * t * t * t - 2) + b;\r\n },\r\n easeInQuint: function (x, t, b, c, d) {\r\n return c * (t /= d) * t * t * t * t + b;\r\n },\r\n easeOutQuint: function (x, t, b, c, d) {\r\n return c * ((t = t / d - 1) * t * t * t * t + 1) + b;\r\n },\r\n easeInOutQuint: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t * t + b : c / 2 * ((t -= 2) * t * t * t * t + 2) + b;\r\n },\r\n easeInSine: function (x, t, b, c, d) {\r\n return -c * _easingsMath.c(t / d * (_easingsMath.p / 2)) + c + b;\r\n },\r\n easeOutSine: function (x, t, b, c, d) {\r\n return c * _easingsMath.s(t / d * (_easingsMath.p / 2)) + b;\r\n },\r\n easeInOutSine: function (x, t, b, c, d) {\r\n return -c / 2 * (_easingsMath.c(_easingsMath.p * t / d) - 1) + b;\r\n },\r\n easeInExpo: function (x, t, b, c, d) {\r\n return (t == 0) ? b : c * _easingsMath.w(2, 10 * (t / d - 1)) + b;\r\n },\r\n easeOutExpo: function (x, t, b, c, d) {\r\n return (t == d) ? b + c : c * (-_easingsMath.w(2, -10 * t / d) + 1) + b;\r\n },\r\n easeInOutExpo: function (x, t, b, c, d) {\r\n if (t == 0) return b;\r\n if (t == d) return b + c;\r\n if ((t /= d / 2) < 1) return c / 2 * _easingsMath.w(2, 10 * (t - 1)) + b;\r\n return c / 2 * (-_easingsMath.w(2, -10 * --t) + 2) + b;\r\n },\r\n easeInCirc: function (x, t, b, c, d) {\r\n return -c * (_easingsMath.t(1 - (t /= d) * t) - 1) + b;\r\n },\r\n easeOutCirc: function (x, t, b, c, d) {\r\n return c * _easingsMath.t(1 - (t = t / d - 1) * t) + b;\r\n },\r\n easeInOutCirc: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? -c / 2 * (_easingsMath.t(1 - t * t) - 1) + b : c / 2 * (_easingsMath.t(1 - (t -= 2) * t) + 1) + b;\r\n },\r\n easeInElastic: function (x, t, b, c, d) {\r\n var s = _easingsMath.o; var p = 0; var a = c;\r\n if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;\r\n if (a < _easingsMath.a(c)) { a = c; s = p / 4; }\r\n else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a);\r\n return -(a * _easingsMath.w(2, 10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p)) + b;\r\n },\r\n easeOutElastic: function (x, t, b, c, d) {\r\n var s = _easingsMath.o; var p = 0; var a = c;\r\n if (t == 0) return b;\r\n if ((t /= d) == 1) return b + c;\r\n if (!p) p = d * .3;\r\n if (a < _easingsMath.a(c)) { a = c; s = p / 4; }\r\n else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a);\r\n return a * _easingsMath.w(2, -10 * t) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p) + c + b;\r\n },\r\n easeInOutElastic: function (x, t, b, c, d) {\r\n var s = _easingsMath.o; var p = 0; var a = c;\r\n if (t == 0) return b;\r\n if ((t /= d / 2) == 2) return b + c;\r\n if (!p) p = d * (.3 * 1.5);\r\n if (a < _easingsMath.a(c)) { a = c; s = p / 4; }\r\n else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a);\r\n if (t < 1) return -.5 * (a * _easingsMath.w(2, 10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p)) + b;\r\n return a * _easingsMath.w(2, -10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p) * .5 + c + b;\r\n },\r\n easeInBack: function (x, t, b, c, d, s) {\r\n s = s || _easingsMath.o;\r\n return c * (t /= d) * t * ((s + 1) * t - s) + b;\r\n },\r\n easeOutBack: function (x, t, b, c, d, s) {\r\n s = s || _easingsMath.o;\r\n return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\r\n },\r\n easeInOutBack: function (x, t, b, c, d, s) {\r\n s = s || _easingsMath.o;\r\n return ((t /= d / 2) < 1) ? c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b : c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;\r\n },\r\n easeInBounce: function (x, t, b, c, d) {\r\n return c - this.easeOutBounce(x, d - t, 0, c, d) + b;\r\n },\r\n easeOutBounce: function (x, t, b, c, d) {\r\n var o = 7.5625;\r\n if ((t /= d) < (1 / 2.75)) {\r\n return c * (o * t * t) + b;\r\n } else if (t < (2 / 2.75)) {\r\n return c * (o * (t -= (1.5 / 2.75)) * t + .75) + b;\r\n } else if (t < (2.5 / 2.75)) {\r\n return c * (o * (t -= (2.25 / 2.75)) * t + .9375) + b;\r\n } else {\r\n return c * (o * (t -= (2.625 / 2.75)) * t + .984375) + b;\r\n }\r\n },\r\n easeInOutBounce: function (x, t, b, c, d) {\r\n return (t < d / 2) ? this.easeInBounce(x, t * 2, 0, c, d) * .5 + b : this.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b;\r\n }\r\n };\r\n /*\r\n *\r\n * TERMS OF USE - EASING EQUATIONS\r\n * \r\n * Open source under the BSD License. \r\n * \r\n * Copyright © 2001 Robert Penner\r\n * All rights reserved.\r\n * \r\n * Redistribution and use in source and binary forms, with or without modification, \r\n * are permitted provided that the following conditions are met:\r\n * \r\n * Redistributions of source code must retain the above copyright notice, this list of \r\n * conditions and the following disclaimer.\r\n * Redistributions in binary form must reproduce the above copyright notice, this list \r\n * of conditions and the following disclaimer in the documentation and/or other materials \r\n * provided with the distribution.\r\n * \r\n * Neither the name of the author nor the names of contributors may be used to endorse \r\n * or promote products derived from this software without specific prior written permission.\r\n * \r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY \r\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r\n * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\r\n * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \r\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r\n * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED \r\n * OF THE POSSIBILITY OF SUCH DAMAGE. \r\n *\r\n */\r\n })();\r\n var FRAMEWORK = (function () {\r\n var _rnothtmlwhite = (/[^\\x20\\t\\r\\n\\f]+/g);\r\n var _strSpace = ' ';\r\n var _strEmpty = '';\r\n var _strScrollLeft = 'scrollLeft';\r\n var _strScrollTop = 'scrollTop';\r\n var _animations = [];\r\n var _type = COMPATIBILITY.type;\r\n var _cssNumber = {\r\n animationIterationCount: true,\r\n columnCount: true,\r\n fillOpacity: true,\r\n flexGrow: true,\r\n flexShrink: true,\r\n fontWeight: true,\r\n lineHeight: true,\r\n opacity: true,\r\n order: true,\r\n orphans: true,\r\n widows: true,\r\n zIndex: true,\r\n zoom: true\r\n };\r\n\r\n function extend() {\r\n var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {},\r\n i = 1,\r\n length = arguments[LEXICON.l],\r\n deep = false;\r\n\r\n // Handle a deep copy situation\r\n if (_type(target) == TYPES.b) {\r\n deep = target;\r\n target = arguments[1] || {};\r\n // skip the boolean and the target\r\n i = 2;\r\n }\r\n\r\n // Handle case when target is a string or something (possible in deep copy)\r\n if (_type(target) != TYPES.o && !_type(target) == TYPES.f) {\r\n target = {};\r\n }\r\n\r\n // extend jQuery itself if only one argument is passed\r\n if (length === i) {\r\n target = FakejQuery;\r\n --i;\r\n }\r\n\r\n for (; i < length; i++) {\r\n // Only deal with non-null/undefined values\r\n if ((options = arguments[i]) != null) {\r\n // Extend the base object\r\n for (name in options) {\r\n src = target[name];\r\n copy = options[name];\r\n\r\n // Prevent never-ending loop\r\n if (target === copy) {\r\n continue;\r\n }\r\n\r\n // Recurse if we're merging plain objects or arrays\r\n if (deep && copy && (isPlainObject(copy) || (copyIsArray = COMPATIBILITY.isA(copy)))) {\r\n if (copyIsArray) {\r\n copyIsArray = false;\r\n clone = src && COMPATIBILITY.isA(src) ? src : [];\r\n\r\n } else {\r\n clone = src && isPlainObject(src) ? src : {};\r\n }\r\n\r\n // Never move original objects, clone them\r\n target[name] = extend(deep, clone, copy);\r\n\r\n // Don't bring in undefined values\r\n } else if (copy !== undefined) {\r\n target[name] = copy;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Return the modified object\r\n return target;\r\n };\r\n\r\n function inArray(item, arr, fromIndex) {\r\n for (var i = fromIndex || 0; i < arr[LEXICON.l]; i++)\r\n if (arr[i] === item)\r\n return i;\r\n return -1;\r\n }\r\n\r\n function isFunction(obj) {\r\n return _type(obj) == TYPES.f;\r\n };\r\n\r\n function isEmptyObject(obj) {\r\n for (var name in obj)\r\n return false;\r\n return true;\r\n };\r\n\r\n function isPlainObject(obj) {\r\n if (!obj || _type(obj) != TYPES.o)\r\n return false;\r\n\r\n var key;\r\n var proto = LEXICON.p;\r\n var hasOwnProperty = Object[proto].hasOwnProperty;\r\n var hasOwnConstructor = hasOwnProperty.call(obj, 'constructor');\r\n var hasIsPrototypeOf = obj.constructor && obj.constructor[proto] && hasOwnProperty.call(obj.constructor[proto], 'isPrototypeOf');\r\n\r\n if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {\r\n return false;\r\n }\r\n\r\n\r\n for (key in obj) { /**/ }\r\n\r\n return _type(key) == TYPES.u || hasOwnProperty.call(obj, key);\r\n };\r\n\r\n function each(obj, callback) {\r\n var i = 0;\r\n\r\n if (isArrayLike(obj)) {\r\n for (; i < obj[LEXICON.l]; i++) {\r\n if (callback.call(obj[i], i, obj[i]) === false)\r\n break;\r\n }\r\n }\r\n else {\r\n for (i in obj) {\r\n if (callback.call(obj[i], i, obj[i]) === false)\r\n break;\r\n }\r\n }\r\n\r\n return obj;\r\n };\r\n\r\n function isArrayLike(obj) {\r\n var length = !!obj && [LEXICON.l] in obj && obj[LEXICON.l];\r\n var t = _type(obj);\r\n return isFunction(t) ? false : (t == TYPES.a || length === 0 || _type(length) == TYPES.n && length > 0 && (length - 1) in obj);\r\n }\r\n\r\n function stripAndCollapse(value) {\r\n var tokens = value.match(_rnothtmlwhite) || [];\r\n return tokens.join(_strSpace);\r\n }\r\n\r\n function matches(elem, selector) {\r\n var nodeList = (elem.parentNode || document).querySelectorAll(selector) || [];\r\n var i = nodeList[LEXICON.l];\r\n\r\n while (i--)\r\n if (nodeList[i] == elem)\r\n return true;\r\n\r\n return false;\r\n }\r\n\r\n function insertAdjacentElement(el, strategy, child) {\r\n if (COMPATIBILITY.isA(child)) {\r\n for (var i = 0; i < child[LEXICON.l]; i++)\r\n insertAdjacentElement(el, strategy, child[i]);\r\n }\r\n else if (_type(child) == TYPES.s)\r\n el.insertAdjacentHTML(strategy, child);\r\n else\r\n el.insertAdjacentElement(strategy, child.nodeType ? child : child[0]);\r\n }\r\n\r\n function setCSSVal(el, prop, val) {\r\n try {\r\n if (el[LEXICON.s][prop] !== undefined)\r\n el[LEXICON.s][prop] = parseCSSVal(prop, val);\r\n } catch (e) { }\r\n }\r\n\r\n function parseCSSVal(prop, val) {\r\n if (!_cssNumber[prop.toLowerCase()] && _type(val) == TYPES.n)\r\n val += 'px';\r\n return val;\r\n }\r\n\r\n function startNextAnimationInQ(animObj, removeFromQ) {\r\n var index;\r\n var nextAnim;\r\n if (removeFromQ !== false)\r\n animObj.q.splice(0, 1);\r\n if (animObj.q[LEXICON.l] > 0) {\r\n nextAnim = animObj.q[0];\r\n animate(animObj.el, nextAnim.props, nextAnim.duration, nextAnim.easing, nextAnim.complete, true);\r\n }\r\n else {\r\n index = inArray(animObj, _animations);\r\n if (index > -1)\r\n _animations.splice(index, 1);\r\n }\r\n }\r\n\r\n function setAnimationValue(el, prop, value) {\r\n if (prop === _strScrollLeft || prop === _strScrollTop)\r\n el[prop] = value;\r\n else\r\n setCSSVal(el, prop, value);\r\n }\r\n\r\n function animate(el, props, options, easing, complete, guaranteedNext) {\r\n var hasOptions = isPlainObject(options);\r\n var from = {};\r\n var to = {};\r\n var i = 0;\r\n var key;\r\n var animObj;\r\n var start;\r\n var progress;\r\n var step;\r\n var specialEasing;\r\n var duration;\r\n if (hasOptions) {\r\n easing = options.easing;\r\n start = options.start;\r\n progress = options.progress;\r\n step = options.step;\r\n specialEasing = options.specialEasing;\r\n complete = options.complete;\r\n duration = options.duration;\r\n }\r\n else\r\n duration = options;\r\n specialEasing = specialEasing || {};\r\n duration = duration || 400;\r\n easing = easing || 'swing';\r\n guaranteedNext = guaranteedNext || false;\r\n\r\n for (; i < _animations[LEXICON.l]; i++) {\r\n if (_animations[i].el === el) {\r\n animObj = _animations[i];\r\n break;\r\n }\r\n }\r\n\r\n if (!animObj) {\r\n animObj = {\r\n el: el,\r\n q: []\r\n };\r\n _animations.push(animObj);\r\n }\r\n\r\n for (key in props) {\r\n if (key === _strScrollLeft || key === _strScrollTop)\r\n from[key] = el[key];\r\n else\r\n from[key] = FakejQuery(el).css(key);\r\n }\r\n\r\n for (key in from) {\r\n if (from[key] !== props[key] && props[key] !== undefined)\r\n to[key] = props[key];\r\n }\r\n\r\n if (!isEmptyObject(to)) {\r\n var timeNow;\r\n var end;\r\n var percent;\r\n var fromVal;\r\n var toVal;\r\n var easedVal;\r\n var timeStart;\r\n var frame;\r\n var elapsed;\r\n var qPos = guaranteedNext ? 0 : inArray(qObj, animObj.q);\r\n var qObj = {\r\n props: to,\r\n duration: hasOptions ? options : duration,\r\n easing: easing,\r\n complete: complete\r\n };\r\n if (qPos === -1) {\r\n qPos = animObj.q[LEXICON.l];\r\n animObj.q.push(qObj);\r\n }\r\n\r\n if (qPos === 0) {\r\n if (duration > 0) {\r\n timeStart = COMPATIBILITY.now();\r\n frame = function () {\r\n timeNow = COMPATIBILITY.now();\r\n elapsed = (timeNow - timeStart);\r\n end = qObj.stop || elapsed >= duration;\r\n percent = 1 - ((MATH.max(0, timeStart + duration - timeNow) / duration) || 0);\r\n\r\n for (key in to) {\r\n fromVal = parseFloat(from[key]);\r\n toVal = parseFloat(to[key]);\r\n easedVal = (toVal - fromVal) * EASING[specialEasing[key] || easing](percent, percent * duration, 0, 1, duration) + fromVal;\r\n setAnimationValue(el, key, easedVal);\r\n if (isFunction(step)) {\r\n step(easedVal, {\r\n elem: el,\r\n prop: key,\r\n start: fromVal,\r\n now: easedVal,\r\n end: toVal,\r\n pos: percent,\r\n options: {\r\n easing: easing,\r\n speacialEasing: specialEasing,\r\n duration: duration,\r\n complete: complete,\r\n step: step\r\n },\r\n startTime: timeStart\r\n });\r\n }\r\n }\r\n\r\n if (isFunction(progress))\r\n progress({}, percent, MATH.max(0, duration - elapsed));\r\n\r\n if (end) {\r\n startNextAnimationInQ(animObj);\r\n if (isFunction(complete))\r\n complete();\r\n }\r\n else\r\n qObj.frame = COMPATIBILITY.rAF()(frame);\r\n };\r\n qObj.frame = COMPATIBILITY.rAF()(frame);\r\n }\r\n else {\r\n for (key in to)\r\n setAnimationValue(el, key, to[key]);\r\n startNextAnimationInQ(animObj);\r\n }\r\n }\r\n }\r\n else if (guaranteedNext)\r\n startNextAnimationInQ(animObj);\r\n }\r\n\r\n function stop(el, clearQ, jumpToEnd) {\r\n var animObj;\r\n var qObj;\r\n var key;\r\n var i = 0;\r\n for (; i < _animations[LEXICON.l]; i++) {\r\n animObj = _animations[i];\r\n if (animObj.el === el) {\r\n if (animObj.q[LEXICON.l] > 0) {\r\n qObj = animObj.q[0];\r\n qObj.stop = true;\r\n COMPATIBILITY.cAF()(qObj.frame);\r\n animObj.q.splice(0, 1);\r\n\r\n if (jumpToEnd)\r\n for (key in qObj.props)\r\n setAnimationValue(el, key, qObj.props[key]);\r\n\r\n if (clearQ)\r\n animObj.q = [];\r\n else\r\n startNextAnimationInQ(animObj, false);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n\r\n function elementIsVisible(el) {\r\n return !!(el[LEXICON.oW] || el[LEXICON.oH] || el.getClientRects()[LEXICON.l]);\r\n }\r\n\r\n function FakejQuery(selector) {\r\n if (arguments[LEXICON.l] === 0)\r\n return this;\r\n\r\n var base = new FakejQuery();\r\n var elements = selector;\r\n var i = 0;\r\n var elms;\r\n var el;\r\n\r\n if (_type(selector) == TYPES.s) {\r\n elements = [];\r\n if (selector.charAt(0) === '<') {\r\n el = document.createElement('div');\r\n el.innerHTML = selector;\r\n elms = el.children;\r\n }\r\n else {\r\n elms = document.querySelectorAll(selector);\r\n }\r\n\r\n for (; i < elms[LEXICON.l]; i++)\r\n elements.push(elms[i]);\r\n }\r\n\r\n if (elements) {\r\n if (_type(elements) != TYPES.s && (!isArrayLike(elements) || elements === window || elements === elements.self))\r\n elements = [elements];\r\n\r\n for (i = 0; i < elements[LEXICON.l]; i++)\r\n base[i] = elements[i];\r\n\r\n base[LEXICON.l] = elements[LEXICON.l];\r\n }\r\n\r\n return base;\r\n };\r\n\r\n FakejQuery[LEXICON.p] = {\r\n\r\n //EVENTS:\r\n\r\n on: function (eventName, handler) {\r\n eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty];\r\n\r\n var eventNameLength = eventName[LEXICON.l];\r\n var i = 0;\r\n var el;\r\n return this.each(function () {\r\n el = this;\r\n try {\r\n if (el.addEventListener) {\r\n for (; i < eventNameLength; i++)\r\n el.addEventListener(eventName[i], handler);\r\n }\r\n else if (el.detachEvent) {\r\n for (; i < eventNameLength; i++)\r\n el.attachEvent('on' + eventName[i], handler);\r\n }\r\n } catch (e) { }\r\n });\r\n },\r\n\r\n off: function (eventName, handler) {\r\n eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty];\r\n\r\n var eventNameLength = eventName[LEXICON.l];\r\n var i = 0;\r\n var el;\r\n return this.each(function () {\r\n el = this;\r\n try {\r\n if (el.removeEventListener) {\r\n for (; i < eventNameLength; i++)\r\n el.removeEventListener(eventName[i], handler);\r\n }\r\n else if (el.detachEvent) {\r\n for (; i < eventNameLength; i++)\r\n el.detachEvent('on' + eventName[i], handler);\r\n }\r\n } catch (e) { }\r\n });\r\n },\r\n\r\n one: function (eventName, handler) {\r\n eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty];\r\n return this.each(function () {\r\n var el = FakejQuery(this);\r\n FakejQuery.each(eventName, function (i, oneEventName) {\r\n var oneHandler = function (e) {\r\n handler.call(this, e);\r\n el.off(oneEventName, oneHandler);\r\n };\r\n el.on(oneEventName, oneHandler);\r\n });\r\n });\r\n },\r\n\r\n trigger: function (eventName) {\r\n var el;\r\n var event;\r\n return this.each(function () {\r\n el = this;\r\n if (document.createEvent) {\r\n event = document.createEvent('HTMLEvents');\r\n event.initEvent(eventName, true, false);\r\n el.dispatchEvent(event);\r\n }\r\n else {\r\n el.fireEvent('on' + eventName);\r\n }\r\n });\r\n },\r\n\r\n //DOM NODE INSERTING / REMOVING:\r\n\r\n append: function (child) {\r\n return this.each(function () { insertAdjacentElement(this, 'beforeend', child); });\r\n },\r\n\r\n prepend: function (child) {\r\n return this.each(function () { insertAdjacentElement(this, 'afterbegin', child); });\r\n },\r\n\r\n before: function (child) {\r\n return this.each(function () { insertAdjacentElement(this, 'beforebegin', child); });\r\n },\r\n\r\n after: function (child) {\r\n return this.each(function () { insertAdjacentElement(this, 'afterend', child); });\r\n },\r\n\r\n remove: function () {\r\n return this.each(function () {\r\n var el = this;\r\n var parentNode = el.parentNode;\r\n if (parentNode != null)\r\n parentNode.removeChild(el);\r\n });\r\n },\r\n\r\n unwrap: function () {\r\n var parents = [];\r\n var i;\r\n var el;\r\n var parent;\r\n\r\n this.each(function () {\r\n parent = this.parentNode;\r\n if (inArray(parent, parents) === - 1)\r\n parents.push(parent);\r\n });\r\n\r\n for (i = 0; i < parents[LEXICON.l]; i++) {\r\n el = parents[i];\r\n parent = el.parentNode;\r\n while (el.firstChild)\r\n parent.insertBefore(el.firstChild, el);\r\n parent.removeChild(el);\r\n }\r\n\r\n return this;\r\n },\r\n\r\n wrapAll: function (wrapperHTML) {\r\n var i;\r\n var nodes = this;\r\n var wrapper = FakejQuery(wrapperHTML)[0];\r\n var deepest = wrapper;\r\n var parent = nodes[0].parentNode;\r\n var previousSibling = nodes[0].previousSibling;\r\n while (deepest.childNodes[LEXICON.l] > 0)\r\n deepest = deepest.childNodes[0];\r\n\r\n for (i = 0; nodes[LEXICON.l] - i; deepest.firstChild === nodes[0] && i++)\r\n deepest.appendChild(nodes[i]);\r\n\r\n var nextSibling = previousSibling ? previousSibling.nextSibling : parent.firstChild;\r\n parent.insertBefore(wrapper, nextSibling);\r\n\r\n return this;\r\n },\r\n\r\n wrapInner: function (wrapperHTML) {\r\n return this.each(function () {\r\n var el = FakejQuery(this);\r\n var contents = el.contents();\r\n\r\n if (contents[LEXICON.l])\r\n contents.wrapAll(wrapperHTML);\r\n else\r\n el.append(wrapperHTML);\r\n });\r\n },\r\n\r\n wrap: function (wrapperHTML) {\r\n return this.each(function () { FakejQuery(this).wrapAll(wrapperHTML); });\r\n },\r\n\r\n\r\n //DOM NODE MANIPULATION / INFORMATION:\r\n\r\n css: function (styles, val) {\r\n var el;\r\n var key;\r\n var cptStyle;\r\n var getCptStyle = window.getComputedStyle;\r\n if (_type(styles) == TYPES.s) {\r\n if (val === undefined) {\r\n el = this[0];\r\n cptStyle = getCptStyle ? getCptStyle(el, null) : el.currentStyle[styles];\r\n\r\n //https://bugzilla.mozilla.org/show_bug.cgi?id=548397 can be null sometimes if iframe with display: none (firefox only!)\r\n return getCptStyle ? cptStyle != null ? cptStyle.getPropertyValue(styles) : el[LEXICON.s][styles] : cptStyle;\r\n }\r\n else {\r\n return this.each(function () {\r\n setCSSVal(this, styles, val);\r\n });\r\n }\r\n }\r\n else {\r\n return this.each(function () {\r\n for (key in styles)\r\n setCSSVal(this, key, styles[key]);\r\n });\r\n }\r\n },\r\n\r\n hasClass: function (className) {\r\n var elem, i = 0;\r\n var classNamePrepared = _strSpace + className + _strSpace;\r\n var classList;\r\n\r\n while ((elem = this[i++])) {\r\n classList = elem.classList;\r\n if (classList && classList.contains(className))\r\n return true;\r\n else if (elem.nodeType === 1 && (_strSpace + stripAndCollapse(elem.className + _strEmpty) + _strSpace).indexOf(classNamePrepared) > -1)\r\n return true;\r\n }\r\n\r\n return false;\r\n },\r\n\r\n addClass: function (className) {\r\n var classes;\r\n var elem;\r\n var cur;\r\n var curValue;\r\n var clazz;\r\n var finalValue;\r\n var supportClassList;\r\n var elmClassList;\r\n var i = 0;\r\n var v = 0;\r\n\r\n if (className) {\r\n classes = className.match(_rnothtmlwhite) || [];\r\n\r\n while ((elem = this[i++])) {\r\n elmClassList = elem.classList;\r\n if (supportClassList === undefined)\r\n supportClassList = elmClassList !== undefined;\r\n\r\n if (supportClassList) {\r\n while ((clazz = classes[v++]))\r\n elmClassList.add(clazz);\r\n }\r\n else {\r\n curValue = elem.className + _strEmpty;\r\n cur = elem.nodeType === 1 && (_strSpace + stripAndCollapse(curValue) + _strSpace);\r\n\r\n if (cur) {\r\n while ((clazz = classes[v++]))\r\n if (cur.indexOf(_strSpace + clazz + _strSpace) < 0)\r\n cur += clazz + _strSpace;\r\n\r\n finalValue = stripAndCollapse(cur);\r\n if (curValue !== finalValue)\r\n elem.className = finalValue;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return this;\r\n },\r\n\r\n removeClass: function (className) {\r\n var classes;\r\n var elem;\r\n var cur;\r\n var curValue;\r\n var clazz;\r\n var finalValue;\r\n var supportClassList;\r\n var elmClassList;\r\n var i = 0;\r\n var v = 0;\r\n\r\n if (className) {\r\n classes = className.match(_rnothtmlwhite) || [];\r\n\r\n while ((elem = this[i++])) {\r\n elmClassList = elem.classList;\r\n if (supportClassList === undefined)\r\n supportClassList = elmClassList !== undefined;\r\n\r\n if (supportClassList) {\r\n while ((clazz = classes[v++]))\r\n elmClassList.remove(clazz);\r\n }\r\n else {\r\n curValue = elem.className + _strEmpty;\r\n cur = elem.nodeType === 1 && (_strSpace + stripAndCollapse(curValue) + _strSpace);\r\n\r\n if (cur) {\r\n while ((clazz = classes[v++]))\r\n while (cur.indexOf(_strSpace + clazz + _strSpace) > -1)\r\n cur = cur.replace(_strSpace + clazz + _strSpace, _strSpace);\r\n\r\n finalValue = stripAndCollapse(cur);\r\n if (curValue !== finalValue)\r\n elem.className = finalValue;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return this;\r\n },\r\n\r\n hide: function () {\r\n return this.each(function () { this[LEXICON.s].display = 'none'; });\r\n },\r\n\r\n show: function () {\r\n return this.each(function () { this[LEXICON.s].display = 'block'; });\r\n },\r\n\r\n attr: function (attrName, value) {\r\n var i = 0;\r\n var el;\r\n while (el = this[i++]) {\r\n if (value === undefined)\r\n return el.getAttribute(attrName);\r\n el.setAttribute(attrName, value);\r\n }\r\n return this;\r\n },\r\n\r\n removeAttr: function (attrName) {\r\n return this.each(function () { this.removeAttribute(attrName); });\r\n },\r\n\r\n offset: function () {\r\n var el = this[0];\r\n var rect = el[LEXICON.bCR]();\r\n var scrollLeft = window.pageXOffset || document.documentElement[_strScrollLeft];\r\n var scrollTop = window.pageYOffset || document.documentElement[_strScrollTop];\r\n return {\r\n top: rect.top + scrollTop,\r\n left: rect.left + scrollLeft\r\n };\r\n },\r\n\r\n position: function () {\r\n var el = this[0];\r\n return {\r\n top: el.offsetTop,\r\n left: el.offsetLeft\r\n };\r\n },\r\n\r\n scrollLeft: function (value) {\r\n var i = 0;\r\n var el;\r\n while (el = this[i++]) {\r\n if (value === undefined)\r\n return el[_strScrollLeft];\r\n el[_strScrollLeft] = value;\r\n }\r\n return this;\r\n },\r\n\r\n scrollTop: function (value) {\r\n var i = 0;\r\n var el;\r\n while (el = this[i++]) {\r\n if (value === undefined)\r\n return el[_strScrollTop];\r\n el[_strScrollTop] = value;\r\n }\r\n return this;\r\n },\r\n\r\n val: function (value) {\r\n var el = this[0];\r\n if (!value)\r\n return el.value;\r\n el.value = value;\r\n return this;\r\n },\r\n\r\n\r\n //DOM TRAVERSAL / FILTERING:\r\n\r\n first: function () {\r\n return this.eq(0);\r\n },\r\n\r\n last: function () {\r\n return this.eq(-1);\r\n },\r\n\r\n eq: function (index) {\r\n return FakejQuery(this[index >= 0 ? index : this[LEXICON.l] + index]);\r\n },\r\n\r\n find: function (selector) {\r\n var children = [];\r\n var i;\r\n this.each(function () {\r\n var el = this;\r\n var ch = el.querySelectorAll(selector);\r\n for (i = 0; i < ch[LEXICON.l]; i++)\r\n children.push(ch[i]);\r\n });\r\n return FakejQuery(children);\r\n },\r\n\r\n children: function (selector) {\r\n var children = [];\r\n var el;\r\n var ch;\r\n var i;\r\n\r\n this.each(function () {\r\n ch = this.children;\r\n for (i = 0; i < ch[LEXICON.l]; i++) {\r\n el = ch[i];\r\n if (selector) {\r\n if ((el.matches && el.matches(selector)) || matches(el, selector))\r\n children.push(el);\r\n }\r\n else\r\n children.push(el);\r\n }\r\n });\r\n return FakejQuery(children);\r\n },\r\n\r\n parent: function (selector) {\r\n var parents = [];\r\n var parent;\r\n this.each(function () {\r\n parent = this.parentNode;\r\n if (selector ? FakejQuery(parent).is(selector) : true)\r\n parents.push(parent);\r\n });\r\n return FakejQuery(parents);\r\n },\r\n\r\n is: function (selector) {\r\n\r\n var el;\r\n var i;\r\n for (i = 0; i < this[LEXICON.l]; i++) {\r\n el = this[i];\r\n if (selector === ':visible')\r\n return elementIsVisible(el);\r\n if (selector === ':hidden')\r\n return !elementIsVisible(el);\r\n if ((el.matches && el.matches(selector)) || matches(el, selector))\r\n return true;\r\n }\r\n return false;\r\n },\r\n\r\n contents: function () {\r\n var contents = [];\r\n var childs;\r\n var i;\r\n\r\n this.each(function () {\r\n childs = this.childNodes;\r\n for (i = 0; i < childs[LEXICON.l]; i++)\r\n contents.push(childs[i]);\r\n });\r\n\r\n return FakejQuery(contents);\r\n },\r\n\r\n each: function (callback) {\r\n return each(this, callback);\r\n },\r\n\r\n\r\n //ANIMATION:\r\n\r\n animate: function (props, duration, easing, complete) {\r\n return this.each(function () { animate(this, props, duration, easing, complete); });\r\n },\r\n\r\n stop: function (clearQ, jump) {\r\n return this.each(function () { stop(this, clearQ, jump); });\r\n }\r\n };\r\n\r\n extend(FakejQuery, {\r\n extend: extend,\r\n inArray: inArray,\r\n isEmptyObject: isEmptyObject,\r\n isPlainObject: isPlainObject,\r\n each: each\r\n });\r\n\r\n return FakejQuery;\r\n })();\r\n var INSTANCES = (function () {\r\n var _targets = [];\r\n var _instancePropertyString = '__overlayScrollbars__';\r\n\r\n /**\r\n * Register, unregister or get a certain (or all) instances.\r\n * Register: Pass the target and the instance.\r\n * Unregister: Pass the target and null.\r\n * Get Instance: Pass the target from which the instance shall be got.\r\n * Get Targets: Pass no arguments.\r\n * @param target The target to which the instance shall be registered / from which the instance shall be unregistered / the instance shall be got\r\n * @param instance The instance.\r\n * @returns {*|void} Returns the instance from the given target.\r\n */\r\n return function (target, instance) {\r\n var argLen = arguments[LEXICON.l];\r\n if (argLen < 1) {\r\n //return all targets\r\n return _targets;\r\n }\r\n else {\r\n if (instance) {\r\n //register instance\r\n target[_instancePropertyString] = instance;\r\n _targets.push(target);\r\n }\r\n else {\r\n var index = COMPATIBILITY.inA(target, _targets);\r\n if (index > -1) {\r\n if (argLen > 1) {\r\n //unregister instance\r\n delete target[_instancePropertyString];\r\n _targets.splice(index, 1);\r\n }\r\n else {\r\n //get instance from target\r\n return _targets[index][_instancePropertyString];\r\n }\r\n }\r\n }\r\n }\r\n }\r\n })();\r\n var PLUGIN = (function () {\r\n var _plugin;\r\n var _pluginsGlobals;\r\n var _pluginsAutoUpdateLoop;\r\n var _pluginsExtensions = [];\r\n var _pluginsOptions = (function () {\r\n var type = COMPATIBILITY.type;\r\n var possibleTemplateTypes = [\r\n TYPES.b, //boolean\r\n TYPES.n, //number\r\n TYPES.s, //string\r\n TYPES.a, //array\r\n TYPES.o, //object\r\n TYPES.f, //function\r\n TYPES.z //null\r\n ];\r\n var restrictedStringsSplit = ' ';\r\n var restrictedStringsPossibilitiesSplit = ':';\r\n var classNameAllowedValues = [TYPES.z, TYPES.s];\r\n var numberAllowedValues = TYPES.n;\r\n var booleanNullAllowedValues = [TYPES.z, TYPES.b];\r\n var booleanTrueTemplate = [true, TYPES.b];\r\n var booleanFalseTemplate = [false, TYPES.b];\r\n var callbackTemplate = [null, [TYPES.z, TYPES.f]];\r\n var updateOnLoadTemplate = [['img'], [TYPES.s, TYPES.a, TYPES.z]];\r\n var inheritedAttrsTemplate = [['style', 'class'], [TYPES.s, TYPES.a, TYPES.z]];\r\n var resizeAllowedValues = 'n:none b:both h:horizontal v:vertical';\r\n var overflowBehaviorAllowedValues = 'v-h:visible-hidden v-s:visible-scroll s:scroll h:hidden';\r\n var scrollbarsVisibilityAllowedValues = 'v:visible h:hidden a:auto';\r\n var scrollbarsAutoHideAllowedValues = 'n:never s:scroll l:leave m:move';\r\n var optionsDefaultsAndTemplate = {\r\n className: ['os-theme-dark', classNameAllowedValues], //null || string\r\n resize: ['none', resizeAllowedValues], //none || both || horizontal || vertical || n || b || h || v\r\n sizeAutoCapable: booleanTrueTemplate, //true || false\r\n clipAlways: booleanTrueTemplate, //true || false\r\n normalizeRTL: booleanTrueTemplate, //true || false\r\n paddingAbsolute: booleanFalseTemplate, //true || false\r\n autoUpdate: [null, booleanNullAllowedValues], //true || false || null\r\n autoUpdateInterval: [33, numberAllowedValues], //number\r\n updateOnLoad: updateOnLoadTemplate, //string || array || null\r\n nativeScrollbarsOverlaid: {\r\n showNativeScrollbars: booleanFalseTemplate, //true || false\r\n initialize: booleanTrueTemplate //true || false\r\n },\r\n overflowBehavior: {\r\n x: ['scroll', overflowBehaviorAllowedValues], //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s\r\n y: ['scroll', overflowBehaviorAllowedValues] //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s\r\n },\r\n scrollbars: {\r\n visibility: ['auto', scrollbarsVisibilityAllowedValues], //visible || hidden || auto || v || h || a\r\n autoHide: ['never', scrollbarsAutoHideAllowedValues], //never || scroll || leave || move || n || s || l || m\r\n autoHideDelay: [800, numberAllowedValues], //number\r\n dragScrolling: booleanTrueTemplate, //true || false\r\n clickScrolling: booleanFalseTemplate, //true || false\r\n touchSupport: booleanTrueTemplate, //true || false\r\n snapHandle: booleanFalseTemplate //true || false\r\n },\r\n textarea: {\r\n dynWidth: booleanFalseTemplate, //true || false\r\n dynHeight: booleanFalseTemplate, //true || false\r\n inheritedAttrs: inheritedAttrsTemplate //string || array || null\r\n },\r\n callbacks: {\r\n onInitialized: callbackTemplate, //null || function\r\n onInitializationWithdrawn: callbackTemplate, //null || function\r\n onDestroyed: callbackTemplate, //null || function\r\n onScrollStart: callbackTemplate, //null || function\r\n onScroll: callbackTemplate, //null || function\r\n onScrollStop: callbackTemplate, //null || function\r\n onOverflowChanged: callbackTemplate, //null || function\r\n onOverflowAmountChanged: callbackTemplate, //null || function\r\n onDirectionChanged: callbackTemplate, //null || function\r\n onContentSizeChanged: callbackTemplate, //null || function\r\n onHostSizeChanged: callbackTemplate, //null || function\r\n onUpdated: callbackTemplate //null || function\r\n }\r\n };\r\n var convert = function (template) {\r\n var recursive = function (obj) {\r\n var key;\r\n var val;\r\n var valType;\r\n for (key in obj) {\r\n if (!obj[LEXICON.hOP](key))\r\n continue;\r\n val = obj[key];\r\n valType = type(val);\r\n if (valType == TYPES.a)\r\n obj[key] = val[template ? 1 : 0];\r\n else if (valType == TYPES.o)\r\n obj[key] = recursive(val);\r\n }\r\n return obj;\r\n };\r\n return recursive(FRAMEWORK.extend(true, {}, optionsDefaultsAndTemplate));\r\n };\r\n\r\n return {\r\n _defaults: convert(),\r\n\r\n _template: convert(true),\r\n\r\n /**\r\n * Validates the passed object by the passed template.\r\n * @param obj The object which shall be validated.\r\n * @param template The template which defines the allowed values and types.\r\n * @param writeErrors True if errors shall be logged to the console.\r\n * @param diffObj If a object is passed then only valid differences to this object will be returned.\r\n * @returns {{}} A object which contains two objects called \"default\" and \"prepared\" which contains only the valid properties of the passed original object and discards not different values compared to the passed diffObj.\r\n */\r\n _validate: function (obj, template, writeErrors, diffObj) {\r\n var validatedOptions = {};\r\n var validatedOptionsPrepared = {};\r\n var objectCopy = FRAMEWORK.extend(true, {}, obj);\r\n var inArray = FRAMEWORK.inArray;\r\n var isEmptyObj = FRAMEWORK.isEmptyObject;\r\n var checkObjectProps = function (data, template, diffData, validatedOptions, validatedOptionsPrepared, prevPropName) {\r\n for (var prop in template) {\r\n if (template[LEXICON.hOP](prop) && data[LEXICON.hOP](prop)) {\r\n var isValid = false;\r\n var isDiff = false;\r\n var templateValue = template[prop];\r\n var templateValueType = type(templateValue);\r\n var templateIsComplex = templateValueType == TYPES.o;\r\n var templateTypes = !COMPATIBILITY.isA(templateValue) ? [templateValue] : templateValue;\r\n var dataDiffValue = diffData[prop];\r\n var dataValue = data[prop];\r\n var dataValueType = type(dataValue);\r\n var propPrefix = prevPropName ? prevPropName + '.' : '';\r\n var error = \"The option \\\"\" + propPrefix + prop + \"\\\" wasn't set, because\";\r\n var errorPossibleTypes = [];\r\n var errorRestrictedStrings = [];\r\n var restrictedStringValuesSplit;\r\n var restrictedStringValuesPossibilitiesSplit;\r\n var isRestrictedValue;\r\n var mainPossibility;\r\n var currType;\r\n var i;\r\n var v;\r\n var j;\r\n\r\n dataDiffValue = dataDiffValue === undefined ? {} : dataDiffValue;\r\n\r\n //if the template has a object as value, it means that the options are complex (verschachtelt)\r\n if (templateIsComplex && dataValueType == TYPES.o) {\r\n validatedOptions[prop] = {};\r\n validatedOptionsPrepared[prop] = {};\r\n checkObjectProps(dataValue, templateValue, dataDiffValue, validatedOptions[prop], validatedOptionsPrepared[prop], propPrefix + prop);\r\n FRAMEWORK.each([data, validatedOptions, validatedOptionsPrepared], function (index, value) {\r\n if (isEmptyObj(value[prop])) {\r\n delete value[prop];\r\n }\r\n });\r\n }\r\n else if (!templateIsComplex) {\r\n for (i = 0; i < templateTypes[LEXICON.l]; i++) {\r\n currType = templateTypes[i];\r\n templateValueType = type(currType);\r\n //if currtype is string and starts with restrictedStringPrefix and end with restrictedStringSuffix\r\n isRestrictedValue = templateValueType == TYPES.s && inArray(currType, possibleTemplateTypes) === -1;\r\n if (isRestrictedValue) {\r\n errorPossibleTypes.push(TYPES.s);\r\n\r\n //split it into a array which contains all possible values for example: [\"y:yes\", \"n:no\", \"m:maybe\"]\r\n restrictedStringValuesSplit = currType.split(restrictedStringsSplit);\r\n errorRestrictedStrings = errorRestrictedStrings.concat(restrictedStringValuesSplit);\r\n for (v = 0; v < restrictedStringValuesSplit[LEXICON.l]; v++) {\r\n //split the possible values into their possibiliteis for example: [\"y\", \"yes\"] -> the first is always the mainPossibility\r\n restrictedStringValuesPossibilitiesSplit = restrictedStringValuesSplit[v].split(restrictedStringsPossibilitiesSplit);\r\n mainPossibility = restrictedStringValuesPossibilitiesSplit[0];\r\n for (j = 0; j < restrictedStringValuesPossibilitiesSplit[LEXICON.l]; j++) {\r\n //if any possibility matches with the dataValue, its valid\r\n if (dataValue === restrictedStringValuesPossibilitiesSplit[j]) {\r\n isValid = true;\r\n break;\r\n }\r\n }\r\n if (isValid)\r\n break;\r\n }\r\n }\r\n else {\r\n errorPossibleTypes.push(currType);\r\n\r\n if (dataValueType === currType) {\r\n isValid = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (isValid) {\r\n isDiff = dataValue !== dataDiffValue;\r\n\r\n if (isDiff)\r\n validatedOptions[prop] = dataValue;\r\n\r\n if (isRestrictedValue ? inArray(dataDiffValue, restrictedStringValuesPossibilitiesSplit) < 0 : isDiff)\r\n validatedOptionsPrepared[prop] = isRestrictedValue ? mainPossibility : dataValue;\r\n }\r\n else if (writeErrors) {\r\n console.warn(error + \" it doesn't accept the type [ \" + dataValueType.toUpperCase() + \" ] with the value of \\\"\" + dataValue + \"\\\".\\r\\n\" +\r\n \"Accepted types are: [ \" + errorPossibleTypes.join(', ').toUpperCase() + \" ].\" +\r\n (errorRestrictedStrings[length] > 0 ? \"\\r\\nValid strings are: [ \" + errorRestrictedStrings.join(', ').split(restrictedStringsPossibilitiesSplit).join(', ') + \" ].\" : ''));\r\n }\r\n delete data[prop];\r\n }\r\n }\r\n }\r\n };\r\n checkObjectProps(objectCopy, template, diffObj || {}, validatedOptions, validatedOptionsPrepared);\r\n\r\n //add values which aren't specified in the template to the finished validated object to prevent them from being discarded\r\n /*\r\n if(keepForeignProps) {\r\n FRAMEWORK.extend(true, validatedOptions, objectCopy);\r\n FRAMEWORK.extend(true, validatedOptionsPrepared, objectCopy);\r\n }\r\n */\r\n\r\n if (!isEmptyObj(objectCopy) && writeErrors)\r\n console.warn('The following options are discarded due to invalidity:\\r\\n' + window.JSON.stringify(objectCopy, null, 2));\r\n\r\n return {\r\n _default: validatedOptions,\r\n _prepared: validatedOptionsPrepared\r\n };\r\n }\r\n }\r\n }());\r\n\r\n /**\r\n * Initializes the object which contains global information about the plugin and each instance of it.\r\n */\r\n function initOverlayScrollbarsStatics() {\r\n if (!_pluginsGlobals)\r\n _pluginsGlobals = new OverlayScrollbarsGlobals(_pluginsOptions._defaults);\r\n if (!_pluginsAutoUpdateLoop)\r\n _pluginsAutoUpdateLoop = new OverlayScrollbarsAutoUpdateLoop(_pluginsGlobals);\r\n }\r\n\r\n /**\r\n * The global object for the OverlayScrollbars objects. It contains resources which every OverlayScrollbars object needs. This object is initialized only once: if the first OverlayScrollbars object gets initialized.\r\n * @param defaultOptions\r\n * @constructor\r\n */\r\n function OverlayScrollbarsGlobals(defaultOptions) {\r\n var _base = this;\r\n var strOverflow = 'overflow';\r\n var strHidden = 'hidden';\r\n var strScroll = 'scroll';\r\n var bodyElement = FRAMEWORK('body');\r\n var scrollbarDummyElement = FRAMEWORK('<div id=\"os-dummy-scrollbar-size\"><div></div></div>');\r\n var scrollbarDummyElement0 = scrollbarDummyElement[0];\r\n var dummyContainerChild = FRAMEWORK(scrollbarDummyElement.children('div').eq(0));\r\n\r\n bodyElement.append(scrollbarDummyElement);\r\n scrollbarDummyElement.hide().show(); //fix IE8 bug (incorrect measuring)\r\n\r\n var nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement0);\r\n var nativeScrollbarIsOverlaid = {\r\n x: nativeScrollbarSize.x === 0,\r\n y: nativeScrollbarSize.y === 0\r\n };\r\n var msie = (function () {\r\n var ua = window.navigator.userAgent;\r\n var strIndexOf = 'indexOf';\r\n var strSubString = 'substring';\r\n var msie = ua[strIndexOf]('MSIE ');\r\n var trident = ua[strIndexOf]('Trident/');\r\n var edge = ua[strIndexOf]('Edge/');\r\n var rv = ua[strIndexOf]('rv:');\r\n var result;\r\n var parseIntFunc = parseInt;\r\n\r\n // IE 10 or older => return version number\r\n if (msie > 0)\r\n result = parseIntFunc(ua[strSubString](msie + 5, ua[strIndexOf]('.', msie)), 10);\r\n\r\n // IE 11 => return version number\r\n else if (trident > 0)\r\n result = parseIntFunc(ua[strSubString](rv + 3, ua[strIndexOf]('.', rv)), 10);\r\n\r\n // Edge (IE 12+) => return version number\r\n else if (edge > 0)\r\n result = parseIntFunc(ua[strSubString](edge + 5, ua[strIndexOf]('.', edge)), 10);\r\n\r\n // other browser\r\n return result;\r\n })();\r\n\r\n FRAMEWORK.extend(_base, {\r\n defaultOptions: defaultOptions,\r\n msie: msie,\r\n autoUpdateLoop: false,\r\n autoUpdateRecommended: !COMPATIBILITY.mO(),\r\n nativeScrollbarSize: nativeScrollbarSize,\r\n nativeScrollbarIsOverlaid: nativeScrollbarIsOverlaid,\r\n nativeScrollbarStyling: (function () {\r\n var result = false;\r\n scrollbarDummyElement.addClass('os-viewport-native-scrollbars-invisible');\r\n try {\r\n result = (scrollbarDummyElement.css('scrollbar-width') === 'none' && (msie > 9 || !msie)) || window.getComputedStyle(scrollbarDummyElement0, '::-webkit-scrollbar').getPropertyValue('display') === 'none';\r\n } catch (ex) { }\r\n\r\n //fix opera bug: scrollbar styles will only appear if overflow value is scroll or auto during the activation of the style.\r\n //and set overflow to scroll\r\n //scrollbarDummyElement.css(strOverflow, strHidden).hide().css(strOverflow, strScroll).show();\r\n //return (scrollbarDummyElement0[LEXICON.oH] - scrollbarDummyElement0[LEXICON.cH]) === 0 && (scrollbarDummyElement0[LEXICON.oW] - scrollbarDummyElement0[LEXICON.cW]) === 0;\r\n\r\n return result;\r\n })(),\r\n overlayScrollbarDummySize: { x: 30, y: 30 },\r\n cssCalc: VENDORS._cssPropertyValue('width', 'calc', '(1px)') || null,\r\n restrictedMeasuring: (function () {\r\n //https://bugzilla.mozilla.org/show_bug.cgi?id=1439305\r\n //since 1.11.0 always false -> fixed via CSS (hopefully)\r\n scrollbarDummyElement.css(strOverflow, strHidden);\r\n var scrollSize = {\r\n w: scrollbarDummyElement0[LEXICON.sW],\r\n h: scrollbarDummyElement0[LEXICON.sH]\r\n };\r\n scrollbarDummyElement.css(strOverflow, 'visible');\r\n var scrollSize2 = {\r\n w: scrollbarDummyElement0[LEXICON.sW],\r\n h: scrollbarDummyElement0[LEXICON.sH]\r\n };\r\n return (scrollSize.w - scrollSize2.w) !== 0 || (scrollSize.h - scrollSize2.h) !== 0;\r\n })(),\r\n rtlScrollBehavior: (function () {\r\n scrollbarDummyElement.css({ 'overflow-y': strHidden, 'overflow-x': strScroll, 'direction': 'rtl' }).scrollLeft(0);\r\n var dummyContainerOffset = scrollbarDummyElement.offset();\r\n var dummyContainerChildOffset = dummyContainerChild.offset();\r\n //https://github.com/KingSora/OverlayScrollbars/issues/187\r\n scrollbarDummyElement.scrollLeft(-999);\r\n var dummyContainerChildOffsetAfterScroll = dummyContainerChild.offset();\r\n return {\r\n //origin direction = determines if the zero scroll position is on the left or right side\r\n //'i' means 'invert' (i === true means that the axis must be inverted to be correct)\r\n //true = on the left side\r\n //false = on the right side\r\n i: dummyContainerOffset.left === dummyContainerChildOffset.left,\r\n //negative = determines if the maximum scroll is positive or negative\r\n //'n' means 'negate' (n === true means that the axis must be negated to be correct)\r\n //true = negative\r\n //false = positive\r\n n: dummyContainerChildOffset.left !== dummyContainerChildOffsetAfterScroll.left\r\n };\r\n })(),\r\n supportTransform: !!VENDORS._cssProperty('transform'),\r\n supportTransition: !!VENDORS._cssProperty('transition'),\r\n supportPassiveEvents: (function () {\r\n var supportsPassive = false;\r\n try {\r\n window.addEventListener('test', null, Object.defineProperty({}, 'passive', {\r\n get: function () {\r\n supportsPassive = true;\r\n }\r\n }));\r\n } catch (e) { }\r\n return supportsPassive;\r\n })(),\r\n supportResizeObserver: !!COMPATIBILITY.rO(),\r\n supportMutationObserver: !!COMPATIBILITY.mO()\r\n });\r\n\r\n scrollbarDummyElement.removeAttr(LEXICON.s).remove();\r\n\r\n //Catch zoom event:\r\n (function () {\r\n if (nativeScrollbarIsOverlaid.x && nativeScrollbarIsOverlaid.y)\r\n return;\r\n\r\n var abs = MATH.abs;\r\n var windowWidth = COMPATIBILITY.wW();\r\n var windowHeight = COMPATIBILITY.wH();\r\n var windowDpr = getWindowDPR();\r\n var onResize = function () {\r\n if (INSTANCES().length > 0) {\r\n var newW = COMPATIBILITY.wW();\r\n var newH = COMPATIBILITY.wH();\r\n var deltaW = newW - windowWidth;\r\n var deltaH = newH - windowHeight;\r\n\r\n if (deltaW === 0 && deltaH === 0)\r\n return;\r\n\r\n var deltaWRatio = MATH.round(newW / (windowWidth / 100.0));\r\n var deltaHRatio = MATH.round(newH / (windowHeight / 100.0));\r\n var absDeltaW = abs(deltaW);\r\n var absDeltaH = abs(deltaH);\r\n var absDeltaWRatio = abs(deltaWRatio);\r\n var absDeltaHRatio = abs(deltaHRatio);\r\n var newDPR = getWindowDPR();\r\n\r\n var deltaIsBigger = absDeltaW > 2 && absDeltaH > 2;\r\n var difference = !differenceIsBiggerThanOne(absDeltaWRatio, absDeltaHRatio);\r\n var dprChanged = newDPR !== windowDpr && windowDpr > 0;\r\n var isZoom = deltaIsBigger && difference && dprChanged;\r\n var oldScrollbarSize = _base.nativeScrollbarSize;\r\n var newScrollbarSize;\r\n\r\n if (isZoom) {\r\n bodyElement.append(scrollbarDummyElement);\r\n newScrollbarSize = _base.nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement[0]);\r\n scrollbarDummyElement.remove();\r\n if (oldScrollbarSize.x !== newScrollbarSize.x || oldScrollbarSize.y !== newScrollbarSize.y) {\r\n FRAMEWORK.each(INSTANCES(), function () {\r\n if (INSTANCES(this))\r\n INSTANCES(this).update('zoom');\r\n });\r\n }\r\n }\r\n\r\n windowWidth = newW;\r\n windowHeight = newH;\r\n windowDpr = newDPR;\r\n }\r\n };\r\n\r\n function differenceIsBiggerThanOne(valOne, valTwo) {\r\n var absValOne = abs(valOne);\r\n var absValTwo = abs(valTwo);\r\n return !(absValOne === absValTwo || absValOne + 1 === absValTwo || absValOne - 1 === absValTwo);\r\n }\r\n\r\n function getWindowDPR() {\r\n var dDPI = window.screen.deviceXDPI || 0;\r\n var sDPI = window.screen.logicalXDPI || 1;\r\n return window.devicePixelRatio || (dDPI / sDPI);\r\n }\r\n\r\n FRAMEWORK(window).on('resize', onResize);\r\n })();\r\n\r\n function calcNativeScrollbarSize(measureElement) {\r\n return {\r\n x: measureElement[LEXICON.oH] - measureElement[LEXICON.cH],\r\n y: measureElement[LEXICON.oW] - measureElement[LEXICON.cW]\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * The object which manages the auto update loop for all OverlayScrollbars objects. This object is initialized only once: if the first OverlayScrollbars object gets initialized.\r\n * @constructor\r\n */\r\n function OverlayScrollbarsAutoUpdateLoop(globals) {\r\n var _base = this;\r\n var _inArray = FRAMEWORK.inArray;\r\n var _getNow = COMPATIBILITY.now;\r\n var _strAutoUpdate = 'autoUpdate';\r\n var _strAutoUpdateInterval = _strAutoUpdate + 'Interval';\r\n var _strLength = LEXICON.l;\r\n var _loopingInstances = [];\r\n var _loopingInstancesIntervalCache = [];\r\n var _loopIsActive = false;\r\n var _loopIntervalDefault = 33;\r\n var _loopInterval = _loopIntervalDefault;\r\n var _loopTimeOld = _getNow();\r\n var _loopID;\r\n\r\n\r\n /**\r\n * The auto update loop which will run every 50 milliseconds or less if the update interval of a instance is lower than 50 milliseconds.\r\n */\r\n var loop = function () {\r\n if (_loopingInstances[_strLength] > 0 && _loopIsActive) {\r\n _loopID = COMPATIBILITY.rAF()(function () {\r\n loop();\r\n });\r\n var timeNew = _getNow();\r\n var timeDelta = timeNew - _loopTimeOld;\r\n var lowestInterval;\r\n var instance;\r\n var instanceOptions;\r\n var instanceAutoUpdateAllowed;\r\n var instanceAutoUpdateInterval;\r\n var now;\r\n\r\n if (timeDelta > _loopInterval) {\r\n _loopTimeOld = timeNew - (timeDelta % _loopInterval);\r\n lowestInterval = _loopIntervalDefault;\r\n for (var i = 0; i < _loopingInstances[_strLength]; i++) {\r\n instance = _loopingInstances[i];\r\n if (instance !== undefined) {\r\n instanceOptions = instance.options();\r\n instanceAutoUpdateAllowed = instanceOptions[_strAutoUpdate];\r\n instanceAutoUpdateInterval = MATH.max(1, instanceOptions[_strAutoUpdateInterval]);\r\n now = _getNow();\r\n\r\n if ((instanceAutoUpdateAllowed === true || instanceAutoUpdateAllowed === null) && (now - _loopingInstancesIntervalCache[i]) > instanceAutoUpdateInterval) {\r\n instance.update('auto');\r\n _loopingInstancesIntervalCache[i] = new Date(now += instanceAutoUpdateInterval);\r\n }\r\n\r\n lowestInterval = MATH.max(1, MATH.min(lowestInterval, instanceAutoUpdateInterval));\r\n }\r\n }\r\n _loopInterval = lowestInterval;\r\n }\r\n } else {\r\n _loopInterval = _loopIntervalDefault;\r\n }\r\n };\r\n\r\n /**\r\n * Add OverlayScrollbars instance to the auto update loop. Only successful if the instance isn't already added.\r\n * @param instance The instance which shall be updated in a loop automatically.\r\n */\r\n _base.add = function (instance) {\r\n if (_inArray(instance, _loopingInstances) === -1) {\r\n _loopingInstances.push(instance);\r\n _loopingInstancesIntervalCache.push(_getNow());\r\n if (_loopingInstances[_strLength] > 0 && !_loopIsActive) {\r\n _loopIsActive = true;\r\n globals.autoUpdateLoop = _loopIsActive;\r\n loop();\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Remove OverlayScrollbars instance from the auto update loop. Only successful if the instance was added before.\r\n * @param instance The instance which shall be updated in a loop automatically.\r\n */\r\n _base.remove = function (instance) {\r\n var index = _inArray(instance, _loopingInstances);\r\n if (index > -1) {\r\n //remove from loopingInstances list\r\n _loopingInstancesIntervalCache.splice(index, 1);\r\n _loopingInstances.splice(index, 1);\r\n\r\n //correct update loop behavior\r\n if (_loopingInstances[_strLength] === 0 && _loopIsActive) {\r\n _loopIsActive = false;\r\n globals.autoUpdateLoop = _loopIsActive;\r\n if (_loopID !== undefined) {\r\n COMPATIBILITY.cAF()(_loopID);\r\n _loopID = -1;\r\n }\r\n }\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * A object which manages the scrollbars visibility of the target element.\r\n * @param pluginTargetElement The element from which the scrollbars shall be hidden.\r\n * @param options The custom options.\r\n * @param extensions The custom extensions.\r\n * @param globals\r\n * @param autoUpdateLoop\r\n * @returns {*}\r\n * @constructor\r\n */\r\n function OverlayScrollbarsInstance(pluginTargetElement, options, extensions, globals, autoUpdateLoop) {\r\n //shortcuts\r\n var type = COMPATIBILITY.type;\r\n var inArray = FRAMEWORK.inArray;\r\n var each = FRAMEWORK.each;\r\n\r\n //make correct instanceof\r\n var _base = new _plugin();\r\n var _frameworkProto = FRAMEWORK[LEXICON.p];\r\n\r\n //if passed element is no HTML element: skip and return\r\n if (!isHTMLElement(pluginTargetElement))\r\n return;\r\n\r\n //if passed element is already initialized: set passed options if there are any and return its instance\r\n if (INSTANCES(pluginTargetElement)) {\r\n var inst = INSTANCES(pluginTargetElement);\r\n inst.options(options);\r\n return inst;\r\n }\r\n\r\n //globals:\r\n var _nativeScrollbarIsOverlaid;\r\n var _overlayScrollbarDummySize;\r\n var _rtlScrollBehavior;\r\n var _autoUpdateRecommended;\r\n var _msieVersion;\r\n var _nativeScrollbarStyling;\r\n var _cssCalc;\r\n var _nativeScrollbarSize;\r\n var _supportTransition;\r\n var _supportTransform;\r\n var _supportPassiveEvents;\r\n var _supportResizeObserver;\r\n var _supportMutationObserver;\r\n var _restrictedMeasuring;\r\n\r\n //general readonly:\r\n var _initialized;\r\n var _destroyed;\r\n var _isTextarea;\r\n var _isBody;\r\n var _documentMixed;\r\n var _domExists;\r\n\r\n //general:\r\n var _isBorderBox;\r\n var _sizeAutoObserverAdded;\r\n var _paddingX;\r\n var _paddingY;\r\n var _borderX;\r\n var _borderY;\r\n var _marginX;\r\n var _marginY;\r\n var _isRTL;\r\n var _sleeping;\r\n var _contentBorderSize = {};\r\n var _scrollHorizontalInfo = {};\r\n var _scrollVerticalInfo = {};\r\n var _viewportSize = {};\r\n var _nativeScrollbarMinSize = {};\r\n\r\n //naming:\t\r\n var _strMinusHidden = '-hidden';\r\n var _strMarginMinus = 'margin-';\r\n var _strPaddingMinus = 'padding-';\r\n var _strBorderMinus = 'border-';\r\n var _strTop = 'top';\r\n var _strRight = 'right';\r\n var _strBottom = 'bottom';\r\n var _strLeft = 'left';\r\n var _strMinMinus = 'min-';\r\n var _strMaxMinus = 'max-';\r\n var _strWidth = 'width';\r\n var _strHeight = 'height';\r\n var _strFloat = 'float';\r\n var _strEmpty = '';\r\n var _strAuto = 'auto';\r\n var _strSync = 'sync';\r\n var _strScroll = 'scroll';\r\n var _strHundredPercent = '100%';\r\n var _strX = 'x';\r\n var _strY = 'y';\r\n var _strDot = '.';\r\n var _strSpace = ' ';\r\n var _strScrollbar = 'scrollbar';\r\n var _strMinusHorizontal = '-horizontal';\r\n var _strMinusVertical = '-vertical';\r\n var _strScrollLeft = _strScroll + 'Left';\r\n var _strScrollTop = _strScroll + 'Top';\r\n var _strMouseTouchDownEvent = 'mousedown touchstart';\r\n var _strMouseTouchUpEvent = 'mouseup touchend touchcancel';\r\n var _strMouseTouchMoveEvent = 'mousemove touchmove';\r\n var _strMouseEnter = 'mouseenter';\r\n var _strMouseLeave = 'mouseleave';\r\n var _strKeyDownEvent = 'keydown';\r\n var _strKeyUpEvent = 'keyup';\r\n var _strSelectStartEvent = 'selectstart';\r\n var _strTransitionEndEvent = 'transitionend webkitTransitionEnd oTransitionEnd';\r\n var _strResizeObserverProperty = '__overlayScrollbarsRO__';\r\n\r\n //class names:\t\r\n var _cassNamesPrefix = 'os-';\r\n var _classNameHTMLElement = _cassNamesPrefix + 'html';\r\n var _classNameHostElement = _cassNamesPrefix + 'host';\r\n var _classNameHostElementForeign = _classNameHostElement + '-foreign';\r\n var _classNameHostTextareaElement = _classNameHostElement + '-textarea';\r\n var _classNameHostScrollbarHorizontalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusHorizontal + _strMinusHidden;\r\n var _classNameHostScrollbarVerticalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusVertical + _strMinusHidden;\r\n var _classNameHostTransition = _classNameHostElement + '-transition';\r\n var _classNameHostRTL = _classNameHostElement + '-rtl';\r\n var _classNameHostResizeDisabled = _classNameHostElement + '-resize-disabled';\r\n var _classNameHostScrolling = _classNameHostElement + '-scrolling';\r\n var _classNameHostOverflow = _classNameHostElement + '-overflow';\r\n var _classNameHostOverflow = _classNameHostElement + '-overflow';\r\n var _classNameHostOverflowX = _classNameHostOverflow + '-x';\r\n var _classNameHostOverflowY = _classNameHostOverflow + '-y';\r\n var _classNameTextareaElement = _cassNamesPrefix + 'textarea';\r\n var _classNameTextareaCoverElement = _classNameTextareaElement + '-cover';\r\n var _classNamePaddingElement = _cassNamesPrefix + 'padding';\r\n var _classNameViewportElement = _cassNamesPrefix + 'viewport';\r\n var _classNameViewportNativeScrollbarsInvisible = _classNameViewportElement + '-native-scrollbars-invisible';\r\n var _classNameViewportNativeScrollbarsOverlaid = _classNameViewportElement + '-native-scrollbars-overlaid';\r\n var _classNameContentElement = _cassNamesPrefix + 'content';\r\n var _classNameContentArrangeElement = _cassNamesPrefix + 'content-arrange';\r\n var _classNameContentGlueElement = _cassNamesPrefix + 'content-glue';\r\n var _classNameSizeAutoObserverElement = _cassNamesPrefix + 'size-auto-observer';\r\n var _classNameResizeObserverElement = _cassNamesPrefix + 'resize-observer';\r\n var _classNameResizeObserverItemElement = _cassNamesPrefix + 'resize-observer-item';\r\n var _classNameResizeObserverItemFinalElement = _classNameResizeObserverItemElement + '-final';\r\n var _classNameTextInherit = _cassNamesPrefix + 'text-inherit';\r\n var _classNameScrollbar = _cassNamesPrefix + _strScrollbar;\r\n var _classNameScrollbarTrack = _classNameScrollbar + '-track';\r\n var _classNameScrollbarTrackOff = _classNameScrollbarTrack + '-off';\r\n var _classNameScrollbarHandle = _classNameScrollbar + '-handle';\r\n var _classNameScrollbarHandleOff = _classNameScrollbarHandle + '-off';\r\n var _classNameScrollbarUnusable = _classNameScrollbar + '-unusable';\r\n var _classNameScrollbarAutoHidden = _classNameScrollbar + '-' + _strAuto + _strMinusHidden;\r\n var _classNameScrollbarCorner = _classNameScrollbar + '-corner';\r\n var _classNameScrollbarCornerResize = _classNameScrollbarCorner + '-resize';\r\n var _classNameScrollbarCornerResizeB = _classNameScrollbarCornerResize + '-both';\r\n var _classNameScrollbarCornerResizeH = _classNameScrollbarCornerResize + _strMinusHorizontal;\r\n var _classNameScrollbarCornerResizeV = _classNameScrollbarCornerResize + _strMinusVertical;\r\n var _classNameScrollbarHorizontal = _classNameScrollbar + _strMinusHorizontal;\r\n var _classNameScrollbarVertical = _classNameScrollbar + _strMinusVertical;\r\n var _classNameDragging = _cassNamesPrefix + 'dragging';\r\n var _classNameThemeNone = _cassNamesPrefix + 'theme-none';\r\n var _classNamesDynamicDestroy = [\r\n _classNameViewportNativeScrollbarsInvisible,\r\n _classNameViewportNativeScrollbarsOverlaid,\r\n _classNameScrollbarTrackOff,\r\n _classNameScrollbarHandleOff,\r\n _classNameScrollbarUnusable,\r\n _classNameScrollbarAutoHidden,\r\n _classNameScrollbarCornerResize,\r\n _classNameScrollbarCornerResizeB,\r\n _classNameScrollbarCornerResizeH,\r\n _classNameScrollbarCornerResizeV,\r\n _classNameDragging].join(_strSpace);\r\n\r\n //callbacks:\t\r\n var _callbacksInitQeueue = [];\r\n\r\n //attrs viewport shall inherit from target\t\r\n var _viewportAttrsFromTarget = [LEXICON.ti];\r\n\r\n //options:\t\r\n var _defaultOptions;\r\n var _currentOptions;\r\n var _currentPreparedOptions;\r\n\r\n //extensions:\t\r\n var _extensions = {};\r\n var _extensionsPrivateMethods = 'added removed on contract';\r\n\r\n //update\t\r\n var _lastUpdateTime;\r\n var _swallowedUpdateHints = {};\r\n var _swallowedUpdateTimeout;\r\n var _swallowUpdateLag = 42;\r\n var _updateOnLoadEventName = 'load';\r\n var _updateOnLoadElms = [];\r\n\r\n //DOM elements:\t\r\n var _windowElement;\r\n var _documentElement;\r\n var _htmlElement;\r\n var _bodyElement;\r\n var _targetElement; //the target element of this OverlayScrollbars object\t\r\n var _hostElement; //the host element of this OverlayScrollbars object -> may be the same as targetElement\t\r\n var _sizeAutoObserverElement; //observes size auto changes\t\r\n var _sizeObserverElement; //observes size and padding changes\t\r\n var _paddingElement; //manages the padding\t\r\n var _viewportElement; //is the viewport of our scrollbar model\t\r\n var _contentElement; //the element which holds the content\t\r\n var _contentArrangeElement; //is needed for correct sizing of the content element (only if native scrollbars are overlays)\t\r\n var _contentGlueElement; //has always the size of the content element\t\r\n var _textareaCoverElement; //only applied if target is a textarea element. Used for correct size calculation and for prevention of uncontrolled scrolling\t\r\n var _scrollbarCornerElement;\r\n var _scrollbarHorizontalElement;\r\n var _scrollbarHorizontalTrackElement;\r\n var _scrollbarHorizontalHandleElement;\r\n var _scrollbarVerticalElement;\r\n var _scrollbarVerticalTrackElement;\r\n var _scrollbarVerticalHandleElement;\r\n var _windowElementNative;\r\n var _documentElementNative;\r\n var _targetElementNative;\r\n var _hostElementNative;\r\n var _sizeAutoObserverElementNative;\r\n var _sizeObserverElementNative;\r\n var _paddingElementNative;\r\n var _viewportElementNative;\r\n var _contentElementNative;\r\n\r\n //Cache:\t\r\n var _hostSizeCache;\r\n var _contentScrollSizeCache;\r\n var _arrangeContentSizeCache;\r\n var _hasOverflowCache;\r\n var _hideOverflowCache;\r\n var _widthAutoCache;\r\n var _heightAutoCache;\r\n var _cssBoxSizingCache;\r\n var _cssPaddingCache;\r\n var _cssBorderCache;\r\n var _cssMarginCache;\r\n var _cssDirectionCache;\r\n var _cssDirectionDetectedCache;\r\n var _paddingAbsoluteCache;\r\n var _clipAlwaysCache;\r\n var _contentGlueSizeCache;\r\n var _overflowBehaviorCache;\r\n var _overflowAmountCache;\r\n var _ignoreOverlayScrollbarHidingCache;\r\n var _autoUpdateCache;\r\n var _sizeAutoCapableCache;\r\n var _contentElementScrollSizeChangeDetectedCache;\r\n var _hostElementSizeChangeDetectedCache;\r\n var _scrollbarsVisibilityCache;\r\n var _scrollbarsAutoHideCache;\r\n var _scrollbarsClickScrollingCache;\r\n var _scrollbarsDragScrollingCache;\r\n var _resizeCache;\r\n var _normalizeRTLCache;\r\n var _classNameCache;\r\n var _oldClassName;\r\n var _textareaAutoWrappingCache;\r\n var _textareaInfoCache;\r\n var _textareaSizeCache;\r\n var _textareaDynHeightCache;\r\n var _textareaDynWidthCache;\r\n var _bodyMinSizeCache;\r\n var _updateAutoCache = {};\r\n\r\n //MutationObserver:\t\r\n var _mutationObserverHost;\r\n var _mutationObserverContent;\r\n var _mutationObserverHostCallback;\r\n var _mutationObserverContentCallback;\r\n var _mutationObserversConnected;\r\n var _mutationObserverAttrsTextarea = ['wrap', 'cols', 'rows'];\r\n var _mutationObserverAttrsHost = [LEXICON.i, LEXICON.c, LEXICON.s, 'open'].concat(_viewportAttrsFromTarget);\r\n\r\n //events:\t\r\n var _destroyEvents = [];\r\n\r\n //textarea:\t\r\n var _textareaHasFocus;\r\n\r\n //scrollbars:\t\r\n var _scrollbarsAutoHideTimeoutId;\r\n var _scrollbarsAutoHideMoveTimeoutId;\r\n var _scrollbarsAutoHideDelay;\r\n var _scrollbarsAutoHideNever;\r\n var _scrollbarsAutoHideScroll;\r\n var _scrollbarsAutoHideMove;\r\n var _scrollbarsAutoHideLeave;\r\n var _scrollbarsHandleHovered;\r\n var _scrollbarsHandlesDefineScrollPos;\r\n\r\n //resize\t\r\n var _resizeNone;\r\n var _resizeBoth;\r\n var _resizeHorizontal;\r\n var _resizeVertical;\r\n\r\n\r\n //==== Event Listener ====//\t\r\n\r\n /**\t\r\n * Adds or removes a event listener from the given element. \t\r\n * @param element The element to which the event listener shall be applied or removed.\t\r\n * @param eventNames The name(s) of the events.\t\r\n * @param listener The method which shall be called.\t\r\n * @param remove True if the handler shall be removed, false or undefined if the handler shall be added.\t\r\n * @param passiveOrOptions The options for the event.\r\n */\r\n function setupResponsiveEventListener(element, eventNames, listener, remove, passiveOrOptions) {\r\n var collected = COMPATIBILITY.isA(eventNames) && COMPATIBILITY.isA(listener);\r\n var method = remove ? 'removeEventListener' : 'addEventListener';\r\n var onOff = remove ? 'off' : 'on';\r\n var events = collected ? false : eventNames.split(_strSpace)\r\n var i = 0;\r\n\r\n var passiveOrOptionsIsObj = FRAMEWORK.isPlainObject(passiveOrOptions);\r\n var passive = (_supportPassiveEvents && (passiveOrOptionsIsObj ? (passiveOrOptions._passive) : passiveOrOptions)) || false;\r\n var capture = passiveOrOptionsIsObj && (passiveOrOptions._capture || false);\r\n var nativeParam = _supportPassiveEvents ? {\r\n passive: passive,\r\n capture: capture,\r\n } : capture;\r\n\r\n if (collected) {\r\n for (; i < eventNames[LEXICON.l]; i++)\r\n setupResponsiveEventListener(element, eventNames[i], listener[i], remove, passiveOrOptions);\r\n }\r\n else {\r\n for (; i < events[LEXICON.l]; i++) {\r\n if(_supportPassiveEvents) {\r\n element[0][method](events[i], listener, nativeParam);\r\n }\r\n else {\r\n element[onOff](events[i], listener);\r\n } \r\n }\r\n }\r\n }\r\n\r\n\r\n function addDestroyEventListener(element, eventNames, listener, passive) {\r\n setupResponsiveEventListener(element, eventNames, listener, false, passive);\r\n _destroyEvents.push(COMPATIBILITY.bind(setupResponsiveEventListener, 0, element, eventNames, listener, true, passive));\r\n }\r\n\r\n //==== Resize Observer ====//\r\n\r\n /**\r\n * Adds or removes a resize observer from the given element.\r\n * @param targetElement The element to which the resize observer shall be added or removed.\r\n * @param onElementResizedCallback The callback which is fired every time the resize observer registers a size change or false / undefined if the resizeObserver shall be removed.\r\n */\r\n function setupResizeObserver(targetElement, onElementResizedCallback) {\r\n if (targetElement) {\r\n var resizeObserver = COMPATIBILITY.rO();\r\n var strAnimationStartEvent = 'animationstart mozAnimationStart webkitAnimationStart MSAnimationStart';\r\n var strChildNodes = 'childNodes';\r\n var constScroll = 3333333;\r\n var callback = function () {\r\n targetElement[_strScrollTop](constScroll)[_strScrollLeft](_isRTL ? _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll : constScroll);\r\n onElementResizedCallback();\r\n };\r\n //add resize observer:\r\n if (onElementResizedCallback) {\r\n if (_supportResizeObserver) {\r\n var element = targetElement.addClass('observed').append(generateDiv(_classNameResizeObserverElement)).contents()[0];\r\n var observer = element[_strResizeObserverProperty] = new resizeObserver(callback);\r\n observer.observe(element);\r\n }\r\n else {\r\n if (_msieVersion > 9 || !_autoUpdateRecommended) {\r\n targetElement.prepend(\r\n generateDiv(_classNameResizeObserverElement,\r\n generateDiv({ c: _classNameResizeObserverItemElement, dir: 'ltr' },\r\n generateDiv(_classNameResizeObserverItemElement,\r\n generateDiv(_classNameResizeObserverItemFinalElement)\r\n ) +\r\n generateDiv(_classNameResizeObserverItemElement,\r\n generateDiv({ c: _classNameResizeObserverItemFinalElement, style: 'width: 200%; height: 200%' })\r\n )\r\n )\r\n )\r\n );\r\n\r\n var observerElement = targetElement[0][strChildNodes][0][strChildNodes][0];\r\n var shrinkElement = FRAMEWORK(observerElement[strChildNodes][1]);\r\n var expandElement = FRAMEWORK(observerElement[strChildNodes][0]);\r\n var expandElementChild = FRAMEWORK(expandElement[0][strChildNodes][0]);\r\n var widthCache = observerElement[LEXICON.oW];\r\n var heightCache = observerElement[LEXICON.oH];\r\n var isDirty;\r\n var rAFId;\r\n var currWidth;\r\n var currHeight;\r\n var factor = 2;\r\n var nativeScrollbarSize = globals.nativeScrollbarSize; //care don't make changes to this object!!!\r\n var reset = function () {\r\n /*\r\n var sizeResetWidth = observerElement[LEXICON.oW] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y;\r\n var sizeResetHeight = observerElement[LEXICON.oH] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y;\r\n var expandChildCSS = {};\r\n expandChildCSS[_strWidth] = sizeResetWidth;\r\n expandChildCSS[_strHeight] = sizeResetHeight;\r\n expandElementChild.css(expandChildCSS);\r\n\r\n\r\n expandElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight);\r\n shrinkElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight);\r\n */\r\n expandElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll);\r\n shrinkElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll);\r\n };\r\n var onResized = function () {\r\n rAFId = 0;\r\n if (!isDirty)\r\n return;\r\n\r\n widthCache = currWidth;\r\n heightCache = currHeight;\r\n callback();\r\n };\r\n var onScroll = function (event) {\r\n currWidth = observerElement[LEXICON.oW];\r\n currHeight = observerElement[LEXICON.oH];\r\n isDirty = currWidth != widthCache || currHeight != heightCache;\r\n\r\n if (event && isDirty && !rAFId) {\r\n COMPATIBILITY.cAF()(rAFId);\r\n rAFId = COMPATIBILITY.rAF()(onResized);\r\n }\r\n else if (!event)\r\n onResized();\r\n\r\n reset();\r\n if (event) {\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n return false;\r\n };\r\n var expandChildCSS = {};\r\n var observerElementCSS = {};\r\n\r\n setTopRightBottomLeft(observerElementCSS, _strEmpty, [\r\n -((nativeScrollbarSize.y + 1) * factor),\r\n nativeScrollbarSize.x * -factor,\r\n nativeScrollbarSize.y * -factor,\r\n -((nativeScrollbarSize.x + 1) * factor)\r\n ]);\r\n\r\n FRAMEWORK(observerElement).css(observerElementCSS);\r\n expandElement.on(_strScroll, onScroll);\r\n shrinkElement.on(_strScroll, onScroll);\r\n targetElement.on(strAnimationStartEvent, function () {\r\n onScroll(false);\r\n });\r\n //lets assume that the divs will never be that large and a constant value is enough\r\n expandChildCSS[_strWidth] = constScroll;\r\n expandChildCSS[_strHeight] = constScroll;\r\n expandElementChild.css(expandChildCSS);\r\n\r\n reset();\r\n }\r\n else {\r\n var attachEvent = _documentElementNative.attachEvent;\r\n var isIE = _msieVersion !== undefined;\r\n if (attachEvent) {\r\n targetElement.prepend(generateDiv(_classNameResizeObserverElement));\r\n findFirst(targetElement, _strDot + _classNameResizeObserverElement)[0].attachEvent('onresize', callback);\r\n }\r\n else {\r\n var obj = _documentElementNative.createElement(TYPES.o);\r\n obj.setAttribute(LEXICON.ti, '-1');\r\n obj.setAttribute(LEXICON.c, _classNameResizeObserverElement);\r\n obj.onload = function () {\r\n var wnd = this.contentDocument.defaultView;\r\n wnd.addEventListener('resize', callback);\r\n wnd.document.documentElement.style.display = 'none';\r\n };\r\n obj.type = 'text/html';\r\n if (isIE)\r\n targetElement.prepend(obj);\r\n obj.data = 'about:blank';\r\n if (!isIE)\r\n targetElement.prepend(obj);\r\n targetElement.on(strAnimationStartEvent, callback);\r\n }\r\n }\r\n }\r\n\r\n if (targetElement[0] === _sizeObserverElementNative) {\r\n var directionChanged = function () {\r\n var dir = _hostElement.css('direction');\r\n var css = {};\r\n var scrollLeftValue = 0;\r\n var result = false;\r\n if (dir !== _cssDirectionDetectedCache) {\r\n if (dir === 'ltr') {\r\n css[_strLeft] = 0;\r\n css[_strRight] = _strAuto;\r\n scrollLeftValue = constScroll;\r\n }\r\n else {\r\n css[_strLeft] = _strAuto;\r\n css[_strRight] = 0;\r\n scrollLeftValue = _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll;\r\n }\r\n //execution order is important for IE!!!\r\n _sizeObserverElement.children().eq(0).css(css);\r\n _sizeObserverElement[_strScrollLeft](scrollLeftValue)[_strScrollTop](constScroll);\r\n _cssDirectionDetectedCache = dir;\r\n result = true;\r\n }\r\n return result;\r\n };\r\n directionChanged();\r\n addDestroyEventListener(targetElement, _strScroll, function (event) {\r\n if (directionChanged())\r\n update();\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n return false;\r\n });\r\n }\r\n }\r\n //remove resize observer:\r\n else {\r\n if (_supportResizeObserver) {\r\n var element = targetElement.contents()[0];\r\n var resizeObserverObj = element[_strResizeObserverProperty];\r\n if (resizeObserverObj) {\r\n resizeObserverObj.disconnect();\r\n delete element[_strResizeObserverProperty];\r\n }\r\n }\r\n else {\r\n remove(targetElement.children(_strDot + _classNameResizeObserverElement).eq(0));\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Freezes or unfreezes the given resize observer.\r\n * @param targetElement The element to which the target resize observer is applied.\r\n * @param freeze True if the resize observer shall be frozen, false otherwise.\r\n \r\n function freezeResizeObserver(targetElement, freeze) {\r\n if (targetElement !== undefined) {\r\n if(freeze) {\r\n if (_supportResizeObserver) {\r\n var element = targetElement.contents()[0];\r\n element[_strResizeObserverProperty].unobserve(element);\r\n }\r\n else {\r\n targetElement = targetElement.children(_strDot + _classNameResizeObserverElement).eq(0);\r\n var w = targetElement.css(_strWidth);\r\n var h = targetElement.css(_strHeight);\r\n var css = {};\r\n css[_strWidth] = w;\r\n css[_strHeight] = h;\r\n targetElement.css(css);\r\n }\r\n }\r\n else {\r\n if (_supportResizeObserver) {\r\n var element = targetElement.contents()[0];\r\n element[_strResizeObserverProperty].observe(element);\r\n }\r\n else {\r\n var css = { };\r\n css[_strHeight] = _strEmpty;\r\n css[_strWidth] = _strEmpty;\r\n targetElement.children(_strDot + _classNameResizeObserverElement).eq(0).css(css);\r\n }\r\n }\r\n }\r\n }\r\n */\r\n\r\n\r\n //==== Mutation Observers ====//\r\n\r\n /**\r\n * Creates MutationObservers for the host and content Element if they are supported.\r\n */\r\n function createMutationObservers() {\r\n if (_supportMutationObserver) {\r\n var mutationObserverContentLag = 11;\r\n var mutationObserver = COMPATIBILITY.mO();\r\n var contentLastUpdate = COMPATIBILITY.now();\r\n var mutationTarget;\r\n var mutationAttrName;\r\n var mutationIsClass;\r\n var oldMutationVal;\r\n var newClassVal;\r\n var hostClassNameRegex;\r\n var contentTimeout;\r\n var now;\r\n var sizeAuto;\r\n var action;\r\n\r\n _mutationObserverHostCallback = function (mutations) {\r\n\r\n var doUpdate = false;\r\n var doUpdateForce = false;\r\n var mutation;\r\n var mutatedAttrs = [];\r\n\r\n if (_initialized && !_sleeping) {\r\n each(mutations, function () {\r\n mutation = this;\r\n mutationTarget = mutation.target;\r\n mutationAttrName = mutation.attributeName;\r\n mutationIsClass = mutationAttrName === LEXICON.c;\r\n oldMutationVal = mutation.oldValue;\r\n newClassVal = mutationTarget.className;\r\n\r\n if (_domExists && mutationIsClass && !doUpdateForce) {\r\n // if old class value contains _classNameHostElementForeign and new class value doesn't\r\n if (oldMutationVal.indexOf(_classNameHostElementForeign) > -1 && newClassVal.indexOf(_classNameHostElementForeign) < 0) {\r\n hostClassNameRegex = createHostClassNameRegExp(true);\r\n _hostElementNative.className = newClassVal.split(_strSpace).concat(oldMutationVal.split(_strSpace).filter(function (name) {\r\n return name.match(hostClassNameRegex);\r\n })).join(_strSpace);\r\n doUpdate = doUpdateForce = true;\r\n }\r\n }\r\n\r\n if (!doUpdate) {\r\n doUpdate = mutationIsClass\r\n ? hostClassNamesChanged(oldMutationVal, newClassVal)\r\n : mutationAttrName === LEXICON.s\r\n ? oldMutationVal !== mutationTarget[LEXICON.s].cssText\r\n : true;\r\n }\r\n\r\n mutatedAttrs.push(mutationAttrName);\r\n });\r\n\r\n updateViewportAttrsFromTarget(mutatedAttrs);\r\n\r\n if (doUpdate)\r\n _base.update(doUpdateForce || _strAuto);\r\n }\r\n return doUpdate;\r\n };\r\n _mutationObserverContentCallback = function (mutations) {\r\n var doUpdate = false;\r\n var mutation;\r\n\r\n if (_initialized && !_sleeping) {\r\n each(mutations, function () {\r\n mutation = this;\r\n doUpdate = isUnknownMutation(mutation);\r\n return !doUpdate;\r\n });\r\n\r\n if (doUpdate) {\r\n now = COMPATIBILITY.now();\r\n sizeAuto = (_heightAutoCache || _widthAutoCache);\r\n action = function () {\r\n if (!_destroyed) {\r\n contentLastUpdate = now;\r\n\r\n //if cols, rows or wrap attr was changed\r\n if (_isTextarea)\r\n textareaUpdate();\r\n\r\n if (sizeAuto)\r\n update();\r\n else\r\n _base.update(_strAuto);\r\n }\r\n };\r\n clearTimeout(contentTimeout);\r\n if (mutationObserverContentLag <= 0 || now - contentLastUpdate > mutationObserverContentLag || !sizeAuto)\r\n action();\r\n else\r\n contentTimeout = setTimeout(action, mutationObserverContentLag);\r\n }\r\n }\r\n return doUpdate;\r\n }\r\n\r\n _mutationObserverHost = new mutationObserver(_mutationObserverHostCallback);\r\n _mutationObserverContent = new mutationObserver(_mutationObserverContentCallback);\r\n }\r\n }\r\n\r\n /**\r\n * Connects the MutationObservers if they are supported.\r\n */\r\n function connectMutationObservers() {\r\n if (_supportMutationObserver && !_mutationObserversConnected) {\r\n _mutationObserverHost.observe(_hostElementNative, {\r\n attributes: true,\r\n attributeOldValue: true,\r\n attributeFilter: _mutationObserverAttrsHost\r\n });\r\n\r\n _mutationObserverContent.observe(_isTextarea ? _targetElementNative : _contentElementNative, {\r\n attributes: true,\r\n attributeOldValue: true,\r\n subtree: !_isTextarea,\r\n childList: !_isTextarea,\r\n characterData: !_isTextarea,\r\n attributeFilter: _isTextarea ? _mutationObserverAttrsTextarea : _mutationObserverAttrsHost\r\n });\r\n\r\n _mutationObserversConnected = true;\r\n }\r\n }\r\n\r\n /**\r\n * Disconnects the MutationObservers if they are supported.\r\n */\r\n function disconnectMutationObservers() {\r\n if (_supportMutationObserver && _mutationObserversConnected) {\r\n _mutationObserverHost.disconnect();\r\n _mutationObserverContent.disconnect();\r\n\r\n _mutationObserversConnected = false;\r\n }\r\n }\r\n\r\n\r\n //==== Events of elements ====//\r\n\r\n /**\r\n * This method gets called every time the host element gets resized. IMPORTANT: Padding changes are detected too!!\r\n * It refreshes the hostResizedEventArgs and the hostSizeResizeCache.\r\n * If there are any size changes, the update method gets called.\r\n */\r\n function hostOnResized() {\r\n if (!_sleeping) {\r\n var changed;\r\n var hostSize = {\r\n w: _sizeObserverElementNative[LEXICON.sW],\r\n h: _sizeObserverElementNative[LEXICON.sH]\r\n };\r\n\r\n changed = checkCache(hostSize, _hostElementSizeChangeDetectedCache);\r\n _hostElementSizeChangeDetectedCache = hostSize;\r\n if (changed)\r\n update({ _hostSizeChanged: true });\r\n }\r\n }\r\n\r\n /**\r\n * The mouse enter event of the host element. This event is only needed for the autoHide feature.\r\n */\r\n function hostOnMouseEnter() {\r\n if (_scrollbarsAutoHideLeave)\r\n refreshScrollbarsAutoHide(true);\r\n }\r\n\r\n /**\r\n * The mouse leave event of the host element. This event is only needed for the autoHide feature.\r\n */\r\n function hostOnMouseLeave() {\r\n if (_scrollbarsAutoHideLeave && !_bodyElement.hasClass(_classNameDragging))\r\n refreshScrollbarsAutoHide(false);\r\n }\r\n\r\n /**\r\n * The mouse move event of the host element. This event is only needed for the autoHide \"move\" feature.\r\n */\r\n function hostOnMouseMove() {\r\n if (_scrollbarsAutoHideMove) {\r\n refreshScrollbarsAutoHide(true);\r\n clearTimeout(_scrollbarsAutoHideMoveTimeoutId);\r\n _scrollbarsAutoHideMoveTimeoutId = setTimeout(function () {\r\n if (_scrollbarsAutoHideMove && !_destroyed)\r\n refreshScrollbarsAutoHide(false);\r\n }, 100);\r\n }\r\n }\r\n\r\n /**\r\n * Prevents text from deselection if attached to the document element on the mousedown event of a DOM element.\r\n * @param event The select start event.\r\n */\r\n function documentOnSelectStart(event) {\r\n COMPATIBILITY.prvD(event);\r\n return false;\r\n }\r\n\r\n /**\t\r\n * A callback which will be called after a element has loaded.\t\r\n */\r\n function updateOnLoadCallback(event) {\r\n var elm = FRAMEWORK(event.target);\r\n\r\n eachUpdateOnLoad(function (i, updateOnLoadSelector) {\r\n if (elm.is(updateOnLoadSelector)) {\r\n update({ _contentSizeChanged: true });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Adds or removes mouse & touch events of the host element. (for handling auto-hiding of the scrollbars)\r\n * @param destroy Indicates whether the events shall be added or removed.\r\n */\r\n function setupHostMouseTouchEvents(destroy) {\r\n if (!destroy)\r\n setupHostMouseTouchEvents(true);\r\n\r\n setupResponsiveEventListener(_hostElement,\r\n _strMouseTouchMoveEvent.split(_strSpace)[0],\r\n hostOnMouseMove,\r\n (!_scrollbarsAutoHideMove || destroy), true);\r\n setupResponsiveEventListener(_hostElement,\r\n [_strMouseEnter, _strMouseLeave],\r\n [hostOnMouseEnter, hostOnMouseLeave],\r\n (!_scrollbarsAutoHideLeave || destroy), true);\r\n\r\n //if the plugin is initialized and the mouse is over the host element, make the scrollbars visible\r\n if (!_initialized && !destroy)\r\n _hostElement.one('mouseover', hostOnMouseEnter);\r\n }\r\n\r\n\r\n //==== Update Detection ====//\r\n\r\n /**\r\n * Measures the min width and min height of the body element and refreshes the related cache.\r\n * @returns {boolean} True if the min width or min height has changed, false otherwise.\r\n */\r\n function bodyMinSizeChanged() {\r\n var bodyMinSize = {};\r\n if (_isBody && _contentArrangeElement) {\r\n bodyMinSize.w = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strWidth));\r\n bodyMinSize.h = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strHeight));\r\n bodyMinSize.c = checkCache(bodyMinSize, _bodyMinSizeCache);\r\n bodyMinSize.f = true; //flag for \"measured at least once\"\r\n }\r\n _bodyMinSizeCache = bodyMinSize;\r\n return !!bodyMinSize.c;\r\n }\r\n\r\n /**\r\n * Returns true if the class names really changed (new class without plugin host prefix)\r\n * @param oldClassNames The old ClassName string or array.\r\n * @param newClassNames The new ClassName string or array.\r\n * @returns {boolean} True if the class names has really changed, false otherwise.\r\n */\r\n function hostClassNamesChanged(oldClassNames, newClassNames) {\r\n var currClasses = typeof newClassNames == TYPES.s ? newClassNames.split(_strSpace) : [];\r\n var oldClasses = typeof oldClassNames == TYPES.s ? oldClassNames.split(_strSpace) : [];\r\n var diff = getArrayDifferences(oldClasses, currClasses);\r\n\r\n // remove none theme from diff list to prevent update\r\n var idx = inArray(_classNameThemeNone, diff);\r\n var i;\r\n var regex;\r\n\r\n if (idx > -1)\r\n diff.splice(idx, 1);\r\n\r\n if (diff[LEXICON.l] > 0) {\r\n regex = createHostClassNameRegExp(true, true);\r\n for (i = 0; i < diff.length; i++) {\r\n if (!diff[i].match(regex)) {\r\n return true;\r\n }\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Returns true if the given mutation is not from a from the plugin generated element. If the target element is a textarea the mutation is always unknown.\r\n * @param mutation The mutation which shall be checked.\r\n * @returns {boolean} True if the mutation is from a unknown element, false otherwise.\r\n */\r\n function isUnknownMutation(mutation) {\r\n var attributeName = mutation.attributeName;\r\n var mutationTarget = mutation.target;\r\n var mutationType = mutation.type;\r\n var strClosest = 'closest';\r\n\r\n if (mutationTarget === _contentElementNative)\r\n return attributeName === null;\r\n if (mutationType === 'attributes' && (attributeName === LEXICON.c || attributeName === LEXICON.s) && !_isTextarea) {\r\n //ignore className changes by the plugin\t\r\n if (attributeName === LEXICON.c && FRAMEWORK(mutationTarget).hasClass(_classNameHostElement))\r\n return hostClassNamesChanged(mutation.oldValue, mutationTarget.className);\r\n\r\n //only do it of browser support it natively\t\r\n if (typeof mutationTarget[strClosest] != TYPES.f)\r\n return true;\r\n if (mutationTarget[strClosest](_strDot + _classNameResizeObserverElement) !== null ||\r\n mutationTarget[strClosest](_strDot + _classNameScrollbar) !== null ||\r\n mutationTarget[strClosest](_strDot + _classNameScrollbarCorner) !== null)\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns true if the content size was changed since the last time this method was called.\r\n * @returns {boolean} True if the content size was changed, false otherwise.\r\n */\r\n function updateAutoContentSizeChanged() {\r\n if (_sleeping)\r\n return false;\r\n\r\n var contentMeasureElement = getContentMeasureElement();\r\n var textareaValueLength = _isTextarea && _widthAutoCache && !_textareaAutoWrappingCache ? _targetElement.val().length : 0;\r\n var setCSS = !_mutationObserversConnected && _widthAutoCache && !_isTextarea;\r\n var css = {};\r\n var float;\r\n var bodyMinSizeC;\r\n var changed;\r\n var contentElementScrollSize;\r\n\r\n if (setCSS) {\r\n float = _contentElement.css(_strFloat);\r\n css[_strFloat] = _isRTL ? _strRight : _strLeft;\r\n css[_strWidth] = _strAuto;\r\n _contentElement.css(css);\r\n }\r\n contentElementScrollSize = {\r\n w: contentMeasureElement[LEXICON.sW] + textareaValueLength,\r\n h: contentMeasureElement[LEXICON.sH] + textareaValueLength\r\n };\r\n if (setCSS) {\r\n css[_strFloat] = float;\r\n css[_strWidth] = _strHundredPercent;\r\n _contentElement.css(css);\r\n }\r\n\r\n bodyMinSizeC = bodyMinSizeChanged();\r\n changed = checkCache(contentElementScrollSize, _contentElementScrollSizeChangeDetectedCache);\r\n\r\n _contentElementScrollSizeChangeDetectedCache = contentElementScrollSize;\r\n\r\n return changed || bodyMinSizeC;\r\n }\r\n\r\n /**\r\n * Returns true when a attribute which the MutationObserver would observe has changed. \r\n * @returns {boolean} True if one of the attributes which a MutationObserver would observe has changed, false or undefined otherwise.\r\n */\r\n function meaningfulAttrsChanged() {\r\n if (_sleeping || _mutationObserversConnected)\r\n return;\r\n\r\n var elem;\r\n var curr;\r\n var cache;\r\n var changedAttrs = [];\r\n var checks = [\r\n {\r\n _elem: _hostElement,\r\n _attrs: _mutationObserverAttrsHost.concat(':visible')\r\n },\r\n {\r\n _elem: _isTextarea ? _targetElement : undefined,\r\n _attrs: _mutationObserverAttrsTextarea\r\n }\r\n ];\r\n\r\n each(checks, function (index, check) {\r\n elem = check._elem;\r\n if (elem) {\r\n each(check._attrs, function (index, attr) {\r\n curr = attr.charAt(0) === ':' ? elem.is(attr) : elem.attr(attr);\r\n cache = _updateAutoCache[attr];\r\n\r\n if (checkCache(curr, cache)) {\r\n changedAttrs.push(attr);\r\n }\r\n\r\n _updateAutoCache[attr] = curr;\r\n });\r\n }\r\n });\r\n\r\n updateViewportAttrsFromTarget(changedAttrs);\r\n\r\n return changedAttrs[LEXICON.l] > 0;\r\n }\r\n\r\n /**\r\n * Checks is a CSS Property of a child element is affecting the scroll size of the content.\r\n * @param propertyName The CSS property name.\r\n * @returns {boolean} True if the property is affecting the content scroll size, false otherwise.\r\n */\r\n function isSizeAffectingCSSProperty(propertyName) {\r\n if (!_initialized)\r\n return true;\r\n var flexGrow = 'flex-grow';\r\n var flexShrink = 'flex-shrink';\r\n var flexBasis = 'flex-basis';\r\n var affectingPropsX = [\r\n _strWidth,\r\n _strMinMinus + _strWidth,\r\n _strMaxMinus + _strWidth,\r\n _strMarginMinus + _strLeft,\r\n _strMarginMinus + _strRight,\r\n _strLeft,\r\n _strRight,\r\n 'font-weight',\r\n 'word-spacing',\r\n flexGrow,\r\n flexShrink,\r\n flexBasis\r\n ];\r\n var affectingPropsXContentBox = [\r\n _strPaddingMinus + _strLeft,\r\n _strPaddingMinus + _strRight,\r\n _strBorderMinus + _strLeft + _strWidth,\r\n _strBorderMinus + _strRight + _strWidth\r\n ];\r\n var affectingPropsY = [\r\n _strHeight,\r\n _strMinMinus + _strHeight,\r\n _strMaxMinus + _strHeight,\r\n _strMarginMinus + _strTop,\r\n _strMarginMinus + _strBottom,\r\n _strTop,\r\n _strBottom,\r\n 'line-height',\r\n flexGrow,\r\n flexShrink,\r\n flexBasis\r\n ];\r\n var affectingPropsYContentBox = [\r\n _strPaddingMinus + _strTop,\r\n _strPaddingMinus + _strBottom,\r\n _strBorderMinus + _strTop + _strWidth,\r\n _strBorderMinus + _strBottom + _strWidth\r\n ];\r\n var _strS = 's';\r\n var _strVS = 'v-s';\r\n var checkX = _overflowBehaviorCache.x === _strS || _overflowBehaviorCache.x === _strVS;\r\n var checkY = _overflowBehaviorCache.y === _strS || _overflowBehaviorCache.y === _strVS;\r\n var sizeIsAffected = false;\r\n var checkPropertyName = function (arr, name) {\r\n for (var i = 0; i < arr[LEXICON.l]; i++) {\r\n if (arr[i] === name)\r\n return true;\r\n }\r\n return false;\r\n };\r\n\r\n if (checkY) {\r\n sizeIsAffected = checkPropertyName(affectingPropsY, propertyName);\r\n if (!sizeIsAffected && !_isBorderBox)\r\n sizeIsAffected = checkPropertyName(affectingPropsYContentBox, propertyName);\r\n }\r\n if (checkX && !sizeIsAffected) {\r\n sizeIsAffected = checkPropertyName(affectingPropsX, propertyName);\r\n if (!sizeIsAffected && !_isBorderBox)\r\n sizeIsAffected = checkPropertyName(affectingPropsXContentBox, propertyName);\r\n }\r\n return sizeIsAffected;\r\n }\r\n\r\n\r\n //==== Update ====//\r\n\r\n /**\r\n * Sets the attribute values of the viewport element to the values from the target element.\r\n * The value of a attribute is only set if the attribute is whitelisted.\r\n * @attrs attrs The array of attributes which shall be set or undefined if all whitelisted shall be set.\r\n */\r\n function updateViewportAttrsFromTarget(attrs) {\r\n attrs = attrs || _viewportAttrsFromTarget;\r\n each(attrs, function (index, attr) {\r\n if (COMPATIBILITY.inA(attr, _viewportAttrsFromTarget) > -1) {\r\n var targetAttr = _targetElement.attr(attr);\r\n if (type(targetAttr) == TYPES.s) {\r\n _viewportElement.attr(attr, targetAttr);\r\n }\r\n else {\r\n _viewportElement.removeAttr(attr);\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Updates the variables and size of the textarea element, and manages the scroll on new line or new character.\r\n */\r\n function textareaUpdate() {\r\n if (!_sleeping) {\r\n var wrapAttrOff = !_textareaAutoWrappingCache;\r\n var minWidth = _viewportSize.w;\r\n var minHeight = _viewportSize.h;\r\n var css = {};\r\n var doMeasure = _widthAutoCache || wrapAttrOff;\r\n var origWidth;\r\n var width;\r\n var origHeight;\r\n var height;\r\n\r\n //reset min size\r\n css[_strMinMinus + _strWidth] = _strEmpty;\r\n css[_strMinMinus + _strHeight] = _strEmpty;\r\n\r\n //set width auto\r\n css[_strWidth] = _strAuto;\r\n _targetElement.css(css);\r\n\r\n //measure width\r\n origWidth = _targetElementNative[LEXICON.oW];\r\n width = doMeasure ? MATH.max(origWidth, _targetElementNative[LEXICON.sW] - 1) : 1;\r\n /*width += (_widthAutoCache ? _marginX + (!_isBorderBox ? wrapAttrOff ? 0 : _paddingX + _borderX : 0) : 0);*/\r\n\r\n //set measured width\r\n css[_strWidth] = _widthAutoCache ? _strAuto /*width*/ : _strHundredPercent;\r\n css[_strMinMinus + _strWidth] = _strHundredPercent;\r\n\r\n //set height auto\r\n css[_strHeight] = _strAuto;\r\n _targetElement.css(css);\r\n\r\n //measure height\r\n origHeight = _targetElementNative[LEXICON.oH];\r\n height = MATH.max(origHeight, _targetElementNative[LEXICON.sH] - 1);\r\n\r\n //append correct size values\r\n css[_strWidth] = width;\r\n css[_strHeight] = height;\r\n _textareaCoverElement.css(css);\r\n\r\n //apply min width / min height to prevent textarea collapsing\r\n css[_strMinMinus + _strWidth] = minWidth /*+ (!_isBorderBox && _widthAutoCache ? _paddingX + _borderX : 0)*/;\r\n css[_strMinMinus + _strHeight] = minHeight /*+ (!_isBorderBox && _heightAutoCache ? _paddingY + _borderY : 0)*/;\r\n _targetElement.css(css);\r\n\r\n return {\r\n _originalWidth: origWidth,\r\n _originalHeight: origHeight,\r\n _dynamicWidth: width,\r\n _dynamicHeight: height\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Updates the plugin and DOM to the current options.\r\n * This method should only be called if a update is 100% required.\r\n * @param updateHints A objects which contains hints for this update:\r\n * {\r\n * _hostSizeChanged : boolean,\r\n * _contentSizeChanged : boolean,\r\n * _force : boolean, == preventSwallowing\r\n * _changedOptions : { }, == preventSwallowing && preventSleep\r\n * }\r\n */\r\n function update(updateHints) {\r\n clearTimeout(_swallowedUpdateTimeout);\r\n updateHints = updateHints || {};\r\n _swallowedUpdateHints._hostSizeChanged |= updateHints._hostSizeChanged;\r\n _swallowedUpdateHints._contentSizeChanged |= updateHints._contentSizeChanged;\r\n _swallowedUpdateHints._force |= updateHints._force;\r\n\r\n var now = COMPATIBILITY.now();\r\n var hostSizeChanged = !!_swallowedUpdateHints._hostSizeChanged;\r\n var contentSizeChanged = !!_swallowedUpdateHints._contentSizeChanged;\r\n var force = !!_swallowedUpdateHints._force;\r\n var changedOptions = updateHints._changedOptions;\r\n var swallow = _swallowUpdateLag > 0 && _initialized && !_destroyed && !force && !changedOptions && (now - _lastUpdateTime) < _swallowUpdateLag && (!_heightAutoCache && !_widthAutoCache);\r\n var displayIsHidden;\r\n\r\n if (swallow)\r\n _swallowedUpdateTimeout = setTimeout(update, _swallowUpdateLag);\r\n\r\n //abort update due to:\r\n //destroyed\r\n //swallowing\r\n //sleeping\r\n //host is hidden or has false display\r\n if (_destroyed || swallow || (_sleeping && !changedOptions) || (_initialized && !force && (displayIsHidden = _hostElement.is(':hidden'))) || _hostElement.css('display') === 'inline')\r\n return;\r\n\r\n _lastUpdateTime = now;\r\n _swallowedUpdateHints = {};\r\n\r\n //if scrollbar styling is possible and native scrollbars aren't overlaid the scrollbar styling will be applied which hides the native scrollbars completely.\r\n if (_nativeScrollbarStyling && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) {\r\n //native scrollbars are hidden, so change the values to zero\r\n _nativeScrollbarSize.x = 0;\r\n _nativeScrollbarSize.y = 0;\r\n }\r\n else {\r\n //refresh native scrollbar size (in case of zoom)\r\n _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize);\r\n }\r\n\r\n // Scrollbar padding is needed for firefox, because firefox hides scrollbar automatically if the size of the div is too small.\r\n // The calculation: [scrollbar size +3 *3]\r\n // (+3 because of possible decoration e.g. borders, margins etc., but only if native scrollbar is NOT a overlaid scrollbar)\r\n // (*3 because (1)increase / (2)decrease -button and (3)resize handle)\r\n _nativeScrollbarMinSize = {\r\n x: (_nativeScrollbarSize.x + (_nativeScrollbarIsOverlaid.x ? 0 : 3)) * 3,\r\n y: (_nativeScrollbarSize.y + (_nativeScrollbarIsOverlaid.y ? 0 : 3)) * 3\r\n };\r\n\r\n changedOptions = changedOptions || {};\r\n //freezeResizeObserver(_sizeObserverElement, true);\r\n //freezeResizeObserver(_sizeAutoObserverElement, true);\r\n\r\n var checkCacheAutoForce = function () {\r\n return checkCache.apply(this, [].slice.call(arguments).concat([force]));\r\n };\r\n\r\n //save current scroll offset\r\n var currScroll = {\r\n x: _viewportElement[_strScrollLeft](),\r\n y: _viewportElement[_strScrollTop]()\r\n };\r\n\r\n var currentPreparedOptionsScrollbars = _currentPreparedOptions.scrollbars;\r\n var currentPreparedOptionsTextarea = _currentPreparedOptions.textarea;\r\n\r\n //scrollbars visibility:\r\n var scrollbarsVisibility = currentPreparedOptionsScrollbars.visibility;\r\n var scrollbarsVisibilityChanged = checkCacheAutoForce(scrollbarsVisibility, _scrollbarsVisibilityCache);\r\n\r\n //scrollbars autoHide:\r\n var scrollbarsAutoHide = currentPreparedOptionsScrollbars.autoHide;\r\n var scrollbarsAutoHideChanged = checkCacheAutoForce(scrollbarsAutoHide, _scrollbarsAutoHideCache);\r\n\r\n //scrollbars click scrolling\r\n var scrollbarsClickScrolling = currentPreparedOptionsScrollbars.clickScrolling;\r\n var scrollbarsClickScrollingChanged = checkCacheAutoForce(scrollbarsClickScrolling, _scrollbarsClickScrollingCache);\r\n\r\n //scrollbars drag scrolling\r\n var scrollbarsDragScrolling = currentPreparedOptionsScrollbars.dragScrolling;\r\n var scrollbarsDragScrollingChanged = checkCacheAutoForce(scrollbarsDragScrolling, _scrollbarsDragScrollingCache);\r\n\r\n //className\r\n var className = _currentPreparedOptions.className;\r\n var classNameChanged = checkCacheAutoForce(className, _classNameCache);\r\n\r\n //resize\r\n var resize = _currentPreparedOptions.resize;\r\n var resizeChanged = checkCacheAutoForce(resize, _resizeCache) && !_isBody; //body can't be resized since the window itself acts as resize possibility.\r\n\r\n //paddingAbsolute\r\n var paddingAbsolute = _currentPreparedOptions.paddingAbsolute;\r\n var paddingAbsoluteChanged = checkCacheAutoForce(paddingAbsolute, _paddingAbsoluteCache);\r\n\r\n //clipAlways\r\n var clipAlways = _currentPreparedOptions.clipAlways;\r\n var clipAlwaysChanged = checkCacheAutoForce(clipAlways, _clipAlwaysCache);\r\n\r\n //sizeAutoCapable\r\n var sizeAutoCapable = _currentPreparedOptions.sizeAutoCapable && !_isBody; //body can never be size auto, because it shall be always as big as the viewport.\r\n var sizeAutoCapableChanged = checkCacheAutoForce(sizeAutoCapable, _sizeAutoCapableCache);\r\n\r\n //showNativeScrollbars\r\n var ignoreOverlayScrollbarHiding = _currentPreparedOptions.nativeScrollbarsOverlaid.showNativeScrollbars;\r\n var ignoreOverlayScrollbarHidingChanged = checkCacheAutoForce(ignoreOverlayScrollbarHiding, _ignoreOverlayScrollbarHidingCache);\r\n\r\n //autoUpdate\r\n var autoUpdate = _currentPreparedOptions.autoUpdate;\r\n var autoUpdateChanged = checkCacheAutoForce(autoUpdate, _autoUpdateCache);\r\n\r\n //overflowBehavior\r\n var overflowBehavior = _currentPreparedOptions.overflowBehavior;\r\n var overflowBehaviorChanged = checkCacheAutoForce(overflowBehavior, _overflowBehaviorCache, force);\r\n\r\n //dynWidth:\r\n var textareaDynWidth = currentPreparedOptionsTextarea.dynWidth;\r\n var textareaDynWidthChanged = checkCacheAutoForce(_textareaDynWidthCache, textareaDynWidth);\r\n\r\n //dynHeight:\r\n var textareaDynHeight = currentPreparedOptionsTextarea.dynHeight;\r\n var textareaDynHeightChanged = checkCacheAutoForce(_textareaDynHeightCache, textareaDynHeight);\r\n\r\n //scrollbars visibility\r\n _scrollbarsAutoHideNever = scrollbarsAutoHide === 'n';\r\n _scrollbarsAutoHideScroll = scrollbarsAutoHide === 's';\r\n _scrollbarsAutoHideMove = scrollbarsAutoHide === 'm';\r\n _scrollbarsAutoHideLeave = scrollbarsAutoHide === 'l';\r\n\r\n //scrollbars autoHideDelay\r\n _scrollbarsAutoHideDelay = currentPreparedOptionsScrollbars.autoHideDelay;\r\n\r\n //old className\r\n _oldClassName = _classNameCache;\r\n\r\n //resize\r\n _resizeNone = resize === 'n';\r\n _resizeBoth = resize === 'b';\r\n _resizeHorizontal = resize === 'h';\r\n _resizeVertical = resize === 'v';\r\n\r\n //normalizeRTL\r\n _normalizeRTLCache = _currentPreparedOptions.normalizeRTL;\r\n\r\n //ignore overlay scrollbar hiding\r\n ignoreOverlayScrollbarHiding = ignoreOverlayScrollbarHiding && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y);\r\n\r\n //refresh options cache\r\n _scrollbarsVisibilityCache = scrollbarsVisibility;\r\n _scrollbarsAutoHideCache = scrollbarsAutoHide;\r\n _scrollbarsClickScrollingCache = scrollbarsClickScrolling;\r\n _scrollbarsDragScrollingCache = scrollbarsDragScrolling;\r\n _classNameCache = className;\r\n _resizeCache = resize;\r\n _paddingAbsoluteCache = paddingAbsolute;\r\n _clipAlwaysCache = clipAlways;\r\n _sizeAutoCapableCache = sizeAutoCapable;\r\n _ignoreOverlayScrollbarHidingCache = ignoreOverlayScrollbarHiding;\r\n _autoUpdateCache = autoUpdate;\r\n _overflowBehaviorCache = extendDeep({}, overflowBehavior);\r\n _textareaDynWidthCache = textareaDynWidth;\r\n _textareaDynHeightCache = textareaDynHeight;\r\n _hasOverflowCache = _hasOverflowCache || { x: false, y: false };\r\n\r\n //set correct class name to the host element\r\n if (classNameChanged) {\r\n removeClass(_hostElement, _oldClassName + _strSpace + _classNameThemeNone);\r\n addClass(_hostElement, className !== undefined && className !== null && className.length > 0 ? className : _classNameThemeNone);\r\n }\r\n\r\n //set correct auto Update\r\n if (autoUpdateChanged) {\r\n if (autoUpdate === true || (autoUpdate === null && _autoUpdateRecommended)) {\r\n disconnectMutationObservers();\r\n autoUpdateLoop.add(_base);\r\n }\r\n else {\r\n autoUpdateLoop.remove(_base);\r\n connectMutationObservers();\r\n }\r\n }\r\n\r\n //activate or deactivate size auto capability\r\n if (sizeAutoCapableChanged) {\r\n if (sizeAutoCapable) {\r\n if (_contentGlueElement) {\r\n _contentGlueElement.show();\r\n }\r\n else {\r\n _contentGlueElement = FRAMEWORK(generateDiv(_classNameContentGlueElement));\r\n _paddingElement.before(_contentGlueElement);\r\n }\r\n if (_sizeAutoObserverAdded) {\r\n _sizeAutoObserverElement.show();\r\n }\r\n else {\r\n _sizeAutoObserverElement = FRAMEWORK(generateDiv(_classNameSizeAutoObserverElement));\r\n _sizeAutoObserverElementNative = _sizeAutoObserverElement[0];\r\n\r\n _contentGlueElement.before(_sizeAutoObserverElement);\r\n var oldSize = { w: -1, h: -1 };\r\n setupResizeObserver(_sizeAutoObserverElement, function () {\r\n var newSize = {\r\n w: _sizeAutoObserverElementNative[LEXICON.oW],\r\n h: _sizeAutoObserverElementNative[LEXICON.oH]\r\n };\r\n if (checkCache(newSize, oldSize)) {\r\n if (_initialized && (_heightAutoCache && newSize.h > 0) || (_widthAutoCache && newSize.w > 0)) {\r\n update();\r\n }\r\n else if (_initialized && (!_heightAutoCache && newSize.h === 0) || (!_widthAutoCache && newSize.w === 0)) {\r\n update();\r\n }\r\n }\r\n oldSize = newSize;\r\n });\r\n _sizeAutoObserverAdded = true;\r\n //fix heightAuto detector bug if height is fixed but contentHeight is 0.\r\n //the probability this bug will ever happen is very very low, thats why its ok if we use calc which isn't supported in IE8.\r\n if (_cssCalc !== null)\r\n _sizeAutoObserverElement.css(_strHeight, _cssCalc + '(100% + 1px)');\r\n }\r\n }\r\n else {\r\n if (_sizeAutoObserverAdded)\r\n _sizeAutoObserverElement.hide();\r\n if (_contentGlueElement)\r\n _contentGlueElement.hide();\r\n }\r\n }\r\n\r\n //if force, update all resizeObservers too\r\n if (force) {\r\n _sizeObserverElement.find('*').trigger(_strScroll);\r\n if (_sizeAutoObserverAdded)\r\n _sizeAutoObserverElement.find('*').trigger(_strScroll);\r\n }\r\n\r\n //display hidden:\r\n displayIsHidden = displayIsHidden === undefined ? _hostElement.is(':hidden') : displayIsHidden;\r\n\r\n //textarea AutoWrapping:\r\n var textareaAutoWrapping = _isTextarea ? _targetElement.attr('wrap') !== 'off' : false;\r\n var textareaAutoWrappingChanged = checkCacheAutoForce(textareaAutoWrapping, _textareaAutoWrappingCache);\r\n\r\n //detect direction:\r\n var cssDirection = _hostElement.css('direction');\r\n var cssDirectionChanged = checkCacheAutoForce(cssDirection, _cssDirectionCache);\r\n\r\n //detect box-sizing:\r\n var boxSizing = _hostElement.css('box-sizing');\r\n var boxSizingChanged = checkCacheAutoForce(boxSizing, _cssBoxSizingCache);\r\n\r\n //detect padding:\r\n var padding = getTopRightBottomLeftHost(_strPaddingMinus);\r\n\r\n //width + height auto detecting var:\r\n var sizeAutoObserverElementBCRect;\r\n //exception occurs in IE8 sometimes (unknown exception)\r\n try {\r\n sizeAutoObserverElementBCRect = _sizeAutoObserverAdded ? _sizeAutoObserverElementNative[LEXICON.bCR]() : null;\r\n } catch (ex) {\r\n return;\r\n }\r\n\r\n _isRTL = cssDirection === 'rtl';\r\n _isBorderBox = (boxSizing === 'border-box');\r\n var isRTLLeft = _isRTL ? _strLeft : _strRight;\r\n var isRTLRight = _isRTL ? _strRight : _strLeft;\r\n\r\n //detect width auto:\r\n var widthAutoResizeDetection = false;\r\n var widthAutoObserverDetection = (_sizeAutoObserverAdded && (_hostElement.css(_strFloat) !== 'none' /*|| _isTextarea */)) ? (MATH.round(sizeAutoObserverElementBCRect.right - sizeAutoObserverElementBCRect.left) === 0) && (!paddingAbsolute ? (_hostElementNative[LEXICON.cW] - _paddingX) > 0 : true) : false;\r\n if (sizeAutoCapable && !widthAutoObserverDetection) {\r\n var tmpCurrHostWidth = _hostElementNative[LEXICON.oW];\r\n var tmpCurrContentGlueWidth = _contentGlueElement.css(_strWidth);\r\n _contentGlueElement.css(_strWidth, _strAuto);\r\n\r\n var tmpNewHostWidth = _hostElementNative[LEXICON.oW];\r\n _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth);\r\n widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth;\r\n if (!widthAutoResizeDetection) {\r\n _contentGlueElement.css(_strWidth, tmpCurrHostWidth + 1);\r\n tmpNewHostWidth = _hostElementNative[LEXICON.oW];\r\n _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth);\r\n widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth;\r\n }\r\n }\r\n var widthAuto = (widthAutoObserverDetection || widthAutoResizeDetection) && sizeAutoCapable && !displayIsHidden;\r\n var widthAutoChanged = checkCacheAutoForce(widthAuto, _widthAutoCache);\r\n var wasWidthAuto = !widthAuto && _widthAutoCache;\r\n\r\n //detect height auto:\r\n var heightAuto = _sizeAutoObserverAdded && sizeAutoCapable && !displayIsHidden ? (MATH.round(sizeAutoObserverElementBCRect.bottom - sizeAutoObserverElementBCRect.top) === 0) /* && (!paddingAbsolute && (_msieVersion > 9 || !_msieVersion) ? true : true) */ : false;\r\n var heightAutoChanged = checkCacheAutoForce(heightAuto, _heightAutoCache);\r\n var wasHeightAuto = !heightAuto && _heightAutoCache;\r\n\r\n //detect border:\r\n //we need the border only if border box and auto size\r\n var updateBorderX = (widthAuto && _isBorderBox) || !_isBorderBox;\r\n var updateBorderY = (heightAuto && _isBorderBox) || !_isBorderBox;\r\n var border = getTopRightBottomLeftHost(_strBorderMinus, '-' + _strWidth, !updateBorderX, !updateBorderY)\r\n\r\n //detect margin:\r\n var margin = getTopRightBottomLeftHost(_strMarginMinus);\r\n\r\n //vars to apply correct css\r\n var contentElementCSS = {};\r\n var contentGlueElementCSS = {};\r\n\r\n //funcs\r\n var getHostSize = function () {\r\n //has to be clientSize because offsetSize respect borders\r\n return {\r\n w: _hostElementNative[LEXICON.cW],\r\n h: _hostElementNative[LEXICON.cH]\r\n };\r\n };\r\n var getViewportSize = function () {\r\n //viewport size is padding container because it never has padding, margin and a border\r\n //determine zoom rounding error -> sometimes scrollWidth/Height is smaller than clientWidth/Height\r\n //if this happens add the difference to the viewportSize to compensate the rounding error\r\n return {\r\n w: _paddingElementNative[LEXICON.oW] + MATH.max(0, _contentElementNative[LEXICON.cW] - _contentElementNative[LEXICON.sW]),\r\n h: _paddingElementNative[LEXICON.oH] + MATH.max(0, _contentElementNative[LEXICON.cH] - _contentElementNative[LEXICON.sH])\r\n };\r\n };\r\n\r\n //set info for padding\r\n var paddingAbsoluteX = _paddingX = padding.l + padding.r;\r\n var paddingAbsoluteY = _paddingY = padding.t + padding.b;\r\n paddingAbsoluteX *= paddingAbsolute ? 1 : 0;\r\n paddingAbsoluteY *= paddingAbsolute ? 1 : 0;\r\n padding.c = checkCacheAutoForce(padding, _cssPaddingCache);\r\n\r\n //set info for border\r\n _borderX = border.l + border.r;\r\n _borderY = border.t + border.b;\r\n border.c = checkCacheAutoForce(border, _cssBorderCache);\r\n\r\n //set info for margin\r\n _marginX = margin.l + margin.r;\r\n _marginY = margin.t + margin.b;\r\n margin.c = checkCacheAutoForce(margin, _cssMarginCache);\r\n\r\n //refresh cache\r\n _textareaAutoWrappingCache = textareaAutoWrapping;\r\n _cssDirectionCache = cssDirection;\r\n _cssBoxSizingCache = boxSizing;\r\n _widthAutoCache = widthAuto;\r\n _heightAutoCache = heightAuto;\r\n _cssPaddingCache = padding;\r\n _cssBorderCache = border;\r\n _cssMarginCache = margin;\r\n\r\n //IEFix direction changed\r\n if (cssDirectionChanged && _sizeAutoObserverAdded)\r\n _sizeAutoObserverElement.css(_strFloat, isRTLRight);\r\n\r\n //apply padding:\r\n if (padding.c || cssDirectionChanged || paddingAbsoluteChanged || widthAutoChanged || heightAutoChanged || boxSizingChanged || sizeAutoCapableChanged) {\r\n var paddingElementCSS = {};\r\n var textareaCSS = {};\r\n var paddingValues = [padding.t, padding.r, padding.b, padding.l];\r\n\r\n setTopRightBottomLeft(contentGlueElementCSS, _strMarginMinus, [-padding.t, -padding.r, -padding.b, -padding.l]);\r\n if (paddingAbsolute) {\r\n setTopRightBottomLeft(paddingElementCSS, _strEmpty, paddingValues);\r\n setTopRightBottomLeft(_isTextarea ? textareaCSS : contentElementCSS, _strPaddingMinus);\r\n }\r\n else {\r\n setTopRightBottomLeft(paddingElementCSS, _strEmpty);\r\n setTopRightBottomLeft(_isTextarea ? textareaCSS : contentElementCSS, _strPaddingMinus, paddingValues);\r\n }\r\n\r\n _paddingElement.css(paddingElementCSS);\r\n _targetElement.css(textareaCSS);\r\n }\r\n\r\n //viewport size is padding container because it never has padding, margin and a border.\r\n _viewportSize = getViewportSize();\r\n\r\n //update Textarea\r\n var textareaSize = _isTextarea ? textareaUpdate() : false;\r\n var textareaSizeChanged = _isTextarea && checkCacheAutoForce(textareaSize, _textareaSizeCache);\r\n var textareaDynOrigSize = _isTextarea && textareaSize ? {\r\n w: textareaDynWidth ? textareaSize._dynamicWidth : textareaSize._originalWidth,\r\n h: textareaDynHeight ? textareaSize._dynamicHeight : textareaSize._originalHeight\r\n } : {};\r\n _textareaSizeCache = textareaSize;\r\n\r\n //fix height auto / width auto in cooperation with current padding & boxSizing behavior:\r\n if (heightAuto && (heightAutoChanged || paddingAbsoluteChanged || boxSizingChanged || padding.c || border.c)) {\r\n contentElementCSS[_strHeight] = _strAuto;\r\n }\r\n else if (heightAutoChanged || paddingAbsoluteChanged) {\r\n contentElementCSS[_strHeight] = _strHundredPercent;\r\n }\r\n if (widthAuto && (widthAutoChanged || paddingAbsoluteChanged || boxSizingChanged || padding.c || border.c || cssDirectionChanged)) {\r\n contentElementCSS[_strWidth] = _strAuto;\r\n contentGlueElementCSS[_strMaxMinus + _strWidth] = _strHundredPercent; //IE Fix\r\n }\r\n else if (widthAutoChanged || paddingAbsoluteChanged) {\r\n contentElementCSS[_strWidth] = _strHundredPercent;\r\n contentElementCSS[_strFloat] = _strEmpty;\r\n contentGlueElementCSS[_strMaxMinus + _strWidth] = _strEmpty; //IE Fix\r\n }\r\n if (widthAuto) {\r\n //textareaDynOrigSize.w || _strAuto :: doesnt works because applied margin will shift width\r\n contentGlueElementCSS[_strWidth] = _strAuto;\r\n\r\n contentElementCSS[_strWidth] = VENDORS._cssPropertyValue(_strWidth, 'max-content intrinsic') || _strAuto;\r\n contentElementCSS[_strFloat] = isRTLRight;\r\n }\r\n else {\r\n contentGlueElementCSS[_strWidth] = _strEmpty;\r\n }\r\n if (heightAuto) {\r\n //textareaDynOrigSize.h || _contentElementNative[LEXICON.cH] :: use for anti scroll jumping\r\n contentGlueElementCSS[_strHeight] = textareaDynOrigSize.h || _contentElementNative[LEXICON.cH];\r\n }\r\n else {\r\n contentGlueElementCSS[_strHeight] = _strEmpty;\r\n }\r\n if (sizeAutoCapable)\r\n _contentGlueElement.css(contentGlueElementCSS);\r\n _contentElement.css(contentElementCSS);\r\n\r\n //CHECKPOINT HERE ~\r\n contentElementCSS = {};\r\n contentGlueElementCSS = {};\r\n\r\n //if [content(host) client / scroll size, or target element direction, or content(host) max-sizes] changed, or force is true\r\n if (hostSizeChanged || contentSizeChanged || textareaSizeChanged || cssDirectionChanged || boxSizingChanged || paddingAbsoluteChanged || widthAutoChanged || widthAuto || heightAutoChanged || heightAuto || ignoreOverlayScrollbarHidingChanged || overflowBehaviorChanged || clipAlwaysChanged || resizeChanged || scrollbarsVisibilityChanged || scrollbarsAutoHideChanged || scrollbarsDragScrollingChanged || scrollbarsClickScrollingChanged || textareaDynWidthChanged || textareaDynHeightChanged || textareaAutoWrappingChanged) {\r\n var strOverflow = 'overflow';\r\n var strOverflowX = strOverflow + '-x';\r\n var strOverflowY = strOverflow + '-y';\r\n var strHidden = 'hidden';\r\n var strVisible = 'visible';\r\n\r\n //Reset the viewport (very important for natively overlaid scrollbars and zoom change\r\n //don't change the overflow prop as it is very expensive and affects performance !A LOT!\r\n if (!_nativeScrollbarStyling) {\r\n var viewportElementResetCSS = {};\r\n var resetXTmp = _hasOverflowCache.y && _hideOverflowCache.ys && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.y ? _viewportElement.css(isRTLLeft) : -_nativeScrollbarSize.y) : 0;\r\n var resetBottomTmp = _hasOverflowCache.x && _hideOverflowCache.xs && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.x ? _viewportElement.css(_strBottom) : -_nativeScrollbarSize.x) : 0;\r\n setTopRightBottomLeft(viewportElementResetCSS, _strEmpty);\r\n _viewportElement.css(viewportElementResetCSS);\r\n }\r\n\r\n //measure several sizes:\r\n var contentMeasureElement = getContentMeasureElement();\r\n //in Firefox content element has to have overflow hidden, else element margins aren't calculated properly, this element prevents this bug, but only if scrollbars aren't overlaid\r\n var contentSize = {\r\n //use clientSize because natively overlaidScrollbars add borders\r\n w: textareaDynOrigSize.w || contentMeasureElement[LEXICON.cW],\r\n h: textareaDynOrigSize.h || contentMeasureElement[LEXICON.cH]\r\n };\r\n var scrollSize = {\r\n w: contentMeasureElement[LEXICON.sW],\r\n h: contentMeasureElement[LEXICON.sH]\r\n };\r\n\r\n //apply the correct viewport style and measure viewport size\r\n if (!_nativeScrollbarStyling) {\r\n viewportElementResetCSS[_strBottom] = wasHeightAuto ? _strEmpty : resetBottomTmp;\r\n viewportElementResetCSS[isRTLLeft] = wasWidthAuto ? _strEmpty : resetXTmp;\r\n _viewportElement.css(viewportElementResetCSS);\r\n }\r\n _viewportSize = getViewportSize();\r\n\r\n //measure and correct several sizes\r\n var hostSize = getHostSize();\r\n var hostAbsoluteRectSize = {\r\n w: hostSize.w - _marginX - _borderX - (_isBorderBox ? 0 : _paddingX),\r\n h: hostSize.h - _marginY - _borderY - (_isBorderBox ? 0 : _paddingY)\r\n };\r\n var contentGlueSize = {\r\n //client/scrollSize + AbsolutePadding -> because padding is only applied to the paddingElement if its absolute, so you have to add it manually\r\n //hostSize is clientSize -> so padding should be added manually, right? FALSE! Because content glue is inside hostElement, so we don't have to worry about padding\r\n w: MATH.max((widthAuto ? contentSize.w : scrollSize.w) + paddingAbsoluteX, hostAbsoluteRectSize.w),\r\n h: MATH.max((heightAuto ? contentSize.h : scrollSize.h) + paddingAbsoluteY, hostAbsoluteRectSize.h)\r\n };\r\n contentGlueSize.c = checkCacheAutoForce(contentGlueSize, _contentGlueSizeCache);\r\n _contentGlueSizeCache = contentGlueSize;\r\n\r\n //apply correct contentGlue size\r\n if (sizeAutoCapable) {\r\n //size contentGlue correctly to make sure the element has correct size if the sizing switches to auto\r\n if (contentGlueSize.c || (heightAuto || widthAuto)) {\r\n contentGlueElementCSS[_strWidth] = contentGlueSize.w;\r\n contentGlueElementCSS[_strHeight] = contentGlueSize.h;\r\n\r\n //textarea-sizes are already calculated correctly at this point\r\n if (!_isTextarea) {\r\n contentSize = {\r\n //use clientSize because natively overlaidScrollbars add borders\r\n w: contentMeasureElement[LEXICON.cW],\r\n h: contentMeasureElement[LEXICON.cH]\r\n };\r\n }\r\n }\r\n var textareaCoverCSS = {};\r\n var setContentGlueElementCSSfunction = function (horizontal) {\r\n var scrollbarVars = getScrollbarVars(horizontal);\r\n var wh = scrollbarVars._w_h;\r\n var strWH = scrollbarVars._width_height;\r\n var autoSize = horizontal ? widthAuto : heightAuto;\r\n var borderSize = horizontal ? _borderX : _borderY;\r\n var paddingSize = horizontal ? _paddingX : _paddingY;\r\n var marginSize = horizontal ? _marginX : _marginY;\r\n var viewportSize = _viewportSize[wh] - borderSize - marginSize - (_isBorderBox ? 0 : paddingSize);\r\n\r\n //make contentGlue size -1 if element is not auto sized, to make sure that a resize event happens when the element shrinks\r\n if (!autoSize || (!autoSize && border.c))\r\n contentGlueElementCSS[strWH] = hostAbsoluteRectSize[wh] - 1;\r\n\r\n //if size is auto and host is smaller than size as min size, make content glue size -1 to make sure size changes will be detected (this is only needed if padding is 0)\r\n if (autoSize && (contentSize[wh] < viewportSize) && (horizontal && _isTextarea ? !textareaAutoWrapping : true)) {\r\n if (_isTextarea)\r\n textareaCoverCSS[strWH] = parseToZeroOrNumber(_textareaCoverElement.css(strWH)) - 1;\r\n contentGlueElementCSS[strWH] -= 1;\r\n }\r\n\r\n //make sure content glue size is at least 1\r\n if (contentSize[wh] > 0)\r\n contentGlueElementCSS[strWH] = MATH.max(1, contentGlueElementCSS[strWH]);\r\n };\r\n setContentGlueElementCSSfunction(true);\r\n setContentGlueElementCSSfunction(false);\r\n\r\n if (_isTextarea)\r\n _textareaCoverElement.css(textareaCoverCSS);\r\n _contentGlueElement.css(contentGlueElementCSS);\r\n }\r\n if (widthAuto)\r\n contentElementCSS[_strWidth] = _strHundredPercent;\r\n if (widthAuto && !_isBorderBox && !_mutationObserversConnected)\r\n contentElementCSS[_strFloat] = 'none';\r\n\r\n //apply and reset content style\r\n _contentElement.css(contentElementCSS);\r\n contentElementCSS = {};\r\n\r\n //measure again, but this time all correct sizes:\r\n var contentScrollSize = {\r\n w: contentMeasureElement[LEXICON.sW],\r\n h: contentMeasureElement[LEXICON.sH],\r\n };\r\n contentScrollSize.c = contentSizeChanged = checkCacheAutoForce(contentScrollSize, _contentScrollSizeCache);\r\n _contentScrollSizeCache = contentScrollSize;\r\n\r\n //refresh viewport size after correct measuring\r\n _viewportSize = getViewportSize();\r\n\r\n hostSize = getHostSize();\r\n hostSizeChanged = checkCacheAutoForce(hostSize, _hostSizeCache);\r\n _hostSizeCache = hostSize;\r\n\r\n var hideOverflowForceTextarea = _isTextarea && (_viewportSize.w === 0 || _viewportSize.h === 0);\r\n var previousOverflowAmount = _overflowAmountCache;\r\n var overflowBehaviorIsVS = {};\r\n var overflowBehaviorIsVH = {};\r\n var overflowBehaviorIsS = {};\r\n var overflowAmount = {};\r\n var hasOverflow = {};\r\n var hideOverflow = {};\r\n var canScroll = {};\r\n var viewportRect = _paddingElementNative[LEXICON.bCR]();\r\n var setOverflowVariables = function (horizontal) {\r\n var scrollbarVars = getScrollbarVars(horizontal);\r\n var scrollbarVarsInverted = getScrollbarVars(!horizontal);\r\n var xyI = scrollbarVarsInverted._x_y;\r\n var xy = scrollbarVars._x_y;\r\n var wh = scrollbarVars._w_h;\r\n var widthHeight = scrollbarVars._width_height;\r\n var scrollMax = _strScroll + scrollbarVars._Left_Top + 'Max';\r\n var fractionalOverflowAmount = viewportRect[widthHeight] ? MATH.abs(viewportRect[widthHeight] - _viewportSize[wh]) : 0;\r\n var checkFractionalOverflowAmount = previousOverflowAmount && previousOverflowAmount[xy] > 0 && _viewportElementNative[scrollMax] === 0;\r\n overflowBehaviorIsVS[xy] = overflowBehavior[xy] === 'v-s';\r\n overflowBehaviorIsVH[xy] = overflowBehavior[xy] === 'v-h';\r\n overflowBehaviorIsS[xy] = overflowBehavior[xy] === 's';\r\n overflowAmount[xy] = MATH.max(0, MATH.round((contentScrollSize[wh] - _viewportSize[wh]) * 100) / 100);\r\n overflowAmount[xy] *= (hideOverflowForceTextarea || (checkFractionalOverflowAmount && fractionalOverflowAmount > 0 && fractionalOverflowAmount < 1)) ? 0 : 1;\r\n hasOverflow[xy] = overflowAmount[xy] > 0;\r\n\r\n //hideOverflow:\r\n //x || y : true === overflow is hidden by \"overflow: scroll\" OR \"overflow: hidden\"\r\n //xs || ys : true === overflow is hidden by \"overflow: scroll\"\r\n hideOverflow[xy] = overflowBehaviorIsVS[xy] || overflowBehaviorIsVH[xy] ? (hasOverflow[xyI] && !overflowBehaviorIsVS[xyI] && !overflowBehaviorIsVH[xyI]) : hasOverflow[xy];\r\n hideOverflow[xy + 's'] = hideOverflow[xy] ? (overflowBehaviorIsS[xy] || overflowBehaviorIsVS[xy]) : false;\r\n\r\n canScroll[xy] = hasOverflow[xy] && hideOverflow[xy + 's'];\r\n };\r\n setOverflowVariables(true);\r\n setOverflowVariables(false);\r\n\r\n overflowAmount.c = checkCacheAutoForce(overflowAmount, _overflowAmountCache);\r\n _overflowAmountCache = overflowAmount;\r\n hasOverflow.c = checkCacheAutoForce(hasOverflow, _hasOverflowCache);\r\n _hasOverflowCache = hasOverflow;\r\n hideOverflow.c = checkCacheAutoForce(hideOverflow, _hideOverflowCache);\r\n _hideOverflowCache = hideOverflow;\r\n\r\n //if native scrollbar is overlay at x OR y axis, prepare DOM\r\n if (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y) {\r\n var borderDesign = 'px solid transparent';\r\n var contentArrangeElementCSS = {};\r\n var arrangeContent = {};\r\n var arrangeChanged = force;\r\n var setContentElementCSS;\r\n\r\n if (hasOverflow.x || hasOverflow.y) {\r\n arrangeContent.w = _nativeScrollbarIsOverlaid.y && hasOverflow.y ? contentScrollSize.w + _overlayScrollbarDummySize.y : _strEmpty;\r\n arrangeContent.h = _nativeScrollbarIsOverlaid.x && hasOverflow.x ? contentScrollSize.h + _overlayScrollbarDummySize.x : _strEmpty;\r\n arrangeChanged = checkCacheAutoForce(arrangeContent, _arrangeContentSizeCache);\r\n _arrangeContentSizeCache = arrangeContent;\r\n }\r\n\r\n if (hasOverflow.c || hideOverflow.c || contentScrollSize.c || cssDirectionChanged || widthAutoChanged || heightAutoChanged || widthAuto || heightAuto || ignoreOverlayScrollbarHidingChanged) {\r\n contentElementCSS[_strMarginMinus + isRTLRight] = contentElementCSS[_strBorderMinus + isRTLRight] = _strEmpty;\r\n setContentElementCSS = function (horizontal) {\r\n var scrollbarVars = getScrollbarVars(horizontal);\r\n var scrollbarVarsInverted = getScrollbarVars(!horizontal);\r\n var xy = scrollbarVars._x_y;\r\n var strDirection = horizontal ? _strBottom : isRTLLeft;\r\n var invertedAutoSize = horizontal ? heightAuto : widthAuto;\r\n\r\n if (_nativeScrollbarIsOverlaid[xy] && hasOverflow[xy] && hideOverflow[xy + 's']) {\r\n contentElementCSS[_strMarginMinus + strDirection] = invertedAutoSize ? (ignoreOverlayScrollbarHiding ? _strEmpty : _overlayScrollbarDummySize[xy]) : _strEmpty;\r\n contentElementCSS[_strBorderMinus + strDirection] = ((horizontal ? !invertedAutoSize : true) && !ignoreOverlayScrollbarHiding) ? (_overlayScrollbarDummySize[xy] + borderDesign) : _strEmpty;\r\n }\r\n else {\r\n arrangeContent[scrollbarVarsInverted._w_h] =\r\n contentElementCSS[_strMarginMinus + strDirection] =\r\n contentElementCSS[_strBorderMinus + strDirection] = _strEmpty;\r\n arrangeChanged = true;\r\n }\r\n };\r\n\r\n if (_nativeScrollbarStyling) {\r\n addRemoveClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible, !ignoreOverlayScrollbarHiding)\r\n }\r\n else {\r\n setContentElementCSS(true);\r\n setContentElementCSS(false);\r\n }\r\n }\r\n if (ignoreOverlayScrollbarHiding) {\r\n arrangeContent.w = arrangeContent.h = _strEmpty;\r\n arrangeChanged = true;\r\n }\r\n if (arrangeChanged && !_nativeScrollbarStyling) {\r\n contentArrangeElementCSS[_strWidth] = hideOverflow.y ? arrangeContent.w : _strEmpty;\r\n contentArrangeElementCSS[_strHeight] = hideOverflow.x ? arrangeContent.h : _strEmpty;\r\n\r\n if (!_contentArrangeElement) {\r\n _contentArrangeElement = FRAMEWORK(generateDiv(_classNameContentArrangeElement));\r\n _viewportElement.prepend(_contentArrangeElement);\r\n }\r\n _contentArrangeElement.css(contentArrangeElementCSS);\r\n }\r\n _contentElement.css(contentElementCSS);\r\n }\r\n\r\n var viewportElementCSS = {};\r\n var paddingElementCSS = {};\r\n var setViewportCSS;\r\n if (hostSizeChanged || hasOverflow.c || hideOverflow.c || contentScrollSize.c || overflowBehaviorChanged || boxSizingChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged || clipAlwaysChanged || heightAutoChanged) {\r\n viewportElementCSS[isRTLRight] = _strEmpty;\r\n setViewportCSS = function (horizontal) {\r\n var scrollbarVars = getScrollbarVars(horizontal);\r\n var scrollbarVarsInverted = getScrollbarVars(!horizontal);\r\n var xy = scrollbarVars._x_y;\r\n var XY = scrollbarVars._X_Y;\r\n var strDirection = horizontal ? _strBottom : isRTLLeft;\r\n\r\n var reset = function () {\r\n viewportElementCSS[strDirection] = _strEmpty;\r\n _contentBorderSize[scrollbarVarsInverted._w_h] = 0;\r\n };\r\n if (hasOverflow[xy] && hideOverflow[xy + 's']) {\r\n viewportElementCSS[strOverflow + XY] = _strScroll;\r\n if (ignoreOverlayScrollbarHiding || _nativeScrollbarStyling) {\r\n reset();\r\n }\r\n else {\r\n viewportElementCSS[strDirection] = -(_nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[xy] : _nativeScrollbarSize[xy]);\r\n _contentBorderSize[scrollbarVarsInverted._w_h] = _nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[scrollbarVarsInverted._x_y] : 0;\r\n }\r\n } else {\r\n viewportElementCSS[strOverflow + XY] = _strEmpty;\r\n reset();\r\n }\r\n };\r\n setViewportCSS(true);\r\n setViewportCSS(false);\r\n\r\n // if the scroll container is too small and if there is any overflow with no overlay scrollbar (and scrollbar styling isn't possible), \r\n // make viewport element greater in size (Firefox hide Scrollbars fix)\r\n // because firefox starts hiding scrollbars on too small elements\r\n // with this behavior the overflow calculation may be incorrect or the scrollbars would appear suddenly\r\n // https://bugzilla.mozilla.org/show_bug.cgi?id=292284\r\n if (!_nativeScrollbarStyling\r\n && (_viewportSize.h < _nativeScrollbarMinSize.x || _viewportSize.w < _nativeScrollbarMinSize.y)\r\n && ((hasOverflow.x && hideOverflow.x && !_nativeScrollbarIsOverlaid.x) || (hasOverflow.y && hideOverflow.y && !_nativeScrollbarIsOverlaid.y))) {\r\n viewportElementCSS[_strPaddingMinus + _strTop] = _nativeScrollbarMinSize.x;\r\n viewportElementCSS[_strMarginMinus + _strTop] = -_nativeScrollbarMinSize.x;\r\n\r\n viewportElementCSS[_strPaddingMinus + isRTLRight] = _nativeScrollbarMinSize.y;\r\n viewportElementCSS[_strMarginMinus + isRTLRight] = -_nativeScrollbarMinSize.y;\r\n }\r\n else {\r\n viewportElementCSS[_strPaddingMinus + _strTop] =\r\n viewportElementCSS[_strMarginMinus + _strTop] =\r\n viewportElementCSS[_strPaddingMinus + isRTLRight] =\r\n viewportElementCSS[_strMarginMinus + isRTLRight] = _strEmpty;\r\n }\r\n viewportElementCSS[_strPaddingMinus + isRTLLeft] =\r\n viewportElementCSS[_strMarginMinus + isRTLLeft] = _strEmpty;\r\n\r\n //if there is any overflow (x OR y axis) and this overflow shall be hidden, make overflow hidden, else overflow visible\r\n if ((hasOverflow.x && hideOverflow.x) || (hasOverflow.y && hideOverflow.y) || hideOverflowForceTextarea) {\r\n //only hide if is Textarea\r\n if (_isTextarea && hideOverflowForceTextarea) {\r\n paddingElementCSS[strOverflowX] =\r\n paddingElementCSS[strOverflowY] = strHidden;\r\n }\r\n }\r\n else {\r\n if (!clipAlways || (overflowBehaviorIsVH.x || overflowBehaviorIsVS.x || overflowBehaviorIsVH.y || overflowBehaviorIsVS.y)) {\r\n //only un-hide if Textarea\r\n if (_isTextarea) {\r\n paddingElementCSS[strOverflowX] =\r\n paddingElementCSS[strOverflowY] = _strEmpty;\r\n }\r\n viewportElementCSS[strOverflowX] =\r\n viewportElementCSS[strOverflowY] = strVisible;\r\n }\r\n }\r\n\r\n _paddingElement.css(paddingElementCSS);\r\n _viewportElement.css(viewportElementCSS);\r\n viewportElementCSS = {};\r\n\r\n //force soft redraw in webkit because without the scrollbars will may appear because DOM wont be redrawn under special conditions\r\n if ((hasOverflow.c || boxSizingChanged || widthAutoChanged || heightAutoChanged) && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) {\r\n var elementStyle = _contentElementNative[LEXICON.s];\r\n var dump;\r\n elementStyle.webkitTransform = 'scale(1)';\r\n elementStyle.display = 'run-in';\r\n dump = _contentElementNative[LEXICON.oH];\r\n elementStyle.display = _strEmpty; //|| dump; //use dump to prevent it from deletion if minify\r\n elementStyle.webkitTransform = _strEmpty;\r\n }\r\n /*\r\n //force hard redraw in webkit if native overlaid scrollbars shall appear\r\n if (ignoreOverlayScrollbarHidingChanged && ignoreOverlayScrollbarHiding) {\r\n _hostElement.hide();\r\n var dump = _hostElementNative[LEXICON.oH];\r\n _hostElement.show();\r\n }\r\n */\r\n }\r\n\r\n //change to direction RTL and width auto Bugfix in Webkit\r\n //without this fix, the DOM still thinks the scrollbar is LTR and thus the content is shifted to the left\r\n contentElementCSS = {};\r\n if (cssDirectionChanged || widthAutoChanged || heightAutoChanged) {\r\n if (_isRTL && widthAuto) {\r\n var floatTmp = _contentElement.css(_strFloat);\r\n var posLeftWithoutFloat = MATH.round(_contentElement.css(_strFloat, _strEmpty).css(_strLeft, _strEmpty).position().left);\r\n _contentElement.css(_strFloat, floatTmp);\r\n var posLeftWithFloat = MATH.round(_contentElement.position().left);\r\n\r\n if (posLeftWithoutFloat !== posLeftWithFloat)\r\n contentElementCSS[_strLeft] = posLeftWithoutFloat;\r\n }\r\n else {\r\n contentElementCSS[_strLeft] = _strEmpty;\r\n }\r\n }\r\n _contentElement.css(contentElementCSS);\r\n\r\n //handle scroll position\r\n if (_isTextarea && contentSizeChanged) {\r\n var textareaInfo = getTextareaInfo();\r\n if (textareaInfo) {\r\n var textareaRowsChanged = _textareaInfoCache === undefined ? true : textareaInfo._rows !== _textareaInfoCache._rows;\r\n var cursorRow = textareaInfo._cursorRow;\r\n var cursorCol = textareaInfo._cursorColumn;\r\n var widestRow = textareaInfo._widestRow;\r\n var lastRow = textareaInfo._rows;\r\n var lastCol = textareaInfo._columns;\r\n var cursorPos = textareaInfo._cursorPosition;\r\n var cursorMax = textareaInfo._cursorMax;\r\n var cursorIsLastPosition = (cursorPos >= cursorMax && _textareaHasFocus);\r\n var textareaScrollAmount = {\r\n x: (!textareaAutoWrapping && (cursorCol === lastCol && cursorRow === widestRow)) ? _overflowAmountCache.x : -1,\r\n y: (textareaAutoWrapping ? cursorIsLastPosition || textareaRowsChanged && (previousOverflowAmount ? (currScroll.y === previousOverflowAmount.y) : false) : (cursorIsLastPosition || textareaRowsChanged) && cursorRow === lastRow) ? _overflowAmountCache.y : -1\r\n };\r\n currScroll.x = textareaScrollAmount.x > -1 ? (_isRTL && _normalizeRTLCache && _rtlScrollBehavior.i ? 0 : textareaScrollAmount.x) : currScroll.x; //if inverted, scroll to 0 -> normalized this means to max scroll offset.\r\n currScroll.y = textareaScrollAmount.y > -1 ? textareaScrollAmount.y : currScroll.y;\r\n }\r\n _textareaInfoCache = textareaInfo;\r\n }\r\n if (_isRTL && _rtlScrollBehavior.i && _nativeScrollbarIsOverlaid.y && hasOverflow.x && _normalizeRTLCache)\r\n currScroll.x += _contentBorderSize.w || 0;\r\n if (widthAuto)\r\n _hostElement[_strScrollLeft](0);\r\n if (heightAuto)\r\n _hostElement[_strScrollTop](0);\r\n _viewportElement[_strScrollLeft](currScroll.x)[_strScrollTop](currScroll.y);\r\n\r\n //scrollbars management:\r\n var scrollbarsVisibilityVisible = scrollbarsVisibility === 'v';\r\n var scrollbarsVisibilityHidden = scrollbarsVisibility === 'h';\r\n var scrollbarsVisibilityAuto = scrollbarsVisibility === 'a';\r\n var refreshScrollbarsVisibility = function (showX, showY) {\r\n showY = showY === undefined ? showX : showY;\r\n refreshScrollbarAppearance(true, showX, canScroll.x)\r\n refreshScrollbarAppearance(false, showY, canScroll.y)\r\n };\r\n\r\n //manage class name which indicates scrollable overflow\r\n addRemoveClass(_hostElement, _classNameHostOverflow, hideOverflow.x || hideOverflow.y);\r\n addRemoveClass(_hostElement, _classNameHostOverflowX, hideOverflow.x);\r\n addRemoveClass(_hostElement, _classNameHostOverflowY, hideOverflow.y);\r\n\r\n //add or remove rtl class name for styling purposes except when its body, then the scrollbar stays\r\n if (cssDirectionChanged && !_isBody) {\r\n addRemoveClass(_hostElement, _classNameHostRTL, _isRTL);\r\n }\r\n\r\n //manage the resize feature (CSS3 resize \"polyfill\" for this plugin)\r\n if (_isBody)\r\n addClass(_hostElement, _classNameHostResizeDisabled);\r\n if (resizeChanged) {\r\n addRemoveClass(_hostElement, _classNameHostResizeDisabled, _resizeNone);\r\n addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResize, !_resizeNone);\r\n addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeB, _resizeBoth);\r\n addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeH, _resizeHorizontal);\r\n addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeV, _resizeVertical);\r\n }\r\n\r\n //manage the scrollbars general visibility + the scrollbar interactivity (unusable class name)\r\n if (scrollbarsVisibilityChanged || overflowBehaviorChanged || hideOverflow.c || hasOverflow.c || ignoreOverlayScrollbarHidingChanged) {\r\n if (ignoreOverlayScrollbarHiding) {\r\n if (ignoreOverlayScrollbarHidingChanged) {\r\n removeClass(_hostElement, _classNameHostScrolling);\r\n if (ignoreOverlayScrollbarHiding) {\r\n refreshScrollbarsVisibility(false);\r\n }\r\n }\r\n }\r\n else if (scrollbarsVisibilityAuto) {\r\n refreshScrollbarsVisibility(canScroll.x, canScroll.y);\r\n }\r\n else if (scrollbarsVisibilityVisible) {\r\n refreshScrollbarsVisibility(true);\r\n }\r\n else if (scrollbarsVisibilityHidden) {\r\n refreshScrollbarsVisibility(false);\r\n }\r\n }\r\n\r\n //manage the scrollbars auto hide feature (auto hide them after specific actions)\r\n if (scrollbarsAutoHideChanged || ignoreOverlayScrollbarHidingChanged) {\r\n setupHostMouseTouchEvents(!_scrollbarsAutoHideLeave && !_scrollbarsAutoHideMove);\r\n refreshScrollbarsAutoHide(_scrollbarsAutoHideNever, !_scrollbarsAutoHideNever);\r\n }\r\n\r\n //manage scrollbars handle length & offset - don't remove!\r\n if (hostSizeChanged || overflowAmount.c || heightAutoChanged || widthAutoChanged || resizeChanged || boxSizingChanged || paddingAbsoluteChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged) {\r\n refreshScrollbarHandleLength(true);\r\n refreshScrollbarHandleOffset(true);\r\n refreshScrollbarHandleLength(false);\r\n refreshScrollbarHandleOffset(false);\r\n }\r\n\r\n //manage interactivity\r\n if (scrollbarsClickScrollingChanged)\r\n refreshScrollbarsInteractive(true, scrollbarsClickScrolling);\r\n if (scrollbarsDragScrollingChanged)\r\n refreshScrollbarsInteractive(false, scrollbarsDragScrolling);\r\n\r\n //callbacks:\r\n dispatchCallback('onDirectionChanged', {\r\n isRTL: _isRTL,\r\n dir: cssDirection\r\n }, cssDirectionChanged);\r\n dispatchCallback('onHostSizeChanged', {\r\n width: _hostSizeCache.w,\r\n height: _hostSizeCache.h\r\n }, hostSizeChanged);\r\n dispatchCallback('onContentSizeChanged', {\r\n width: _contentScrollSizeCache.w,\r\n height: _contentScrollSizeCache.h\r\n }, contentSizeChanged);\r\n dispatchCallback('onOverflowChanged', {\r\n x: hasOverflow.x,\r\n y: hasOverflow.y,\r\n xScrollable: hideOverflow.xs,\r\n yScrollable: hideOverflow.ys,\r\n clipped: hideOverflow.x || hideOverflow.y\r\n }, hasOverflow.c || hideOverflow.c);\r\n dispatchCallback('onOverflowAmountChanged', {\r\n x: overflowAmount.x,\r\n y: overflowAmount.y\r\n }, overflowAmount.c);\r\n }\r\n\r\n //fix body min size\r\n if (_isBody && _bodyMinSizeCache && (_hasOverflowCache.c || _bodyMinSizeCache.c)) {\r\n //its possible that no min size was measured until now, because the content arrange element was just added now, in this case, measure now the min size.\r\n if (!_bodyMinSizeCache.f)\r\n bodyMinSizeChanged();\r\n if (_nativeScrollbarIsOverlaid.y && _hasOverflowCache.x)\r\n _contentElement.css(_strMinMinus + _strWidth, _bodyMinSizeCache.w + _overlayScrollbarDummySize.y);\r\n if (_nativeScrollbarIsOverlaid.x && _hasOverflowCache.y)\r\n _contentElement.css(_strMinMinus + _strHeight, _bodyMinSizeCache.h + _overlayScrollbarDummySize.x);\r\n _bodyMinSizeCache.c = false;\r\n }\r\n\r\n if (_initialized && changedOptions.updateOnLoad) {\r\n updateElementsOnLoad();\r\n }\r\n\r\n //freezeResizeObserver(_sizeObserverElement, false);\r\n //freezeResizeObserver(_sizeAutoObserverElement, false);\r\n\r\n dispatchCallback('onUpdated', { forced: force });\r\n }\r\n\r\n /**\r\n * Updates the found elements of which the load event shall be handled.\r\n */\r\n function updateElementsOnLoad() {\r\n if (!_isTextarea) {\r\n eachUpdateOnLoad(function (i, updateOnLoadSelector) {\r\n _contentElement.find(updateOnLoadSelector).each(function (i, el) {\r\n // if element doesn't have a updateOnLoadCallback applied\r\n if (COMPATIBILITY.inA(el, _updateOnLoadElms) < 0) {\r\n _updateOnLoadElms.push(el);\r\n FRAMEWORK(el)\r\n .off(_updateOnLoadEventName, updateOnLoadCallback)\r\n .on(_updateOnLoadEventName, updateOnLoadCallback);\r\n }\r\n });\r\n });\r\n }\r\n }\r\n\r\n //==== Options ====//\r\n\r\n /**\r\n * Sets new options but doesn't call the update method.\r\n * @param newOptions The object which contains the new options.\r\n * @returns {*} A object which contains the changed options.\r\n */\r\n function setOptions(newOptions) {\r\n var validatedOpts = _pluginsOptions._validate(newOptions, _pluginsOptions._template, true, _currentOptions)\r\n\r\n _currentOptions = extendDeep({}, _currentOptions, validatedOpts._default);\r\n _currentPreparedOptions = extendDeep({}, _currentPreparedOptions, validatedOpts._prepared);\r\n\r\n return validatedOpts._prepared;\r\n }\r\n\r\n\r\n //==== Structure ====//\r\n\r\n /**\r\n * Builds or destroys the wrapper and helper DOM elements.\r\n * @param destroy Indicates whether the DOM shall be build or destroyed.\r\n */\r\n /**\r\n * Builds or destroys the wrapper and helper DOM elements.\r\n * @param destroy Indicates whether the DOM shall be build or destroyed.\r\n */\r\n function setupStructureDOM(destroy) {\r\n var strParent = 'parent';\r\n var classNameResizeObserverHost = 'os-resize-observer-host';\r\n var classNameTextareaElementFull = _classNameTextareaElement + _strSpace + _classNameTextInherit;\r\n var textareaClass = _isTextarea ? _strSpace + _classNameTextInherit : _strEmpty;\r\n var adoptAttrs = _currentPreparedOptions.textarea.inheritedAttrs;\r\n var adoptAttrsMap = {};\r\n var applyAdoptedAttrs = function () {\r\n var applyAdoptedAttrsElm = destroy ? _targetElement : _hostElement;\r\n each(adoptAttrsMap, function (key, value) {\r\n if (type(value) == TYPES.s) {\r\n if (key == LEXICON.c)\r\n applyAdoptedAttrsElm.addClass(value);\r\n else\r\n applyAdoptedAttrsElm.attr(key, value);\r\n }\r\n });\r\n };\r\n var hostElementClassNames = [\r\n _classNameHostElement,\r\n _classNameHostElementForeign,\r\n _classNameHostTextareaElement,\r\n _classNameHostResizeDisabled,\r\n _classNameHostRTL,\r\n _classNameHostScrollbarHorizontalHidden,\r\n _classNameHostScrollbarVerticalHidden,\r\n _classNameHostTransition,\r\n _classNameHostScrolling,\r\n _classNameHostOverflow,\r\n _classNameHostOverflowX,\r\n _classNameHostOverflowY,\r\n _classNameThemeNone,\r\n _classNameTextareaElement,\r\n _classNameTextInherit,\r\n _classNameCache].join(_strSpace);\r\n var hostElementCSS = {};\r\n\r\n //get host element as first element, because that's the most upper element and required for the other elements\r\n _hostElement = _hostElement || (_isTextarea ? (_domExists ? _targetElement[strParent]()[strParent]()[strParent]()[strParent]() : FRAMEWORK(generateDiv(_classNameHostTextareaElement))) : _targetElement);\r\n _contentElement = _contentElement || selectOrGenerateDivByClass(_classNameContentElement + textareaClass);\r\n _viewportElement = _viewportElement || selectOrGenerateDivByClass(_classNameViewportElement + textareaClass);\r\n _paddingElement = _paddingElement || selectOrGenerateDivByClass(_classNamePaddingElement + textareaClass);\r\n _sizeObserverElement = _sizeObserverElement || selectOrGenerateDivByClass(classNameResizeObserverHost);\r\n _textareaCoverElement = _textareaCoverElement || (_isTextarea ? selectOrGenerateDivByClass(_classNameTextareaCoverElement) : undefined);\r\n\r\n //add this class to workaround class changing issues with UI frameworks especially Vue\r\n if (_domExists)\r\n addClass(_hostElement, _classNameHostElementForeign);\r\n\r\n //on destroy, remove all generated class names from the host element before collecting the adopted attributes \r\n //to prevent adopting generated class names\r\n if (destroy)\r\n removeClass(_hostElement, hostElementClassNames);\r\n\r\n //collect all adopted attributes\r\n adoptAttrs = type(adoptAttrs) == TYPES.s ? adoptAttrs.split(_strSpace) : adoptAttrs;\r\n if (COMPATIBILITY.isA(adoptAttrs) && _isTextarea) {\r\n each(adoptAttrs, function (i, v) {\r\n if (type(v) == TYPES.s) {\r\n adoptAttrsMap[v] = destroy ? _hostElement.attr(v) : _targetElement.attr(v);\r\n }\r\n });\r\n }\r\n\r\n if (!destroy) {\r\n if (_isTextarea) {\r\n if (!_currentPreparedOptions.sizeAutoCapable) {\r\n hostElementCSS[_strWidth] = _targetElement.css(_strWidth);\r\n hostElementCSS[_strHeight] = _targetElement.css(_strHeight);\r\n }\r\n\r\n if (!_domExists)\r\n _targetElement.addClass(_classNameTextInherit).wrap(_hostElement);\r\n\r\n //jQuery clones elements in wrap functions, so we have to select them again\r\n _hostElement = _targetElement[strParent]().css(hostElementCSS);\r\n }\r\n\r\n if (!_domExists) {\r\n //add the correct class to the target element\r\n addClass(_targetElement, _isTextarea ? classNameTextareaElementFull : _classNameHostElement);\r\n\r\n //wrap the content into the generated elements to create the required DOM\r\n _hostElement.wrapInner(_contentElement)\r\n .wrapInner(_viewportElement)\r\n .wrapInner(_paddingElement)\r\n .prepend(_sizeObserverElement);\r\n\r\n //jQuery clones elements in wrap functions, so we have to select them again\r\n _contentElement = findFirst(_hostElement, _strDot + _classNameContentElement);\r\n _viewportElement = findFirst(_hostElement, _strDot + _classNameViewportElement);\r\n _paddingElement = findFirst(_hostElement, _strDot + _classNamePaddingElement);\r\n\r\n if (_isTextarea) {\r\n _contentElement.prepend(_textareaCoverElement);\r\n applyAdoptedAttrs();\r\n }\r\n }\r\n\r\n if (_nativeScrollbarStyling)\r\n addClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible);\r\n if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)\r\n addClass(_viewportElement, _classNameViewportNativeScrollbarsOverlaid);\r\n if (_isBody)\r\n addClass(_htmlElement, _classNameHTMLElement);\r\n\r\n _sizeObserverElementNative = _sizeObserverElement[0];\r\n _hostElementNative = _hostElement[0];\r\n _paddingElementNative = _paddingElement[0];\r\n _viewportElementNative = _viewportElement[0];\r\n _contentElementNative = _contentElement[0];\r\n\r\n updateViewportAttrsFromTarget();\r\n }\r\n else {\r\n if (_domExists && _initialized) {\r\n //clear size observer\r\n _sizeObserverElement.children().remove();\r\n\r\n //remove the style property and classes from already generated elements\r\n each([_paddingElement, _viewportElement, _contentElement, _textareaCoverElement], function (i, elm) {\r\n if (elm) {\r\n removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy);\r\n }\r\n });\r\n\r\n //add classes to the host element which was removed previously to match the expected DOM\r\n addClass(_hostElement, _isTextarea ? _classNameHostTextareaElement : _classNameHostElement);\r\n }\r\n else {\r\n //remove size observer\r\n remove(_sizeObserverElement);\r\n\r\n //unwrap the content to restore DOM\r\n _contentElement.contents()\r\n .unwrap()\r\n .unwrap()\r\n .unwrap();\r\n\r\n if (_isTextarea) {\r\n _targetElement.unwrap();\r\n remove(_hostElement);\r\n remove(_textareaCoverElement);\r\n applyAdoptedAttrs();\r\n }\r\n }\r\n\r\n if (_isTextarea)\r\n _targetElement.removeAttr(LEXICON.s);\r\n\r\n if (_isBody)\r\n removeClass(_htmlElement, _classNameHTMLElement);\r\n }\r\n }\r\n\r\n /**\r\n * Adds or removes all wrapper elements interactivity events.\r\n * @param destroy Indicates whether the Events shall be added or removed.\r\n */\r\n function setupStructureEvents() {\r\n var textareaKeyDownRestrictedKeyCodes = [\r\n 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 123, //F1 to F12\r\n 33, 34, //page up, page down\r\n 37, 38, 39, 40, //left, up, right, down arrows\r\n 16, 17, 18, 19, 20, 144 //Shift, Ctrl, Alt, Pause, CapsLock, NumLock\r\n ];\r\n var textareaKeyDownKeyCodesList = [];\r\n var textareaUpdateIntervalID;\r\n var scrollStopTimeoutId;\r\n var scrollStopDelay = 175;\r\n var strFocus = 'focus';\r\n\r\n function updateTextarea(doClearInterval) {\r\n textareaUpdate();\r\n _base.update(_strAuto);\r\n if (doClearInterval && _autoUpdateRecommended)\r\n clearInterval(textareaUpdateIntervalID);\r\n }\r\n function textareaOnScroll(event) {\r\n _targetElement[_strScrollLeft](_rtlScrollBehavior.i && _normalizeRTLCache ? 9999999 : 0);\r\n _targetElement[_strScrollTop](0);\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n return false;\r\n }\r\n function textareaOnDrop(event) {\r\n setTimeout(function () {\r\n if (!_destroyed)\r\n updateTextarea();\r\n }, 50);\r\n }\r\n function textareaOnFocus() {\r\n _textareaHasFocus = true;\r\n addClass(_hostElement, strFocus);\r\n }\r\n function textareaOnFocusout() {\r\n _textareaHasFocus = false;\r\n textareaKeyDownKeyCodesList = [];\r\n removeClass(_hostElement, strFocus);\r\n updateTextarea(true);\r\n }\r\n function textareaOnKeyDown(event) {\r\n var keyCode = event.keyCode;\r\n\r\n if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) {\r\n if (!textareaKeyDownKeyCodesList[LEXICON.l]) {\r\n updateTextarea();\r\n textareaUpdateIntervalID = setInterval(updateTextarea, 1000 / 60);\r\n }\r\n if (inArray(keyCode, textareaKeyDownKeyCodesList) < 0)\r\n textareaKeyDownKeyCodesList.push(keyCode);\r\n }\r\n }\r\n function textareaOnKeyUp(event) {\r\n var keyCode = event.keyCode;\r\n var index = inArray(keyCode, textareaKeyDownKeyCodesList);\r\n\r\n if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) {\r\n if (index > -1)\r\n textareaKeyDownKeyCodesList.splice(index, 1);\r\n if (!textareaKeyDownKeyCodesList[LEXICON.l])\r\n updateTextarea(true);\r\n }\r\n }\r\n function contentOnTransitionEnd(event) {\r\n if (_autoUpdateCache === true)\r\n return;\r\n event = event.originalEvent || event;\r\n if (isSizeAffectingCSSProperty(event.propertyName))\r\n _base.update(_strAuto);\r\n }\r\n function viewportOnScroll(event) {\r\n if (!_sleeping) {\r\n if (scrollStopTimeoutId !== undefined)\r\n clearTimeout(scrollStopTimeoutId);\r\n else {\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(true);\r\n\r\n if (!nativeOverlayScrollbarsAreActive())\r\n addClass(_hostElement, _classNameHostScrolling);\r\n\r\n dispatchCallback('onScrollStart', event);\r\n }\r\n\r\n //if a scrollbars handle gets dragged, the mousemove event is responsible for refreshing the handle offset\r\n //because if CSS scroll-snap is used, the handle offset gets only refreshed on every snap point\r\n //this looks laggy & clunky, it looks much better if the offset refreshes with the mousemove\r\n if (!_scrollbarsHandlesDefineScrollPos) {\r\n refreshScrollbarHandleOffset(true);\r\n refreshScrollbarHandleOffset(false);\r\n }\r\n dispatchCallback('onScroll', event);\r\n\r\n scrollStopTimeoutId = setTimeout(function () {\r\n if (!_destroyed) {\r\n //OnScrollStop:\r\n clearTimeout(scrollStopTimeoutId);\r\n scrollStopTimeoutId = undefined;\r\n\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(false);\r\n\r\n if (!nativeOverlayScrollbarsAreActive())\r\n removeClass(_hostElement, _classNameHostScrolling);\r\n\r\n dispatchCallback('onScrollStop', event);\r\n }\r\n }, scrollStopDelay);\r\n }\r\n }\r\n\r\n\r\n if (_isTextarea) {\r\n if (_msieVersion > 9 || !_autoUpdateRecommended) {\r\n addDestroyEventListener(_targetElement, 'input', updateTextarea);\r\n }\r\n else {\r\n addDestroyEventListener(_targetElement,\r\n [_strKeyDownEvent, _strKeyUpEvent],\r\n [textareaOnKeyDown, textareaOnKeyUp]);\r\n }\r\n\r\n addDestroyEventListener(_targetElement,\r\n [_strScroll, 'drop', strFocus, strFocus + 'out'],\r\n [textareaOnScroll, textareaOnDrop, textareaOnFocus, textareaOnFocusout]);\r\n }\r\n else {\r\n addDestroyEventListener(_contentElement, _strTransitionEndEvent, contentOnTransitionEnd);\r\n }\r\n addDestroyEventListener(_viewportElement, _strScroll, viewportOnScroll, true);\r\n }\r\n\r\n\r\n //==== Scrollbars ====//\r\n\r\n /**\r\n * Builds or destroys all scrollbar DOM elements (scrollbar, track, handle)\r\n * @param destroy Indicates whether the DOM shall be build or destroyed.\r\n */\r\n function setupScrollbarsDOM(destroy) {\r\n var selectOrGenerateScrollbarDOM = function (isHorizontal) {\r\n var scrollbarClassName = isHorizontal ? _classNameScrollbarHorizontal : _classNameScrollbarVertical;\r\n var scrollbar = selectOrGenerateDivByClass(_classNameScrollbar + _strSpace + scrollbarClassName, true);\r\n var track = selectOrGenerateDivByClass(_classNameScrollbarTrack, scrollbar);\r\n var handle = selectOrGenerateDivByClass(_classNameScrollbarHandle, scrollbar);\r\n\r\n if (!_domExists && !destroy) {\r\n scrollbar.append(track);\r\n track.append(handle);\r\n }\r\n\r\n return {\r\n _scrollbar: scrollbar,\r\n _track: track,\r\n _handle: handle\r\n };\r\n };\r\n function resetScrollbarDOM(isHorizontal) {\r\n var scrollbarVars = getScrollbarVars(isHorizontal);\r\n var scrollbar = scrollbarVars._scrollbar;\r\n var track = scrollbarVars._track;\r\n var handle = scrollbarVars._handle;\r\n\r\n if (_domExists && _initialized) {\r\n each([scrollbar, track, handle], function (i, elm) {\r\n removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy);\r\n });\r\n }\r\n else {\r\n remove(scrollbar || selectOrGenerateScrollbarDOM(isHorizontal)._scrollbar);\r\n }\r\n }\r\n var horizontalElements;\r\n var verticalElements;\r\n\r\n if (!destroy) {\r\n horizontalElements = selectOrGenerateScrollbarDOM(true);\r\n verticalElements = selectOrGenerateScrollbarDOM();\r\n\r\n _scrollbarHorizontalElement = horizontalElements._scrollbar;\r\n _scrollbarHorizontalTrackElement = horizontalElements._track;\r\n _scrollbarHorizontalHandleElement = horizontalElements._handle;\r\n _scrollbarVerticalElement = verticalElements._scrollbar;\r\n _scrollbarVerticalTrackElement = verticalElements._track;\r\n _scrollbarVerticalHandleElement = verticalElements._handle;\r\n\r\n if (!_domExists) {\r\n _paddingElement.after(_scrollbarVerticalElement);\r\n _paddingElement.after(_scrollbarHorizontalElement);\r\n }\r\n }\r\n else {\r\n resetScrollbarDOM(true);\r\n resetScrollbarDOM();\r\n }\r\n }\r\n\r\n /**\r\n * Initializes all scrollbar interactivity events. (track and handle dragging, clicking, scrolling)\r\n * @param isHorizontal True if the target scrollbar is the horizontal scrollbar, false if the target scrollbar is the vertical scrollbar.\r\n */\r\n function setupScrollbarEvents(isHorizontal) {\r\n var scrollbarVars = getScrollbarVars(isHorizontal);\r\n var scrollbarVarsInfo = scrollbarVars._info;\r\n var insideIFrame = _windowElementNative.top !== _windowElementNative;\r\n var xy = scrollbarVars._x_y;\r\n var XY = scrollbarVars._X_Y;\r\n var scroll = _strScroll + scrollbarVars._Left_Top;\r\n var strActive = 'active';\r\n var strSnapHandle = 'snapHandle';\r\n var strClickEvent = 'click';\r\n var scrollDurationFactor = 1;\r\n var increaseDecreaseScrollAmountKeyCodes = [16, 17]; //shift, ctrl\r\n var trackTimeout;\r\n var mouseDownScroll;\r\n var mouseDownOffset;\r\n var mouseDownInvertedScale;\r\n\r\n function getPointerPosition(event) {\r\n return _msieVersion && insideIFrame ? event['screen' + XY] : COMPATIBILITY.page(event)[xy]; //use screen coordinates in EDGE & IE because the page values are incorrect in frames.\r\n }\r\n function getPreparedScrollbarsOption(name) {\r\n return _currentPreparedOptions.scrollbars[name];\r\n }\r\n function increaseTrackScrollAmount() {\r\n scrollDurationFactor = 0.5;\r\n }\r\n function decreaseTrackScrollAmount() {\r\n scrollDurationFactor = 1;\r\n }\r\n function stopClickEventPropagation(event) {\r\n COMPATIBILITY.stpP(event);\r\n }\r\n function documentKeyDown(event) {\r\n if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1)\r\n increaseTrackScrollAmount();\r\n }\r\n function documentKeyUp(event) {\r\n if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1)\r\n decreaseTrackScrollAmount();\r\n }\r\n function onMouseTouchDownContinue(event) {\r\n var originalEvent = event.originalEvent || event;\r\n var isTouchEvent = originalEvent.touches !== undefined;\r\n return _sleeping || _destroyed || nativeOverlayScrollbarsAreActive() || !_scrollbarsDragScrollingCache || (isTouchEvent && !getPreparedScrollbarsOption('touchSupport')) ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent;\r\n }\r\n function documentDragMove(event) {\r\n if (onMouseTouchDownContinue(event)) {\r\n var trackLength = scrollbarVarsInfo._trackLength;\r\n var handleLength = scrollbarVarsInfo._handleLength;\r\n var scrollRange = scrollbarVarsInfo._maxScroll;\r\n var scrollRaw = (getPointerPosition(event) - mouseDownOffset) * mouseDownInvertedScale;\r\n var scrollDeltaPercent = scrollRaw / (trackLength - handleLength);\r\n var scrollDelta = (scrollRange * scrollDeltaPercent);\r\n scrollDelta = isFinite(scrollDelta) ? scrollDelta : 0;\r\n if (_isRTL && isHorizontal && !_rtlScrollBehavior.i)\r\n scrollDelta *= -1;\r\n\r\n _viewportElement[scroll](MATH.round(mouseDownScroll + scrollDelta));\r\n\r\n if (_scrollbarsHandlesDefineScrollPos)\r\n refreshScrollbarHandleOffset(isHorizontal, mouseDownScroll + scrollDelta);\r\n\r\n if (!_supportPassiveEvents)\r\n COMPATIBILITY.prvD(event);\r\n }\r\n else\r\n documentMouseTouchUp(event);\r\n }\r\n function documentMouseTouchUp(event) {\r\n event = event || event.originalEvent;\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent],\r\n [documentDragMove, documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart],\r\n true);\r\n COMPATIBILITY.rAF()(function() {\r\n setupResponsiveEventListener(_documentElement, strClickEvent, stopClickEventPropagation, true, { _capture: true });\r\n });\r\n \r\n \r\n if (_scrollbarsHandlesDefineScrollPos)\r\n refreshScrollbarHandleOffset(isHorizontal, true);\r\n\r\n _scrollbarsHandlesDefineScrollPos = false;\r\n removeClass(_bodyElement, _classNameDragging);\r\n removeClass(scrollbarVars._handle, strActive);\r\n removeClass(scrollbarVars._track, strActive);\r\n removeClass(scrollbarVars._scrollbar, strActive);\r\n\r\n mouseDownScroll = undefined;\r\n mouseDownOffset = undefined;\r\n mouseDownInvertedScale = 1;\r\n\r\n decreaseTrackScrollAmount();\r\n\r\n if (trackTimeout !== undefined) {\r\n _base.scrollStop();\r\n clearTimeout(trackTimeout);\r\n trackTimeout = undefined;\r\n }\r\n\r\n if (event) {\r\n var rect = _hostElementNative[LEXICON.bCR]();\r\n var mouseInsideHost = event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom;\r\n\r\n //if mouse is outside host element\r\n if (!mouseInsideHost)\r\n hostOnMouseLeave();\r\n\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(false);\r\n }\r\n }\r\n function onHandleMouseTouchDown(event) {\r\n if (onMouseTouchDownContinue(event))\r\n onHandleMouseTouchDownAction(event);\r\n }\r\n function onHandleMouseTouchDownAction(event) {\r\n mouseDownScroll = _viewportElement[scroll]();\r\n mouseDownScroll = isNaN(mouseDownScroll) ? 0 : mouseDownScroll;\r\n if (_isRTL && isHorizontal && !_rtlScrollBehavior.n || !_isRTL)\r\n mouseDownScroll = mouseDownScroll < 0 ? 0 : mouseDownScroll;\r\n\r\n mouseDownInvertedScale = getHostElementInvertedScale()[xy];\r\n mouseDownOffset = getPointerPosition(event);\r\n\r\n _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle);\r\n addClass(_bodyElement, _classNameDragging);\r\n addClass(scrollbarVars._handle, strActive);\r\n addClass(scrollbarVars._scrollbar, strActive);\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strSelectStartEvent],\r\n [documentDragMove, documentMouseTouchUp, documentOnSelectStart]);\r\n COMPATIBILITY.rAF()(function() {\r\n setupResponsiveEventListener(_documentElement, strClickEvent, stopClickEventPropagation, false, { _capture: true });\r\n });\r\n \r\n\r\n if (_msieVersion || !_documentMixed)\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n function onTrackMouseTouchDown(event) {\r\n if (onMouseTouchDownContinue(event)) {\r\n var handleToViewportRatio = scrollbarVars._info._handleLength / Math.round(MATH.min(1, _viewportSize[scrollbarVars._w_h] / _contentScrollSizeCache[scrollbarVars._w_h]) * scrollbarVars._info._trackLength);\r\n var scrollDistance = MATH.round(_viewportSize[scrollbarVars._w_h] * handleToViewportRatio);\r\n var scrollBaseDuration = 270 * handleToViewportRatio;\r\n var scrollFirstIterationDelay = 400 * handleToViewportRatio;\r\n var trackOffset = scrollbarVars._track.offset()[scrollbarVars._left_top];\r\n var ctrlKey = event.ctrlKey;\r\n var instantScroll = event.shiftKey;\r\n var instantScrollTransition = instantScroll && ctrlKey;\r\n var isFirstIteration = true;\r\n var easing = 'linear';\r\n var decreaseScroll;\r\n var finishedCondition;\r\n var scrollActionFinsished = function (transition) {\r\n if (_scrollbarsHandlesDefineScrollPos)\r\n refreshScrollbarHandleOffset(isHorizontal, transition);\r\n };\r\n var scrollActionInstantFinished = function () {\r\n scrollActionFinsished();\r\n onHandleMouseTouchDownAction(event);\r\n };\r\n var scrollAction = function () {\r\n if (!_destroyed) {\r\n var mouseOffset = (mouseDownOffset - trackOffset) * mouseDownInvertedScale;\r\n var handleOffset = scrollbarVarsInfo._handleOffset;\r\n var trackLength = scrollbarVarsInfo._trackLength;\r\n var handleLength = scrollbarVarsInfo._handleLength;\r\n var scrollRange = scrollbarVarsInfo._maxScroll;\r\n var currScroll = scrollbarVarsInfo._currentScroll;\r\n var scrollDuration = scrollBaseDuration * scrollDurationFactor;\r\n var timeoutDelay = isFirstIteration ? MATH.max(scrollFirstIterationDelay, scrollDuration) : scrollDuration;\r\n var instantScrollPosition = scrollRange * ((mouseOffset - (handleLength / 2)) / (trackLength - handleLength)); // 100% * positionPercent\r\n var rtlIsNormal = _isRTL && isHorizontal && ((!_rtlScrollBehavior.i && !_rtlScrollBehavior.n) || _normalizeRTLCache);\r\n var decreaseScrollCondition = rtlIsNormal ? handleOffset < mouseOffset : handleOffset > mouseOffset;\r\n var scrollObj = {};\r\n var animationObj = {\r\n easing: easing,\r\n step: function (now) {\r\n if (_scrollbarsHandlesDefineScrollPos) {\r\n _viewportElement[scroll](now); //https://github.com/jquery/jquery/issues/4340\r\n refreshScrollbarHandleOffset(isHorizontal, now);\r\n }\r\n }\r\n };\r\n instantScrollPosition = isFinite(instantScrollPosition) ? instantScrollPosition : 0;\r\n instantScrollPosition = _isRTL && isHorizontal && !_rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition;\r\n\r\n //_base.scrollStop();\r\n\r\n if (instantScroll) {\r\n _viewportElement[scroll](instantScrollPosition); //scroll instantly to new position\r\n if (instantScrollTransition) {\r\n //get the scroll position after instant scroll (in case CSS Snap Points are used) to get the correct snapped scroll position\r\n //and the animation stops at the correct point\r\n instantScrollPosition = _viewportElement[scroll]();\r\n //scroll back to the position before instant scrolling so animation can be performed\r\n _viewportElement[scroll](currScroll);\r\n\r\n instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition;\r\n instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.n ? -instantScrollPosition : instantScrollPosition;\r\n\r\n scrollObj[xy] = instantScrollPosition;\r\n _base.scroll(scrollObj, extendDeep(animationObj, {\r\n duration: 130,\r\n complete: scrollActionInstantFinished\r\n }));\r\n }\r\n else\r\n scrollActionInstantFinished();\r\n }\r\n else {\r\n decreaseScroll = isFirstIteration ? decreaseScrollCondition : decreaseScroll;\r\n finishedCondition = rtlIsNormal\r\n ? (decreaseScroll ? handleOffset + handleLength >= mouseOffset : handleOffset <= mouseOffset)\r\n : (decreaseScroll ? handleOffset <= mouseOffset : handleOffset + handleLength >= mouseOffset);\r\n\r\n if (finishedCondition) {\r\n clearTimeout(trackTimeout);\r\n _base.scrollStop();\r\n trackTimeout = undefined;\r\n scrollActionFinsished(true);\r\n }\r\n else {\r\n trackTimeout = setTimeout(scrollAction, timeoutDelay);\r\n\r\n scrollObj[xy] = (decreaseScroll ? '-=' : '+=') + scrollDistance;\r\n _base.scroll(scrollObj, extendDeep(animationObj, {\r\n duration: scrollDuration\r\n }));\r\n }\r\n isFirstIteration = false;\r\n }\r\n }\r\n };\r\n if (ctrlKey)\r\n increaseTrackScrollAmount();\r\n\r\n mouseDownInvertedScale = getHostElementInvertedScale()[xy];\r\n mouseDownOffset = COMPATIBILITY.page(event)[xy];\r\n\r\n _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle);\r\n addClass(_bodyElement, _classNameDragging);\r\n addClass(scrollbarVars._track, strActive);\r\n addClass(scrollbarVars._scrollbar, strActive);\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent],\r\n [documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart]);\r\n\r\n scrollAction();\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n }\r\n function onTrackMouseTouchEnter(event) {\r\n //make sure both scrollbars will stay visible if one scrollbar is hovered if autoHide is \"scroll\" or \"move\".\r\n _scrollbarsHandleHovered = true;\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(true);\r\n }\r\n function onTrackMouseTouchLeave(event) {\r\n _scrollbarsHandleHovered = false;\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(false);\r\n }\r\n function onScrollbarMouseTouchDown(event) {\r\n COMPATIBILITY.stpP(event);\r\n }\r\n\r\n addDestroyEventListener(scrollbarVars._handle,\r\n _strMouseTouchDownEvent,\r\n onHandleMouseTouchDown);\r\n addDestroyEventListener(scrollbarVars._track,\r\n [_strMouseTouchDownEvent, _strMouseEnter, _strMouseLeave],\r\n [onTrackMouseTouchDown, onTrackMouseTouchEnter, onTrackMouseTouchLeave]);\r\n addDestroyEventListener(scrollbarVars._scrollbar,\r\n _strMouseTouchDownEvent,\r\n onScrollbarMouseTouchDown);\r\n\r\n if (_supportTransition) {\r\n addDestroyEventListener(scrollbarVars._scrollbar, _strTransitionEndEvent, function (event) {\r\n if (event.target !== scrollbarVars._scrollbar[0])\r\n return;\r\n refreshScrollbarHandleLength(isHorizontal);\r\n refreshScrollbarHandleOffset(isHorizontal);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Shows or hides the given scrollbar and applied a class name which indicates if the scrollbar is scrollable or not.\r\n * @param isHorizontal True if the horizontal scrollbar is the target, false if the vertical scrollbar is the target.\r\n * @param shallBeVisible True if the scrollbar shall be shown, false if hidden.\r\n * @param canScroll True if the scrollbar is scrollable, false otherwise.\r\n */\r\n function refreshScrollbarAppearance(isHorizontal, shallBeVisible, canScroll) {\r\n var scrollbarHiddenClassName = isHorizontal ? _classNameHostScrollbarHorizontalHidden : _classNameHostScrollbarVerticalHidden;\r\n var scrollbarElement = isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement;\r\n\r\n addRemoveClass(_hostElement, scrollbarHiddenClassName, !shallBeVisible);\r\n addRemoveClass(scrollbarElement, _classNameScrollbarUnusable, !canScroll);\r\n }\r\n\r\n /**\r\n * Autoshows / autohides both scrollbars with.\r\n * @param shallBeVisible True if the scrollbars shall be autoshown (only the case if they are hidden by a autohide), false if the shall be auto hidden.\r\n * @param delayfree True if the scrollbars shall be hidden without a delay, false or undefined otherwise.\r\n */\r\n function refreshScrollbarsAutoHide(shallBeVisible, delayfree) {\r\n clearTimeout(_scrollbarsAutoHideTimeoutId);\r\n if (shallBeVisible) {\r\n //if(_hasOverflowCache.x && _hideOverflowCache.xs)\r\n removeClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden);\r\n //if(_hasOverflowCache.y && _hideOverflowCache.ys)\r\n removeClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden);\r\n }\r\n else {\r\n var anyActive;\r\n var strActive = 'active';\r\n var hide = function () {\r\n if (!_scrollbarsHandleHovered && !_destroyed) {\r\n anyActive = _scrollbarHorizontalHandleElement.hasClass(strActive) || _scrollbarVerticalHandleElement.hasClass(strActive);\r\n if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave))\r\n addClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden);\r\n if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave))\r\n addClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden);\r\n }\r\n };\r\n if (_scrollbarsAutoHideDelay > 0 && delayfree !== true)\r\n _scrollbarsAutoHideTimeoutId = setTimeout(hide, _scrollbarsAutoHideDelay);\r\n else\r\n hide();\r\n }\r\n }\r\n\r\n /**\r\n * Refreshes the handle length of the given scrollbar.\r\n * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed.\r\n */\r\n function refreshScrollbarHandleLength(isHorizontal) {\r\n var handleCSS = {};\r\n var scrollbarVars = getScrollbarVars(isHorizontal);\r\n var scrollbarVarsInfo = scrollbarVars._info;\r\n var digit = 1000000;\r\n //get and apply intended handle length\r\n var handleRatio = MATH.min(1, _viewportSize[scrollbarVars._w_h] / _contentScrollSizeCache[scrollbarVars._w_h]);\r\n handleCSS[scrollbarVars._width_height] = (MATH.floor(handleRatio * 100 * digit) / digit) + '%'; //the last * digit / digit is for flooring to the 4th digit\r\n\r\n if (!nativeOverlayScrollbarsAreActive())\r\n scrollbarVars._handle.css(handleCSS);\r\n\r\n //measure the handle length to respect min & max length\r\n scrollbarVarsInfo._handleLength = scrollbarVars._handle[0]['offset' + scrollbarVars._Width_Height];\r\n scrollbarVarsInfo._handleLengthRatio = handleRatio;\r\n }\r\n\r\n /**\r\n * Refreshes the handle offset of the given scrollbar.\r\n * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed.\r\n * @param scrollOrTransition The scroll position of the given scrollbar axis to which the handle shall be moved or a boolean which indicates whether a transition shall be applied. If undefined or boolean if the current scroll-offset is taken. (if isHorizontal ? scrollLeft : scrollTop)\r\n */\r\n function refreshScrollbarHandleOffset(isHorizontal, scrollOrTransition) {\r\n var transition = type(scrollOrTransition) == TYPES.b;\r\n var transitionDuration = 250;\r\n var isRTLisHorizontal = _isRTL && isHorizontal;\r\n var scrollbarVars = getScrollbarVars(isHorizontal);\r\n var scrollbarVarsInfo = scrollbarVars._info;\r\n var strTranslateBrace = 'translate(';\r\n var strTransform = VENDORS._cssProperty('transform');\r\n var strTransition = VENDORS._cssProperty('transition');\r\n var nativeScroll = isHorizontal ? _viewportElement[_strScrollLeft]() : _viewportElement[_strScrollTop]();\r\n var currentScroll = scrollOrTransition === undefined || transition ? nativeScroll : scrollOrTransition;\r\n\r\n //measure the handle length to respect min & max length\r\n var handleLength = scrollbarVarsInfo._handleLength;\r\n var trackLength = scrollbarVars._track[0]['offset' + scrollbarVars._Width_Height];\r\n var handleTrackDiff = trackLength - handleLength;\r\n var handleCSS = {};\r\n var transformOffset;\r\n var translateValue;\r\n\r\n //DONT use the variable '_contentScrollSizeCache[scrollbarVars._w_h]' instead of '_viewportElement[0]['scroll' + scrollbarVars._Width_Height]'\r\n // because its a bit behind during the small delay when content size updates\r\n //(delay = mutationObserverContentLag, if its 0 then this var could be used)\r\n var maxScroll = (_viewportElementNative[_strScroll + scrollbarVars._Width_Height] - _viewportElementNative['client' + scrollbarVars._Width_Height]) * (_rtlScrollBehavior.n && isRTLisHorizontal ? -1 : 1); //* -1 if rtl scroll max is negative\r\n var getScrollRatio = function (base) {\r\n return isNaN(base / maxScroll) ? 0 : MATH.max(0, MATH.min(1, base / maxScroll));\r\n };\r\n var getHandleOffset = function (scrollRatio) {\r\n var offset = handleTrackDiff * scrollRatio;\r\n offset = isNaN(offset) ? 0 : offset;\r\n offset = (isRTLisHorizontal && !_rtlScrollBehavior.i) ? (trackLength - handleLength - offset) : offset;\r\n offset = MATH.max(0, offset);\r\n return offset;\r\n };\r\n var scrollRatio = getScrollRatio(nativeScroll);\r\n var unsnappedScrollRatio = getScrollRatio(currentScroll);\r\n var handleOffset = getHandleOffset(unsnappedScrollRatio);\r\n var snappedHandleOffset = getHandleOffset(scrollRatio);\r\n\r\n scrollbarVarsInfo._maxScroll = maxScroll;\r\n scrollbarVarsInfo._currentScroll = nativeScroll;\r\n scrollbarVarsInfo._currentScrollRatio = scrollRatio;\r\n\r\n if (_supportTransform) {\r\n transformOffset = isRTLisHorizontal ? -(trackLength - handleLength - handleOffset) : handleOffset; //in px\r\n //transformOffset = (transformOffset / trackLength * 100) * (trackLength / handleLength); //in %\r\n translateValue = isHorizontal ? strTranslateBrace + transformOffset + 'px, 0)' : strTranslateBrace + '0, ' + transformOffset + 'px)';\r\n\r\n handleCSS[strTransform] = translateValue;\r\n\r\n //apply or clear up transition\r\n if (_supportTransition)\r\n handleCSS[strTransition] = transition && MATH.abs(handleOffset - scrollbarVarsInfo._handleOffset) > 1 ? getCSSTransitionString(scrollbarVars._handle) + ', ' + (strTransform + _strSpace + transitionDuration + 'ms') : _strEmpty;\r\n }\r\n else\r\n handleCSS[scrollbarVars._left_top] = handleOffset;\r\n\r\n\r\n //only apply css if offset has changed and overflow exists.\r\n if (!nativeOverlayScrollbarsAreActive()) {\r\n scrollbarVars._handle.css(handleCSS);\r\n\r\n //clear up transition\r\n if (_supportTransform && _supportTransition && transition) {\r\n scrollbarVars._handle.one(_strTransitionEndEvent, function () {\r\n if (!_destroyed)\r\n scrollbarVars._handle.css(strTransition, _strEmpty);\r\n });\r\n }\r\n }\r\n\r\n scrollbarVarsInfo._handleOffset = handleOffset;\r\n scrollbarVarsInfo._snappedHandleOffset = snappedHandleOffset;\r\n scrollbarVarsInfo._trackLength = trackLength;\r\n }\r\n\r\n /**\r\n * Refreshes the interactivity of the given scrollbar element.\r\n * @param isTrack True if the track element is the target, false if the handle element is the target.\r\n * @param value True for interactivity false for no interactivity.\r\n */\r\n function refreshScrollbarsInteractive(isTrack, value) {\r\n var action = value ? 'removeClass' : 'addClass';\r\n var element1 = isTrack ? _scrollbarHorizontalTrackElement : _scrollbarHorizontalHandleElement;\r\n var element2 = isTrack ? _scrollbarVerticalTrackElement : _scrollbarVerticalHandleElement;\r\n var className = isTrack ? _classNameScrollbarTrackOff : _classNameScrollbarHandleOff;\r\n\r\n element1[action](className);\r\n element2[action](className);\r\n }\r\n\r\n /**\r\n * Returns a object which is used for fast access for specific variables.\r\n * @param isHorizontal True if the horizontal scrollbar vars shall be accessed, false if the vertical scrollbar vars shall be accessed.\r\n * @returns {{wh: string, WH: string, lt: string, _wh: string, _lt: string, t: *, h: *, c: {}, s: *}}\r\n */\r\n function getScrollbarVars(isHorizontal) {\r\n return {\r\n _width_height: isHorizontal ? _strWidth : _strHeight,\r\n _Width_Height: isHorizontal ? 'Width' : 'Height',\r\n _left_top: isHorizontal ? _strLeft : _strTop,\r\n _Left_Top: isHorizontal ? 'Left' : 'Top',\r\n _x_y: isHorizontal ? _strX : _strY,\r\n _X_Y: isHorizontal ? 'X' : 'Y',\r\n _w_h: isHorizontal ? 'w' : 'h',\r\n _l_t: isHorizontal ? 'l' : 't',\r\n _track: isHorizontal ? _scrollbarHorizontalTrackElement : _scrollbarVerticalTrackElement,\r\n _handle: isHorizontal ? _scrollbarHorizontalHandleElement : _scrollbarVerticalHandleElement,\r\n _scrollbar: isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement,\r\n _info: isHorizontal ? _scrollHorizontalInfo : _scrollVerticalInfo\r\n };\r\n }\r\n\r\n\r\n //==== Scrollbar Corner ====//\r\n\r\n /**\r\n * Builds or destroys the scrollbar corner DOM element.\r\n * @param destroy Indicates whether the DOM shall be build or destroyed.\r\n */\r\n function setupScrollbarCornerDOM(destroy) {\r\n _scrollbarCornerElement = _scrollbarCornerElement || selectOrGenerateDivByClass(_classNameScrollbarCorner, true);\r\n\r\n if (!destroy) {\r\n if (!_domExists) {\r\n _hostElement.append(_scrollbarCornerElement);\r\n }\r\n }\r\n else {\r\n if (_domExists && _initialized) {\r\n removeClass(_scrollbarCornerElement.removeAttr(LEXICON.s), _classNamesDynamicDestroy);\r\n }\r\n else {\r\n remove(_scrollbarCornerElement);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Initializes all scrollbar corner interactivity events.\r\n */\r\n function setupScrollbarCornerEvents() {\r\n var insideIFrame = _windowElementNative.top !== _windowElementNative;\r\n var mouseDownPosition = {};\r\n var mouseDownSize = {};\r\n var mouseDownInvertedScale = {};\r\n var reconnectMutationObserver;\r\n\r\n function documentDragMove(event) {\r\n if (onMouseTouchDownContinue(event)) {\r\n var pageOffset = getCoordinates(event);\r\n var hostElementCSS = {};\r\n if (_resizeHorizontal || _resizeBoth)\r\n hostElementCSS[_strWidth] = (mouseDownSize.w + (pageOffset.x - mouseDownPosition.x) * mouseDownInvertedScale.x);\r\n if (_resizeVertical || _resizeBoth)\r\n hostElementCSS[_strHeight] = (mouseDownSize.h + (pageOffset.y - mouseDownPosition.y) * mouseDownInvertedScale.y);\r\n _hostElement.css(hostElementCSS);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n else {\r\n documentMouseTouchUp(event);\r\n }\r\n }\r\n function documentMouseTouchUp(event) {\r\n var eventIsTrusted = event !== undefined;\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent],\r\n [documentOnSelectStart, documentDragMove, documentMouseTouchUp],\r\n true);\r\n\r\n removeClass(_bodyElement, _classNameDragging);\r\n if (_scrollbarCornerElement.releaseCapture)\r\n _scrollbarCornerElement.releaseCapture();\r\n\r\n if (eventIsTrusted) {\r\n if (reconnectMutationObserver)\r\n connectMutationObservers();\r\n _base.update(_strAuto);\r\n }\r\n reconnectMutationObserver = false;\r\n }\r\n function onMouseTouchDownContinue(event) {\r\n var originalEvent = event.originalEvent || event;\r\n var isTouchEvent = originalEvent.touches !== undefined;\r\n return _sleeping || _destroyed ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent;\r\n }\r\n function getCoordinates(event) {\r\n return _msieVersion && insideIFrame ? { x: event.screenX, y: event.screenY } : COMPATIBILITY.page(event);\r\n }\r\n\r\n addDestroyEventListener(_scrollbarCornerElement, _strMouseTouchDownEvent, function (event) {\r\n if (onMouseTouchDownContinue(event) && !_resizeNone) {\r\n if (_mutationObserversConnected) {\r\n reconnectMutationObserver = true;\r\n disconnectMutationObservers();\r\n }\r\n\r\n mouseDownPosition = getCoordinates(event);\r\n\r\n mouseDownSize.w = _hostElementNative[LEXICON.oW] - (!_isBorderBox ? _paddingX : 0);\r\n mouseDownSize.h = _hostElementNative[LEXICON.oH] - (!_isBorderBox ? _paddingY : 0);\r\n mouseDownInvertedScale = getHostElementInvertedScale();\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent],\r\n [documentOnSelectStart, documentDragMove, documentMouseTouchUp]);\r\n\r\n addClass(_bodyElement, _classNameDragging);\r\n if (_scrollbarCornerElement.setCapture)\r\n _scrollbarCornerElement.setCapture();\r\n\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n });\r\n }\r\n\r\n\r\n //==== Utils ====//\r\n\r\n /**\r\n * Calls the callback with the given name. The Context of this callback is always _base (this).\r\n * @param name The name of the target which shall be called.\r\n * @param args The args with which the callback shall be called.\r\n * @param dependent Boolean which decides whether the callback shall be fired, undefined is like a \"true\" value.\r\n */\r\n function dispatchCallback(name, args, dependent) {\r\n if (dependent === false)\r\n return;\r\n if (_initialized) {\r\n var callback = _currentPreparedOptions.callbacks[name];\r\n var extensionOnName = name;\r\n var ext;\r\n\r\n if (extensionOnName.substr(0, 2) === 'on')\r\n extensionOnName = extensionOnName.substr(2, 1).toLowerCase() + extensionOnName.substr(3);\r\n\r\n if (type(callback) == TYPES.f)\r\n callback.call(_base, args);\r\n\r\n each(_extensions, function () {\r\n ext = this;\r\n if (type(ext.on) == TYPES.f)\r\n ext.on(extensionOnName, args);\r\n });\r\n }\r\n else if (!_destroyed)\r\n _callbacksInitQeueue.push({ n: name, a: args });\r\n }\r\n\r\n /**\r\n * Sets the \"top, right, bottom, left\" properties, with a given prefix, of the given css object.\r\n * @param targetCSSObject The css object to which the values shall be applied.\r\n * @param prefix The prefix of the \"top, right, bottom, left\" css properties. (example: 'padding-' is a valid prefix)\r\n * @param values A array of values which shall be applied to the \"top, right, bottom, left\" -properties. The array order is [top, right, bottom, left].\r\n * If this argument is undefined the value '' (empty string) will be applied to all properties.\r\n */\r\n function setTopRightBottomLeft(targetCSSObject, prefix, values) {\r\n prefix = prefix || _strEmpty;\r\n values = values || [_strEmpty, _strEmpty, _strEmpty, _strEmpty];\r\n\r\n targetCSSObject[prefix + _strTop] = values[0];\r\n targetCSSObject[prefix + _strRight] = values[1];\r\n targetCSSObject[prefix + _strBottom] = values[2];\r\n targetCSSObject[prefix + _strLeft] = values[3];\r\n }\r\n\r\n /**\r\n * Gets the \"top, right, bottom, left\" CSS properties of the CSS property with the given prefix from the host element.\r\n * @param prefix The prefix of the \"top, right, bottom, left\" css properties. (example: 'padding-' is a valid prefix)\r\n * @param suffix The suffix of the \"top, right, bottom, left\" css properties. (example: 'border-' is a valid prefix with '-width' is a valid suffix)\r\n * @param zeroX True if the x axis shall be 0.\r\n * @param zeroY True if the y axis shall be 0.\r\n * @returns {{}} The object which contains the numbers of the read CSS properties.\r\n */\r\n function getTopRightBottomLeftHost(prefix, suffix, zeroX, zeroY) {\r\n suffix = suffix || _strEmpty;\r\n prefix = prefix || _strEmpty;\r\n return {\r\n t: zeroY ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strTop + suffix)),\r\n r: zeroX ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strRight + suffix)),\r\n b: zeroY ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strBottom + suffix)),\r\n l: zeroX ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strLeft + suffix))\r\n };\r\n }\r\n\r\n /**\r\n * Returns the computed CSS transition string from the given element.\r\n * @param element The element from which the transition string shall be returned.\r\n * @returns {string} The CSS transition string from the given element.\r\n */\r\n function getCSSTransitionString(element) {\r\n var transitionStr = VENDORS._cssProperty('transition');\r\n var assembledValue = element.css(transitionStr);\r\n if (assembledValue)\r\n return assembledValue;\r\n var regExpString = '\\\\s*(' + '([^,(]+(\\\\(.+?\\\\))?)+' + ')[\\\\s,]*';\r\n var regExpMain = new RegExp(regExpString);\r\n var regExpValidate = new RegExp('^(' + regExpString + ')+$');\r\n var properties = 'property duration timing-function delay'.split(' ');\r\n var result = [];\r\n var strResult;\r\n var valueArray;\r\n var i = 0;\r\n var j;\r\n var splitCssStyleByComma = function (str) {\r\n strResult = [];\r\n if (!str.match(regExpValidate))\r\n return str;\r\n while (str.match(regExpMain)) {\r\n strResult.push(RegExp.$1);\r\n str = str.replace(regExpMain, _strEmpty);\r\n }\r\n\r\n return strResult;\r\n };\r\n for (; i < properties[LEXICON.l]; i++) {\r\n valueArray = splitCssStyleByComma(element.css(transitionStr + '-' + properties[i]));\r\n for (j = 0; j < valueArray[LEXICON.l]; j++)\r\n result[j] = (result[j] ? result[j] + _strSpace : _strEmpty) + valueArray[j];\r\n }\r\n return result.join(', ');\r\n }\r\n\r\n /**\r\n * Generates a Regular Expression which matches with a string which starts with 'os-host'.\r\n * @param {boolean} withCurrClassNameOption The Regular Expression also matches if the string is the current ClassName option (multiple values splitted by space possible).\r\n * @param {boolean} withOldClassNameOption The Regular Expression also matches if the string is the old ClassName option (multiple values splitted by space possible).\r\n */\r\n function createHostClassNameRegExp(withCurrClassNameOption, withOldClassNameOption) {\r\n var i;\r\n var split;\r\n var appendix;\r\n var appendClasses = function (classes, condition) {\r\n appendix = '';\r\n if (condition && typeof classes == TYPES.s) {\r\n split = classes.split(_strSpace);\r\n for (i = 0; i < split[LEXICON.l]; i++)\r\n appendix += '|' + split[i] + '$';\r\n // split[i].replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') for escaping regex characters\r\n }\r\n return appendix;\r\n };\r\n\r\n return new RegExp(\r\n '(^' + _classNameHostElement + '([-_].+|)$)' +\r\n appendClasses(_classNameCache, withCurrClassNameOption) +\r\n appendClasses(_oldClassName, withOldClassNameOption), 'g');\r\n }\r\n\r\n /**\r\n * Calculates the host-elements inverted scale. (invertedScale = 1 / scale)\r\n * @returns {{x: number, y: number}} The scale of the host-element.\r\n */\r\n function getHostElementInvertedScale() {\r\n var rect = _paddingElementNative[LEXICON.bCR]();\r\n return {\r\n x: _supportTransform ? 1 / (MATH.round(rect.width) / _paddingElementNative[LEXICON.oW]) || 1 : 1,\r\n y: _supportTransform ? 1 / (MATH.round(rect.height) / _paddingElementNative[LEXICON.oH]) || 1 : 1\r\n };\r\n }\r\n\r\n /**\r\n * Checks whether the given object is a HTMLElement.\r\n * @param o The object which shall be checked.\r\n * @returns {boolean} True the given object is a HTMLElement, false otherwise.\r\n */\r\n function isHTMLElement(o) {\r\n var strOwnerDocument = 'ownerDocument';\r\n var strHTMLElement = 'HTMLElement';\r\n var wnd = o && o[strOwnerDocument] ? (o[strOwnerDocument].parentWindow || window) : window;\r\n return (\r\n typeof wnd[strHTMLElement] == TYPES.o ? o instanceof wnd[strHTMLElement] : //DOM2\r\n o && typeof o == TYPES.o && o !== null && o.nodeType === 1 && typeof o.nodeName == TYPES.s\r\n );\r\n }\r\n\r\n /**\r\n * Compares 2 arrays and returns the differences between them as a array.\r\n * @param a1 The first array which shall be compared.\r\n * @param a2 The second array which shall be compared.\r\n * @returns {Array} The differences between the two arrays.\r\n */\r\n function getArrayDifferences(a1, a2) {\r\n var a = [];\r\n var diff = [];\r\n var i;\r\n var k;\r\n for (i = 0; i < a1.length; i++)\r\n a[a1[i]] = true;\r\n for (i = 0; i < a2.length; i++) {\r\n if (a[a2[i]])\r\n delete a[a2[i]];\r\n else\r\n a[a2[i]] = true;\r\n }\r\n for (k in a)\r\n diff.push(k);\r\n return diff;\r\n }\r\n\r\n /**\r\n * Returns Zero or the number to which the value can be parsed.\r\n * @param value The value which shall be parsed.\r\n * @param toFloat Indicates whether the number shall be parsed to a float.\r\n */\r\n function parseToZeroOrNumber(value, toFloat) {\r\n var num = toFloat ? parseFloat(value) : parseInt(value, 10);\r\n return isNaN(num) ? 0 : num;\r\n }\r\n\r\n /**\r\n * Gets several information of the textarea and returns them as a object or undefined if the browser doesn't support it.\r\n * @returns {{cursorRow: Number, cursorCol, rows: Number, cols: number, wRow: number, pos: number, max : number}} or undefined if not supported.\r\n */\r\n function getTextareaInfo() {\r\n //read needed values\r\n var textareaCursorPosition = _targetElementNative.selectionStart;\r\n if (textareaCursorPosition === undefined)\r\n return;\r\n\r\n var textareaValue = _targetElement.val();\r\n var textareaLength = textareaValue[LEXICON.l];\r\n var textareaRowSplit = textareaValue.split('\\n');\r\n var textareaLastRow = textareaRowSplit[LEXICON.l];\r\n var textareaCurrentCursorRowSplit = textareaValue.substr(0, textareaCursorPosition).split('\\n');\r\n var widestRow = 0;\r\n var textareaLastCol = 0;\r\n var cursorRow = textareaCurrentCursorRowSplit[LEXICON.l];\r\n var cursorCol = textareaCurrentCursorRowSplit[textareaCurrentCursorRowSplit[LEXICON.l] - 1][LEXICON.l];\r\n var rowCols;\r\n var i;\r\n\r\n //get widest Row and the last column of the textarea\r\n for (i = 0; i < textareaRowSplit[LEXICON.l]; i++) {\r\n rowCols = textareaRowSplit[i][LEXICON.l];\r\n if (rowCols > textareaLastCol) {\r\n widestRow = i + 1;\r\n textareaLastCol = rowCols;\r\n }\r\n }\r\n\r\n return {\r\n _cursorRow: cursorRow, //cursorRow\r\n _cursorColumn: cursorCol, //cursorCol\r\n _rows: textareaLastRow, //rows\r\n _columns: textareaLastCol, //cols\r\n _widestRow: widestRow, //wRow\r\n _cursorPosition: textareaCursorPosition, //pos\r\n _cursorMax: textareaLength //max\r\n };\r\n }\r\n\r\n /**\r\n * Determines whether native overlay scrollbars are active.\r\n * @returns {boolean} True if native overlay scrollbars are active, false otherwise.\r\n */\r\n function nativeOverlayScrollbarsAreActive() {\r\n return (_ignoreOverlayScrollbarHidingCache && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y));\r\n }\r\n\r\n /**\r\n * Gets the element which is used to measure the content size.\r\n * @returns {*} TextareaCover if target element is textarea else the ContentElement.\r\n */\r\n function getContentMeasureElement() {\r\n return _isTextarea ? _textareaCoverElement[0] : _contentElementNative;\r\n }\r\n\r\n /**\r\n * Generates a string which represents a HTML div with the given classes or attributes.\r\n * @param classesOrAttrs The class of the div as string or a object which represents the attributes of the div. (The class attribute can also be written as \"className\".)\r\n * @param content The content of the div as string.\r\n * @returns {string} The concated string which represents a HTML div and its content.\r\n */\r\n function generateDiv(classesOrAttrs, content) {\r\n return '<div ' + (classesOrAttrs ? type(classesOrAttrs) == TYPES.s ?\r\n 'class=\"' + classesOrAttrs + '\"' :\r\n (function () {\r\n var key;\r\n var attrs = _strEmpty;\r\n if (FRAMEWORK.isPlainObject(classesOrAttrs)) {\r\n for (key in classesOrAttrs)\r\n attrs += (key === 'c' ? 'class' : key) + '=\"' + classesOrAttrs[key] + '\" ';\r\n }\r\n return attrs;\r\n })() :\r\n _strEmpty) +\r\n '>' +\r\n (content || _strEmpty) +\r\n '</div>';\r\n }\r\n\r\n /**\r\n * Selects or generates a div with the given class attribute.\r\n * @param className The class names (divided by spaces) of the div which shall be selected or generated.\r\n * @param selectParentOrOnlyChildren The parent element from which of the element shall be selected. (if undefined or boolean its hostElement)\r\n * If its a boolean it decides whether only the children of the host element shall be selected.\r\n * @returns {*} The generated or selected element.\r\n */\r\n function selectOrGenerateDivByClass(className, selectParentOrOnlyChildren) {\r\n var onlyChildren = type(selectParentOrOnlyChildren) == TYPES.b;\r\n var selectParent = onlyChildren ? _hostElement : (selectParentOrOnlyChildren || _hostElement);\r\n\r\n return (_domExists && !selectParent[LEXICON.l])\r\n ? null\r\n : _domExists\r\n ? selectParent[onlyChildren ? 'children' : 'find'](_strDot + className.replace(/\\s/g, _strDot)).eq(0)\r\n : FRAMEWORK(generateDiv(className))\r\n }\r\n\r\n /**\r\n * Gets the value of the given property from the given object.\r\n * @param obj The object from which the property value shall be got.\r\n * @param path The property of which the value shall be got.\r\n * @returns {*} Returns the value of the searched property or undefined of the property wasn't found.\r\n */\r\n function getObjectPropVal(obj, path) {\r\n var splits = path.split(_strDot);\r\n var i = 0;\r\n var val;\r\n for (; i < splits.length; i++) {\r\n if (!obj[LEXICON.hOP](splits[i]))\r\n return;\r\n val = obj[splits[i]];\r\n if (i < splits.length && type(val) == TYPES.o)\r\n obj = val;\r\n }\r\n return val;\r\n }\r\n\r\n /**\r\n * Sets the value of the given property from the given object.\r\n * @param obj The object from which the property value shall be set.\r\n * @param path The property of which the value shall be set.\r\n * @param val The value of the property which shall be set.\r\n */\r\n function setObjectPropVal(obj, path, val) {\r\n var splits = path.split(_strDot);\r\n var splitsLength = splits.length;\r\n var i = 0;\r\n var extendObj = {};\r\n var extendObjRoot = extendObj;\r\n for (; i < splitsLength; i++)\r\n extendObj = extendObj[splits[i]] = i + 1 < splitsLength ? {} : val;\r\n FRAMEWORK.extend(obj, extendObjRoot, true);\r\n }\r\n\r\n /**\t\r\n * Runs a action for each selector inside the updateOnLoad option.\t\r\n * @param {Function} action The action for each updateOnLoad selector, the arguments the function takes is the index and the value (the selector).\t\r\n */\r\n function eachUpdateOnLoad(action) {\r\n var updateOnLoad = _currentPreparedOptions.updateOnLoad;\r\n updateOnLoad = type(updateOnLoad) == TYPES.s ? updateOnLoad.split(_strSpace) : updateOnLoad;\r\n\r\n if (COMPATIBILITY.isA(updateOnLoad) && !_destroyed) {\r\n each(updateOnLoad, action);\r\n }\r\n }\r\n\r\n\r\n //==== Utils Cache ====//\r\n\r\n /**\r\n * Compares two values or objects and returns true if they aren't equal.\r\n * @param current The first value or object which shall be compared.\r\n * @param cache The second value or object which shall be compared.\r\n * @param force If true the returned value is always true.\r\n * @returns {boolean} True if both values or objects aren't equal or force is true, false otherwise.\r\n */\r\n function checkCache(current, cache, force) {\r\n if (force)\r\n return force;\r\n if (type(current) == TYPES.o && type(cache) == TYPES.o) {\r\n for (var prop in current) {\r\n if (prop !== 'c') {\r\n if (current[LEXICON.hOP](prop) && cache[LEXICON.hOP](prop)) {\r\n if (checkCache(current[prop], cache[prop]))\r\n return true;\r\n }\r\n else {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n return current !== cache;\r\n }\r\n return false;\r\n }\r\n\r\n\r\n //==== Shortcuts ====//\r\n\r\n /**\r\n * jQuery extend method shortcut with a appended \"true\" as first argument.\r\n */\r\n function extendDeep() {\r\n return FRAMEWORK.extend.apply(this, [true].concat([].slice.call(arguments)));\r\n }\r\n\r\n /**\r\n * jQuery addClass method shortcut.\r\n */\r\n function addClass(el, classes) {\r\n return _frameworkProto.addClass.call(el, classes);\r\n }\r\n\r\n /**\r\n * jQuery removeClass method shortcut.\r\n */\r\n function removeClass(el, classes) {\r\n return _frameworkProto.removeClass.call(el, classes);\r\n }\r\n\r\n /**\r\n * Adds or removes the given classes dependent on the boolean value. True for add, false for remove.\r\n */\r\n function addRemoveClass(el, classes, doAdd) {\r\n return doAdd ? addClass(el, classes) : removeClass(el, classes);\r\n }\r\n\r\n /**\r\n * jQuery remove method shortcut.\r\n */\r\n function remove(el) {\r\n return _frameworkProto.remove.call(el);\r\n }\r\n\r\n /**\r\n * Finds the first child element with the given selector of the given element.\r\n * @param el The root element from which the selector shall be valid.\r\n * @param selector The selector of the searched element.\r\n * @returns {*} The first element which is a child of the given element and matches the givens selector.\r\n */\r\n function findFirst(el, selector) {\r\n return _frameworkProto.find.call(el, selector).eq(0);\r\n }\r\n\r\n\r\n //==== API ====//\r\n\r\n /**\r\n * Puts the instance to sleep. It wont respond to any changes in the DOM and won't update. Scrollbar Interactivity is also disabled as well as the resize handle.\r\n * This behavior can be reset by calling the update method.\r\n */\r\n _base.sleep = function () {\r\n _sleeping = true;\r\n };\r\n\r\n /**\r\n * Updates the plugin and DOM to the current options.\r\n * This method should only be called if a update is 100% required.\r\n * @param force True if every property shall be updated and the cache shall be ignored.\r\n * !INTERNAL USAGE! : force can be a string \"auto\", \"sync\" or \"zoom\" too\r\n * if \"auto\" then before a real update the content size and host element attributes gets checked, and if they changed only then the update method will be called.\r\n * if \"sync\" then the async update process (MutationObserver or UpdateLoop) gets synchronized and a corresponding update takes place if one was needed due to pending changes.\r\n * if \"zoom\" then a update takes place where it's assumed that content and host size changed\r\n * @returns {boolean|undefined} \r\n * If force is \"sync\" then a boolean is returned which indicates whether a update was needed due to pending changes.\r\n * If force is \"auto\" then a boolean is returned whether a update was needed due to attribute or size changes.\r\n * undefined otherwise.\r\n */\r\n _base.update = function (force) {\r\n if (_destroyed)\r\n return;\r\n\r\n var attrsChanged;\r\n var contentSizeC;\r\n var isString = type(force) == TYPES.s;\r\n var doUpdateAuto;\r\n var mutHost;\r\n var mutContent;\r\n\r\n if (isString) {\r\n if (force === _strAuto) {\r\n attrsChanged = meaningfulAttrsChanged();\r\n contentSizeC = updateAutoContentSizeChanged();\r\n doUpdateAuto = attrsChanged || contentSizeC;\r\n if (doUpdateAuto) {\r\n update({\r\n _contentSizeChanged: contentSizeC,\r\n _changedOptions: _initialized ? undefined : _currentPreparedOptions\r\n });\r\n }\r\n }\r\n else if (force === _strSync) {\r\n if (_mutationObserversConnected) {\r\n mutHost = _mutationObserverHostCallback(_mutationObserverHost.takeRecords());\r\n mutContent = _mutationObserverContentCallback(_mutationObserverContent.takeRecords());\r\n }\r\n else {\r\n mutHost = _base.update(_strAuto);\r\n }\r\n }\r\n else if (force === 'zoom') {\r\n update({\r\n _hostSizeChanged: true,\r\n _contentSizeChanged: true\r\n });\r\n }\r\n }\r\n else {\r\n force = _sleeping || force;\r\n _sleeping = false;\r\n if (!_base.update(_strSync) || force)\r\n update({ _force: force });\r\n }\r\n\r\n updateElementsOnLoad();\r\n\r\n return doUpdateAuto || mutHost || mutContent;\r\n };\r\n\r\n /**\r\n Gets or sets the current options. The update method will be called automatically if new options were set.\r\n * @param newOptions If new options are given, then the new options will be set, if new options aren't given (undefined or a not a plain object) then the current options will be returned.\r\n * @param value If new options is a property path string, then this value will be used to set the option to which the property path string leads.\r\n * @returns {*}\r\n */\r\n _base.options = function (newOptions, value) {\r\n var option = {};\r\n var changedOps;\r\n\r\n //return current options if newOptions are undefined or empty\r\n if (FRAMEWORK.isEmptyObject(newOptions) || !FRAMEWORK.isPlainObject(newOptions)) {\r\n if (type(newOptions) == TYPES.s) {\r\n if (arguments.length > 1) {\r\n setObjectPropVal(option, newOptions, value);\r\n changedOps = setOptions(option);\r\n }\r\n else\r\n return getObjectPropVal(_currentOptions, newOptions);\r\n }\r\n else\r\n return _currentOptions;\r\n }\r\n else {\r\n changedOps = setOptions(newOptions);\r\n }\r\n\r\n if (!FRAMEWORK.isEmptyObject(changedOps)) {\r\n update({ _changedOptions: changedOps });\r\n }\r\n };\r\n\r\n /**\r\n * Restore the DOM, disconnects all observers, remove all resize observers and put the instance to sleep.\r\n */\r\n _base.destroy = function () {\r\n if (_destroyed)\r\n return;\r\n\r\n //remove this instance from auto update loop\r\n autoUpdateLoop.remove(_base);\r\n\r\n //disconnect all mutation observers\r\n disconnectMutationObservers();\r\n\r\n //remove all resize observers\r\n setupResizeObserver(_sizeObserverElement);\r\n setupResizeObserver(_sizeAutoObserverElement);\r\n\r\n //remove all extensions\r\n for (var extName in _extensions)\r\n _base.removeExt(extName);\r\n\r\n //remove all 'destroy' events\r\n while (_destroyEvents[LEXICON.l] > 0)\r\n _destroyEvents.pop()();\r\n\r\n //remove all events from host element\r\n setupHostMouseTouchEvents(true);\r\n\r\n //remove all helper / detection elements\r\n if (_contentGlueElement)\r\n remove(_contentGlueElement);\r\n if (_contentArrangeElement)\r\n remove(_contentArrangeElement);\r\n if (_sizeAutoObserverAdded)\r\n remove(_sizeAutoObserverElement);\r\n\r\n //remove all generated DOM\r\n setupScrollbarsDOM(true);\r\n setupScrollbarCornerDOM(true);\r\n setupStructureDOM(true);\r\n\r\n //remove all generated image load events\r\n for (var i = 0; i < _updateOnLoadElms[LEXICON.l]; i++)\r\n FRAMEWORK(_updateOnLoadElms[i]).off(_updateOnLoadEventName, updateOnLoadCallback);\r\n _updateOnLoadElms = undefined;\r\n\r\n _destroyed = true;\r\n _sleeping = true;\r\n\r\n //remove this instance from the instances list\r\n INSTANCES(pluginTargetElement, 0);\r\n dispatchCallback('onDestroyed');\r\n\r\n //remove all properties and methods\r\n //for (var property in _base)\r\n // delete _base[property];\r\n //_base = undefined;\r\n };\r\n\r\n /**\r\n * Scrolls to a given position or element.\r\n * @param coordinates\r\n * 1. Can be \"coordinates\" which looks like:\r\n * { x : ?, y : ? } OR Object with x and y properties\r\n * { left : ?, top : ? } OR Object with left and top properties\r\n * { l : ?, t : ? } OR Object with l and t properties\r\n * [ ?, ? ] OR Array where the first two element are the coordinates (first is x, second is y)\r\n * ? A single value which stays for both axis\r\n * A value can be a number, a string or a calculation.\r\n *\r\n * Operators:\r\n * [NONE] The current scroll will be overwritten by the value.\r\n * '+=' The value will be added to the current scroll offset\r\n * '-=' The value will be subtracted from the current scroll offset\r\n * '*=' The current scroll wil be multiplicated by the value.\r\n * '/=' The current scroll wil be divided by the value.\r\n *\r\n * Units:\r\n * [NONE] The value is the final scroll amount. final = (value * 1)\r\n * 'px' Same as none\r\n * '%' The value is dependent on the current scroll value. final = ((currentScrollValue / 100) * value)\r\n * 'vw' The value is multiplicated by the viewport width. final = (value * viewportWidth)\r\n * 'vh' The value is multiplicated by the viewport height. final = (value * viewportHeight)\r\n *\r\n * example final values:\r\n * 200, '200px', '50%', '1vw', '1vh', '+=200', '/=1vw', '*=2px', '-=5vh', '+=33%', '+= 50% - 2px', '-= 1vw - 50%'\r\n *\r\n * 2. Can be a HTML or jQuery element:\r\n * The final scroll offset is the offset (without margin) of the given HTML / jQuery element.\r\n *\r\n * 3. Can be a object with a HTML or jQuery element with additional settings:\r\n * {\r\n * el : [HTMLElement, jQuery element], MUST be specified, else this object isn't valid.\r\n * scroll : [string, array, object], Default value is 'always'.\r\n * block : [string, array, object], Default value is 'begin'.\r\n * margin : [number, boolean, array, object] Default value is false.\r\n * }\r\n *\r\n * Possible scroll settings are:\r\n * 'always' Scrolls always.\r\n * 'ifneeded' Scrolls only if the element isnt fully in view.\r\n * 'never' Scrolls never.\r\n *\r\n * Possible block settings are:\r\n * 'begin' Both axis shall be docked to the \"begin\" edge. - The element will be docked to the top and left edge of the viewport.\r\n * 'end' Both axis shall be docked to the \"end\" edge. - The element will be docked to the bottom and right edge of the viewport. (If direction is RTL to the bottom and left edge.)\r\n * 'center' Both axis shall be docked to \"center\". - The element will be centered in the viewport.\r\n * 'nearest' The element will be docked to the nearest edge(s).\r\n *\r\n * Possible margin settings are: -- The actual margin of the element wont be affect, this option affects only the final scroll offset.\r\n * [BOOLEAN] If true the css margin of the element will be used, if false no margin will be used.\r\n * [NUMBER] The margin will be used for all edges.\r\n *\r\n * @param duration The duration of the scroll animation, OR a jQuery animation configuration object.\r\n * @param easing The animation easing.\r\n * @param complete The animation complete callback.\r\n * @returns {{\r\n * position: {x: number, y: number},\r\n * ratio: {x: number, y: number},\r\n * max: {x: number, y: number},\r\n * handleOffset: {x: number, y: number},\r\n * handleLength: {x: number, y: number},\r\n * handleLengthRatio: {x: number, y: number}, t\r\n * rackLength: {x: number, y: number},\r\n * isRTL: boolean,\r\n * isRTLNormalized: boolean\r\n * }}\r\n */\r\n _base.scroll = function (coordinates, duration, easing, complete) {\r\n if (arguments.length === 0 || coordinates === undefined) {\r\n var infoX = _scrollHorizontalInfo;\r\n var infoY = _scrollVerticalInfo;\r\n var normalizeInvert = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.i;\r\n var normalizeNegate = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.n;\r\n var scrollX = infoX._currentScroll;\r\n var scrollXRatio = infoX._currentScrollRatio;\r\n var maxScrollX = infoX._maxScroll;\r\n scrollXRatio = normalizeInvert ? 1 - scrollXRatio : scrollXRatio;\r\n scrollX = normalizeInvert ? maxScrollX - scrollX : scrollX;\r\n scrollX *= normalizeNegate ? -1 : 1;\r\n maxScrollX *= normalizeNegate ? -1 : 1;\r\n\r\n return {\r\n position: {\r\n x: scrollX,\r\n y: infoY._currentScroll\r\n },\r\n ratio: {\r\n x: scrollXRatio,\r\n y: infoY._currentScrollRatio\r\n },\r\n max: {\r\n x: maxScrollX,\r\n y: infoY._maxScroll\r\n },\r\n handleOffset: {\r\n x: infoX._handleOffset,\r\n y: infoY._handleOffset\r\n },\r\n handleLength: {\r\n x: infoX._handleLength,\r\n y: infoY._handleLength\r\n },\r\n handleLengthRatio: {\r\n x: infoX._handleLengthRatio,\r\n y: infoY._handleLengthRatio\r\n },\r\n trackLength: {\r\n x: infoX._trackLength,\r\n y: infoY._trackLength\r\n },\r\n snappedHandleOffset: {\r\n x: infoX._snappedHandleOffset,\r\n y: infoY._snappedHandleOffset\r\n },\r\n isRTL: _isRTL,\r\n isRTLNormalized: _normalizeRTLCache\r\n };\r\n }\r\n\r\n _base.update(_strSync);\r\n\r\n var normalizeRTL = _normalizeRTLCache;\r\n var coordinatesXAxisProps = [_strX, _strLeft, 'l'];\r\n var coordinatesYAxisProps = [_strY, _strTop, 't'];\r\n var coordinatesOperators = ['+=', '-=', '*=', '/='];\r\n var durationIsObject = type(duration) == TYPES.o;\r\n var completeCallback = durationIsObject ? duration.complete : complete;\r\n var i;\r\n var finalScroll = {};\r\n var specialEasing = {};\r\n var doScrollLeft;\r\n var doScrollTop;\r\n var animationOptions;\r\n var strEnd = 'end';\r\n var strBegin = 'begin';\r\n var strCenter = 'center';\r\n var strNearest = 'nearest';\r\n var strAlways = 'always';\r\n var strNever = 'never';\r\n var strIfNeeded = 'ifneeded';\r\n var strLength = LEXICON.l;\r\n var settingsAxis;\r\n var settingsScroll;\r\n var settingsBlock;\r\n var settingsMargin;\r\n var finalElement;\r\n var elementObjSettingsAxisValues = [_strX, _strY, 'xy', 'yx'];\r\n var elementObjSettingsBlockValues = [strBegin, strEnd, strCenter, strNearest];\r\n var elementObjSettingsScrollValues = [strAlways, strNever, strIfNeeded];\r\n var coordinatesIsElementObj = coordinates[LEXICON.hOP]('el');\r\n var possibleElement = coordinatesIsElementObj ? coordinates.el : coordinates;\r\n var possibleElementIsJQuery = possibleElement instanceof FRAMEWORK || JQUERY ? possibleElement instanceof JQUERY : false;\r\n var possibleElementIsHTMLElement = possibleElementIsJQuery ? false : isHTMLElement(possibleElement);\r\n var updateScrollbarInfos = function () {\r\n if (doScrollLeft)\r\n refreshScrollbarHandleOffset(true);\r\n if (doScrollTop)\r\n refreshScrollbarHandleOffset(false);\r\n };\r\n var proxyCompleteCallback = type(completeCallback) != TYPES.f ? undefined : function () {\r\n updateScrollbarInfos();\r\n completeCallback();\r\n };\r\n function checkSettingsStringValue(currValue, allowedValues) {\r\n for (i = 0; i < allowedValues[strLength]; i++) {\r\n if (currValue === allowedValues[i])\r\n return true;\r\n }\r\n return false;\r\n }\r\n function getRawScroll(isX, coordinates) {\r\n var coordinateProps = isX ? coordinatesXAxisProps : coordinatesYAxisProps;\r\n coordinates = type(coordinates) == TYPES.s || type(coordinates) == TYPES.n ? [coordinates, coordinates] : coordinates;\r\n\r\n if (COMPATIBILITY.isA(coordinates))\r\n return isX ? coordinates[0] : coordinates[1];\r\n else if (type(coordinates) == TYPES.o) {\r\n //decides RTL normalization \"hack\" with .n\r\n //normalizeRTL = type(coordinates.n) == TYPES.b ? coordinates.n : normalizeRTL; \r\n for (i = 0; i < coordinateProps[strLength]; i++)\r\n if (coordinateProps[i] in coordinates)\r\n return coordinates[coordinateProps[i]];\r\n }\r\n }\r\n function getFinalScroll(isX, rawScroll) {\r\n var isString = type(rawScroll) == TYPES.s;\r\n var operator;\r\n var amount;\r\n var scrollInfo = isX ? _scrollHorizontalInfo : _scrollVerticalInfo;\r\n var currScroll = scrollInfo._currentScroll;\r\n var maxScroll = scrollInfo._maxScroll;\r\n var mult = ' * ';\r\n var finalValue;\r\n var isRTLisX = _isRTL && isX;\r\n var normalizeShortcuts = isRTLisX && _rtlScrollBehavior.n && !normalizeRTL;\r\n var strReplace = 'replace';\r\n var evalFunc = eval;\r\n var possibleOperator;\r\n if (isString) {\r\n //check operator\r\n if (rawScroll[strLength] > 2) {\r\n possibleOperator = rawScroll.substr(0, 2);\r\n if (inArray(possibleOperator, coordinatesOperators) > -1)\r\n operator = possibleOperator;\r\n }\r\n\r\n //calculate units and shortcuts\r\n rawScroll = operator ? rawScroll.substr(2) : rawScroll;\r\n rawScroll = rawScroll\r\n [strReplace](/min/g, 0) //'min' = 0%\r\n [strReplace](/</g, 0) //'<' = 0%\r\n [strReplace](/max/g, (normalizeShortcuts ? '-' : _strEmpty) + _strHundredPercent) //'max' = 100%\r\n [strReplace](/>/g, (normalizeShortcuts ? '-' : _strEmpty) + _strHundredPercent) //'>' = 100%\r\n [strReplace](/px/g, _strEmpty)\r\n [strReplace](/%/g, mult + (maxScroll * (isRTLisX && _rtlScrollBehavior.n ? -1 : 1) / 100.0))\r\n [strReplace](/vw/g, mult + _viewportSize.w)\r\n [strReplace](/vh/g, mult + _viewportSize.h);\r\n amount = parseToZeroOrNumber(isNaN(rawScroll) ? parseToZeroOrNumber(evalFunc(rawScroll), true).toFixed() : rawScroll);\r\n }\r\n else {\r\n amount = rawScroll;\r\n }\r\n\r\n if (amount !== undefined && !isNaN(amount) && type(amount) == TYPES.n) {\r\n var normalizeIsRTLisX = normalizeRTL && isRTLisX;\r\n var operatorCurrScroll = currScroll * (normalizeIsRTLisX && _rtlScrollBehavior.n ? -1 : 1);\r\n var invert = normalizeIsRTLisX && _rtlScrollBehavior.i;\r\n var negate = normalizeIsRTLisX && _rtlScrollBehavior.n;\r\n operatorCurrScroll = invert ? (maxScroll - operatorCurrScroll) : operatorCurrScroll;\r\n switch (operator) {\r\n case '+=':\r\n finalValue = operatorCurrScroll + amount;\r\n break;\r\n case '-=':\r\n finalValue = operatorCurrScroll - amount;\r\n break;\r\n case '*=':\r\n finalValue = operatorCurrScroll * amount;\r\n break;\r\n case '/=':\r\n finalValue = operatorCurrScroll / amount;\r\n break;\r\n default:\r\n finalValue = amount;\r\n break;\r\n }\r\n finalValue = invert ? maxScroll - finalValue : finalValue;\r\n finalValue *= negate ? -1 : 1;\r\n finalValue = isRTLisX && _rtlScrollBehavior.n ? MATH.min(0, MATH.max(maxScroll, finalValue)) : MATH.max(0, MATH.min(maxScroll, finalValue));\r\n }\r\n return finalValue === currScroll ? undefined : finalValue;\r\n }\r\n function getPerAxisValue(value, valueInternalType, defaultValue, allowedValues) {\r\n var resultDefault = [defaultValue, defaultValue];\r\n var valueType = type(value);\r\n var valueArrLength;\r\n var valueArrItem;\r\n\r\n //value can be [ string, or array of two strings ]\r\n if (valueType == valueInternalType) {\r\n value = [value, value];\r\n }\r\n else if (valueType == TYPES.a) {\r\n valueArrLength = value[strLength];\r\n if (valueArrLength > 2 || valueArrLength < 1)\r\n value = resultDefault;\r\n else {\r\n if (valueArrLength === 1)\r\n value[1] = defaultValue;\r\n for (i = 0; i < valueArrLength; i++) {\r\n valueArrItem = value[i];\r\n if (type(valueArrItem) != valueInternalType || !checkSettingsStringValue(valueArrItem, allowedValues)) {\r\n value = resultDefault;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n else if (valueType == TYPES.o)\r\n value = [value[_strX] || defaultValue, value[_strY] || defaultValue];\r\n else\r\n value = resultDefault;\r\n return { x: value[0], y: value[1] };\r\n }\r\n function generateMargin(marginTopRightBottomLeftArray) {\r\n var result = [];\r\n var currValue;\r\n var currValueType;\r\n var valueDirections = [_strTop, _strRight, _strBottom, _strLeft];\r\n for (i = 0; i < marginTopRightBottomLeftArray[strLength]; i++) {\r\n if (i === valueDirections[strLength])\r\n break;\r\n currValue = marginTopRightBottomLeftArray[i];\r\n currValueType = type(currValue);\r\n if (currValueType == TYPES.b)\r\n result.push(currValue ? parseToZeroOrNumber(finalElement.css(_strMarginMinus + valueDirections[i])) : 0);\r\n else\r\n result.push(currValueType == TYPES.n ? currValue : 0);\r\n }\r\n return result;\r\n }\r\n\r\n if (possibleElementIsJQuery || possibleElementIsHTMLElement) {\r\n //get settings\r\n var margin = coordinatesIsElementObj ? coordinates.margin : 0;\r\n var axis = coordinatesIsElementObj ? coordinates.axis : 0;\r\n var scroll = coordinatesIsElementObj ? coordinates.scroll : 0;\r\n var block = coordinatesIsElementObj ? coordinates.block : 0;\r\n var marginDefault = [0, 0, 0, 0];\r\n var marginType = type(margin);\r\n var marginLength;\r\n finalElement = possibleElementIsJQuery ? possibleElement : FRAMEWORK(possibleElement);\r\n\r\n if (finalElement[strLength] > 0) {\r\n //margin can be [ boolean, number, array of 2, array of 4, object ]\r\n if (marginType == TYPES.n || marginType == TYPES.b)\r\n margin = generateMargin([margin, margin, margin, margin]);\r\n else if (marginType == TYPES.a) {\r\n marginLength = margin[strLength];\r\n if (marginLength === 2)\r\n margin = generateMargin([margin[0], margin[1], margin[0], margin[1]]);\r\n else if (marginLength >= 4)\r\n margin = generateMargin(margin);\r\n else\r\n margin = marginDefault;\r\n }\r\n else if (marginType == TYPES.o)\r\n margin = generateMargin([margin[_strTop], margin[_strRight], margin[_strBottom], margin[_strLeft]]);\r\n else\r\n margin = marginDefault;\r\n\r\n //block = type(block) === TYPES.b ? block ? [ strNearest, strBegin ] : [ strNearest, strEnd ] : block;\r\n settingsAxis = checkSettingsStringValue(axis, elementObjSettingsAxisValues) ? axis : 'xy';\r\n settingsScroll = getPerAxisValue(scroll, TYPES.s, strAlways, elementObjSettingsScrollValues);\r\n settingsBlock = getPerAxisValue(block, TYPES.s, strBegin, elementObjSettingsBlockValues);\r\n settingsMargin = margin;\r\n\r\n var viewportScroll = {\r\n l: _scrollHorizontalInfo._currentScroll,\r\n t: _scrollVerticalInfo._currentScroll\r\n };\r\n // use padding element instead of viewport element because padding element has never padding, margin or position applied.\r\n var viewportOffset = _paddingElement.offset();\r\n\r\n //get coordinates\r\n var elementOffset = finalElement.offset();\r\n var doNotScroll = {\r\n x: settingsScroll.x == strNever || settingsAxis == _strY,\r\n y: settingsScroll.y == strNever || settingsAxis == _strX\r\n };\r\n elementOffset[_strTop] -= settingsMargin[0];\r\n elementOffset[_strLeft] -= settingsMargin[3];\r\n var elementScrollCoordinates = {\r\n x: MATH.round(elementOffset[_strLeft] - viewportOffset[_strLeft] + viewportScroll.l),\r\n y: MATH.round(elementOffset[_strTop] - viewportOffset[_strTop] + viewportScroll.t)\r\n };\r\n if (_isRTL) {\r\n if (!_rtlScrollBehavior.n && !_rtlScrollBehavior.i)\r\n elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + viewportScroll.l);\r\n if (_rtlScrollBehavior.n && normalizeRTL)\r\n elementScrollCoordinates.x *= -1;\r\n if (_rtlScrollBehavior.i && normalizeRTL)\r\n elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + (_scrollHorizontalInfo._maxScroll - viewportScroll.l));\r\n }\r\n\r\n //measuring is required\r\n if (settingsBlock.x != strBegin || settingsBlock.y != strBegin || settingsScroll.x == strIfNeeded || settingsScroll.y == strIfNeeded || _isRTL) {\r\n var measuringElm = finalElement[0];\r\n var rawElementSize = _supportTransform ? measuringElm[LEXICON.bCR]() : {\r\n width: measuringElm[LEXICON.oW],\r\n height: measuringElm[LEXICON.oH]\r\n };\r\n var elementSize = {\r\n w: rawElementSize[_strWidth] + settingsMargin[3] + settingsMargin[1],\r\n h: rawElementSize[_strHeight] + settingsMargin[0] + settingsMargin[2]\r\n };\r\n var finalizeBlock = function (isX) {\r\n var vars = getScrollbarVars(isX);\r\n var wh = vars._w_h;\r\n var lt = vars._left_top;\r\n var xy = vars._x_y;\r\n var blockIsEnd = settingsBlock[xy] == (isX ? _isRTL ? strBegin : strEnd : strEnd);\r\n var blockIsCenter = settingsBlock[xy] == strCenter;\r\n var blockIsNearest = settingsBlock[xy] == strNearest;\r\n var scrollNever = settingsScroll[xy] == strNever;\r\n var scrollIfNeeded = settingsScroll[xy] == strIfNeeded;\r\n var vpSize = _viewportSize[wh];\r\n var vpOffset = viewportOffset[lt];\r\n var elSize = elementSize[wh];\r\n var elOffset = elementOffset[lt];\r\n var divide = blockIsCenter ? 2 : 1;\r\n var elementCenterOffset = elOffset + (elSize / 2);\r\n var viewportCenterOffset = vpOffset + (vpSize / 2);\r\n var isInView =\r\n elSize <= vpSize\r\n && elOffset >= vpOffset\r\n && elOffset + elSize <= vpOffset + vpSize;\r\n\r\n if (scrollNever)\r\n doNotScroll[xy] = true;\r\n else if (!doNotScroll[xy]) {\r\n if (blockIsNearest || scrollIfNeeded) {\r\n doNotScroll[xy] = scrollIfNeeded ? isInView : false;\r\n blockIsEnd = elSize < vpSize ? elementCenterOffset > viewportCenterOffset : elementCenterOffset < viewportCenterOffset;\r\n }\r\n elementScrollCoordinates[xy] -= blockIsEnd || blockIsCenter ? ((vpSize / divide) - (elSize / divide)) * (isX && _isRTL && normalizeRTL ? -1 : 1) : 0;\r\n }\r\n };\r\n finalizeBlock(true);\r\n finalizeBlock(false);\r\n }\r\n\r\n if (doNotScroll.y)\r\n delete elementScrollCoordinates.y;\r\n if (doNotScroll.x)\r\n delete elementScrollCoordinates.x;\r\n\r\n coordinates = elementScrollCoordinates;\r\n }\r\n }\r\n\r\n finalScroll[_strScrollLeft] = getFinalScroll(true, getRawScroll(true, coordinates));\r\n finalScroll[_strScrollTop] = getFinalScroll(false, getRawScroll(false, coordinates));\r\n doScrollLeft = finalScroll[_strScrollLeft] !== undefined;\r\n doScrollTop = finalScroll[_strScrollTop] !== undefined;\r\n\r\n if ((doScrollLeft || doScrollTop) && (duration > 0 || durationIsObject)) {\r\n if (durationIsObject) {\r\n duration.complete = proxyCompleteCallback;\r\n _viewportElement.animate(finalScroll, duration);\r\n }\r\n else {\r\n animationOptions = {\r\n duration: duration,\r\n complete: proxyCompleteCallback\r\n };\r\n if (COMPATIBILITY.isA(easing) || FRAMEWORK.isPlainObject(easing)) {\r\n specialEasing[_strScrollLeft] = easing[0] || easing.x;\r\n specialEasing[_strScrollTop] = easing[1] || easing.y;\r\n animationOptions.specialEasing = specialEasing;\r\n }\r\n else {\r\n animationOptions.easing = easing;\r\n }\r\n _viewportElement.animate(finalScroll, animationOptions);\r\n }\r\n }\r\n else {\r\n if (doScrollLeft)\r\n _viewportElement[_strScrollLeft](finalScroll[_strScrollLeft]);\r\n if (doScrollTop)\r\n _viewportElement[_strScrollTop](finalScroll[_strScrollTop]);\r\n updateScrollbarInfos();\r\n }\r\n };\r\n\r\n /**\r\n * Stops all scroll animations.\r\n * @returns {*} The current OverlayScrollbars instance (for chaining).\r\n */\r\n _base.scrollStop = function (param1, param2, param3) {\r\n _viewportElement.stop(param1, param2, param3);\r\n return _base;\r\n };\r\n\r\n /**\r\n * Returns all relevant elements.\r\n * @param elementName The name of the element which shall be returned.\r\n * @returns {{target: *, host: *, padding: *, viewport: *, content: *, scrollbarHorizontal: {scrollbar: *, track: *, handle: *}, scrollbarVertical: {scrollbar: *, track: *, handle: *}, scrollbarCorner: *} | *}\r\n */\r\n _base.getElements = function (elementName) {\r\n var obj = {\r\n target: _targetElementNative,\r\n host: _hostElementNative,\r\n padding: _paddingElementNative,\r\n viewport: _viewportElementNative,\r\n content: _contentElementNative,\r\n scrollbarHorizontal: {\r\n scrollbar: _scrollbarHorizontalElement[0],\r\n track: _scrollbarHorizontalTrackElement[0],\r\n handle: _scrollbarHorizontalHandleElement[0]\r\n },\r\n scrollbarVertical: {\r\n scrollbar: _scrollbarVerticalElement[0],\r\n track: _scrollbarVerticalTrackElement[0],\r\n handle: _scrollbarVerticalHandleElement[0]\r\n },\r\n scrollbarCorner: _scrollbarCornerElement[0]\r\n };\r\n return type(elementName) == TYPES.s ? getObjectPropVal(obj, elementName) : obj;\r\n };\r\n\r\n /**\r\n * Returns a object which describes the current state of this instance.\r\n * @param stateProperty A specific property from the state object which shall be returned.\r\n * @returns {{widthAuto, heightAuto, overflowAmount, hideOverflow, hasOverflow, contentScrollSize, viewportSize, hostSize, autoUpdate} | *}\r\n */\r\n _base.getState = function (stateProperty) {\r\n function prepare(obj) {\r\n if (!FRAMEWORK.isPlainObject(obj))\r\n return obj;\r\n var extended = extendDeep({}, obj);\r\n var changePropertyName = function (from, to) {\r\n if (extended[LEXICON.hOP](from)) {\r\n extended[to] = extended[from];\r\n delete extended[from];\r\n }\r\n };\r\n changePropertyName('w', _strWidth); //change w to width\r\n changePropertyName('h', _strHeight); //change h to height\r\n delete extended.c; //delete c (the 'changed' prop)\r\n return extended;\r\n };\r\n var obj = {\r\n destroyed: !!prepare(_destroyed),\r\n sleeping: !!prepare(_sleeping),\r\n autoUpdate: prepare(!_mutationObserversConnected),\r\n widthAuto: prepare(_widthAutoCache),\r\n heightAuto: prepare(_heightAutoCache),\r\n padding: prepare(_cssPaddingCache),\r\n overflowAmount: prepare(_overflowAmountCache),\r\n hideOverflow: prepare(_hideOverflowCache),\r\n hasOverflow: prepare(_hasOverflowCache),\r\n contentScrollSize: prepare(_contentScrollSizeCache),\r\n viewportSize: prepare(_viewportSize),\r\n hostSize: prepare(_hostSizeCache),\r\n documentMixed: prepare(_documentMixed)\r\n };\r\n return type(stateProperty) == TYPES.s ? getObjectPropVal(obj, stateProperty) : obj;\r\n };\r\n\r\n /**\r\n * Gets all or specific extension instance.\r\n * @param extName The name of the extension from which the instance shall be got.\r\n * @returns {{}} The instance of the extension with the given name or undefined if the instance couldn't be found.\r\n */\r\n _base.ext = function (extName) {\r\n var result;\r\n var privateMethods = _extensionsPrivateMethods.split(' ');\r\n var i = 0;\r\n if (type(extName) == TYPES.s) {\r\n if (_extensions[LEXICON.hOP](extName)) {\r\n result = extendDeep({}, _extensions[extName]);\r\n for (; i < privateMethods.length; i++)\r\n delete result[privateMethods[i]];\r\n }\r\n }\r\n else {\r\n result = {};\r\n for (i in _extensions)\r\n result[i] = extendDeep({}, _base.ext(i));\r\n }\r\n return result;\r\n };\r\n\r\n /**\r\n * Adds a extension to this instance.\r\n * @param extName The name of the extension which shall be added.\r\n * @param extensionOptions The extension options which shall be used.\r\n * @returns {{}} The instance of the added extension or undefined if the extension couldn't be added properly.\r\n */\r\n _base.addExt = function (extName, extensionOptions) {\r\n var registeredExtensionObj = _plugin.extension(extName);\r\n var instance;\r\n var instanceAdded;\r\n var instanceContract;\r\n var contractResult;\r\n var contractFulfilled = true;\r\n if (registeredExtensionObj) {\r\n if (!_extensions[LEXICON.hOP](extName)) {\r\n instance = registeredExtensionObj.extensionFactory.call(_base,\r\n extendDeep({}, registeredExtensionObj.defaultOptions),\r\n FRAMEWORK,\r\n COMPATIBILITY);\r\n\r\n if (instance) {\r\n instanceContract = instance.contract;\r\n if (type(instanceContract) == TYPES.f) {\r\n contractResult = instanceContract(window);\r\n contractFulfilled = type(contractResult) == TYPES.b ? contractResult : contractFulfilled;\r\n }\r\n if (contractFulfilled) {\r\n _extensions[extName] = instance;\r\n instanceAdded = instance.added;\r\n if (type(instanceAdded) == TYPES.f)\r\n instanceAdded(extensionOptions);\r\n\r\n return _base.ext(extName);\r\n }\r\n }\r\n }\r\n else\r\n return _base.ext(extName);\r\n }\r\n else\r\n console.warn(\"A extension with the name \\\"\" + extName + \"\\\" isn't registered.\");\r\n };\r\n\r\n /**\r\n * Removes a extension from this instance.\r\n * @param extName The name of the extension which shall be removed.\r\n * @returns {boolean} True if the extension was removed, false otherwise e.g. if the extension wasn't added before.\r\n */\r\n _base.removeExt = function (extName) {\r\n var instance = _extensions[extName];\r\n var instanceRemoved;\r\n if (instance) {\r\n delete _extensions[extName];\r\n\r\n instanceRemoved = instance.removed;\r\n if (type(instanceRemoved) == TYPES.f)\r\n instanceRemoved();\r\n\r\n return true;\r\n }\r\n return false;\r\n };\r\n\r\n /**\r\n * Constructs the plugin.\r\n * @param targetElement The element to which the plugin shall be applied.\r\n * @param options The initial options of the plugin.\r\n * @param extensions The extension(s) which shall be added right after the initialization.\r\n * @returns {boolean} True if the plugin was successfully initialized, false otherwise.\r\n */\r\n function construct(targetElement, options, extensions) {\r\n _defaultOptions = globals.defaultOptions;\r\n _nativeScrollbarStyling = globals.nativeScrollbarStyling;\r\n _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize);\r\n _nativeScrollbarIsOverlaid = extendDeep({}, globals.nativeScrollbarIsOverlaid);\r\n _overlayScrollbarDummySize = extendDeep({}, globals.overlayScrollbarDummySize);\r\n _rtlScrollBehavior = extendDeep({}, globals.rtlScrollBehavior);\r\n\r\n //parse & set options but don't update\r\n setOptions(extendDeep({}, _defaultOptions, options));\r\n\r\n _cssCalc = globals.cssCalc;\r\n _msieVersion = globals.msie;\r\n _autoUpdateRecommended = globals.autoUpdateRecommended;\r\n _supportTransition = globals.supportTransition;\r\n _supportTransform = globals.supportTransform;\r\n _supportPassiveEvents = globals.supportPassiveEvents;\r\n _supportResizeObserver = globals.supportResizeObserver;\r\n _supportMutationObserver = globals.supportMutationObserver;\r\n _restrictedMeasuring = globals.restrictedMeasuring;\r\n _documentElement = FRAMEWORK(targetElement.ownerDocument);\r\n _documentElementNative = _documentElement[0];\r\n _windowElement = FRAMEWORK(_documentElementNative.defaultView || _documentElementNative.parentWindow);\r\n _windowElementNative = _windowElement[0];\r\n _htmlElement = findFirst(_documentElement, 'html');\r\n _bodyElement = findFirst(_htmlElement, 'body');\r\n _targetElement = FRAMEWORK(targetElement);\r\n _targetElementNative = _targetElement[0];\r\n _isTextarea = _targetElement.is('textarea');\r\n _isBody = _targetElement.is('body');\r\n _documentMixed = _documentElementNative !== document;\r\n\r\n /* On a div Element The if checks only whether:\r\n * - the targetElement has the class \"os-host\"\r\n * - the targetElement has a a child with the class \"os-padding\"\r\n * \r\n * If that's the case, its assumed the DOM has already the following structure:\r\n * (The \".os-host\" element is the targetElement)\r\n *\r\n * <div class=\"os-host\">\r\n * <div class=\"os-resize-observer-host\"></div>\r\n * <div class=\"os-padding\">\r\n * <div class=\"os-viewport\">\r\n * <div class=\"os-content\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar os-scrollbar-horizontal \">\r\n * <div class=\"os-scrollbar-track\">\r\n * <div class=\"os-scrollbar-handle\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar os-scrollbar-vertical\">\r\n * <div class=\"os-scrollbar-track\">\r\n * <div class=\"os-scrollbar-handle\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar-corner\"></div>\r\n * </div>\r\n *\r\n * =====================================================================================\r\n * \r\n * On a Textarea Element The if checks only whether:\r\n * - the targetElement has the class \"os-textarea\" \r\n * - the targetElement is inside a element with the class \"os-content\" \r\n * \r\n * If that's the case, its assumed the DOM has already the following structure:\r\n * (The \".os-textarea\" (textarea) element is the targetElement)\r\n *\r\n * <div class=\"os-host-textarea\">\r\n * <div class=\"os-resize-observer-host\"></div>\r\n * <div class=\"os-padding os-text-inherit\">\r\n * <div class=\"os-viewport os-text-inherit\">\r\n * <div class=\"os-content os-text-inherit\">\r\n * <div class=\"os-textarea-cover\"></div>\r\n * <textarea class=\"os-textarea os-text-inherit\"></textarea>\r\n * </div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar os-scrollbar-horizontal \">\r\n * <div class=\"os-scrollbar-track\">\r\n * <div class=\"os-scrollbar-handle\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar os-scrollbar-vertical\">\r\n * <div class=\"os-scrollbar-track\">\r\n * <div class=\"os-scrollbar-handle\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar-corner\"></div>\r\n * </div>\r\n */\r\n _domExists = _isTextarea\r\n ? _targetElement.hasClass(_classNameTextareaElement) && _targetElement.parent().hasClass(_classNameContentElement)\r\n : _targetElement.hasClass(_classNameHostElement) && _targetElement.children(_strDot + _classNamePaddingElement)[LEXICON.l];\r\n\r\n var initBodyScroll;\r\n var bodyMouseTouchDownListener;\r\n\r\n //check if the plugin hasn't to be initialized\r\n if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y && !_currentPreparedOptions.nativeScrollbarsOverlaid.initialize) {\r\n dispatchCallback('onInitializationWithdrawn');\r\n if (_domExists) {\r\n setupStructureDOM(true);\r\n setupScrollbarsDOM(true);\r\n setupScrollbarCornerDOM(true);\r\n }\r\n\r\n _destroyed = true;\r\n _sleeping = true;\r\n\r\n return _base;\r\n }\r\n\r\n if (_isBody) {\r\n initBodyScroll = {};\r\n initBodyScroll.l = MATH.max(_targetElement[_strScrollLeft](), _htmlElement[_strScrollLeft](), _windowElement[_strScrollLeft]());\r\n initBodyScroll.t = MATH.max(_targetElement[_strScrollTop](), _htmlElement[_strScrollTop](), _windowElement[_strScrollTop]());\r\n\r\n bodyMouseTouchDownListener = function () {\r\n _viewportElement.removeAttr(LEXICON.ti);\r\n setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, true, true);\r\n }\r\n }\r\n\r\n //build OverlayScrollbars DOM\r\n setupStructureDOM();\r\n setupScrollbarsDOM();\r\n setupScrollbarCornerDOM();\r\n\r\n //create OverlayScrollbars events\r\n setupStructureEvents();\r\n setupScrollbarEvents(true);\r\n setupScrollbarEvents(false);\r\n setupScrollbarCornerEvents();\r\n\r\n //create mutation observers\r\n createMutationObservers();\r\n\r\n //build resize observer for the host element\r\n setupResizeObserver(_sizeObserverElement, hostOnResized);\r\n\r\n if (_isBody) {\r\n //apply the body scroll to handle it right in the update method\r\n _viewportElement[_strScrollLeft](initBodyScroll.l)[_strScrollTop](initBodyScroll.t);\r\n\r\n //set the focus on the viewport element so you dont have to click on the page to use keyboard keys (up / down / space) for scrolling\r\n if (document.activeElement == targetElement && _viewportElementNative.focus) {\r\n //set a tabindex to make the viewportElement focusable\r\n _viewportElement.attr(LEXICON.ti, '-1');\r\n _viewportElementNative.focus();\r\n\r\n /* the tabindex has to be removed due to;\r\n * If you set the tabindex attribute on an <div>, then its child content cannot be scrolled with the arrow keys unless you set tabindex on the content, too\r\n * https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex\r\n */\r\n setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, false, true);\r\n }\r\n }\r\n\r\n //update for the first time & initialize cache\r\n _base.update(_strAuto);\r\n\r\n //the plugin is initialized now!\r\n _initialized = true;\r\n dispatchCallback('onInitialized');\r\n\r\n //call all callbacks which would fire before the initialized was complete\r\n each(_callbacksInitQeueue, function (index, value) { dispatchCallback(value.n, value.a); });\r\n _callbacksInitQeueue = [];\r\n\r\n //add extensions\r\n if (type(extensions) == TYPES.s)\r\n extensions = [extensions];\r\n if (COMPATIBILITY.isA(extensions))\r\n each(extensions, function (index, value) { _base.addExt(value); });\r\n else if (FRAMEWORK.isPlainObject(extensions))\r\n each(extensions, function (key, value) { _base.addExt(key, value); });\r\n\r\n //add the transition class for transitions AFTER the first update & AFTER the applied extensions (for preventing unwanted transitions)\r\n setTimeout(function () {\r\n if (_supportTransition && !_destroyed)\r\n addClass(_hostElement, _classNameHostTransition);\r\n }, 333);\r\n\r\n return _base;\r\n }\r\n\r\n if (_plugin.valid(construct(pluginTargetElement, options, extensions))) {\r\n INSTANCES(pluginTargetElement, _base);\r\n }\r\n\r\n return _base;\r\n }\r\n\r\n /**\r\n * Initializes a new OverlayScrollbarsInstance object or changes options if already initialized or returns the current instance.\r\n * @param pluginTargetElements The elements to which the Plugin shall be initialized.\r\n * @param options The custom options with which the plugin shall be initialized.\r\n * @param extensions The extension(s) which shall be added right after initialization.\r\n * @returns {*}\r\n */\r\n _plugin = window[PLUGINNAME] = function (pluginTargetElements, options, extensions) {\r\n if (arguments[LEXICON.l] === 0)\r\n return this;\r\n\r\n var arr = [];\r\n var optsIsPlainObj = FRAMEWORK.isPlainObject(options);\r\n var inst;\r\n var result;\r\n\r\n //pluginTargetElements is null or undefined\r\n if (!pluginTargetElements)\r\n return optsIsPlainObj || !options ? result : arr;\r\n\r\n /*\r\n pluginTargetElements will be converted to:\r\n 1. A jQueryElement Array\r\n 2. A HTMLElement Array\r\n 3. A Array with a single HTML Element\r\n so pluginTargetElements is always a array.\r\n */\r\n pluginTargetElements = pluginTargetElements[LEXICON.l] != undefined ? pluginTargetElements : [pluginTargetElements[0] || pluginTargetElements];\r\n initOverlayScrollbarsStatics();\r\n\r\n if (pluginTargetElements[LEXICON.l] > 0) {\r\n if (optsIsPlainObj) {\r\n FRAMEWORK.each(pluginTargetElements, function (i, v) {\r\n inst = v;\r\n if (inst !== undefined)\r\n arr.push(OverlayScrollbarsInstance(inst, options, extensions, _pluginsGlobals, _pluginsAutoUpdateLoop));\r\n });\r\n }\r\n else {\r\n FRAMEWORK.each(pluginTargetElements, function (i, v) {\r\n inst = INSTANCES(v);\r\n if ((options === '!' && _plugin.valid(inst)) || (COMPATIBILITY.type(options) == TYPES.f && options(v, inst)))\r\n arr.push(inst);\r\n else if (options === undefined)\r\n arr.push(inst);\r\n });\r\n }\r\n result = arr[LEXICON.l] === 1 ? arr[0] : arr;\r\n }\r\n return result;\r\n };\r\n\r\n /**\r\n * Returns a object which contains global information about the plugin and each instance of it.\r\n * The returned object is just a copy, that means that changes to the returned object won't have any effect to the original object.\r\n */\r\n _plugin.globals = function () {\r\n initOverlayScrollbarsStatics();\r\n var globals = FRAMEWORK.extend(true, {}, _pluginsGlobals);\r\n delete globals['msie'];\r\n return globals;\r\n };\r\n\r\n /**\r\n * Gets or Sets the default options for each new plugin initialization.\r\n * @param newDefaultOptions The object with which the default options shall be extended.\r\n */\r\n _plugin.defaultOptions = function (newDefaultOptions) {\r\n initOverlayScrollbarsStatics();\r\n var currDefaultOptions = _pluginsGlobals.defaultOptions;\r\n if (newDefaultOptions === undefined)\r\n return FRAMEWORK.extend(true, {}, currDefaultOptions);\r\n\r\n //set the new default options\r\n _pluginsGlobals.defaultOptions = FRAMEWORK.extend(true, {}, currDefaultOptions, _pluginsOptions._validate(newDefaultOptions, _pluginsOptions._template, true, currDefaultOptions)._default);\r\n };\r\n\r\n /**\r\n * Checks whether the passed instance is a non-destroyed OverlayScrollbars instance.\r\n * @param osInstance The potential OverlayScrollbars instance which shall be checked.\r\n * @returns {boolean} True if the passed value is a non-destroyed OverlayScrollbars instance, false otherwise.\r\n */\r\n _plugin.valid = function (osInstance) {\r\n return osInstance instanceof _plugin && !osInstance.getState().destroyed;\r\n };\r\n\r\n /**\r\n * Registers, Unregisters or returns a extension.\r\n * Register: Pass the name and the extension. (defaultOptions is optional)\r\n * Unregister: Pass the name and anything except a function as extension parameter.\r\n * Get extension: Pass the name of the extension which shall be got.\r\n * Get all extensions: Pass no arguments.\r\n * @param extensionName The name of the extension which shall be registered, unregistered or returned.\r\n * @param extension A function which generates the instance of the extension or anything other to remove a already registered extension.\r\n * @param defaultOptions The default options which shall be used for the registered extension.\r\n */\r\n _plugin.extension = function (extensionName, extension, defaultOptions) {\r\n var extNameTypeString = COMPATIBILITY.type(extensionName) == TYPES.s;\r\n var argLen = arguments[LEXICON.l];\r\n var i = 0;\r\n if (argLen < 1 || !extNameTypeString) {\r\n //return a copy of all extension objects\r\n return FRAMEWORK.extend(true, { length: _pluginsExtensions[LEXICON.l] }, _pluginsExtensions);\r\n }\r\n else if (extNameTypeString) {\r\n if (COMPATIBILITY.type(extension) == TYPES.f) {\r\n //register extension\r\n _pluginsExtensions.push({\r\n name: extensionName,\r\n extensionFactory: extension,\r\n defaultOptions: defaultOptions\r\n });\r\n }\r\n else {\r\n for (; i < _pluginsExtensions[LEXICON.l]; i++) {\r\n if (_pluginsExtensions[i].name === extensionName) {\r\n if (argLen > 1)\r\n _pluginsExtensions.splice(i, 1); //remove extension\r\n else\r\n return FRAMEWORK.extend(true, {}, _pluginsExtensions[i]); //return extension with the given name\r\n }\r\n }\r\n }\r\n }\r\n };\r\n\r\n return _plugin;\r\n })();\r\n\r\n if (JQUERY && JQUERY.fn) {\r\n /**\r\n * The jQuery initialization interface.\r\n * @param options The initial options for the construction of the plugin. To initialize the plugin, this option has to be a object! If it isn't a object, the instance(s) are returned and the plugin wont be initialized.\r\n * @param extensions The extension(s) which shall be added right after initialization.\r\n * @returns {*} After initialization it returns the jQuery element array, else it returns the instance(s) of the elements which are selected.\r\n */\r\n JQUERY.fn.overlayScrollbars = function (options, extensions) {\r\n var _elements = this;\r\n if (JQUERY.isPlainObject(options)) {\r\n JQUERY.each(_elements, function () { PLUGIN(this, options, extensions); });\r\n return _elements;\r\n }\r\n else\r\n return PLUGIN(_elements, options);\r\n };\r\n }\r\n return PLUGIN;\r\n }\r\n));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vL2hvbWUvamVua2lucy93b3Jrc3BhY2UvZGVzaWduLXN5c3RlbV9QUi0xMy9ub2RlX21vZHVsZXMvb3ZlcmxheXNjcm9sbGJhcnMvanMvT3ZlcmxheVNjcm9sbGJhcnMuanM/YWUyNyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxRQUFRLElBQTBDO0FBQ2xELFFBQVEsbUNBQU8sYUFBYSxvREFBb0QsRUFBRTtBQUFBLG9HQUFDO0FBQ25GLFNBQVMsRUFHMkM7QUFDcEQsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQix3QkFBd0I7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsb0NBQW9DO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwwQkFBMEIsOEJBQThCO0FBQ3hELDhCQUE4QixxQ0FBcUM7QUFDbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOEJBQThCLDJCQUEyQjtBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0M7QUFDeEMsMENBQTBDLDRHQUE0Rzs7QUFFdEo7QUFDQSw4Q0FBOEM7QUFDOUM7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsY0FBYztBQUMzQztBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsY0FBYztBQUMzQztBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsNkJBQTZCO0FBQzFEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLFdBQVc7QUFDeEM7QUFDQSw4RkFBOEYsMkNBQTJDLEVBQUU7O0FBRTNJO0FBQ0E7QUFDQSw2QkFBNkIsV0FBVztBQUN4QztBQUNBLDJGQUEyRixnQ0FBZ0MsRUFBRTs7QUFFN0g7QUFDQTtBQUNBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QixzQkFBc0I7QUFDcEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsT0FBTztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsT0FBTztBQUNwQztBQUNBO0FBQ0EsbUNBQW1DLG9CQUFvQjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLE9BQU87QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7OztBQUdqQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsWUFBWTs7QUFFekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7OztBQUdUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtREFBbUQsbUJBQW1CO0FBQ3RFOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsMkNBQTJDLFdBQVc7QUFDdEQseUNBQXlDLGlDQUFpQztBQUMxRSxnREFBZ0QsT0FBTyxXQUFXO0FBQ2xFO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSwyQ0FBMkMsV0FBVztBQUN0RDtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsT0FBTyxXQUFXO0FBQ2xFO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSwyQ0FBMkMsV0FBVztBQUN0RDtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsT0FBTyxXQUFXO0FBQ2xFO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLCtCQUErQjtBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2RkFBNkY7QUFDN0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsc0JBQXNCLFlBQVk7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaUNBQWlDO0FBQ2pDO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRDQUE0QyxvQkFBb0I7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQSxrQ0FBa0M7O0FBRWxDO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDBCQUEwQixvQkFBb0I7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUNBQW1DLHNCQUFzQjtBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixZQUFZO0FBQzdCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsc0JBQXNCLDRCQUE0QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBLHlDQUF5QztBQUN6QztBQUNBOztBQUVBO0FBQ0EsK0NBQStDOztBQUUvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsNEJBQTRCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQixxQkFBcUI7QUFDL0M7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsK0JBQStCLHlCQUF5QjtBQUN4RDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQyxxQkFBcUI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLHFCQUFxQjtBQUMzRDtBQUNBO0FBQ0EseUJBQXlCLFlBQVk7QUFDckMscUJBQXFCO0FBQ3JCLGlCQUFpQjs7QUFFakI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQyxxQkFBcUI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLHFCQUFxQjtBQUMzRDtBQUNBO0FBQ0EseUJBQXlCLFlBQVk7QUFDckMscUJBQXFCO0FBQ3JCLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekIscUJBQXFCO0FBQ3JCLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckIsaUJBQWlCOztBQUVqQjs7QUFFQTtBQUNBLGtEQUFrRCxpREFBaUQsRUFBRTtBQUNyRyxpQkFBaUI7O0FBRWpCO0FBQ0Esa0RBQWtELGtEQUFrRCxFQUFFO0FBQ3RHLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0QsbURBQW1ELEVBQUU7QUFDdkcsaUJBQWlCOztBQUVqQjtBQUNBLGtEQUFrRCxnREFBZ0QsRUFBRTtBQUNwRyxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQixpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7O0FBRXJCLCtCQUErQix3QkFBd0I7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsK0JBQStCLHNCQUFzQjtBQUNyRDs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQixpQkFBaUI7O0FBRWpCO0FBQ0Esa0RBQWtELHVDQUF1QyxFQUFFO0FBQzNGLGlCQUFpQjs7O0FBR2pCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0Esa0RBQWtELGtDQUFrQyxFQUFFO0FBQ3RGLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0QsbUNBQW1DLEVBQUU7QUFDdkYsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0Esa0RBQWtELGdDQUFnQyxFQUFFO0FBQ3BGLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7OztBQUdqQjs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsbUJBQW1CO0FBQ3REO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQ0FBbUMsbUJBQW1CO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EsaUJBQWlCOztBQUVqQjs7QUFFQTtBQUNBO0FBQ0EsK0JBQStCLHFCQUFxQjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQ0FBbUMsdUJBQXVCO0FBQzFEO0FBQ0EscUJBQXFCOztBQUVyQjtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBLGlCQUFpQjs7O0FBR2pCOztBQUVBO0FBQ0Esa0RBQWtELGtEQUFrRCxFQUFFO0FBQ3RHLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0QsMEJBQTBCLEVBQUU7QUFDOUU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLE9BQU87QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOERBQThEO0FBQzlEOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0VBQWtFO0FBQ2xFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0ZBQW9GOztBQUVwRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBLG1EQUFtRCw4QkFBOEI7QUFDakY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRCw0Q0FBNEM7QUFDdkc7QUFDQTtBQUNBO0FBQ0EsK0RBQStELHlEQUF5RDtBQUN4SDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRFQUE0RTs7QUFFNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0RBQW9EOztBQUVwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLGFBQWE7O0FBRXRDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EscUJBQXFCO0FBQ3JCLGdEQUFnRCxlQUFlO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLG1EQUFtRCx1RUFBdUU7QUFDMUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEZBQTBGO0FBQzFGO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3Qix5QkFBeUIsWUFBWTtBQUNyQztBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDO0FBQ3JDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkMsbUNBQW1DO0FBQzlFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQyxpQ0FBaUM7QUFDakMsNkNBQTZDO0FBQzdDLHlDQUF5QztBQUN6QyxvQ0FBb0M7QUFDcEMscUNBQXFDO0FBQ3JDLG9DQUFvQztBQUNwQywyQ0FBMkM7QUFDM0Msd0NBQXdDO0FBQ3hDLDBDQUEwQztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7O0FBRXJCO0FBQ0EsOEJBQThCLDJCQUEyQjtBQUN6RDtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsdUJBQXVCO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QjtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RCxxREFBcUQ7QUFDOUc7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRUFBaUUsa0VBQWtFLGdCQUFnQjtBQUNuSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEZBQTBGO0FBQzFGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQztBQUNyQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQ0FBaUM7O0FBRWpDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQzs7QUFFakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCOztBQUV6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5Qjs7QUFFekI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyx5QkFBeUI7QUFDN0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0NBQW9DLDRCQUE0QjtBQUNoRTtBQUNBLHFCQUFxQjtBQUNyQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1DQUFtQyxpQkFBaUI7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBLHFCQUFxQjs7QUFFckI7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QyxvQkFBb0I7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1JQUFtSTs7QUFFbkk7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLEVBQUU7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDREQUE0RDtBQUM1RDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDhGQUE4Rjs7QUFFOUY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDhGQUE4RjtBQUM5Rjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBEQUEwRDtBQUMxRDtBQUNBO0FBQ0EsOERBQThEOztBQUU5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwrQ0FBK0M7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkZBQTZGO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0ZBQW9GO0FBQ3BGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlFQUFpRSxXQUFXO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdMQUFnTDtBQUNoTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtREFBbUQsZ0JBQWdCO0FBQ25FOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0IseUJBQXlCO0FBQ3pCO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLEVBQUU7QUFDL0I7QUFDQTtBQUNBOztBQUVBLG1EQUFtRDtBQUNuRCwyREFBMkQ7O0FBRTNEO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7O0FBRTdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3RUFBd0U7QUFDeEU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxtSEFBbUg7QUFDbkg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0SEFBNEgsaUJBQWlCO0FBQzdJLHlCQUF5Qjs7O0FBR3pCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2SEFBNkgsaUJBQWlCO0FBQzlJLHlCQUF5Qjs7O0FBR3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtKQUFrSjtBQUNsSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhFQUE4RTtBQUM5RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSx3RkFBd0Y7QUFDeEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtSEFBbUg7O0FBRW5IO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsK05BQStOO0FBQy9OO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEhBQTBIO0FBQzFILGlIQUFpSDtBQUNqSDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QiwrRUFBK0U7QUFDN0c7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0RBQStELHFDQUFxQztBQUNwRzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBLG1EQUFtRCxtQkFBbUI7QUFDdEU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsT0FBTztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwwQkFBMEIsMkJBQTJCO0FBQ3JEO0FBQ0EsbUNBQW1DLDJCQUEyQjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMkJBQTJCLFFBQVE7QUFDbkMsMkJBQTJCLFFBQVE7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLHNCQUFzQjtBQUM3RDtBQUNBLDBEQUEwRDtBQUMxRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOEJBQThCLHNCQUFzQjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLE1BQU07QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLGVBQWU7QUFDOUM7QUFDQSwrQkFBK0IsZUFBZTtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4QkFBOEIsbUdBQW1HO0FBQ2pJO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsK0JBQStCLGlDQUFpQztBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLG1CQUFtQjtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQixrQkFBa0I7QUFDNUMsb0ZBQW9GO0FBQ3BGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJCQUEyQixTQUFTO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixrQjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsZ0JBQWdCO0FBQ3BEOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQ0FBZ0MsOEJBQThCO0FBQzlEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsbUNBQW1DLGtDQUFrQztBQUNyRTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsZUFBZTtBQUN0Qyx1QkFBdUIsb0JBQW9CO0FBQzNDLHVCQUF1QixlQUFlO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxxQkFBcUI7QUFDckQsNkJBQTZCLHFCQUFxQjtBQUNsRCwyQkFBMkIscUJBQXFCO0FBQ2hELG9DQUFvQyxxQkFBcUI7QUFDekQsb0NBQW9DLHFCQUFxQjtBQUN6RCx5Q0FBeUMscUJBQXFCO0FBQzlELGtDQUFrQyxxQkFBcUI7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsOEJBQThCO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRztBQUNBLHVDQUF1QyxnQ0FBZ0M7QUFDdkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyxvQkFBb0I7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyw4Q0FBOEM7QUFDakY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLEVBQUU7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsK0VBQStFLGtDQUFrQyxzQkFBc0Isa0NBQWtDLHFCQUFxQjtBQUM1TjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLHdIQUF3SDtBQUN0SjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0RBQW9EO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRDtBQUMzRCw0REFBNEQ7QUFDNUQsMENBQTBDO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRDtBQUNsRCxrQ0FBa0MsMkJBQTJCO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRDtBQUNyRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3REFBd0Q7QUFDeEQsOERBQThEO0FBQzlELDhEQUE4RDtBQUM5RCxzREFBc0Q7O0FBRXREO0FBQ0EsNENBQTRDOztBQUU1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esd0VBQXdFLG9DQUFvQyxFQUFFO0FBQzlHOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0VBQWtFLHFCQUFxQixFQUFFO0FBQ3pGO0FBQ0EsZ0VBQWdFLDBCQUEwQixFQUFFOztBQUU1RjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjs7QUFFckI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQ7QUFDdkQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0Q7O0FBRXBEO0FBQ0EsMEVBQTBFO0FBQzFFOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixRQUFRO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1ELHdDQUF3QztBQUMzRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQSw4QkFBOEIsbUNBQW1DO0FBQ2pFO0FBQ0E7QUFDQSxvRUFBb0U7QUFDcEU7QUFDQSxvRUFBb0UseUJBQXlCO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsRUFBRTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RCxtQ0FBbUMsRUFBRTtBQUM3RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMTA4NC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qIVxyXG4gKiBPdmVybGF5U2Nyb2xsYmFyc1xyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vS2luZ1NvcmEvT3ZlcmxheVNjcm9sbGJhcnNcclxuICpcclxuICogVmVyc2lvbjogMS4xMy4wXHJcbiAqXHJcbiAqIENvcHlyaWdodCBLaW5nU29yYSB8IFJlbmUgSGFhcy5cclxuICogaHR0cHM6Ly9naXRodWIuY29tL0tpbmdTb3JhXHJcbiAqXHJcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cclxuICogRGF0ZTogMDIuMDguMjAyMFxyXG4gKi9cclxuXHJcbihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XHJcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKVxyXG4gICAgICAgIGRlZmluZShmdW5jdGlvbiAoKSB7IHJldHVybiBmYWN0b3J5KGdsb2JhbCwgZ2xvYmFsLmRvY3VtZW50LCB1bmRlZmluZWQpOyB9KTtcclxuICAgIGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gJ29iamVjdCcpXHJcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KGdsb2JhbCwgZ2xvYmFsLmRvY3VtZW50LCB1bmRlZmluZWQpO1xyXG4gICAgZWxzZVxyXG4gICAgICAgIGZhY3RvcnkoZ2xvYmFsLCBnbG9iYWwuZG9jdW1lbnQsIHVuZGVmaW5lZCk7XHJcbn0odHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0aGlzLFxyXG4gICAgZnVuY3Rpb24gKHdpbmRvdywgZG9jdW1lbnQsIHVuZGVmaW5lZCkge1xyXG4gICAgICAgICd1c2Ugc3RyaWN0JztcclxuICAgICAgICB2YXIgUExVR0lOTkFNRSA9ICdPdmVybGF5U2Nyb2xsYmFycyc7XHJcbiAgICAgICAgdmFyIFRZUEVTID0ge1xyXG4gICAgICAgICAgICBvOiAnb2JqZWN0JyxcclxuICAgICAgICAgICAgZjogJ2Z1bmN0aW9uJyxcclxuICAgICAgICAgICAgYTogJ2FycmF5JyxcclxuICAgICAgICAgICAgczogJ3N0cmluZycsXHJcbiAgICAgICAgICAgIGI6ICdib29sZWFuJyxcclxuICAgICAgICAgICAgbjogJ251bWJlcicsXHJcbiAgICAgICAgICAgIHU6ICd1bmRlZmluZWQnLFxyXG4gICAgICAgICAgICB6OiAnbnVsbCdcclxuICAgICAgICAgICAgLy9kIDogJ2RhdGUnLFxyXG4gICAgICAgICAgICAvL2UgOiAnZXJyb3InLFxyXG4gICAgICAgICAgICAvL3IgOiAncmVnZXhwJyxcclxuICAgICAgICAgICAgLy95IDogJ3N5bWJvbCdcclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciBMRVhJQ09OID0ge1xyXG4gICAgICAgICAgICBjOiAnY2xhc3MnLFxyXG4gICAgICAgICAgICBzOiAnc3R5bGUnLFxyXG4gICAgICAgICAgICBpOiAnaWQnLFxyXG4gICAgICAgICAgICBsOiAnbGVuZ3RoJyxcclxuICAgICAgICAgICAgcDogJ3Byb3RvdHlwZScsXHJcbiAgICAgICAgICAgIHRpOiAndGFiaW5kZXgnLFxyXG4gICAgICAgICAgICBvSDogJ29mZnNldEhlaWdodCcsXHJcbiAgICAgICAgICAgIGNIOiAnY2xpZW50SGVpZ2h0JyxcclxuICAgICAgICAgICAgc0g6ICdzY3JvbGxIZWlnaHQnLFxyXG4gICAgICAgICAgICBvVzogJ29mZnNldFdpZHRoJyxcclxuICAgICAgICAgICAgY1c6ICdjbGllbnRXaWR0aCcsXHJcbiAgICAgICAgICAgIHNXOiAnc2Nyb2xsV2lkdGgnLFxyXG4gICAgICAgICAgICBoT1A6ICdoYXNPd25Qcm9wZXJ0eScsXHJcbiAgICAgICAgICAgIGJDUjogJ2dldEJvdW5kaW5nQ2xpZW50UmVjdCdcclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciBWRU5ET1JTID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy9odHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL0dsb3NzYXJ5L1ZlbmRvcl9QcmVmaXhcclxuICAgICAgICAgICAgdmFyIGpzQ2FjaGUgPSB7fTtcclxuICAgICAgICAgICAgdmFyIGNzc0NhY2hlID0ge307XHJcbiAgICAgICAgICAgIHZhciBjc3NQcmVmaXhlcyA9IFsnLXdlYmtpdC0nLCAnLW1vei0nLCAnLW8tJywgJy1tcy0nXTtcclxuICAgICAgICAgICAgdmFyIGpzUHJlZml4ZXMgPSBbJ1dlYktpdCcsICdNb3onLCAnTycsICdNUyddO1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBmaXJzdExldHRlclRvVXBwZXIoc3RyKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgX2Nzc1ByZWZpeGVzOiBjc3NQcmVmaXhlcyxcclxuICAgICAgICAgICAgICAgIF9qc1ByZWZpeGVzOiBqc1ByZWZpeGVzLFxyXG4gICAgICAgICAgICAgICAgX2Nzc1Byb3BlcnR5OiBmdW5jdGlvbiAobmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBjc3NDYWNoZVtuYW1lXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNzc0NhY2hlW0xFWElDT04uaE9QXShuYW1lKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHVwcGVyY2FzZWROYW1lID0gZmlyc3RMZXR0ZXJUb1VwcGVyKG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbG1TdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpW0xFWElDT04uc107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdFBvc3NpYmlsaXRpZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyVmVuZG9yV2l0aG91dERhc2hlcztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBjc3NQcmVmaXhlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyVmVuZG9yV2l0aG91dERhc2hlcyA9IGNzc1ByZWZpeGVzW2ldLnJlcGxhY2UoLy0vZywgJycpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRQb3NzaWJpbGl0aWVzID0gW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgLy90cmFuc2l0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3NQcmVmaXhlc1tpXSArIG5hbWUsIC8vLXdlYmtpdC10cmFuc2l0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyVmVuZG9yV2l0aG91dERhc2hlcyArIHVwcGVyY2FzZWROYW1lLCAvL3dlYmtpdFRyYW5zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0TGV0dGVyVG9VcHBlcihjdXJyVmVuZG9yV2l0aG91dERhc2hlcykgKyB1cHBlcmNhc2VkTmFtZSAvL1dlYmtpdFRyYW5zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2ID0gMDsgdiA8IHJlc3VsdFBvc3NpYmlsaXRpZXNbTEVYSUNPTi5sXTsgdisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxtU3R5bGVbcmVzdWx0UG9zc2liaWxpdGllc1t2XV0gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdFBvc3NpYmlsaXRpZXNbdl07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNzc0NhY2hlW25hbWVdID0gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgX2Nzc1Byb3BlcnR5VmFsdWU6IGZ1bmN0aW9uIChwcm9wZXJ0eSwgdmFsdWVzLCBzdWZmaXgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IHByb3BlcnR5ICsgJyAnICsgdmFsdWVzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBjc3NDYWNoZVtuYW1lXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNzc0NhY2hlW0xFWElDT04uaE9QXShuYW1lKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGR1bW15U3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVtMRVhJQ09OLnNdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3NzYmxlVmFsdWVzID0gdmFsdWVzLnNwbGl0KCcgJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByZXBhcmVkU3VmZml4ID0gc3VmZml4IHx8ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdiA9IC0xO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwcm9wO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IHBvc3NibGVWYWx1ZXNbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyB2IDwgVkVORE9SUy5fY3NzUHJlZml4ZXNbTEVYSUNPTi5sXTsgdisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wID0gdiA8IDAgPyBwb3NzYmxlVmFsdWVzW2ldIDogVkVORE9SUy5fY3NzUHJlZml4ZXNbdl0gKyBwb3NzYmxlVmFsdWVzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVtbXlTdHlsZS5jc3NUZXh0ID0gcHJvcGVydHkgKyAnOicgKyBwcm9wICsgcHJlcGFyZWRTdWZmaXg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZHVtbXlTdHlsZVtMRVhJQ09OLmxdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcHJvcDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY3NzQ2FjaGVbbmFtZV0gPSByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBfanNBUEk6IGZ1bmN0aW9uIChuYW1lLCBpc0ludGVyZmFjZSwgZmFsbGJhY2spIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGpzQ2FjaGVbbmFtZV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghanNDYWNoZVtMRVhJQ09OLmhPUF0obmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gd2luZG93W25hbWVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGpzUHJlZml4ZXNbTEVYSUNPTi5sXTsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0IHx8IHdpbmRvd1soaXNJbnRlcmZhY2UgPyBqc1ByZWZpeGVzW2ldIDoganNQcmVmaXhlc1tpXS50b0xvd2VyQ2FzZSgpKSArIGZpcnN0TGV0dGVyVG9VcHBlcihuYW1lKV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzQ2FjaGVbbmFtZV0gPSByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgfHwgZmFsbGJhY2s7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KSgpO1xyXG4gICAgICAgIHZhciBDT01QQVRJQklMSVRZID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgZnVuY3Rpb24gd2luZG93U2l6ZSh4KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4geCA/IHdpbmRvdy5pbm5lcldpZHRoIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudFtMRVhJQ09OLmNXXSB8fCBkb2N1bWVudC5ib2R5W0xFWElDT04uY1ddIDogd2luZG93LmlubmVySGVpZ2h0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudFtMRVhJQ09OLmNIXSB8fCBkb2N1bWVudC5ib2R5W0xFWElDT04uY0hdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGJpbmQoZnVuYywgdGhpc09iaikge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBmdW5jICE9IFRZUEVTLmYpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBcIkNhbid0IGJpbmQgZnVuY3Rpb24hXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY2xvc2VzdCB0aGluZyBwb3NzaWJsZSB0byB0aGUgRUNNQVNjcmlwdCA1XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gaW50ZXJuYWwgSXNDYWxsYWJsZSBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgIC8vdGhyb3cgbmV3IFR5cGVFcnJvcignRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgLSB3aGF0IGlzIHRyeWluZyB0byBiZSBib3VuZCBpcyBub3QgY2FsbGFibGUnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHZhciBwcm90byA9IExFWElDT04ucDtcclxuICAgICAgICAgICAgICAgIHZhciBhQXJncyA9IEFycmF5W3Byb3RvXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XHJcbiAgICAgICAgICAgICAgICB2YXIgZk5PUCA9IGZ1bmN0aW9uICgpIHsgfTtcclxuICAgICAgICAgICAgICAgIHZhciBmQm91bmQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBmdW5jLmFwcGx5KHRoaXMgaW5zdGFuY2VvZiBmTk9QID8gdGhpcyA6IHRoaXNPYmosIGFBcmdzLmNvbmNhdChBcnJheVtwcm90b10uc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7IH07XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGZ1bmNbcHJvdG9dKVxyXG4gICAgICAgICAgICAgICAgICAgIGZOT1BbcHJvdG9dID0gZnVuY1twcm90b107IC8vIEZ1bmN0aW9uLnByb3RvdHlwZSBkb2Vzbid0IGhhdmUgYSBwcm90b3R5cGUgcHJvcGVydHlcclxuICAgICAgICAgICAgICAgIGZCb3VuZFtwcm90b10gPSBuZXcgZk5PUCgpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBmQm91bmQ7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIGN1cnJlbnQgd2luZG93IHdpZHRoLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge051bWJlcnxudW1iZXJ9IFRoZSBjdXJyZW50IHdpbmRvdyB3aWR0aCBpbiBwaXhlbC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgd1c6IGJpbmQod2luZG93U2l6ZSwgMCwgdHJ1ZSksXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHdpbmRvdyBoZWlnaHQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7TnVtYmVyfG51bWJlcn0gVGhlIGN1cnJlbnQgd2luZG93IGhlaWdodCBpbiBwaXhlbC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgd0g6IGJpbmQod2luZG93U2l6ZSwgMCksXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHRoZSBNdXRhdGlvbk9ic2VydmVyIE9iamVjdCBvciB1bmRlZmluZWQgaWYgbm90IHN1cHBvcnRlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtNdXRhdGlvbk9ic2VydmVyfCp8dW5kZWZpbmVkfSBUaGUgTXV0YXRpb25zT2JzZXJ2ZXIgT2JqZWN0IG9yIHVuZGVmaW5lZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgbU86IGJpbmQoVkVORE9SUy5fanNBUEksIDAsICdNdXRhdGlvbk9ic2VydmVyJywgdHJ1ZSksXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHRoZSBSZXNpemVPYnNlcnZlciBPYmplY3Qgb3IgdW5kZWZpbmVkIGlmIG5vdCBzdXBwb3J0ZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7TXV0YXRpb25PYnNlcnZlcnwqfHVuZGVmaW5lZH0gVGhlIFJlc2l6ZU9ic2VydmVyIE9iamVjdCBvciB1bmRlZmluZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIHJPOiBiaW5kKFZFTkRPUlMuX2pzQVBJLCAwLCAnUmVzaXplT2JzZXJ2ZXInLCB0cnVlKSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIFJlcXVlc3RBbmltYXRpb25GcmFtZSBtZXRob2Qgb3IgaXQncyBjb3JyZXNwb25kaW5nIHBvbHlmaWxsLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMgeyp8RnVuY3Rpb259IFRoZSBSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgbWV0aG9kIG9yIGl0J3MgY29ycmVzcG9uZGluZyBwb2x5ZmlsbC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgckFGOiBiaW5kKFZFTkRPUlMuX2pzQVBJLCAwLCAncmVxdWVzdEFuaW1hdGlvbkZyYW1lJywgZmFsc2UsIGZ1bmN0aW9uIChmdW5jKSB7IHJldHVybiB3aW5kb3cuc2V0VGltZW91dChmdW5jLCAxMDAwIC8gNjApOyB9KSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIENhbmNlbEFuaW1hdGlvbkZyYW1lIG1ldGhvZCBvciBpdCdzIGNvcnJlc3BvbmRpbmcgcG9seWZpbGwuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7KnxGdW5jdGlvbn0gVGhlIENhbmNlbEFuaW1hdGlvbkZyYW1lIG1ldGhvZCBvciBpdCdzIGNvcnJlc3BvbmRpbmcgcG9seWZpbGwuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGNBRjogYmluZChWRU5ET1JTLl9qc0FQSSwgMCwgJ2NhbmNlbEFuaW1hdGlvbkZyYW1lJywgZmFsc2UsIGZ1bmN0aW9uIChpZCkgeyByZXR1cm4gd2luZG93LmNsZWFyVGltZW91dChpZCk7IH0pLFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgY3VycmVudCB0aW1lLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge251bWJlcn0gVGhlIGN1cnJlbnQgdGltZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgbm93OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERhdGUubm93ICYmIERhdGUubm93KCkgfHwgbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogU3RvcHMgdGhlIHByb3BhZ2F0aW9uIG9mIHRoZSBnaXZlbiBldmVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgb2Ygd2hpY2ggdGhlIHByb3BhZ2F0aW9uIHNoYWxsIGJlIHN0b3BlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgc3RwUDogZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50LnN0b3BQcm9wYWdhdGlvbilcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5jYW5jZWxCdWJibGUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFByZXZlbnRzIHRoZSBkZWZhdWx0IGFjdGlvbiBvZiB0aGUgZ2l2ZW4gZXZlbnQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZXZlbnQgVGhlIGV2ZW50IG9mIHdoaWNoIHRoZSBkZWZhdWx0IGFjdGlvbiBzaGFsbCBiZSBwcmV2ZW50ZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIHBydkQ6IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChldmVudC5wcmV2ZW50RGVmYXVsdCAmJiBldmVudC5jYW5jZWxhYmxlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucmV0dXJuVmFsdWUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHRoZSBwYWdlWCBhbmQgcGFnZVkgdmFsdWVzIG9mIHRoZSBnaXZlbiBtb3VzZSBldmVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBldmVudCBUaGUgbW91c2UgZXZlbnQgb2Ygd2hpY2ggdGhlIHBhZ2VYIGFuZCBwYWdlWCBzaGFsbCBiZSBnb3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e3g6IG51bWJlciwgeTogbnVtYmVyfX0geCA9IHBhZ2VYIHZhbHVlLCB5ID0gcGFnZVkgdmFsdWUuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIHBhZ2U6IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50ID0gZXZlbnQub3JpZ2luYWxFdmVudCB8fCBldmVudDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clBhZ2UgPSAncGFnZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckNsaWVudCA9ICdjbGllbnQnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJYID0gJ1gnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJZID0gJ1knO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSBldmVudC50YXJnZXQgfHwgZXZlbnQuc3JjRWxlbWVudCB8fCBkb2N1bWVudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnREb2MgPSB0YXJnZXQub3duZXJEb2N1bWVudCB8fCBkb2N1bWVudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZG9jID0gZXZlbnREb2MuZG9jdW1lbnRFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBib2R5ID0gZXZlbnREb2MuYm9keTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9pZiB0b3VjaCBldmVudCByZXR1cm4gcmV0dXJuIHBhZ2VYL1kgb2YgaXRcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQudG91Y2hlcyAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0b3VjaCA9IGV2ZW50LnRvdWNoZXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiB0b3VjaFtzdHJQYWdlICsgc3RyWF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiB0b3VjaFtzdHJQYWdlICsgc3RyWV1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIHBhZ2VYL1kgaWYgbm90IG5hdGl2ZSBzdXBwb3J0ZWRcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWV2ZW50W3N0clBhZ2UgKyBzdHJYXSAmJiBldmVudFtzdHJDbGllbnQgKyBzdHJYXSAmJiBldmVudFtzdHJDbGllbnQgKyBzdHJYXSAhPSBudWxsKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogZXZlbnRbc3RyQ2xpZW50ICsgc3RyWF0gK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkb2MgJiYgZG9jLnNjcm9sbExlZnQgfHwgYm9keSAmJiBib2R5LnNjcm9sbExlZnQgfHwgMCkgLVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkb2MgJiYgZG9jLmNsaWVudExlZnQgfHwgYm9keSAmJiBib2R5LmNsaWVudExlZnQgfHwgMCksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBldmVudFtzdHJDbGllbnQgKyBzdHJZXSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRvYyAmJiBkb2Muc2Nyb2xsVG9wIHx8IGJvZHkgJiYgYm9keS5zY3JvbGxUb3AgfHwgMCkgLVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkb2MgJiYgZG9jLmNsaWVudFRvcCB8fCBib2R5ICYmIGJvZHkuY2xpZW50VG9wIHx8IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgeDogZXZlbnRbc3RyUGFnZSArIHN0clhdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBldmVudFtzdHJQYWdlICsgc3RyWV1cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIGNsaWNrZWQgbW91c2UgYnV0dG9uIG9mIHRoZSBnaXZlbiBtb3VzZSBldmVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBldmVudCBUaGUgbW91c2UgZXZlbnQgb2Ygd2hpY2ggdGhlIGNsaWNrZWQgYnV0dG9uIHNoYWwgYmUgZ290LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge251bWJlcn0gVGhlIG51bWJlciBvZiB0aGUgY2xpY2tlZCBtb3VzZSBidXR0b24uICgwIDogbm9uZSB8IDEgOiBsZWZ0QnV0dG9uIHwgMiA6IG1pZGRsZUJ1dHRvbiB8IDMgOiByaWdodEJ1dHRvbilcclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgbUJ0bjogZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJ1dHRvbiA9IGV2ZW50LmJ1dHRvbjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWV2ZW50LndoaWNoICYmIGJ1dHRvbiAhPT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGJ1dHRvbiAmIDEgPyAxIDogKGJ1dHRvbiAmIDIgPyAzIDogKGJ1dHRvbiAmIDQgPyAyIDogMCkpKTtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBldmVudC53aGljaDtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDaGVja3Mgd2hldGhlciBhIGl0ZW0gaXMgaW4gdGhlIGdpdmVuIGFycmF5IGFuZCByZXR1cm5zIGl0cyBpbmRleC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpdGVtIFRoZSBpdGVtIG9mIHdoaWNoIHRoZSBwb3NpdGlvbiBpbiB0aGUgYXJyYXkgc2hhbGwgYmUgZGV0ZXJtaW5lZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBhcnIgVGhlIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge251bWJlcn0gVGhlIHplcm8gYmFzZWQgaW5kZXggb2YgdGhlIGl0ZW0gb3IgLTEgaWYgdGhlIGl0ZW0gaXNuJ3QgaW4gdGhlIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBpbkE6IGZ1bmN0aW9uIChpdGVtLCBhcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFycltMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vU29tZXRpZW1zIGluIElFIGEgXCJTQ1JJUFQ3MFwiIFBlcm1pc3Npb24gZGVuaWVkIGVycm9yIG9jY3VycyBpZiBIVE1MIGVsZW1lbnRzIGluIGEgaUZyYW1lIGFyZSBjb21wYXJlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFycltpXSA9PT0gaXRlbSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZSkgeyB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gdmFsdWUgaXMgYSBhcnJheS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBhcnIgVGhlIHBvdGVudGlhbCBhcnJheS5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyBhIGFycmF5LCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGlzQTogZnVuY3Rpb24gKGFycikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkZWYgPSBBcnJheS5pc0FycmF5O1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWYgPyBkZWYoYXJyKSA6IHRoaXMudHlwZShhcnIpID09IFRZUEVTLmE7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogRGV0ZXJtaW5lIHRoZSBpbnRlcm5hbCBKYXZhU2NyaXB0IFtbQ2xhc3NdXSBvZiB0aGUgZ2l2ZW4gb2JqZWN0LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG9iaiBUaGUgb2JqZWN0IG9mIHdoaWNoIHRoZSB0eXBlIHNoYWxsIGJlIGRldGVybWluZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgdHlwZSBvZiB0aGUgZ2l2ZW4gb2JqZWN0LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICB0eXBlOiBmdW5jdGlvbiAob2JqKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9iaiA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2JqICsgJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9iaiA9PT0gbnVsbClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9iaiArICcnO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3RbTEVYSUNPTi5wXS50b1N0cmluZy5jYWxsKG9iaikucmVwbGFjZSgvXlxcW29iamVjdCAoLispXFxdJC8sICckMScpLnRvTG93ZXJDYXNlKCk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICBiaW5kOiBiaW5kXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHRoZSB2ZW5kb3ItcHJlZml4ZWQgQ1NTIHByb3BlcnR5IGJ5IHRoZSBnaXZlbiBuYW1lLlxyXG4gICAgICAgICAgICAgICAgICogRm9yIGV4YW1wbGUgdGhlIGdpdmVuIG5hbWUgaXMgXCJ0cmFuc2Zvcm1cIiBhbmQgeW91J3JlIHVzaW5nIGEgb2xkIEZpcmVmb3ggYnJvd3NlciB0aGVuIHRoZSByZXR1cm5lZCB2YWx1ZSB3b3VsZCBiZSBcIi1tb3otdHJhbnNmb3JtXCIuXHJcbiAgICAgICAgICAgICAgICAgKiBJZiB0aGUgYnJvd3NlciBkb2Vzbid0IG5lZWQgYSB2ZW5kb3ItcHJlZml4LCB0aGVuIHRoZSByZXR1cm5lZCBzdHJpbmcgaXMgdGhlIGdpdmVuIG5hbWUuXHJcbiAgICAgICAgICAgICAgICAgKiBJZiB0aGUgYnJvd3NlciBkb2Vzbid0IHN1cHBvcnQgdGhlIGdpdmVuIHByb3BlcnR5IG5hbWUgYXQgYWxsIChub3QgZXZlbiB3aXRoIGEgdmVuZG9yLXByZWZpeCkgdGhlIHJldHVybmVkIHZhbHVlIGlzIG51bGwuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gcHJvcE5hbWUgVGhlIHVucHJlZml4ZWQgQ1NTIHByb3BlcnR5IG5hbWUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IFRoZSB2ZW5kb3ItcHJlZml4ZWQgQ1NTIHByb3BlcnR5IG9yIG51bGwgaWYgdGhlIGJyb3dzZXIgZG9lc24ndCBzdXBwb3J0IHRoZSBnaXZlbiBDU1MgcHJvcGVydHkuXHJcblxyXG4gICAgICAgICAgICAgICAgY3NzUHJvcDogZnVuY3Rpb24ocHJvcE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVkVORE9SUy5fY3NzUHJvcGVydHkocHJvcE5hbWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pKCk7XHJcblxyXG5cclxuICAgICAgICB2YXIgTUFUSCA9IE1hdGg7XHJcbiAgICAgICAgdmFyIEpRVUVSWSA9IHdpbmRvdy5qUXVlcnk7XHJcbiAgICAgICAgdmFyIEVBU0lORyA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBfZWFzaW5nc01hdGggPSB7XHJcbiAgICAgICAgICAgICAgICBwOiBNQVRILlBJLFxyXG4gICAgICAgICAgICAgICAgYzogTUFUSC5jb3MsXHJcbiAgICAgICAgICAgICAgICBzOiBNQVRILnNpbixcclxuICAgICAgICAgICAgICAgIHc6IE1BVEgucG93LFxyXG4gICAgICAgICAgICAgICAgdDogTUFUSC5zcXJ0LFxyXG4gICAgICAgICAgICAgICAgbjogTUFUSC5hc2luLFxyXG4gICAgICAgICAgICAgICAgYTogTUFUSC5hYnMsXHJcbiAgICAgICAgICAgICAgICBvOiAxLjcwMTU4XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAvKlxyXG4gICAgICAgICAgICAgeCA6IGN1cnJlbnQgcGVyY2VudCAoMCAtIDEpLFxyXG4gICAgICAgICAgICAgdCA6IGN1cnJlbnQgdGltZSAoZHVyYXRpb24gKiBwZXJjZW50KSxcclxuICAgICAgICAgICAgIGIgOiBzdGFydCB2YWx1ZSAoZnJvbSksXHJcbiAgICAgICAgICAgICBjIDogZW5kIHZhbHVlICh0byksXHJcbiAgICAgICAgICAgICBkIDogZHVyYXRpb25cclxuXHJcbiAgICAgICAgICAgICBlYXNpbmdOYW1lIDogZnVuY3Rpb24oeCwgdCwgYiwgYywgZCkgeyByZXR1cm4gZWFzZWRWYWx1ZTsgfVxyXG4gICAgICAgICAgICAgKi9cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBzd2luZzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMC41IC0gX2Vhc2luZ3NNYXRoLmMoeCAqIF9lYXNpbmdzTWF0aC5wKSAvIDI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgbGluZWFyOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB4O1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJblF1YWQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAodCAvPSBkKSAqIHQgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRRdWFkOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtYyAqICh0IC89IGQpICogKHQgLSAyKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0UXVhZDogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCh0IC89IGQgLyAyKSA8IDEpID8gYyAvIDIgKiB0ICogdCArIGIgOiAtYyAvIDIgKiAoKC0tdCkgKiAodCAtIDIpIC0gMSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbkN1YmljOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogKHQgLz0gZCkgKiB0ICogdCArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dEN1YmljOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogKCh0ID0gdCAvIGQgLSAxKSAqIHQgKiB0ICsgMSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbk91dEN1YmljOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKHQgLz0gZCAvIDIpIDwgMSkgPyBjIC8gMiAqIHQgKiB0ICogdCArIGIgOiBjIC8gMiAqICgodCAtPSAyKSAqIHQgKiB0ICsgMikgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJblF1YXJ0OiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogKHQgLz0gZCkgKiB0ICogdCAqIHQgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRRdWFydDogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLWMgKiAoKHQgPSB0IC8gZCAtIDEpICogdCAqIHQgKiB0IC0gMSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbk91dFF1YXJ0OiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKHQgLz0gZCAvIDIpIDwgMSkgPyBjIC8gMiAqIHQgKiB0ICogdCAqIHQgKyBiIDogLWMgLyAyICogKCh0IC09IDIpICogdCAqIHQgKiB0IC0gMikgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJblF1aW50OiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogKHQgLz0gZCkgKiB0ICogdCAqIHQgKiB0ICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlT3V0UXVpbnQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAoKHQgPSB0IC8gZCAtIDEpICogdCAqIHQgKiB0ICogdCArIDEpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5PdXRRdWludDogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCh0IC89IGQgLyAyKSA8IDEpID8gYyAvIDIgKiB0ICogdCAqIHQgKiB0ICogdCArIGIgOiBjIC8gMiAqICgodCAtPSAyKSAqIHQgKiB0ICogdCAqIHQgKyAyKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluU2luZTogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLWMgKiBfZWFzaW5nc01hdGguYyh0IC8gZCAqIChfZWFzaW5nc01hdGgucCAvIDIpKSArIGMgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRTaW5lOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogX2Vhc2luZ3NNYXRoLnModCAvIGQgKiAoX2Vhc2luZ3NNYXRoLnAgLyAyKSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbk91dFNpbmU6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC1jIC8gMiAqIChfZWFzaW5nc01hdGguYyhfZWFzaW5nc01hdGgucCAqIHQgLyBkKSAtIDEpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5FeHBvOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAodCA9PSAwKSA/IGIgOiBjICogX2Vhc2luZ3NNYXRoLncoMiwgMTAgKiAodCAvIGQgLSAxKSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRFeHBvOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAodCA9PSBkKSA/IGIgKyBjIDogYyAqICgtX2Vhc2luZ3NNYXRoLncoMiwgLTEwICogdCAvIGQpICsgMSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbk91dEV4cG86IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgPT0gMCkgcmV0dXJuIGI7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgPT0gZCkgcmV0dXJuIGIgKyBjO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgodCAvPSBkIC8gMikgPCAxKSByZXR1cm4gYyAvIDIgKiBfZWFzaW5nc01hdGgudygyLCAxMCAqICh0IC0gMSkpICsgYjtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAvIDIgKiAoLV9lYXNpbmdzTWF0aC53KDIsIC0xMCAqIC0tdCkgKyAyKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluQ2lyYzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLWMgKiAoX2Vhc2luZ3NNYXRoLnQoMSAtICh0IC89IGQpICogdCkgLSAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dENpcmM6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiBfZWFzaW5nc01hdGgudCgxIC0gKHQgPSB0IC8gZCAtIDEpICogdCkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbk91dENpcmM6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgodCAvPSBkIC8gMikgPCAxKSA/IC1jIC8gMiAqIChfZWFzaW5nc01hdGgudCgxIC0gdCAqIHQpIC0gMSkgKyBiIDogYyAvIDIgKiAoX2Vhc2luZ3NNYXRoLnQoMSAtICh0IC09IDIpICogdCkgKyAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluRWxhc3RpYzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcyA9IF9lYXNpbmdzTWF0aC5vOyB2YXIgcCA9IDA7IHZhciBhID0gYztcclxuICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSAwKSByZXR1cm4gYjsgaWYgKCh0IC89IGQpID09IDEpIHJldHVybiBiICsgYzsgaWYgKCFwKSBwID0gZCAqIC4zO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhIDwgX2Vhc2luZ3NNYXRoLmEoYykpIHsgYSA9IGM7IHMgPSBwIC8gNDsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgcyA9IHAgLyAoMiAqIF9lYXNpbmdzTWF0aC5wKSAqIF9lYXNpbmdzTWF0aC5uKGMgLyBhKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLShhICogX2Vhc2luZ3NNYXRoLncoMiwgMTAgKiAodCAtPSAxKSkgKiBfZWFzaW5nc01hdGgucygodCAqIGQgLSBzKSAqICgyICogX2Vhc2luZ3NNYXRoLnApIC8gcCkpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlT3V0RWxhc3RpYzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcyA9IF9lYXNpbmdzTWF0aC5vOyB2YXIgcCA9IDA7IHZhciBhID0gYztcclxuICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSAwKSByZXR1cm4gYjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKHQgLz0gZCkgPT0gMSkgcmV0dXJuIGIgKyBjO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghcCkgcCA9IGQgKiAuMztcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYSA8IF9lYXNpbmdzTWF0aC5hKGMpKSB7IGEgPSBjOyBzID0gcCAvIDQ7IH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHMgPSBwIC8gKDIgKiBfZWFzaW5nc01hdGgucCkgKiBfZWFzaW5nc01hdGgubihjIC8gYSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGEgKiBfZWFzaW5nc01hdGgudygyLCAtMTAgKiB0KSAqIF9lYXNpbmdzTWF0aC5zKCh0ICogZCAtIHMpICogKDIgKiBfZWFzaW5nc01hdGgucCkgLyBwKSArIGMgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbk91dEVsYXN0aWM6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHMgPSBfZWFzaW5nc01hdGgubzsgdmFyIHAgPSAwOyB2YXIgYSA9IGM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgPT0gMCkgcmV0dXJuIGI7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCh0IC89IGQgLyAyKSA9PSAyKSByZXR1cm4gYiArIGM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFwKSBwID0gZCAqICguMyAqIDEuNSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGEgPCBfZWFzaW5nc01hdGguYShjKSkgeyBhID0gYzsgcyA9IHAgLyA0OyB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBzID0gcCAvICgyICogX2Vhc2luZ3NNYXRoLnApICogX2Vhc2luZ3NNYXRoLm4oYyAvIGEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0IDwgMSkgcmV0dXJuIC0uNSAqIChhICogX2Vhc2luZ3NNYXRoLncoMiwgMTAgKiAodCAtPSAxKSkgKiBfZWFzaW5nc01hdGgucygodCAqIGQgLSBzKSAqICgyICogX2Vhc2luZ3NNYXRoLnApIC8gcCkpICsgYjtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYSAqIF9lYXNpbmdzTWF0aC53KDIsIC0xMCAqICh0IC09IDEpKSAqIF9lYXNpbmdzTWF0aC5zKCh0ICogZCAtIHMpICogKDIgKiBfZWFzaW5nc01hdGgucCkgLyBwKSAqIC41ICsgYyArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluQmFjazogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQsIHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBzID0gcyB8fCBfZWFzaW5nc01hdGgubztcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqICh0IC89IGQpICogdCAqICgocyArIDEpICogdCAtIHMpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlT3V0QmFjazogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQsIHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBzID0gcyB8fCBfZWFzaW5nc01hdGgubztcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqICgodCA9IHQgLyBkIC0gMSkgKiB0ICogKChzICsgMSkgKiB0ICsgcykgKyAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0QmFjazogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQsIHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBzID0gcyB8fCBfZWFzaW5nc01hdGgubztcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCh0IC89IGQgLyAyKSA8IDEpID8gYyAvIDIgKiAodCAqIHQgKiAoKChzICo9ICgxLjUyNSkpICsgMSkgKiB0IC0gcykpICsgYiA6IGMgLyAyICogKCh0IC09IDIpICogdCAqICgoKHMgKj0gKDEuNTI1KSkgKyAxKSAqIHQgKyBzKSArIDIpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5Cb3VuY2U6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgLSB0aGlzLmVhc2VPdXRCb3VuY2UoeCwgZCAtIHQsIDAsIGMsIGQpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlT3V0Qm91bmNlOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvID0gNy41NjI1O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgodCAvPSBkKSA8ICgxIC8gMi43NSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAobyAqIHQgKiB0KSArIGI7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0IDwgKDIgLyAyLjc1KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqIChvICogKHQgLT0gKDEuNSAvIDIuNzUpKSAqIHQgKyAuNzUpICsgYjtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHQgPCAoMi41IC8gMi43NSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAobyAqICh0IC09ICgyLjI1IC8gMi43NSkpICogdCArIC45Mzc1KSArIGI7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAobyAqICh0IC09ICgyLjYyNSAvIDIuNzUpKSAqIHQgKyAuOTg0Mzc1KSArIGI7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbk91dEJvdW5jZTogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHQgPCBkIC8gMikgPyB0aGlzLmVhc2VJbkJvdW5jZSh4LCB0ICogMiwgMCwgYywgZCkgKiAuNSArIGIgOiB0aGlzLmVhc2VPdXRCb3VuY2UoeCwgdCAqIDIgLSBkLCAwLCBjLCBkKSAqIC41ICsgYyAqIC41ICsgYjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgLypcclxuICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICogVEVSTVMgT0YgVVNFIC0gRUFTSU5HIEVRVUFUSU9OU1xyXG4gICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICogT3BlbiBzb3VyY2UgdW5kZXIgdGhlIEJTRCBMaWNlbnNlLiBcclxuICAgICAgICAgICAgICogXHJcbiAgICAgICAgICAgICAqIENvcHlyaWdodCDDgsKpIDIwMDEgUm9iZXJ0IFBlbm5lclxyXG4gICAgICAgICAgICAgKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4gICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgXHJcbiAgICAgICAgICAgICAqIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcclxuICAgICAgICAgICAgICogXHJcbiAgICAgICAgICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIFxyXG4gICAgICAgICAgICAgKiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXHJcbiAgICAgICAgICAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IFxyXG4gICAgICAgICAgICAgKiBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBcclxuICAgICAgICAgICAgICogcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxyXG4gICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgYXV0aG9yIG5vciB0aGUgbmFtZXMgb2YgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2UgXHJcbiAgICAgICAgICAgICAqIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXHJcbiAgICAgICAgICAgICAqIFxyXG4gICAgICAgICAgICAgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIiBBTkQgQU5ZIFxyXG4gICAgICAgICAgICAgKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0ZcclxuICAgICAgICAgICAgICogTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXHJcbiAgICAgICAgICAgICAqICBDT1BZUklHSFQgT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsXHJcbiAgICAgICAgICAgICAqICBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEVcclxuICAgICAgICAgICAgICogIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBcclxuICAgICAgICAgICAgICogQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkdcclxuICAgICAgICAgICAgICogIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIFxyXG4gICAgICAgICAgICAgKiBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuIFxyXG4gICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICB9KSgpO1xyXG4gICAgICAgIHZhciBGUkFNRVdPUksgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgX3Jub3RodG1sd2hpdGUgPSAoL1teXFx4MjBcXHRcXHJcXG5cXGZdKy9nKTtcclxuICAgICAgICAgICAgdmFyIF9zdHJTcGFjZSA9ICcgJztcclxuICAgICAgICAgICAgdmFyIF9zdHJFbXB0eSA9ICcnO1xyXG4gICAgICAgICAgICB2YXIgX3N0clNjcm9sbExlZnQgPSAnc2Nyb2xsTGVmdCc7XHJcbiAgICAgICAgICAgIHZhciBfc3RyU2Nyb2xsVG9wID0gJ3Njcm9sbFRvcCc7XHJcbiAgICAgICAgICAgIHZhciBfYW5pbWF0aW9ucyA9IFtdO1xyXG4gICAgICAgICAgICB2YXIgX3R5cGUgPSBDT01QQVRJQklMSVRZLnR5cGU7XHJcbiAgICAgICAgICAgIHZhciBfY3NzTnVtYmVyID0ge1xyXG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBjb2x1bW5Db3VudDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGZpbGxPcGFjaXR5OiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgZmxleEdyb3c6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBmbGV4U2hyaW5rOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgZm9udFdlaWdodDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGxpbmVIZWlnaHQ6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgb3JkZXI6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBvcnBoYW5zOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgd2lkb3dzOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgekluZGV4OiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgem9vbTogdHJ1ZVxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gZXh0ZW5kKCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHNyYywgY29weUlzQXJyYXksIGNvcHksIG5hbWUsIG9wdGlvbnMsIGNsb25lLCB0YXJnZXQgPSBhcmd1bWVudHNbMF0gfHwge30sXHJcbiAgICAgICAgICAgICAgICAgICAgaSA9IDEsXHJcbiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID0gYXJndW1lbnRzW0xFWElDT04ubF0sXHJcbiAgICAgICAgICAgICAgICAgICAgZGVlcCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBhIGRlZXAgY29weSBzaXR1YXRpb25cclxuICAgICAgICAgICAgICAgIGlmIChfdHlwZSh0YXJnZXQpID09IFRZUEVTLmIpIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWVwID0gdGFyZ2V0O1xyXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IGFyZ3VtZW50c1sxXSB8fCB7fTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBza2lwIHRoZSBib29sZWFuIGFuZCB0aGUgdGFyZ2V0XHJcbiAgICAgICAgICAgICAgICAgICAgaSA9IDI7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gSGFuZGxlIGNhc2Ugd2hlbiB0YXJnZXQgaXMgYSBzdHJpbmcgb3Igc29tZXRoaW5nIChwb3NzaWJsZSBpbiBkZWVwIGNvcHkpXHJcbiAgICAgICAgICAgICAgICBpZiAoX3R5cGUodGFyZ2V0KSAhPSBUWVBFUy5vICYmICFfdHlwZSh0YXJnZXQpID09IFRZUEVTLmYpIHtcclxuICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPSB7fTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBleHRlbmQgalF1ZXJ5IGl0c2VsZiBpZiBvbmx5IG9uZSBhcmd1bWVudCBpcyBwYXNzZWRcclxuICAgICAgICAgICAgICAgIGlmIChsZW5ndGggPT09IGkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPSBGYWtlalF1ZXJ5O1xyXG4gICAgICAgICAgICAgICAgICAgIC0taTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gT25seSBkZWFsIHdpdGggbm9uLW51bGwvdW5kZWZpbmVkIHZhbHVlc1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgob3B0aW9ucyA9IGFyZ3VtZW50c1tpXSkgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBFeHRlbmQgdGhlIGJhc2Ugb2JqZWN0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobmFtZSBpbiBvcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmMgPSB0YXJnZXRbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5ID0gb3B0aW9uc1tuYW1lXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQcmV2ZW50IG5ldmVyLWVuZGluZyBsb29wXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0ID09PSBjb3B5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVjdXJzZSBpZiB3ZSdyZSBtZXJnaW5nIHBsYWluIG9iamVjdHMgb3IgYXJyYXlzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVlcCAmJiBjb3B5ICYmIChpc1BsYWluT2JqZWN0KGNvcHkpIHx8IChjb3B5SXNBcnJheSA9IENPTVBBVElCSUxJVFkuaXNBKGNvcHkpKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29weUlzQXJyYXkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29weUlzQXJyYXkgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvbmUgPSBzcmMgJiYgQ09NUEFUSUJJTElUWS5pc0Eoc3JjKSA/IHNyYyA6IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9uZSA9IHNyYyAmJiBpc1BsYWluT2JqZWN0KHNyYykgPyBzcmMgOiB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5ldmVyIG1vdmUgb3JpZ2luYWwgb2JqZWN0cywgY2xvbmUgdGhlbVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFtuYW1lXSA9IGV4dGVuZChkZWVwLCBjbG9uZSwgY29weSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERvbid0IGJyaW5nIGluIHVuZGVmaW5lZCB2YWx1ZXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY29weSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W25hbWVdID0gY29weTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBSZXR1cm4gdGhlIG1vZGlmaWVkIG9iamVjdFxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldDtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGluQXJyYXkoaXRlbSwgYXJyLCBmcm9tSW5kZXgpIHtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSBmcm9tSW5kZXggfHwgMDsgaSA8IGFycltMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFycltpXSA9PT0gaXRlbSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGlzRnVuY3Rpb24ob2JqKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gX3R5cGUob2JqKSA9PSBUWVBFUy5mO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gaXNFbXB0eU9iamVjdChvYmopIHtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIG5hbWUgaW4gb2JqKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gaXNQbGFpbk9iamVjdChvYmopIHtcclxuICAgICAgICAgICAgICAgIGlmICghb2JqIHx8IF90eXBlKG9iaikgIT0gVFlQRVMubylcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgdmFyIGtleTtcclxuICAgICAgICAgICAgICAgIHZhciBwcm90byA9IExFWElDT04ucDtcclxuICAgICAgICAgICAgICAgIHZhciBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdFtwcm90b10uaGFzT3duUHJvcGVydHk7XHJcbiAgICAgICAgICAgICAgICB2YXIgaGFzT3duQ29uc3RydWN0b3IgPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgJ2NvbnN0cnVjdG9yJyk7XHJcbiAgICAgICAgICAgICAgICB2YXIgaGFzSXNQcm90b3R5cGVPZiA9IG9iai5jb25zdHJ1Y3RvciAmJiBvYmouY29uc3RydWN0b3JbcHJvdG9dICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqLmNvbnN0cnVjdG9yW3Byb3RvXSwgJ2lzUHJvdG90eXBlT2YnKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAob2JqLmNvbnN0cnVjdG9yICYmICFoYXNPd25Db25zdHJ1Y3RvciAmJiAhaGFzSXNQcm90b3R5cGVPZikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gb2JqKSB7IC8qKi8gfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBfdHlwZShrZXkpID09IFRZUEVTLnUgfHwgaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBlYWNoKG9iaiwgY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoaXNBcnJheUxpa2Uob2JqKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgb2JqW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2suY2FsbChvYmpbaV0sIGksIG9ialtpXSkgPT09IGZhbHNlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChpIGluIG9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2suY2FsbChvYmpbaV0sIGksIG9ialtpXSkgPT09IGZhbHNlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBvYmo7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBpc0FycmF5TGlrZShvYmopIHtcclxuICAgICAgICAgICAgICAgIHZhciBsZW5ndGggPSAhIW9iaiAmJiBbTEVYSUNPTi5sXSBpbiBvYmogJiYgb2JqW0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICB2YXIgdCA9IF90eXBlKG9iaik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaXNGdW5jdGlvbih0KSA/IGZhbHNlIDogKHQgPT0gVFlQRVMuYSB8fCBsZW5ndGggPT09IDAgfHwgX3R5cGUobGVuZ3RoKSA9PSBUWVBFUy5uICYmIGxlbmd0aCA+IDAgJiYgKGxlbmd0aCAtIDEpIGluIG9iaik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIHN0cmlwQW5kQ29sbGFwc2UodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIHZhciB0b2tlbnMgPSB2YWx1ZS5tYXRjaChfcm5vdGh0bWx3aGl0ZSkgfHwgW107XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdG9rZW5zLmpvaW4oX3N0clNwYWNlKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gbWF0Y2hlcyhlbGVtLCBzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgdmFyIG5vZGVMaXN0ID0gKGVsZW0ucGFyZW50Tm9kZSB8fCBkb2N1bWVudCkucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvcikgfHwgW107XHJcbiAgICAgICAgICAgICAgICB2YXIgaSA9IG5vZGVMaXN0W0xFWElDT04ubF07XHJcblxyXG4gICAgICAgICAgICAgICAgd2hpbGUgKGktLSlcclxuICAgICAgICAgICAgICAgICAgICBpZiAobm9kZUxpc3RbaV0gPT0gZWxlbSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBpbnNlcnRBZGphY2VudEVsZW1lbnQoZWwsIHN0cmF0ZWd5LCBjaGlsZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkuaXNBKGNoaWxkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRbTEVYSUNPTi5sXTsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnRBZGphY2VudEVsZW1lbnQoZWwsIHN0cmF0ZWd5LCBjaGlsZFtpXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChfdHlwZShjaGlsZCkgPT0gVFlQRVMucylcclxuICAgICAgICAgICAgICAgICAgICBlbC5pbnNlcnRBZGphY2VudEhUTUwoc3RyYXRlZ3ksIGNoaWxkKTtcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBlbC5pbnNlcnRBZGphY2VudEVsZW1lbnQoc3RyYXRlZ3ksIGNoaWxkLm5vZGVUeXBlID8gY2hpbGQgOiBjaGlsZFswXSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIHNldENTU1ZhbChlbCwgcHJvcCwgdmFsKSB7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlbFtMRVhJQ09OLnNdW3Byb3BdICE9PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsW0xFWElDT04uc11bcHJvcF0gPSBwYXJzZUNTU1ZhbChwcm9wLCB2YWwpO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgeyB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIHBhcnNlQ1NTVmFsKHByb3AsIHZhbCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFfY3NzTnVtYmVyW3Byb3AudG9Mb3dlckNhc2UoKV0gJiYgX3R5cGUodmFsKSA9PSBUWVBFUy5uKVxyXG4gICAgICAgICAgICAgICAgICAgIHZhbCArPSAncHgnO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gc3RhcnROZXh0QW5pbWF0aW9uSW5RKGFuaW1PYmosIHJlbW92ZUZyb21RKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgaW5kZXg7XHJcbiAgICAgICAgICAgICAgICB2YXIgbmV4dEFuaW07XHJcbiAgICAgICAgICAgICAgICBpZiAocmVtb3ZlRnJvbVEgIT09IGZhbHNlKVxyXG4gICAgICAgICAgICAgICAgICAgIGFuaW1PYmoucS5zcGxpY2UoMCwgMSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoYW5pbU9iai5xW0xFWElDT04ubF0gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV4dEFuaW0gPSBhbmltT2JqLnFbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgYW5pbWF0ZShhbmltT2JqLmVsLCBuZXh0QW5pbS5wcm9wcywgbmV4dEFuaW0uZHVyYXRpb24sIG5leHRBbmltLmVhc2luZywgbmV4dEFuaW0uY29tcGxldGUsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBpbkFycmF5KGFuaW1PYmosIF9hbmltYXRpb25zKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPiAtMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2FuaW1hdGlvbnMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gc2V0QW5pbWF0aW9uVmFsdWUoZWwsIHByb3AsIHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocHJvcCA9PT0gX3N0clNjcm9sbExlZnQgfHwgcHJvcCA9PT0gX3N0clNjcm9sbFRvcClcclxuICAgICAgICAgICAgICAgICAgICBlbFtwcm9wXSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIHNldENTU1ZhbChlbCwgcHJvcCwgdmFsdWUpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBhbmltYXRlKGVsLCBwcm9wcywgb3B0aW9ucywgZWFzaW5nLCBjb21wbGV0ZSwgZ3VhcmFudGVlZE5leHQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBoYXNPcHRpb25zID0gaXNQbGFpbk9iamVjdChvcHRpb25zKTtcclxuICAgICAgICAgICAgICAgIHZhciBmcm9tID0ge307XHJcbiAgICAgICAgICAgICAgICB2YXIgdG8gPSB7fTtcclxuICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgIHZhciBrZXk7XHJcbiAgICAgICAgICAgICAgICB2YXIgYW5pbU9iajtcclxuICAgICAgICAgICAgICAgIHZhciBzdGFydDtcclxuICAgICAgICAgICAgICAgIHZhciBwcm9ncmVzcztcclxuICAgICAgICAgICAgICAgIHZhciBzdGVwO1xyXG4gICAgICAgICAgICAgICAgdmFyIHNwZWNpYWxFYXNpbmc7XHJcbiAgICAgICAgICAgICAgICB2YXIgZHVyYXRpb247XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFzT3B0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgICAgIGVhc2luZyA9IG9wdGlvbnMuZWFzaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0ID0gb3B0aW9ucy5zdGFydDtcclxuICAgICAgICAgICAgICAgICAgICBwcm9ncmVzcyA9IG9wdGlvbnMucHJvZ3Jlc3M7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RlcCA9IG9wdGlvbnMuc3RlcDtcclxuICAgICAgICAgICAgICAgICAgICBzcGVjaWFsRWFzaW5nID0gb3B0aW9ucy5zcGVjaWFsRWFzaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlID0gb3B0aW9ucy5jb21wbGV0ZTtcclxuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IG9wdGlvbnMuZHVyYXRpb247XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSBvcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgc3BlY2lhbEVhc2luZyA9IHNwZWNpYWxFYXNpbmcgfHwge307XHJcbiAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IGR1cmF0aW9uIHx8IDQwMDtcclxuICAgICAgICAgICAgICAgIGVhc2luZyA9IGVhc2luZyB8fCAnc3dpbmcnO1xyXG4gICAgICAgICAgICAgICAgZ3VhcmFudGVlZE5leHQgPSBndWFyYW50ZWVkTmV4dCB8fCBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IF9hbmltYXRpb25zW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfYW5pbWF0aW9uc1tpXS5lbCA9PT0gZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYW5pbU9iaiA9IF9hbmltYXRpb25zW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCFhbmltT2JqKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYW5pbU9iaiA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWw6IGVsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBxOiBbXVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgX2FuaW1hdGlvbnMucHVzaChhbmltT2JqKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiBwcm9wcykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkgPT09IF9zdHJTY3JvbGxMZWZ0IHx8IGtleSA9PT0gX3N0clNjcm9sbFRvcClcclxuICAgICAgICAgICAgICAgICAgICAgICAgZnJvbVtrZXldID0gZWxba2V5XTtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZyb21ba2V5XSA9IEZha2VqUXVlcnkoZWwpLmNzcyhrZXkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGZvciAoa2V5IGluIGZyb20pIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZnJvbVtrZXldICE9PSBwcm9wc1trZXldICYmIHByb3BzW2tleV0gIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG9ba2V5XSA9IHByb3BzW2tleV07XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCFpc0VtcHR5T2JqZWN0KHRvKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0aW1lTm93O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbmQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBlcmNlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZyb21WYWw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRvVmFsO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlYXNlZFZhbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGltZVN0YXJ0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmcmFtZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxhcHNlZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcVBvcyA9IGd1YXJhbnRlZWROZXh0ID8gMCA6IGluQXJyYXkocU9iaiwgYW5pbU9iai5xKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcU9iaiA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvcHM6IHRvLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbjogaGFzT3B0aW9ucyA/IG9wdGlvbnMgOiBkdXJhdGlvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFzaW5nOiBlYXNpbmcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOiBjb21wbGV0ZVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHFQb3MgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHFQb3MgPSBhbmltT2JqLnFbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYW5pbU9iai5xLnB1c2gocU9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAocVBvcyA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZHVyYXRpb24gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lU3RhcnQgPSBDT01QQVRJQklMSVRZLm5vdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZU5vdyA9IENPTVBBVElCSUxJVFkubm93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxhcHNlZCA9ICh0aW1lTm93IC0gdGltZVN0YXJ0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQgPSBxT2JqLnN0b3AgfHwgZWxhcHNlZCA+PSBkdXJhdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJjZW50ID0gMSAtICgoTUFUSC5tYXgoMCwgdGltZVN0YXJ0ICsgZHVyYXRpb24gLSB0aW1lTm93KSAvIGR1cmF0aW9uKSB8fCAwKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gdG8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbVZhbCA9IHBhcnNlRmxvYXQoZnJvbVtrZXldKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9WYWwgPSBwYXJzZUZsb2F0KHRvW2tleV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYXNlZFZhbCA9ICh0b1ZhbCAtIGZyb21WYWwpICogRUFTSU5HW3NwZWNpYWxFYXNpbmdba2V5XSB8fCBlYXNpbmddKHBlcmNlbnQsIHBlcmNlbnQgKiBkdXJhdGlvbiwgMCwgMSwgZHVyYXRpb24pICsgZnJvbVZhbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0QW5pbWF0aW9uVmFsdWUoZWwsIGtleSwgZWFzZWRWYWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNGdW5jdGlvbihzdGVwKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcChlYXNlZFZhbCwge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW06IGVsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3A6IGtleSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydDogZnJvbVZhbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3c6IGVhc2VkVmFsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZDogdG9WYWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zOiBwZXJjZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWFzaW5nOiBlYXNpbmcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWFjaWFsRWFzaW5nOiBzcGVjaWFsRWFzaW5nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbjogZHVyYXRpb24sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOiBjb21wbGV0ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcDogc3RlcFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lOiB0aW1lU3RhcnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNGdW5jdGlvbihwcm9ncmVzcykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2dyZXNzKHt9LCBwZXJjZW50LCBNQVRILm1heCgwLCBkdXJhdGlvbiAtIGVsYXBzZWQpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVuZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydE5leHRBbmltYXRpb25JblEoYW5pbU9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKGNvbXBsZXRlKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcU9iai5mcmFtZSA9IENPTVBBVElCSUxJVFkuckFGKCkoZnJhbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFPYmouZnJhbWUgPSBDT01QQVRJQklMSVRZLnJBRigpKGZyYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoa2V5IGluIHRvKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEFuaW1hdGlvblZhbHVlKGVsLCBrZXksIHRvW2tleV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnROZXh0QW5pbWF0aW9uSW5RKGFuaW1PYmopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoZ3VhcmFudGVlZE5leHQpXHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnROZXh0QW5pbWF0aW9uSW5RKGFuaW1PYmopO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBzdG9wKGVsLCBjbGVhclEsIGp1bXBUb0VuZCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGFuaW1PYmo7XHJcbiAgICAgICAgICAgICAgICB2YXIgcU9iajtcclxuICAgICAgICAgICAgICAgIHZhciBrZXk7XHJcbiAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IF9hbmltYXRpb25zW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGFuaW1PYmogPSBfYW5pbWF0aW9uc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5pbU9iai5lbCA9PT0gZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFuaW1PYmoucVtMRVhJQ09OLmxdID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcU9iaiA9IGFuaW1PYmoucVswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFPYmouc3RvcCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLmNBRigpKHFPYmouZnJhbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbU9iai5xLnNwbGljZSgwLCAxKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoanVtcFRvRW5kKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoa2V5IGluIHFPYmoucHJvcHMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEFuaW1hdGlvblZhbHVlKGVsLCBrZXksIHFPYmoucHJvcHNba2V5XSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNsZWFyUSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltT2JqLnEgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydE5leHRBbmltYXRpb25JblEoYW5pbU9iaiwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gZWxlbWVudElzVmlzaWJsZShlbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICEhKGVsW0xFWElDT04ub1ddIHx8IGVsW0xFWElDT04ub0hdIHx8IGVsLmdldENsaWVudFJlY3RzKClbTEVYSUNPTi5sXSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIEZha2VqUXVlcnkoc2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgIGlmIChhcmd1bWVudHNbTEVYSUNPTi5sXSA9PT0gMClcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgYmFzZSA9IG5ldyBGYWtlalF1ZXJ5KCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgZWxlbWVudHMgPSBzZWxlY3RvcjtcclxuICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgIHZhciBlbG1zO1xyXG4gICAgICAgICAgICAgICAgdmFyIGVsO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChfdHlwZShzZWxlY3RvcikgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdG9yLmNoYXJBdCgwKSA9PT0gJzwnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsLmlubmVySFRNTCA9IHNlbGVjdG9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbG1zID0gZWwuY2hpbGRyZW47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbG1zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGVsbXNbTEVYSUNPTi5sXTsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKGVsbXNbaV0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50cykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfdHlwZShlbGVtZW50cykgIT0gVFlQRVMucyAmJiAoIWlzQXJyYXlMaWtlKGVsZW1lbnRzKSB8fCBlbGVtZW50cyA9PT0gd2luZG93IHx8IGVsZW1lbnRzID09PSBlbGVtZW50cy5zZWxmKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMgPSBbZWxlbWVudHNdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZWxlbWVudHNbTEVYSUNPTi5sXTsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBiYXNlW2ldID0gZWxlbWVudHNbaV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGJhc2VbTEVYSUNPTi5sXSA9IGVsZW1lbnRzW0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJhc2U7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBGYWtlalF1ZXJ5W0xFWElDT04ucF0gPSB7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9FVkVOVFM6XHJcblxyXG4gICAgICAgICAgICAgICAgb246IGZ1bmN0aW9uIChldmVudE5hbWUsIGhhbmRsZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICBldmVudE5hbWUgPSAoZXZlbnROYW1lIHx8IF9zdHJFbXB0eSkubWF0Y2goX3Jub3RodG1sd2hpdGUpIHx8IFtfc3RyRW1wdHldO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnROYW1lTGVuZ3RoID0gZXZlbnROYW1lW0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsLmFkZEV2ZW50TGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGV2ZW50TmFtZUxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZVtpXSwgaGFuZGxlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlbC5kZXRhY2hFdmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgZXZlbnROYW1lTGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLmF0dGFjaEV2ZW50KCdvbicgKyBldmVudE5hbWVbaV0sIGhhbmRsZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7IH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgb2ZmOiBmdW5jdGlvbiAoZXZlbnROYW1lLCBoYW5kbGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXZlbnROYW1lID0gKGV2ZW50TmFtZSB8fCBfc3RyRW1wdHkpLm1hdGNoKF9ybm90aHRtbHdoaXRlKSB8fCBbX3N0ckVtcHR5XTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGV2ZW50TmFtZUxlbmd0aCA9IGV2ZW50TmFtZVtMRVhJQ09OLmxdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbC5yZW1vdmVFdmVudExpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBldmVudE5hbWVMZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudE5hbWVbaV0sIGhhbmRsZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZWwuZGV0YWNoRXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGV2ZW50TmFtZUxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5kZXRhY2hFdmVudCgnb24nICsgZXZlbnROYW1lW2ldLCBoYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgeyB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIG9uZTogZnVuY3Rpb24gKGV2ZW50TmFtZSwgaGFuZGxlcikge1xyXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50TmFtZSA9IChldmVudE5hbWUgfHwgX3N0ckVtcHR5KS5tYXRjaChfcm5vdGh0bWx3aGl0ZSkgfHwgW19zdHJFbXB0eV07XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbCA9IEZha2VqUXVlcnkodGhpcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEZha2VqUXVlcnkuZWFjaChldmVudE5hbWUsIGZ1bmN0aW9uIChpLCBvbmVFdmVudE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvbmVIYW5kbGVyID0gZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwub2ZmKG9uZUV2ZW50TmFtZSwgb25lSGFuZGxlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwub24ob25lRXZlbnROYW1lLCBvbmVIYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHRyaWdnZXI6IGZ1bmN0aW9uIChldmVudE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGV2ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbCA9IHRoaXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5jcmVhdGVFdmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnSFRNTEV2ZW50cycpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuaW5pdEV2ZW50KGV2ZW50TmFtZSwgdHJ1ZSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5maXJlRXZlbnQoJ29uJyArIGV2ZW50TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgLy9ET00gTk9ERSBJTlNFUlRJTkcgLyBSRU1PVklORzpcclxuXHJcbiAgICAgICAgICAgICAgICBhcHBlbmQ6IGZ1bmN0aW9uIChjaGlsZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyBpbnNlcnRBZGphY2VudEVsZW1lbnQodGhpcywgJ2JlZm9yZWVuZCcsIGNoaWxkKTsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHByZXBlbmQ6IGZ1bmN0aW9uIChjaGlsZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyBpbnNlcnRBZGphY2VudEVsZW1lbnQodGhpcywgJ2FmdGVyYmVnaW4nLCBjaGlsZCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBiZWZvcmU6IGZ1bmN0aW9uIChjaGlsZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyBpbnNlcnRBZGphY2VudEVsZW1lbnQodGhpcywgJ2JlZm9yZWJlZ2luJywgY2hpbGQpOyB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgYWZ0ZXI6IGZ1bmN0aW9uIChjaGlsZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyBpbnNlcnRBZGphY2VudEVsZW1lbnQodGhpcywgJ2FmdGVyZW5kJywgY2hpbGQpOyB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgcmVtb3ZlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbCA9IHRoaXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnROb2RlID0gZWwucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudE5vZGUgIT0gbnVsbClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICB1bndyYXA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50cyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQgPSB0aGlzLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbkFycmF5KHBhcmVudCwgcGFyZW50cykgPT09IC0gMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudHMucHVzaChwYXJlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcGFyZW50c1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSBwYXJlbnRzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQgPSBlbC5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZWwuZmlyc3RDaGlsZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoZWwuZmlyc3RDaGlsZCwgZWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoZWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHdyYXBBbGw6IGZ1bmN0aW9uICh3cmFwcGVySFRNTCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBub2RlcyA9IHRoaXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdyYXBwZXIgPSBGYWtlalF1ZXJ5KHdyYXBwZXJIVE1MKVswXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZGVlcGVzdCA9IHdyYXBwZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudCA9IG5vZGVzWzBdLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByZXZpb3VzU2libGluZyA9IG5vZGVzWzBdLnByZXZpb3VzU2libGluZztcclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZGVlcGVzdC5jaGlsZE5vZGVzW0xFWElDT04ubF0gPiAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWVwZXN0ID0gZGVlcGVzdC5jaGlsZE5vZGVzWzBdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBub2Rlc1tMRVhJQ09OLmxdIC0gaTsgZGVlcGVzdC5maXJzdENoaWxkID09PSBub2Rlc1swXSAmJiBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZXBlc3QuYXBwZW5kQ2hpbGQobm9kZXNbaV0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgbmV4dFNpYmxpbmcgPSBwcmV2aW91c1NpYmxpbmcgPyBwcmV2aW91c1NpYmxpbmcubmV4dFNpYmxpbmcgOiBwYXJlbnQuZmlyc3RDaGlsZDtcclxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKHdyYXBwZXIsIG5leHRTaWJsaW5nKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHdyYXBJbm5lcjogZnVuY3Rpb24gKHdyYXBwZXJIVE1MKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbCA9IEZha2VqUXVlcnkodGhpcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50cyA9IGVsLmNvbnRlbnRzKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29udGVudHNbTEVYSUNPTi5sXSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRzLndyYXBBbGwod3JhcHBlckhUTUwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5hcHBlbmQod3JhcHBlckhUTUwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICB3cmFwOiBmdW5jdGlvbiAod3JhcHBlckhUTUwpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHsgRmFrZWpRdWVyeSh0aGlzKS53cmFwQWxsKHdyYXBwZXJIVE1MKTsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvL0RPTSBOT0RFIE1BTklQVUxBVElPTiAvIElORk9STUFUSU9OOlxyXG5cclxuICAgICAgICAgICAgICAgIGNzczogZnVuY3Rpb24gKHN0eWxlcywgdmFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBrZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNwdFN0eWxlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBnZXRDcHRTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfdHlwZShzdHlsZXMpID09IFRZUEVTLnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbCA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbCA9IHRoaXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcHRTdHlsZSA9IGdldENwdFN0eWxlID8gZ2V0Q3B0U3R5bGUoZWwsIG51bGwpIDogZWwuY3VycmVudFN0eWxlW3N0eWxlc107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9odHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD01NDgzOTcgY2FuIGJlIG51bGwgc29tZXRpbWVzIGlmIGlmcmFtZSB3aXRoIGRpc3BsYXk6IG5vbmUgKGZpcmVmb3ggb25seSEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0Q3B0U3R5bGUgPyBjcHRTdHlsZSAhPSBudWxsID8gY3B0U3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShzdHlsZXMpIDogZWxbTEVYSUNPTi5zXVtzdHlsZXNdIDogY3B0U3R5bGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRDU1NWYWwodGhpcywgc3R5bGVzLCB2YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gc3R5bGVzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldENTU1ZhbCh0aGlzLCBrZXksIHN0eWxlc1trZXldKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBoYXNDbGFzczogZnVuY3Rpb24gKGNsYXNzTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGVtLCBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lUHJlcGFyZWQgPSBfc3RyU3BhY2UgKyBjbGFzc05hbWUgKyBfc3RyU3BhY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzTGlzdDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChlbGVtID0gdGhpc1tpKytdKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc0xpc3QgPSBlbGVtLmNsYXNzTGlzdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzTGlzdCAmJiBjbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlbGVtLm5vZGVUeXBlID09PSAxICYmIChfc3RyU3BhY2UgKyBzdHJpcEFuZENvbGxhcHNlKGVsZW0uY2xhc3NOYW1lICsgX3N0ckVtcHR5KSArIF9zdHJTcGFjZSkuaW5kZXhPZihjbGFzc05hbWVQcmVwYXJlZCkgPiAtMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBhZGRDbGFzczogZnVuY3Rpb24gKGNsYXNzTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc2VzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGVtO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN1clZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGF6ejtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZmluYWxWYWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3VwcG9ydENsYXNzTGlzdDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxtQ2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdiA9IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc05hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NlcyA9IGNsYXNzTmFtZS5tYXRjaChfcm5vdGh0bWx3aGl0ZSkgfHwgW107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGVsZW0gPSB0aGlzW2krK10pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbG1DbGFzc0xpc3QgPSBlbGVtLmNsYXNzTGlzdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdXBwb3J0Q2xhc3NMaXN0ID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VwcG9ydENsYXNzTGlzdCA9IGVsbUNsYXNzTGlzdCAhPT0gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdXBwb3J0Q2xhc3NMaXN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChjbGF6eiA9IGNsYXNzZXNbdisrXSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsbUNsYXNzTGlzdC5hZGQoY2xhenopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyVmFsdWUgPSBlbGVtLmNsYXNzTmFtZSArIF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmIChfc3RyU3BhY2UgKyBzdHJpcEFuZENvbGxhcHNlKGN1clZhbHVlKSArIF9zdHJTcGFjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChjbGF6eiA9IGNsYXNzZXNbdisrXSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyLmluZGV4T2YoX3N0clNwYWNlICsgY2xhenogKyBfc3RyU3BhY2UpIDwgMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXIgKz0gY2xhenogKyBfc3RyU3BhY2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlID0gc3RyaXBBbmRDb2xsYXBzZShjdXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyVmFsdWUgIT09IGZpbmFsVmFsdWUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLmNsYXNzTmFtZSA9IGZpbmFsVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3M6IGZ1bmN0aW9uIChjbGFzc05hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NlcztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VyO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJWYWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xheno7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZpbmFsVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN1cHBvcnRDbGFzc0xpc3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsbUNsYXNzTGlzdDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHYgPSAwO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzZXMgPSBjbGFzc05hbWUubWF0Y2goX3Jub3RodG1sd2hpdGUpIHx8IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChlbGVtID0gdGhpc1tpKytdKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxtQ2xhc3NMaXN0ID0gZWxlbS5jbGFzc0xpc3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3VwcG9ydENsYXNzTGlzdCA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cHBvcnRDbGFzc0xpc3QgPSBlbG1DbGFzc0xpc3QgIT09IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3VwcG9ydENsYXNzTGlzdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgoY2xhenogPSBjbGFzc2VzW3YrK10pKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbG1DbGFzc0xpc3QucmVtb3ZlKGNsYXp6KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1clZhbHVlID0gZWxlbS5jbGFzc05hbWUgKyBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyID0gZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiAoX3N0clNwYWNlICsgc3RyaXBBbmRDb2xsYXBzZShjdXJWYWx1ZSkgKyBfc3RyU3BhY2UpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgoY2xhenogPSBjbGFzc2VzW3YrK10pKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGN1ci5pbmRleE9mKF9zdHJTcGFjZSArIGNsYXp6ICsgX3N0clNwYWNlKSA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1ciA9IGN1ci5yZXBsYWNlKF9zdHJTcGFjZSArIGNsYXp6ICsgX3N0clNwYWNlLCBfc3RyU3BhY2UpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxWYWx1ZSA9IHN0cmlwQW5kQ29sbGFwc2UoY3VyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1clZhbHVlICE9PSBmaW5hbFZhbHVlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS5jbGFzc05hbWUgPSBmaW5hbFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIGhpZGU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHsgdGhpc1tMRVhJQ09OLnNdLmRpc3BsYXkgPSAnbm9uZSc7IH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBzaG93OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IHRoaXNbTEVYSUNPTi5zXS5kaXNwbGF5ID0gJ2Jsb2NrJzsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIGF0dHI6IGZ1bmN0aW9uIChhdHRyTmFtZSwgdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbCA9IHRoaXNbaSsrXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbC5nZXRBdHRyaWJ1dGUoYXR0ck5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoYXR0ck5hbWUsIHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHJlbW92ZUF0dHI6IGZ1bmN0aW9uIChhdHRyTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyB0aGlzLnJlbW92ZUF0dHJpYnV0ZShhdHRyTmFtZSk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWwgPSB0aGlzWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWN0ID0gZWxbTEVYSUNPTi5iQ1JdKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbExlZnQgPSB3aW5kb3cucGFnZVhPZmZzZXQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsVG9wID0gd2luZG93LnBhZ2VZT2Zmc2V0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudFtfc3RyU2Nyb2xsVG9wXTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3A6IHJlY3QudG9wICsgc2Nyb2xsVG9wLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0OiByZWN0LmxlZnQgKyBzY3JvbGxMZWZ0XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgcG9zaXRpb246IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWwgPSB0aGlzWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogZWwub2Zmc2V0VG9wLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0OiBlbC5vZmZzZXRMZWZ0XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgc2Nyb2xsTGVmdDogZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZWwgPSB0aGlzW2krK10pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxbX3N0clNjcm9sbExlZnRdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbFtfc3RyU2Nyb2xsTGVmdF0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHNjcm9sbFRvcDogZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZWwgPSB0aGlzW2krK10pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxbX3N0clNjcm9sbFRvcF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsW19zdHJTY3JvbGxUb3BdID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICB2YWw6IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbCA9IHRoaXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF2YWx1ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsLnZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsLnZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvL0RPTSBUUkFWRVJTQUwgLyBGSUxURVJJTkc6XHJcblxyXG4gICAgICAgICAgICAgICAgZmlyc3Q6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lcSgwKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgbGFzdDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVxKC0xKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgZXE6IGZ1bmN0aW9uIChpbmRleCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5KHRoaXNbaW5kZXggPj0gMCA/IGluZGV4IDogdGhpc1tMRVhJQ09OLmxdICsgaW5kZXhdKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgZmluZDogZnVuY3Rpb24gKHNlbGVjdG9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoID0gZWwucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjaFtMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGNoW2ldKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRmFrZWpRdWVyeShjaGlsZHJlbik7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRyZW4gPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaCA9IHRoaXMuY2hpbGRyZW47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjaFtMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsID0gY2hbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGVsLm1hdGNoZXMgJiYgZWwubWF0Y2hlcyhzZWxlY3RvcikpIHx8IG1hdGNoZXMoZWwsIHNlbGVjdG9yKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4ucHVzaChlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4ucHVzaChlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRmFrZWpRdWVyeShjaGlsZHJlbik7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHBhcmVudDogZnVuY3Rpb24gKHNlbGVjdG9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudHMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IHRoaXMucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdG9yID8gRmFrZWpRdWVyeShwYXJlbnQpLmlzKHNlbGVjdG9yKSA6IHRydWUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRzLnB1c2gocGFyZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRmFrZWpRdWVyeShwYXJlbnRzKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgaXM6IGZ1bmN0aW9uIChzZWxlY3Rvcikge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXNbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsID0gdGhpc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdG9yID09PSAnOnZpc2libGUnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnRJc1Zpc2libGUoZWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IgPT09ICc6aGlkZGVuJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAhZWxlbWVudElzVmlzaWJsZShlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZWwubWF0Y2hlcyAmJiBlbC5tYXRjaGVzKHNlbGVjdG9yKSkgfHwgbWF0Y2hlcyhlbCwgc2VsZWN0b3IpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgY29udGVudHM6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudHMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHMgPSB0aGlzLmNoaWxkTm9kZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjaGlsZHNbTEVYSUNPTi5sXTsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudHMucHVzaChjaGlsZHNbaV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRmFrZWpRdWVyeShjb250ZW50cyk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIGVhY2g6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBlYWNoKHRoaXMsIGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vQU5JTUFUSU9OOlxyXG5cclxuICAgICAgICAgICAgICAgIGFuaW1hdGU6IGZ1bmN0aW9uIChwcm9wcywgZHVyYXRpb24sIGVhc2luZywgY29tcGxldGUpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHsgYW5pbWF0ZSh0aGlzLCBwcm9wcywgZHVyYXRpb24sIGVhc2luZywgY29tcGxldGUpOyB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgc3RvcDogZnVuY3Rpb24gKGNsZWFyUSwganVtcCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyBzdG9wKHRoaXMsIGNsZWFyUSwganVtcCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgZXh0ZW5kKEZha2VqUXVlcnksIHtcclxuICAgICAgICAgICAgICAgIGV4dGVuZDogZXh0ZW5kLFxyXG4gICAgICAgICAgICAgICAgaW5BcnJheTogaW5BcnJheSxcclxuICAgICAgICAgICAgICAgIGlzRW1wdHlPYmplY3Q6IGlzRW1wdHlPYmplY3QsXHJcbiAgICAgICAgICAgICAgICBpc1BsYWluT2JqZWN0OiBpc1BsYWluT2JqZWN0LFxyXG4gICAgICAgICAgICAgICAgZWFjaDogZWFjaFxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5O1xyXG4gICAgICAgIH0pKCk7XHJcbiAgICAgICAgdmFyIElOU1RBTkNFUyA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBfdGFyZ2V0cyA9IFtdO1xyXG4gICAgICAgICAgICB2YXIgX2luc3RhbmNlUHJvcGVydHlTdHJpbmcgPSAnX19vdmVybGF5U2Nyb2xsYmFyc19fJztcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBSZWdpc3RlciwgdW5yZWdpc3RlciBvciBnZXQgYSBjZXJ0YWluIChvciBhbGwpIGluc3RhbmNlcy5cclxuICAgICAgICAgICAgICogUmVnaXN0ZXI6IFBhc3MgdGhlIHRhcmdldCBhbmQgdGhlIGluc3RhbmNlLlxyXG4gICAgICAgICAgICAgKiBVbnJlZ2lzdGVyOiBQYXNzIHRoZSB0YXJnZXQgYW5kIG51bGwuXHJcbiAgICAgICAgICAgICAqIEdldCBJbnN0YW5jZTogUGFzcyB0aGUgdGFyZ2V0IGZyb20gd2hpY2ggdGhlIGluc3RhbmNlIHNoYWxsIGJlIGdvdC5cclxuICAgICAgICAgICAgICogR2V0IFRhcmdldHM6IFBhc3Mgbm8gYXJndW1lbnRzLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB0YXJnZXQgdG8gd2hpY2ggdGhlIGluc3RhbmNlIHNoYWxsIGJlIHJlZ2lzdGVyZWQgLyBmcm9tIHdoaWNoIHRoZSBpbnN0YW5jZSBzaGFsbCBiZSB1bnJlZ2lzdGVyZWQgLyB0aGUgaW5zdGFuY2Ugc2hhbGwgYmUgZ290XHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBpbnN0YW5jZSBUaGUgaW5zdGFuY2UuXHJcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfHZvaWR9IFJldHVybnMgdGhlIGluc3RhbmNlIGZyb20gdGhlIGdpdmVuIHRhcmdldC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBpbnN0YW5jZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGFyZ0xlbiA9IGFyZ3VtZW50c1tMRVhJQ09OLmxdO1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ0xlbiA8IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL3JldHVybiBhbGwgdGFyZ2V0c1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGFyZ2V0cztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3JlZ2lzdGVyIGluc3RhbmNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFtfaW5zdGFuY2VQcm9wZXJ0eVN0cmluZ10gPSBpbnN0YW5jZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldHMucHVzaCh0YXJnZXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gQ09NUEFUSUJJTElUWS5pbkEodGFyZ2V0LCBfdGFyZ2V0cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJnTGVuID4gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdW5yZWdpc3RlciBpbnN0YW5jZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0YXJnZXRbX2luc3RhbmNlUHJvcGVydHlTdHJpbmddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2dldCBpbnN0YW5jZSBmcm9tIHRhcmdldFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGFyZ2V0c1tpbmRleF1bX2luc3RhbmNlUHJvcGVydHlTdHJpbmddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSkoKTtcclxuICAgICAgICB2YXIgUExVR0lOID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIF9wbHVnaW47XHJcbiAgICAgICAgICAgIHZhciBfcGx1Z2luc0dsb2JhbHM7XHJcbiAgICAgICAgICAgIHZhciBfcGx1Z2luc0F1dG9VcGRhdGVMb29wO1xyXG4gICAgICAgICAgICB2YXIgX3BsdWdpbnNFeHRlbnNpb25zID0gW107XHJcbiAgICAgICAgICAgIHZhciBfcGx1Z2luc09wdGlvbnMgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHR5cGUgPSBDT01QQVRJQklMSVRZLnR5cGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgcG9zc2libGVUZW1wbGF0ZVR5cGVzID0gW1xyXG4gICAgICAgICAgICAgICAgICAgIFRZUEVTLmIsIC8vYm9vbGVhblxyXG4gICAgICAgICAgICAgICAgICAgIFRZUEVTLm4sIC8vbnVtYmVyXHJcbiAgICAgICAgICAgICAgICAgICAgVFlQRVMucywgLy9zdHJpbmdcclxuICAgICAgICAgICAgICAgICAgICBUWVBFUy5hLCAvL2FycmF5XHJcbiAgICAgICAgICAgICAgICAgICAgVFlQRVMubywgLy9vYmplY3RcclxuICAgICAgICAgICAgICAgICAgICBUWVBFUy5mLCAvL2Z1bmN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgVFlQRVMueiAgLy9udWxsXHJcbiAgICAgICAgICAgICAgICBdO1xyXG4gICAgICAgICAgICAgICAgdmFyIHJlc3RyaWN0ZWRTdHJpbmdzU3BsaXQgPSAnICc7XHJcbiAgICAgICAgICAgICAgICB2YXIgcmVzdHJpY3RlZFN0cmluZ3NQb3NzaWJpbGl0aWVzU3BsaXQgPSAnOic7XHJcbiAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lQWxsb3dlZFZhbHVlcyA9IFtUWVBFUy56LCBUWVBFUy5zXTtcclxuICAgICAgICAgICAgICAgIHZhciBudW1iZXJBbGxvd2VkVmFsdWVzID0gVFlQRVMubjtcclxuICAgICAgICAgICAgICAgIHZhciBib29sZWFuTnVsbEFsbG93ZWRWYWx1ZXMgPSBbVFlQRVMueiwgVFlQRVMuYl07XHJcbiAgICAgICAgICAgICAgICB2YXIgYm9vbGVhblRydWVUZW1wbGF0ZSA9IFt0cnVlLCBUWVBFUy5iXTtcclxuICAgICAgICAgICAgICAgIHZhciBib29sZWFuRmFsc2VUZW1wbGF0ZSA9IFtmYWxzZSwgVFlQRVMuYl07XHJcbiAgICAgICAgICAgICAgICB2YXIgY2FsbGJhY2tUZW1wbGF0ZSA9IFtudWxsLCBbVFlQRVMueiwgVFlQRVMuZl1dO1xyXG4gICAgICAgICAgICAgICAgdmFyIHVwZGF0ZU9uTG9hZFRlbXBsYXRlID0gW1snaW1nJ10sIFtUWVBFUy5zLCBUWVBFUy5hLCBUWVBFUy56XV07XHJcbiAgICAgICAgICAgICAgICB2YXIgaW5oZXJpdGVkQXR0cnNUZW1wbGF0ZSA9IFtbJ3N0eWxlJywgJ2NsYXNzJ10sIFtUWVBFUy5zLCBUWVBFUy5hLCBUWVBFUy56XV07XHJcbiAgICAgICAgICAgICAgICB2YXIgcmVzaXplQWxsb3dlZFZhbHVlcyA9ICduOm5vbmUgYjpib3RoIGg6aG9yaXpvbnRhbCB2OnZlcnRpY2FsJztcclxuICAgICAgICAgICAgICAgIHZhciBvdmVyZmxvd0JlaGF2aW9yQWxsb3dlZFZhbHVlcyA9ICd2LWg6dmlzaWJsZS1oaWRkZW4gdi1zOnZpc2libGUtc2Nyb2xsIHM6c2Nyb2xsIGg6aGlkZGVuJztcclxuICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzVmlzaWJpbGl0eUFsbG93ZWRWYWx1ZXMgPSAndjp2aXNpYmxlIGg6aGlkZGVuIGE6YXV0byc7XHJcbiAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc0F1dG9IaWRlQWxsb3dlZFZhbHVlcyA9ICduOm5ldmVyIHM6c2Nyb2xsIGw6bGVhdmUgbTptb3ZlJztcclxuICAgICAgICAgICAgICAgIHZhciBvcHRpb25zRGVmYXVsdHNBbmRUZW1wbGF0ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFsnb3MtdGhlbWUtZGFyaycsIGNsYXNzTmFtZUFsbG93ZWRWYWx1ZXNdLCAgICAgICAgICAgICAgICAvL251bGwgfHwgc3RyaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzaXplOiBbJ25vbmUnLCByZXNpemVBbGxvd2VkVmFsdWVzXSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9ub25lIHx8IGJvdGggIHx8IGhvcml6b250YWwgfHwgdmVydGljYWwgfHwgbiB8fCBiIHx8IGggfHwgdlxyXG4gICAgICAgICAgICAgICAgICAgIHNpemVBdXRvQ2FwYWJsZTogYm9vbGVhblRydWVUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIGNsaXBBbHdheXM6IGJvb2xlYW5UcnVlVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIG5vcm1hbGl6ZVJUTDogYm9vbGVhblRydWVUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIHBhZGRpbmdBYnNvbHV0ZTogYm9vbGVhbkZhbHNlVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIGF1dG9VcGRhdGU6IFtudWxsLCBib29sZWFuTnVsbEFsbG93ZWRWYWx1ZXNdLCAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZSB8fCBudWxsXHJcbiAgICAgICAgICAgICAgICAgICAgYXV0b1VwZGF0ZUludGVydmFsOiBbMzMsIG51bWJlckFsbG93ZWRWYWx1ZXNdLCAgICAgICAgICAgICAgICAgICAgICAgLy9udW1iZXJcclxuICAgICAgICAgICAgICAgICAgICB1cGRhdGVPbkxvYWQ6IHVwZGF0ZU9uTG9hZFRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3N0cmluZyB8fCBhcnJheSB8fCBudWxsXHJcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlU2Nyb2xsYmFyc092ZXJsYWlkOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dOYXRpdmVTY3JvbGxiYXJzOiBib29sZWFuRmFsc2VUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluaXRpYWxpemU6IGJvb2xlYW5UcnVlVGVtcGxhdGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0JlaGF2aW9yOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IFsnc2Nyb2xsJywgb3ZlcmZsb3dCZWhhdmlvckFsbG93ZWRWYWx1ZXNdLCAgICAgICAgICAgICAgICAgICAgLy92aXNpYmxlLWhpZGRlbiAgfHwgdmlzaWJsZS1zY3JvbGwgfHwgaGlkZGVuIHx8IHNjcm9sbCB8fCB2LWggfHwgdi1zIHx8IGggfHwgc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBbJ3Njcm9sbCcsIG92ZXJmbG93QmVoYXZpb3JBbGxvd2VkVmFsdWVzXSAgICAgICAgICAgICAgICAgICAgIC8vdmlzaWJsZS1oaWRkZW4gIHx8IHZpc2libGUtc2Nyb2xsIHx8IGhpZGRlbiB8fCBzY3JvbGwgfHwgdi1oIHx8IHYtcyB8fCBoIHx8IHNcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhcnM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmlzaWJpbGl0eTogWydhdXRvJywgc2Nyb2xsYmFyc1Zpc2liaWxpdHlBbGxvd2VkVmFsdWVzXSwgICAgICAgICAvL3Zpc2libGUgfHwgaGlkZGVuIHx8IGF1dG8gfHwgdiB8fCBoIHx8IGFcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b0hpZGU6IFsnbmV2ZXInLCBzY3JvbGxiYXJzQXV0b0hpZGVBbGxvd2VkVmFsdWVzXSwgICAgICAgICAgICAvL25ldmVyIHx8IHNjcm9sbCB8fCBsZWF2ZSB8fCBtb3ZlIHx8IG4gfHwgcyB8fCBsIHx8IG1cclxuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b0hpZGVEZWxheTogWzgwMCwgbnVtYmVyQWxsb3dlZFZhbHVlc10sICAgICAgICAgICAgICAgICAgICAgICAvL251bWJlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkcmFnU2Nyb2xsaW5nOiBib29sZWFuVHJ1ZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGlja1Njcm9sbGluZzogYm9vbGVhbkZhbHNlVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3VjaFN1cHBvcnQ6IGJvb2xlYW5UcnVlVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzbmFwSGFuZGxlOiBib29sZWFuRmFsc2VUZW1wbGF0ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWE6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHluV2lkdGg6IGJvb2xlYW5GYWxzZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RydWUgfHwgZmFsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHluSGVpZ2h0OiBib29sZWFuRmFsc2VUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RydWUgfHwgZmFsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5oZXJpdGVkQXR0cnM6IGluaGVyaXRlZEF0dHJzVGVtcGxhdGUgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3N0cmluZyB8fCBhcnJheSB8fCBudWxsXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFja3M6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb25Jbml0aWFsaXplZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL251bGwgfHwgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgb25Jbml0aWFsaXphdGlvbldpdGhkcmF3bjogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAvL251bGwgfHwgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgb25EZXN0cm95ZWQ6IGNhbGxiYWNrVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL251bGwgfHwgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgb25TY3JvbGxTdGFydDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL251bGwgfHwgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgb25TY3JvbGw6IGNhbGxiYWNrVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL251bGwgfHwgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgb25TY3JvbGxTdG9wOiBjYWxsYmFja1RlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL251bGwgfHwgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgb25PdmVyZmxvd0NoYW5nZWQ6IGNhbGxiYWNrVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL251bGwgfHwgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgb25PdmVyZmxvd0Ftb3VudENoYW5nZWQ6IGNhbGxiYWNrVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAvL251bGwgfHwgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgb25EaXJlY3Rpb25DaGFuZ2VkOiBjYWxsYmFja1RlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL251bGwgfHwgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgb25Db250ZW50U2l6ZUNoYW5nZWQ6IGNhbGxiYWNrVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAvL251bGwgfHwgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgb25Ib3N0U2l6ZUNoYW5nZWQ6IGNhbGxiYWNrVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL251bGwgfHwgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgb25VcGRhdGVkOiBjYWxsYmFja1RlbXBsYXRlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL251bGwgfHwgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgdmFyIGNvbnZlcnQgPSBmdW5jdGlvbiAodGVtcGxhdGUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVjdXJzaXZlID0gZnVuY3Rpb24gKG9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIga2V5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsVHlwZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gb2JqKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9ialtMRVhJQ09OLmhPUF0oa2V5KSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA9IG9ialtrZXldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsVHlwZSA9IHR5cGUodmFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWxUeXBlID09IFRZUEVTLmEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqW2tleV0gPSB2YWxbdGVtcGxhdGUgPyAxIDogMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh2YWxUeXBlID09IFRZUEVTLm8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqW2tleV0gPSByZWN1cnNpdmUodmFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2JqO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlY3Vyc2l2ZShGUkFNRVdPUksuZXh0ZW5kKHRydWUsIHt9LCBvcHRpb25zRGVmYXVsdHNBbmRUZW1wbGF0ZSkpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIF9kZWZhdWx0czogY29udmVydCgpLFxyXG5cclxuICAgICAgICAgICAgICAgICAgICBfdGVtcGxhdGU6IGNvbnZlcnQodHJ1ZSksXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICAgICAqIFZhbGlkYXRlcyB0aGUgcGFzc2VkIG9iamVjdCBieSB0aGUgcGFzc2VkIHRlbXBsYXRlLlxyXG4gICAgICAgICAgICAgICAgICAgICAqIEBwYXJhbSBvYmogVGhlIG9iamVjdCB3aGljaCBzaGFsbCBiZSB2YWxpZGF0ZWQuXHJcbiAgICAgICAgICAgICAgICAgICAgICogQHBhcmFtIHRlbXBsYXRlIFRoZSB0ZW1wbGF0ZSB3aGljaCBkZWZpbmVzIHRoZSBhbGxvd2VkIHZhbHVlcyBhbmQgdHlwZXMuXHJcbiAgICAgICAgICAgICAgICAgICAgICogQHBhcmFtIHdyaXRlRXJyb3JzIFRydWUgaWYgZXJyb3JzIHNoYWxsIGJlIGxvZ2dlZCB0byB0aGUgY29uc29sZS5cclxuICAgICAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZGlmZk9iaiBJZiBhIG9iamVjdCBpcyBwYXNzZWQgdGhlbiBvbmx5IHZhbGlkIGRpZmZlcmVuY2VzIHRvIHRoaXMgb2JqZWN0IHdpbGwgYmUgcmV0dXJuZWQuXHJcbiAgICAgICAgICAgICAgICAgICAgICogQHJldHVybnMge3t9fSBBIG9iamVjdCB3aGljaCBjb250YWlucyB0d28gb2JqZWN0cyBjYWxsZWQgXCJkZWZhdWx0XCIgYW5kIFwicHJlcGFyZWRcIiB3aGljaCBjb250YWlucyBvbmx5IHRoZSB2YWxpZCBwcm9wZXJ0aWVzIG9mIHRoZSBwYXNzZWQgb3JpZ2luYWwgb2JqZWN0IGFuZCBkaXNjYXJkcyBub3QgZGlmZmVyZW50IHZhbHVlcyBjb21wYXJlZCB0byB0aGUgcGFzc2VkIGRpZmZPYmouXHJcbiAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgX3ZhbGlkYXRlOiBmdW5jdGlvbiAob2JqLCB0ZW1wbGF0ZSwgd3JpdGVFcnJvcnMsIGRpZmZPYmopIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbGlkYXRlZE9wdGlvbnMgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbGlkYXRlZE9wdGlvbnNQcmVwYXJlZCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2JqZWN0Q29weSA9IEZSQU1FV09SSy5leHRlbmQodHJ1ZSwge30sIG9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbkFycmF5ID0gRlJBTUVXT1JLLmluQXJyYXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpc0VtcHR5T2JqID0gRlJBTUVXT1JLLmlzRW1wdHlPYmplY3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGVja09iamVjdFByb3BzID0gZnVuY3Rpb24gKGRhdGEsIHRlbXBsYXRlLCBkaWZmRGF0YSwgdmFsaWRhdGVkT3B0aW9ucywgdmFsaWRhdGVkT3B0aW9uc1ByZXBhcmVkLCBwcmV2UHJvcE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIHByb3AgaW4gdGVtcGxhdGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcGxhdGVbTEVYSUNPTi5oT1BdKHByb3ApICYmIGRhdGFbTEVYSUNPTi5oT1BdKHByb3ApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpc1ZhbGlkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpc0RpZmYgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRlbXBsYXRlVmFsdWUgPSB0ZW1wbGF0ZVtwcm9wXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRlbXBsYXRlVmFsdWVUeXBlID0gdHlwZSh0ZW1wbGF0ZVZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRlbXBsYXRlSXNDb21wbGV4ID0gdGVtcGxhdGVWYWx1ZVR5cGUgPT0gVFlQRVMubztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRlbXBsYXRlVHlwZXMgPSAhQ09NUEFUSUJJTElUWS5pc0EodGVtcGxhdGVWYWx1ZSkgPyBbdGVtcGxhdGVWYWx1ZV0gOiB0ZW1wbGF0ZVZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YURpZmZWYWx1ZSA9IGRpZmZEYXRhW3Byb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YVZhbHVlID0gZGF0YVtwcm9wXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRhdGFWYWx1ZVR5cGUgPSB0eXBlKGRhdGFWYWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcm9wUHJlZml4ID0gcHJldlByb3BOYW1lID8gcHJldlByb3BOYW1lICsgJy4nIDogJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9IFwiVGhlIG9wdGlvbiBcXFwiXCIgKyBwcm9wUHJlZml4ICsgcHJvcCArIFwiXFxcIiB3YXNuJ3Qgc2V0LCBiZWNhdXNlXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlcnJvclBvc3NpYmxlVHlwZXMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yUmVzdHJpY3RlZFN0cmluZ3MgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3RyaWN0ZWRTdHJpbmdWYWx1ZXNTcGxpdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3RyaWN0ZWRTdHJpbmdWYWx1ZXNQb3NzaWJpbGl0aWVzU3BsaXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpc1Jlc3RyaWN0ZWRWYWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1haW5Qb3NzaWJpbGl0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJUeXBlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHY7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBqO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YURpZmZWYWx1ZSA9IGRhdGFEaWZmVmFsdWUgPT09IHVuZGVmaW5lZCA/IHt9IDogZGF0YURpZmZWYWx1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgdGhlIHRlbXBsYXRlIGhhcyBhIG9iamVjdCBhcyB2YWx1ZSwgaXQgbWVhbnMgdGhhdCB0aGUgb3B0aW9ucyBhcmUgY29tcGxleCAodmVyc2NoYWNodGVsdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXBsYXRlSXNDb21wbGV4ICYmIGRhdGFWYWx1ZVR5cGUgPT0gVFlQRVMubykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGVkT3B0aW9uc1twcm9wXSA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGVkT3B0aW9uc1ByZXBhcmVkW3Byb3BdID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja09iamVjdFByb3BzKGRhdGFWYWx1ZSwgdGVtcGxhdGVWYWx1ZSwgZGF0YURpZmZWYWx1ZSwgdmFsaWRhdGVkT3B0aW9uc1twcm9wXSwgdmFsaWRhdGVkT3B0aW9uc1ByZXBhcmVkW3Byb3BdLCBwcm9wUHJlZml4ICsgcHJvcCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGUkFNRVdPUksuZWFjaChbZGF0YSwgdmFsaWRhdGVkT3B0aW9ucywgdmFsaWRhdGVkT3B0aW9uc1ByZXBhcmVkXSwgZnVuY3Rpb24gKGluZGV4LCB2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0VtcHR5T2JqKHZhbHVlW3Byb3BdKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgdmFsdWVbcHJvcF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoIXRlbXBsYXRlSXNDb21wbGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGVtcGxhdGVUeXBlc1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyVHlwZSA9IHRlbXBsYXRlVHlwZXNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVWYWx1ZVR5cGUgPSB0eXBlKGN1cnJUeXBlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIGN1cnJ0eXBlIGlzIHN0cmluZyBhbmQgc3RhcnRzIHdpdGggcmVzdHJpY3RlZFN0cmluZ1ByZWZpeCBhbmQgZW5kIHdpdGggcmVzdHJpY3RlZFN0cmluZ1N1ZmZpeFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzUmVzdHJpY3RlZFZhbHVlID0gdGVtcGxhdGVWYWx1ZVR5cGUgPT0gVFlQRVMucyAmJiBpbkFycmF5KGN1cnJUeXBlLCBwb3NzaWJsZVRlbXBsYXRlVHlwZXMpID09PSAtMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNSZXN0cmljdGVkVmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JQb3NzaWJsZVR5cGVzLnB1c2goVFlQRVMucyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3NwbGl0IGl0IGludG8gYSBhcnJheSB3aGljaCBjb250YWlucyBhbGwgcG9zc2libGUgdmFsdWVzIGZvciBleGFtcGxlOiBbXCJ5Onllc1wiLCBcIm46bm9cIiwgXCJtOm1heWJlXCJdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWRTdHJpbmdWYWx1ZXNTcGxpdCA9IGN1cnJUeXBlLnNwbGl0KHJlc3RyaWN0ZWRTdHJpbmdzU3BsaXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvclJlc3RyaWN0ZWRTdHJpbmdzID0gZXJyb3JSZXN0cmljdGVkU3RyaW5ncy5jb25jYXQocmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1NwbGl0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2ID0gMDsgdiA8IHJlc3RyaWN0ZWRTdHJpbmdWYWx1ZXNTcGxpdFtMRVhJQ09OLmxdOyB2KyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3BsaXQgdGhlIHBvc3NpYmxlIHZhbHVlcyBpbnRvIHRoZWlyIHBvc3NpYmlsaXRlaXMgZm9yIGV4YW1wbGU6IFtcInlcIiwgXCJ5ZXNcIl0gLT4gdGhlIGZpcnN0IGlzIGFsd2F5cyB0aGUgbWFpblBvc3NpYmlsaXR5XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN0cmljdGVkU3RyaW5nVmFsdWVzUG9zc2liaWxpdGllc1NwbGl0ID0gcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1NwbGl0W3ZdLnNwbGl0KHJlc3RyaWN0ZWRTdHJpbmdzUG9zc2liaWxpdGllc1NwbGl0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1haW5Qb3NzaWJpbGl0eSA9IHJlc3RyaWN0ZWRTdHJpbmdWYWx1ZXNQb3NzaWJpbGl0aWVzU3BsaXRbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1Bvc3NpYmlsaXRpZXNTcGxpdFtMRVhJQ09OLmxdOyBqKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIGFueSBwb3NzaWJpbGl0eSBtYXRjaGVzIHdpdGggdGhlIGRhdGFWYWx1ZSwgaXRzIHZhbGlkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFWYWx1ZSA9PT0gcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1Bvc3NpYmlsaXRpZXNTcGxpdFtqXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1ZhbGlkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzVmFsaWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yUG9zc2libGVUeXBlcy5wdXNoKGN1cnJUeXBlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhVmFsdWVUeXBlID09PSBjdXJyVHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNWYWxpZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNWYWxpZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzRGlmZiA9IGRhdGFWYWx1ZSAhPT0gZGF0YURpZmZWYWx1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRGlmZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGVkT3B0aW9uc1twcm9wXSA9IGRhdGFWYWx1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzUmVzdHJpY3RlZFZhbHVlID8gaW5BcnJheShkYXRhRGlmZlZhbHVlLCByZXN0cmljdGVkU3RyaW5nVmFsdWVzUG9zc2liaWxpdGllc1NwbGl0KSA8IDAgOiBpc0RpZmYpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRlZE9wdGlvbnNQcmVwYXJlZFtwcm9wXSA9IGlzUmVzdHJpY3RlZFZhbHVlID8gbWFpblBvc3NpYmlsaXR5IDogZGF0YVZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAod3JpdGVFcnJvcnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oZXJyb3IgKyBcIiBpdCBkb2Vzbid0IGFjY2VwdCB0aGUgdHlwZSBbIFwiICsgZGF0YVZhbHVlVHlwZS50b1VwcGVyQ2FzZSgpICsgXCIgXSB3aXRoIHRoZSB2YWx1ZSBvZiBcXFwiXCIgKyBkYXRhVmFsdWUgKyBcIlxcXCIuXFxyXFxuXCIgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIkFjY2VwdGVkIHR5cGVzIGFyZTogWyBcIiArIGVycm9yUG9zc2libGVUeXBlcy5qb2luKCcsICcpLnRvVXBwZXJDYXNlKCkgKyBcIiBdLlwiICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGVycm9yUmVzdHJpY3RlZFN0cmluZ3NbbGVuZ3RoXSA+IDAgPyBcIlxcclxcblZhbGlkIHN0cmluZ3MgYXJlOiBbIFwiICsgZXJyb3JSZXN0cmljdGVkU3RyaW5ncy5qb2luKCcsICcpLnNwbGl0KHJlc3RyaWN0ZWRTdHJpbmdzUG9zc2liaWxpdGllc1NwbGl0KS5qb2luKCcsICcpICsgXCIgXS5cIiA6ICcnKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgZGF0YVtwcm9wXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tPYmplY3RQcm9wcyhvYmplY3RDb3B5LCB0ZW1wbGF0ZSwgZGlmZk9iaiB8fCB7fSwgdmFsaWRhdGVkT3B0aW9ucywgdmFsaWRhdGVkT3B0aW9uc1ByZXBhcmVkKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYWRkIHZhbHVlcyB3aGljaCBhcmVuJ3Qgc3BlY2lmaWVkIGluIHRoZSB0ZW1wbGF0ZSB0byB0aGUgZmluaXNoZWQgdmFsaWRhdGVkIG9iamVjdCB0byBwcmV2ZW50IHRoZW0gZnJvbSBiZWluZyBkaXNjYXJkZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgLypcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYoa2VlcEZvcmVpZ25Qcm9wcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB2YWxpZGF0ZWRPcHRpb25zLCBvYmplY3RDb3B5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSy5leHRlbmQodHJ1ZSwgdmFsaWRhdGVkT3B0aW9uc1ByZXBhcmVkLCBvYmplY3RDb3B5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAqL1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0VtcHR5T2JqKG9iamVjdENvcHkpICYmIHdyaXRlRXJyb3JzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdUaGUgZm9sbG93aW5nIG9wdGlvbnMgYXJlIGRpc2NhcmRlZCBkdWUgdG8gaW52YWxpZGl0eTpcXHJcXG4nICsgd2luZG93LkpTT04uc3RyaW5naWZ5KG9iamVjdENvcHksIG51bGwsIDIpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZGVmYXVsdDogdmFsaWRhdGVkT3B0aW9ucyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wcmVwYXJlZDogdmFsaWRhdGVkT3B0aW9uc1ByZXBhcmVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KCkpO1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIHRoZSBvYmplY3Qgd2hpY2ggY29udGFpbnMgZ2xvYmFsIGluZm9ybWF0aW9uIGFib3V0IHRoZSBwbHVnaW4gYW5kIGVhY2ggaW5zdGFuY2Ugb2YgaXQuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBpbml0T3ZlcmxheVNjcm9sbGJhcnNTdGF0aWNzKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFfcGx1Z2luc0dsb2JhbHMpXHJcbiAgICAgICAgICAgICAgICAgICAgX3BsdWdpbnNHbG9iYWxzID0gbmV3IE92ZXJsYXlTY3JvbGxiYXJzR2xvYmFscyhfcGx1Z2luc09wdGlvbnMuX2RlZmF1bHRzKTtcclxuICAgICAgICAgICAgICAgIGlmICghX3BsdWdpbnNBdXRvVXBkYXRlTG9vcClcclxuICAgICAgICAgICAgICAgICAgICBfcGx1Z2luc0F1dG9VcGRhdGVMb29wID0gbmV3IE92ZXJsYXlTY3JvbGxiYXJzQXV0b1VwZGF0ZUxvb3AoX3BsdWdpbnNHbG9iYWxzKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFRoZSBnbG9iYWwgb2JqZWN0IGZvciB0aGUgT3ZlcmxheVNjcm9sbGJhcnMgb2JqZWN0cy4gSXQgY29udGFpbnMgcmVzb3VyY2VzIHdoaWNoIGV2ZXJ5IE92ZXJsYXlTY3JvbGxiYXJzIG9iamVjdCBuZWVkcy4gVGhpcyBvYmplY3QgaXMgaW5pdGlhbGl6ZWQgb25seSBvbmNlOiBpZiB0aGUgZmlyc3QgT3ZlcmxheVNjcm9sbGJhcnMgb2JqZWN0IGdldHMgaW5pdGlhbGl6ZWQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBkZWZhdWx0T3B0aW9uc1xyXG4gICAgICAgICAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIE92ZXJsYXlTY3JvbGxiYXJzR2xvYmFscyhkZWZhdWx0T3B0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgdmFyIF9iYXNlID0gdGhpcztcclxuICAgICAgICAgICAgICAgIHZhciBzdHJPdmVyZmxvdyA9ICdvdmVyZmxvdyc7XHJcbiAgICAgICAgICAgICAgICB2YXIgc3RySGlkZGVuID0gJ2hpZGRlbic7XHJcbiAgICAgICAgICAgICAgICB2YXIgc3RyU2Nyb2xsID0gJ3Njcm9sbCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgYm9keUVsZW1lbnQgPSBGUkFNRVdPUksoJ2JvZHknKTtcclxuICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJEdW1teUVsZW1lbnQgPSBGUkFNRVdPUksoJzxkaXYgaWQ9XCJvcy1kdW1teS1zY3JvbGxiYXItc2l6ZVwiPjxkaXY+PC9kaXY+PC9kaXY+Jyk7XHJcbiAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyRHVtbXlFbGVtZW50MCA9IHNjcm9sbGJhckR1bW15RWxlbWVudFswXTtcclxuICAgICAgICAgICAgICAgIHZhciBkdW1teUNvbnRhaW5lckNoaWxkID0gRlJBTUVXT1JLKHNjcm9sbGJhckR1bW15RWxlbWVudC5jaGlsZHJlbignZGl2JykuZXEoMCkpO1xyXG5cclxuICAgICAgICAgICAgICAgIGJvZHlFbGVtZW50LmFwcGVuZChzY3JvbGxiYXJEdW1teUVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgc2Nyb2xsYmFyRHVtbXlFbGVtZW50LmhpZGUoKS5zaG93KCk7IC8vZml4IElFOCBidWcgKGluY29ycmVjdCBtZWFzdXJpbmcpXHJcblxyXG4gICAgICAgICAgICAgICAgdmFyIG5hdGl2ZVNjcm9sbGJhclNpemUgPSBjYWxjTmF0aXZlU2Nyb2xsYmFyU2l6ZShzY3JvbGxiYXJEdW1teUVsZW1lbnQwKTtcclxuICAgICAgICAgICAgICAgIHZhciBuYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIHg6IG5hdGl2ZVNjcm9sbGJhclNpemUueCA9PT0gMCxcclxuICAgICAgICAgICAgICAgICAgICB5OiBuYXRpdmVTY3JvbGxiYXJTaXplLnkgPT09IDBcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB2YXIgbXNpZSA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHVhID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckluZGV4T2YgPSAnaW5kZXhPZic7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clN1YlN0cmluZyA9ICdzdWJzdHJpbmcnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtc2llID0gdWFbc3RySW5kZXhPZl0oJ01TSUUgJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRyaWRlbnQgPSB1YVtzdHJJbmRleE9mXSgnVHJpZGVudC8nKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWRnZSA9IHVhW3N0ckluZGV4T2ZdKCdFZGdlLycpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBydiA9IHVhW3N0ckluZGV4T2ZdKCdydjonKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJzZUludEZ1bmMgPSBwYXJzZUludDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gSUUgMTAgb3Igb2xkZXIgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1zaWUgPiAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBwYXJzZUludEZ1bmModWFbc3RyU3ViU3RyaW5nXShtc2llICsgNSwgdWFbc3RySW5kZXhPZl0oJy4nLCBtc2llKSksIDEwKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gSUUgMTEgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyXHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHJpZGVudCA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHBhcnNlSW50RnVuYyh1YVtzdHJTdWJTdHJpbmddKHJ2ICsgMywgdWFbc3RySW5kZXhPZl0oJy4nLCBydikpLCAxMCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIEVkZ2UgKElFIDEyKykgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyXHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZWRnZSA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHBhcnNlSW50RnVuYyh1YVtzdHJTdWJTdHJpbmddKGVkZ2UgKyA1LCB1YVtzdHJJbmRleE9mXSgnLicsIGVkZ2UpKSwgMTApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBvdGhlciBicm93c2VyXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgICAgIH0pKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgRlJBTUVXT1JLLmV4dGVuZChfYmFzZSwge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRPcHRpb25zOiBkZWZhdWx0T3B0aW9ucyxcclxuICAgICAgICAgICAgICAgICAgICBtc2llOiBtc2llLFxyXG4gICAgICAgICAgICAgICAgICAgIGF1dG9VcGRhdGVMb29wOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICBhdXRvVXBkYXRlUmVjb21tZW5kZWQ6ICFDT01QQVRJQklMSVRZLm1PKCksXHJcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlU2Nyb2xsYmFyU2l6ZTogbmF0aXZlU2Nyb2xsYmFyU2l6ZSxcclxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkOiBuYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLFxyXG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZVNjcm9sbGJhclN0eWxpbmc6IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyRHVtbXlFbGVtZW50LmFkZENsYXNzKCdvcy12aWV3cG9ydC1uYXRpdmUtc2Nyb2xsYmFycy1pbnZpc2libGUnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IChzY3JvbGxiYXJEdW1teUVsZW1lbnQuY3NzKCdzY3JvbGxiYXItd2lkdGgnKSA9PT0gJ25vbmUnICYmIChtc2llID4gOSB8fCAhbXNpZSkpIHx8IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHNjcm9sbGJhckR1bW15RWxlbWVudDAsICc6Oi13ZWJraXQtc2Nyb2xsYmFyJykuZ2V0UHJvcGVydHlWYWx1ZSgnZGlzcGxheScpID09PSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4KSB7IH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vZml4IG9wZXJhIGJ1Zzogc2Nyb2xsYmFyIHN0eWxlcyB3aWxsIG9ubHkgYXBwZWFyIGlmIG92ZXJmbG93IHZhbHVlIGlzIHNjcm9sbCBvciBhdXRvIGR1cmluZyB0aGUgYWN0aXZhdGlvbiBvZiB0aGUgc3R5bGUuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYW5kIHNldCBvdmVyZmxvdyB0byBzY3JvbGxcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxiYXJEdW1teUVsZW1lbnQuY3NzKHN0ck92ZXJmbG93LCBzdHJIaWRkZW4pLmhpZGUoKS5jc3Moc3RyT3ZlcmZsb3csIHN0clNjcm9sbCkuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3JldHVybiAoc2Nyb2xsYmFyRHVtbXlFbGVtZW50MFtMRVhJQ09OLm9IXSAtIHNjcm9sbGJhckR1bW15RWxlbWVudDBbTEVYSUNPTi5jSF0pID09PSAwICYmIChzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04ub1ddIC0gc2Nyb2xsYmFyRHVtbXlFbGVtZW50MFtMRVhJQ09OLmNXXSkgPT09IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIH0pKCksXHJcbiAgICAgICAgICAgICAgICAgICAgb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZTogeyB4OiAzMCwgeTogMzAgfSxcclxuICAgICAgICAgICAgICAgICAgICBjc3NDYWxjOiBWRU5ET1JTLl9jc3NQcm9wZXJ0eVZhbHVlKCd3aWR0aCcsICdjYWxjJywgJygxcHgpJykgfHwgbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICByZXN0cmljdGVkTWVhc3VyaW5nOiAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2h0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTE0MzkzMDVcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zaW5jZSAxLjExLjAgYWx3YXlzIGZhbHNlIC0+IGZpeGVkIHZpYSBDU1MgKGhvcGVmdWxseSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyRHVtbXlFbGVtZW50LmNzcyhzdHJPdmVyZmxvdywgc3RySGlkZGVuKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04uc1ddLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogc2Nyb2xsYmFyRHVtbXlFbGVtZW50MFtMRVhJQ09OLnNIXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuY3NzKHN0ck92ZXJmbG93LCAndmlzaWJsZScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsU2l6ZTIgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04uc1ddLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogc2Nyb2xsYmFyRHVtbXlFbGVtZW50MFtMRVhJQ09OLnNIXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHNjcm9sbFNpemUudyAtIHNjcm9sbFNpemUyLncpICE9PSAwIHx8IChzY3JvbGxTaXplLmggLSBzY3JvbGxTaXplMi5oKSAhPT0gMDtcclxuICAgICAgICAgICAgICAgICAgICB9KSgpLFxyXG4gICAgICAgICAgICAgICAgICAgIHJ0bFNjcm9sbEJlaGF2aW9yOiAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuY3NzKHsgJ292ZXJmbG93LXknOiBzdHJIaWRkZW4sICdvdmVyZmxvdy14Jzogc3RyU2Nyb2xsLCAnZGlyZWN0aW9uJzogJ3J0bCcgfSkuc2Nyb2xsTGVmdCgwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGR1bW15Q29udGFpbmVyT2Zmc2V0ID0gc2Nyb2xsYmFyRHVtbXlFbGVtZW50Lm9mZnNldCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZHVtbXlDb250YWluZXJDaGlsZE9mZnNldCA9IGR1bW15Q29udGFpbmVyQ2hpbGQub2Zmc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaHR0cHM6Ly9naXRodWIuY29tL0tpbmdTb3JhL092ZXJsYXlTY3JvbGxiYXJzL2lzc3Vlcy8xODdcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyRHVtbXlFbGVtZW50LnNjcm9sbExlZnQoLTk5OSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkdW1teUNvbnRhaW5lckNoaWxkT2Zmc2V0QWZ0ZXJTY3JvbGwgPSBkdW1teUNvbnRhaW5lckNoaWxkLm9mZnNldCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9vcmlnaW4gZGlyZWN0aW9uID0gZGV0ZXJtaW5lcyBpZiB0aGUgemVybyBzY3JvbGwgcG9zaXRpb24gaXMgb24gdGhlIGxlZnQgb3IgcmlnaHQgc2lkZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8naScgbWVhbnMgJ2ludmVydCcgKGkgPT09IHRydWUgbWVhbnMgdGhhdCB0aGUgYXhpcyBtdXN0IGJlIGludmVydGVkIHRvIGJlIGNvcnJlY3QpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RydWUgPSBvbiB0aGUgbGVmdCBzaWRlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2ZhbHNlID0gb24gdGhlIHJpZ2h0IHNpZGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGk6IGR1bW15Q29udGFpbmVyT2Zmc2V0LmxlZnQgPT09IGR1bW15Q29udGFpbmVyQ2hpbGRPZmZzZXQubGVmdCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbmVnYXRpdmUgPSBkZXRlcm1pbmVzIGlmIHRoZSBtYXhpbXVtIHNjcm9sbCBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8nbicgbWVhbnMgJ25lZ2F0ZScgKG4gPT09IHRydWUgbWVhbnMgdGhhdCB0aGUgYXhpcyBtdXN0IGJlIG5lZ2F0ZWQgdG8gYmUgY29ycmVjdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSA9IG5lZ2F0aXZlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2ZhbHNlID0gcG9zaXRpdmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG46IGR1bW15Q29udGFpbmVyQ2hpbGRPZmZzZXQubGVmdCAhPT0gZHVtbXlDb250YWluZXJDaGlsZE9mZnNldEFmdGVyU2Nyb2xsLmxlZnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9KSgpLFxyXG4gICAgICAgICAgICAgICAgICAgIHN1cHBvcnRUcmFuc2Zvcm06ICEhVkVORE9SUy5fY3NzUHJvcGVydHkoJ3RyYW5zZm9ybScpLFxyXG4gICAgICAgICAgICAgICAgICAgIHN1cHBvcnRUcmFuc2l0aW9uOiAhIVZFTkRPUlMuX2Nzc1Byb3BlcnR5KCd0cmFuc2l0aW9uJyksXHJcbiAgICAgICAgICAgICAgICAgICAgc3VwcG9ydFBhc3NpdmVFdmVudHM6IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdXBwb3J0c1Bhc3NpdmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCd0ZXN0JywgbnVsbCwgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAncGFzc2l2ZScsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VwcG9ydHNQYXNzaXZlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VwcG9ydHNQYXNzaXZlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pKCksXHJcbiAgICAgICAgICAgICAgICAgICAgc3VwcG9ydFJlc2l6ZU9ic2VydmVyOiAhIUNPTVBBVElCSUxJVFkuck8oKSxcclxuICAgICAgICAgICAgICAgICAgICBzdXBwb3J0TXV0YXRpb25PYnNlcnZlcjogISFDT01QQVRJQklMSVRZLm1PKClcclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIHNjcm9sbGJhckR1bW15RWxlbWVudC5yZW1vdmVBdHRyKExFWElDT04ucykucmVtb3ZlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9DYXRjaCB6b29tIGV2ZW50OlxyXG4gICAgICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIG5hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWJzID0gTUFUSC5hYnM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdpbmRvd1dpZHRoID0gQ09NUEFUSUJJTElUWS53VygpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB3aW5kb3dIZWlnaHQgPSBDT01QQVRJQklMSVRZLndIKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdpbmRvd0RwciA9IGdldFdpbmRvd0RQUigpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvblJlc2l6ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKElOU1RBTkNFUygpLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdXID0gQ09NUEFUSUJJTElUWS53VygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld0ggPSBDT01QQVRJQklMSVRZLndIKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVsdGFXID0gbmV3VyAtIHdpbmRvd1dpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRlbHRhSCA9IG5ld0ggLSB3aW5kb3dIZWlnaHQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRlbHRhVyA9PT0gMCAmJiBkZWx0YUggPT09IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZWx0YVdSYXRpbyA9IE1BVEgucm91bmQobmV3VyAvICh3aW5kb3dXaWR0aCAvIDEwMC4wKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVsdGFIUmF0aW8gPSBNQVRILnJvdW5kKG5ld0ggLyAod2luZG93SGVpZ2h0IC8gMTAwLjApKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhYnNEZWx0YVcgPSBhYnMoZGVsdGFXKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhYnNEZWx0YUggPSBhYnMoZGVsdGFIKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhYnNEZWx0YVdSYXRpbyA9IGFicyhkZWx0YVdSYXRpbyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWJzRGVsdGFIUmF0aW8gPSBhYnMoZGVsdGFIUmF0aW8pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld0RQUiA9IGdldFdpbmRvd0RQUigpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZWx0YUlzQmlnZ2VyID0gYWJzRGVsdGFXID4gMiAmJiBhYnNEZWx0YUggPiAyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRpZmZlcmVuY2UgPSAhZGlmZmVyZW5jZUlzQmlnZ2VyVGhhbk9uZShhYnNEZWx0YVdSYXRpbywgYWJzRGVsdGFIUmF0aW8pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRwckNoYW5nZWQgPSBuZXdEUFIgIT09IHdpbmRvd0RwciAmJiB3aW5kb3dEcHIgPiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzWm9vbSA9IGRlbHRhSXNCaWdnZXIgJiYgZGlmZmVyZW5jZSAmJiBkcHJDaGFuZ2VkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9sZFNjcm9sbGJhclNpemUgPSBfYmFzZS5uYXRpdmVTY3JvbGxiYXJTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld1Njcm9sbGJhclNpemU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzWm9vbSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvZHlFbGVtZW50LmFwcGVuZChzY3JvbGxiYXJEdW1teUVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1Njcm9sbGJhclNpemUgPSBfYmFzZS5uYXRpdmVTY3JvbGxiYXJTaXplID0gY2FsY05hdGl2ZVNjcm9sbGJhclNpemUoc2Nyb2xsYmFyRHVtbXlFbGVtZW50WzBdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9sZFNjcm9sbGJhclNpemUueCAhPT0gbmV3U2Nyb2xsYmFyU2l6ZS54IHx8IG9sZFNjcm9sbGJhclNpemUueSAhPT0gbmV3U2Nyb2xsYmFyU2l6ZS55KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSy5lYWNoKElOU1RBTkNFUygpLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoSU5TVEFOQ0VTKHRoaXMpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOU1RBTkNFUyh0aGlzKS51cGRhdGUoJ3pvb20nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd1dpZHRoID0gbmV3VztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd0hlaWdodCA9IG5ld0g7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dEcHIgPSBuZXdEUFI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkaWZmZXJlbmNlSXNCaWdnZXJUaGFuT25lKHZhbE9uZSwgdmFsVHdvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhYnNWYWxPbmUgPSBhYnModmFsT25lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFic1ZhbFR3byA9IGFicyh2YWxUd28pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIShhYnNWYWxPbmUgPT09IGFic1ZhbFR3byB8fCBhYnNWYWxPbmUgKyAxID09PSBhYnNWYWxUd28gfHwgYWJzVmFsT25lIC0gMSA9PT0gYWJzVmFsVHdvKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldFdpbmRvd0RQUigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGREUEkgPSB3aW5kb3cuc2NyZWVuLmRldmljZVhEUEkgfHwgMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNEUEkgPSB3aW5kb3cuc2NyZWVuLmxvZ2ljYWxYRFBJIHx8IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyB8fCAoZERQSSAvIHNEUEkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLKHdpbmRvdykub24oJ3Jlc2l6ZScsIG9uUmVzaXplKTtcclxuICAgICAgICAgICAgICAgIH0pKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gY2FsY05hdGl2ZVNjcm9sbGJhclNpemUobWVhc3VyZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBtZWFzdXJlRWxlbWVudFtMRVhJQ09OLm9IXSAtIG1lYXN1cmVFbGVtZW50W0xFWElDT04uY0hdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBtZWFzdXJlRWxlbWVudFtMRVhJQ09OLm9XXSAtIG1lYXN1cmVFbGVtZW50W0xFWElDT04uY1ddXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFRoZSBvYmplY3Qgd2hpY2ggbWFuYWdlcyB0aGUgYXV0byB1cGRhdGUgbG9vcCBmb3IgYWxsIE92ZXJsYXlTY3JvbGxiYXJzIG9iamVjdHMuIFRoaXMgb2JqZWN0IGlzIGluaXRpYWxpemVkIG9ubHkgb25jZTogaWYgdGhlIGZpcnN0IE92ZXJsYXlTY3JvbGxiYXJzIG9iamVjdCBnZXRzIGluaXRpYWxpemVkLlxyXG4gICAgICAgICAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIE92ZXJsYXlTY3JvbGxiYXJzQXV0b1VwZGF0ZUxvb3AoZ2xvYmFscykge1xyXG4gICAgICAgICAgICAgICAgdmFyIF9iYXNlID0gdGhpcztcclxuICAgICAgICAgICAgICAgIHZhciBfaW5BcnJheSA9IEZSQU1FV09SSy5pbkFycmF5O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9nZXROb3cgPSBDT01QQVRJQklMSVRZLm5vdztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyQXV0b1VwZGF0ZSA9ICdhdXRvVXBkYXRlJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyQXV0b1VwZGF0ZUludGVydmFsID0gX3N0ckF1dG9VcGRhdGUgKyAnSW50ZXJ2YWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJMZW5ndGggPSBMRVhJQ09OLmw7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2xvb3BpbmdJbnN0YW5jZXMgPSBbXTtcclxuICAgICAgICAgICAgICAgIHZhciBfbG9vcGluZ0luc3RhbmNlc0ludGVydmFsQ2FjaGUgPSBbXTtcclxuICAgICAgICAgICAgICAgIHZhciBfbG9vcElzQWN0aXZlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2xvb3BJbnRlcnZhbERlZmF1bHQgPSAzMztcclxuICAgICAgICAgICAgICAgIHZhciBfbG9vcEludGVydmFsID0gX2xvb3BJbnRlcnZhbERlZmF1bHQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2xvb3BUaW1lT2xkID0gX2dldE5vdygpO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9sb29wSUQ7XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVGhlIGF1dG8gdXBkYXRlIGxvb3Agd2hpY2ggd2lsbCBydW4gZXZlcnkgNTAgbWlsbGlzZWNvbmRzIG9yIGxlc3MgaWYgdGhlIHVwZGF0ZSBpbnRlcnZhbCBvZiBhIGluc3RhbmNlIGlzIGxvd2VyIHRoYW4gNTAgbWlsbGlzZWNvbmRzLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICB2YXIgbG9vcCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2xvb3BpbmdJbnN0YW5jZXNbX3N0ckxlbmd0aF0gPiAwICYmIF9sb29wSXNBY3RpdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BJRCA9IENPTVBBVElCSUxJVFkuckFGKCkoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9vcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRpbWVOZXcgPSBfZ2V0Tm93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0aW1lRGVsdGEgPSB0aW1lTmV3IC0gX2xvb3BUaW1lT2xkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbG93ZXN0SW50ZXJ2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlT3B0aW9ucztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlQXV0b1VwZGF0ZUFsbG93ZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZUF1dG9VcGRhdGVJbnRlcnZhbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vdztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aW1lRGVsdGEgPiBfbG9vcEludGVydmFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbG9vcFRpbWVPbGQgPSB0aW1lTmV3IC0gKHRpbWVEZWx0YSAlIF9sb29wSW50ZXJ2YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXN0SW50ZXJ2YWwgPSBfbG9vcEludGVydmFsRGVmYXVsdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgX2xvb3BpbmdJbnN0YW5jZXNbX3N0ckxlbmd0aF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlID0gX2xvb3BpbmdJbnN0YW5jZXNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VPcHRpb25zID0gaW5zdGFuY2Uub3B0aW9ucygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUF1dG9VcGRhdGVBbGxvd2VkID0gaW5zdGFuY2VPcHRpb25zW19zdHJBdXRvVXBkYXRlXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VBdXRvVXBkYXRlSW50ZXJ2YWwgPSBNQVRILm1heCgxLCBpbnN0YW5jZU9wdGlvbnNbX3N0ckF1dG9VcGRhdGVJbnRlcnZhbF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3cgPSBfZ2V0Tm93KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGluc3RhbmNlQXV0b1VwZGF0ZUFsbG93ZWQgPT09IHRydWUgfHwgaW5zdGFuY2VBdXRvVXBkYXRlQWxsb3dlZCA9PT0gbnVsbCkgJiYgKG5vdyAtIF9sb29waW5nSW5zdGFuY2VzSW50ZXJ2YWxDYWNoZVtpXSkgPiBpbnN0YW5jZUF1dG9VcGRhdGVJbnRlcnZhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UudXBkYXRlKCdhdXRvJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbG9vcGluZ0luc3RhbmNlc0ludGVydmFsQ2FjaGVbaV0gPSBuZXcgRGF0ZShub3cgKz0gaW5zdGFuY2VBdXRvVXBkYXRlSW50ZXJ2YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb3dlc3RJbnRlcnZhbCA9IE1BVEgubWF4KDEsIE1BVEgubWluKGxvd2VzdEludGVydmFsLCBpbnN0YW5jZUF1dG9VcGRhdGVJbnRlcnZhbCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sb29wSW50ZXJ2YWwgPSBsb3dlc3RJbnRlcnZhbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9sb29wSW50ZXJ2YWwgPSBfbG9vcEludGVydmFsRGVmYXVsdDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQWRkIE92ZXJsYXlTY3JvbGxiYXJzIGluc3RhbmNlIHRvIHRoZSBhdXRvIHVwZGF0ZSBsb29wLiBPbmx5IHN1Y2Nlc3NmdWwgaWYgdGhlIGluc3RhbmNlIGlzbid0IGFscmVhZHkgYWRkZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gaW5zdGFuY2UgVGhlIGluc3RhbmNlIHdoaWNoIHNoYWxsIGJlIHVwZGF0ZWQgaW4gYSBsb29wIGF1dG9tYXRpY2FsbHkuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLmFkZCA9IGZ1bmN0aW9uIChpbnN0YW5jZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfaW5BcnJheShpbnN0YW5jZSwgX2xvb3BpbmdJbnN0YW5jZXMpID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbG9vcGluZ0luc3RhbmNlcy5wdXNoKGluc3RhbmNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BpbmdJbnN0YW5jZXNJbnRlcnZhbENhY2hlLnB1c2goX2dldE5vdygpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9sb29waW5nSW5zdGFuY2VzW19zdHJMZW5ndGhdID4gMCAmJiAhX2xvb3BJc0FjdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BJc0FjdGl2ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbG9iYWxzLmF1dG9VcGRhdGVMb29wID0gX2xvb3BJc0FjdGl2ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZW1vdmUgT3ZlcmxheVNjcm9sbGJhcnMgaW5zdGFuY2UgZnJvbSB0aGUgYXV0byB1cGRhdGUgbG9vcC4gT25seSBzdWNjZXNzZnVsIGlmIHRoZSBpbnN0YW5jZSB3YXMgYWRkZWQgYmVmb3JlLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGluc3RhbmNlIFRoZSBpbnN0YW5jZSB3aGljaCBzaGFsbCBiZSB1cGRhdGVkIGluIGEgbG9vcCBhdXRvbWF0aWNhbGx5LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5yZW1vdmUgPSBmdW5jdGlvbiAoaW5zdGFuY2UpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBfaW5BcnJheShpbnN0YW5jZSwgX2xvb3BpbmdJbnN0YW5jZXMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIGZyb20gbG9vcGluZ0luc3RhbmNlcyBsaXN0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9sb29waW5nSW5zdGFuY2VzSW50ZXJ2YWxDYWNoZS5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbG9vcGluZ0luc3RhbmNlcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb3JyZWN0IHVwZGF0ZSBsb29wIGJlaGF2aW9yXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbG9vcGluZ0luc3RhbmNlc1tfc3RyTGVuZ3RoXSA9PT0gMCAmJiBfbG9vcElzQWN0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbG9vcElzQWN0aXZlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbG9iYWxzLmF1dG9VcGRhdGVMb29wID0gX2xvb3BJc0FjdGl2ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbG9vcElEICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLmNBRigpKF9sb29wSUQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sb29wSUQgPSAtMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBBIG9iamVjdCB3aGljaCBtYW5hZ2VzIHRoZSBzY3JvbGxiYXJzIHZpc2liaWxpdHkgb2YgdGhlIHRhcmdldCBlbGVtZW50LlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gcGx1Z2luVGFyZ2V0RWxlbWVudCBUaGUgZWxlbWVudCBmcm9tIHdoaWNoIHRoZSBzY3JvbGxiYXJzIHNoYWxsIGJlIGhpZGRlbi5cclxuICAgICAgICAgICAgICogQHBhcmFtIG9wdGlvbnMgVGhlIGN1c3RvbSBvcHRpb25zLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gZXh0ZW5zaW9ucyBUaGUgY3VzdG9tIGV4dGVuc2lvbnMuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBnbG9iYWxzXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBhdXRvVXBkYXRlTG9vcFxyXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn1cclxuICAgICAgICAgICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBPdmVybGF5U2Nyb2xsYmFyc0luc3RhbmNlKHBsdWdpblRhcmdldEVsZW1lbnQsIG9wdGlvbnMsIGV4dGVuc2lvbnMsIGdsb2JhbHMsIGF1dG9VcGRhdGVMb29wKSB7XHJcbiAgICAgICAgICAgICAgICAvL3Nob3J0Y3V0c1xyXG4gICAgICAgICAgICAgICAgdmFyIHR5cGUgPSBDT01QQVRJQklMSVRZLnR5cGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgaW5BcnJheSA9IEZSQU1FV09SSy5pbkFycmF5O1xyXG4gICAgICAgICAgICAgICAgdmFyIGVhY2ggPSBGUkFNRVdPUksuZWFjaDtcclxuXHJcbiAgICAgICAgICAgICAgICAvL21ha2UgY29ycmVjdCBpbnN0YW5jZW9mXHJcbiAgICAgICAgICAgICAgICB2YXIgX2Jhc2UgPSBuZXcgX3BsdWdpbigpO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9mcmFtZXdvcmtQcm90byA9IEZSQU1FV09SS1tMRVhJQ09OLnBdO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vaWYgcGFzc2VkIGVsZW1lbnQgaXMgbm8gSFRNTCBlbGVtZW50OiBza2lwIGFuZCByZXR1cm5cclxuICAgICAgICAgICAgICAgIGlmICghaXNIVE1MRWxlbWVudChwbHVnaW5UYXJnZXRFbGVtZW50KSlcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgLy9pZiBwYXNzZWQgZWxlbWVudCBpcyBhbHJlYWR5IGluaXRpYWxpemVkOiBzZXQgcGFzc2VkIG9wdGlvbnMgaWYgdGhlcmUgYXJlIGFueSBhbmQgcmV0dXJuIGl0cyBpbnN0YW5jZVxyXG4gICAgICAgICAgICAgICAgaWYgKElOU1RBTkNFUyhwbHVnaW5UYXJnZXRFbGVtZW50KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbnN0ID0gSU5TVEFOQ0VTKHBsdWdpblRhcmdldEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGluc3Qub3B0aW9ucyhvcHRpb25zKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5zdDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvL2dsb2JhbHM6XHJcbiAgICAgICAgICAgICAgICB2YXIgX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3J0bFNjcm9sbEJlaGF2aW9yO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9hdXRvVXBkYXRlUmVjb21tZW5kZWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX21zaWVWZXJzaW9uO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jc3NDYWxjO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9uYXRpdmVTY3JvbGxiYXJTaXplO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdXBwb3J0VHJhbnNpdGlvbjtcclxuICAgICAgICAgICAgICAgIHZhciBfc3VwcG9ydFRyYW5zZm9ybTtcclxuICAgICAgICAgICAgICAgIHZhciBfc3VwcG9ydFBhc3NpdmVFdmVudHM7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N1cHBvcnRSZXNpemVPYnNlcnZlcjtcclxuICAgICAgICAgICAgICAgIHZhciBfc3VwcG9ydE11dGF0aW9uT2JzZXJ2ZXI7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Jlc3RyaWN0ZWRNZWFzdXJpbmc7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9nZW5lcmFsIHJlYWRvbmx5OlxyXG4gICAgICAgICAgICAgICAgdmFyIF9pbml0aWFsaXplZDtcclxuICAgICAgICAgICAgICAgIHZhciBfZGVzdHJveWVkO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9pc1RleHRhcmVhO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9pc0JvZHk7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2RvY3VtZW50TWl4ZWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2RvbUV4aXN0cztcclxuXHJcbiAgICAgICAgICAgICAgICAvL2dlbmVyYWw6XHJcbiAgICAgICAgICAgICAgICB2YXIgX2lzQm9yZGVyQm94O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zaXplQXV0b09ic2VydmVyQWRkZWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3BhZGRpbmdYO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9wYWRkaW5nWTtcclxuICAgICAgICAgICAgICAgIHZhciBfYm9yZGVyWDtcclxuICAgICAgICAgICAgICAgIHZhciBfYm9yZGVyWTtcclxuICAgICAgICAgICAgICAgIHZhciBfbWFyZ2luWDtcclxuICAgICAgICAgICAgICAgIHZhciBfbWFyZ2luWTtcclxuICAgICAgICAgICAgICAgIHZhciBfaXNSVEw7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3NsZWVwaW5nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jb250ZW50Qm9yZGVyU2l6ZSA9IHt9O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxIb3Jpem9udGFsSW5mbyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxWZXJ0aWNhbEluZm8gPSB7fTtcclxuICAgICAgICAgICAgICAgIHZhciBfdmlld3BvcnRTaXplID0ge307XHJcbiAgICAgICAgICAgICAgICB2YXIgX25hdGl2ZVNjcm9sbGJhck1pblNpemUgPSB7fTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL25hbWluZzpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJNaW51c0hpZGRlbiA9ICctaGlkZGVuJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTWFyZ2luTWludXMgPSAnbWFyZ2luLSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clBhZGRpbmdNaW51cyA9ICdwYWRkaW5nLSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckJvcmRlck1pbnVzID0gJ2JvcmRlci0nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJUb3AgPSAndG9wJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyUmlnaHQgPSAncmlnaHQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJCb3R0b20gPSAnYm90dG9tJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTGVmdCA9ICdsZWZ0JztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTWluTWludXMgPSAnbWluLSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1heE1pbnVzID0gJ21heC0nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJXaWR0aCA9ICd3aWR0aCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckhlaWdodCA9ICdoZWlnaHQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJGbG9hdCA9ICdmbG9hdCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckVtcHR5ID0gJyc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckF1dG8gPSAnYXV0byc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clN5bmMgPSAnc3luYyc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clNjcm9sbCA9ICdzY3JvbGwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJIdW5kcmVkUGVyY2VudCA9ICcxMDAlJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyWCA9ICd4JztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyWSA9ICd5JztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyRG90ID0gJy4nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJTcGFjZSA9ICcgJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyU2Nyb2xsYmFyID0gJ3Njcm9sbGJhcic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1pbnVzSG9yaXpvbnRhbCA9ICctaG9yaXpvbnRhbCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1pbnVzVmVydGljYWwgPSAnLXZlcnRpY2FsJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyU2Nyb2xsTGVmdCA9IF9zdHJTY3JvbGwgKyAnTGVmdCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clNjcm9sbFRvcCA9IF9zdHJTY3JvbGwgKyAnVG9wJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTW91c2VUb3VjaERvd25FdmVudCA9ICdtb3VzZWRvd24gdG91Y2hzdGFydCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1vdXNlVG91Y2hVcEV2ZW50ID0gJ21vdXNldXAgdG91Y2hlbmQgdG91Y2hjYW5jZWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJNb3VzZVRvdWNoTW92ZUV2ZW50ID0gJ21vdXNlbW92ZSB0b3VjaG1vdmUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJNb3VzZUVudGVyID0gJ21vdXNlZW50ZXInO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJNb3VzZUxlYXZlID0gJ21vdXNlbGVhdmUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJLZXlEb3duRXZlbnQgPSAna2V5ZG93bic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0cktleVVwRXZlbnQgPSAna2V5dXAnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJTZWxlY3RTdGFydEV2ZW50ID0gJ3NlbGVjdHN0YXJ0JztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyVHJhbnNpdGlvbkVuZEV2ZW50ID0gJ3RyYW5zaXRpb25lbmQgd2Via2l0VHJhbnNpdGlvbkVuZCBvVHJhbnNpdGlvbkVuZCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clJlc2l6ZU9ic2VydmVyUHJvcGVydHkgPSAnX19vdmVybGF5U2Nyb2xsYmFyc1JPX18nO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vY2xhc3MgbmFtZXM6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfY2Fzc05hbWVzUHJlZml4ID0gJ29zLSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhUTUxFbGVtZW50ID0gX2Nhc3NOYW1lc1ByZWZpeCArICdodG1sJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ2hvc3QnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0RWxlbWVudEZvcmVpZ24gPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLWZvcmVpZ24nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0VGV4dGFyZWFFbGVtZW50ID0gX2NsYXNzTmFtZUhvc3RFbGVtZW50ICsgJy10ZXh0YXJlYSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RTY3JvbGxiYXJIb3Jpem9udGFsSGlkZGVuID0gX2NsYXNzTmFtZUhvc3RFbGVtZW50ICsgJy0nICsgX3N0clNjcm9sbGJhciArIF9zdHJNaW51c0hvcml6b250YWwgKyBfc3RyTWludXNIaWRkZW47XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RTY3JvbGxiYXJWZXJ0aWNhbEhpZGRlbiA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctJyArIF9zdHJTY3JvbGxiYXIgKyBfc3RyTWludXNWZXJ0aWNhbCArIF9zdHJNaW51c0hpZGRlbjtcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdFRyYW5zaXRpb24gPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLXRyYW5zaXRpb24nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0UlRMID0gX2NsYXNzTmFtZUhvc3RFbGVtZW50ICsgJy1ydGwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0UmVzaXplRGlzYWJsZWQgPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLXJlc2l6ZS1kaXNhYmxlZCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RTY3JvbGxpbmcgPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLXNjcm9sbGluZyc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RPdmVyZmxvdyA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctb3ZlcmZsb3cnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3cgPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLW92ZXJmbG93JztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdE92ZXJmbG93WCA9IF9jbGFzc05hbWVIb3N0T3ZlcmZsb3cgKyAnLXgnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3dZID0gX2NsYXNzTmFtZUhvc3RPdmVyZmxvdyArICcteSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVRleHRhcmVhRWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAndGV4dGFyZWEnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVUZXh0YXJlYUNvdmVyRWxlbWVudCA9IF9jbGFzc05hbWVUZXh0YXJlYUVsZW1lbnQgKyAnLWNvdmVyJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lUGFkZGluZ0VsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ3BhZGRpbmcnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVWaWV3cG9ydEVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ3ZpZXdwb3J0JztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lVmlld3BvcnROYXRpdmVTY3JvbGxiYXJzSW52aXNpYmxlID0gX2NsYXNzTmFtZVZpZXdwb3J0RWxlbWVudCArICctbmF0aXZlLXNjcm9sbGJhcnMtaW52aXNpYmxlJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lVmlld3BvcnROYXRpdmVTY3JvbGxiYXJzT3ZlcmxhaWQgPSBfY2xhc3NOYW1lVmlld3BvcnRFbGVtZW50ICsgJy1uYXRpdmUtc2Nyb2xsYmFycy1vdmVybGFpZCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUNvbnRlbnRFbGVtZW50ID0gX2Nhc3NOYW1lc1ByZWZpeCArICdjb250ZW50JztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lQ29udGVudEFycmFuZ2VFbGVtZW50ID0gX2Nhc3NOYW1lc1ByZWZpeCArICdjb250ZW50LWFycmFuZ2UnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVDb250ZW50R2x1ZUVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ2NvbnRlbnQtZ2x1ZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50ID0gX2Nhc3NOYW1lc1ByZWZpeCArICdzaXplLWF1dG8tb2JzZXJ2ZXInO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ3Jlc2l6ZS1vYnNlcnZlcic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVySXRlbUVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ3Jlc2l6ZS1vYnNlcnZlci1pdGVtJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJJdGVtRmluYWxFbGVtZW50ID0gX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVySXRlbUVsZW1lbnQgKyAnLWZpbmFsJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lVGV4dEluaGVyaXQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ3RleHQtaW5oZXJpdCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhciA9IF9jYXNzTmFtZXNQcmVmaXggKyBfc3RyU2Nyb2xsYmFyO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJUcmFjayA9IF9jbGFzc05hbWVTY3JvbGxiYXIgKyAnLXRyYWNrJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFyVHJhY2tPZmYgPSBfY2xhc3NOYW1lU2Nyb2xsYmFyVHJhY2sgKyAnLW9mZic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckhhbmRsZSA9IF9jbGFzc05hbWVTY3JvbGxiYXIgKyAnLWhhbmRsZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckhhbmRsZU9mZiA9IF9jbGFzc05hbWVTY3JvbGxiYXJIYW5kbGUgKyAnLW9mZic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhclVudXNhYmxlID0gX2NsYXNzTmFtZVNjcm9sbGJhciArICctdW51c2FibGUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJBdXRvSGlkZGVuID0gX2NsYXNzTmFtZVNjcm9sbGJhciArICctJyArIF9zdHJBdXRvICsgX3N0ck1pbnVzSGlkZGVuO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXIgPSBfY2xhc3NOYW1lU2Nyb2xsYmFyICsgJy1jb3JuZXInO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemUgPSBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyICsgJy1yZXNpemUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemVCID0gX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZSArICctYm90aCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZUggPSBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplICsgX3N0ck1pbnVzSG9yaXpvbnRhbDtcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplViA9IF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemUgKyBfc3RyTWludXNWZXJ0aWNhbDtcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFySG9yaXpvbnRhbCA9IF9jbGFzc05hbWVTY3JvbGxiYXIgKyBfc3RyTWludXNIb3Jpem9udGFsO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJWZXJ0aWNhbCA9IF9jbGFzc05hbWVTY3JvbGxiYXIgKyBfc3RyTWludXNWZXJ0aWNhbDtcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lRHJhZ2dpbmcgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ2RyYWdnaW5nJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lVGhlbWVOb25lID0gX2Nhc3NOYW1lc1ByZWZpeCArICd0aGVtZS1ub25lJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lc0R5bmFtaWNEZXN0cm95ID0gW1xyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVWaWV3cG9ydE5hdGl2ZVNjcm9sbGJhcnNJbnZpc2libGUsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVZpZXdwb3J0TmF0aXZlU2Nyb2xsYmFyc092ZXJsYWlkLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJUcmFja09mZixcclxuICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lU2Nyb2xsYmFySGFuZGxlT2ZmLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJVbnVzYWJsZSxcclxuICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lU2Nyb2xsYmFyQXV0b0hpZGRlbixcclxuICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemVCLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemVILFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemVWLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVEcmFnZ2luZ10uam9pbihfc3RyU3BhY2UpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vY2FsbGJhY2tzOlx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NhbGxiYWNrc0luaXRRZXVldWUgPSBbXTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL2F0dHJzIHZpZXdwb3J0IHNoYWxsIGluaGVyaXQgZnJvbSB0YXJnZXRcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF92aWV3cG9ydEF0dHJzRnJvbVRhcmdldCA9IFtMRVhJQ09OLnRpXTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL29wdGlvbnM6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfZGVmYXVsdE9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2N1cnJlbnRPcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jdXJyZW50UHJlcGFyZWRPcHRpb25zO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vZXh0ZW5zaW9uczpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9leHRlbnNpb25zID0ge307XHJcbiAgICAgICAgICAgICAgICB2YXIgX2V4dGVuc2lvbnNQcml2YXRlTWV0aG9kcyA9ICdhZGRlZCByZW1vdmVkIG9uIGNvbnRyYWN0JztcclxuXHJcbiAgICAgICAgICAgICAgICAvL3VwZGF0ZVx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2xhc3RVcGRhdGVUaW1lO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zd2FsbG93ZWRVcGRhdGVIaW50cyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zd2FsbG93ZWRVcGRhdGVUaW1lb3V0O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zd2FsbG93VXBkYXRlTGFnID0gNDI7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3VwZGF0ZU9uTG9hZEV2ZW50TmFtZSA9ICdsb2FkJztcclxuICAgICAgICAgICAgICAgIHZhciBfdXBkYXRlT25Mb2FkRWxtcyA9IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vRE9NIGVsZW1lbnRzOlx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3dpbmRvd0VsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2RvY3VtZW50RWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfaHRtbEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2JvZHlFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF90YXJnZXRFbGVtZW50OyAgICAgICAgICAgICAgICAgICAgIC8vdGhlIHRhcmdldCBlbGVtZW50IG9mIHRoaXMgT3ZlcmxheVNjcm9sbGJhcnMgb2JqZWN0XHRcclxuICAgICAgICAgICAgICAgIHZhciBfaG9zdEVsZW1lbnQ7ICAgICAgICAgICAgICAgICAgICAgICAvL3RoZSBob3N0IGVsZW1lbnQgb2YgdGhpcyBPdmVybGF5U2Nyb2xsYmFycyBvYmplY3QgLT4gbWF5IGJlIHRoZSBzYW1lIGFzIHRhcmdldEVsZW1lbnRcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9zaXplQXV0b09ic2VydmVyRWxlbWVudDsgICAgICAgICAgIC8vb2JzZXJ2ZXMgc2l6ZSBhdXRvIGNoYW5nZXNcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9zaXplT2JzZXJ2ZXJFbGVtZW50OyAgICAgICAgICAgICAgIC8vb2JzZXJ2ZXMgc2l6ZSBhbmQgcGFkZGluZyBjaGFuZ2VzXHRcclxuICAgICAgICAgICAgICAgIHZhciBfcGFkZGluZ0VsZW1lbnQ7ICAgICAgICAgICAgICAgICAgICAvL21hbmFnZXMgdGhlIHBhZGRpbmdcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF92aWV3cG9ydEVsZW1lbnQ7ICAgICAgICAgICAgICAgICAgIC8vaXMgdGhlIHZpZXdwb3J0IG9mIG91ciBzY3JvbGxiYXIgbW9kZWxcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9jb250ZW50RWxlbWVudDsgICAgICAgICAgICAgICAgICAgIC8vdGhlIGVsZW1lbnQgd2hpY2ggaG9sZHMgdGhlIGNvbnRlbnRcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9jb250ZW50QXJyYW5nZUVsZW1lbnQ7ICAgICAgICAgICAgIC8vaXMgbmVlZGVkIGZvciBjb3JyZWN0IHNpemluZyBvZiB0aGUgY29udGVudCBlbGVtZW50IChvbmx5IGlmIG5hdGl2ZSBzY3JvbGxiYXJzIGFyZSBvdmVybGF5cylcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9jb250ZW50R2x1ZUVsZW1lbnQ7ICAgICAgICAgICAgICAgIC8vaGFzIGFsd2F5cyB0aGUgc2l6ZSBvZiB0aGUgY29udGVudCBlbGVtZW50XHRcclxuICAgICAgICAgICAgICAgIHZhciBfdGV4dGFyZWFDb3ZlckVsZW1lbnQ7ICAgICAgICAgICAgICAvL29ubHkgYXBwbGllZCBpZiB0YXJnZXQgaXMgYSB0ZXh0YXJlYSBlbGVtZW50LiBVc2VkIGZvciBjb3JyZWN0IHNpemUgY2FsY3VsYXRpb24gYW5kIGZvciBwcmV2ZW50aW9uIG9mIHVuY29udHJvbGxlZCBzY3JvbGxpbmdcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJIb3Jpem9udGFsRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFySG9yaXpvbnRhbFRyYWNrRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFySG9yaXpvbnRhbEhhbmRsZUVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhclZlcnRpY2FsRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyVmVydGljYWxUcmFja0VsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhclZlcnRpY2FsSGFuZGxlRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfd2luZG93RWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfZG9jdW1lbnRFbGVtZW50TmF0aXZlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF90YXJnZXRFbGVtZW50TmF0aXZlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9ob3N0RWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3NpemVPYnNlcnZlckVsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3BhZGRpbmdFbGVtZW50TmF0aXZlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF92aWV3cG9ydEVsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRFbGVtZW50TmF0aXZlO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vQ2FjaGU6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfaG9zdFNpemVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfY29udGVudFNjcm9sbFNpemVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfYXJyYW5nZUNvbnRlbnRTaXplQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2hhc092ZXJmbG93Q2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2hpZGVPdmVyZmxvd0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF93aWR0aEF1dG9DYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfaGVpZ2h0QXV0b0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jc3NCb3hTaXppbmdDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfY3NzUGFkZGluZ0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jc3NCb3JkZXJDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfY3NzTWFyZ2luQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Nzc0RpcmVjdGlvbkNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jc3NEaXJlY3Rpb25EZXRlY3RlZENhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9wYWRkaW5nQWJzb2x1dGVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfY2xpcEFsd2F5c0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jb250ZW50R2x1ZVNpemVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfb3ZlcmZsb3dCZWhhdmlvckNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9vdmVyZmxvd0Ftb3VudENhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9pZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2F1dG9VcGRhdGVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2l6ZUF1dG9DYXBhYmxlQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZUNoYW5nZURldGVjdGVkQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2hvc3RFbGVtZW50U2l6ZUNoYW5nZURldGVjdGVkQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNWaXNpYmlsaXR5Q2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNBdXRvSGlkZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQ2xpY2tTY3JvbGxpbmdDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0RyYWdTY3JvbGxpbmdDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzaXplQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX25vcm1hbGl6ZVJUTENhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfb2xkQ2xhc3NOYW1lO1xyXG4gICAgICAgICAgICAgICAgdmFyIF90ZXh0YXJlYUF1dG9XcmFwcGluZ0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF90ZXh0YXJlYUluZm9DYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfdGV4dGFyZWFTaXplQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RleHRhcmVhRHluSGVpZ2h0Q2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RleHRhcmVhRHluV2lkdGhDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfYm9keU1pblNpemVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfdXBkYXRlQXV0b0NhY2hlID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgLy9NdXRhdGlvbk9ic2VydmVyOlx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX211dGF0aW9uT2JzZXJ2ZXJIb3N0O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tdXRhdGlvbk9ic2VydmVyQ29udGVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfbXV0YXRpb25PYnNlcnZlckhvc3RDYWxsYmFjaztcclxuICAgICAgICAgICAgICAgIHZhciBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnRDYWxsYmFjaztcclxuICAgICAgICAgICAgICAgIHZhciBfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX211dGF0aW9uT2JzZXJ2ZXJBdHRyc1RleHRhcmVhID0gWyd3cmFwJywgJ2NvbHMnLCAncm93cyddO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tdXRhdGlvbk9ic2VydmVyQXR0cnNIb3N0ID0gW0xFWElDT04uaSwgTEVYSUNPTi5jLCBMRVhJQ09OLnMsICdvcGVuJ10uY29uY2F0KF92aWV3cG9ydEF0dHJzRnJvbVRhcmdldCk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9ldmVudHM6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfZGVzdHJveUV2ZW50cyA9IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vdGV4dGFyZWE6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfdGV4dGFyZWFIYXNGb2N1cztcclxuXHJcbiAgICAgICAgICAgICAgICAvL3Njcm9sbGJhcnM6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0F1dG9IaWRlVGltZW91dElkO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlVGltZW91dElkO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVEZWxheTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0F1dG9IaWRlTmV2ZXI7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbDtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0F1dG9IaWRlTGVhdmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNIYW5kbGVIb3ZlcmVkO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzSGFuZGxlc0RlZmluZVNjcm9sbFBvcztcclxuXHJcbiAgICAgICAgICAgICAgICAvL3Jlc2l6ZVx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Jlc2l6ZU5vbmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Jlc2l6ZUJvdGg7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Jlc2l6ZUhvcml6b250YWw7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Jlc2l6ZVZlcnRpY2FsO1xyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gRXZlbnQgTGlzdGVuZXIgPT09PS8vXHRcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcdFxyXG4gICAgICAgICAgICAgICAgICogQWRkcyBvciByZW1vdmVzIGEgZXZlbnQgbGlzdGVuZXIgZnJvbSB0aGUgZ2l2ZW4gZWxlbWVudC4gXHRcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBlbGVtZW50IFRoZSBlbGVtZW50IHRvIHdoaWNoIHRoZSBldmVudCBsaXN0ZW5lciBzaGFsbCBiZSBhcHBsaWVkIG9yIHJlbW92ZWQuXHRcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBldmVudE5hbWVzIFRoZSBuYW1lKHMpIG9mIHRoZSBldmVudHMuXHRcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBsaXN0ZW5lciBUaGUgbWV0aG9kIHdoaWNoIHNoYWxsIGJlIGNhbGxlZC5cdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHJlbW92ZSBUcnVlIGlmIHRoZSBoYW5kbGVyIHNoYWxsIGJlIHJlbW92ZWQsIGZhbHNlIG9yIHVuZGVmaW5lZCBpZiB0aGUgaGFuZGxlciBzaGFsbCBiZSBhZGRlZC5cdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHBhc3NpdmVPck9wdGlvbnMgVGhlIG9wdGlvbnMgZm9yIHRoZSBldmVudC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihlbGVtZW50LCBldmVudE5hbWVzLCBsaXN0ZW5lciwgcmVtb3ZlLCBwYXNzaXZlT3JPcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbGxlY3RlZCA9IENPTVBBVElCSUxJVFkuaXNBKGV2ZW50TmFtZXMpICYmIENPTVBBVElCSUxJVFkuaXNBKGxpc3RlbmVyKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbWV0aG9kID0gcmVtb3ZlID8gJ3JlbW92ZUV2ZW50TGlzdGVuZXInIDogJ2FkZEV2ZW50TGlzdGVuZXInO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvbk9mZiA9IHJlbW92ZSA/ICdvZmYnIDogJ29uJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnRzID0gY29sbGVjdGVkID8gZmFsc2UgOiBldmVudE5hbWVzLnNwbGl0KF9zdHJTcGFjZSlcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXNzaXZlT3JPcHRpb25zSXNPYmogPSBGUkFNRVdPUksuaXNQbGFpbk9iamVjdChwYXNzaXZlT3JPcHRpb25zKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFzc2l2ZSA9IChfc3VwcG9ydFBhc3NpdmVFdmVudHMgJiYgKHBhc3NpdmVPck9wdGlvbnNJc09iaiA/IChwYXNzaXZlT3JPcHRpb25zLl9wYXNzaXZlKSA6IHBhc3NpdmVPck9wdGlvbnMpKSB8fCBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2FwdHVyZSA9IHBhc3NpdmVPck9wdGlvbnNJc09iaiAmJiAocGFzc2l2ZU9yT3B0aW9ucy5fY2FwdHVyZSB8fCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5hdGl2ZVBhcmFtID0gX3N1cHBvcnRQYXNzaXZlRXZlbnRzID8ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXNzaXZlOiBwYXNzaXZlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXB0dXJlOiBjYXB0dXJlLFxyXG4gICAgICAgICAgICAgICAgICAgIH0gOiBjYXB0dXJlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY29sbGVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgZXZlbnROYW1lc1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKGVsZW1lbnQsIGV2ZW50TmFtZXNbaV0sIGxpc3RlbmVyW2ldLCByZW1vdmUsIHBhc3NpdmVPck9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBldmVudHNbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihfc3VwcG9ydFBhc3NpdmVFdmVudHMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50WzBdW21ldGhvZF0oZXZlbnRzW2ldLCBsaXN0ZW5lciwgbmF0aXZlUGFyYW0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFtvbk9mZl0oZXZlbnRzW2ldLCBsaXN0ZW5lcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIoZWxlbWVudCwgZXZlbnROYW1lcywgbGlzdGVuZXIsIHBhc3NpdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKGVsZW1lbnQsIGV2ZW50TmFtZXMsIGxpc3RlbmVyLCBmYWxzZSwgcGFzc2l2ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2Rlc3Ryb3lFdmVudHMucHVzaChDT01QQVRJQklMSVRZLmJpbmQoc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lciwgMCwgZWxlbWVudCwgZXZlbnROYW1lcywgbGlzdGVuZXIsIHRydWUsIHBhc3NpdmUpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gUmVzaXplIE9ic2VydmVyID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQWRkcyBvciByZW1vdmVzIGEgcmVzaXplIG9ic2VydmVyIGZyb20gdGhlIGdpdmVuIGVsZW1lbnQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0RWxlbWVudCBUaGUgZWxlbWVudCB0byB3aGljaCB0aGUgcmVzaXplIG9ic2VydmVyIHNoYWxsIGJlIGFkZGVkIG9yIHJlbW92ZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gb25FbGVtZW50UmVzaXplZENhbGxiYWNrIFRoZSBjYWxsYmFjayB3aGljaCBpcyBmaXJlZCBldmVyeSB0aW1lIHRoZSByZXNpemUgb2JzZXJ2ZXIgcmVnaXN0ZXJzIGEgc2l6ZSBjaGFuZ2Ugb3IgZmFsc2UgLyB1bmRlZmluZWQgaWYgdGhlIHJlc2l6ZU9ic2VydmVyIHNoYWxsIGJlIHJlbW92ZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldHVwUmVzaXplT2JzZXJ2ZXIodGFyZ2V0RWxlbWVudCwgb25FbGVtZW50UmVzaXplZENhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc2l6ZU9ic2VydmVyID0gQ09NUEFUSUJJTElUWS5yTygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQW5pbWF0aW9uU3RhcnRFdmVudCA9ICdhbmltYXRpb25zdGFydCBtb3pBbmltYXRpb25TdGFydCB3ZWJraXRBbmltYXRpb25TdGFydCBNU0FuaW1hdGlvblN0YXJ0JztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckNoaWxkTm9kZXMgPSAnY2hpbGROb2Rlcyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb25zdFNjcm9sbCA9IDMzMzMzMzM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnRbX3N0clNjcm9sbFRvcF0oY29uc3RTY3JvbGwpW19zdHJTY3JvbGxMZWZ0XShfaXNSVEwgPyBfcnRsU2Nyb2xsQmVoYXZpb3IubiA/IC1jb25zdFNjcm9sbCA6IF9ydGxTY3JvbGxCZWhhdmlvci5pID8gMCA6IGNvbnN0U2Nyb2xsIDogY29uc3RTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25FbGVtZW50UmVzaXplZENhbGxiYWNrKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYWRkIHJlc2l6ZSBvYnNlcnZlcjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9uRWxlbWVudFJlc2l6ZWRDYWxsYmFjaykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zdXBwb3J0UmVzaXplT2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudCA9IHRhcmdldEVsZW1lbnQuYWRkQ2xhc3MoJ29ic2VydmVkJykuYXBwZW5kKGdlbmVyYXRlRGl2KF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckVsZW1lbnQpKS5jb250ZW50cygpWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvYnNlcnZlciA9IGVsZW1lbnRbX3N0clJlc2l6ZU9ic2VydmVyUHJvcGVydHldID0gbmV3IHJlc2l6ZU9ic2VydmVyKGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vYnNlcnZlKGVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9tc2llVmVyc2lvbiA+IDkgfHwgIV9hdXRvVXBkYXRlUmVjb21tZW5kZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5wcmVwZW5kKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZURpdih7IGM6IF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckl0ZW1FbGVtZW50LCBkaXI6ICdsdHInIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRlRGl2KF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckl0ZW1FbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVySXRlbUZpbmFsRWxlbWVudClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRlRGl2KF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckl0ZW1FbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGVEaXYoeyBjOiBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJJdGVtRmluYWxFbGVtZW50LCBzdHlsZTogJ3dpZHRoOiAyMDAlOyBoZWlnaHQ6IDIwMCUnIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2JzZXJ2ZXJFbGVtZW50ID0gdGFyZ2V0RWxlbWVudFswXVtzdHJDaGlsZE5vZGVzXVswXVtzdHJDaGlsZE5vZGVzXVswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNocmlua0VsZW1lbnQgPSBGUkFNRVdPUksob2JzZXJ2ZXJFbGVtZW50W3N0ckNoaWxkTm9kZXNdWzFdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGV4cGFuZEVsZW1lbnQgPSBGUkFNRVdPUksob2JzZXJ2ZXJFbGVtZW50W3N0ckNoaWxkTm9kZXNdWzBdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGV4cGFuZEVsZW1lbnRDaGlsZCA9IEZSQU1FV09SSyhleHBhbmRFbGVtZW50WzBdW3N0ckNoaWxkTm9kZXNdWzBdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHdpZHRoQ2FjaGUgPSBvYnNlcnZlckVsZW1lbnRbTEVYSUNPTi5vV107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoZWlnaHRDYWNoZSA9IG9ic2VydmVyRWxlbWVudFtMRVhJQ09OLm9IXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzRGlydHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByQUZJZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJIZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmYWN0b3IgPSAyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmF0aXZlU2Nyb2xsYmFyU2l6ZSA9IGdsb2JhbHMubmF0aXZlU2Nyb2xsYmFyU2l6ZTsgLy9jYXJlIGRvbid0IG1ha2UgY2hhbmdlcyB0byB0aGlzIG9iamVjdCEhIVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzZXQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzaXplUmVzZXRXaWR0aCA9IG9ic2VydmVyRWxlbWVudFtMRVhJQ09OLm9XXSArIG5hdGl2ZVNjcm9sbGJhclNpemUueCAqIGZhY3RvciArIG5hdGl2ZVNjcm9sbGJhclNpemUueSAqIGZhY3RvciArIF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplLnggKyBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZS55O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzaXplUmVzZXRIZWlnaHQgPSBvYnNlcnZlckVsZW1lbnRbTEVYSUNPTi5vSF0gKyBuYXRpdmVTY3JvbGxiYXJTaXplLnggKiBmYWN0b3IgKyBuYXRpdmVTY3JvbGxiYXJTaXplLnkgKiBmYWN0b3IgKyBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZS54ICsgX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemUueTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXhwYW5kQ2hpbGRDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRDaGlsZENTU1tfc3RyV2lkdGhdID0gc2l6ZVJlc2V0V2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwYW5kQ2hpbGRDU1NbX3N0ckhlaWdodF0gPSBzaXplUmVzZXRIZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwYW5kRWxlbWVudENoaWxkLmNzcyhleHBhbmRDaGlsZENTUyk7XHJcblxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XShzaXplUmVzZXRXaWR0aClbX3N0clNjcm9sbFRvcF0oc2l6ZVJlc2V0SGVpZ2h0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaHJpbmtFbGVtZW50W19zdHJTY3JvbGxMZWZ0XShzaXplUmVzZXRXaWR0aClbX3N0clNjcm9sbFRvcF0oc2l6ZVJlc2V0SGVpZ2h0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwYW5kRWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oY29uc3RTY3JvbGwpW19zdHJTY3JvbGxUb3BdKGNvbnN0U2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNocmlua0VsZW1lbnRbX3N0clNjcm9sbExlZnRdKGNvbnN0U2Nyb2xsKVtfc3RyU2Nyb2xsVG9wXShjb25zdFNjcm9sbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvblJlc2l6ZWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByQUZJZCA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzRGlydHkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoQ2FjaGUgPSBjdXJyV2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHRDYWNoZSA9IGN1cnJIZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgb25TY3JvbGwgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJXaWR0aCA9IG9ic2VydmVyRWxlbWVudFtMRVhJQ09OLm9XXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJIZWlnaHQgPSBvYnNlcnZlckVsZW1lbnRbTEVYSUNPTi5vSF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0RpcnR5ID0gY3VycldpZHRoICE9IHdpZHRoQ2FjaGUgfHwgY3VyckhlaWdodCAhPSBoZWlnaHRDYWNoZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQgJiYgaXNEaXJ0eSAmJiAhckFGSWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLmNBRigpKHJBRklkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByQUZJZCA9IENPTVBBVElCSUxJVFkuckFGKCkob25SZXNpemVkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFldmVudClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvblJlc2l6ZWQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNldCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5wcnZEKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnN0cFAoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXhwYW5kQ2hpbGRDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9ic2VydmVyRWxlbWVudENTUyA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VG9wUmlnaHRCb3R0b21MZWZ0KG9ic2VydmVyRWxlbWVudENTUywgX3N0ckVtcHR5LCBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtKChuYXRpdmVTY3JvbGxiYXJTaXplLnkgKyAxKSAqIGZhY3RvciksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVTY3JvbGxiYXJTaXplLnggKiAtZmFjdG9yLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlU2Nyb2xsYmFyU2l6ZS55ICogLWZhY3RvcixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0oKG5hdGl2ZVNjcm9sbGJhclNpemUueCArIDEpICogZmFjdG9yKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSyhvYnNlcnZlckVsZW1lbnQpLmNzcyhvYnNlcnZlckVsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRFbGVtZW50Lm9uKF9zdHJTY3JvbGwsIG9uU2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hyaW5rRWxlbWVudC5vbihfc3RyU2Nyb2xsLCBvblNjcm9sbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQub24oc3RyQW5pbWF0aW9uU3RhcnRFdmVudCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25TY3JvbGwoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9sZXRzIGFzc3VtZSB0aGF0IHRoZSBkaXZzIHdpbGwgbmV2ZXIgYmUgdGhhdCBsYXJnZSBhbmQgYSBjb25zdGFudCB2YWx1ZSBpcyBlbm91Z2hcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwYW5kQ2hpbGRDU1NbX3N0cldpZHRoXSA9IGNvbnN0U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRDaGlsZENTU1tfc3RySGVpZ2h0XSA9IGNvbnN0U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRFbGVtZW50Q2hpbGQuY3NzKGV4cGFuZENoaWxkQ1NTKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXR0YWNoRXZlbnQgPSBfZG9jdW1lbnRFbGVtZW50TmF0aXZlLmF0dGFjaEV2ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNJRSA9IF9tc2llVmVyc2lvbiAhPT0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0YWNoRXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQucHJlcGVuZChnZW5lcmF0ZURpdihfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJFbGVtZW50KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5kRmlyc3QodGFyZ2V0RWxlbWVudCwgX3N0ckRvdCArIF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckVsZW1lbnQpWzBdLmF0dGFjaEV2ZW50KCdvbnJlc2l6ZScsIGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvYmogPSBfZG9jdW1lbnRFbGVtZW50TmF0aXZlLmNyZWF0ZUVsZW1lbnQoVFlQRVMubyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouc2V0QXR0cmlidXRlKExFWElDT04udGksICctMScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnNldEF0dHJpYnV0ZShMRVhJQ09OLmMsIF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd25kID0gdGhpcy5jb250ZW50RG9jdW1lbnQuZGVmYXVsdFZpZXc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd25kLmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3bmQuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnR5cGUgPSAndGV4dC9odG1sJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0lFKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQucHJlcGVuZChvYmopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmRhdGEgPSAnYWJvdXQ6YmxhbmsnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0lFKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQucHJlcGVuZChvYmopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5vbihzdHJBbmltYXRpb25TdGFydEV2ZW50LCBjYWxsYmFjayk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldEVsZW1lbnRbMF0gPT09IF9zaXplT2JzZXJ2ZXJFbGVtZW50TmF0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRpcmVjdGlvbkNoYW5nZWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkaXIgPSBfaG9zdEVsZW1lbnQuY3NzKCdkaXJlY3Rpb24nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNzcyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsTGVmdFZhbHVlID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlyICE9PSBfY3NzRGlyZWN0aW9uRGV0ZWN0ZWRDYWNoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRpciA9PT0gJ2x0cicpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ckxlZnRdID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0clJpZ2h0XSA9IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbExlZnRWYWx1ZSA9IGNvbnN0U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJMZWZ0XSA9IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyUmlnaHRdID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxMZWZ0VmFsdWUgPSBfcnRsU2Nyb2xsQmVoYXZpb3IubiA/IC1jb25zdFNjcm9sbCA6IF9ydGxTY3JvbGxCZWhhdmlvci5pID8gMCA6IGNvbnN0U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9leGVjdXRpb24gb3JkZXIgaXMgaW1wb3J0YW50IGZvciBJRSEhIVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVPYnNlcnZlckVsZW1lbnQuY2hpbGRyZW4oKS5lcSgwKS5jc3MoY3NzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplT2JzZXJ2ZXJFbGVtZW50W19zdHJTY3JvbGxMZWZ0XShzY3JvbGxMZWZ0VmFsdWUpW19zdHJTY3JvbGxUb3BdKGNvbnN0U2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jc3NEaXJlY3Rpb25EZXRlY3RlZENhY2hlID0gZGlyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKHRhcmdldEVsZW1lbnQsIF9zdHJTY3JvbGwsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlyZWN0aW9uQ2hhbmdlZCgpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuc3RwUChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSByZXNpemUgb2JzZXJ2ZXI6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zdXBwb3J0UmVzaXplT2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudCA9IHRhcmdldEVsZW1lbnQuY29udGVudHMoKVswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzaXplT2JzZXJ2ZXJPYmogPSBlbGVtZW50W19zdHJSZXNpemVPYnNlcnZlclByb3BlcnR5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzaXplT2JzZXJ2ZXJPYmopIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzaXplT2JzZXJ2ZXJPYmouZGlzY29ubmVjdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgZWxlbWVudFtfc3RyUmVzaXplT2JzZXJ2ZXJQcm9wZXJ0eV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKHRhcmdldEVsZW1lbnQuY2hpbGRyZW4oX3N0ckRvdCArIF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckVsZW1lbnQpLmVxKDApKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEZyZWV6ZXMgb3IgdW5mcmVlemVzIHRoZSBnaXZlbiByZXNpemUgb2JzZXJ2ZXIuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0RWxlbWVudCBUaGUgZWxlbWVudCB0byB3aGljaCB0aGUgdGFyZ2V0IHJlc2l6ZSBvYnNlcnZlciBpcyBhcHBsaWVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGZyZWV6ZSBUcnVlIGlmIHRoZSByZXNpemUgb2JzZXJ2ZXIgc2hhbGwgYmUgZnJvemVuLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBmcmVlemVSZXNpemVPYnNlcnZlcih0YXJnZXRFbGVtZW50LCBmcmVlemUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0RWxlbWVudCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGZyZWV6ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zdXBwb3J0UmVzaXplT2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudCA9IHRhcmdldEVsZW1lbnQuY29udGVudHMoKVswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50W19zdHJSZXNpemVPYnNlcnZlclByb3BlcnR5XS51bm9ic2VydmUoZWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50ID0gdGFyZ2V0RWxlbWVudC5jaGlsZHJlbihfc3RyRG90ICsgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCkuZXEoMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHcgPSB0YXJnZXRFbGVtZW50LmNzcyhfc3RyV2lkdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoID0gdGFyZ2V0RWxlbWVudC5jc3MoX3N0ckhlaWdodCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNzcyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyV2lkdGhdID0gdztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ckhlaWdodF0gPSBoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQuY3NzKGNzcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRSZXNpemVPYnNlcnZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gdGFyZ2V0RWxlbWVudC5jb250ZW50cygpWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRbX3N0clJlc2l6ZU9ic2VydmVyUHJvcGVydHldLm9ic2VydmUoZWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3NzID0geyB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RySGVpZ2h0XSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0cldpZHRoXSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50LmNoaWxkcmVuKF9zdHJEb3QgKyBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJFbGVtZW50KS5lcSgwKS5jc3MoY3NzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICovXHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBNdXRhdGlvbiBPYnNlcnZlcnMgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDcmVhdGVzIE11dGF0aW9uT2JzZXJ2ZXJzIGZvciB0aGUgaG9zdCBhbmQgY29udGVudCBFbGVtZW50IGlmIHRoZXkgYXJlIHN1cHBvcnRlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gY3JlYXRlTXV0YXRpb25PYnNlcnZlcnMoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9zdXBwb3J0TXV0YXRpb25PYnNlcnZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXV0YXRpb25PYnNlcnZlckNvbnRlbnRMYWcgPSAxMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uT2JzZXJ2ZXIgPSBDT01QQVRJQklMSVRZLm1PKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50TGFzdFVwZGF0ZSA9IENPTVBBVElCSUxJVFkubm93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtdXRhdGlvblRhcmdldDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uQXR0ck5hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtdXRhdGlvbklzQ2xhc3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvbGRNdXRhdGlvblZhbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld0NsYXNzVmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdENsYXNzTmFtZVJlZ2V4O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudFRpbWVvdXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub3c7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzaXplQXV0bztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFjdGlvbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9tdXRhdGlvbk9ic2VydmVySG9zdENhbGxiYWNrID0gZnVuY3Rpb24gKG11dGF0aW9ucykge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkb1VwZGF0ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRvVXBkYXRlRm9yY2UgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtdXRhdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtdXRhdGVkQXR0cnMgPSBbXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2luaXRpYWxpemVkICYmICFfc2xlZXBpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYWNoKG11dGF0aW9ucywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGlvbiA9IHRoaXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0aW9uVGFyZ2V0ID0gbXV0YXRpb24udGFyZ2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGlvbkF0dHJOYW1lID0gbXV0YXRpb24uYXR0cmlidXRlTmFtZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRpb25Jc0NsYXNzID0gbXV0YXRpb25BdHRyTmFtZSA9PT0gTEVYSUNPTi5jO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRNdXRhdGlvblZhbCA9IG11dGF0aW9uLm9sZFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdDbGFzc1ZhbCA9IG11dGF0aW9uVGFyZ2V0LmNsYXNzTmFtZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZG9tRXhpc3RzICYmIG11dGF0aW9uSXNDbGFzcyAmJiAhZG9VcGRhdGVGb3JjZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgb2xkIGNsYXNzIHZhbHVlIGNvbnRhaW5zIF9jbGFzc05hbWVIb3N0RWxlbWVudEZvcmVpZ24gYW5kIG5ldyBjbGFzcyB2YWx1ZSBkb2Vzbid0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob2xkTXV0YXRpb25WYWwuaW5kZXhPZihfY2xhc3NOYW1lSG9zdEVsZW1lbnRGb3JlaWduKSA+IC0xICYmIG5ld0NsYXNzVmFsLmluZGV4T2YoX2NsYXNzTmFtZUhvc3RFbGVtZW50Rm9yZWlnbikgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zdENsYXNzTmFtZVJlZ2V4ID0gY3JlYXRlSG9zdENsYXNzTmFtZVJlZ0V4cCh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnROYXRpdmUuY2xhc3NOYW1lID0gbmV3Q2xhc3NWYWwuc3BsaXQoX3N0clNwYWNlKS5jb25jYXQob2xkTXV0YXRpb25WYWwuc3BsaXQoX3N0clNwYWNlKS5maWx0ZXIoZnVuY3Rpb24gKG5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hbWUubWF0Y2goaG9zdENsYXNzTmFtZVJlZ2V4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSkuam9pbihfc3RyU3BhY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvVXBkYXRlID0gZG9VcGRhdGVGb3JjZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZG9VcGRhdGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvVXBkYXRlID0gbXV0YXRpb25Jc0NsYXNzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBob3N0Q2xhc3NOYW1lc0NoYW5nZWQob2xkTXV0YXRpb25WYWwsIG5ld0NsYXNzVmFsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbXV0YXRpb25BdHRyTmFtZSA9PT0gTEVYSUNPTi5zXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gb2xkTXV0YXRpb25WYWwgIT09IG11dGF0aW9uVGFyZ2V0W0xFWElDT04uc10uY3NzVGV4dFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZWRBdHRycy5wdXNoKG11dGF0aW9uQXR0ck5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVWaWV3cG9ydEF0dHJzRnJvbVRhcmdldChtdXRhdGVkQXR0cnMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9VcGRhdGUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9iYXNlLnVwZGF0ZShkb1VwZGF0ZUZvcmNlIHx8IF9zdHJBdXRvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkb1VwZGF0ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX211dGF0aW9uT2JzZXJ2ZXJDb250ZW50Q2FsbGJhY2sgPSBmdW5jdGlvbiAobXV0YXRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZG9VcGRhdGUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtdXRhdGlvbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2luaXRpYWxpemVkICYmICFfc2xlZXBpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYWNoKG11dGF0aW9ucywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGlvbiA9IHRoaXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvVXBkYXRlID0gaXNVbmtub3duTXV0YXRpb24obXV0YXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIWRvVXBkYXRlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9VcGRhdGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm93ID0gQ09NUEFUSUJJTElUWS5ub3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZUF1dG8gPSAoX2hlaWdodEF1dG9DYWNoZSB8fCBfd2lkdGhBdXRvQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb24gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9kZXN0cm95ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50TGFzdFVwZGF0ZSA9IG5vdztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiBjb2xzLCByb3dzIG9yIHdyYXAgYXR0ciB3YXMgY2hhbmdlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWFVcGRhdGUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNpemVBdXRvKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9iYXNlLnVwZGF0ZShfc3RyQXV0byk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChjb250ZW50VGltZW91dCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtdXRhdGlvbk9ic2VydmVyQ29udGVudExhZyA8PSAwIHx8IG5vdyAtIGNvbnRlbnRMYXN0VXBkYXRlID4gbXV0YXRpb25PYnNlcnZlckNvbnRlbnRMYWcgfHwgIXNpemVBdXRvKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRUaW1lb3V0ID0gc2V0VGltZW91dChhY3Rpb24sIG11dGF0aW9uT2JzZXJ2ZXJDb250ZW50TGFnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9VcGRhdGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9tdXRhdGlvbk9ic2VydmVySG9zdCA9IG5ldyBtdXRhdGlvbk9ic2VydmVyKF9tdXRhdGlvbk9ic2VydmVySG9zdENhbGxiYWNrKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX211dGF0aW9uT2JzZXJ2ZXJDb250ZW50ID0gbmV3IG11dGF0aW9uT2JzZXJ2ZXIoX211dGF0aW9uT2JzZXJ2ZXJDb250ZW50Q2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENvbm5lY3RzIHRoZSBNdXRhdGlvbk9ic2VydmVycyBpZiB0aGV5IGFyZSBzdXBwb3J0ZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGNvbm5lY3RNdXRhdGlvbk9ic2VydmVycygpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRNdXRhdGlvbk9ic2VydmVyICYmICFfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX211dGF0aW9uT2JzZXJ2ZXJIb3N0Lm9ic2VydmUoX2hvc3RFbGVtZW50TmF0aXZlLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlT2xkVmFsdWU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVGaWx0ZXI6IF9tdXRhdGlvbk9ic2VydmVyQXR0cnNIb3N0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX211dGF0aW9uT2JzZXJ2ZXJDb250ZW50Lm9ic2VydmUoX2lzVGV4dGFyZWEgPyBfdGFyZ2V0RWxlbWVudE5hdGl2ZSA6IF9jb250ZW50RWxlbWVudE5hdGl2ZSwge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZU9sZFZhbHVlOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VidHJlZTogIV9pc1RleHRhcmVhLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRMaXN0OiAhX2lzVGV4dGFyZWEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyYWN0ZXJEYXRhOiAhX2lzVGV4dGFyZWEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVGaWx0ZXI6IF9pc1RleHRhcmVhID8gX211dGF0aW9uT2JzZXJ2ZXJBdHRyc1RleHRhcmVhIDogX211dGF0aW9uT2JzZXJ2ZXJBdHRyc0hvc3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIERpc2Nvbm5lY3RzIHRoZSBNdXRhdGlvbk9ic2VydmVycyBpZiB0aGV5IGFyZSBzdXBwb3J0ZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRpc2Nvbm5lY3RNdXRhdGlvbk9ic2VydmVycygpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRNdXRhdGlvbk9ic2VydmVyICYmIF9tdXRhdGlvbk9ic2VydmVyc0Nvbm5lY3RlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckhvc3QuZGlzY29ubmVjdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnQuZGlzY29ubmVjdCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gRXZlbnRzIG9mIGVsZW1lbnRzID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVGhpcyBtZXRob2QgZ2V0cyBjYWxsZWQgZXZlcnkgdGltZSB0aGUgaG9zdCBlbGVtZW50IGdldHMgcmVzaXplZC4gSU1QT1JUQU5UOiBQYWRkaW5nIGNoYW5nZXMgYXJlIGRldGVjdGVkIHRvbyEhXHJcbiAgICAgICAgICAgICAgICAgKiBJdCByZWZyZXNoZXMgdGhlIGhvc3RSZXNpemVkRXZlbnRBcmdzIGFuZCB0aGUgaG9zdFNpemVSZXNpemVDYWNoZS5cclxuICAgICAgICAgICAgICAgICAqIElmIHRoZXJlIGFyZSBhbnkgc2l6ZSBjaGFuZ2VzLCB0aGUgdXBkYXRlIG1ldGhvZCBnZXRzIGNhbGxlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gaG9zdE9uUmVzaXplZCgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIV9zbGVlcGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hhbmdlZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhvc3RTaXplID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogX3NpemVPYnNlcnZlckVsZW1lbnROYXRpdmVbTEVYSUNPTi5zV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBfc2l6ZU9ic2VydmVyRWxlbWVudE5hdGl2ZVtMRVhJQ09OLnNIXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlZCA9IGNoZWNrQ2FjaGUoaG9zdFNpemUsIF9ob3N0RWxlbWVudFNpemVDaGFuZ2VEZXRlY3RlZENhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50U2l6ZUNoYW5nZURldGVjdGVkQ2FjaGUgPSBob3N0U2l6ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoYW5nZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoeyBfaG9zdFNpemVDaGFuZ2VkOiB0cnVlIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFRoZSBtb3VzZSBlbnRlciBldmVudCBvZiB0aGUgaG9zdCBlbGVtZW50LiBUaGlzIGV2ZW50IGlzIG9ubHkgbmVlZGVkIGZvciB0aGUgYXV0b0hpZGUgZmVhdHVyZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gaG9zdE9uTW91c2VFbnRlcigpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZUxlYXZlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc0F1dG9IaWRlKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVGhlIG1vdXNlIGxlYXZlIGV2ZW50IG9mIHRoZSBob3N0IGVsZW1lbnQuIFRoaXMgZXZlbnQgaXMgb25seSBuZWVkZWQgZm9yIHRoZSBhdXRvSGlkZSBmZWF0dXJlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBob3N0T25Nb3VzZUxlYXZlKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlTGVhdmUgJiYgIV9ib2R5RWxlbWVudC5oYXNDbGFzcyhfY2xhc3NOYW1lRHJhZ2dpbmcpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc0F1dG9IaWRlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFRoZSBtb3VzZSBtb3ZlIGV2ZW50IG9mIHRoZSBob3N0IGVsZW1lbnQuIFRoaXMgZXZlbnQgaXMgb25seSBuZWVkZWQgZm9yIHRoZSBhdXRvSGlkZSBcIm1vdmVcIiBmZWF0dXJlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBob3N0T25Nb3VzZU1vdmUoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZVRpbWVvdXRJZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlVGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUgJiYgIV9kZXN0cm95ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIDEwMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUHJldmVudHMgdGV4dCBmcm9tIGRlc2VsZWN0aW9uIGlmIGF0dGFjaGVkIHRvIHRoZSBkb2N1bWVudCBlbGVtZW50IG9uIHRoZSBtb3VzZWRvd24gZXZlbnQgb2YgYSBET00gZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBldmVudCBUaGUgc2VsZWN0IHN0YXJ0IGV2ZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudE9uU2VsZWN0U3RhcnQoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnBydkQoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcdFxyXG4gICAgICAgICAgICAgICAgICogQSBjYWxsYmFjayB3aGljaCB3aWxsIGJlIGNhbGxlZCBhZnRlciBhIGVsZW1lbnQgaGFzIGxvYWRlZC5cdFxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiB1cGRhdGVPbkxvYWRDYWxsYmFjayhldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbG0gPSBGUkFNRVdPUksoZXZlbnQudGFyZ2V0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZWFjaFVwZGF0ZU9uTG9hZChmdW5jdGlvbiAoaSwgdXBkYXRlT25Mb2FkU2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsbS5pcyh1cGRhdGVPbkxvYWRTZWxlY3RvcikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZSh7IF9jb250ZW50U2l6ZUNoYW5nZWQ6IHRydWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICogQWRkcyBvciByZW1vdmVzIG1vdXNlICYgdG91Y2ggZXZlbnRzIG9mIHRoZSBob3N0IGVsZW1lbnQuIChmb3IgaGFuZGxpbmcgYXV0by1oaWRpbmcgb2YgdGhlIHNjcm9sbGJhcnMpXHJcbiAgICAgICAgICAgICAgICAqIEBwYXJhbSBkZXN0cm95IEluZGljYXRlcyB3aGV0aGVyIHRoZSBldmVudHMgc2hhbGwgYmUgYWRkZWQgb3IgcmVtb3ZlZC5cclxuICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXR1cEhvc3RNb3VzZVRvdWNoRXZlbnRzKGRlc3Ryb3kpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWRlc3Ryb3kpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwSG9zdE1vdXNlVG91Y2hFdmVudHModHJ1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoX2hvc3RFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTW91c2VUb3VjaE1vdmVFdmVudC5zcGxpdChfc3RyU3BhY2UpWzBdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBob3N0T25Nb3VzZU1vdmUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICghX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUgfHwgZGVzdHJveSksIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoX2hvc3RFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbX3N0ck1vdXNlRW50ZXIsIF9zdHJNb3VzZUxlYXZlXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgW2hvc3RPbk1vdXNlRW50ZXIsIGhvc3RPbk1vdXNlTGVhdmVdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoIV9zY3JvbGxiYXJzQXV0b0hpZGVMZWF2ZSB8fCBkZXN0cm95KSwgdHJ1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vaWYgdGhlIHBsdWdpbiBpcyBpbml0aWFsaXplZCBhbmQgdGhlIG1vdXNlIGlzIG92ZXIgdGhlIGhvc3QgZWxlbWVudCwgbWFrZSB0aGUgc2Nyb2xsYmFycyB2aXNpYmxlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFfaW5pdGlhbGl6ZWQgJiYgIWRlc3Ryb3kpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudC5vbmUoJ21vdXNlb3ZlcicsIGhvc3RPbk1vdXNlRW50ZXIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gVXBkYXRlIERldGVjdGlvbiA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIE1lYXN1cmVzIHRoZSBtaW4gd2lkdGggYW5kIG1pbiBoZWlnaHQgb2YgdGhlIGJvZHkgZWxlbWVudCBhbmQgcmVmcmVzaGVzIHRoZSByZWxhdGVkIGNhY2hlLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIG1pbiB3aWR0aCBvciBtaW4gaGVpZ2h0IGhhcyBjaGFuZ2VkLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGJvZHlNaW5TaXplQ2hhbmdlZCgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYm9keU1pblNpemUgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSAmJiBfY29udGVudEFycmFuZ2VFbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHlNaW5TaXplLncgPSBwYXJzZVRvWmVyb09yTnVtYmVyKF9jb250ZW50QXJyYW5nZUVsZW1lbnQuY3NzKF9zdHJNaW5NaW51cyArIF9zdHJXaWR0aCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5TWluU2l6ZS5oID0gcGFyc2VUb1plcm9Pck51bWJlcihfY29udGVudEFycmFuZ2VFbGVtZW50LmNzcyhfc3RyTWluTWludXMgKyBfc3RySGVpZ2h0KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHlNaW5TaXplLmMgPSBjaGVja0NhY2hlKGJvZHlNaW5TaXplLCBfYm9keU1pblNpemVDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHlNaW5TaXplLmYgPSB0cnVlOyAvL2ZsYWcgZm9yIFwibWVhc3VyZWQgYXQgbGVhc3Qgb25jZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIF9ib2R5TWluU2l6ZUNhY2hlID0gYm9keU1pblNpemU7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICEhYm9keU1pblNpemUuYztcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY2xhc3MgbmFtZXMgcmVhbGx5IGNoYW5nZWQgKG5ldyBjbGFzcyB3aXRob3V0IHBsdWdpbiBob3N0IHByZWZpeClcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBvbGRDbGFzc05hbWVzIFRoZSBvbGQgQ2xhc3NOYW1lIHN0cmluZyBvciBhcnJheS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBuZXdDbGFzc05hbWVzIFRoZSBuZXcgQ2xhc3NOYW1lIHN0cmluZyBvciBhcnJheS5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBjbGFzcyBuYW1lcyBoYXMgcmVhbGx5IGNoYW5nZWQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gaG9zdENsYXNzTmFtZXNDaGFuZ2VkKG9sZENsYXNzTmFtZXMsIG5ld0NsYXNzTmFtZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VyckNsYXNzZXMgPSB0eXBlb2YgbmV3Q2xhc3NOYW1lcyA9PSBUWVBFUy5zID8gbmV3Q2xhc3NOYW1lcy5zcGxpdChfc3RyU3BhY2UpIDogW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9sZENsYXNzZXMgPSB0eXBlb2Ygb2xkQ2xhc3NOYW1lcyA9PSBUWVBFUy5zID8gb2xkQ2xhc3NOYW1lcy5zcGxpdChfc3RyU3BhY2UpIDogW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRpZmYgPSBnZXRBcnJheURpZmZlcmVuY2VzKG9sZENsYXNzZXMsIGN1cnJDbGFzc2VzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIG5vbmUgdGhlbWUgZnJvbSBkaWZmIGxpc3QgdG8gcHJldmVudCB1cGRhdGVcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaWR4ID0gaW5BcnJheShfY2xhc3NOYW1lVGhlbWVOb25lLCBkaWZmKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVnZXg7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpZHggPiAtMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlmZi5zcGxpY2UoaWR4LCAxKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRpZmZbTEVYSUNPTi5sXSA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVnZXggPSBjcmVhdGVIb3N0Q2xhc3NOYW1lUmVnRXhwKHRydWUsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZGlmZi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFkaWZmW2ldLm1hdGNoKHJlZ2V4KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gbXV0YXRpb24gaXMgbm90IGZyb20gYSBmcm9tIHRoZSBwbHVnaW4gZ2VuZXJhdGVkIGVsZW1lbnQuIElmIHRoZSB0YXJnZXQgZWxlbWVudCBpcyBhIHRleHRhcmVhIHRoZSBtdXRhdGlvbiBpcyBhbHdheXMgdW5rbm93bi5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBtdXRhdGlvbiBUaGUgbXV0YXRpb24gd2hpY2ggc2hhbGwgYmUgY2hlY2tlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBtdXRhdGlvbiBpcyBmcm9tIGEgdW5rbm93biBlbGVtZW50LCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGlzVW5rbm93bk11dGF0aW9uKG11dGF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZU5hbWUgPSBtdXRhdGlvbi5hdHRyaWJ1dGVOYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtdXRhdGlvblRhcmdldCA9IG11dGF0aW9uLnRhcmdldDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbXV0YXRpb25UeXBlID0gbXV0YXRpb24udHlwZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQ2xvc2VzdCA9ICdjbG9zZXN0JztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG11dGF0aW9uVGFyZ2V0ID09PSBfY29udGVudEVsZW1lbnROYXRpdmUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhdHRyaWJ1dGVOYW1lID09PSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChtdXRhdGlvblR5cGUgPT09ICdhdHRyaWJ1dGVzJyAmJiAoYXR0cmlidXRlTmFtZSA9PT0gTEVYSUNPTi5jIHx8IGF0dHJpYnV0ZU5hbWUgPT09IExFWElDT04ucykgJiYgIV9pc1RleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWdub3JlIGNsYXNzTmFtZSBjaGFuZ2VzIGJ5IHRoZSBwbHVnaW5cdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlTmFtZSA9PT0gTEVYSUNPTi5jICYmIEZSQU1FV09SSyhtdXRhdGlvblRhcmdldCkuaGFzQ2xhc3MoX2NsYXNzTmFtZUhvc3RFbGVtZW50KSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBob3N0Q2xhc3NOYW1lc0NoYW5nZWQobXV0YXRpb24ub2xkVmFsdWUsIG11dGF0aW9uVGFyZ2V0LmNsYXNzTmFtZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL29ubHkgZG8gaXQgb2YgYnJvd3NlciBzdXBwb3J0IGl0IG5hdGl2ZWx5XHRcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtdXRhdGlvblRhcmdldFtzdHJDbG9zZXN0XSAhPSBUWVBFUy5mKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtdXRhdGlvblRhcmdldFtzdHJDbG9zZXN0XShfc3RyRG90ICsgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCkgIT09IG51bGwgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0aW9uVGFyZ2V0W3N0ckNsb3Nlc3RdKF9zdHJEb3QgKyBfY2xhc3NOYW1lU2Nyb2xsYmFyKSAhPT0gbnVsbCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRpb25UYXJnZXRbc3RyQ2xvc2VzdF0oX3N0ckRvdCArIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXIpICE9PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY29udGVudCBzaXplIHdhcyBjaGFuZ2VkIHNpbmNlIHRoZSBsYXN0IHRpbWUgdGhpcyBtZXRob2Qgd2FzIGNhbGxlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBjb250ZW50IHNpemUgd2FzIGNoYW5nZWQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gdXBkYXRlQXV0b0NvbnRlbnRTaXplQ2hhbmdlZCgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3NsZWVwaW5nKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50TWVhc3VyZUVsZW1lbnQgPSBnZXRDb250ZW50TWVhc3VyZUVsZW1lbnQoKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFWYWx1ZUxlbmd0aCA9IF9pc1RleHRhcmVhICYmIF93aWR0aEF1dG9DYWNoZSAmJiAhX3RleHRhcmVhQXV0b1dyYXBwaW5nQ2FjaGUgPyBfdGFyZ2V0RWxlbWVudC52YWwoKS5sZW5ndGggOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzZXRDU1MgPSAhX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkICYmIF93aWR0aEF1dG9DYWNoZSAmJiAhX2lzVGV4dGFyZWE7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNzcyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmbG9hdDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYm9keU1pblNpemVDO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGFuZ2VkO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50RWxlbWVudFNjcm9sbFNpemU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXRDU1MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgPSBfY29udGVudEVsZW1lbnQuY3NzKF9zdHJGbG9hdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyRmxvYXRdID0gX2lzUlRMID8gX3N0clJpZ2h0IDogX3N0ckxlZnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyV2lkdGhdID0gX3N0ckF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoY3NzKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRTY3JvbGxTaXplID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3OiBjb250ZW50TWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5zV10gKyB0ZXh0YXJlYVZhbHVlTGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBoOiBjb250ZW50TWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5zSF0gKyB0ZXh0YXJlYVZhbHVlTGVuZ3RoXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2V0Q1NTKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyRmxvYXRdID0gZmxvYXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyV2lkdGhdID0gX3N0ckh1bmRyZWRQZXJjZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnQuY3NzKGNzcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBib2R5TWluU2l6ZUMgPSBib2R5TWluU2l6ZUNoYW5nZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICBjaGFuZ2VkID0gY2hlY2tDYWNoZShjb250ZW50RWxlbWVudFNjcm9sbFNpemUsIF9jb250ZW50RWxlbWVudFNjcm9sbFNpemVDaGFuZ2VEZXRlY3RlZENhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZUNoYW5nZURldGVjdGVkQ2FjaGUgPSBjb250ZW50RWxlbWVudFNjcm9sbFNpemU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjaGFuZ2VkIHx8IGJvZHlNaW5TaXplQztcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJldHVybnMgdHJ1ZSB3aGVuIGEgYXR0cmlidXRlIHdoaWNoIHRoZSBNdXRhdGlvbk9ic2VydmVyIHdvdWxkIG9ic2VydmUgaGFzIGNoYW5nZWQuICBcclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIG9uZSBvZiB0aGUgYXR0cmlidXRlcyB3aGljaCBhIE11dGF0aW9uT2JzZXJ2ZXIgd291bGQgb2JzZXJ2ZSBoYXMgY2hhbmdlZCwgZmFsc2Ugb3IgdW5kZWZpbmVkIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gbWVhbmluZ2Z1bEF0dHJzQ2hhbmdlZCgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3NsZWVwaW5nIHx8IF9tdXRhdGlvbk9ic2VydmVyc0Nvbm5lY3RlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VycjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2FjaGU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoYW5nZWRBdHRycyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGVja3MgPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9lbGVtOiBfaG9zdEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYXR0cnM6IF9tdXRhdGlvbk9ic2VydmVyQXR0cnNIb3N0LmNvbmNhdCgnOnZpc2libGUnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZWxlbTogX2lzVGV4dGFyZWEgPyBfdGFyZ2V0RWxlbWVudCA6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9hdHRyczogX211dGF0aW9uT2JzZXJ2ZXJBdHRyc1RleHRhcmVhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBlYWNoKGNoZWNrcywgZnVuY3Rpb24gKGluZGV4LCBjaGVjaykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtID0gY2hlY2suX2VsZW07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYWNoKGNoZWNrLl9hdHRycywgZnVuY3Rpb24gKGluZGV4LCBhdHRyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyciA9IGF0dHIuY2hhckF0KDApID09PSAnOicgPyBlbGVtLmlzKGF0dHIpIDogZWxlbS5hdHRyKGF0dHIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlID0gX3VwZGF0ZUF1dG9DYWNoZVthdHRyXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoZWNrQ2FjaGUoY3VyciwgY2FjaGUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZWRBdHRycy5wdXNoKGF0dHIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3VwZGF0ZUF1dG9DYWNoZVthdHRyXSA9IGN1cnI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB1cGRhdGVWaWV3cG9ydEF0dHJzRnJvbVRhcmdldChjaGFuZ2VkQXR0cnMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2hhbmdlZEF0dHJzW0xFWElDT04ubF0gPiAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQ2hlY2tzIGlzIGEgQ1NTIFByb3BlcnR5IG9mIGEgY2hpbGQgZWxlbWVudCBpcyBhZmZlY3RpbmcgdGhlIHNjcm9sbCBzaXplIG9mIHRoZSBjb250ZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHByb3BlcnR5TmFtZSBUaGUgQ1NTIHByb3BlcnR5IG5hbWUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgcHJvcGVydHkgaXMgYWZmZWN0aW5nIHRoZSBjb250ZW50IHNjcm9sbCBzaXplLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGlzU2l6ZUFmZmVjdGluZ0NTU1Byb3BlcnR5KHByb3BlcnR5TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghX2luaXRpYWxpemVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZmxleEdyb3cgPSAnZmxleC1ncm93JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZmxleFNocmluayA9ICdmbGV4LXNocmluayc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZsZXhCYXNpcyA9ICdmbGV4LWJhc2lzJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWZmZWN0aW5nUHJvcHNYID0gW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyV2lkdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJNaW5NaW51cyArIF9zdHJXaWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ck1heE1pbnVzICsgX3N0cldpZHRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWFyZ2luTWludXMgKyBfc3RyTGVmdCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ck1hcmdpbk1pbnVzICsgX3N0clJpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTGVmdCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0clJpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAnZm9udC13ZWlnaHQnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAnd29yZC1zcGFjaW5nJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleEdyb3csXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZsZXhTaHJpbmssXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZsZXhCYXNpc1xyXG4gICAgICAgICAgICAgICAgICAgIF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFmZmVjdGluZ1Byb3BzWENvbnRlbnRCb3ggPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJQYWRkaW5nTWludXMgKyBfc3RyTGVmdCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0clBhZGRpbmdNaW51cyArIF9zdHJSaWdodCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ckJvcmRlck1pbnVzICsgX3N0ckxlZnQgKyBfc3RyV2lkdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJCb3JkZXJNaW51cyArIF9zdHJSaWdodCArIF9zdHJXaWR0aFxyXG4gICAgICAgICAgICAgICAgICAgIF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFmZmVjdGluZ1Byb3BzWSA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ckhlaWdodCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ck1pbk1pbnVzICsgX3N0ckhlaWdodCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ck1heE1pbnVzICsgX3N0ckhlaWdodCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ck1hcmdpbk1pbnVzICsgX3N0clRvcCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ck1hcmdpbk1pbnVzICsgX3N0ckJvdHRvbSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0clRvcCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ckJvdHRvbSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ2xpbmUtaGVpZ2h0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleEdyb3csXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZsZXhTaHJpbmssXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZsZXhCYXNpc1xyXG4gICAgICAgICAgICAgICAgICAgIF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFmZmVjdGluZ1Byb3BzWUNvbnRlbnRCb3ggPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJQYWRkaW5nTWludXMgKyBfc3RyVG9wLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyUGFkZGluZ01pbnVzICsgX3N0ckJvdHRvbSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ckJvcmRlck1pbnVzICsgX3N0clRvcCArIF9zdHJXaWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ckJvcmRlck1pbnVzICsgX3N0ckJvdHRvbSArIF9zdHJXaWR0aFxyXG4gICAgICAgICAgICAgICAgICAgIF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIF9zdHJTID0gJ3MnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBfc3RyVlMgPSAndi1zJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hlY2tYID0gX292ZXJmbG93QmVoYXZpb3JDYWNoZS54ID09PSBfc3RyUyB8fCBfb3ZlcmZsb3dCZWhhdmlvckNhY2hlLnggPT09IF9zdHJWUztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hlY2tZID0gX292ZXJmbG93QmVoYXZpb3JDYWNoZS55ID09PSBfc3RyUyB8fCBfb3ZlcmZsb3dCZWhhdmlvckNhY2hlLnkgPT09IF9zdHJWUztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2l6ZUlzQWZmZWN0ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hlY2tQcm9wZXJ0eU5hbWUgPSBmdW5jdGlvbiAoYXJyLCBuYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFycltpXSA9PT0gbmFtZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoZWNrWSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplSXNBZmZlY3RlZCA9IGNoZWNrUHJvcGVydHlOYW1lKGFmZmVjdGluZ1Byb3BzWSwgcHJvcGVydHlOYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzaXplSXNBZmZlY3RlZCAmJiAhX2lzQm9yZGVyQm94KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZUlzQWZmZWN0ZWQgPSBjaGVja1Byb3BlcnR5TmFtZShhZmZlY3RpbmdQcm9wc1lDb250ZW50Qm94LCBwcm9wZXJ0eU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hlY2tYICYmICFzaXplSXNBZmZlY3RlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplSXNBZmZlY3RlZCA9IGNoZWNrUHJvcGVydHlOYW1lKGFmZmVjdGluZ1Byb3BzWCwgcHJvcGVydHlOYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzaXplSXNBZmZlY3RlZCAmJiAhX2lzQm9yZGVyQm94KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZUlzQWZmZWN0ZWQgPSBjaGVja1Byb3BlcnR5TmFtZShhZmZlY3RpbmdQcm9wc1hDb250ZW50Qm94LCBwcm9wZXJ0eU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2l6ZUlzQWZmZWN0ZWQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBVcGRhdGUgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBTZXRzIHRoZSBhdHRyaWJ1dGUgdmFsdWVzIG9mIHRoZSB2aWV3cG9ydCBlbGVtZW50IHRvIHRoZSB2YWx1ZXMgZnJvbSB0aGUgdGFyZ2V0IGVsZW1lbnQuXHJcbiAgICAgICAgICAgICAgICAgKiBUaGUgdmFsdWUgb2YgYSBhdHRyaWJ1dGUgaXMgb25seSBzZXQgaWYgdGhlIGF0dHJpYnV0ZSBpcyB3aGl0ZWxpc3RlZC5cclxuICAgICAgICAgICAgICAgICAqIEBhdHRycyBhdHRycyBUaGUgYXJyYXkgb2YgYXR0cmlidXRlcyB3aGljaCBzaGFsbCBiZSBzZXQgb3IgdW5kZWZpbmVkIGlmIGFsbCB3aGl0ZWxpc3RlZCBzaGFsbCBiZSBzZXQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVZpZXdwb3J0QXR0cnNGcm9tVGFyZ2V0KGF0dHJzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXR0cnMgPSBhdHRycyB8fCBfdmlld3BvcnRBdHRyc0Zyb21UYXJnZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgZWFjaChhdHRycywgZnVuY3Rpb24gKGluZGV4LCBhdHRyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChDT01QQVRJQklMSVRZLmluQShhdHRyLCBfdmlld3BvcnRBdHRyc0Zyb21UYXJnZXQpID4gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0YXJnZXRBdHRyID0gX3RhcmdldEVsZW1lbnQuYXR0cihhdHRyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKHRhcmdldEF0dHIpID09IFRZUEVTLnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50LmF0dHIoYXR0ciwgdGFyZ2V0QXR0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50LnJlbW92ZUF0dHIoYXR0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFVwZGF0ZXMgdGhlIHZhcmlhYmxlcyBhbmQgc2l6ZSBvZiB0aGUgdGV4dGFyZWEgZWxlbWVudCwgYW5kIG1hbmFnZXMgdGhlIHNjcm9sbCBvbiBuZXcgbGluZSBvciBuZXcgY2hhcmFjdGVyLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiB0ZXh0YXJlYVVwZGF0ZSgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIV9zbGVlcGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgd3JhcEF0dHJPZmYgPSAhX3RleHRhcmVhQXV0b1dyYXBwaW5nQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtaW5XaWR0aCA9IF92aWV3cG9ydFNpemUudztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1pbkhlaWdodCA9IF92aWV3cG9ydFNpemUuaDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNzcyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZG9NZWFzdXJlID0gX3dpZHRoQXV0b0NhY2hlIHx8IHdyYXBBdHRyT2ZmO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3JpZ1dpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcmlnSGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGVpZ2h0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9yZXNldCBtaW4gc2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ck1pbk1pbnVzICsgX3N0cldpZHRoXSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJNaW5NaW51cyArIF9zdHJIZWlnaHRdID0gX3N0ckVtcHR5O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zZXQgd2lkdGggYXV0b1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0cldpZHRoXSA9IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0RWxlbWVudC5jc3MoY3NzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWVhc3VyZSB3aWR0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvcmlnV2lkdGggPSBfdGFyZ2V0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9XXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSBkb01lYXN1cmUgPyBNQVRILm1heChvcmlnV2lkdGgsIF90YXJnZXRFbGVtZW50TmF0aXZlW0xFWElDT04uc1ddIC0gMSkgOiAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKndpZHRoICs9IChfd2lkdGhBdXRvQ2FjaGUgPyBfbWFyZ2luWCArICghX2lzQm9yZGVyQm94ID8gd3JhcEF0dHJPZmYgPyAwIDogX3BhZGRpbmdYICsgX2JvcmRlclggOiAwKSA6IDApOyovXHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NldCBtZWFzdXJlZCB3aWR0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0cldpZHRoXSA9IF93aWR0aEF1dG9DYWNoZSA/IF9zdHJBdXRvIC8qd2lkdGgqLyA6IF9zdHJIdW5kcmVkUGVyY2VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJNaW5NaW51cyArIF9zdHJXaWR0aF0gPSBfc3RySHVuZHJlZFBlcmNlbnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NldCBoZWlnaHQgYXV0b1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ckhlaWdodF0gPSBfc3RyQXV0bztcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnQuY3NzKGNzcyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21lYXN1cmUgaGVpZ2h0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdIZWlnaHQgPSBfdGFyZ2V0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9IXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0ID0gTUFUSC5tYXgob3JpZ0hlaWdodCwgX3RhcmdldEVsZW1lbnROYXRpdmVbTEVYSUNPTi5zSF0gLSAxKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYXBwZW5kIGNvcnJlY3Qgc2l6ZSB2YWx1ZXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJXaWR0aF0gPSB3aWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJIZWlnaHRdID0gaGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGV4dGFyZWFDb3ZlckVsZW1lbnQuY3NzKGNzcyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2FwcGx5IG1pbiB3aWR0aCAvIG1pbiBoZWlnaHQgdG8gcHJldmVudCB0ZXh0YXJlYSBjb2xsYXBzaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyTWluTWludXMgKyBfc3RyV2lkdGhdID0gbWluV2lkdGggLyorICghX2lzQm9yZGVyQm94ICYmIF93aWR0aEF1dG9DYWNoZSA/IF9wYWRkaW5nWCArIF9ib3JkZXJYIDogMCkqLztcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJNaW5NaW51cyArIF9zdHJIZWlnaHRdID0gbWluSGVpZ2h0IC8qKyAoIV9pc0JvcmRlckJveCAmJiBfaGVpZ2h0QXV0b0NhY2hlID8gX3BhZGRpbmdZICsgX2JvcmRlclkgOiAwKSovO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0RWxlbWVudC5jc3MoY3NzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfb3JpZ2luYWxXaWR0aDogb3JpZ1dpZHRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX29yaWdpbmFsSGVpZ2h0OiBvcmlnSGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2R5bmFtaWNXaWR0aDogd2lkdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZHluYW1pY0hlaWdodDogaGVpZ2h0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVXBkYXRlcyB0aGUgcGx1Z2luIGFuZCBET00gdG8gdGhlIGN1cnJlbnQgb3B0aW9ucy5cclxuICAgICAgICAgICAgICAgICAqIFRoaXMgbWV0aG9kIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBpZiBhIHVwZGF0ZSBpcyAxMDAlIHJlcXVpcmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHVwZGF0ZUhpbnRzIEEgb2JqZWN0cyB3aGljaCBjb250YWlucyBoaW50cyBmb3IgdGhpcyB1cGRhdGU6XHJcbiAgICAgICAgICAgICAgICAgKiB7XHJcbiAgICAgICAgICAgICAgICAgKiAgIF9ob3N0U2l6ZUNoYW5nZWQgOiBib29sZWFuLFxyXG4gICAgICAgICAgICAgICAgICogICBfY29udGVudFNpemVDaGFuZ2VkIDogYm9vbGVhbixcclxuICAgICAgICAgICAgICAgICAqICAgX2ZvcmNlIDogYm9vbGVhbiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgID09IHByZXZlbnRTd2FsbG93aW5nXHJcbiAgICAgICAgICAgICAgICAgKiAgIF9jaGFuZ2VkT3B0aW9ucyA6IHsgfSwgICAgICAgICAgICAgICAgICAgICAgICA9PSBwcmV2ZW50U3dhbGxvd2luZyAmJiBwcmV2ZW50U2xlZXBcclxuICAgICAgICAgICAgICAgICogIH1cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gdXBkYXRlKHVwZGF0ZUhpbnRzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF9zd2FsbG93ZWRVcGRhdGVUaW1lb3V0KTtcclxuICAgICAgICAgICAgICAgICAgICB1cGRhdGVIaW50cyA9IHVwZGF0ZUhpbnRzIHx8IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIF9zd2FsbG93ZWRVcGRhdGVIaW50cy5faG9zdFNpemVDaGFuZ2VkIHw9IHVwZGF0ZUhpbnRzLl9ob3N0U2l6ZUNoYW5nZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgX3N3YWxsb3dlZFVwZGF0ZUhpbnRzLl9jb250ZW50U2l6ZUNoYW5nZWQgfD0gdXBkYXRlSGludHMuX2NvbnRlbnRTaXplQ2hhbmdlZDtcclxuICAgICAgICAgICAgICAgICAgICBfc3dhbGxvd2VkVXBkYXRlSGludHMuX2ZvcmNlIHw9IHVwZGF0ZUhpbnRzLl9mb3JjZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5vdyA9IENPTVBBVElCSUxJVFkubm93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhvc3RTaXplQ2hhbmdlZCA9ICEhX3N3YWxsb3dlZFVwZGF0ZUhpbnRzLl9ob3N0U2l6ZUNoYW5nZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRTaXplQ2hhbmdlZCA9ICEhX3N3YWxsb3dlZFVwZGF0ZUhpbnRzLl9jb250ZW50U2l6ZUNoYW5nZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZvcmNlID0gISFfc3dhbGxvd2VkVXBkYXRlSGludHMuX2ZvcmNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGFuZ2VkT3B0aW9ucyA9IHVwZGF0ZUhpbnRzLl9jaGFuZ2VkT3B0aW9ucztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3dhbGxvdyA9IF9zd2FsbG93VXBkYXRlTGFnID4gMCAmJiBfaW5pdGlhbGl6ZWQgJiYgIV9kZXN0cm95ZWQgJiYgIWZvcmNlICYmICFjaGFuZ2VkT3B0aW9ucyAmJiAobm93IC0gX2xhc3RVcGRhdGVUaW1lKSA8IF9zd2FsbG93VXBkYXRlTGFnICYmICghX2hlaWdodEF1dG9DYWNoZSAmJiAhX3dpZHRoQXV0b0NhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZGlzcGxheUlzSGlkZGVuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3dhbGxvdylcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N3YWxsb3dlZFVwZGF0ZVRpbWVvdXQgPSBzZXRUaW1lb3V0KHVwZGF0ZSwgX3N3YWxsb3dVcGRhdGVMYWcpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2Fib3J0IHVwZGF0ZSBkdWUgdG86XHJcbiAgICAgICAgICAgICAgICAgICAgLy9kZXN0cm95ZWRcclxuICAgICAgICAgICAgICAgICAgICAvL3N3YWxsb3dpbmdcclxuICAgICAgICAgICAgICAgICAgICAvL3NsZWVwaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgLy9ob3N0IGlzIGhpZGRlbiBvciBoYXMgZmFsc2UgZGlzcGxheVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfZGVzdHJveWVkIHx8IHN3YWxsb3cgfHwgKF9zbGVlcGluZyAmJiAhY2hhbmdlZE9wdGlvbnMpIHx8IChfaW5pdGlhbGl6ZWQgJiYgIWZvcmNlICYmIChkaXNwbGF5SXNIaWRkZW4gPSBfaG9zdEVsZW1lbnQuaXMoJzpoaWRkZW4nKSkpIHx8IF9ob3N0RWxlbWVudC5jc3MoJ2Rpc3BsYXknKSA9PT0gJ2lubGluZScpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgX2xhc3RVcGRhdGVUaW1lID0gbm93O1xyXG4gICAgICAgICAgICAgICAgICAgIF9zd2FsbG93ZWRVcGRhdGVIaW50cyA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lmIHNjcm9sbGJhciBzdHlsaW5nIGlzIHBvc3NpYmxlIGFuZCBuYXRpdmUgc2Nyb2xsYmFycyBhcmVuJ3Qgb3ZlcmxhaWQgdGhlIHNjcm9sbGJhciBzdHlsaW5nIHdpbGwgYmUgYXBwbGllZCB3aGljaCBoaWRlcyB0aGUgbmF0aXZlIHNjcm9sbGJhcnMgY29tcGxldGVseS5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcgJiYgIShfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vbmF0aXZlIHNjcm9sbGJhcnMgYXJlIGhpZGRlbiwgc28gY2hhbmdlIHRoZSB2YWx1ZXMgdG8gemVyb1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbmF0aXZlU2Nyb2xsYmFyU2l6ZS54ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX25hdGl2ZVNjcm9sbGJhclNpemUueSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3JlZnJlc2ggbmF0aXZlIHNjcm9sbGJhciBzaXplIChpbiBjYXNlIG9mIHpvb20pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9uYXRpdmVTY3JvbGxiYXJTaXplID0gZXh0ZW5kRGVlcCh7fSwgZ2xvYmFscy5uYXRpdmVTY3JvbGxiYXJTaXplKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIFNjcm9sbGJhciBwYWRkaW5nIGlzIG5lZWRlZCBmb3IgZmlyZWZveCwgYmVjYXVzZSBmaXJlZm94IGhpZGVzIHNjcm9sbGJhciBhdXRvbWF0aWNhbGx5IGlmIHRoZSBzaXplIG9mIHRoZSBkaXYgaXMgdG9vIHNtYWxsLlxyXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBjYWxjdWxhdGlvbjogW3Njcm9sbGJhciBzaXplICszICozXVxyXG4gICAgICAgICAgICAgICAgICAgIC8vICgrMyBiZWNhdXNlIG9mIHBvc3NpYmxlIGRlY29yYXRpb24gZS5nLiBib3JkZXJzLCBtYXJnaW5zIGV0Yy4sIGJ1dCBvbmx5IGlmIG5hdGl2ZSBzY3JvbGxiYXIgaXMgTk9UIGEgb3ZlcmxhaWQgc2Nyb2xsYmFyKVxyXG4gICAgICAgICAgICAgICAgICAgIC8vICgqMyBiZWNhdXNlICgxKWluY3JlYXNlIC8gKDIpZGVjcmVhc2UgLWJ1dHRvbiBhbmQgKDMpcmVzaXplIGhhbmRsZSlcclxuICAgICAgICAgICAgICAgICAgICBfbmF0aXZlU2Nyb2xsYmFyTWluU2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgeDogKF9uYXRpdmVTY3JvbGxiYXJTaXplLnggKyAoX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueCA/IDAgOiAzKSkgKiAzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiAoX25hdGl2ZVNjcm9sbGJhclNpemUueSArIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55ID8gMCA6IDMpKSAqIDNcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBjaGFuZ2VkT3B0aW9ucyA9IGNoYW5nZWRPcHRpb25zIHx8IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vZnJlZXplUmVzaXplT2JzZXJ2ZXIoX3NpemVPYnNlcnZlckVsZW1lbnQsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vZnJlZXplUmVzaXplT2JzZXJ2ZXIoX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoZWNrQ2FjaGVBdXRvRm9yY2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjaGVja0NhY2hlLmFwcGx5KHRoaXMsIFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKS5jb25jYXQoW2ZvcmNlXSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2F2ZSBjdXJyZW50IHNjcm9sbCBvZmZzZXRcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VyclNjcm9sbCA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgeDogX3ZpZXdwb3J0RWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgeTogX3ZpZXdwb3J0RWxlbWVudFtfc3RyU2Nyb2xsVG9wXSgpXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRQcmVwYXJlZE9wdGlvbnNTY3JvbGxiYXJzID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMuc2Nyb2xsYmFycztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VycmVudFByZXBhcmVkT3B0aW9uc1RleHRhcmVhID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMudGV4dGFyZWE7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2Nyb2xsYmFycyB2aXNpYmlsaXR5OlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzVmlzaWJpbGl0eSA9IGN1cnJlbnRQcmVwYXJlZE9wdGlvbnNTY3JvbGxiYXJzLnZpc2liaWxpdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNWaXNpYmlsaXR5Q2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2Uoc2Nyb2xsYmFyc1Zpc2liaWxpdHksIF9zY3JvbGxiYXJzVmlzaWJpbGl0eUNhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxiYXJzIGF1dG9IaWRlOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzQXV0b0hpZGUgPSBjdXJyZW50UHJlcGFyZWRPcHRpb25zU2Nyb2xsYmFycy5hdXRvSGlkZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc0F1dG9IaWRlQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2Uoc2Nyb2xsYmFyc0F1dG9IaWRlLCBfc2Nyb2xsYmFyc0F1dG9IaWRlQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGJhcnMgY2xpY2sgc2Nyb2xsaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNDbGlja1Njcm9sbGluZyA9IGN1cnJlbnRQcmVwYXJlZE9wdGlvbnNTY3JvbGxiYXJzLmNsaWNrU2Nyb2xsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzQ2xpY2tTY3JvbGxpbmdDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShzY3JvbGxiYXJzQ2xpY2tTY3JvbGxpbmcsIF9zY3JvbGxiYXJzQ2xpY2tTY3JvbGxpbmdDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2Nyb2xsYmFycyBkcmFnIHNjcm9sbGluZ1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzRHJhZ1Njcm9sbGluZyA9IGN1cnJlbnRQcmVwYXJlZE9wdGlvbnNTY3JvbGxiYXJzLmRyYWdTY3JvbGxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2Uoc2Nyb2xsYmFyc0RyYWdTY3JvbGxpbmcsIF9zY3JvbGxiYXJzRHJhZ1Njcm9sbGluZ0NhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9jbGFzc05hbWVcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMuY2xhc3NOYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc05hbWVDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShjbGFzc05hbWUsIF9jbGFzc05hbWVDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc2l6ZSA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLnJlc2l6ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzaXplQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UocmVzaXplLCBfcmVzaXplQ2FjaGUpICYmICFfaXNCb2R5OyAvL2JvZHkgY2FuJ3QgYmUgcmVzaXplZCBzaW5jZSB0aGUgd2luZG93IGl0c2VsZiBhY3RzIGFzIHJlc2l6ZSBwb3NzaWJpbGl0eS5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9wYWRkaW5nQWJzb2x1dGVcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ0Fic29sdXRlID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMucGFkZGluZ0Fic29sdXRlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShwYWRkaW5nQWJzb2x1dGUsIF9wYWRkaW5nQWJzb2x1dGVDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vY2xpcEFsd2F5c1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGlwQWx3YXlzID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMuY2xpcEFsd2F5cztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xpcEFsd2F5c0NoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGNsaXBBbHdheXMsIF9jbGlwQWx3YXlzQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3NpemVBdXRvQ2FwYWJsZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzaXplQXV0b0NhcGFibGUgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5zaXplQXV0b0NhcGFibGUgJiYgIV9pc0JvZHk7IC8vYm9keSBjYW4gbmV2ZXIgYmUgc2l6ZSBhdXRvLCBiZWNhdXNlIGl0IHNoYWxsIGJlIGFsd2F5cyBhcyBiaWcgYXMgdGhlIHZpZXdwb3J0LlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzaXplQXV0b0NhcGFibGVDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShzaXplQXV0b0NhcGFibGUsIF9zaXplQXV0b0NhcGFibGVDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2hvd05hdGl2ZVNjcm9sbGJhcnNcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZyA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLm5hdGl2ZVNjcm9sbGJhcnNPdmVybGFpZC5zaG93TmF0aXZlU2Nyb2xsYmFycztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmcsIF9pZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2F1dG9VcGRhdGVcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXV0b1VwZGF0ZSA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLmF1dG9VcGRhdGU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGF1dG9VcGRhdGVDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShhdXRvVXBkYXRlLCBfYXV0b1VwZGF0ZUNhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9vdmVyZmxvd0JlaGF2aW9yXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QmVoYXZpb3IgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5vdmVyZmxvd0JlaGF2aW9yO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvdmVyZmxvd0JlaGF2aW9yQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2Uob3ZlcmZsb3dCZWhhdmlvciwgX292ZXJmbG93QmVoYXZpb3JDYWNoZSwgZm9yY2UpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2R5bldpZHRoOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUR5bldpZHRoID0gY3VycmVudFByZXBhcmVkT3B0aW9uc1RleHRhcmVhLmR5bldpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUR5bldpZHRoQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoX3RleHRhcmVhRHluV2lkdGhDYWNoZSwgdGV4dGFyZWFEeW5XaWR0aCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZHluSGVpZ2h0OlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUR5bkhlaWdodCA9IGN1cnJlbnRQcmVwYXJlZE9wdGlvbnNUZXh0YXJlYS5keW5IZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhRHluSGVpZ2h0Q2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoX3RleHRhcmVhRHluSGVpZ2h0Q2FjaGUsIHRleHRhcmVhRHluSGVpZ2h0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxiYXJzIHZpc2liaWxpdHlcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0F1dG9IaWRlTmV2ZXIgPSBzY3JvbGxiYXJzQXV0b0hpZGUgPT09ICduJztcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0F1dG9IaWRlU2Nyb2xsID0gc2Nyb2xsYmFyc0F1dG9IaWRlID09PSAncyc7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUgPSBzY3JvbGxiYXJzQXV0b0hpZGUgPT09ICdtJztcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0F1dG9IaWRlTGVhdmUgPSBzY3JvbGxiYXJzQXV0b0hpZGUgPT09ICdsJztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxiYXJzIGF1dG9IaWRlRGVsYXlcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0F1dG9IaWRlRGVsYXkgPSBjdXJyZW50UHJlcGFyZWRPcHRpb25zU2Nyb2xsYmFycy5hdXRvSGlkZURlbGF5O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL29sZCBjbGFzc05hbWVcclxuICAgICAgICAgICAgICAgICAgICBfb2xkQ2xhc3NOYW1lID0gX2NsYXNzTmFtZUNhY2hlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3Jlc2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgIF9yZXNpemVOb25lID0gcmVzaXplID09PSAnbic7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc2l6ZUJvdGggPSByZXNpemUgPT09ICdiJztcclxuICAgICAgICAgICAgICAgICAgICBfcmVzaXplSG9yaXpvbnRhbCA9IHJlc2l6ZSA9PT0gJ2gnO1xyXG4gICAgICAgICAgICAgICAgICAgIF9yZXNpemVWZXJ0aWNhbCA9IHJlc2l6ZSA9PT0gJ3YnO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL25vcm1hbGl6ZVJUTFxyXG4gICAgICAgICAgICAgICAgICAgIF9ub3JtYWxpemVSVExDYWNoZSA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLm5vcm1hbGl6ZVJUTDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9pZ25vcmUgb3ZlcmxheSBzY3JvbGxiYXIgaGlkaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZyA9IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmcgJiYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVmcmVzaCBvcHRpb25zIGNhY2hlXHJcbiAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNWaXNpYmlsaXR5Q2FjaGUgPSBzY3JvbGxiYXJzVmlzaWJpbGl0eTtcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0F1dG9IaWRlQ2FjaGUgPSBzY3JvbGxiYXJzQXV0b0hpZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NhY2hlID0gc2Nyb2xsYmFyc0NsaWNrU2Nyb2xsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzRHJhZ1Njcm9sbGluZ0NhY2hlID0gc2Nyb2xsYmFyc0RyYWdTY3JvbGxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUNhY2hlID0gY2xhc3NOYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIF9yZXNpemVDYWNoZSA9IHJlc2l6ZTtcclxuICAgICAgICAgICAgICAgICAgICBfcGFkZGluZ0Fic29sdXRlQ2FjaGUgPSBwYWRkaW5nQWJzb2x1dGU7XHJcbiAgICAgICAgICAgICAgICAgICAgX2NsaXBBbHdheXNDYWNoZSA9IGNsaXBBbHdheXM7XHJcbiAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvQ2FwYWJsZUNhY2hlID0gc2l6ZUF1dG9DYXBhYmxlO1xyXG4gICAgICAgICAgICAgICAgICAgIF9pZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nQ2FjaGUgPSBpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIF9hdXRvVXBkYXRlQ2FjaGUgPSBhdXRvVXBkYXRlO1xyXG4gICAgICAgICAgICAgICAgICAgIF9vdmVyZmxvd0JlaGF2aW9yQ2FjaGUgPSBleHRlbmREZWVwKHt9LCBvdmVyZmxvd0JlaGF2aW9yKTtcclxuICAgICAgICAgICAgICAgICAgICBfdGV4dGFyZWFEeW5XaWR0aENhY2hlID0gdGV4dGFyZWFEeW5XaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICBfdGV4dGFyZWFEeW5IZWlnaHRDYWNoZSA9IHRleHRhcmVhRHluSGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgICAgIF9oYXNPdmVyZmxvd0NhY2hlID0gX2hhc092ZXJmbG93Q2FjaGUgfHwgeyB4OiBmYWxzZSwgeTogZmFsc2UgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zZXQgY29ycmVjdCBjbGFzcyBuYW1lIHRvIHRoZSBob3N0IGVsZW1lbnRcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2xhc3NOYW1lQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9vbGRDbGFzc05hbWUgKyBfc3RyU3BhY2UgKyBfY2xhc3NOYW1lVGhlbWVOb25lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX2hvc3RFbGVtZW50LCBjbGFzc05hbWUgIT09IHVuZGVmaW5lZCAmJiBjbGFzc05hbWUgIT09IG51bGwgJiYgY2xhc3NOYW1lLmxlbmd0aCA+IDAgPyBjbGFzc05hbWUgOiBfY2xhc3NOYW1lVGhlbWVOb25lKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2V0IGNvcnJlY3QgYXV0byBVcGRhdGVcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXV0b1VwZGF0ZUNoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF1dG9VcGRhdGUgPT09IHRydWUgfHwgKGF1dG9VcGRhdGUgPT09IG51bGwgJiYgX2F1dG9VcGRhdGVSZWNvbW1lbmRlZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RNdXRhdGlvbk9ic2VydmVycygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0b1VwZGF0ZUxvb3AuYWRkKF9iYXNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9VcGRhdGVMb29wLnJlbW92ZShfYmFzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0TXV0YXRpb25PYnNlcnZlcnMoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9hY3RpdmF0ZSBvciBkZWFjdGl2YXRlIHNpemUgYXV0byBjYXBhYmlsaXR5XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemVBdXRvQ2FwYWJsZUNoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNpemVBdXRvQ2FwYWJsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9jb250ZW50R2x1ZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEdsdWVFbGVtZW50LnNob3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQgPSBGUkFNRVdPUksoZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZUNvbnRlbnRHbHVlRWxlbWVudCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nRWxlbWVudC5iZWZvcmUoX2NvbnRlbnRHbHVlRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplQXV0b09ic2VydmVyRWxlbWVudC5zaG93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQgPSBGUkFNRVdPUksoZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZVNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50TmF0aXZlID0gX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50WzBdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEdsdWVFbGVtZW50LmJlZm9yZShfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvbGRTaXplID0geyB3OiAtMSwgaDogLTEgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc2l6ZU9ic2VydmVyKF9zaXplQXV0b09ic2VydmVyRWxlbWVudCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3U2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IF9zaXplQXV0b09ic2VydmVyRWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9XXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IF9zaXplQXV0b09ic2VydmVyRWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9IXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hlY2tDYWNoZShuZXdTaXplLCBvbGRTaXplKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pbml0aWFsaXplZCAmJiAoX2hlaWdodEF1dG9DYWNoZSAmJiBuZXdTaXplLmggPiAwKSB8fCAoX3dpZHRoQXV0b0NhY2hlICYmIG5ld1NpemUudyA+IDApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChfaW5pdGlhbGl6ZWQgJiYgKCFfaGVpZ2h0QXV0b0NhY2hlICYmIG5ld1NpemUuaCA9PT0gMCkgfHwgKCFfd2lkdGhBdXRvQ2FjaGUgJiYgbmV3U2l6ZS53ID09PSAwKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZFNpemUgPSBuZXdTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplQXV0b09ic2VydmVyQWRkZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZml4IGhlaWdodEF1dG8gZGV0ZWN0b3IgYnVnIGlmIGhlaWdodCBpcyBmaXhlZCBidXQgY29udGVudEhlaWdodCBpcyAwLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhlIHByb2JhYmlsaXR5IHRoaXMgYnVnIHdpbGwgZXZlciBoYXBwZW4gaXMgdmVyeSB2ZXJ5IGxvdywgdGhhdHMgd2h5IGl0cyBvayBpZiB3ZSB1c2UgY2FsYyB3aGljaCBpc24ndCBzdXBwb3J0ZWQgaW4gSUU4LlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfY3NzQ2FsYyAhPT0gbnVsbClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LmNzcyhfc3RySGVpZ2h0LCBfY3NzQ2FsYyArICcoMTAwJSArIDFweCknKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2l6ZUF1dG9PYnNlcnZlckFkZGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplQXV0b09ic2VydmVyRWxlbWVudC5oaWRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2NvbnRlbnRHbHVlRWxlbWVudClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEdsdWVFbGVtZW50LmhpZGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9pZiBmb3JjZSwgdXBkYXRlIGFsbCByZXNpemVPYnNlcnZlcnMgdG9vXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZvcmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplT2JzZXJ2ZXJFbGVtZW50LmZpbmQoJyonKS50cmlnZ2VyKF9zdHJTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplQXV0b09ic2VydmVyRWxlbWVudC5maW5kKCcqJykudHJpZ2dlcihfc3RyU2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZGlzcGxheSBoaWRkZW46XHJcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheUlzSGlkZGVuID0gZGlzcGxheUlzSGlkZGVuID09PSB1bmRlZmluZWQgPyBfaG9zdEVsZW1lbnQuaXMoJzpoaWRkZW4nKSA6IGRpc3BsYXlJc0hpZGRlbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy90ZXh0YXJlYSBBdXRvV3JhcHBpbmc6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhQXV0b1dyYXBwaW5nID0gX2lzVGV4dGFyZWEgPyBfdGFyZ2V0RWxlbWVudC5hdHRyKCd3cmFwJykgIT09ICdvZmYnIDogZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhQXV0b1dyYXBwaW5nQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UodGV4dGFyZWFBdXRvV3JhcHBpbmcsIF90ZXh0YXJlYUF1dG9XcmFwcGluZ0NhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9kZXRlY3QgZGlyZWN0aW9uOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjc3NEaXJlY3Rpb24gPSBfaG9zdEVsZW1lbnQuY3NzKCdkaXJlY3Rpb24nKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3NzRGlyZWN0aW9uQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoY3NzRGlyZWN0aW9uLCBfY3NzRGlyZWN0aW9uQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2RldGVjdCBib3gtc2l6aW5nOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBib3hTaXppbmcgPSBfaG9zdEVsZW1lbnQuY3NzKCdib3gtc2l6aW5nJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJveFNpemluZ0NoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGJveFNpemluZywgX2Nzc0JveFNpemluZ0NhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9kZXRlY3QgcGFkZGluZzpcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFkZGluZyA9IGdldFRvcFJpZ2h0Qm90dG9tTGVmdEhvc3QoX3N0clBhZGRpbmdNaW51cyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vd2lkdGggKyBoZWlnaHQgYXV0byBkZXRlY3RpbmcgdmFyOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzaXplQXV0b09ic2VydmVyRWxlbWVudEJDUmVjdDtcclxuICAgICAgICAgICAgICAgICAgICAvL2V4Y2VwdGlvbiBvY2N1cnMgaW4gSUU4IHNvbWV0aW1lcyAodW5rbm93biBleGNlcHRpb24pXHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnRCQ1JlY3QgPSBfc2l6ZUF1dG9PYnNlcnZlckFkZGVkID8gX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50TmF0aXZlW0xFWElDT04uYkNSXSgpIDogbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBfaXNSVEwgPSBjc3NEaXJlY3Rpb24gPT09ICdydGwnO1xyXG4gICAgICAgICAgICAgICAgICAgIF9pc0JvcmRlckJveCA9IChib3hTaXppbmcgPT09ICdib3JkZXItYm94Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGlzUlRMTGVmdCA9IF9pc1JUTCA/IF9zdHJMZWZ0IDogX3N0clJpZ2h0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpc1JUTFJpZ2h0ID0gX2lzUlRMID8gX3N0clJpZ2h0IDogX3N0ckxlZnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZGV0ZWN0IHdpZHRoIGF1dG86XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdpZHRoQXV0b1Jlc2l6ZURldGVjdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB3aWR0aEF1dG9PYnNlcnZlckRldGVjdGlvbiA9IChfc2l6ZUF1dG9PYnNlcnZlckFkZGVkICYmIChfaG9zdEVsZW1lbnQuY3NzKF9zdHJGbG9hdCkgIT09ICdub25lJyAvKnx8IF9pc1RleHRhcmVhICovKSkgPyAoTUFUSC5yb3VuZChzaXplQXV0b09ic2VydmVyRWxlbWVudEJDUmVjdC5yaWdodCAtIHNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50QkNSZWN0LmxlZnQpID09PSAwKSAmJiAoIXBhZGRpbmdBYnNvbHV0ZSA/IChfaG9zdEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jV10gLSBfcGFkZGluZ1gpID4gMCA6IHRydWUpIDogZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemVBdXRvQ2FwYWJsZSAmJiAhd2lkdGhBdXRvT2JzZXJ2ZXJEZXRlY3Rpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRtcEN1cnJIb3N0V2lkdGggPSBfaG9zdEVsZW1lbnROYXRpdmVbTEVYSUNPTi5vV107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0bXBDdXJyQ29udGVudEdsdWVXaWR0aCA9IF9jb250ZW50R2x1ZUVsZW1lbnQuY3NzKF9zdHJXaWR0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuY3NzKF9zdHJXaWR0aCwgX3N0ckF1dG8pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRtcE5ld0hvc3RXaWR0aCA9IF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9XXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRHbHVlRWxlbWVudC5jc3MoX3N0cldpZHRoLCB0bXBDdXJyQ29udGVudEdsdWVXaWR0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoQXV0b1Jlc2l6ZURldGVjdGlvbiA9IHRtcEN1cnJIb3N0V2lkdGggIT09IHRtcE5ld0hvc3RXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF3aWR0aEF1dG9SZXNpemVEZXRlY3Rpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuY3NzKF9zdHJXaWR0aCwgdG1wQ3Vyckhvc3RXaWR0aCArIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wTmV3SG9zdFdpZHRoID0gX2hvc3RFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRHbHVlRWxlbWVudC5jc3MoX3N0cldpZHRoLCB0bXBDdXJyQ29udGVudEdsdWVXaWR0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aEF1dG9SZXNpemVEZXRlY3Rpb24gPSB0bXBDdXJySG9zdFdpZHRoICE9PSB0bXBOZXdIb3N0V2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdpZHRoQXV0byA9ICh3aWR0aEF1dG9PYnNlcnZlckRldGVjdGlvbiB8fCB3aWR0aEF1dG9SZXNpemVEZXRlY3Rpb24pICYmIHNpemVBdXRvQ2FwYWJsZSAmJiAhZGlzcGxheUlzSGlkZGVuO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB3aWR0aEF1dG9DaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZSh3aWR0aEF1dG8sIF93aWR0aEF1dG9DYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdhc1dpZHRoQXV0byA9ICF3aWR0aEF1dG8gJiYgX3dpZHRoQXV0b0NhY2hlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2RldGVjdCBoZWlnaHQgYXV0bzpcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaGVpZ2h0QXV0byA9IF9zaXplQXV0b09ic2VydmVyQWRkZWQgJiYgc2l6ZUF1dG9DYXBhYmxlICYmICFkaXNwbGF5SXNIaWRkZW4gPyAoTUFUSC5yb3VuZChzaXplQXV0b09ic2VydmVyRWxlbWVudEJDUmVjdC5ib3R0b20gLSBzaXplQXV0b09ic2VydmVyRWxlbWVudEJDUmVjdC50b3ApID09PSAwKSAvKiAmJiAoIXBhZGRpbmdBYnNvbHV0ZSAmJiAoX21zaWVWZXJzaW9uID4gOSB8fCAhX21zaWVWZXJzaW9uKSA/IHRydWUgOiB0cnVlKSAqLyA6IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoZWlnaHRBdXRvQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoaGVpZ2h0QXV0bywgX2hlaWdodEF1dG9DYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdhc0hlaWdodEF1dG8gPSAhaGVpZ2h0QXV0byAmJiBfaGVpZ2h0QXV0b0NhY2hlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2RldGVjdCBib3JkZXI6XHJcbiAgICAgICAgICAgICAgICAgICAgLy93ZSBuZWVkIHRoZSBib3JkZXIgb25seSBpZiBib3JkZXIgYm94IGFuZCBhdXRvIHNpemVcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdXBkYXRlQm9yZGVyWCA9ICh3aWR0aEF1dG8gJiYgX2lzQm9yZGVyQm94KSB8fCAhX2lzQm9yZGVyQm94O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1cGRhdGVCb3JkZXJZID0gKGhlaWdodEF1dG8gJiYgX2lzQm9yZGVyQm94KSB8fCAhX2lzQm9yZGVyQm94O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBib3JkZXIgPSBnZXRUb3BSaWdodEJvdHRvbUxlZnRIb3N0KF9zdHJCb3JkZXJNaW51cywgJy0nICsgX3N0cldpZHRoLCAhdXBkYXRlQm9yZGVyWCwgIXVwZGF0ZUJvcmRlclkpXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZGV0ZWN0IG1hcmdpbjpcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbWFyZ2luID0gZ2V0VG9wUmlnaHRCb3R0b21MZWZ0SG9zdChfc3RyTWFyZ2luTWludXMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3ZhcnMgdG8gYXBwbHkgY29ycmVjdCBjc3NcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudEVsZW1lbnRDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudEdsdWVFbGVtZW50Q1NTID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZnVuY3NcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZ2V0SG9zdFNpemUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaGFzIHRvIGJlIGNsaWVudFNpemUgYmVjYXVzZSBvZmZzZXRTaXplIHJlc3BlY3QgYm9yZGVyc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogX2hvc3RFbGVtZW50TmF0aXZlW0xFWElDT04uY1ddLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogX2hvc3RFbGVtZW50TmF0aXZlW0xFWElDT04uY0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZ2V0Vmlld3BvcnRTaXplID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3ZpZXdwb3J0IHNpemUgaXMgcGFkZGluZyBjb250YWluZXIgYmVjYXVzZSBpdCBuZXZlciBoYXMgcGFkZGluZywgbWFyZ2luIGFuZCBhIGJvcmRlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2RldGVybWluZSB6b29tIHJvdW5kaW5nIGVycm9yIC0+IHNvbWV0aW1lcyBzY3JvbGxXaWR0aC9IZWlnaHQgaXMgc21hbGxlciB0aGFuIGNsaWVudFdpZHRoL0hlaWdodFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2lmIHRoaXMgaGFwcGVucyBhZGQgdGhlIGRpZmZlcmVuY2UgdG8gdGhlIHZpZXdwb3J0U2l6ZSB0byBjb21wZW5zYXRlIHRoZSByb3VuZGluZyBlcnJvclxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogX3BhZGRpbmdFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddICsgTUFUSC5tYXgoMCwgX2NvbnRlbnRFbGVtZW50TmF0aXZlW0xFWElDT04uY1ddIC0gX2NvbnRlbnRFbGVtZW50TmF0aXZlW0xFWElDT04uc1ddKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IF9wYWRkaW5nRWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9IXSArIE1BVEgubWF4KDAsIF9jb250ZW50RWxlbWVudE5hdGl2ZVtMRVhJQ09OLmNIXSAtIF9jb250ZW50RWxlbWVudE5hdGl2ZVtMRVhJQ09OLnNIXSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3NldCBpbmZvIGZvciBwYWRkaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhZGRpbmdBYnNvbHV0ZVggPSBfcGFkZGluZ1ggPSBwYWRkaW5nLmwgKyBwYWRkaW5nLnI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhZGRpbmdBYnNvbHV0ZVkgPSBfcGFkZGluZ1kgPSBwYWRkaW5nLnQgKyBwYWRkaW5nLmI7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0Fic29sdXRlWCAqPSBwYWRkaW5nQWJzb2x1dGUgPyAxIDogMDtcclxuICAgICAgICAgICAgICAgICAgICBwYWRkaW5nQWJzb2x1dGVZICo9IHBhZGRpbmdBYnNvbHV0ZSA/IDEgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHBhZGRpbmcuYyA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UocGFkZGluZywgX2Nzc1BhZGRpbmdDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2V0IGluZm8gZm9yIGJvcmRlclxyXG4gICAgICAgICAgICAgICAgICAgIF9ib3JkZXJYID0gYm9yZGVyLmwgKyBib3JkZXIucjtcclxuICAgICAgICAgICAgICAgICAgICBfYm9yZGVyWSA9IGJvcmRlci50ICsgYm9yZGVyLmI7XHJcbiAgICAgICAgICAgICAgICAgICAgYm9yZGVyLmMgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGJvcmRlciwgX2Nzc0JvcmRlckNhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zZXQgaW5mbyBmb3IgbWFyZ2luXHJcbiAgICAgICAgICAgICAgICAgICAgX21hcmdpblggPSBtYXJnaW4ubCArIG1hcmdpbi5yO1xyXG4gICAgICAgICAgICAgICAgICAgIF9tYXJnaW5ZID0gbWFyZ2luLnQgKyBtYXJnaW4uYjtcclxuICAgICAgICAgICAgICAgICAgICBtYXJnaW4uYyA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UobWFyZ2luLCBfY3NzTWFyZ2luQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlZnJlc2ggY2FjaGVcclxuICAgICAgICAgICAgICAgICAgICBfdGV4dGFyZWFBdXRvV3JhcHBpbmdDYWNoZSA9IHRleHRhcmVhQXV0b1dyYXBwaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jc3NEaXJlY3Rpb25DYWNoZSA9IGNzc0RpcmVjdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICBfY3NzQm94U2l6aW5nQ2FjaGUgPSBib3hTaXppbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX3dpZHRoQXV0b0NhY2hlID0gd2lkdGhBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgIF9oZWlnaHRBdXRvQ2FjaGUgPSBoZWlnaHRBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jc3NQYWRkaW5nQ2FjaGUgPSBwYWRkaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jc3NCb3JkZXJDYWNoZSA9IGJvcmRlcjtcclxuICAgICAgICAgICAgICAgICAgICBfY3NzTWFyZ2luQ2FjaGUgPSBtYXJnaW47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vSUVGaXggZGlyZWN0aW9uIGNoYW5nZWRcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY3NzRGlyZWN0aW9uQ2hhbmdlZCAmJiBfc2l6ZUF1dG9PYnNlcnZlckFkZGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQuY3NzKF9zdHJGbG9hdCwgaXNSVExSaWdodCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYXBwbHkgcGFkZGluZzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAocGFkZGluZy5jIHx8IGNzc0RpcmVjdGlvbkNoYW5nZWQgfHwgcGFkZGluZ0Fic29sdXRlQ2hhbmdlZCB8fCB3aWR0aEF1dG9DaGFuZ2VkIHx8IGhlaWdodEF1dG9DaGFuZ2VkIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgc2l6ZUF1dG9DYXBhYmxlQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ0VsZW1lbnRDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhQ1NTID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nVmFsdWVzID0gW3BhZGRpbmcudCwgcGFkZGluZy5yLCBwYWRkaW5nLmIsIHBhZGRpbmcubF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUb3BSaWdodEJvdHRvbUxlZnQoY29udGVudEdsdWVFbGVtZW50Q1NTLCBfc3RyTWFyZ2luTWludXMsIFstcGFkZGluZy50LCAtcGFkZGluZy5yLCAtcGFkZGluZy5iLCAtcGFkZGluZy5sXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYWRkaW5nQWJzb2x1dGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFRvcFJpZ2h0Qm90dG9tTGVmdChwYWRkaW5nRWxlbWVudENTUywgX3N0ckVtcHR5LCBwYWRkaW5nVmFsdWVzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFRvcFJpZ2h0Qm90dG9tTGVmdChfaXNUZXh0YXJlYSA/IHRleHRhcmVhQ1NTIDogY29udGVudEVsZW1lbnRDU1MsIF9zdHJQYWRkaW5nTWludXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VG9wUmlnaHRCb3R0b21MZWZ0KHBhZGRpbmdFbGVtZW50Q1NTLCBfc3RyRW1wdHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VG9wUmlnaHRCb3R0b21MZWZ0KF9pc1RleHRhcmVhID8gdGV4dGFyZWFDU1MgOiBjb250ZW50RWxlbWVudENTUywgX3N0clBhZGRpbmdNaW51cywgcGFkZGluZ1ZhbHVlcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nRWxlbWVudC5jc3MocGFkZGluZ0VsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0RWxlbWVudC5jc3ModGV4dGFyZWFDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy92aWV3cG9ydCBzaXplIGlzIHBhZGRpbmcgY29udGFpbmVyIGJlY2F1c2UgaXQgbmV2ZXIgaGFzIHBhZGRpbmcsIG1hcmdpbiBhbmQgYSBib3JkZXIuXHJcbiAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0U2l6ZSA9IGdldFZpZXdwb3J0U2l6ZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3VwZGF0ZSBUZXh0YXJlYVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYVNpemUgPSBfaXNUZXh0YXJlYSA/IHRleHRhcmVhVXBkYXRlKCkgOiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFTaXplQ2hhbmdlZCA9IF9pc1RleHRhcmVhICYmIGNoZWNrQ2FjaGVBdXRvRm9yY2UodGV4dGFyZWFTaXplLCBfdGV4dGFyZWFTaXplQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUR5bk9yaWdTaXplID0gX2lzVGV4dGFyZWEgJiYgdGV4dGFyZWFTaXplID8ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3OiB0ZXh0YXJlYUR5bldpZHRoID8gdGV4dGFyZWFTaXplLl9keW5hbWljV2lkdGggOiB0ZXh0YXJlYVNpemUuX29yaWdpbmFsV2lkdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGg6IHRleHRhcmVhRHluSGVpZ2h0ID8gdGV4dGFyZWFTaXplLl9keW5hbWljSGVpZ2h0IDogdGV4dGFyZWFTaXplLl9vcmlnaW5hbEhlaWdodFxyXG4gICAgICAgICAgICAgICAgICAgIH0gOiB7fTtcclxuICAgICAgICAgICAgICAgICAgICBfdGV4dGFyZWFTaXplQ2FjaGUgPSB0ZXh0YXJlYVNpemU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZml4IGhlaWdodCBhdXRvIC8gd2lkdGggYXV0byBpbiBjb29wZXJhdGlvbiB3aXRoIGN1cnJlbnQgcGFkZGluZyAmIGJveFNpemluZyBiZWhhdmlvcjpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaGVpZ2h0QXV0byAmJiAoaGVpZ2h0QXV0b0NoYW5nZWQgfHwgcGFkZGluZ0Fic29sdXRlQ2hhbmdlZCB8fCBib3hTaXppbmdDaGFuZ2VkIHx8IHBhZGRpbmcuYyB8fCBib3JkZXIuYykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ckhlaWdodF0gPSBfc3RyQXV0bztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoaGVpZ2h0QXV0b0NoYW5nZWQgfHwgcGFkZGluZ0Fic29sdXRlQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RySGVpZ2h0XSA9IF9zdHJIdW5kcmVkUGVyY2VudDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdpZHRoQXV0byAmJiAod2lkdGhBdXRvQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgcGFkZGluZy5jIHx8IGJvcmRlci5jIHx8IGNzc0RpcmVjdGlvbkNoYW5nZWQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBfc3RyQXV0bztcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEdsdWVFbGVtZW50Q1NTW19zdHJNYXhNaW51cyArIF9zdHJXaWR0aF0gPSBfc3RySHVuZHJlZFBlcmNlbnQ7IC8vSUUgRml4XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHdpZHRoQXV0b0NoYW5nZWQgfHwgcGFkZGluZ0Fic29sdXRlQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyV2lkdGhdID0gX3N0ckh1bmRyZWRQZXJjZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyRmxvYXRdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1NbX3N0ck1heE1pbnVzICsgX3N0cldpZHRoXSA9IF9zdHJFbXB0eTsgLy9JRSBGaXhcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdpZHRoQXV0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3RleHRhcmVhRHluT3JpZ1NpemUudyB8fCBfc3RyQXV0byA6OiBkb2VzbnQgd29ya3MgYmVjYXVzZSBhcHBsaWVkIG1hcmdpbiB3aWxsIHNoaWZ0IHdpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RyV2lkdGhdID0gX3N0ckF1dG87XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyV2lkdGhdID0gVkVORE9SUy5fY3NzUHJvcGVydHlWYWx1ZShfc3RyV2lkdGgsICdtYXgtY29udGVudCBpbnRyaW5zaWMnKSB8fCBfc3RyQXV0bztcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ckZsb2F0XSA9IGlzUlRMUmlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1NbX3N0cldpZHRoXSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhlaWdodEF1dG8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy90ZXh0YXJlYUR5bk9yaWdTaXplLmggfHwgX2NvbnRlbnRFbGVtZW50TmF0aXZlW0xFWElDT04uY0hdIDo6IHVzZSBmb3IgYW50aSBzY3JvbGwganVtcGluZ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1NbX3N0ckhlaWdodF0gPSB0ZXh0YXJlYUR5bk9yaWdTaXplLmggfHwgX2NvbnRlbnRFbGVtZW50TmF0aXZlW0xFWElDT04uY0hdO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEdsdWVFbGVtZW50Q1NTW19zdHJIZWlnaHRdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG9DYXBhYmxlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEdsdWVFbGVtZW50LmNzcyhjb250ZW50R2x1ZUVsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoY29udGVudEVsZW1lbnRDU1MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL0NIRUNLUE9JTlQgSEVSRSB+XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1MgPSB7fTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9pZiBbY29udGVudChob3N0KSBjbGllbnQgLyBzY3JvbGwgc2l6ZSwgb3IgdGFyZ2V0IGVsZW1lbnQgZGlyZWN0aW9uLCBvciBjb250ZW50KGhvc3QpIG1heC1zaXplc10gY2hhbmdlZCwgb3IgZm9yY2UgaXMgdHJ1ZVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChob3N0U2l6ZUNoYW5nZWQgfHwgY29udGVudFNpemVDaGFuZ2VkIHx8IHRleHRhcmVhU2l6ZUNoYW5nZWQgfHwgY3NzRGlyZWN0aW9uQ2hhbmdlZCB8fCBib3hTaXppbmdDaGFuZ2VkIHx8IHBhZGRpbmdBYnNvbHV0ZUNoYW5nZWQgfHwgd2lkdGhBdXRvQ2hhbmdlZCB8fCB3aWR0aEF1dG8gfHwgaGVpZ2h0QXV0b0NoYW5nZWQgfHwgaGVpZ2h0QXV0byB8fCBpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nQ2hhbmdlZCB8fCBvdmVyZmxvd0JlaGF2aW9yQ2hhbmdlZCB8fCBjbGlwQWx3YXlzQ2hhbmdlZCB8fCByZXNpemVDaGFuZ2VkIHx8IHNjcm9sbGJhcnNWaXNpYmlsaXR5Q2hhbmdlZCB8fCBzY3JvbGxiYXJzQXV0b0hpZGVDaGFuZ2VkIHx8IHNjcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2hhbmdlZCB8fCBzY3JvbGxiYXJzQ2xpY2tTY3JvbGxpbmdDaGFuZ2VkIHx8IHRleHRhcmVhRHluV2lkdGhDaGFuZ2VkIHx8IHRleHRhcmVhRHluSGVpZ2h0Q2hhbmdlZCB8fCB0ZXh0YXJlYUF1dG9XcmFwcGluZ0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0ck92ZXJmbG93ID0gJ292ZXJmbG93JztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0ck92ZXJmbG93WCA9IHN0ck92ZXJmbG93ICsgJy14JztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0ck92ZXJmbG93WSA9IHN0ck92ZXJmbG93ICsgJy15JztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckhpZGRlbiA9ICdoaWRkZW4nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyVmlzaWJsZSA9ICd2aXNpYmxlJztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vUmVzZXQgdGhlIHZpZXdwb3J0ICh2ZXJ5IGltcG9ydGFudCBmb3IgbmF0aXZlbHkgb3ZlcmxhaWQgc2Nyb2xsYmFycyBhbmQgem9vbSBjaGFuZ2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9kb24ndCBjaGFuZ2UgdGhlIG92ZXJmbG93IHByb3AgYXMgaXQgaXMgdmVyeSBleHBlbnNpdmUgYW5kIGFmZmVjdHMgcGVyZm9ybWFuY2UgIUEgTE9UIVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRFbGVtZW50UmVzZXRDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNldFhUbXAgPSBfaGFzT3ZlcmZsb3dDYWNoZS55ICYmIF9oaWRlT3ZlcmZsb3dDYWNoZS55cyAmJiAhaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZyA/IChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55ID8gX3ZpZXdwb3J0RWxlbWVudC5jc3MoaXNSVExMZWZ0KSA6IC1fbmF0aXZlU2Nyb2xsYmFyU2l6ZS55KSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzZXRCb3R0b21UbXAgPSBfaGFzT3ZlcmZsb3dDYWNoZS54ICYmIF9oaWRlT3ZlcmZsb3dDYWNoZS54cyAmJiAhaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZyA/IChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ID8gX3ZpZXdwb3J0RWxlbWVudC5jc3MoX3N0ckJvdHRvbSkgOiAtX25hdGl2ZVNjcm9sbGJhclNpemUueCkgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VG9wUmlnaHRCb3R0b21MZWZ0KHZpZXdwb3J0RWxlbWVudFJlc2V0Q1NTLCBfc3RyRW1wdHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudC5jc3Modmlld3BvcnRFbGVtZW50UmVzZXRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21lYXN1cmUgc2V2ZXJhbCBzaXplczpcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRNZWFzdXJlRWxlbWVudCA9IGdldENvbnRlbnRNZWFzdXJlRWxlbWVudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2luIEZpcmVmb3ggY29udGVudCBlbGVtZW50IGhhcyB0byBoYXZlIG92ZXJmbG93IGhpZGRlbiwgZWxzZSBlbGVtZW50IG1hcmdpbnMgYXJlbid0IGNhbGN1bGF0ZWQgcHJvcGVybHksIHRoaXMgZWxlbWVudCBwcmV2ZW50cyB0aGlzIGJ1ZywgYnV0IG9ubHkgaWYgc2Nyb2xsYmFycyBhcmVuJ3Qgb3ZlcmxhaWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRTaXplID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy91c2UgY2xpZW50U2l6ZSBiZWNhdXNlIG5hdGl2ZWx5IG92ZXJsYWlkU2Nyb2xsYmFycyBhZGQgYm9yZGVyc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogdGV4dGFyZWFEeW5PcmlnU2l6ZS53IHx8IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLmNXXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IHRleHRhcmVhRHluT3JpZ1NpemUuaCB8fCBjb250ZW50TWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5jSF1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBjb250ZW50TWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5zV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBjb250ZW50TWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5zSF1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYXBwbHkgdGhlIGNvcnJlY3Qgdmlld3BvcnQgc3R5bGUgYW5kIG1lYXN1cmUgdmlld3BvcnQgc2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRSZXNldENTU1tfc3RyQm90dG9tXSA9IHdhc0hlaWdodEF1dG8gPyBfc3RyRW1wdHkgOiByZXNldEJvdHRvbVRtcDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudFJlc2V0Q1NTW2lzUlRMTGVmdF0gPSB3YXNXaWR0aEF1dG8gPyBfc3RyRW1wdHkgOiByZXNldFhUbXA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50LmNzcyh2aWV3cG9ydEVsZW1lbnRSZXNldENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0U2l6ZSA9IGdldFZpZXdwb3J0U2l6ZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tZWFzdXJlIGFuZCBjb3JyZWN0IHNldmVyYWwgc2l6ZXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhvc3RTaXplID0gZ2V0SG9zdFNpemUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhvc3RBYnNvbHV0ZVJlY3RTaXplID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogaG9zdFNpemUudyAtIF9tYXJnaW5YIC0gX2JvcmRlclggLSAoX2lzQm9yZGVyQm94ID8gMCA6IF9wYWRkaW5nWCksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBob3N0U2l6ZS5oIC0gX21hcmdpblkgLSBfYm9yZGVyWSAtIChfaXNCb3JkZXJCb3ggPyAwIDogX3BhZGRpbmdZKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudEdsdWVTaXplID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9jbGllbnQvc2Nyb2xsU2l6ZSArIEFic29sdXRlUGFkZGluZyAtPiBiZWNhdXNlIHBhZGRpbmcgaXMgb25seSBhcHBsaWVkIHRvIHRoZSBwYWRkaW5nRWxlbWVudCBpZiBpdHMgYWJzb2x1dGUsIHNvIHlvdSBoYXZlIHRvIGFkZCBpdCBtYW51YWxseVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9ob3N0U2l6ZSBpcyBjbGllbnRTaXplIC0+IHNvIHBhZGRpbmcgc2hvdWxkIGJlIGFkZGVkIG1hbnVhbGx5LCByaWdodD8gRkFMU0UhIEJlY2F1c2UgY29udGVudCBnbHVlIGlzIGluc2lkZSBob3N0RWxlbWVudCwgc28gd2UgZG9uJ3QgaGF2ZSB0byB3b3JyeSBhYm91dCBwYWRkaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBNQVRILm1heCgod2lkdGhBdXRvID8gY29udGVudFNpemUudyA6IHNjcm9sbFNpemUudykgKyBwYWRkaW5nQWJzb2x1dGVYLCBob3N0QWJzb2x1dGVSZWN0U2l6ZS53KSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IE1BVEgubWF4KChoZWlnaHRBdXRvID8gY29udGVudFNpemUuaCA6IHNjcm9sbFNpemUuaCkgKyBwYWRkaW5nQWJzb2x1dGVZLCBob3N0QWJzb2x1dGVSZWN0U2l6ZS5oKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZVNpemUuYyA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoY29udGVudEdsdWVTaXplLCBfY29udGVudEdsdWVTaXplQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEdsdWVTaXplQ2FjaGUgPSBjb250ZW50R2x1ZVNpemU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2FwcGx5IGNvcnJlY3QgY29udGVudEdsdWUgc2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG9DYXBhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3NpemUgY29udGVudEdsdWUgY29ycmVjdGx5IHRvIG1ha2Ugc3VyZSB0aGUgZWxlbWVudCBoYXMgY29ycmVjdCBzaXplIGlmIHRoZSBzaXppbmcgc3dpdGNoZXMgdG8gYXV0b1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRHbHVlU2l6ZS5jIHx8IChoZWlnaHRBdXRvIHx8IHdpZHRoQXV0bykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1NbX3N0cldpZHRoXSA9IGNvbnRlbnRHbHVlU2l6ZS53O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RySGVpZ2h0XSA9IGNvbnRlbnRHbHVlU2l6ZS5oO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RleHRhcmVhLXNpemVzIGFyZSBhbHJlYWR5IGNhbGN1bGF0ZWQgY29ycmVjdGx5IGF0IHRoaXMgcG9pbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9pc1RleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRTaXplID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy91c2UgY2xpZW50U2l6ZSBiZWNhdXNlIG5hdGl2ZWx5IG92ZXJsYWlkU2Nyb2xsYmFycyBhZGQgYm9yZGVyc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogY29udGVudE1lYXN1cmVFbGVtZW50W0xFWElDT04uY1ddLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogY29udGVudE1lYXN1cmVFbGVtZW50W0xFWElDT04uY0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhQ292ZXJDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzZXRDb250ZW50R2x1ZUVsZW1lbnRDU1NmdW5jdGlvbiA9IGZ1bmN0aW9uIChob3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhclZhcnMgPSBnZXRTY3JvbGxiYXJWYXJzKGhvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aCA9IHNjcm9sbGJhclZhcnMuX3dfaDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyV0ggPSBzY3JvbGxiYXJWYXJzLl93aWR0aF9oZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGF1dG9TaXplID0gaG9yaXpvbnRhbCA/IHdpZHRoQXV0byA6IGhlaWdodEF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGJvcmRlclNpemUgPSBob3Jpem9udGFsID8gX2JvcmRlclggOiBfYm9yZGVyWTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ1NpemUgPSBob3Jpem9udGFsID8gX3BhZGRpbmdYIDogX3BhZGRpbmdZO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtYXJnaW5TaXplID0gaG9yaXpvbnRhbCA/IF9tYXJnaW5YIDogX21hcmdpblk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZpZXdwb3J0U2l6ZSA9IF92aWV3cG9ydFNpemVbd2hdIC0gYm9yZGVyU2l6ZSAtIG1hcmdpblNpemUgLSAoX2lzQm9yZGVyQm94ID8gMCA6IHBhZGRpbmdTaXplKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9tYWtlIGNvbnRlbnRHbHVlIHNpemUgLTEgaWYgZWxlbWVudCBpcyBub3QgYXV0byBzaXplZCwgdG8gbWFrZSBzdXJlIHRoYXQgYSByZXNpemUgZXZlbnQgaGFwcGVucyB3aGVuIHRoZSBlbGVtZW50IHNocmlua3NcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWF1dG9TaXplIHx8ICghYXV0b1NpemUgJiYgYm9yZGVyLmMpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1Nbc3RyV0hdID0gaG9zdEFic29sdXRlUmVjdFNpemVbd2hdIC0gMTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiBzaXplIGlzIGF1dG8gYW5kIGhvc3QgaXMgc21hbGxlciB0aGFuIHNpemUgYXMgbWluIHNpemUsIG1ha2UgY29udGVudCBnbHVlIHNpemUgLTEgdG8gbWFrZSBzdXJlIHNpemUgY2hhbmdlcyB3aWxsIGJlIGRldGVjdGVkICh0aGlzIGlzIG9ubHkgbmVlZGVkIGlmIHBhZGRpbmcgaXMgMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXV0b1NpemUgJiYgKGNvbnRlbnRTaXplW3doXSA8IHZpZXdwb3J0U2l6ZSkgJiYgKGhvcml6b250YWwgJiYgX2lzVGV4dGFyZWEgPyAhdGV4dGFyZWFBdXRvV3JhcHBpbmcgOiB0cnVlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzVGV4dGFyZWEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYUNvdmVyQ1NTW3N0cldIXSA9IHBhcnNlVG9aZXJvT3JOdW1iZXIoX3RleHRhcmVhQ292ZXJFbGVtZW50LmNzcyhzdHJXSCkpIC0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEdsdWVFbGVtZW50Q1NTW3N0cldIXSAtPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9tYWtlIHN1cmUgY29udGVudCBnbHVlIHNpemUgaXMgYXQgbGVhc3QgMVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50U2l6ZVt3aF0gPiAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1Nbc3RyV0hdID0gTUFUSC5tYXgoMSwgY29udGVudEdsdWVFbGVtZW50Q1NTW3N0cldIXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0Q29udGVudEdsdWVFbGVtZW50Q1NTZnVuY3Rpb24odHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRDb250ZW50R2x1ZUVsZW1lbnRDU1NmdW5jdGlvbihmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUNvdmVyRWxlbWVudC5jc3ModGV4dGFyZWFDb3ZlckNTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEdsdWVFbGVtZW50LmNzcyhjb250ZW50R2x1ZUVsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3aWR0aEF1dG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyV2lkdGhdID0gX3N0ckh1bmRyZWRQZXJjZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAod2lkdGhBdXRvICYmICFfaXNCb3JkZXJCb3ggJiYgIV9tdXRhdGlvbk9ic2VydmVyc0Nvbm5lY3RlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJGbG9hdF0gPSAnbm9uZSc7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2FwcGx5IGFuZCByZXNldCBjb250ZW50IHN0eWxlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoY29udGVudEVsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTUyA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tZWFzdXJlIGFnYWluLCBidXQgdGhpcyB0aW1lIGFsbCBjb3JyZWN0IHNpemVzOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudFNjcm9sbFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBjb250ZW50TWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5zV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBjb250ZW50TWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5zSF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRTY3JvbGxTaXplLmMgPSBjb250ZW50U2l6ZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGNvbnRlbnRTY3JvbGxTaXplLCBfY29udGVudFNjcm9sbFNpemVDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50U2Nyb2xsU2l6ZUNhY2hlID0gY29udGVudFNjcm9sbFNpemU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3JlZnJlc2ggdmlld3BvcnQgc2l6ZSBhZnRlciBjb3JyZWN0IG1lYXN1cmluZ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRTaXplID0gZ2V0Vmlld3BvcnRTaXplKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBob3N0U2l6ZSA9IGdldEhvc3RTaXplKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RTaXplQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoaG9zdFNpemUsIF9ob3N0U2l6ZUNhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RTaXplQ2FjaGUgPSBob3N0U2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoaWRlT3ZlcmZsb3dGb3JjZVRleHRhcmVhID0gX2lzVGV4dGFyZWEgJiYgKF92aWV3cG9ydFNpemUudyA9PT0gMCB8fCBfdmlld3BvcnRTaXplLmggPT09IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcHJldmlvdXNPdmVyZmxvd0Ftb3VudCA9IF9vdmVyZmxvd0Ftb3VudENhY2hlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3ZlcmZsb3dCZWhhdmlvcklzVlMgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QmVoYXZpb3JJc1ZIID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvdmVyZmxvd0JlaGF2aW9ySXNTID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvdmVyZmxvd0Ftb3VudCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGFzT3ZlcmZsb3cgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhpZGVPdmVyZmxvdyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2FuU2Nyb2xsID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2aWV3cG9ydFJlY3QgPSBfcGFkZGluZ0VsZW1lbnROYXRpdmVbTEVYSUNPTi5iQ1JdKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzZXRPdmVyZmxvd1ZhcmlhYmxlcyA9IGZ1bmN0aW9uIChob3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFycyA9IGdldFNjcm9sbGJhclZhcnMoaG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFyc0ludmVydGVkID0gZ2V0U2Nyb2xsYmFyVmFycyghaG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgeHlJID0gc2Nyb2xsYmFyVmFyc0ludmVydGVkLl94X3k7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgeHkgPSBzY3JvbGxiYXJWYXJzLl94X3k7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2ggPSBzY3JvbGxiYXJWYXJzLl93X2g7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2lkdGhIZWlnaHQgPSBzY3JvbGxiYXJWYXJzLl93aWR0aF9oZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsTWF4ID0gX3N0clNjcm9sbCArIHNjcm9sbGJhclZhcnMuX0xlZnRfVG9wICsgJ01heCc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZnJhY3Rpb25hbE92ZXJmbG93QW1vdW50ID0gdmlld3BvcnRSZWN0W3dpZHRoSGVpZ2h0XSA/IE1BVEguYWJzKHZpZXdwb3J0UmVjdFt3aWR0aEhlaWdodF0gLSBfdmlld3BvcnRTaXplW3doXSkgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoZWNrRnJhY3Rpb25hbE92ZXJmbG93QW1vdW50ID0gcHJldmlvdXNPdmVyZmxvd0Ftb3VudCAmJiBwcmV2aW91c092ZXJmbG93QW1vdW50W3h5XSA+IDAgJiYgX3ZpZXdwb3J0RWxlbWVudE5hdGl2ZVtzY3JvbGxNYXhdID09PSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmZsb3dCZWhhdmlvcklzVlNbeHldID0gb3ZlcmZsb3dCZWhhdmlvclt4eV0gPT09ICd2LXMnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmZsb3dCZWhhdmlvcklzVkhbeHldID0gb3ZlcmZsb3dCZWhhdmlvclt4eV0gPT09ICd2LWgnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmZsb3dCZWhhdmlvcklzU1t4eV0gPSBvdmVyZmxvd0JlaGF2aW9yW3h5XSA9PT0gJ3MnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmZsb3dBbW91bnRbeHldID0gTUFUSC5tYXgoMCwgTUFUSC5yb3VuZCgoY29udGVudFNjcm9sbFNpemVbd2hdIC0gX3ZpZXdwb3J0U2l6ZVt3aF0pICogMTAwKSAvIDEwMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0Ftb3VudFt4eV0gKj0gKGhpZGVPdmVyZmxvd0ZvcmNlVGV4dGFyZWEgfHwgKGNoZWNrRnJhY3Rpb25hbE92ZXJmbG93QW1vdW50ICYmIGZyYWN0aW9uYWxPdmVyZmxvd0Ftb3VudCA+IDAgJiYgZnJhY3Rpb25hbE92ZXJmbG93QW1vdW50IDwgMSkpID8gMCA6IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXNPdmVyZmxvd1t4eV0gPSBvdmVyZmxvd0Ftb3VudFt4eV0gPiAwO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaGlkZU92ZXJmbG93OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy94IHx8IHkgOiB0cnVlID09PSBvdmVyZmxvdyBpcyBoaWRkZW4gYnkgXCJvdmVyZmxvdzogc2Nyb2xsXCIgT1IgXCJvdmVyZmxvdzogaGlkZGVuXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8veHMgfHwgeXMgOiB0cnVlID09PSBvdmVyZmxvdyBpcyBoaWRkZW4gYnkgXCJvdmVyZmxvdzogc2Nyb2xsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZGVPdmVyZmxvd1t4eV0gPSBvdmVyZmxvd0JlaGF2aW9ySXNWU1t4eV0gfHwgb3ZlcmZsb3dCZWhhdmlvcklzVkhbeHldID8gKGhhc092ZXJmbG93W3h5SV0gJiYgIW92ZXJmbG93QmVoYXZpb3JJc1ZTW3h5SV0gJiYgIW92ZXJmbG93QmVoYXZpb3JJc1ZIW3h5SV0pIDogaGFzT3ZlcmZsb3dbeHldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZU92ZXJmbG93W3h5ICsgJ3MnXSA9IGhpZGVPdmVyZmxvd1t4eV0gPyAob3ZlcmZsb3dCZWhhdmlvcklzU1t4eV0gfHwgb3ZlcmZsb3dCZWhhdmlvcklzVlNbeHldKSA6IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhblNjcm9sbFt4eV0gPSBoYXNPdmVyZmxvd1t4eV0gJiYgaGlkZU92ZXJmbG93W3h5ICsgJ3MnXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0T3ZlcmZsb3dWYXJpYWJsZXModHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldE92ZXJmbG93VmFyaWFibGVzKGZhbHNlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJmbG93QW1vdW50LmMgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKG92ZXJmbG93QW1vdW50LCBfb3ZlcmZsb3dBbW91bnRDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9vdmVyZmxvd0Ftb3VudENhY2hlID0gb3ZlcmZsb3dBbW91bnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc092ZXJmbG93LmMgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGhhc092ZXJmbG93LCBfaGFzT3ZlcmZsb3dDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9oYXNPdmVyZmxvd0NhY2hlID0gaGFzT3ZlcmZsb3c7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhpZGVPdmVyZmxvdy5jID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShoaWRlT3ZlcmZsb3csIF9oaWRlT3ZlcmZsb3dDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9oaWRlT3ZlcmZsb3dDYWNoZSA9IGhpZGVPdmVyZmxvdztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgbmF0aXZlIHNjcm9sbGJhciBpcyBvdmVybGF5IGF0IHggT1IgeSBheGlzLCBwcmVwYXJlIERPTVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueCB8fCBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYm9yZGVyRGVzaWduID0gJ3B4IHNvbGlkIHRyYW5zcGFyZW50JztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50QXJyYW5nZUVsZW1lbnRDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhcnJhbmdlQ29udGVudCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFycmFuZ2VDaGFuZ2VkID0gZm9yY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2V0Q29udGVudEVsZW1lbnRDU1M7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhhc092ZXJmbG93LnggfHwgaGFzT3ZlcmZsb3cueSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmFuZ2VDb250ZW50LncgPSBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55ICYmIGhhc092ZXJmbG93LnkgPyBjb250ZW50U2Nyb2xsU2l6ZS53ICsgX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemUueSA6IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlQ29udGVudC5oID0gX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueCAmJiBoYXNPdmVyZmxvdy54ID8gY29udGVudFNjcm9sbFNpemUuaCArIF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplLnggOiBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYW5nZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGFycmFuZ2VDb250ZW50LCBfYXJyYW5nZUNvbnRlbnRTaXplQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9hcnJhbmdlQ29udGVudFNpemVDYWNoZSA9IGFycmFuZ2VDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoYXNPdmVyZmxvdy5jIHx8IGhpZGVPdmVyZmxvdy5jIHx8IGNvbnRlbnRTY3JvbGxTaXplLmMgfHwgY3NzRGlyZWN0aW9uQ2hhbmdlZCB8fCB3aWR0aEF1dG9DaGFuZ2VkIHx8IGhlaWdodEF1dG9DaGFuZ2VkIHx8IHdpZHRoQXV0byB8fCBoZWlnaHRBdXRvIHx8IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ck1hcmdpbk1pbnVzICsgaXNSVExSaWdodF0gPSBjb250ZW50RWxlbWVudENTU1tfc3RyQm9yZGVyTWludXMgKyBpc1JUTFJpZ2h0XSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRDb250ZW50RWxlbWVudENTUyA9IGZ1bmN0aW9uIChob3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhob3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhclZhcnNJbnZlcnRlZCA9IGdldFNjcm9sbGJhclZhcnMoIWhvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgeHkgPSBzY3JvbGxiYXJWYXJzLl94X3k7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJEaXJlY3Rpb24gPSBob3Jpem9udGFsID8gX3N0ckJvdHRvbSA6IGlzUlRMTGVmdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGludmVydGVkQXV0b1NpemUgPSBob3Jpem9udGFsID8gaGVpZ2h0QXV0byA6IHdpZHRoQXV0bztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZFt4eV0gJiYgaGFzT3ZlcmZsb3dbeHldICYmIGhpZGVPdmVyZmxvd1t4eSArICdzJ10pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJNYXJnaW5NaW51cyArIHN0ckRpcmVjdGlvbl0gPSBpbnZlcnRlZEF1dG9TaXplID8gKGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmcgPyBfc3RyRW1wdHkgOiBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZVt4eV0pIDogX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ckJvcmRlck1pbnVzICsgc3RyRGlyZWN0aW9uXSA9ICgoaG9yaXpvbnRhbCA/ICFpbnZlcnRlZEF1dG9TaXplIDogdHJ1ZSkgJiYgIWlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmcpID8gKF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplW3h5XSArIGJvcmRlckRlc2lnbikgOiBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlQ29udGVudFtzY3JvbGxiYXJWYXJzSW52ZXJ0ZWQuX3dfaF0gPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJNYXJnaW5NaW51cyArIHN0ckRpcmVjdGlvbl0gPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJCb3JkZXJNaW51cyArIHN0ckRpcmVjdGlvbl0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlQ2hhbmdlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX3ZpZXdwb3J0RWxlbWVudCwgX2NsYXNzTmFtZVZpZXdwb3J0TmF0aXZlU2Nyb2xsYmFyc0ludmlzaWJsZSwgIWlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRDb250ZW50RWxlbWVudENTUyh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0Q29udGVudEVsZW1lbnRDU1MoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYW5nZUNvbnRlbnQudyA9IGFycmFuZ2VDb250ZW50LmggPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYW5nZUNoYW5nZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFycmFuZ2VDaGFuZ2VkICYmICFfbmF0aXZlU2Nyb2xsYmFyU3R5bGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRBcnJhbmdlRWxlbWVudENTU1tfc3RyV2lkdGhdID0gaGlkZU92ZXJmbG93LnkgPyBhcnJhbmdlQ29udGVudC53IDogX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRBcnJhbmdlRWxlbWVudENTU1tfc3RySGVpZ2h0XSA9IGhpZGVPdmVyZmxvdy54ID8gYXJyYW5nZUNvbnRlbnQuaCA6IF9zdHJFbXB0eTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfY29udGVudEFycmFuZ2VFbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50QXJyYW5nZUVsZW1lbnQgPSBGUkFNRVdPUksoZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZUNvbnRlbnRBcnJhbmdlRWxlbWVudCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50LnByZXBlbmQoX2NvbnRlbnRBcnJhbmdlRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50QXJyYW5nZUVsZW1lbnQuY3NzKGNvbnRlbnRBcnJhbmdlRWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnQuY3NzKGNvbnRlbnRFbGVtZW50Q1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZpZXdwb3J0RWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ0VsZW1lbnRDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNldFZpZXdwb3J0Q1NTO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaG9zdFNpemVDaGFuZ2VkIHx8IGhhc092ZXJmbG93LmMgfHwgaGlkZU92ZXJmbG93LmMgfHwgY29udGVudFNjcm9sbFNpemUuYyB8fCBvdmVyZmxvd0JlaGF2aW9yQ2hhbmdlZCB8fCBib3hTaXppbmdDaGFuZ2VkIHx8IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkIHx8IGNzc0RpcmVjdGlvbkNoYW5nZWQgfHwgY2xpcEFsd2F5c0NoYW5nZWQgfHwgaGVpZ2h0QXV0b0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tpc1JUTFJpZ2h0XSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFZpZXdwb3J0Q1NTID0gZnVuY3Rpb24gKGhvcml6b250YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFycyA9IGdldFNjcm9sbGJhclZhcnMoaG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhclZhcnNJbnZlcnRlZCA9IGdldFNjcm9sbGJhclZhcnMoIWhvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4eSA9IHNjcm9sbGJhclZhcnMuX3hfeTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgWFkgPSBzY3JvbGxiYXJWYXJzLl9YX1k7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckRpcmVjdGlvbiA9IGhvcml6b250YWwgPyBfc3RyQm90dG9tIDogaXNSVExMZWZ0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzZXQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tzdHJEaXJlY3Rpb25dID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEJvcmRlclNpemVbc2Nyb2xsYmFyVmFyc0ludmVydGVkLl93X2hdID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoYXNPdmVyZmxvd1t4eV0gJiYgaGlkZU92ZXJmbG93W3h5ICsgJ3MnXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1Nbc3RyT3ZlcmZsb3cgKyBYWV0gPSBfc3RyU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZyB8fCBfbmF0aXZlU2Nyb2xsYmFyU3R5bGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tzdHJEaXJlY3Rpb25dID0gLShfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZFt4eV0gPyBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZVt4eV0gOiBfbmF0aXZlU2Nyb2xsYmFyU2l6ZVt4eV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRCb3JkZXJTaXplW3Njcm9sbGJhclZhcnNJbnZlcnRlZC5fd19oXSA9IF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkW3h5XSA/IF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplW3Njcm9sbGJhclZhcnNJbnZlcnRlZC5feF95XSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1Nbc3RyT3ZlcmZsb3cgKyBYWV0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFZpZXdwb3J0Q1NTKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0Vmlld3BvcnRDU1MoZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBzY3JvbGwgY29udGFpbmVyIGlzIHRvbyBzbWFsbCBhbmQgaWYgdGhlcmUgaXMgYW55IG92ZXJmbG93IHdpdGggbm8gb3ZlcmxheSBzY3JvbGxiYXIgKGFuZCBzY3JvbGxiYXIgc3R5bGluZyBpc24ndCBwb3NzaWJsZSksIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWFrZSB2aWV3cG9ydCBlbGVtZW50IGdyZWF0ZXIgaW4gc2l6ZSAoRmlyZWZveCBoaWRlIFNjcm9sbGJhcnMgZml4KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBmaXJlZm94IHN0YXJ0cyBoaWRpbmcgc2Nyb2xsYmFycyBvbiB0b28gc21hbGwgZWxlbWVudHNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdpdGggdGhpcyBiZWhhdmlvciB0aGUgb3ZlcmZsb3cgY2FsY3VsYXRpb24gbWF5IGJlIGluY29ycmVjdCBvciB0aGUgc2Nyb2xsYmFycyB3b3VsZCBhcHBlYXIgc3VkZGVubHlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTI5MjI4NFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfbmF0aXZlU2Nyb2xsYmFyU3R5bGluZ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIChfdmlld3BvcnRTaXplLmggPCBfbmF0aXZlU2Nyb2xsYmFyTWluU2l6ZS54IHx8IF92aWV3cG9ydFNpemUudyA8IF9uYXRpdmVTY3JvbGxiYXJNaW5TaXplLnkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKChoYXNPdmVyZmxvdy54ICYmIGhpZGVPdmVyZmxvdy54ICYmICFfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54KSB8fCAoaGFzT3ZlcmZsb3cueSAmJiBoaWRlT3ZlcmZsb3cueSAmJiAhX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJQYWRkaW5nTWludXMgKyBfc3RyVG9wXSA9IF9uYXRpdmVTY3JvbGxiYXJNaW5TaXplLng7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJNYXJnaW5NaW51cyArIF9zdHJUb3BdID0gLV9uYXRpdmVTY3JvbGxiYXJNaW5TaXplLng7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tfc3RyUGFkZGluZ01pbnVzICsgaXNSVExSaWdodF0gPSBfbmF0aXZlU2Nyb2xsYmFyTWluU2l6ZS55O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tfc3RyTWFyZ2luTWludXMgKyBpc1JUTFJpZ2h0XSA9IC1fbmF0aXZlU2Nyb2xsYmFyTWluU2l6ZS55O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJQYWRkaW5nTWludXMgKyBfc3RyVG9wXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tfc3RyTWFyZ2luTWludXMgKyBfc3RyVG9wXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tfc3RyUGFkZGluZ01pbnVzICsgaXNSVExSaWdodF0gPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1NbX3N0ck1hcmdpbk1pbnVzICsgaXNSVExSaWdodF0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1NbX3N0clBhZGRpbmdNaW51cyArIGlzUlRMTGVmdF0gPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tfc3RyTWFyZ2luTWludXMgKyBpc1JUTExlZnRdID0gX3N0ckVtcHR5O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgdGhlcmUgaXMgYW55IG92ZXJmbG93ICh4IE9SIHkgYXhpcykgYW5kIHRoaXMgb3ZlcmZsb3cgc2hhbGwgYmUgaGlkZGVuLCBtYWtlIG92ZXJmbG93IGhpZGRlbiwgZWxzZSBvdmVyZmxvdyB2aXNpYmxlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGhhc092ZXJmbG93LnggJiYgaGlkZU92ZXJmbG93LngpIHx8IChoYXNPdmVyZmxvdy55ICYmIGhpZGVPdmVyZmxvdy55KSB8fCBoaWRlT3ZlcmZsb3dGb3JjZVRleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9vbmx5IGhpZGUgaWYgaXMgVGV4dGFyZWFcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzVGV4dGFyZWEgJiYgaGlkZU92ZXJmbG93Rm9yY2VUZXh0YXJlYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWRkaW5nRWxlbWVudENTU1tzdHJPdmVyZmxvd1hdID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZGRpbmdFbGVtZW50Q1NTW3N0ck92ZXJmbG93WV0gPSBzdHJIaWRkZW47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjbGlwQWx3YXlzIHx8IChvdmVyZmxvd0JlaGF2aW9ySXNWSC54IHx8IG92ZXJmbG93QmVoYXZpb3JJc1ZTLnggfHwgb3ZlcmZsb3dCZWhhdmlvcklzVkgueSB8fCBvdmVyZmxvd0JlaGF2aW9ySXNWUy55KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL29ubHkgdW4taGlkZSBpZiBUZXh0YXJlYVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZGRpbmdFbGVtZW50Q1NTW3N0ck92ZXJmbG93WF0gPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZGRpbmdFbGVtZW50Q1NTW3N0ck92ZXJmbG93WV0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW3N0ck92ZXJmbG93WF0gPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW3N0ck92ZXJmbG93WV0gPSBzdHJWaXNpYmxlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcGFkZGluZ0VsZW1lbnQuY3NzKHBhZGRpbmdFbGVtZW50Q1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuY3NzKHZpZXdwb3J0RWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1MgPSB7fTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2ZvcmNlIHNvZnQgcmVkcmF3IGluIHdlYmtpdCBiZWNhdXNlIHdpdGhvdXQgdGhlIHNjcm9sbGJhcnMgd2lsbCBtYXkgYXBwZWFyIGJlY2F1c2UgRE9NIHdvbnQgYmUgcmVkcmF3biB1bmRlciBzcGVjaWFsIGNvbmRpdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoaGFzT3ZlcmZsb3cuYyB8fCBib3hTaXppbmdDaGFuZ2VkIHx8IHdpZHRoQXV0b0NoYW5nZWQgfHwgaGVpZ2h0QXV0b0NoYW5nZWQpICYmICEoX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueCAmJiBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50U3R5bGUgPSBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5zXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZHVtcDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3NjYWxlKDEpJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3R5bGUuZGlzcGxheSA9ICdydW4taW4nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1bXAgPSBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5vSF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFN0eWxlLmRpc3BsYXkgPSBfc3RyRW1wdHk7IC8vfHwgZHVtcDsgLy91c2UgZHVtcCB0byBwcmV2ZW50IGl0IGZyb20gZGVsZXRpb24gaWYgbWluaWZ5XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFN0eWxlLndlYmtpdFRyYW5zZm9ybSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2ZvcmNlIGhhcmQgcmVkcmF3IGluIHdlYmtpdCBpZiBuYXRpdmUgb3ZlcmxhaWQgc2Nyb2xsYmFycyBzaGFsbCBhcHBlYXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nQ2hhbmdlZCAmJiBpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50LmhpZGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZHVtcCA9IF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9IXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnQuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jaGFuZ2UgdG8gZGlyZWN0aW9uIFJUTCBhbmQgd2lkdGggYXV0byBCdWdmaXggaW4gV2Via2l0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vd2l0aG91dCB0aGlzIGZpeCwgdGhlIERPTSBzdGlsbCB0aGlua3MgdGhlIHNjcm9sbGJhciBpcyBMVFIgYW5kIHRodXMgdGhlIGNvbnRlbnQgaXMgc2hpZnRlZCB0byB0aGUgbGVmdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3NzRGlyZWN0aW9uQ2hhbmdlZCB8fCB3aWR0aEF1dG9DaGFuZ2VkIHx8IGhlaWdodEF1dG9DaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzUlRMICYmIHdpZHRoQXV0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmbG9hdFRtcCA9IF9jb250ZW50RWxlbWVudC5jc3MoX3N0ckZsb2F0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcG9zTGVmdFdpdGhvdXRGbG9hdCA9IE1BVEgucm91bmQoX2NvbnRlbnRFbGVtZW50LmNzcyhfc3RyRmxvYXQsIF9zdHJFbXB0eSkuY3NzKF9zdHJMZWZ0LCBfc3RyRW1wdHkpLnBvc2l0aW9uKCkubGVmdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhfc3RyRmxvYXQsIGZsb2F0VG1wKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcG9zTGVmdFdpdGhGbG9hdCA9IE1BVEgucm91bmQoX2NvbnRlbnRFbGVtZW50LnBvc2l0aW9uKCkubGVmdCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwb3NMZWZ0V2l0aG91dEZsb2F0ICE9PSBwb3NMZWZ0V2l0aEZsb2F0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyTGVmdF0gPSBwb3NMZWZ0V2l0aG91dEZsb2F0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ckxlZnRdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoY29udGVudEVsZW1lbnRDU1MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9oYW5kbGUgc2Nyb2xsIHBvc2l0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSAmJiBjb250ZW50U2l6ZUNoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUluZm8gPSBnZXRUZXh0YXJlYUluZm8oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0YXJlYUluZm8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFSb3dzQ2hhbmdlZCA9IF90ZXh0YXJlYUluZm9DYWNoZSA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6IHRleHRhcmVhSW5mby5fcm93cyAhPT0gX3RleHRhcmVhSW5mb0NhY2hlLl9yb3dzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JSb3cgPSB0ZXh0YXJlYUluZm8uX2N1cnNvclJvdztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3Vyc29yQ29sID0gdGV4dGFyZWFJbmZvLl9jdXJzb3JDb2x1bW47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHdpZGVzdFJvdyA9IHRleHRhcmVhSW5mby5fd2lkZXN0Um93O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsYXN0Um93ID0gdGV4dGFyZWFJbmZvLl9yb3dzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsYXN0Q29sID0gdGV4dGFyZWFJbmZvLl9jb2x1bW5zO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JQb3MgPSB0ZXh0YXJlYUluZm8uX2N1cnNvclBvc2l0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JNYXggPSB0ZXh0YXJlYUluZm8uX2N1cnNvck1heDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3Vyc29ySXNMYXN0UG9zaXRpb24gPSAoY3Vyc29yUG9zID49IGN1cnNvck1heCAmJiBfdGV4dGFyZWFIYXNGb2N1cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhU2Nyb2xsQW1vdW50ID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiAoIXRleHRhcmVhQXV0b1dyYXBwaW5nICYmIChjdXJzb3JDb2wgPT09IGxhc3RDb2wgJiYgY3Vyc29yUm93ID09PSB3aWRlc3RSb3cpKSA/IF9vdmVyZmxvd0Ftb3VudENhY2hlLnggOiAtMSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogKHRleHRhcmVhQXV0b1dyYXBwaW5nID8gY3Vyc29ySXNMYXN0UG9zaXRpb24gfHwgdGV4dGFyZWFSb3dzQ2hhbmdlZCAmJiAocHJldmlvdXNPdmVyZmxvd0Ftb3VudCA/IChjdXJyU2Nyb2xsLnkgPT09IHByZXZpb3VzT3ZlcmZsb3dBbW91bnQueSkgOiBmYWxzZSkgOiAoY3Vyc29ySXNMYXN0UG9zaXRpb24gfHwgdGV4dGFyZWFSb3dzQ2hhbmdlZCkgJiYgY3Vyc29yUm93ID09PSBsYXN0Um93KSA/IF9vdmVyZmxvd0Ftb3VudENhY2hlLnkgOiAtMVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyclNjcm9sbC54ID0gdGV4dGFyZWFTY3JvbGxBbW91bnQueCA+IC0xID8gKF9pc1JUTCAmJiBfbm9ybWFsaXplUlRMQ2FjaGUgJiYgX3J0bFNjcm9sbEJlaGF2aW9yLmkgPyAwIDogdGV4dGFyZWFTY3JvbGxBbW91bnQueCkgOiBjdXJyU2Nyb2xsLng7IC8vaWYgaW52ZXJ0ZWQsIHNjcm9sbCB0byAwIC0+IG5vcm1hbGl6ZWQgdGhpcyBtZWFucyB0byBtYXggc2Nyb2xsIG9mZnNldC5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyU2Nyb2xsLnkgPSB0ZXh0YXJlYVNjcm9sbEFtb3VudC55ID4gLTEgPyB0ZXh0YXJlYVNjcm9sbEFtb3VudC55IDogY3VyclNjcm9sbC55O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RleHRhcmVhSW5mb0NhY2hlID0gdGV4dGFyZWFJbmZvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNSVEwgJiYgX3J0bFNjcm9sbEJlaGF2aW9yLmkgJiYgX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSAmJiBoYXNPdmVyZmxvdy54ICYmIF9ub3JtYWxpemVSVExDYWNoZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJTY3JvbGwueCArPSBfY29udGVudEJvcmRlclNpemUudyB8fCAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAod2lkdGhBdXRvKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50W19zdHJTY3JvbGxMZWZ0XSgwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhlaWdodEF1dG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnRbX3N0clNjcm9sbFRvcF0oMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKGN1cnJTY3JvbGwueClbX3N0clNjcm9sbFRvcF0oY3VyclNjcm9sbC55KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vc2Nyb2xsYmFycyBtYW5hZ2VtZW50OlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc1Zpc2liaWxpdHlWaXNpYmxlID0gc2Nyb2xsYmFyc1Zpc2liaWxpdHkgPT09ICd2JztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNWaXNpYmlsaXR5SGlkZGVuID0gc2Nyb2xsYmFyc1Zpc2liaWxpdHkgPT09ICdoJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNWaXNpYmlsaXR5QXV0byA9IHNjcm9sbGJhcnNWaXNpYmlsaXR5ID09PSAnYSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWZyZXNoU2Nyb2xsYmFyc1Zpc2liaWxpdHkgPSBmdW5jdGlvbiAoc2hvd1gsIHNob3dZKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93WSA9IHNob3dZID09PSB1bmRlZmluZWQgPyBzaG93WCA6IHNob3dZO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckFwcGVhcmFuY2UodHJ1ZSwgc2hvd1gsIGNhblNjcm9sbC54KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckFwcGVhcmFuY2UoZmFsc2UsIHNob3dZLCBjYW5TY3JvbGwueSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWFuYWdlIGNsYXNzIG5hbWUgd2hpY2ggaW5kaWNhdGVzIHNjcm9sbGFibGUgb3ZlcmZsb3dcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBfY2xhc3NOYW1lSG9zdE92ZXJmbG93LCBoaWRlT3ZlcmZsb3cueCB8fCBoaWRlT3ZlcmZsb3cueSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZFJlbW92ZUNsYXNzKF9ob3N0RWxlbWVudCwgX2NsYXNzTmFtZUhvc3RPdmVyZmxvd1gsIGhpZGVPdmVyZmxvdy54KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBfY2xhc3NOYW1lSG9zdE92ZXJmbG93WSwgaGlkZU92ZXJmbG93LnkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hZGQgb3IgcmVtb3ZlIHJ0bCBjbGFzcyBuYW1lIGZvciBzdHlsaW5nIHB1cnBvc2VzIGV4Y2VwdCB3aGVuIGl0cyBib2R5LCB0aGVuIHRoZSBzY3JvbGxiYXIgc3RheXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNzc0RpcmVjdGlvbkNoYW5nZWQgJiYgIV9pc0JvZHkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFJlbW92ZUNsYXNzKF9ob3N0RWxlbWVudCwgX2NsYXNzTmFtZUhvc3RSVEwsIF9pc1JUTCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWFuYWdlIHRoZSByZXNpemUgZmVhdHVyZSAoQ1NTMyByZXNpemUgXCJwb2x5ZmlsbFwiIGZvciB0aGlzIHBsdWdpbilcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc0JvZHkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0UmVzaXplRGlzYWJsZWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzaXplQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBfY2xhc3NOYW1lSG9zdFJlc2l6ZURpc2FibGVkLCBfcmVzaXplTm9uZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCwgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZSwgIV9yZXNpemVOb25lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFJlbW92ZUNsYXNzKF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplQiwgX3Jlc2l6ZUJvdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQsIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemVILCBfcmVzaXplSG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCwgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZVYsIF9yZXNpemVWZXJ0aWNhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWFuYWdlIHRoZSBzY3JvbGxiYXJzIGdlbmVyYWwgdmlzaWJpbGl0eSArIHRoZSBzY3JvbGxiYXIgaW50ZXJhY3Rpdml0eSAodW51c2FibGUgY2xhc3MgbmFtZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbGJhcnNWaXNpYmlsaXR5Q2hhbmdlZCB8fCBvdmVyZmxvd0JlaGF2aW9yQ2hhbmdlZCB8fCBoaWRlT3ZlcmZsb3cuYyB8fCBoYXNPdmVyZmxvdy5jIHx8IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0U2Nyb2xsaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzVmlzaWJpbGl0eShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChzY3JvbGxiYXJzVmlzaWJpbGl0eUF1dG8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc1Zpc2liaWxpdHkoY2FuU2Nyb2xsLngsIGNhblNjcm9sbC55KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHNjcm9sbGJhcnNWaXNpYmlsaXR5VmlzaWJsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzVmlzaWJpbGl0eSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHNjcm9sbGJhcnNWaXNpYmlsaXR5SGlkZGVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNWaXNpYmlsaXR5KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2UgdGhlIHNjcm9sbGJhcnMgYXV0byBoaWRlIGZlYXR1cmUgKGF1dG8gaGlkZSB0aGVtIGFmdGVyIHNwZWNpZmljIGFjdGlvbnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzY3JvbGxiYXJzQXV0b0hpZGVDaGFuZ2VkIHx8IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cEhvc3RNb3VzZVRvdWNoRXZlbnRzKCFfc2Nyb2xsYmFyc0F1dG9IaWRlTGVhdmUgJiYgIV9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUoX3Njcm9sbGJhcnNBdXRvSGlkZU5ldmVyLCAhX3Njcm9sbGJhcnNBdXRvSGlkZU5ldmVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2Ugc2Nyb2xsYmFycyBoYW5kbGUgbGVuZ3RoICYgb2Zmc2V0IC0gZG9uJ3QgcmVtb3ZlIVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaG9zdFNpemVDaGFuZ2VkIHx8IG92ZXJmbG93QW1vdW50LmMgfHwgaGVpZ2h0QXV0b0NoYW5nZWQgfHwgd2lkdGhBdXRvQ2hhbmdlZCB8fCByZXNpemVDaGFuZ2VkIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgcGFkZGluZ0Fic29sdXRlQ2hhbmdlZCB8fCBpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nQ2hhbmdlZCB8fCBjc3NEaXJlY3Rpb25DaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlTGVuZ3RoKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldCh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVMZW5ndGgoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldChmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWFuYWdlIGludGVyYWN0aXZpdHlcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NoYW5nZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc0ludGVyYWN0aXZlKHRydWUsIHNjcm9sbGJhcnNDbGlja1Njcm9sbGluZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzY3JvbGxiYXJzRHJhZ1Njcm9sbGluZ0NoYW5nZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc0ludGVyYWN0aXZlKGZhbHNlLCBzY3JvbGxiYXJzRHJhZ1Njcm9sbGluZyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2NhbGxiYWNrczpcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25EaXJlY3Rpb25DaGFuZ2VkJywge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNSVEw6IF9pc1JUTCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpcjogY3NzRGlyZWN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIGNzc0RpcmVjdGlvbkNoYW5nZWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvbkhvc3RTaXplQ2hhbmdlZCcsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBfaG9zdFNpemVDYWNoZS53LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBfaG9zdFNpemVDYWNoZS5oXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIGhvc3RTaXplQ2hhbmdlZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uQ29udGVudFNpemVDaGFuZ2VkJywge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IF9jb250ZW50U2Nyb2xsU2l6ZUNhY2hlLncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IF9jb250ZW50U2Nyb2xsU2l6ZUNhY2hlLmhcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgY29udGVudFNpemVDaGFuZ2VkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25PdmVyZmxvd0NoYW5nZWQnLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBoYXNPdmVyZmxvdy54LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaGFzT3ZlcmZsb3cueSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhTY3JvbGxhYmxlOiBoaWRlT3ZlcmZsb3cueHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5U2Nyb2xsYWJsZTogaGlkZU92ZXJmbG93LnlzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpcHBlZDogaGlkZU92ZXJmbG93LnggfHwgaGlkZU92ZXJmbG93LnlcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgaGFzT3ZlcmZsb3cuYyB8fCBoaWRlT3ZlcmZsb3cuYyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uT3ZlcmZsb3dBbW91bnRDaGFuZ2VkJywge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogb3ZlcmZsb3dBbW91bnQueCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IG92ZXJmbG93QW1vdW50LnlcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgb3ZlcmZsb3dBbW91bnQuYyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2ZpeCBib2R5IG1pbiBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc0JvZHkgJiYgX2JvZHlNaW5TaXplQ2FjaGUgJiYgKF9oYXNPdmVyZmxvd0NhY2hlLmMgfHwgX2JvZHlNaW5TaXplQ2FjaGUuYykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9pdHMgcG9zc2libGUgdGhhdCBubyBtaW4gc2l6ZSB3YXMgbWVhc3VyZWQgdW50aWwgbm93LCBiZWNhdXNlIHRoZSBjb250ZW50IGFycmFuZ2UgZWxlbWVudCB3YXMganVzdCBhZGRlZCBub3csIGluIHRoaXMgY2FzZSwgbWVhc3VyZSBub3cgdGhlIG1pbiBzaXplLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9ib2R5TWluU2l6ZUNhY2hlLmYpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBib2R5TWluU2l6ZUNoYW5nZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkgJiYgX2hhc092ZXJmbG93Q2FjaGUueClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoX3N0ck1pbk1pbnVzICsgX3N0cldpZHRoLCBfYm9keU1pblNpemVDYWNoZS53ICsgX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemUueSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIF9oYXNPdmVyZmxvd0NhY2hlLnkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnQuY3NzKF9zdHJNaW5NaW51cyArIF9zdHJIZWlnaHQsIF9ib2R5TWluU2l6ZUNhY2hlLmggKyBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZS54KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2JvZHlNaW5TaXplQ2FjaGUuYyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pbml0aWFsaXplZCAmJiBjaGFuZ2VkT3B0aW9ucy51cGRhdGVPbkxvYWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlRWxlbWVudHNPbkxvYWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZnJlZXplUmVzaXplT2JzZXJ2ZXIoX3NpemVPYnNlcnZlckVsZW1lbnQsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAvL2ZyZWV6ZVJlc2l6ZU9ic2VydmVyKF9zaXplQXV0b09ic2VydmVyRWxlbWVudCwgZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvblVwZGF0ZWQnLCB7IGZvcmNlZDogZm9yY2UgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBVcGRhdGVzIHRoZSBmb3VuZCBlbGVtZW50cyBvZiB3aGljaCB0aGUgbG9hZCBldmVudCBzaGFsbCBiZSBoYW5kbGVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiB1cGRhdGVFbGVtZW50c09uTG9hZCgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIV9pc1RleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVhY2hVcGRhdGVPbkxvYWQoZnVuY3Rpb24gKGksIHVwZGF0ZU9uTG9hZFNlbGVjdG9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnQuZmluZCh1cGRhdGVPbkxvYWRTZWxlY3RvcikuZWFjaChmdW5jdGlvbiAoaSwgZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBlbGVtZW50IGRvZXNuJ3QgaGF2ZSBhIHVwZGF0ZU9uTG9hZENhbGxiYWNrIGFwcGxpZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoQ09NUEFUSUJJTElUWS5pbkEoZWwsIF91cGRhdGVPbkxvYWRFbG1zKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3VwZGF0ZU9uTG9hZEVsbXMucHVzaChlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSyhlbClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vZmYoX3VwZGF0ZU9uTG9hZEV2ZW50TmFtZSwgdXBkYXRlT25Mb2FkQ2FsbGJhY2spXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAub24oX3VwZGF0ZU9uTG9hZEV2ZW50TmFtZSwgdXBkYXRlT25Mb2FkQ2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IE9wdGlvbnMgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBTZXRzIG5ldyBvcHRpb25zIGJ1dCBkb2Vzbid0IGNhbGwgdGhlIHVwZGF0ZSBtZXRob2QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gbmV3T3B0aW9ucyBUaGUgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBuZXcgb3B0aW9ucy5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfSBBIG9iamVjdCB3aGljaCBjb250YWlucyB0aGUgY2hhbmdlZCBvcHRpb25zLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXRPcHRpb25zKG5ld09wdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdmFsaWRhdGVkT3B0cyA9IF9wbHVnaW5zT3B0aW9ucy5fdmFsaWRhdGUobmV3T3B0aW9ucywgX3BsdWdpbnNPcHRpb25zLl90ZW1wbGF0ZSwgdHJ1ZSwgX2N1cnJlbnRPcHRpb25zKVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBfY3VycmVudE9wdGlvbnMgPSBleHRlbmREZWVwKHt9LCBfY3VycmVudE9wdGlvbnMsIHZhbGlkYXRlZE9wdHMuX2RlZmF1bHQpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jdXJyZW50UHJlcGFyZWRPcHRpb25zID0gZXh0ZW5kRGVlcCh7fSwgX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMsIHZhbGlkYXRlZE9wdHMuX3ByZXBhcmVkKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbGlkYXRlZE9wdHMuX3ByZXBhcmVkO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gU3RydWN0dXJlID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQnVpbGRzIG9yIGRlc3Ryb3lzIHRoZSB3cmFwcGVyIGFuZCBoZWxwZXIgRE9NIGVsZW1lbnRzLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlc3Ryb3kgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIERPTSBzaGFsbCBiZSBidWlsZCBvciBkZXN0cm95ZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQnVpbGRzIG9yIGRlc3Ryb3lzIHRoZSB3cmFwcGVyIGFuZCBoZWxwZXIgRE9NIGVsZW1lbnRzLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlc3Ryb3kgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIERPTSBzaGFsbCBiZSBidWlsZCBvciBkZXN0cm95ZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldHVwU3RydWN0dXJlRE9NKGRlc3Ryb3kpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyUGFyZW50ID0gJ3BhcmVudCc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzTmFtZVJlc2l6ZU9ic2VydmVySG9zdCA9ICdvcy1yZXNpemUtb2JzZXJ2ZXItaG9zdCc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzTmFtZVRleHRhcmVhRWxlbWVudEZ1bGwgPSBfY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50ICsgX3N0clNwYWNlICsgX2NsYXNzTmFtZVRleHRJbmhlcml0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUNsYXNzID0gX2lzVGV4dGFyZWEgPyBfc3RyU3BhY2UgKyBfY2xhc3NOYW1lVGV4dEluaGVyaXQgOiBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFkb3B0QXR0cnMgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy50ZXh0YXJlYS5pbmhlcml0ZWRBdHRycztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWRvcHRBdHRyc01hcCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhcHBseUFkb3B0ZWRBdHRycyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFwcGx5QWRvcHRlZEF0dHJzRWxtID0gZGVzdHJveSA/IF90YXJnZXRFbGVtZW50IDogX2hvc3RFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlYWNoKGFkb3B0QXR0cnNNYXAsIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSh2YWx1ZSkgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXkgPT0gTEVYSUNPTi5jKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBseUFkb3B0ZWRBdHRyc0VsbS5hZGRDbGFzcyh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBseUFkb3B0ZWRBdHRyc0VsbS5hdHRyKGtleSwgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBob3N0RWxlbWVudENsYXNzTmFtZXMgPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVIb3N0RWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RFbGVtZW50Rm9yZWlnbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RUZXh0YXJlYUVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVIb3N0UmVzaXplRGlzYWJsZWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVIb3N0UlRMLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lSG9zdFNjcm9sbGJhckhvcml6b250YWxIaWRkZW4sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVIb3N0U2Nyb2xsYmFyVmVydGljYWxIaWRkZW4sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVIb3N0VHJhbnNpdGlvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RTY3JvbGxpbmcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3csXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3dYLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lSG9zdE92ZXJmbG93WSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVRoZW1lTm9uZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVRleHRhcmVhRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVRleHRJbmhlcml0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lQ2FjaGVdLmpvaW4oX3N0clNwYWNlKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdEVsZW1lbnRDU1MgPSB7fTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9nZXQgaG9zdCBlbGVtZW50IGFzIGZpcnN0IGVsZW1lbnQsIGJlY2F1c2UgdGhhdCdzIHRoZSBtb3N0IHVwcGVyIGVsZW1lbnQgYW5kIHJlcXVpcmVkIGZvciB0aGUgb3RoZXIgZWxlbWVudHNcclxuICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnQgPSBfaG9zdEVsZW1lbnQgfHwgKF9pc1RleHRhcmVhID8gKF9kb21FeGlzdHMgPyBfdGFyZ2V0RWxlbWVudFtzdHJQYXJlbnRdKClbc3RyUGFyZW50XSgpW3N0clBhcmVudF0oKVtzdHJQYXJlbnRdKCkgOiBGUkFNRVdPUksoZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZUhvc3RUZXh0YXJlYUVsZW1lbnQpKSkgOiBfdGFyZ2V0RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50ID0gX2NvbnRlbnRFbGVtZW50IHx8IHNlbGVjdE9yR2VuZXJhdGVEaXZCeUNsYXNzKF9jbGFzc05hbWVDb250ZW50RWxlbWVudCArIHRleHRhcmVhQ2xhc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQgPSBfdmlld3BvcnRFbGVtZW50IHx8IHNlbGVjdE9yR2VuZXJhdGVEaXZCeUNsYXNzKF9jbGFzc05hbWVWaWV3cG9ydEVsZW1lbnQgKyB0ZXh0YXJlYUNsYXNzKTtcclxuICAgICAgICAgICAgICAgICAgICBfcGFkZGluZ0VsZW1lbnQgPSBfcGFkZGluZ0VsZW1lbnQgfHwgc2VsZWN0T3JHZW5lcmF0ZURpdkJ5Q2xhc3MoX2NsYXNzTmFtZVBhZGRpbmdFbGVtZW50ICsgdGV4dGFyZWFDbGFzcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3NpemVPYnNlcnZlckVsZW1lbnQgPSBfc2l6ZU9ic2VydmVyRWxlbWVudCB8fCBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhjbGFzc05hbWVSZXNpemVPYnNlcnZlckhvc3QpO1xyXG4gICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUNvdmVyRWxlbWVudCA9IF90ZXh0YXJlYUNvdmVyRWxlbWVudCB8fCAoX2lzVGV4dGFyZWEgPyBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lVGV4dGFyZWFDb3ZlckVsZW1lbnQpIDogdW5kZWZpbmVkKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9hZGQgdGhpcyBjbGFzcyB0byB3b3JrYXJvdW5kIGNsYXNzIGNoYW5naW5nIGlzc3VlcyB3aXRoIFVJIGZyYW1ld29ya3MgZXNwZWNpYWxseSBWdWVcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2RvbUV4aXN0cylcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX2hvc3RFbGVtZW50LCBfY2xhc3NOYW1lSG9zdEVsZW1lbnRGb3JlaWduKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9vbiBkZXN0cm95LCByZW1vdmUgYWxsIGdlbmVyYXRlZCBjbGFzcyBuYW1lcyBmcm9tIHRoZSBob3N0IGVsZW1lbnQgYmVmb3JlIGNvbGxlY3RpbmcgdGhlIGFkb3B0ZWQgYXR0cmlidXRlcyBcclxuICAgICAgICAgICAgICAgICAgICAvL3RvIHByZXZlbnQgYWRvcHRpbmcgZ2VuZXJhdGVkIGNsYXNzIG5hbWVzXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlc3Ryb3kpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ob3N0RWxlbWVudCwgaG9zdEVsZW1lbnRDbGFzc05hbWVzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9jb2xsZWN0IGFsbCBhZG9wdGVkIGF0dHJpYnV0ZXNcclxuICAgICAgICAgICAgICAgICAgICBhZG9wdEF0dHJzID0gdHlwZShhZG9wdEF0dHJzKSA9PSBUWVBFUy5zID8gYWRvcHRBdHRycy5zcGxpdChfc3RyU3BhY2UpIDogYWRvcHRBdHRycztcclxuICAgICAgICAgICAgICAgICAgICBpZiAoQ09NUEFUSUJJTElUWS5pc0EoYWRvcHRBdHRycykgJiYgX2lzVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaChhZG9wdEF0dHJzLCBmdW5jdGlvbiAoaSwgdikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUodikgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkb3B0QXR0cnNNYXBbdl0gPSBkZXN0cm95ID8gX2hvc3RFbGVtZW50LmF0dHIodikgOiBfdGFyZ2V0RWxlbWVudC5hdHRyKHYpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZGVzdHJveSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMuc2l6ZUF1dG9DYXBhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zdEVsZW1lbnRDU1NbX3N0cldpZHRoXSA9IF90YXJnZXRFbGVtZW50LmNzcyhfc3RyV2lkdGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RFbGVtZW50Q1NTW19zdHJIZWlnaHRdID0gX3RhcmdldEVsZW1lbnQuY3NzKF9zdHJIZWlnaHQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2RvbUV4aXN0cylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0RWxlbWVudC5hZGRDbGFzcyhfY2xhc3NOYW1lVGV4dEluaGVyaXQpLndyYXAoX2hvc3RFbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2pRdWVyeSBjbG9uZXMgZWxlbWVudHMgaW4gd3JhcCBmdW5jdGlvbnMsIHNvIHdlIGhhdmUgdG8gc2VsZWN0IHRoZW0gYWdhaW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudCA9IF90YXJnZXRFbGVtZW50W3N0clBhcmVudF0oKS5jc3MoaG9zdEVsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9kb21FeGlzdHMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vYWRkIHRoZSBjb3JyZWN0IGNsYXNzIHRvIHRoZSB0YXJnZXQgZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX3RhcmdldEVsZW1lbnQsIF9pc1RleHRhcmVhID8gY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50RnVsbCA6IF9jbGFzc05hbWVIb3N0RWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy93cmFwIHRoZSBjb250ZW50IGludG8gdGhlIGdlbmVyYXRlZCBlbGVtZW50cyB0byBjcmVhdGUgdGhlIHJlcXVpcmVkIERPTVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50LndyYXBJbm5lcihfY29udGVudEVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndyYXBJbm5lcihfdmlld3BvcnRFbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC53cmFwSW5uZXIoX3BhZGRpbmdFbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wcmVwZW5kKF9zaXplT2JzZXJ2ZXJFbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2pRdWVyeSBjbG9uZXMgZWxlbWVudHMgaW4gd3JhcCBmdW5jdGlvbnMsIHNvIHdlIGhhdmUgdG8gc2VsZWN0IHRoZW0gYWdhaW5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudCA9IGZpbmRGaXJzdChfaG9zdEVsZW1lbnQsIF9zdHJEb3QgKyBfY2xhc3NOYW1lQ29udGVudEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudCA9IGZpbmRGaXJzdChfaG9zdEVsZW1lbnQsIF9zdHJEb3QgKyBfY2xhc3NOYW1lVmlld3BvcnRFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nRWxlbWVudCA9IGZpbmRGaXJzdChfaG9zdEVsZW1lbnQsIF9zdHJEb3QgKyBfY2xhc3NOYW1lUGFkZGluZ0VsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5wcmVwZW5kKF90ZXh0YXJlYUNvdmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwbHlBZG9wdGVkQXR0cnMoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX3ZpZXdwb3J0RWxlbWVudCwgX2NsYXNzTmFtZVZpZXdwb3J0TmF0aXZlU2Nyb2xsYmFyc0ludmlzaWJsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfdmlld3BvcnRFbGVtZW50LCBfY2xhc3NOYW1lVmlld3BvcnROYXRpdmVTY3JvbGxiYXJzT3ZlcmxhaWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF9odG1sRWxlbWVudCwgX2NsYXNzTmFtZUhUTUxFbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplT2JzZXJ2ZXJFbGVtZW50TmF0aXZlID0gX3NpemVPYnNlcnZlckVsZW1lbnRbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudE5hdGl2ZSA9IF9ob3N0RWxlbWVudFswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50TmF0aXZlID0gX3BhZGRpbmdFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50TmF0aXZlID0gX3ZpZXdwb3J0RWxlbWVudFswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50TmF0aXZlID0gX2NvbnRlbnRFbGVtZW50WzBdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlVmlld3BvcnRBdHRyc0Zyb21UYXJnZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZG9tRXhpc3RzICYmIF9pbml0aWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9jbGVhciBzaXplIG9ic2VydmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2l6ZU9ic2VydmVyRWxlbWVudC5jaGlsZHJlbigpLnJlbW92ZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIHRoZSBzdHlsZSBwcm9wZXJ0eSBhbmQgY2xhc3NlcyBmcm9tIGFscmVhZHkgZ2VuZXJhdGVkIGVsZW1lbnRzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYWNoKFtfcGFkZGluZ0VsZW1lbnQsIF92aWV3cG9ydEVsZW1lbnQsIF9jb250ZW50RWxlbWVudCwgX3RleHRhcmVhQ292ZXJFbGVtZW50XSwgZnVuY3Rpb24gKGksIGVsbSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbG0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoZWxtLnJlbW92ZUF0dHIoTEVYSUNPTi5zKSwgX2NsYXNzTmFtZXNEeW5hbWljRGVzdHJveSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9hZGQgY2xhc3NlcyB0byB0aGUgaG9zdCBlbGVtZW50IHdoaWNoIHdhcyByZW1vdmVkIHByZXZpb3VzbHkgdG8gbWF0Y2ggdGhlIGV4cGVjdGVkIERPTVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX2hvc3RFbGVtZW50LCBfaXNUZXh0YXJlYSA/IF9jbGFzc05hbWVIb3N0VGV4dGFyZWFFbGVtZW50IDogX2NsYXNzTmFtZUhvc3RFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIHNpemUgb2JzZXJ2ZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZShfc2l6ZU9ic2VydmVyRWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy91bndyYXAgdGhlIGNvbnRlbnQgdG8gcmVzdG9yZSBET01cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jb250ZW50cygpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnVud3JhcCgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnVud3JhcCgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnVud3JhcCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LnVud3JhcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZShfaG9zdEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZShfdGV4dGFyZWFDb3ZlckVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGx5QWRvcHRlZEF0dHJzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LnJlbW92ZUF0dHIoTEVYSUNPTi5zKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNCb2R5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX2h0bWxFbGVtZW50LCBfY2xhc3NOYW1lSFRNTEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEFkZHMgb3IgcmVtb3ZlcyBhbGwgd3JhcHBlciBlbGVtZW50cyBpbnRlcmFjdGl2aXR5IGV2ZW50cy5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBkZXN0cm95IEluZGljYXRlcyB3aGV0aGVyIHRoZSBFdmVudHMgc2hhbGwgYmUgYWRkZWQgb3IgcmVtb3ZlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBTdHJ1Y3R1cmVFdmVudHMoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhS2V5RG93blJlc3RyaWN0ZWRLZXlDb2RlcyA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAxMTksIDEyMCwgMTIxLCAxMjMsICAgIC8vRjEgdG8gRjEyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDMzLCAzNCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3BhZ2UgdXAsIHBhZ2UgZG93blxyXG4gICAgICAgICAgICAgICAgICAgICAgICAzNywgMzgsIDM5LCA0MCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9sZWZ0LCB1cCwgcmlnaHQsIGRvd24gYXJyb3dzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDE2LCAxNywgMTgsIDE5LCAyMCwgMTQ0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1NoaWZ0LCBDdHJsLCBBbHQsIFBhdXNlLCBDYXBzTG9jaywgTnVtTG9ja1xyXG4gICAgICAgICAgICAgICAgICAgIF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhS2V5RG93bktleUNvZGVzTGlzdCA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYVVwZGF0ZUludGVydmFsSUQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbFN0b3BUaW1lb3V0SWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbFN0b3BEZWxheSA9IDE3NTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyRm9jdXMgPSAnZm9jdXMnO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiB1cGRhdGVUZXh0YXJlYShkb0NsZWFySW50ZXJ2YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWFVcGRhdGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlKF9zdHJBdXRvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvQ2xlYXJJbnRlcnZhbCAmJiBfYXV0b1VwZGF0ZVJlY29tbWVuZGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0ZXh0YXJlYVVwZGF0ZUludGVydmFsSUQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiB0ZXh0YXJlYU9uU2Nyb2xsKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XShfcnRsU2Nyb2xsQmVoYXZpb3IuaSAmJiBfbm9ybWFsaXplUlRMQ2FjaGUgPyA5OTk5OTk5IDogMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50W19zdHJTY3JvbGxUb3BdKDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnBydkQoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnN0cFAoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHRleHRhcmVhT25Ecm9wKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfZGVzdHJveWVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZVRleHRhcmVhKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIDUwKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gdGV4dGFyZWFPbkZvY3VzKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGV4dGFyZWFIYXNGb2N1cyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF9ob3N0RWxlbWVudCwgc3RyRm9jdXMpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiB0ZXh0YXJlYU9uRm9jdXNvdXQoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUhhc0ZvY3VzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHRhcmVhS2V5RG93bktleUNvZGVzTGlzdCA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIHN0ckZvY3VzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlVGV4dGFyZWEodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHRleHRhcmVhT25LZXlEb3duKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXlDb2RlID0gZXZlbnQua2V5Q29kZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbkFycmF5KGtleUNvZGUsIHRleHRhcmVhS2V5RG93blJlc3RyaWN0ZWRLZXlDb2RlcykgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRleHRhcmVhS2V5RG93bktleUNvZGVzTGlzdFtMRVhJQ09OLmxdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlVGV4dGFyZWEoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYVVwZGF0ZUludGVydmFsSUQgPSBzZXRJbnRlcnZhbCh1cGRhdGVUZXh0YXJlYSwgMTAwMCAvIDYwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbkFycmF5KGtleUNvZGUsIHRleHRhcmVhS2V5RG93bktleUNvZGVzTGlzdCkgPCAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRhcmVhS2V5RG93bktleUNvZGVzTGlzdC5wdXNoKGtleUNvZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHRleHRhcmVhT25LZXlVcChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIga2V5Q29kZSA9IGV2ZW50LmtleUNvZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IGluQXJyYXkoa2V5Q29kZSwgdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbkFycmF5KGtleUNvZGUsIHRleHRhcmVhS2V5RG93blJlc3RyaWN0ZWRLZXlDb2RlcykgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPiAtMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYUtleURvd25LZXlDb2Rlc0xpc3Quc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0W0xFWElDT04ubF0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlVGV4dGFyZWEodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gY29udGVudE9uVHJhbnNpdGlvbkVuZChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2F1dG9VcGRhdGVDYWNoZSA9PT0gdHJ1ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSBldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNTaXplQWZmZWN0aW5nQ1NTUHJvcGVydHkoZXZlbnQucHJvcGVydHlOYW1lKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9iYXNlLnVwZGF0ZShfc3RyQXV0byk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHZpZXdwb3J0T25TY3JvbGwoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfc2xlZXBpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzY3JvbGxTdG9wVGltZW91dElkICE9PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHNjcm9sbFN0b3BUaW1lb3V0SWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJzQXV0b0hpZGVTY3JvbGwgfHwgX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUodHJ1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbmF0aXZlT3ZlcmxheVNjcm9sbGJhcnNBcmVBY3RpdmUoKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX2hvc3RFbGVtZW50LCBfY2xhc3NOYW1lSG9zdFNjcm9sbGluZyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uU2Nyb2xsU3RhcnQnLCBldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiBhIHNjcm9sbGJhcnMgaGFuZGxlIGdldHMgZHJhZ2dlZCwgdGhlIG1vdXNlbW92ZSBldmVudCBpcyByZXNwb25zaWJsZSBmb3IgcmVmcmVzaGluZyB0aGUgaGFuZGxlIG9mZnNldFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9iZWNhdXNlIGlmIENTUyBzY3JvbGwtc25hcCBpcyB1c2VkLCB0aGUgaGFuZGxlIG9mZnNldCBnZXRzIG9ubHkgcmVmcmVzaGVkIG9uIGV2ZXJ5IHNuYXAgcG9pbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcyBsb29rcyBsYWdneSAmIGNsdW5reSwgaXQgbG9va3MgbXVjaCBiZXR0ZXIgaWYgdGhlIG9mZnNldCByZWZyZXNoZXMgd2l0aCB0aGUgbW91c2Vtb3ZlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9zY3JvbGxiYXJzSGFuZGxlc0RlZmluZVNjcm9sbFBvcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVPZmZzZXQodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldChmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvblNjcm9sbCcsIGV2ZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxTdG9wVGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfZGVzdHJveWVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vT25TY3JvbGxTdG9wOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoc2Nyb2xsU3RvcFRpbWVvdXRJZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFN0b3BUaW1lb3V0SWQgPSB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUoZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFuYXRpdmVPdmVybGF5U2Nyb2xsYmFyc0FyZUFjdGl2ZSgpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBfY2xhc3NOYW1lSG9zdFNjcm9sbGluZyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvblNjcm9sbFN0b3AnLCBldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgc2Nyb2xsU3RvcERlbGF5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX21zaWVWZXJzaW9uID4gOSB8fCAhX2F1dG9VcGRhdGVSZWNvbW1lbmRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIoX3RhcmdldEVsZW1lbnQsICdpbnB1dCcsIHVwZGF0ZVRleHRhcmVhKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKF90YXJnZXRFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtfc3RyS2V5RG93bkV2ZW50LCBfc3RyS2V5VXBFdmVudF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RleHRhcmVhT25LZXlEb3duLCB0ZXh0YXJlYU9uS2V5VXBdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIoX3RhcmdldEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbX3N0clNjcm9sbCwgJ2Ryb3AnLCBzdHJGb2N1cywgc3RyRm9jdXMgKyAnb3V0J10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGV4dGFyZWFPblNjcm9sbCwgdGV4dGFyZWFPbkRyb3AsIHRleHRhcmVhT25Gb2N1cywgdGV4dGFyZWFPbkZvY3Vzb3V0XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihfY29udGVudEVsZW1lbnQsIF9zdHJUcmFuc2l0aW9uRW5kRXZlbnQsIGNvbnRlbnRPblRyYW5zaXRpb25FbmQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihfdmlld3BvcnRFbGVtZW50LCBfc3RyU2Nyb2xsLCB2aWV3cG9ydE9uU2Nyb2xsLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IFNjcm9sbGJhcnMgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBCdWlsZHMgb3IgZGVzdHJveXMgYWxsIHNjcm9sbGJhciBET00gZWxlbWVudHMgKHNjcm9sbGJhciwgdHJhY2ssIGhhbmRsZSlcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBkZXN0cm95IEluZGljYXRlcyB3aGV0aGVyIHRoZSBET00gc2hhbGwgYmUgYnVpbGQgb3IgZGVzdHJveWVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXR1cFNjcm9sbGJhcnNET00oZGVzdHJveSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzZWxlY3RPckdlbmVyYXRlU2Nyb2xsYmFyRE9NID0gZnVuY3Rpb24gKGlzSG9yaXpvbnRhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyQ2xhc3NOYW1lID0gaXNIb3Jpem9udGFsID8gX2NsYXNzTmFtZVNjcm9sbGJhckhvcml6b250YWwgOiBfY2xhc3NOYW1lU2Nyb2xsYmFyVmVydGljYWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXIgPSBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lU2Nyb2xsYmFyICsgX3N0clNwYWNlICsgc2Nyb2xsYmFyQ2xhc3NOYW1lLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRyYWNrID0gc2VsZWN0T3JHZW5lcmF0ZURpdkJ5Q2xhc3MoX2NsYXNzTmFtZVNjcm9sbGJhclRyYWNrLCBzY3JvbGxiYXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGFuZGxlID0gc2VsZWN0T3JHZW5lcmF0ZURpdkJ5Q2xhc3MoX2NsYXNzTmFtZVNjcm9sbGJhckhhbmRsZSwgc2Nyb2xsYmFyKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2RvbUV4aXN0cyAmJiAhZGVzdHJveSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyLmFwcGVuZCh0cmFjayk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFjay5hcHBlbmQoaGFuZGxlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXI6IHNjcm9sbGJhcixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90cmFjazogdHJhY2ssXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaGFuZGxlOiBoYW5kbGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHJlc2V0U2Nyb2xsYmFyRE9NKGlzSG9yaXpvbnRhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFycyA9IGdldFNjcm9sbGJhclZhcnMoaXNIb3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhciA9IHNjcm9sbGJhclZhcnMuX3Njcm9sbGJhcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRyYWNrID0gc2Nyb2xsYmFyVmFycy5fdHJhY2s7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGUgPSBzY3JvbGxiYXJWYXJzLl9oYW5kbGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2RvbUV4aXN0cyAmJiBfaW5pdGlhbGl6ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2goW3Njcm9sbGJhciwgdHJhY2ssIGhhbmRsZV0sIGZ1bmN0aW9uIChpLCBlbG0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhlbG0ucmVtb3ZlQXR0cihMRVhJQ09OLnMpLCBfY2xhc3NOYW1lc0R5bmFtaWNEZXN0cm95KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKHNjcm9sbGJhciB8fCBzZWxlY3RPckdlbmVyYXRlU2Nyb2xsYmFyRE9NKGlzSG9yaXpvbnRhbCkuX3Njcm9sbGJhcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhvcml6b250YWxFbGVtZW50cztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdmVydGljYWxFbGVtZW50cztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvcml6b250YWxFbGVtZW50cyA9IHNlbGVjdE9yR2VuZXJhdGVTY3JvbGxiYXJET00odHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcnRpY2FsRWxlbWVudHMgPSBzZWxlY3RPckdlbmVyYXRlU2Nyb2xsYmFyRE9NKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFySG9yaXpvbnRhbEVsZW1lbnQgPSBob3Jpem9udGFsRWxlbWVudHMuX3Njcm9sbGJhcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhckhvcml6b250YWxUcmFja0VsZW1lbnQgPSBob3Jpem9udGFsRWxlbWVudHMuX3RyYWNrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFySG9yaXpvbnRhbEhhbmRsZUVsZW1lbnQgPSBob3Jpem9udGFsRWxlbWVudHMuX2hhbmRsZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhclZlcnRpY2FsRWxlbWVudCA9IHZlcnRpY2FsRWxlbWVudHMuX3Njcm9sbGJhcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhclZlcnRpY2FsVHJhY2tFbGVtZW50ID0gdmVydGljYWxFbGVtZW50cy5fdHJhY2s7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJWZXJ0aWNhbEhhbmRsZUVsZW1lbnQgPSB2ZXJ0aWNhbEVsZW1lbnRzLl9oYW5kbGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9kb21FeGlzdHMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nRWxlbWVudC5hZnRlcihfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nRWxlbWVudC5hZnRlcihfc2Nyb2xsYmFySG9yaXpvbnRhbEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNldFNjcm9sbGJhckRPTSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXRTY3JvbGxiYXJET00oKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBJbml0aWFsaXplcyBhbGwgc2Nyb2xsYmFyIGludGVyYWN0aXZpdHkgZXZlbnRzLiAodHJhY2sgYW5kIGhhbmRsZSBkcmFnZ2luZywgY2xpY2tpbmcsIHNjcm9sbGluZylcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpc0hvcml6b250YWwgVHJ1ZSBpZiB0aGUgdGFyZ2V0IHNjcm9sbGJhciBpcyB0aGUgaG9yaXpvbnRhbCBzY3JvbGxiYXIsIGZhbHNlIGlmIHRoZSB0YXJnZXQgc2Nyb2xsYmFyIGlzIHRoZSB2ZXJ0aWNhbCBzY3JvbGxiYXIuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldHVwU2Nyb2xsYmFyRXZlbnRzKGlzSG9yaXpvbnRhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhpc0hvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzSW5mbyA9IHNjcm9sbGJhclZhcnMuX2luZm87XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc2lkZUlGcmFtZSA9IF93aW5kb3dFbGVtZW50TmF0aXZlLnRvcCAhPT0gX3dpbmRvd0VsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHh5ID0gc2Nyb2xsYmFyVmFycy5feF95O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBYWSA9IHNjcm9sbGJhclZhcnMuX1hfWTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsID0gX3N0clNjcm9sbCArIHNjcm9sbGJhclZhcnMuX0xlZnRfVG9wO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJBY3RpdmUgPSAnYWN0aXZlJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyU25hcEhhbmRsZSA9ICdzbmFwSGFuZGxlJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQ2xpY2tFdmVudCA9ICdjbGljayc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbER1cmF0aW9uRmFjdG9yID0gMTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaW5jcmVhc2VEZWNyZWFzZVNjcm9sbEFtb3VudEtleUNvZGVzID0gWzE2LCAxN107IC8vc2hpZnQsIGN0cmxcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdHJhY2tUaW1lb3V0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtb3VzZURvd25TY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1vdXNlRG93bk9mZnNldDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbW91c2VEb3duSW52ZXJ0ZWRTY2FsZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0UG9pbnRlclBvc2l0aW9uKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfbXNpZVZlcnNpb24gJiYgaW5zaWRlSUZyYW1lID8gZXZlbnRbJ3NjcmVlbicgKyBYWV0gOiBDT01QQVRJQklMSVRZLnBhZ2UoZXZlbnQpW3h5XTsgLy91c2Ugc2NyZWVuIGNvb3JkaW5hdGVzIGluIEVER0UgJiBJRSBiZWNhdXNlIHRoZSBwYWdlIHZhbHVlcyBhcmUgaW5jb3JyZWN0IGluIGZyYW1lcy5cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0UHJlcGFyZWRTY3JvbGxiYXJzT3B0aW9uKG5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLnNjcm9sbGJhcnNbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGluY3JlYXNlVHJhY2tTY3JvbGxBbW91bnQoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbER1cmF0aW9uRmFjdG9yID0gMC41O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkZWNyZWFzZVRyYWNrU2Nyb2xsQW1vdW50KCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxEdXJhdGlvbkZhY3RvciA9IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHN0b3BDbGlja0V2ZW50UHJvcGFnYXRpb24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZG9jdW1lbnRLZXlEb3duKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbkFycmF5KGV2ZW50LmtleUNvZGUsIGluY3JlYXNlRGVjcmVhc2VTY3JvbGxBbW91bnRLZXlDb2RlcykgPiAtMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY3JlYXNlVHJhY2tTY3JvbGxBbW91bnQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZG9jdW1lbnRLZXlVcChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5BcnJheShldmVudC5rZXlDb2RlLCBpbmNyZWFzZURlY3JlYXNlU2Nyb2xsQW1vdW50S2V5Q29kZXMpID4gLTEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNyZWFzZVRyYWNrU2Nyb2xsQW1vdW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uTW91c2VUb3VjaERvd25Db250aW51ZShldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3JpZ2luYWxFdmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQgfHwgZXZlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpc1RvdWNoRXZlbnQgPSBvcmlnaW5hbEV2ZW50LnRvdWNoZXMgIT09IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9zbGVlcGluZyB8fCBfZGVzdHJveWVkIHx8IG5hdGl2ZU92ZXJsYXlTY3JvbGxiYXJzQXJlQWN0aXZlKCkgfHwgIV9zY3JvbGxiYXJzRHJhZ1Njcm9sbGluZ0NhY2hlIHx8IChpc1RvdWNoRXZlbnQgJiYgIWdldFByZXBhcmVkU2Nyb2xsYmFyc09wdGlvbigndG91Y2hTdXBwb3J0JykpID8gZmFsc2UgOiBDT01QQVRJQklMSVRZLm1CdG4oZXZlbnQpID09PSAxIHx8IGlzVG91Y2hFdmVudDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZG9jdW1lbnREcmFnTW92ZShldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob25Nb3VzZVRvdWNoRG93bkNvbnRpbnVlKGV2ZW50KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRyYWNrTGVuZ3RoID0gc2Nyb2xsYmFyVmFyc0luZm8uX3RyYWNrTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZUxlbmd0aCA9IHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsUmFuZ2UgPSBzY3JvbGxiYXJWYXJzSW5mby5fbWF4U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbFJhdyA9IChnZXRQb2ludGVyUG9zaXRpb24oZXZlbnQpIC0gbW91c2VEb3duT2Zmc2V0KSAqIG1vdXNlRG93bkludmVydGVkU2NhbGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsRGVsdGFQZXJjZW50ID0gc2Nyb2xsUmF3IC8gKHRyYWNrTGVuZ3RoIC0gaGFuZGxlTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxEZWx0YSA9IChzY3JvbGxSYW5nZSAqIHNjcm9sbERlbHRhUGVyY2VudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxEZWx0YSA9IGlzRmluaXRlKHNjcm9sbERlbHRhKSA/IHNjcm9sbERlbHRhIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNSVEwgJiYgaXNIb3Jpem9udGFsICYmICFfcnRsU2Nyb2xsQmVoYXZpb3IuaSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxEZWx0YSAqPSAtMTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50W3Njcm9sbF0oTUFUSC5yb3VuZChtb3VzZURvd25TY3JvbGwgKyBzY3JvbGxEZWx0YSkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0hhbmRsZXNEZWZpbmVTY3JvbGxQb3MpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldChpc0hvcml6b250YWwsIG1vdXNlRG93blNjcm9sbCArIHNjcm9sbERlbHRhKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9zdXBwb3J0UGFzc2l2ZUV2ZW50cylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnBydkQoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50TW91c2VUb3VjaFVwKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZG9jdW1lbnRNb3VzZVRvdWNoVXAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSBldmVudCB8fCBldmVudC5vcmlnaW5hbEV2ZW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfZG9jdW1lbnRFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW19zdHJNb3VzZVRvdWNoTW92ZUV2ZW50LCBfc3RyTW91c2VUb3VjaFVwRXZlbnQsIF9zdHJLZXlEb3duRXZlbnQsIF9zdHJLZXlVcEV2ZW50LCBfc3RyU2VsZWN0U3RhcnRFdmVudF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZG9jdW1lbnREcmFnTW92ZSwgZG9jdW1lbnRNb3VzZVRvdWNoVXAsIGRvY3VtZW50S2V5RG93biwgZG9jdW1lbnRLZXlVcCwgZG9jdW1lbnRPblNlbGVjdFN0YXJ0XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnJBRigpKGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfZG9jdW1lbnRFbGVtZW50LCBzdHJDbGlja0V2ZW50LCBzdG9wQ2xpY2tFdmVudFByb3BhZ2F0aW9uLCB0cnVlLCB7IF9jYXB0dXJlOiB0cnVlIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJzSGFuZGxlc0RlZmluZVNjcm9sbFBvcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVPZmZzZXQoaXNIb3Jpem9udGFsLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzSGFuZGxlc0RlZmluZVNjcm9sbFBvcyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhfYm9keUVsZW1lbnQsIF9jbGFzc05hbWVEcmFnZ2luZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKHNjcm9sbGJhclZhcnMuX2hhbmRsZSwgc3RyQWN0aXZlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3Moc2Nyb2xsYmFyVmFycy5fdHJhY2ssIHN0ckFjdGl2ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKHNjcm9sbGJhclZhcnMuX3Njcm9sbGJhciwgc3RyQWN0aXZlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93blNjcm9sbCA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duT2Zmc2V0ID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtb3VzZURvd25JbnZlcnRlZFNjYWxlID0gMTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlY3JlYXNlVHJhY2tTY3JvbGxBbW91bnQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0cmFja1RpbWVvdXQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2Uuc2Nyb2xsU3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRyYWNrVGltZW91dCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFja1RpbWVvdXQgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlY3QgPSBfaG9zdEVsZW1lbnROYXRpdmVbTEVYSUNPTi5iQ1JdKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbW91c2VJbnNpZGVIb3N0ID0gZXZlbnQuY2xpZW50WCA+PSByZWN0LmxlZnQgJiYgZXZlbnQuY2xpZW50WCA8PSByZWN0LnJpZ2h0ICYmIGV2ZW50LmNsaWVudFkgPj0gcmVjdC50b3AgJiYgZXZlbnQuY2xpZW50WSA8PSByZWN0LmJvdHRvbTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIG1vdXNlIGlzIG91dHNpZGUgaG9zdCBlbGVtZW50XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1vdXNlSW5zaWRlSG9zdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3N0T25Nb3VzZUxlYXZlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJzQXV0b0hpZGVTY3JvbGwgfHwgX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gb25IYW5kbGVNb3VzZVRvdWNoRG93bihldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob25Nb3VzZVRvdWNoRG93bkNvbnRpbnVlKGV2ZW50KSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uSGFuZGxlTW91c2VUb3VjaERvd25BY3Rpb24oZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBvbkhhbmRsZU1vdXNlVG91Y2hEb3duQWN0aW9uKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93blNjcm9sbCA9IF92aWV3cG9ydEVsZW1lbnRbc2Nyb2xsXSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtb3VzZURvd25TY3JvbGwgPSBpc05hTihtb3VzZURvd25TY3JvbGwpID8gMCA6IG1vdXNlRG93blNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1JUTCAmJiBpc0hvcml6b250YWwgJiYgIV9ydGxTY3JvbGxCZWhhdmlvci5uIHx8ICFfaXNSVEwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3VzZURvd25TY3JvbGwgPSBtb3VzZURvd25TY3JvbGwgPCAwID8gMCA6IG1vdXNlRG93blNjcm9sbDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93bkludmVydGVkU2NhbGUgPSBnZXRIb3N0RWxlbWVudEludmVydGVkU2NhbGUoKVt4eV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93bk9mZnNldCA9IGdldFBvaW50ZXJQb3NpdGlvbihldmVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0hhbmRsZXNEZWZpbmVTY3JvbGxQb3MgPSAhZ2V0UHJlcGFyZWRTY3JvbGxiYXJzT3B0aW9uKHN0clNuYXBIYW5kbGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfYm9keUVsZW1lbnQsIF9jbGFzc05hbWVEcmFnZ2luZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKHNjcm9sbGJhclZhcnMuX2hhbmRsZSwgc3RyQWN0aXZlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3Moc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyLCBzdHJBY3RpdmUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfZG9jdW1lbnRFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW19zdHJNb3VzZVRvdWNoTW92ZUV2ZW50LCBfc3RyTW91c2VUb3VjaFVwRXZlbnQsIF9zdHJTZWxlY3RTdGFydEV2ZW50XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkb2N1bWVudERyYWdNb3ZlLCBkb2N1bWVudE1vdXNlVG91Y2hVcCwgZG9jdW1lbnRPblNlbGVjdFN0YXJ0XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuckFGKCkoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF9kb2N1bWVudEVsZW1lbnQsIHN0ckNsaWNrRXZlbnQsIHN0b3BDbGlja0V2ZW50UHJvcGFnYXRpb24sIGZhbHNlLCB7IF9jYXB0dXJlOiB0cnVlIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX21zaWVWZXJzaW9uIHx8ICFfZG9jdW1lbnRNaXhlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuc3RwUChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uVHJhY2tNb3VzZVRvdWNoRG93bihldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob25Nb3VzZVRvdWNoRG93bkNvbnRpbnVlKGV2ZW50KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZVRvVmlld3BvcnRSYXRpbyA9IHNjcm9sbGJhclZhcnMuX2luZm8uX2hhbmRsZUxlbmd0aCAvIE1hdGgucm91bmQoTUFUSC5taW4oMSwgX3ZpZXdwb3J0U2l6ZVtzY3JvbGxiYXJWYXJzLl93X2hdIC8gX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGVbc2Nyb2xsYmFyVmFycy5fd19oXSkgKiBzY3JvbGxiYXJWYXJzLl9pbmZvLl90cmFja0xlbmd0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsRGlzdGFuY2UgPSBNQVRILnJvdW5kKF92aWV3cG9ydFNpemVbc2Nyb2xsYmFyVmFycy5fd19oXSAqIGhhbmRsZVRvVmlld3BvcnRSYXRpbyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsQmFzZUR1cmF0aW9uID0gMjcwICogaGFuZGxlVG9WaWV3cG9ydFJhdGlvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbEZpcnN0SXRlcmF0aW9uRGVsYXkgPSA0MDAgKiBoYW5kbGVUb1ZpZXdwb3J0UmF0aW87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhY2tPZmZzZXQgPSBzY3JvbGxiYXJWYXJzLl90cmFjay5vZmZzZXQoKVtzY3JvbGxiYXJWYXJzLl9sZWZ0X3RvcF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3RybEtleSA9IGV2ZW50LmN0cmxLZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFudFNjcm9sbCA9IGV2ZW50LnNoaWZ0S2V5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbnRTY3JvbGxUcmFuc2l0aW9uID0gaW5zdGFudFNjcm9sbCAmJiBjdHJsS2V5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzRmlyc3RJdGVyYXRpb24gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVhc2luZyA9ICdsaW5lYXInO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRlY3JlYXNlU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZpbmlzaGVkQ29uZGl0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbEFjdGlvbkZpbnNpc2hlZCA9IGZ1bmN0aW9uICh0cmFuc2l0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJzSGFuZGxlc0RlZmluZVNjcm9sbFBvcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldChpc0hvcml6b250YWwsIHRyYW5zaXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxBY3Rpb25JbnN0YW50RmluaXNoZWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsQWN0aW9uRmluc2lzaGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25IYW5kbGVNb3VzZVRvdWNoRG93bkFjdGlvbihldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbEFjdGlvbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9kZXN0cm95ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1vdXNlT2Zmc2V0ID0gKG1vdXNlRG93bk9mZnNldCAtIHRyYWNrT2Zmc2V0KSAqIG1vdXNlRG93bkludmVydGVkU2NhbGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVPZmZzZXQgPSBzY3JvbGxiYXJWYXJzSW5mby5faGFuZGxlT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhY2tMZW5ndGggPSBzY3JvbGxiYXJWYXJzSW5mby5fdHJhY2tMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVMZW5ndGggPSBzY3JvbGxiYXJWYXJzSW5mby5faGFuZGxlTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsUmFuZ2UgPSBzY3JvbGxiYXJWYXJzSW5mby5fbWF4U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyclNjcm9sbCA9IHNjcm9sbGJhclZhcnNJbmZvLl9jdXJyZW50U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsRHVyYXRpb24gPSBzY3JvbGxCYXNlRHVyYXRpb24gKiBzY3JvbGxEdXJhdGlvbkZhY3RvcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRpbWVvdXREZWxheSA9IGlzRmlyc3RJdGVyYXRpb24gPyBNQVRILm1heChzY3JvbGxGaXJzdEl0ZXJhdGlvbkRlbGF5LCBzY3JvbGxEdXJhdGlvbikgOiBzY3JvbGxEdXJhdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbnRTY3JvbGxQb3NpdGlvbiA9IHNjcm9sbFJhbmdlICogKChtb3VzZU9mZnNldCAtIChoYW5kbGVMZW5ndGggLyAyKSkgLyAodHJhY2tMZW5ndGggLSBoYW5kbGVMZW5ndGgpKTsgLy8gMTAwJSAqIHBvc2l0aW9uUGVyY2VudFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcnRsSXNOb3JtYWwgPSBfaXNSVEwgJiYgaXNIb3Jpem9udGFsICYmICgoIV9ydGxTY3JvbGxCZWhhdmlvci5pICYmICFfcnRsU2Nyb2xsQmVoYXZpb3IubikgfHwgX25vcm1hbGl6ZVJUTENhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRlY3JlYXNlU2Nyb2xsQ29uZGl0aW9uID0gcnRsSXNOb3JtYWwgPyBoYW5kbGVPZmZzZXQgPCBtb3VzZU9mZnNldCA6IGhhbmRsZU9mZnNldCA+IG1vdXNlT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsT2JqID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhbmltYXRpb25PYmogPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYXNpbmc6IGVhc2luZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXA6IGZ1bmN0aW9uIChub3cpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbc2Nyb2xsXShub3cpOyAvL2h0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvanF1ZXJ5L2lzc3Vlcy80MzQwXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVPZmZzZXQoaXNIb3Jpem9udGFsLCBub3cpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gaXNGaW5pdGUoaW5zdGFudFNjcm9sbFBvc2l0aW9uKSA/IGluc3RhbnRTY3JvbGxQb3NpdGlvbiA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbnRTY3JvbGxQb3NpdGlvbiA9IF9pc1JUTCAmJiBpc0hvcml6b250YWwgJiYgIV9ydGxTY3JvbGxCZWhhdmlvci5pID8gKHNjcm9sbFJhbmdlIC0gaW5zdGFudFNjcm9sbFBvc2l0aW9uKSA6IGluc3RhbnRTY3JvbGxQb3NpdGlvbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vX2Jhc2Uuc2Nyb2xsU3RvcCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbnRTY3JvbGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbc2Nyb2xsXShpbnN0YW50U2Nyb2xsUG9zaXRpb24pOyAvL3Njcm9sbCBpbnN0YW50bHkgdG8gbmV3IHBvc2l0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFudFNjcm9sbFRyYW5zaXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2dldCB0aGUgc2Nyb2xsIHBvc2l0aW9uIGFmdGVyIGluc3RhbnQgc2Nyb2xsIChpbiBjYXNlIENTUyBTbmFwIFBvaW50cyBhcmUgdXNlZCkgdG8gZ2V0IHRoZSBjb3JyZWN0IHNuYXBwZWQgc2Nyb2xsIHBvc2l0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9hbmQgdGhlIGFuaW1hdGlvbiBzdG9wcyBhdCB0aGUgY29ycmVjdCBwb2ludFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbnRTY3JvbGxQb3NpdGlvbiA9IF92aWV3cG9ydEVsZW1lbnRbc2Nyb2xsXSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc2Nyb2xsIGJhY2sgdG8gdGhlIHBvc2l0aW9uIGJlZm9yZSBpbnN0YW50IHNjcm9sbGluZyBzbyBhbmltYXRpb24gY2FuIGJlIHBlcmZvcm1lZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbc2Nyb2xsXShjdXJyU2Nyb2xsKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gcnRsSXNOb3JtYWwgJiYgX3J0bFNjcm9sbEJlaGF2aW9yLmkgPyAoc2Nyb2xsUmFuZ2UgLSBpbnN0YW50U2Nyb2xsUG9zaXRpb24pIDogaW5zdGFudFNjcm9sbFBvc2l0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbnRTY3JvbGxQb3NpdGlvbiA9IHJ0bElzTm9ybWFsICYmIF9ydGxTY3JvbGxCZWhhdmlvci5uID8gLWluc3RhbnRTY3JvbGxQb3NpdGlvbiA6IGluc3RhbnRTY3JvbGxQb3NpdGlvbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsT2JqW3h5XSA9IGluc3RhbnRTY3JvbGxQb3NpdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS5zY3JvbGwoc2Nyb2xsT2JqLCBleHRlbmREZWVwKGFuaW1hdGlvbk9iaiwge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbjogMTMwLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZTogc2Nyb2xsQWN0aW9uSW5zdGFudEZpbmlzaGVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbEFjdGlvbkluc3RhbnRGaW5pc2hlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjcmVhc2VTY3JvbGwgPSBpc0ZpcnN0SXRlcmF0aW9uID8gZGVjcmVhc2VTY3JvbGxDb25kaXRpb24gOiBkZWNyZWFzZVNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmlzaGVkQ29uZGl0aW9uID0gcnRsSXNOb3JtYWxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IChkZWNyZWFzZVNjcm9sbCA/IGhhbmRsZU9mZnNldCArIGhhbmRsZUxlbmd0aCA+PSBtb3VzZU9mZnNldCA6IGhhbmRsZU9mZnNldCA8PSBtb3VzZU9mZnNldClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IChkZWNyZWFzZVNjcm9sbCA/IGhhbmRsZU9mZnNldCA8PSBtb3VzZU9mZnNldCA6IGhhbmRsZU9mZnNldCArIGhhbmRsZUxlbmd0aCA+PSBtb3VzZU9mZnNldCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkQ29uZGl0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRyYWNrVGltZW91dCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2Uuc2Nyb2xsU3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrVGltZW91dCA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxBY3Rpb25GaW5zaXNoZWQodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFja1RpbWVvdXQgPSBzZXRUaW1lb3V0KHNjcm9sbEFjdGlvbiwgdGltZW91dERlbGF5KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsT2JqW3h5XSA9IChkZWNyZWFzZVNjcm9sbCA/ICctPScgOiAnKz0nKSArIHNjcm9sbERpc3RhbmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9iYXNlLnNjcm9sbChzY3JvbGxPYmosIGV4dGVuZERlZXAoYW5pbWF0aW9uT2JqLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBzY3JvbGxEdXJhdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzRmlyc3RJdGVyYXRpb24gPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3RybEtleSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNyZWFzZVRyYWNrU2Nyb2xsQW1vdW50KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duSW52ZXJ0ZWRTY2FsZSA9IGdldEhvc3RFbGVtZW50SW52ZXJ0ZWRTY2FsZSgpW3h5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93bk9mZnNldCA9IENPTVBBVElCSUxJVFkucGFnZShldmVudClbeHldO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzSGFuZGxlc0RlZmluZVNjcm9sbFBvcyA9ICFnZXRQcmVwYXJlZFNjcm9sbGJhcnNPcHRpb24oc3RyU25hcEhhbmRsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfYm9keUVsZW1lbnQsIF9jbGFzc05hbWVEcmFnZ2luZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhzY3JvbGxiYXJWYXJzLl90cmFjaywgc3RyQWN0aXZlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKHNjcm9sbGJhclZhcnMuX3Njcm9sbGJhciwgc3RyQWN0aXZlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF9kb2N1bWVudEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW19zdHJNb3VzZVRvdWNoVXBFdmVudCwgX3N0cktleURvd25FdmVudCwgX3N0cktleVVwRXZlbnQsIF9zdHJTZWxlY3RTdGFydEV2ZW50XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZG9jdW1lbnRNb3VzZVRvdWNoVXAsIGRvY3VtZW50S2V5RG93biwgZG9jdW1lbnRLZXlVcCwgZG9jdW1lbnRPblNlbGVjdFN0YXJ0XSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsQWN0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnBydkQoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBvblRyYWNrTW91c2VUb3VjaEVudGVyKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWFrZSBzdXJlIGJvdGggc2Nyb2xsYmFycyB3aWxsIHN0YXkgdmlzaWJsZSBpZiBvbmUgc2Nyb2xsYmFyIGlzIGhvdmVyZWQgaWYgYXV0b0hpZGUgaXMgXCJzY3JvbGxcIiBvciBcIm1vdmVcIi5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNIYW5kbGVIb3ZlcmVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJzQXV0b0hpZGVTY3JvbGwgfHwgX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc0F1dG9IaWRlKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBvblRyYWNrTW91c2VUb3VjaExlYXZlKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzSGFuZGxlSG92ZXJlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBvblNjcm9sbGJhck1vdXNlVG91Y2hEb3duKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuc3RwUChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihzY3JvbGxiYXJWYXJzLl9oYW5kbGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJNb3VzZVRvdWNoRG93bkV2ZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkhhbmRsZU1vdXNlVG91Y2hEb3duKTtcclxuICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihzY3JvbGxiYXJWYXJzLl90cmFjayxcclxuICAgICAgICAgICAgICAgICAgICAgICAgW19zdHJNb3VzZVRvdWNoRG93bkV2ZW50LCBfc3RyTW91c2VFbnRlciwgX3N0ck1vdXNlTGVhdmVdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbb25UcmFja01vdXNlVG91Y2hEb3duLCBvblRyYWNrTW91c2VUb3VjaEVudGVyLCBvblRyYWNrTW91c2VUb3VjaExlYXZlXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIoc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTW91c2VUb3VjaERvd25FdmVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgb25TY3JvbGxiYXJNb3VzZVRvdWNoRG93bik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydFRyYW5zaXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIoc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyLCBfc3RyVHJhbnNpdGlvbkVuZEV2ZW50LCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudC50YXJnZXQgIT09IHNjcm9sbGJhclZhcnMuX3Njcm9sbGJhclswXSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlTGVuZ3RoKGlzSG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGlzSG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNob3dzIG9yIGhpZGVzIHRoZSBnaXZlbiBzY3JvbGxiYXIgYW5kIGFwcGxpZWQgYSBjbGFzcyBuYW1lIHdoaWNoIGluZGljYXRlcyBpZiB0aGUgc2Nyb2xsYmFyIGlzIHNjcm9sbGFibGUgb3Igbm90LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGlzSG9yaXpvbnRhbCBUcnVlIGlmIHRoZSBob3Jpem9udGFsIHNjcm9sbGJhciBpcyB0aGUgdGFyZ2V0LCBmYWxzZSBpZiB0aGUgdmVydGljYWwgc2Nyb2xsYmFyIGlzIHRoZSB0YXJnZXQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gc2hhbGxCZVZpc2libGUgVHJ1ZSBpZiB0aGUgc2Nyb2xsYmFyIHNoYWxsIGJlIHNob3duLCBmYWxzZSBpZiBoaWRkZW4uXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gY2FuU2Nyb2xsIFRydWUgaWYgdGhlIHNjcm9sbGJhciBpcyBzY3JvbGxhYmxlLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHJlZnJlc2hTY3JvbGxiYXJBcHBlYXJhbmNlKGlzSG9yaXpvbnRhbCwgc2hhbGxCZVZpc2libGUsIGNhblNjcm9sbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJIaWRkZW5DbGFzc05hbWUgPSBpc0hvcml6b250YWwgPyBfY2xhc3NOYW1lSG9zdFNjcm9sbGJhckhvcml6b250YWxIaWRkZW4gOiBfY2xhc3NOYW1lSG9zdFNjcm9sbGJhclZlcnRpY2FsSGlkZGVuO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJFbGVtZW50ID0gaXNIb3Jpem9udGFsID8gX3Njcm9sbGJhckhvcml6b250YWxFbGVtZW50IDogX3Njcm9sbGJhclZlcnRpY2FsRWxlbWVudDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBzY3JvbGxiYXJIaWRkZW5DbGFzc05hbWUsICFzaGFsbEJlVmlzaWJsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3Moc2Nyb2xsYmFyRWxlbWVudCwgX2NsYXNzTmFtZVNjcm9sbGJhclVudXNhYmxlLCAhY2FuU2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEF1dG9zaG93cyAvIGF1dG9oaWRlcyBib3RoIHNjcm9sbGJhcnMgd2l0aC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBzaGFsbEJlVmlzaWJsZSBUcnVlIGlmIHRoZSBzY3JvbGxiYXJzIHNoYWxsIGJlIGF1dG9zaG93biAob25seSB0aGUgY2FzZSBpZiB0aGV5IGFyZSBoaWRkZW4gYnkgYSBhdXRvaGlkZSksIGZhbHNlIGlmIHRoZSBzaGFsbCBiZSBhdXRvIGhpZGRlbi5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBkZWxheWZyZWUgVHJ1ZSBpZiB0aGUgc2Nyb2xsYmFycyBzaGFsbCBiZSBoaWRkZW4gd2l0aG91dCBhIGRlbGF5LCBmYWxzZSBvciB1bmRlZmluZWQgb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiByZWZyZXNoU2Nyb2xsYmFyc0F1dG9IaWRlKHNoYWxsQmVWaXNpYmxlLCBkZWxheWZyZWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoX3Njcm9sbGJhcnNBdXRvSGlkZVRpbWVvdXRJZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNoYWxsQmVWaXNpYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYoX2hhc092ZXJmbG93Q2FjaGUueCAmJiBfaGlkZU92ZXJmbG93Q2FjaGUueHMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9zY3JvbGxiYXJIb3Jpem9udGFsRWxlbWVudCwgX2NsYXNzTmFtZVNjcm9sbGJhckF1dG9IaWRkZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2lmKF9oYXNPdmVyZmxvd0NhY2hlLnkgJiYgX2hpZGVPdmVyZmxvd0NhY2hlLnlzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQXV0b0hpZGRlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYW55QWN0aXZlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQWN0aXZlID0gJ2FjdGl2ZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoaWRlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfc2Nyb2xsYmFyc0hhbmRsZUhvdmVyZWQgJiYgIV9kZXN0cm95ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnlBY3RpdmUgPSBfc2Nyb2xsYmFySG9yaXpvbnRhbEhhbmRsZUVsZW1lbnQuaGFzQ2xhc3Moc3RyQWN0aXZlKSB8fCBfc2Nyb2xsYmFyVmVydGljYWxIYW5kbGVFbGVtZW50Lmhhc0NsYXNzKHN0ckFjdGl2ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhbnlBY3RpdmUgJiYgKF9zY3JvbGxiYXJzQXV0b0hpZGVTY3JvbGwgfHwgX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUgfHwgX3Njcm9sbGJhcnNBdXRvSGlkZUxlYXZlKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX3Njcm9sbGJhckhvcml6b250YWxFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQXV0b0hpZGRlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhbnlBY3RpdmUgJiYgKF9zY3JvbGxiYXJzQXV0b0hpZGVTY3JvbGwgfHwgX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUgfHwgX3Njcm9sbGJhcnNBdXRvSGlkZUxlYXZlKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX3Njcm9sbGJhclZlcnRpY2FsRWxlbWVudCwgX2NsYXNzTmFtZVNjcm9sbGJhckF1dG9IaWRkZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZURlbGF5ID4gMCAmJiBkZWxheWZyZWUgIT09IHRydWUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0F1dG9IaWRlVGltZW91dElkID0gc2V0VGltZW91dChoaWRlLCBfc2Nyb2xsYmFyc0F1dG9IaWRlRGVsYXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmVmcmVzaGVzIHRoZSBoYW5kbGUgbGVuZ3RoIG9mIHRoZSBnaXZlbiBzY3JvbGxiYXIuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gaXNIb3Jpem9udGFsIFRydWUgaWYgdGhlIGhvcml6b250YWwgc2Nyb2xsYmFyIGhhbmRsZSBzaGFsbCBiZSByZWZyZXNoZWQsIGZhbHNlIGlmIHRoZSB2ZXJ0aWNhbCBvbmUgc2hhbGwgYmUgcmVmcmVzaGVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiByZWZyZXNoU2Nyb2xsYmFySGFuZGxlTGVuZ3RoKGlzSG9yaXpvbnRhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFycyA9IGdldFNjcm9sbGJhclZhcnMoaXNIb3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFyc0luZm8gPSBzY3JvbGxiYXJWYXJzLl9pbmZvO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkaWdpdCA9IDEwMDAwMDA7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9nZXQgYW5kIGFwcGx5IGludGVuZGVkIGhhbmRsZSBsZW5ndGhcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaGFuZGxlUmF0aW8gPSBNQVRILm1pbigxLCBfdmlld3BvcnRTaXplW3Njcm9sbGJhclZhcnMuX3dfaF0gLyBfY29udGVudFNjcm9sbFNpemVDYWNoZVtzY3JvbGxiYXJWYXJzLl93X2hdKTtcclxuICAgICAgICAgICAgICAgICAgICBoYW5kbGVDU1Nbc2Nyb2xsYmFyVmFycy5fd2lkdGhfaGVpZ2h0XSA9IChNQVRILmZsb29yKGhhbmRsZVJhdGlvICogMTAwICogZGlnaXQpIC8gZGlnaXQpICsgJyUnOyAvL3RoZSBsYXN0ICogZGlnaXQgLyBkaWdpdCBpcyBmb3IgZmxvb3JpbmcgdG8gdGhlIDR0aCBkaWdpdFxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5hdGl2ZU92ZXJsYXlTY3JvbGxiYXJzQXJlQWN0aXZlKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnMuX2hhbmRsZS5jc3MoaGFuZGxlQ1NTKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9tZWFzdXJlIHRoZSBoYW5kbGUgbGVuZ3RoIHRvIHJlc3BlY3QgbWluICYgbWF4IGxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVMZW5ndGggPSBzY3JvbGxiYXJWYXJzLl9oYW5kbGVbMF1bJ29mZnNldCcgKyBzY3JvbGxiYXJWYXJzLl9XaWR0aF9IZWlnaHRdO1xyXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVMZW5ndGhSYXRpbyA9IGhhbmRsZVJhdGlvO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmVmcmVzaGVzIHRoZSBoYW5kbGUgb2Zmc2V0IG9mIHRoZSBnaXZlbiBzY3JvbGxiYXIuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gaXNIb3Jpem9udGFsIFRydWUgaWYgdGhlIGhvcml6b250YWwgc2Nyb2xsYmFyIGhhbmRsZSBzaGFsbCBiZSByZWZyZXNoZWQsIGZhbHNlIGlmIHRoZSB2ZXJ0aWNhbCBvbmUgc2hhbGwgYmUgcmVmcmVzaGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHNjcm9sbE9yVHJhbnNpdGlvbiBUaGUgc2Nyb2xsIHBvc2l0aW9uIG9mIHRoZSBnaXZlbiBzY3JvbGxiYXIgYXhpcyB0byB3aGljaCB0aGUgaGFuZGxlIHNoYWxsIGJlIG1vdmVkIG9yIGEgYm9vbGVhbiB3aGljaCBpbmRpY2F0ZXMgd2hldGhlciBhIHRyYW5zaXRpb24gc2hhbGwgYmUgYXBwbGllZC4gSWYgdW5kZWZpbmVkIG9yIGJvb2xlYW4gaWYgdGhlIGN1cnJlbnQgc2Nyb2xsLW9mZnNldCBpcyB0YWtlbi4gKGlmIGlzSG9yaXpvbnRhbCA/IHNjcm9sbExlZnQgOiBzY3JvbGxUb3ApXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVPZmZzZXQoaXNIb3Jpem9udGFsLCBzY3JvbGxPclRyYW5zaXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdHJhbnNpdGlvbiA9IHR5cGUoc2Nyb2xsT3JUcmFuc2l0aW9uKSA9PSBUWVBFUy5iO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFuc2l0aW9uRHVyYXRpb24gPSAyNTA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGlzUlRMaXNIb3Jpem9udGFsID0gX2lzUlRMICYmIGlzSG9yaXpvbnRhbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFycyA9IGdldFNjcm9sbGJhclZhcnMoaXNIb3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFyc0luZm8gPSBzY3JvbGxiYXJWYXJzLl9pbmZvO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJUcmFuc2xhdGVCcmFjZSA9ICd0cmFuc2xhdGUoJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyVHJhbnNmb3JtID0gVkVORE9SUy5fY3NzUHJvcGVydHkoJ3RyYW5zZm9ybScpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJUcmFuc2l0aW9uID0gVkVORE9SUy5fY3NzUHJvcGVydHkoJ3RyYW5zaXRpb24nKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbmF0aXZlU2Nyb2xsID0gaXNIb3Jpem9udGFsID8gX3ZpZXdwb3J0RWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oKSA6IF92aWV3cG9ydEVsZW1lbnRbX3N0clNjcm9sbFRvcF0oKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VycmVudFNjcm9sbCA9IHNjcm9sbE9yVHJhbnNpdGlvbiA9PT0gdW5kZWZpbmVkIHx8IHRyYW5zaXRpb24gPyBuYXRpdmVTY3JvbGwgOiBzY3JvbGxPclRyYW5zaXRpb247XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vbWVhc3VyZSB0aGUgaGFuZGxlIGxlbmd0aCB0byByZXNwZWN0IG1pbiAmIG1heCBsZW5ndGhcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaGFuZGxlTGVuZ3RoID0gc2Nyb2xsYmFyVmFyc0luZm8uX2hhbmRsZUxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdHJhY2tMZW5ndGggPSBzY3JvbGxiYXJWYXJzLl90cmFja1swXVsnb2Zmc2V0JyArIHNjcm9sbGJhclZhcnMuX1dpZHRoX0hlaWdodF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZVRyYWNrRGlmZiA9IHRyYWNrTGVuZ3RoIC0gaGFuZGxlTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdHJhbnNmb3JtT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFuc2xhdGVWYWx1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9ET05UIHVzZSB0aGUgdmFyaWFibGUgJ19jb250ZW50U2Nyb2xsU2l6ZUNhY2hlW3Njcm9sbGJhclZhcnMuX3dfaF0nIGluc3RlYWQgb2YgJ192aWV3cG9ydEVsZW1lbnRbMF1bJ3Njcm9sbCcgKyBzY3JvbGxiYXJWYXJzLl9XaWR0aF9IZWlnaHRdJ1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGJlY2F1c2UgaXRzIGEgYml0IGJlaGluZCBkdXJpbmcgdGhlIHNtYWxsIGRlbGF5IHdoZW4gY29udGVudCBzaXplIHVwZGF0ZXNcclxuICAgICAgICAgICAgICAgICAgICAvLyhkZWxheSA9IG11dGF0aW9uT2JzZXJ2ZXJDb250ZW50TGFnLCBpZiBpdHMgMCB0aGVuIHRoaXMgdmFyIGNvdWxkIGJlIHVzZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1heFNjcm9sbCA9IChfdmlld3BvcnRFbGVtZW50TmF0aXZlW19zdHJTY3JvbGwgKyBzY3JvbGxiYXJWYXJzLl9XaWR0aF9IZWlnaHRdIC0gX3ZpZXdwb3J0RWxlbWVudE5hdGl2ZVsnY2xpZW50JyArIHNjcm9sbGJhclZhcnMuX1dpZHRoX0hlaWdodF0pICogKF9ydGxTY3JvbGxCZWhhdmlvci5uICYmIGlzUlRMaXNIb3Jpem9udGFsID8gLTEgOiAxKTsgLy8qIC0xIGlmIHJ0bCBzY3JvbGwgbWF4IGlzIG5lZ2F0aXZlXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGdldFNjcm9sbFJhdGlvID0gZnVuY3Rpb24gKGJhc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlzTmFOKGJhc2UgLyBtYXhTY3JvbGwpID8gMCA6IE1BVEgubWF4KDAsIE1BVEgubWluKDEsIGJhc2UgLyBtYXhTY3JvbGwpKTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBnZXRIYW5kbGVPZmZzZXQgPSBmdW5jdGlvbiAoc2Nyb2xsUmF0aW8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9mZnNldCA9IGhhbmRsZVRyYWNrRGlmZiAqIHNjcm9sbFJhdGlvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBpc05hTihvZmZzZXQpID8gMCA6IG9mZnNldDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gKGlzUlRMaXNIb3Jpem9udGFsICYmICFfcnRsU2Nyb2xsQmVoYXZpb3IuaSkgPyAodHJhY2tMZW5ndGggLSBoYW5kbGVMZW5ndGggLSBvZmZzZXQpIDogb2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBNQVRILm1heCgwLCBvZmZzZXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbFJhdGlvID0gZ2V0U2Nyb2xsUmF0aW8obmF0aXZlU2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdW5zbmFwcGVkU2Nyb2xsUmF0aW8gPSBnZXRTY3JvbGxSYXRpbyhjdXJyZW50U2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaGFuZGxlT2Zmc2V0ID0gZ2V0SGFuZGxlT2Zmc2V0KHVuc25hcHBlZFNjcm9sbFJhdGlvKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc25hcHBlZEhhbmRsZU9mZnNldCA9IGdldEhhbmRsZU9mZnNldChzY3JvbGxSYXRpbyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnNJbmZvLl9tYXhTY3JvbGwgPSBtYXhTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX2N1cnJlbnRTY3JvbGwgPSBuYXRpdmVTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX2N1cnJlbnRTY3JvbGxSYXRpbyA9IHNjcm9sbFJhdGlvO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRUcmFuc2Zvcm0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtT2Zmc2V0ID0gaXNSVExpc0hvcml6b250YWwgPyAtKHRyYWNrTGVuZ3RoIC0gaGFuZGxlTGVuZ3RoIC0gaGFuZGxlT2Zmc2V0KSA6IGhhbmRsZU9mZnNldDsgLy9pbiBweFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3RyYW5zZm9ybU9mZnNldCA9ICh0cmFuc2Zvcm1PZmZzZXQgLyB0cmFja0xlbmd0aCAqIDEwMCkgKiAodHJhY2tMZW5ndGggLyBoYW5kbGVMZW5ndGgpOyAvL2luICVcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlVmFsdWUgPSBpc0hvcml6b250YWwgPyBzdHJUcmFuc2xhdGVCcmFjZSArIHRyYW5zZm9ybU9mZnNldCArICdweCwgMCknIDogc3RyVHJhbnNsYXRlQnJhY2UgKyAnMCwgJyArIHRyYW5zZm9ybU9mZnNldCArICdweCknO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlQ1NTW3N0clRyYW5zZm9ybV0gPSB0cmFuc2xhdGVWYWx1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYXBwbHkgb3IgY2xlYXIgdXAgdHJhbnNpdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRUcmFuc2l0aW9uKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlQ1NTW3N0clRyYW5zaXRpb25dID0gdHJhbnNpdGlvbiAmJiBNQVRILmFicyhoYW5kbGVPZmZzZXQgLSBzY3JvbGxiYXJWYXJzSW5mby5faGFuZGxlT2Zmc2V0KSA+IDEgPyBnZXRDU1NUcmFuc2l0aW9uU3RyaW5nKHNjcm9sbGJhclZhcnMuX2hhbmRsZSkgKyAnLCAnICsgKHN0clRyYW5zZm9ybSArIF9zdHJTcGFjZSArIHRyYW5zaXRpb25EdXJhdGlvbiArICdtcycpIDogX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUNTU1tzY3JvbGxiYXJWYXJzLl9sZWZ0X3RvcF0gPSBoYW5kbGVPZmZzZXQ7XHJcblxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL29ubHkgYXBwbHkgY3NzIGlmIG9mZnNldCBoYXMgY2hhbmdlZCBhbmQgb3ZlcmZsb3cgZXhpc3RzLlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbmF0aXZlT3ZlcmxheVNjcm9sbGJhcnNBcmVBY3RpdmUoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJWYXJzLl9oYW5kbGUuY3NzKGhhbmRsZUNTUyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2NsZWFyIHVwIHRyYW5zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zdXBwb3J0VHJhbnNmb3JtICYmIF9zdXBwb3J0VHJhbnNpdGlvbiAmJiB0cmFuc2l0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJWYXJzLl9oYW5kbGUub25lKF9zdHJUcmFuc2l0aW9uRW5kRXZlbnQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9kZXN0cm95ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnMuX2hhbmRsZS5jc3Moc3RyVHJhbnNpdGlvbiwgX3N0ckVtcHR5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJWYXJzSW5mby5faGFuZGxlT2Zmc2V0ID0gaGFuZGxlT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnNJbmZvLl9zbmFwcGVkSGFuZGxlT2Zmc2V0ID0gc25hcHBlZEhhbmRsZU9mZnNldDtcclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJWYXJzSW5mby5fdHJhY2tMZW5ndGggPSB0cmFja0xlbmd0aDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJlZnJlc2hlcyB0aGUgaW50ZXJhY3Rpdml0eSBvZiB0aGUgZ2l2ZW4gc2Nyb2xsYmFyIGVsZW1lbnQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gaXNUcmFjayBUcnVlIGlmIHRoZSB0cmFjayBlbGVtZW50IGlzIHRoZSB0YXJnZXQsIGZhbHNlIGlmIHRoZSBoYW5kbGUgZWxlbWVudCBpcyB0aGUgdGFyZ2V0LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHZhbHVlIFRydWUgZm9yIGludGVyYWN0aXZpdHkgZmFsc2UgZm9yIG5vIGludGVyYWN0aXZpdHkuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHJlZnJlc2hTY3JvbGxiYXJzSW50ZXJhY3RpdmUoaXNUcmFjaywgdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWN0aW9uID0gdmFsdWUgPyAncmVtb3ZlQ2xhc3MnIDogJ2FkZENsYXNzJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudDEgPSBpc1RyYWNrID8gX3Njcm9sbGJhckhvcml6b250YWxUcmFja0VsZW1lbnQgOiBfc2Nyb2xsYmFySG9yaXpvbnRhbEhhbmRsZUVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQyID0gaXNUcmFjayA/IF9zY3JvbGxiYXJWZXJ0aWNhbFRyYWNrRWxlbWVudCA6IF9zY3JvbGxiYXJWZXJ0aWNhbEhhbmRsZUVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzTmFtZSA9IGlzVHJhY2sgPyBfY2xhc3NOYW1lU2Nyb2xsYmFyVHJhY2tPZmYgOiBfY2xhc3NOYW1lU2Nyb2xsYmFySGFuZGxlT2ZmO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50MVthY3Rpb25dKGNsYXNzTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudDJbYWN0aW9uXShjbGFzc05hbWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyBhIG9iamVjdCB3aGljaCBpcyB1c2VkIGZvciBmYXN0IGFjY2VzcyBmb3Igc3BlY2lmaWMgdmFyaWFibGVzLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGlzSG9yaXpvbnRhbCBUcnVlIGlmIHRoZSBob3Jpem9udGFsIHNjcm9sbGJhciB2YXJzIHNoYWxsIGJlIGFjY2Vzc2VkLCBmYWxzZSBpZiB0aGUgdmVydGljYWwgc2Nyb2xsYmFyIHZhcnMgc2hhbGwgYmUgYWNjZXNzZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e3doOiBzdHJpbmcsIFdIOiBzdHJpbmcsIGx0OiBzdHJpbmcsIF93aDogc3RyaW5nLCBfbHQ6IHN0cmluZywgdDogKiwgaDogKiwgYzoge30sIHM6ICp9fVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRTY3JvbGxiYXJWYXJzKGlzSG9yaXpvbnRhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF93aWR0aF9oZWlnaHQ6IGlzSG9yaXpvbnRhbCA/IF9zdHJXaWR0aCA6IF9zdHJIZWlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9XaWR0aF9IZWlnaHQ6IGlzSG9yaXpvbnRhbCA/ICdXaWR0aCcgOiAnSGVpZ2h0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2xlZnRfdG9wOiBpc0hvcml6b250YWwgPyBfc3RyTGVmdCA6IF9zdHJUb3AsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9MZWZ0X1RvcDogaXNIb3Jpem9udGFsID8gJ0xlZnQnIDogJ1RvcCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF94X3k6IGlzSG9yaXpvbnRhbCA/IF9zdHJYIDogX3N0clksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9YX1k6IGlzSG9yaXpvbnRhbCA/ICdYJyA6ICdZJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3dfaDogaXNIb3Jpem9udGFsID8gJ3cnIDogJ2gnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbF90OiBpc0hvcml6b250YWwgPyAnbCcgOiAndCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90cmFjazogaXNIb3Jpem9udGFsID8gX3Njcm9sbGJhckhvcml6b250YWxUcmFja0VsZW1lbnQgOiBfc2Nyb2xsYmFyVmVydGljYWxUcmFja0VsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9oYW5kbGU6IGlzSG9yaXpvbnRhbCA/IF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudCA6IF9zY3JvbGxiYXJWZXJ0aWNhbEhhbmRsZUVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXI6IGlzSG9yaXpvbnRhbCA/IF9zY3JvbGxiYXJIb3Jpem9udGFsRWxlbWVudCA6IF9zY3JvbGxiYXJWZXJ0aWNhbEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9pbmZvOiBpc0hvcml6b250YWwgPyBfc2Nyb2xsSG9yaXpvbnRhbEluZm8gOiBfc2Nyb2xsVmVydGljYWxJbmZvXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IFNjcm9sbGJhciBDb3JuZXIgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBCdWlsZHMgb3IgZGVzdHJveXMgdGhlIHNjcm9sbGJhciBjb3JuZXIgRE9NIGVsZW1lbnQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZGVzdHJveSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgRE9NIHNoYWxsIGJlIGJ1aWxkIG9yIGRlc3Ryb3llZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBTY3JvbGxiYXJDb3JuZXJET00oZGVzdHJveSkge1xyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50ID0gX3Njcm9sbGJhckNvcm5lckVsZW1lbnQgfHwgc2VsZWN0T3JHZW5lcmF0ZURpdkJ5Q2xhc3MoX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lciwgdHJ1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZGVzdHJveSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9kb21FeGlzdHMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudC5hcHBlbmQoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2RvbUV4aXN0cyAmJiBfaW5pdGlhbGl6ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50LnJlbW92ZUF0dHIoTEVYSUNPTi5zKSwgX2NsYXNzTmFtZXNEeW5hbWljRGVzdHJveSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgYWxsIHNjcm9sbGJhciBjb3JuZXIgaW50ZXJhY3Rpdml0eSBldmVudHMuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldHVwU2Nyb2xsYmFyQ29ybmVyRXZlbnRzKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbnNpZGVJRnJhbWUgPSBfd2luZG93RWxlbWVudE5hdGl2ZS50b3AgIT09IF93aW5kb3dFbGVtZW50TmF0aXZlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtb3VzZURvd25Qb3NpdGlvbiA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtb3VzZURvd25TaXplID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1vdXNlRG93bkludmVydGVkU2NhbGUgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVjb25uZWN0TXV0YXRpb25PYnNlcnZlcjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZG9jdW1lbnREcmFnTW92ZShldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob25Nb3VzZVRvdWNoRG93bkNvbnRpbnVlKGV2ZW50KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhZ2VPZmZzZXQgPSBnZXRDb29yZGluYXRlcyhldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdEVsZW1lbnRDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfcmVzaXplSG9yaXpvbnRhbCB8fCBfcmVzaXplQm90aClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3N0RWxlbWVudENTU1tfc3RyV2lkdGhdID0gKG1vdXNlRG93blNpemUudyArIChwYWdlT2Zmc2V0LnggLSBtb3VzZURvd25Qb3NpdGlvbi54KSAqIG1vdXNlRG93bkludmVydGVkU2NhbGUueCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Jlc2l6ZVZlcnRpY2FsIHx8IF9yZXNpemVCb3RoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RFbGVtZW50Q1NTW19zdHJIZWlnaHRdID0gKG1vdXNlRG93blNpemUuaCArIChwYWdlT2Zmc2V0LnkgLSBtb3VzZURvd25Qb3NpdGlvbi55KSAqIG1vdXNlRG93bkludmVydGVkU2NhbGUueSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnQuY3NzKGhvc3RFbGVtZW50Q1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuc3RwUChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudE1vdXNlVG91Y2hVcChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZG9jdW1lbnRNb3VzZVRvdWNoVXAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGV2ZW50SXNUcnVzdGVkID0gZXZlbnQgIT09IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoX2RvY3VtZW50RWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtfc3RyU2VsZWN0U3RhcnRFdmVudCwgX3N0ck1vdXNlVG91Y2hNb3ZlRXZlbnQsIF9zdHJNb3VzZVRvdWNoVXBFdmVudF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZG9jdW1lbnRPblNlbGVjdFN0YXJ0LCBkb2N1bWVudERyYWdNb3ZlLCBkb2N1bWVudE1vdXNlVG91Y2hVcF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ib2R5RWxlbWVudCwgX2NsYXNzTmFtZURyYWdnaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50LnJlbGVhc2VDYXB0dXJlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhckNvcm5lckVsZW1lbnQucmVsZWFzZUNhcHR1cmUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudElzVHJ1c3RlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXIpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXJzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS51cGRhdGUoX3N0ckF1dG8pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXIgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gb25Nb3VzZVRvdWNoRG93bkNvbnRpbnVlKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcmlnaW5hbEV2ZW50ID0gZXZlbnQub3JpZ2luYWxFdmVudCB8fCBldmVudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzVG91Y2hFdmVudCA9IG9yaWdpbmFsRXZlbnQudG91Y2hlcyAhPT0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3NsZWVwaW5nIHx8IF9kZXN0cm95ZWQgPyBmYWxzZSA6IENPTVBBVElCSUxJVFkubUJ0bihldmVudCkgPT09IDEgfHwgaXNUb3VjaEV2ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRDb29yZGluYXRlcyhldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX21zaWVWZXJzaW9uICYmIGluc2lkZUlGcmFtZSA/IHsgeDogZXZlbnQuc2NyZWVuWCwgeTogZXZlbnQuc2NyZWVuWSB9IDogQ09NUEFUSUJJTElUWS5wYWdlKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50LCBfc3RyTW91c2VUb3VjaERvd25FdmVudCwgZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpICYmICFfcmVzaXplTm9uZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9tdXRhdGlvbk9ic2VydmVyc0Nvbm5lY3RlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXIgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RNdXRhdGlvbk9ic2VydmVycygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93blBvc2l0aW9uID0gZ2V0Q29vcmRpbmF0ZXMoZXZlbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93blNpemUudyA9IF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9XXSAtICghX2lzQm9yZGVyQm94ID8gX3BhZGRpbmdYIDogMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3VzZURvd25TaXplLmggPSBfaG9zdEVsZW1lbnROYXRpdmVbTEVYSUNPTi5vSF0gLSAoIV9pc0JvcmRlckJveCA/IF9wYWRkaW5nWSA6IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duSW52ZXJ0ZWRTY2FsZSA9IGdldEhvc3RFbGVtZW50SW52ZXJ0ZWRTY2FsZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoX2RvY3VtZW50RWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbX3N0clNlbGVjdFN0YXJ0RXZlbnQsIF9zdHJNb3VzZVRvdWNoTW92ZUV2ZW50LCBfc3RyTW91c2VUb3VjaFVwRXZlbnRdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkb2N1bWVudE9uU2VsZWN0U3RhcnQsIGRvY3VtZW50RHJhZ01vdmUsIGRvY3VtZW50TW91c2VUb3VjaFVwXSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX2JvZHlFbGVtZW50LCBfY2xhc3NOYW1lRHJhZ2dpbmcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50LnNldENhcHR1cmUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhckNvcm5lckVsZW1lbnQuc2V0Q2FwdHVyZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnN0cFAoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBVdGlscyA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENhbGxzIHRoZSBjYWxsYmFjayB3aXRoIHRoZSBnaXZlbiBuYW1lLiBUaGUgQ29udGV4dCBvZiB0aGlzIGNhbGxiYWNrIGlzIGFsd2F5cyBfYmFzZSAodGhpcykuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0IHdoaWNoIHNoYWxsIGJlIGNhbGxlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBhcmdzIFRoZSBhcmdzIHdpdGggd2hpY2ggdGhlIGNhbGxiYWNrIHNoYWxsIGJlIGNhbGxlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBkZXBlbmRlbnQgQm9vbGVhbiB3aGljaCBkZWNpZGVzIHdoZXRoZXIgdGhlIGNhbGxiYWNrIHNoYWxsIGJlIGZpcmVkLCB1bmRlZmluZWQgaXMgbGlrZSBhIFwidHJ1ZVwiIHZhbHVlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBkaXNwYXRjaENhbGxiYWNrKG5hbWUsIGFyZ3MsIGRlcGVuZGVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChkZXBlbmRlbnQgPT09IGZhbHNlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pbml0aWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2FsbGJhY2sgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5jYWxsYmFja3NbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleHRlbnNpb25Pbk5hbWUgPSBuYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXh0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbk9uTmFtZS5zdWJzdHIoMCwgMikgPT09ICdvbicpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25Pbk5hbWUgPSBleHRlbnNpb25Pbk5hbWUuc3Vic3RyKDIsIDEpLnRvTG93ZXJDYXNlKCkgKyBleHRlbnNpb25Pbk5hbWUuc3Vic3RyKDMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUoY2FsbGJhY2spID09IFRZUEVTLmYpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKF9iYXNlLCBhcmdzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVhY2goX2V4dGVuc2lvbnMsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dCA9IHRoaXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShleHQub24pID09IFRZUEVTLmYpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0Lm9uKGV4dGVuc2lvbk9uTmFtZSwgYXJncyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghX2Rlc3Ryb3llZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NhbGxiYWNrc0luaXRRZXVldWUucHVzaCh7IG46IG5hbWUsIGE6IGFyZ3MgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBTZXRzIHRoZSBcInRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdFwiIHByb3BlcnRpZXMsIHdpdGggYSBnaXZlbiBwcmVmaXgsIG9mIHRoZSBnaXZlbiBjc3Mgb2JqZWN0LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHRhcmdldENTU09iamVjdCBUaGUgY3NzIG9iamVjdCB0byB3aGljaCB0aGUgdmFsdWVzIHNoYWxsIGJlIGFwcGxpZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gcHJlZml4IFRoZSBwcmVmaXggb2YgdGhlIFwidG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XCIgY3NzIHByb3BlcnRpZXMuIChleGFtcGxlOiAncGFkZGluZy0nIGlzIGEgdmFsaWQgcHJlZml4KVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHZhbHVlcyBBIGFycmF5IG9mIHZhbHVlcyB3aGljaCBzaGFsbCBiZSBhcHBsaWVkIHRvIHRoZSBcInRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdFwiIC1wcm9wZXJ0aWVzLiBUaGUgYXJyYXkgb3JkZXIgaXMgW3RvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdF0uXHJcbiAgICAgICAgICAgICAgICAgKiBJZiB0aGlzIGFyZ3VtZW50IGlzIHVuZGVmaW5lZCB0aGUgdmFsdWUgJycgKGVtcHR5IHN0cmluZykgd2lsbCBiZSBhcHBsaWVkIHRvIGFsbCBwcm9wZXJ0aWVzLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXRUb3BSaWdodEJvdHRvbUxlZnQodGFyZ2V0Q1NTT2JqZWN0LCBwcmVmaXgsIHZhbHVlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IHByZWZpeCB8fCBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzIHx8IFtfc3RyRW1wdHksIF9zdHJFbXB0eSwgX3N0ckVtcHR5LCBfc3RyRW1wdHldO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRDU1NPYmplY3RbcHJlZml4ICsgX3N0clRvcF0gPSB2YWx1ZXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Q1NTT2JqZWN0W3ByZWZpeCArIF9zdHJSaWdodF0gPSB2YWx1ZXNbMV07XHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Q1NTT2JqZWN0W3ByZWZpeCArIF9zdHJCb3R0b21dID0gdmFsdWVzWzJdO1xyXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldENTU09iamVjdFtwcmVmaXggKyBfc3RyTGVmdF0gPSB2YWx1ZXNbM107XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHRoZSBcInRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdFwiIENTUyBwcm9wZXJ0aWVzIG9mIHRoZSBDU1MgcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4gcHJlZml4IGZyb20gdGhlIGhvc3QgZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCBvZiB0aGUgXCJ0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRcIiBjc3MgcHJvcGVydGllcy4gKGV4YW1wbGU6ICdwYWRkaW5nLScgaXMgYSB2YWxpZCBwcmVmaXgpXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gc3VmZml4IFRoZSBzdWZmaXggb2YgdGhlIFwidG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XCIgY3NzIHByb3BlcnRpZXMuIChleGFtcGxlOiAnYm9yZGVyLScgaXMgYSB2YWxpZCBwcmVmaXggd2l0aCAnLXdpZHRoJyBpcyBhIHZhbGlkIHN1ZmZpeClcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB6ZXJvWCBUcnVlIGlmIHRoZSB4IGF4aXMgc2hhbGwgYmUgMC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB6ZXJvWSBUcnVlIGlmIHRoZSB5IGF4aXMgc2hhbGwgYmUgMC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIG9iamVjdCB3aGljaCBjb250YWlucyB0aGUgbnVtYmVycyBvZiB0aGUgcmVhZCBDU1MgcHJvcGVydGllcy5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0VG9wUmlnaHRCb3R0b21MZWZ0SG9zdChwcmVmaXgsIHN1ZmZpeCwgemVyb1gsIHplcm9ZKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3VmZml4ID0gc3VmZml4IHx8IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICBwcmVmaXggPSBwcmVmaXggfHwgX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHQ6IHplcm9ZID8gMCA6IHBhcnNlVG9aZXJvT3JOdW1iZXIoX2hvc3RFbGVtZW50LmNzcyhwcmVmaXggKyBfc3RyVG9wICsgc3VmZml4KSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHI6IHplcm9YID8gMCA6IHBhcnNlVG9aZXJvT3JOdW1iZXIoX2hvc3RFbGVtZW50LmNzcyhwcmVmaXggKyBfc3RyUmlnaHQgKyBzdWZmaXgpKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgYjogemVyb1kgPyAwIDogcGFyc2VUb1plcm9Pck51bWJlcihfaG9zdEVsZW1lbnQuY3NzKHByZWZpeCArIF9zdHJCb3R0b20gKyBzdWZmaXgpKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgbDogemVyb1ggPyAwIDogcGFyc2VUb1plcm9Pck51bWJlcihfaG9zdEVsZW1lbnQuY3NzKHByZWZpeCArIF9zdHJMZWZ0ICsgc3VmZml4KSlcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0aGUgY29tcHV0ZWQgQ1NTIHRyYW5zaXRpb24gc3RyaW5nIGZyb20gdGhlIGdpdmVuIGVsZW1lbnQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZWxlbWVudCBUaGUgZWxlbWVudCBmcm9tIHdoaWNoIHRoZSB0cmFuc2l0aW9uIHN0cmluZyBzaGFsbCBiZSByZXR1cm5lZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBDU1MgdHJhbnNpdGlvbiBzdHJpbmcgZnJvbSB0aGUgZ2l2ZW4gZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0Q1NTVHJhbnNpdGlvblN0cmluZyhlbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRyYW5zaXRpb25TdHIgPSBWRU5ET1JTLl9jc3NQcm9wZXJ0eSgndHJhbnNpdGlvbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhc3NlbWJsZWRWYWx1ZSA9IGVsZW1lbnQuY3NzKHRyYW5zaXRpb25TdHIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhc3NlbWJsZWRWYWx1ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFzc2VtYmxlZFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWdFeHBTdHJpbmcgPSAnXFxcXHMqKCcgKyAnKFteLChdKyhcXFxcKC4rP1xcXFwpKT8pKycgKyAnKVtcXFxccyxdKic7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlZ0V4cE1haW4gPSBuZXcgUmVnRXhwKHJlZ0V4cFN0cmluZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlZ0V4cFZhbGlkYXRlID0gbmV3IFJlZ0V4cCgnXignICsgcmVnRXhwU3RyaW5nICsgJykrJCcpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwcm9wZXJ0aWVzID0gJ3Byb3BlcnR5IGR1cmF0aW9uIHRpbWluZy1mdW5jdGlvbiBkZWxheScuc3BsaXQoJyAnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWVBcnJheTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGo7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNwbGl0Q3NzU3R5bGVCeUNvbW1hID0gZnVuY3Rpb24gKHN0cikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJSZXN1bHQgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzdHIubWF0Y2gocmVnRXhwVmFsaWRhdGUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0cjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN0ci5tYXRjaChyZWdFeHBNYWluKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyUmVzdWx0LnB1c2goUmVnRXhwLiQxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHJlZ0V4cE1haW4sIF9zdHJFbXB0eSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHJSZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IHByb3BlcnRpZXNbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlQXJyYXkgPSBzcGxpdENzc1N0eWxlQnlDb21tYShlbGVtZW50LmNzcyh0cmFuc2l0aW9uU3RyICsgJy0nICsgcHJvcGVydGllc1tpXSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgdmFsdWVBcnJheVtMRVhJQ09OLmxdOyBqKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbal0gPSAocmVzdWx0W2pdID8gcmVzdWx0W2pdICsgX3N0clNwYWNlIDogX3N0ckVtcHR5KSArIHZhbHVlQXJyYXlbal07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQuam9pbignLCAnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdlbmVyYXRlcyBhIFJlZ3VsYXIgRXhwcmVzc2lvbiB3aGljaCBtYXRjaGVzIHdpdGggYSBzdHJpbmcgd2hpY2ggc3RhcnRzIHdpdGggJ29zLWhvc3QnLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHtib29sZWFufSB3aXRoQ3VyckNsYXNzTmFtZU9wdGlvbiBUaGUgUmVndWxhciBFeHByZXNzaW9uIGFsc28gbWF0Y2hlcyBpZiB0aGUgc3RyaW5nIGlzIHRoZSBjdXJyZW50IENsYXNzTmFtZSBvcHRpb24gKG11bHRpcGxlIHZhbHVlcyBzcGxpdHRlZCBieSBzcGFjZSBwb3NzaWJsZSkuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHdpdGhPbGRDbGFzc05hbWVPcHRpb24gVGhlIFJlZ3VsYXIgRXhwcmVzc2lvbiBhbHNvIG1hdGNoZXMgaWYgdGhlIHN0cmluZyBpcyB0aGUgb2xkIENsYXNzTmFtZSBvcHRpb24gKG11bHRpcGxlIHZhbHVlcyBzcGxpdHRlZCBieSBzcGFjZSBwb3NzaWJsZSkuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGNyZWF0ZUhvc3RDbGFzc05hbWVSZWdFeHAod2l0aEN1cnJDbGFzc05hbWVPcHRpb24sIHdpdGhPbGRDbGFzc05hbWVPcHRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3BsaXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFwcGVuZGl4O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhcHBlbmRDbGFzc2VzID0gZnVuY3Rpb24gKGNsYXNzZXMsIGNvbmRpdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRpeCA9ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29uZGl0aW9uICYmIHR5cGVvZiBjbGFzc2VzID09IFRZUEVTLnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwbGl0ID0gY2xhc3Nlcy5zcGxpdChfc3RyU3BhY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHNwbGl0W0xFWElDT04ubF07IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRpeCArPSAnfCcgKyBzcGxpdFtpXSArICckJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNwbGl0W2ldLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCAnXFxcXCQmJykgZm9yIGVzY2FwaW5nIHJlZ2V4IGNoYXJhY3RlcnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXBwZW5kaXg7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWdFeHAoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICcoXicgKyBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnKFstX10uK3wpJCknICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kQ2xhc3NlcyhfY2xhc3NOYW1lQ2FjaGUsIHdpdGhDdXJyQ2xhc3NOYW1lT3B0aW9uKSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZENsYXNzZXMoX29sZENsYXNzTmFtZSwgd2l0aE9sZENsYXNzTmFtZU9wdGlvbiksICdnJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDYWxjdWxhdGVzIHRoZSBob3N0LWVsZW1lbnRzIGludmVydGVkIHNjYWxlLiAoaW52ZXJ0ZWRTY2FsZSA9IDEgLyBzY2FsZSlcclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7eDogbnVtYmVyLCB5OiBudW1iZXJ9fSBUaGUgc2NhbGUgb2YgdGhlIGhvc3QtZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0SG9zdEVsZW1lbnRJbnZlcnRlZFNjYWxlKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWN0ID0gX3BhZGRpbmdFbGVtZW50TmF0aXZlW0xFWElDT04uYkNSXSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IF9zdXBwb3J0VHJhbnNmb3JtID8gMSAvIChNQVRILnJvdW5kKHJlY3Qud2lkdGgpIC8gX3BhZGRpbmdFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddKSB8fCAxIDogMSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgeTogX3N1cHBvcnRUcmFuc2Zvcm0gPyAxIC8gKE1BVEgucm91bmQocmVjdC5oZWlnaHQpIC8gX3BhZGRpbmdFbGVtZW50TmF0aXZlW0xFWElDT04ub0hdKSB8fCAxIDogMVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgSFRNTEVsZW1lbnQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gbyBUaGUgb2JqZWN0IHdoaWNoIHNoYWxsIGJlIGNoZWNrZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSB0aGUgZ2l2ZW4gb2JqZWN0IGlzIGEgSFRNTEVsZW1lbnQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gaXNIVE1MRWxlbWVudChvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ck93bmVyRG9jdW1lbnQgPSAnb3duZXJEb2N1bWVudCc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckhUTUxFbGVtZW50ID0gJ0hUTUxFbGVtZW50JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd25kID0gbyAmJiBvW3N0ck93bmVyRG9jdW1lbnRdID8gKG9bc3RyT3duZXJEb2N1bWVudF0ucGFyZW50V2luZG93IHx8IHdpbmRvdykgOiB3aW5kb3c7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHduZFtzdHJIVE1MRWxlbWVudF0gPT0gVFlQRVMubyA/IG8gaW5zdGFuY2VvZiB3bmRbc3RySFRNTEVsZW1lbnRdIDogLy9ET00yXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvICYmIHR5cGVvZiBvID09IFRZUEVTLm8gJiYgbyAhPT0gbnVsbCAmJiBvLm5vZGVUeXBlID09PSAxICYmIHR5cGVvZiBvLm5vZGVOYW1lID09IFRZUEVTLnNcclxuICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQ29tcGFyZXMgMiBhcnJheXMgYW5kIHJldHVybnMgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlbSBhcyBhIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGExIFRoZSBmaXJzdCBhcnJheSB3aGljaCBzaGFsbCBiZSBjb21wYXJlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBhMiBUaGUgc2Vjb25kIGFycmF5IHdoaWNoIHNoYWxsIGJlIGNvbXBhcmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge0FycmF5fSBUaGUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgdHdvIGFycmF5cy5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0QXJyYXlEaWZmZXJlbmNlcyhhMSwgYTIpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkaWZmID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGs7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGExLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhW2ExW2ldXSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGEyLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhW2EyW2ldXSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBhW2EyW2ldXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYVthMltpXV0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGsgaW4gYSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlmZi5wdXNoKGspO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkaWZmO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyBaZXJvIG9yIHRoZSBudW1iZXIgdG8gd2hpY2ggdGhlIHZhbHVlIGNhbiBiZSBwYXJzZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHdoaWNoIHNoYWxsIGJlIHBhcnNlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB0b0Zsb2F0IEluZGljYXRlcyB3aGV0aGVyIHRoZSBudW1iZXIgc2hhbGwgYmUgcGFyc2VkIHRvIGEgZmxvYXQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHBhcnNlVG9aZXJvT3JOdW1iZXIodmFsdWUsIHRvRmxvYXQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbnVtID0gdG9GbG9hdCA/IHBhcnNlRmxvYXQodmFsdWUpIDogcGFyc2VJbnQodmFsdWUsIDEwKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNOYU4obnVtKSA/IDAgOiBudW07XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHNldmVyYWwgaW5mb3JtYXRpb24gb2YgdGhlIHRleHRhcmVhIGFuZCByZXR1cm5zIHRoZW0gYXMgYSBvYmplY3Qgb3IgdW5kZWZpbmVkIGlmIHRoZSBicm93c2VyIGRvZXNuJ3Qgc3VwcG9ydCBpdC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7Y3Vyc29yUm93OiBOdW1iZXIsIGN1cnNvckNvbCwgcm93czogTnVtYmVyLCBjb2xzOiBudW1iZXIsIHdSb3c6IG51bWJlciwgcG9zOiBudW1iZXIsIG1heCA6IG51bWJlcn19IG9yIHVuZGVmaW5lZCBpZiBub3Qgc3VwcG9ydGVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRUZXh0YXJlYUluZm8oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZWFkIG5lZWRlZCB2YWx1ZXNcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFDdXJzb3JQb3NpdGlvbiA9IF90YXJnZXRFbGVtZW50TmF0aXZlLnNlbGVjdGlvblN0YXJ0O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0YXJlYUN1cnNvclBvc2l0aW9uID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhVmFsdWUgPSBfdGFyZ2V0RWxlbWVudC52YWwoKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFMZW5ndGggPSB0ZXh0YXJlYVZhbHVlW0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhUm93U3BsaXQgPSB0ZXh0YXJlYVZhbHVlLnNwbGl0KCdcXG4nKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFMYXN0Um93ID0gdGV4dGFyZWFSb3dTcGxpdFtMRVhJQ09OLmxdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUN1cnJlbnRDdXJzb3JSb3dTcGxpdCA9IHRleHRhcmVhVmFsdWUuc3Vic3RyKDAsIHRleHRhcmVhQ3Vyc29yUG9zaXRpb24pLnNwbGl0KCdcXG4nKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2lkZXN0Um93ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFMYXN0Q29sID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3Vyc29yUm93ID0gdGV4dGFyZWFDdXJyZW50Q3Vyc29yUm93U3BsaXRbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3Vyc29yQ29sID0gdGV4dGFyZWFDdXJyZW50Q3Vyc29yUm93U3BsaXRbdGV4dGFyZWFDdXJyZW50Q3Vyc29yUm93U3BsaXRbTEVYSUNPTi5sXSAtIDFdW0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJvd0NvbHM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZ2V0IHdpZGVzdCBSb3cgYW5kIHRoZSBsYXN0IGNvbHVtbiBvZiB0aGUgdGV4dGFyZWFcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGV4dGFyZWFSb3dTcGxpdFtMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcm93Q29scyA9IHRleHRhcmVhUm93U3BsaXRbaV1bTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJvd0NvbHMgPiB0ZXh0YXJlYUxhc3RDb2wpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZGVzdFJvdyA9IGkgKyAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWFMYXN0Q29sID0gcm93Q29scztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2N1cnNvclJvdzogY3Vyc29yUm93LCAvL2N1cnNvclJvd1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY3Vyc29yQ29sdW1uOiBjdXJzb3JDb2wsIC8vY3Vyc29yQ29sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9yb3dzOiB0ZXh0YXJlYUxhc3RSb3csIC8vcm93c1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY29sdW1uczogdGV4dGFyZWFMYXN0Q29sLCAvL2NvbHNcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3dpZGVzdFJvdzogd2lkZXN0Um93LCAvL3dSb3dcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2N1cnNvclBvc2l0aW9uOiB0ZXh0YXJlYUN1cnNvclBvc2l0aW9uLCAvL3Bvc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY3Vyc29yTWF4OiB0ZXh0YXJlYUxlbmd0aCAvL21heFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgbmF0aXZlIG92ZXJsYXkgc2Nyb2xsYmFycyBhcmUgYWN0aXZlLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgbmF0aXZlIG92ZXJsYXkgc2Nyb2xsYmFycyBhcmUgYWN0aXZlLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG5hdGl2ZU92ZXJsYXlTY3JvbGxiYXJzQXJlQWN0aXZlKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoX2lnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDYWNoZSAmJiAoX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueCAmJiBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55KSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHRoZSBlbGVtZW50IHdoaWNoIGlzIHVzZWQgdG8gbWVhc3VyZSB0aGUgY29udGVudCBzaXplLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMgeyp9IFRleHRhcmVhQ292ZXIgaWYgdGFyZ2V0IGVsZW1lbnQgaXMgdGV4dGFyZWEgZWxzZSB0aGUgQ29udGVudEVsZW1lbnQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldENvbnRlbnRNZWFzdXJlRWxlbWVudCgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2lzVGV4dGFyZWEgPyBfdGV4dGFyZWFDb3ZlckVsZW1lbnRbMF0gOiBfY29udGVudEVsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZW5lcmF0ZXMgYSBzdHJpbmcgd2hpY2ggcmVwcmVzZW50cyBhIEhUTUwgZGl2IHdpdGggdGhlIGdpdmVuIGNsYXNzZXMgb3IgYXR0cmlidXRlcy5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBjbGFzc2VzT3JBdHRycyBUaGUgY2xhc3Mgb2YgdGhlIGRpdiBhcyBzdHJpbmcgb3IgYSBvYmplY3Qgd2hpY2ggcmVwcmVzZW50cyB0aGUgYXR0cmlidXRlcyBvZiB0aGUgZGl2LiAoVGhlIGNsYXNzIGF0dHJpYnV0ZSBjYW4gYWxzbyBiZSB3cml0dGVuIGFzIFwiY2xhc3NOYW1lXCIuKVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGNvbnRlbnQgVGhlIGNvbnRlbnQgb2YgdGhlIGRpdiBhcyBzdHJpbmcuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY29uY2F0ZWQgc3RyaW5nIHdoaWNoIHJlcHJlc2VudHMgYSBIVE1MIGRpdiBhbmQgaXRzIGNvbnRlbnQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdlbmVyYXRlRGl2KGNsYXNzZXNPckF0dHJzLCBjb250ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICc8ZGl2ICcgKyAoY2xhc3Nlc09yQXR0cnMgPyB0eXBlKGNsYXNzZXNPckF0dHJzKSA9PSBUWVBFUy5zID9cclxuICAgICAgICAgICAgICAgICAgICAgICAgJ2NsYXNzPVwiJyArIGNsYXNzZXNPckF0dHJzICsgJ1wiJyA6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIga2V5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJzID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEZSQU1FV09SSy5pc1BsYWluT2JqZWN0KGNsYXNzZXNPckF0dHJzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoa2V5IGluIGNsYXNzZXNPckF0dHJzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRycyArPSAoa2V5ID09PSAnYycgPyAnY2xhc3MnIDoga2V5KSArICc9XCInICsgY2xhc3Nlc09yQXR0cnNba2V5XSArICdcIiAnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSgpIDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ckVtcHR5KSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICc+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjb250ZW50IHx8IF9zdHJFbXB0eSkgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JztcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNlbGVjdHMgb3IgZ2VuZXJhdGVzIGEgZGl2IHdpdGggdGhlIGdpdmVuIGNsYXNzIGF0dHJpYnV0ZS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBjbGFzc05hbWUgVGhlIGNsYXNzIG5hbWVzIChkaXZpZGVkIGJ5IHNwYWNlcykgb2YgdGhlIGRpdiB3aGljaCBzaGFsbCBiZSBzZWxlY3RlZCBvciBnZW5lcmF0ZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gc2VsZWN0UGFyZW50T3JPbmx5Q2hpbGRyZW4gVGhlIHBhcmVudCBlbGVtZW50IGZyb20gd2hpY2ggb2YgdGhlIGVsZW1lbnQgc2hhbGwgYmUgc2VsZWN0ZWQuIChpZiB1bmRlZmluZWQgb3IgYm9vbGVhbiBpdHMgaG9zdEVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgKiBJZiBpdHMgYSBib29sZWFuIGl0IGRlY2lkZXMgd2hldGhlciBvbmx5IHRoZSBjaGlsZHJlbiBvZiB0aGUgaG9zdCBlbGVtZW50IHNoYWxsIGJlIHNlbGVjdGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMgeyp9IFRoZSBnZW5lcmF0ZWQgb3Igc2VsZWN0ZWQgZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2VsZWN0T3JHZW5lcmF0ZURpdkJ5Q2xhc3MoY2xhc3NOYW1lLCBzZWxlY3RQYXJlbnRPck9ubHlDaGlsZHJlbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvbmx5Q2hpbGRyZW4gPSB0eXBlKHNlbGVjdFBhcmVudE9yT25seUNoaWxkcmVuKSA9PSBUWVBFUy5iO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzZWxlY3RQYXJlbnQgPSBvbmx5Q2hpbGRyZW4gPyBfaG9zdEVsZW1lbnQgOiAoc2VsZWN0UGFyZW50T3JPbmx5Q2hpbGRyZW4gfHwgX2hvc3RFbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChfZG9tRXhpc3RzICYmICFzZWxlY3RQYXJlbnRbTEVYSUNPTi5sXSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgPyBudWxsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogX2RvbUV4aXN0c1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBzZWxlY3RQYXJlbnRbb25seUNoaWxkcmVuID8gJ2NoaWxkcmVuJyA6ICdmaW5kJ10oX3N0ckRvdCArIGNsYXNzTmFtZS5yZXBsYWNlKC9cXHMvZywgX3N0ckRvdCkpLmVxKDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IEZSQU1FV09SSyhnZW5lcmF0ZURpdihjbGFzc05hbWUpKVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgdmFsdWUgb2YgdGhlIGdpdmVuIHByb3BlcnR5IGZyb20gdGhlIGdpdmVuIG9iamVjdC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBvYmogVGhlIG9iamVjdCBmcm9tIHdoaWNoIHRoZSBwcm9wZXJ0eSB2YWx1ZSBzaGFsbCBiZSBnb3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gcGF0aCBUaGUgcHJvcGVydHkgb2Ygd2hpY2ggdGhlIHZhbHVlIHNoYWxsIGJlIGdvdC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgc2VhcmNoZWQgcHJvcGVydHkgb3IgdW5kZWZpbmVkIG9mIHRoZSBwcm9wZXJ0eSB3YXNuJ3QgZm91bmQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldE9iamVjdFByb3BWYWwob2JqLCBwYXRoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNwbGl0cyA9IHBhdGguc3BsaXQoX3N0ckRvdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBzcGxpdHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFvYmpbTEVYSUNPTi5oT1BdKHNwbGl0c1tpXSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA9IG9ialtzcGxpdHNbaV1dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA8IHNwbGl0cy5sZW5ndGggJiYgdHlwZSh2YWwpID09IFRZUEVTLm8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmogPSB2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gcHJvcGVydHkgZnJvbSB0aGUgZ2l2ZW4gb2JqZWN0LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG9iaiBUaGUgb2JqZWN0IGZyb20gd2hpY2ggdGhlIHByb3BlcnR5IHZhbHVlIHNoYWxsIGJlIHNldC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBwYXRoIFRoZSBwcm9wZXJ0eSBvZiB3aGljaCB0aGUgdmFsdWUgc2hhbGwgYmUgc2V0LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHZhbCBUaGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5IHdoaWNoIHNoYWxsIGJlIHNldC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0T2JqZWN0UHJvcFZhbChvYmosIHBhdGgsIHZhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzcGxpdHMgPSBwYXRoLnNwbGl0KF9zdHJEb3QpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzcGxpdHNMZW5ndGggPSBzcGxpdHMubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXh0ZW5kT2JqID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGV4dGVuZE9ialJvb3QgPSBleHRlbmRPYmo7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBzcGxpdHNMZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kT2JqID0gZXh0ZW5kT2JqW3NwbGl0c1tpXV0gPSBpICsgMSA8IHNwbGl0c0xlbmd0aCA/IHt9IDogdmFsO1xyXG4gICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSy5leHRlbmQob2JqLCBleHRlbmRPYmpSb290LCB0cnVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcdFxyXG4gICAgICAgICAgICAgICAgICogUnVucyBhIGFjdGlvbiBmb3IgZWFjaCBzZWxlY3RvciBpbnNpZGUgdGhlIHVwZGF0ZU9uTG9hZCBvcHRpb24uXHRcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGFjdGlvbiBUaGUgYWN0aW9uIGZvciBlYWNoIHVwZGF0ZU9uTG9hZCBzZWxlY3RvciwgdGhlIGFyZ3VtZW50cyB0aGUgZnVuY3Rpb24gdGFrZXMgaXMgdGhlIGluZGV4IGFuZCB0aGUgdmFsdWUgKHRoZSBzZWxlY3RvcikuXHRcclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZWFjaFVwZGF0ZU9uTG9hZChhY3Rpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdXBkYXRlT25Mb2FkID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMudXBkYXRlT25Mb2FkO1xyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZU9uTG9hZCA9IHR5cGUodXBkYXRlT25Mb2FkKSA9PSBUWVBFUy5zID8gdXBkYXRlT25Mb2FkLnNwbGl0KF9zdHJTcGFjZSkgOiB1cGRhdGVPbkxvYWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChDT01QQVRJQklMSVRZLmlzQSh1cGRhdGVPbkxvYWQpICYmICFfZGVzdHJveWVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVhY2godXBkYXRlT25Mb2FkLCBhY3Rpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IFV0aWxzIENhY2hlID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQ29tcGFyZXMgdHdvIHZhbHVlcyBvciBvYmplY3RzIGFuZCByZXR1cm5zIHRydWUgaWYgdGhleSBhcmVuJ3QgZXF1YWwuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gY3VycmVudCBUaGUgZmlyc3QgdmFsdWUgb3Igb2JqZWN0IHdoaWNoIHNoYWxsIGJlIGNvbXBhcmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGNhY2hlIFRoZSBzZWNvbmQgdmFsdWUgb3Igb2JqZWN0IHdoaWNoIHNoYWxsIGJlIGNvbXBhcmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGZvcmNlIElmIHRydWUgdGhlIHJldHVybmVkIHZhbHVlIGlzIGFsd2F5cyB0cnVlLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgYm90aCB2YWx1ZXMgb3Igb2JqZWN0cyBhcmVuJ3QgZXF1YWwgb3IgZm9yY2UgaXMgdHJ1ZSwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBjaGVja0NhY2hlKGN1cnJlbnQsIGNhY2hlLCBmb3JjZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmb3JjZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZvcmNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKGN1cnJlbnQpID09IFRZUEVTLm8gJiYgdHlwZShjYWNoZSkgPT0gVFlQRVMubykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBwcm9wIGluIGN1cnJlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9wICE9PSAnYycpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudFtMRVhJQ09OLmhPUF0ocHJvcCkgJiYgY2FjaGVbTEVYSUNPTi5oT1BdKHByb3ApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGVja0NhY2hlKGN1cnJlbnRbcHJvcF0sIGNhY2hlW3Byb3BdKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudCAhPT0gY2FjaGU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IFNob3J0Y3V0cyA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIGpRdWVyeSBleHRlbmQgbWV0aG9kIHNob3J0Y3V0IHdpdGggYSBhcHBlbmRlZCBcInRydWVcIiBhcyBmaXJzdCBhcmd1bWVudC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZXh0ZW5kRGVlcCgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRlJBTUVXT1JLLmV4dGVuZC5hcHBseSh0aGlzLCBbdHJ1ZV0uY29uY2F0KFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogalF1ZXJ5IGFkZENsYXNzIG1ldGhvZCBzaG9ydGN1dC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gYWRkQ2xhc3MoZWwsIGNsYXNzZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2ZyYW1ld29ya1Byb3RvLmFkZENsYXNzLmNhbGwoZWwsIGNsYXNzZXMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogalF1ZXJ5IHJlbW92ZUNsYXNzIG1ldGhvZCBzaG9ydGN1dC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVtb3ZlQ2xhc3MoZWwsIGNsYXNzZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2ZyYW1ld29ya1Byb3RvLnJlbW92ZUNsYXNzLmNhbGwoZWwsIGNsYXNzZXMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQWRkcyBvciByZW1vdmVzIHRoZSBnaXZlbiBjbGFzc2VzIGRlcGVuZGVudCBvbiB0aGUgYm9vbGVhbiB2YWx1ZS4gVHJ1ZSBmb3IgYWRkLCBmYWxzZSBmb3IgcmVtb3ZlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBhZGRSZW1vdmVDbGFzcyhlbCwgY2xhc3NlcywgZG9BZGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9BZGQgPyBhZGRDbGFzcyhlbCwgY2xhc3NlcykgOiByZW1vdmVDbGFzcyhlbCwgY2xhc3Nlcyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBqUXVlcnkgcmVtb3ZlIG1ldGhvZCBzaG9ydGN1dC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVtb3ZlKGVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9mcmFtZXdvcmtQcm90by5yZW1vdmUuY2FsbChlbCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBGaW5kcyB0aGUgZmlyc3QgY2hpbGQgZWxlbWVudCB3aXRoIHRoZSBnaXZlbiBzZWxlY3RvciBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBlbCBUaGUgcm9vdCBlbGVtZW50IGZyb20gd2hpY2ggdGhlIHNlbGVjdG9yIHNoYWxsIGJlIHZhbGlkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHNlbGVjdG9yIFRoZSBzZWxlY3RvciBvZiB0aGUgc2VhcmNoZWQgZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfSBUaGUgZmlyc3QgZWxlbWVudCB3aGljaCBpcyBhIGNoaWxkIG9mIHRoZSBnaXZlbiBlbGVtZW50IGFuZCBtYXRjaGVzIHRoZSBnaXZlbnMgc2VsZWN0b3IuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGZpbmRGaXJzdChlbCwgc2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2ZyYW1ld29ya1Byb3RvLmZpbmQuY2FsbChlbCwgc2VsZWN0b3IpLmVxKDApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gQVBJID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUHV0cyB0aGUgaW5zdGFuY2UgdG8gc2xlZXAuIEl0IHdvbnQgcmVzcG9uZCB0byBhbnkgY2hhbmdlcyBpbiB0aGUgRE9NIGFuZCB3b24ndCB1cGRhdGUuIFNjcm9sbGJhciBJbnRlcmFjdGl2aXR5IGlzIGFsc28gZGlzYWJsZWQgYXMgd2VsbCBhcyB0aGUgcmVzaXplIGhhbmRsZS5cclxuICAgICAgICAgICAgICAgICAqIFRoaXMgYmVoYXZpb3IgY2FuIGJlIHJlc2V0IGJ5IGNhbGxpbmcgdGhlIHVwZGF0ZSBtZXRob2QuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLnNsZWVwID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIF9zbGVlcGluZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVXBkYXRlcyB0aGUgcGx1Z2luIGFuZCBET00gdG8gdGhlIGN1cnJlbnQgb3B0aW9ucy5cclxuICAgICAgICAgICAgICAgICAqIFRoaXMgbWV0aG9kIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBpZiBhIHVwZGF0ZSBpcyAxMDAlIHJlcXVpcmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGZvcmNlIFRydWUgaWYgZXZlcnkgcHJvcGVydHkgc2hhbGwgYmUgdXBkYXRlZCBhbmQgdGhlIGNhY2hlIHNoYWxsIGJlIGlnbm9yZWQuXHJcbiAgICAgICAgICAgICAgICAgKiAhSU5URVJOQUwgVVNBR0UhIDogZm9yY2UgY2FuIGJlIGEgc3RyaW5nIFwiYXV0b1wiLCBcInN5bmNcIiBvciBcInpvb21cIiB0b29cclxuICAgICAgICAgICAgICAgICAqIGlmIFwiYXV0b1wiIHRoZW4gYmVmb3JlIGEgcmVhbCB1cGRhdGUgdGhlIGNvbnRlbnQgc2l6ZSBhbmQgaG9zdCBlbGVtZW50IGF0dHJpYnV0ZXMgZ2V0cyBjaGVja2VkLCBhbmQgaWYgdGhleSBjaGFuZ2VkIG9ubHkgdGhlbiB0aGUgdXBkYXRlIG1ldGhvZCB3aWxsIGJlIGNhbGxlZC5cclxuICAgICAgICAgICAgICAgICAqIGlmIFwic3luY1wiIHRoZW4gdGhlIGFzeW5jIHVwZGF0ZSBwcm9jZXNzIChNdXRhdGlvbk9ic2VydmVyIG9yIFVwZGF0ZUxvb3ApIGdldHMgc3luY2hyb25pemVkIGFuZCBhIGNvcnJlc3BvbmRpbmcgdXBkYXRlIHRha2VzIHBsYWNlIGlmIG9uZSB3YXMgbmVlZGVkIGR1ZSB0byBwZW5kaW5nIGNoYW5nZXMuXHJcbiAgICAgICAgICAgICAgICAgKiBpZiBcInpvb21cIiB0aGVuIGEgdXBkYXRlIHRha2VzIHBsYWNlIHdoZXJlIGl0J3MgYXNzdW1lZCB0aGF0IGNvbnRlbnQgYW5kIGhvc3Qgc2l6ZSBjaGFuZ2VkXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbnx1bmRlZmluZWR9IFxyXG4gICAgICAgICAgICAgICAgICogSWYgZm9yY2UgaXMgXCJzeW5jXCIgdGhlbiBhIGJvb2xlYW4gaXMgcmV0dXJuZWQgd2hpY2ggaW5kaWNhdGVzIHdoZXRoZXIgYSB1cGRhdGUgd2FzIG5lZWRlZCBkdWUgdG8gcGVuZGluZyBjaGFuZ2VzLlxyXG4gICAgICAgICAgICAgICAgICogSWYgZm9yY2UgaXMgXCJhdXRvXCIgdGhlbiBhIGJvb2xlYW4gaXMgcmV0dXJuZWQgd2hldGhlciBhIHVwZGF0ZSB3YXMgbmVlZGVkIGR1ZSB0byBhdHRyaWJ1dGUgb3Igc2l6ZSBjaGFuZ2VzLlxyXG4gICAgICAgICAgICAgICAgICogdW5kZWZpbmVkIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlID0gZnVuY3Rpb24gKGZvcmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9kZXN0cm95ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJzQ2hhbmdlZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudFNpemVDO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpc1N0cmluZyA9IHR5cGUoZm9yY2UpID09IFRZUEVTLnM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRvVXBkYXRlQXV0bztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbXV0SG9zdDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbXV0Q29udGVudDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3RyaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3JjZSA9PT0gX3N0ckF1dG8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzQ2hhbmdlZCA9IG1lYW5pbmdmdWxBdHRyc0NoYW5nZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRTaXplQyA9IHVwZGF0ZUF1dG9Db250ZW50U2l6ZUNoYW5nZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvVXBkYXRlQXV0byA9IGF0dHJzQ2hhbmdlZCB8fCBjb250ZW50U2l6ZUM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9VcGRhdGVBdXRvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRTaXplQ2hhbmdlZDogY29udGVudFNpemVDLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY2hhbmdlZE9wdGlvbnM6IF9pbml0aWFsaXplZCA/IHVuZGVmaW5lZCA6IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZm9yY2UgPT09IF9zdHJTeW5jKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0SG9zdCA9IF9tdXRhdGlvbk9ic2VydmVySG9zdENhbGxiYWNrKF9tdXRhdGlvbk9ic2VydmVySG9zdC50YWtlUmVjb3JkcygpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRDb250ZW50ID0gX211dGF0aW9uT2JzZXJ2ZXJDb250ZW50Q2FsbGJhY2soX211dGF0aW9uT2JzZXJ2ZXJDb250ZW50LnRha2VSZWNvcmRzKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0SG9zdCA9IF9iYXNlLnVwZGF0ZShfc3RyQXV0byk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZm9yY2UgPT09ICd6b29tJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdFNpemVDaGFuZ2VkOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50U2l6ZUNoYW5nZWQ6IHRydWVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JjZSA9IF9zbGVlcGluZyB8fCBmb3JjZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3NsZWVwaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2Jhc2UudXBkYXRlKF9zdHJTeW5jKSB8fCBmb3JjZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZSh7IF9mb3JjZTogZm9yY2UgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICB1cGRhdGVFbGVtZW50c09uTG9hZCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9VcGRhdGVBdXRvIHx8IG11dEhvc3QgfHwgbXV0Q29udGVudDtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgR2V0cyBvciBzZXRzIHRoZSBjdXJyZW50IG9wdGlvbnMuIFRoZSB1cGRhdGUgbWV0aG9kIHdpbGwgYmUgY2FsbGVkIGF1dG9tYXRpY2FsbHkgaWYgbmV3IG9wdGlvbnMgd2VyZSBzZXQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gbmV3T3B0aW9ucyBJZiBuZXcgb3B0aW9ucyBhcmUgZ2l2ZW4sIHRoZW4gdGhlIG5ldyBvcHRpb25zIHdpbGwgYmUgc2V0LCBpZiBuZXcgb3B0aW9ucyBhcmVuJ3QgZ2l2ZW4gKHVuZGVmaW5lZCBvciBhIG5vdCBhIHBsYWluIG9iamVjdCkgdGhlbiB0aGUgY3VycmVudCBvcHRpb25zIHdpbGwgYmUgcmV0dXJuZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdmFsdWUgSWYgbmV3IG9wdGlvbnMgaXMgYSBwcm9wZXJ0eSBwYXRoIHN0cmluZywgdGhlbiB0aGlzIHZhbHVlIHdpbGwgYmUgdXNlZCB0byBzZXQgdGhlIG9wdGlvbiB0byB3aGljaCB0aGUgcHJvcGVydHkgcGF0aCBzdHJpbmcgbGVhZHMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn1cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgX2Jhc2Uub3B0aW9ucyA9IGZ1bmN0aW9uIChuZXdPcHRpb25zLCB2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvcHRpb24gPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hhbmdlZE9wcztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZXR1cm4gY3VycmVudCBvcHRpb25zIGlmIG5ld09wdGlvbnMgYXJlIHVuZGVmaW5lZCBvciBlbXB0eVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChGUkFNRVdPUksuaXNFbXB0eU9iamVjdChuZXdPcHRpb25zKSB8fCAhRlJBTUVXT1JLLmlzUGxhaW5PYmplY3QobmV3T3B0aW9ucykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUobmV3T3B0aW9ucykgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0T2JqZWN0UHJvcFZhbChvcHRpb24sIG5ld09wdGlvbnMsIHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VkT3BzID0gc2V0T3B0aW9ucyhvcHRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRPYmplY3RQcm9wVmFsKF9jdXJyZW50T3B0aW9ucywgbmV3T3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9jdXJyZW50T3B0aW9ucztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZWRPcHMgPSBzZXRPcHRpb25zKG5ld09wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFGUkFNRVdPUksuaXNFbXB0eU9iamVjdChjaGFuZ2VkT3BzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoeyBfY2hhbmdlZE9wdGlvbnM6IGNoYW5nZWRPcHMgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJlc3RvcmUgdGhlIERPTSwgZGlzY29ubmVjdHMgYWxsIG9ic2VydmVycywgcmVtb3ZlIGFsbCByZXNpemUgb2JzZXJ2ZXJzIGFuZCBwdXQgdGhlIGluc3RhbmNlIHRvIHNsZWVwLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfZGVzdHJveWVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIHRoaXMgaW5zdGFuY2UgZnJvbSBhdXRvIHVwZGF0ZSBsb29wXHJcbiAgICAgICAgICAgICAgICAgICAgYXV0b1VwZGF0ZUxvb3AucmVtb3ZlKF9iYXNlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9kaXNjb25uZWN0IGFsbCBtdXRhdGlvbiBvYnNlcnZlcnNcclxuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TXV0YXRpb25PYnNlcnZlcnMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgYWxsIHJlc2l6ZSBvYnNlcnZlcnNcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc2l6ZU9ic2VydmVyKF9zaXplT2JzZXJ2ZXJFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc2l6ZU9ic2VydmVyKF9zaXplQXV0b09ic2VydmVyRWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIGFsbCBleHRlbnNpb25zXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgZXh0TmFtZSBpbiBfZXh0ZW5zaW9ucylcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2UucmVtb3ZlRXh0KGV4dE5hbWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgJ2Rlc3Ryb3knIGV2ZW50c1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChfZGVzdHJveUV2ZW50c1tMRVhJQ09OLmxdID4gMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Rlc3Ryb3lFdmVudHMucG9wKCkoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgYWxsIGV2ZW50cyBmcm9tIGhvc3QgZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwSG9zdE1vdXNlVG91Y2hFdmVudHModHJ1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIGFsbCBoZWxwZXIgLyBkZXRlY3Rpb24gZWxlbWVudHNcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2NvbnRlbnRHbHVlRWxlbWVudClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKF9jb250ZW50R2x1ZUVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfY29udGVudEFycmFuZ2VFbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUoX2NvbnRlbnRBcnJhbmdlRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9zaXplQXV0b09ic2VydmVyQWRkZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZShfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgZ2VuZXJhdGVkIERPTVxyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU2Nyb2xsYmFyc0RPTSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhckNvcm5lckRPTSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFN0cnVjdHVyZURPTSh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgYWxsIGdlbmVyYXRlZCBpbWFnZSBsb2FkIGV2ZW50c1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgX3VwZGF0ZU9uTG9hZEVsbXNbTEVYSUNPTi5sXTsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBGUkFNRVdPUksoX3VwZGF0ZU9uTG9hZEVsbXNbaV0pLm9mZihfdXBkYXRlT25Mb2FkRXZlbnROYW1lLCB1cGRhdGVPbkxvYWRDYWxsYmFjayk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3VwZGF0ZU9uTG9hZEVsbXMgPSB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF9kZXN0cm95ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zbGVlcGluZyA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIHRoaXMgaW5zdGFuY2UgZnJvbSB0aGUgaW5zdGFuY2VzIGxpc3RcclxuICAgICAgICAgICAgICAgICAgICBJTlNUQU5DRVMocGx1Z2luVGFyZ2V0RWxlbWVudCwgMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25EZXN0cm95ZWQnKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgYWxsIHByb3BlcnRpZXMgYW5kIG1ldGhvZHNcclxuICAgICAgICAgICAgICAgICAgICAvL2ZvciAodmFyIHByb3BlcnR5IGluIF9iYXNlKVxyXG4gICAgICAgICAgICAgICAgICAgIC8vICAgIGRlbGV0ZSBfYmFzZVtwcm9wZXJ0eV07XHJcbiAgICAgICAgICAgICAgICAgICAgLy9fYmFzZSA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBTY3JvbGxzIHRvIGEgZ2l2ZW4gcG9zaXRpb24gb3IgZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBjb29yZGluYXRlc1xyXG4gICAgICAgICAgICAgICAgICogMS4gQ2FuIGJlIFwiY29vcmRpbmF0ZXNcIiB3aGljaCBsb29rcyBsaWtlOlxyXG4gICAgICAgICAgICAgICAgICogICAgeyB4IDogPywgeSA6ID8gfSBPUiAgICAgICAgICBPYmplY3Qgd2l0aCB4IGFuZCB5IHByb3BlcnRpZXNcclxuICAgICAgICAgICAgICAgICAqICAgIHsgbGVmdCA6ID8sIHRvcCA6ID8gfSBPUiAgICAgT2JqZWN0IHdpdGggbGVmdCBhbmQgdG9wIHByb3BlcnRpZXNcclxuICAgICAgICAgICAgICAgICAqICAgIHsgbCA6ID8sIHQgOiA/IH0gT1IgICAgICAgICAgT2JqZWN0IHdpdGggbCBhbmQgdCBwcm9wZXJ0aWVzXHJcbiAgICAgICAgICAgICAgICAgKiAgICBbID8sID8gXSBPUiAgICAgICAgICAgICAgICAgIEFycmF5IHdoZXJlIHRoZSBmaXJzdCB0d28gZWxlbWVudCBhcmUgdGhlIGNvb3JkaW5hdGVzIChmaXJzdCBpcyB4LCBzZWNvbmQgaXMgeSlcclxuICAgICAgICAgICAgICAgICAqICAgID8gICAgICAgICAgICAgICAgICAgICAgICAgICAgQSBzaW5nbGUgdmFsdWUgd2hpY2ggc3RheXMgZm9yIGJvdGggYXhpc1xyXG4gICAgICAgICAgICAgICAgICogICAgQSB2YWx1ZSBjYW4gYmUgYSBudW1iZXIsIGEgc3RyaW5nIG9yIGEgY2FsY3VsYXRpb24uXHJcbiAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICogICAgT3BlcmF0b3JzOlxyXG4gICAgICAgICAgICAgICAgICogICAgW05PTkVdICBUaGUgY3VycmVudCBzY3JvbGwgd2lsbCBiZSBvdmVyd3JpdHRlbiBieSB0aGUgdmFsdWUuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnKz0nICAgIFRoZSB2YWx1ZSB3aWxsIGJlIGFkZGVkIHRvIHRoZSBjdXJyZW50IHNjcm9sbCBvZmZzZXRcclxuICAgICAgICAgICAgICAgICAqICAgICctPScgICAgVGhlIHZhbHVlIHdpbGwgYmUgc3VidHJhY3RlZCBmcm9tIHRoZSBjdXJyZW50IHNjcm9sbCBvZmZzZXRcclxuICAgICAgICAgICAgICAgICAqICAgICcqPScgICAgVGhlIGN1cnJlbnQgc2Nyb2xsIHdpbCBiZSBtdWx0aXBsaWNhdGVkIGJ5IHRoZSB2YWx1ZS5cclxuICAgICAgICAgICAgICAgICAqICAgICcvPScgICAgVGhlIGN1cnJlbnQgc2Nyb2xsIHdpbCBiZSBkaXZpZGVkIGJ5IHRoZSB2YWx1ZS5cclxuICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgKiAgICBVbml0czpcclxuICAgICAgICAgICAgICAgICAqICAgIFtOT05FXSAgVGhlIHZhbHVlIGlzIHRoZSBmaW5hbCBzY3JvbGwgYW1vdW50LiAgICAgICAgICAgICAgICAgICBmaW5hbCA9ICh2YWx1ZSAqIDEpXHJcbiAgICAgICAgICAgICAgICAgKiAgICAncHgnICAgIFNhbWUgYXMgbm9uZVxyXG4gICAgICAgICAgICAgICAgICogICAgJyUnICAgICBUaGUgdmFsdWUgaXMgZGVwZW5kZW50IG9uIHRoZSBjdXJyZW50IHNjcm9sbCB2YWx1ZS4gICAgIGZpbmFsID0gKChjdXJyZW50U2Nyb2xsVmFsdWUgLyAxMDApICogdmFsdWUpXHJcbiAgICAgICAgICAgICAgICAgKiAgICAndncnICAgIFRoZSB2YWx1ZSBpcyBtdWx0aXBsaWNhdGVkIGJ5IHRoZSB2aWV3cG9ydCB3aWR0aC4gICAgICAgZmluYWwgPSAodmFsdWUgKiB2aWV3cG9ydFdpZHRoKVxyXG4gICAgICAgICAgICAgICAgICogICAgJ3ZoJyAgICBUaGUgdmFsdWUgaXMgbXVsdGlwbGljYXRlZCBieSB0aGUgdmlld3BvcnQgaGVpZ2h0LiAgICAgIGZpbmFsID0gKHZhbHVlICogdmlld3BvcnRIZWlnaHQpXHJcbiAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICogICAgZXhhbXBsZSBmaW5hbCB2YWx1ZXM6XHJcbiAgICAgICAgICAgICAgICAgKiAgICAyMDAsICcyMDBweCcsICc1MCUnLCAnMXZ3JywgJzF2aCcsICcrPTIwMCcsICcvPTF2dycsICcqPTJweCcsICctPTV2aCcsICcrPTMzJScsICcrPSA1MCUgLSAycHgnLCAnLT0gMXZ3IC0gNTAlJ1xyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqIDIuIENhbiBiZSBhIEhUTUwgb3IgalF1ZXJ5IGVsZW1lbnQ6XHJcbiAgICAgICAgICAgICAgICAgKiAgICBUaGUgZmluYWwgc2Nyb2xsIG9mZnNldCBpcyB0aGUgb2Zmc2V0ICh3aXRob3V0IG1hcmdpbikgb2YgdGhlIGdpdmVuIEhUTUwgLyBqUXVlcnkgZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgKiAzLiBDYW4gYmUgYSBvYmplY3Qgd2l0aCBhIEhUTUwgb3IgalF1ZXJ5IGVsZW1lbnQgd2l0aCBhZGRpdGlvbmFsIHNldHRpbmdzOlxyXG4gICAgICAgICAgICAgICAgICogICAge1xyXG4gICAgICAgICAgICAgICAgICogICAgICBlbCA6IFtIVE1MRWxlbWVudCwgalF1ZXJ5IGVsZW1lbnRdLCAgICAgICAgICAgICBNVVNUIGJlIHNwZWNpZmllZCwgZWxzZSB0aGlzIG9iamVjdCBpc24ndCB2YWxpZC5cclxuICAgICAgICAgICAgICAgICAqICAgICAgc2Nyb2xsIDogW3N0cmluZywgYXJyYXksIG9iamVjdF0sICAgICAgICAgICAgICAgRGVmYXVsdCB2YWx1ZSBpcyAnYWx3YXlzJy5cclxuICAgICAgICAgICAgICAgICAqICAgICAgYmxvY2sgOiBbc3RyaW5nLCBhcnJheSwgb2JqZWN0XSwgICAgICAgICAgICAgICAgRGVmYXVsdCB2YWx1ZSBpcyAnYmVnaW4nLlxyXG4gICAgICAgICAgICAgICAgICogICAgICBtYXJnaW4gOiBbbnVtYmVyLCBib29sZWFuLCBhcnJheSwgb2JqZWN0XSAgICAgICBEZWZhdWx0IHZhbHVlIGlzIGZhbHNlLlxyXG4gICAgICAgICAgICAgICAgICogICAgfVxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqICAgIFBvc3NpYmxlIHNjcm9sbCBzZXR0aW5ncyBhcmU6XHJcbiAgICAgICAgICAgICAgICAgKiAgICAnYWx3YXlzJyAgICAgIFNjcm9sbHMgYWx3YXlzLlxyXG4gICAgICAgICAgICAgICAgICogICAgJ2lmbmVlZGVkJyAgICBTY3JvbGxzIG9ubHkgaWYgdGhlIGVsZW1lbnQgaXNudCBmdWxseSBpbiB2aWV3LlxyXG4gICAgICAgICAgICAgICAgICogICAgJ25ldmVyJyAgICAgICBTY3JvbGxzIG5ldmVyLlxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqICAgIFBvc3NpYmxlIGJsb2NrIHNldHRpbmdzIGFyZTpcclxuICAgICAgICAgICAgICAgICAqICAgICdiZWdpbicgICBCb3RoIGF4aXMgc2hhbGwgYmUgZG9ja2VkIHRvIHRoZSBcImJlZ2luXCIgZWRnZS4gLSBUaGUgZWxlbWVudCB3aWxsIGJlIGRvY2tlZCB0byB0aGUgdG9wIGFuZCBsZWZ0IGVkZ2Ugb2YgdGhlIHZpZXdwb3J0LlxyXG4gICAgICAgICAgICAgICAgICogICAgJ2VuZCcgICAgIEJvdGggYXhpcyBzaGFsbCBiZSBkb2NrZWQgdG8gdGhlIFwiZW5kXCIgZWRnZS4gLSBUaGUgZWxlbWVudCB3aWxsIGJlIGRvY2tlZCB0byB0aGUgYm90dG9tIGFuZCByaWdodCBlZGdlIG9mIHRoZSB2aWV3cG9ydC4gKElmIGRpcmVjdGlvbiBpcyBSVEwgdG8gdGhlIGJvdHRvbSBhbmQgbGVmdCBlZGdlLilcclxuICAgICAgICAgICAgICAgICAqICAgICdjZW50ZXInICBCb3RoIGF4aXMgc2hhbGwgYmUgZG9ja2VkIHRvIFwiY2VudGVyXCIuIC0gVGhlIGVsZW1lbnQgd2lsbCBiZSBjZW50ZXJlZCBpbiB0aGUgdmlld3BvcnQuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnbmVhcmVzdCcgVGhlIGVsZW1lbnQgd2lsbCBiZSBkb2NrZWQgdG8gdGhlIG5lYXJlc3QgZWRnZShzKS5cclxuICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgKiAgICBQb3NzaWJsZSBtYXJnaW4gc2V0dGluZ3MgYXJlOiAtLSBUaGUgYWN0dWFsIG1hcmdpbiBvZiB0aGUgZWxlbWVudCB3b250IGJlIGFmZmVjdCwgdGhpcyBvcHRpb24gYWZmZWN0cyBvbmx5IHRoZSBmaW5hbCBzY3JvbGwgb2Zmc2V0LlxyXG4gICAgICAgICAgICAgICAgICogICAgW0JPT0xFQU5dICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJZiB0cnVlIHRoZSBjc3MgbWFyZ2luIG9mIHRoZSBlbGVtZW50IHdpbGwgYmUgdXNlZCwgaWYgZmFsc2Ugbm8gbWFyZ2luIHdpbGwgYmUgdXNlZC5cclxuICAgICAgICAgICAgICAgICAqICAgIFtOVU1CRVJdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhlIG1hcmdpbiB3aWxsIGJlIHVzZWQgZm9yIGFsbCBlZGdlcy5cclxuICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZHVyYXRpb24gVGhlIGR1cmF0aW9uIG9mIHRoZSBzY3JvbGwgYW5pbWF0aW9uLCBPUiBhIGpRdWVyeSBhbmltYXRpb24gY29uZmlndXJhdGlvbiBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZWFzaW5nIFRoZSBhbmltYXRpb24gZWFzaW5nLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGNvbXBsZXRlIFRoZSBhbmltYXRpb24gY29tcGxldGUgY2FsbGJhY2suXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e1xyXG4gICAgICAgICAgICAgICAgICogICBwb3NpdGlvbjoge3g6IG51bWJlciwgeTogbnVtYmVyfSxcclxuICAgICAgICAgICAgICAgICAqICAgcmF0aW86IHt4OiBudW1iZXIsIHk6IG51bWJlcn0sXHJcbiAgICAgICAgICAgICAgICAgKiAgIG1heDoge3g6IG51bWJlciwgeTogbnVtYmVyfSxcclxuICAgICAgICAgICAgICAgICAqICAgaGFuZGxlT2Zmc2V0OiB7eDogbnVtYmVyLCB5OiBudW1iZXJ9LFxyXG4gICAgICAgICAgICAgICAgICogICBoYW5kbGVMZW5ndGg6IHt4OiBudW1iZXIsIHk6IG51bWJlcn0sXHJcbiAgICAgICAgICAgICAgICAgKiAgIGhhbmRsZUxlbmd0aFJhdGlvOiB7eDogbnVtYmVyLCB5OiBudW1iZXJ9LCB0XHJcbiAgICAgICAgICAgICAgICAgKiAgIHJhY2tMZW5ndGg6IHt4OiBudW1iZXIsIHk6IG51bWJlcn0sXHJcbiAgICAgICAgICAgICAgICAgKiAgIGlzUlRMOiBib29sZWFuLFxyXG4gICAgICAgICAgICAgICAgICogICBpc1JUTE5vcm1hbGl6ZWQ6IGJvb2xlYW5cclxuICAgICAgICAgICAgICAgICAqICB9fVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5zY3JvbGwgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZXMsIGR1cmF0aW9uLCBlYXNpbmcsIGNvbXBsZXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDAgfHwgY29vcmRpbmF0ZXMgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5mb1ggPSBfc2Nyb2xsSG9yaXpvbnRhbEluZm87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbmZvWSA9IF9zY3JvbGxWZXJ0aWNhbEluZm87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub3JtYWxpemVJbnZlcnQgPSBfbm9ybWFsaXplUlRMQ2FjaGUgJiYgX2lzUlRMICYmIF9ydGxTY3JvbGxCZWhhdmlvci5pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9ybWFsaXplTmVnYXRlID0gX25vcm1hbGl6ZVJUTENhY2hlICYmIF9pc1JUTCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IubjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbFggPSBpbmZvWC5fY3VycmVudFNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbFhSYXRpbyA9IGluZm9YLl9jdXJyZW50U2Nyb2xsUmF0aW87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtYXhTY3JvbGxYID0gaW5mb1guX21heFNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsWFJhdGlvID0gbm9ybWFsaXplSW52ZXJ0ID8gMSAtIHNjcm9sbFhSYXRpbyA6IHNjcm9sbFhSYXRpbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsWCA9IG5vcm1hbGl6ZUludmVydCA/IG1heFNjcm9sbFggLSBzY3JvbGxYIDogc2Nyb2xsWDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsWCAqPSBub3JtYWxpemVOZWdhdGUgPyAtMSA6IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heFNjcm9sbFggKj0gbm9ybWFsaXplTmVnYXRlID8gLTEgOiAxO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogc2Nyb2xsWCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBpbmZvWS5fY3VycmVudFNjcm9sbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhdGlvOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogc2Nyb2xsWFJhdGlvLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGluZm9ZLl9jdXJyZW50U2Nyb2xsUmF0aW9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXg6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBtYXhTY3JvbGxYLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGluZm9ZLl9tYXhTY3JvbGxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVPZmZzZXQ6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBpbmZvWC5faGFuZGxlT2Zmc2V0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGluZm9ZLl9oYW5kbGVPZmZzZXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVMZW5ndGg6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBpbmZvWC5faGFuZGxlTGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGluZm9ZLl9oYW5kbGVMZW5ndGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVMZW5ndGhSYXRpbzoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGluZm9YLl9oYW5kbGVMZW5ndGhSYXRpbyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBpbmZvWS5faGFuZGxlTGVuZ3RoUmF0aW9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFja0xlbmd0aDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGluZm9YLl90cmFja0xlbmd0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBpbmZvWS5fdHJhY2tMZW5ndGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbmFwcGVkSGFuZGxlT2Zmc2V0OiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogaW5mb1guX3NuYXBwZWRIYW5kbGVPZmZzZXQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaW5mb1kuX3NuYXBwZWRIYW5kbGVPZmZzZXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1JUTDogX2lzUlRMLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNSVExOb3JtYWxpemVkOiBfbm9ybWFsaXplUlRMQ2FjaGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF9iYXNlLnVwZGF0ZShfc3RyU3luYyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBub3JtYWxpemVSVEwgPSBfbm9ybWFsaXplUlRMQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvb3JkaW5hdGVzWEF4aXNQcm9wcyA9IFtfc3RyWCwgX3N0ckxlZnQsICdsJ107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvb3JkaW5hdGVzWUF4aXNQcm9wcyA9IFtfc3RyWSwgX3N0clRvcCwgJ3QnXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZXNPcGVyYXRvcnMgPSBbJys9JywgJy09JywgJyo9JywgJy89J107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGR1cmF0aW9uSXNPYmplY3QgPSB0eXBlKGR1cmF0aW9uKSA9PSBUWVBFUy5vO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb21wbGV0ZUNhbGxiYWNrID0gZHVyYXRpb25Jc09iamVjdCA/IGR1cmF0aW9uLmNvbXBsZXRlIDogY29tcGxldGU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZpbmFsU2Nyb2xsID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNwZWNpYWxFYXNpbmcgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZG9TY3JvbGxMZWZ0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkb1Njcm9sbFRvcDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYW5pbWF0aW9uT3B0aW9ucztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyRW5kID0gJ2VuZCc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckJlZ2luID0gJ2JlZ2luJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQ2VudGVyID0gJ2NlbnRlcic7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ck5lYXJlc3QgPSAnbmVhcmVzdCc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckFsd2F5cyA9ICdhbHdheXMnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJOZXZlciA9ICduZXZlcic7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0cklmTmVlZGVkID0gJ2lmbmVlZGVkJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyTGVuZ3RoID0gTEVYSUNPTi5sO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzZXR0aW5nc0F4aXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNldHRpbmdzU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzZXR0aW5nc0Jsb2NrO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzZXR0aW5nc01hcmdpbjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZmluYWxFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50T2JqU2V0dGluZ3NBeGlzVmFsdWVzID0gW19zdHJYLCBfc3RyWSwgJ3h5JywgJ3l4J107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRPYmpTZXR0aW5nc0Jsb2NrVmFsdWVzID0gW3N0ckJlZ2luLCBzdHJFbmQsIHN0ckNlbnRlciwgc3RyTmVhcmVzdF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRPYmpTZXR0aW5nc1Njcm9sbFZhbHVlcyA9IFtzdHJBbHdheXMsIHN0ck5ldmVyLCBzdHJJZk5lZWRlZF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvb3JkaW5hdGVzSXNFbGVtZW50T2JqID0gY29vcmRpbmF0ZXNbTEVYSUNPTi5oT1BdKCdlbCcpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3NzaWJsZUVsZW1lbnQgPSBjb29yZGluYXRlc0lzRWxlbWVudE9iaiA/IGNvb3JkaW5hdGVzLmVsIDogY29vcmRpbmF0ZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvc3NpYmxlRWxlbWVudElzSlF1ZXJ5ID0gcG9zc2libGVFbGVtZW50IGluc3RhbmNlb2YgRlJBTUVXT1JLIHx8IEpRVUVSWSA/IHBvc3NpYmxlRWxlbWVudCBpbnN0YW5jZW9mIEpRVUVSWSA6IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3NzaWJsZUVsZW1lbnRJc0hUTUxFbGVtZW50ID0gcG9zc2libGVFbGVtZW50SXNKUXVlcnkgPyBmYWxzZSA6IGlzSFRNTEVsZW1lbnQocG9zc2libGVFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdXBkYXRlU2Nyb2xsYmFySW5mb3MgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1Njcm9sbExlZnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9TY3JvbGxUb3ApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwcm94eUNvbXBsZXRlQ2FsbGJhY2sgPSB0eXBlKGNvbXBsZXRlQ2FsbGJhY2spICE9IFRZUEVTLmYgPyB1bmRlZmluZWQgOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZVNjcm9sbGJhckluZm9zKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlQ2FsbGJhY2soKTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGNoZWNrU2V0dGluZ3NTdHJpbmdWYWx1ZShjdXJyVmFsdWUsIGFsbG93ZWRWYWx1ZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGFsbG93ZWRWYWx1ZXNbc3RyTGVuZ3RoXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyclZhbHVlID09PSBhbGxvd2VkVmFsdWVzW2ldKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0UmF3U2Nyb2xsKGlzWCwgY29vcmRpbmF0ZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvb3JkaW5hdGVQcm9wcyA9IGlzWCA/IGNvb3JkaW5hdGVzWEF4aXNQcm9wcyA6IGNvb3JkaW5hdGVzWUF4aXNQcm9wcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMgPSB0eXBlKGNvb3JkaW5hdGVzKSA9PSBUWVBFUy5zIHx8IHR5cGUoY29vcmRpbmF0ZXMpID09IFRZUEVTLm4gPyBbY29vcmRpbmF0ZXMsIGNvb3JkaW5hdGVzXSA6IGNvb3JkaW5hdGVzO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkuaXNBKGNvb3JkaW5hdGVzKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpc1ggPyBjb29yZGluYXRlc1swXSA6IGNvb3JkaW5hdGVzWzFdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlKGNvb3JkaW5hdGVzKSA9PSBUWVBFUy5vKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2RlY2lkZXMgUlRMIG5vcm1hbGl6YXRpb24gXCJoYWNrXCIgd2l0aCAublxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9ub3JtYWxpemVSVEwgPSB0eXBlKGNvb3JkaW5hdGVzLm4pID09IFRZUEVTLmIgPyBjb29yZGluYXRlcy5uIDogbm9ybWFsaXplUlRMOyBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb29yZGluYXRlUHJvcHNbc3RyTGVuZ3RoXTsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb29yZGluYXRlUHJvcHNbaV0gaW4gY29vcmRpbmF0ZXMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb29yZGluYXRlc1tjb29yZGluYXRlUHJvcHNbaV1dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldEZpbmFsU2Nyb2xsKGlzWCwgcmF3U2Nyb2xsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpc1N0cmluZyA9IHR5cGUocmF3U2Nyb2xsKSA9PSBUWVBFUy5zO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3BlcmF0b3I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhbW91bnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxJbmZvID0gaXNYID8gX3Njcm9sbEhvcml6b250YWxJbmZvIDogX3Njcm9sbFZlcnRpY2FsSW5mbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJTY3JvbGwgPSBzY3JvbGxJbmZvLl9jdXJyZW50U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWF4U2Nyb2xsID0gc2Nyb2xsSW5mby5fbWF4U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXVsdCA9ICcgKiAnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmluYWxWYWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzUlRMaXNYID0gX2lzUlRMICYmIGlzWDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vcm1hbGl6ZVNob3J0Y3V0cyA9IGlzUlRMaXNYICYmIF9ydGxTY3JvbGxCZWhhdmlvci5uICYmICFub3JtYWxpemVSVEw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJSZXBsYWNlID0gJ3JlcGxhY2UnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXZhbEZ1bmMgPSBldmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcG9zc2libGVPcGVyYXRvcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3RyaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NoZWNrIG9wZXJhdG9yXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmF3U2Nyb2xsW3N0ckxlbmd0aF0gPiAyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zc2libGVPcGVyYXRvciA9IHJhd1Njcm9sbC5zdWJzdHIoMCwgMik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkocG9zc2libGVPcGVyYXRvciwgY29vcmRpbmF0ZXNPcGVyYXRvcnMpID4gLTEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yID0gcG9zc2libGVPcGVyYXRvcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NhbGN1bGF0ZSB1bml0cyBhbmQgc2hvcnRjdXRzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdTY3JvbGwgPSBvcGVyYXRvciA/IHJhd1Njcm9sbC5zdWJzdHIoMikgOiByYXdTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdTY3JvbGwgPSByYXdTY3JvbGxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHJSZXBsYWNlXSgvbWluL2csIDApIC8vJ21pbicgPSAwJVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0clJlcGxhY2VdKC88L2csIDApICAgLy8nPCcgICA9IDAlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oL21heC9nLCAobm9ybWFsaXplU2hvcnRjdXRzID8gJy0nIDogX3N0ckVtcHR5KSArIF9zdHJIdW5kcmVkUGVyY2VudCkgICAgLy8nbWF4JyA9IDEwMCVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHJSZXBsYWNlXSgvPi9nLCAobm9ybWFsaXplU2hvcnRjdXRzID8gJy0nIDogX3N0ckVtcHR5KSArIF9zdHJIdW5kcmVkUGVyY2VudCkgICAgICAvLyc+JyAgID0gMTAwJVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0clJlcGxhY2VdKC9weC9nLCBfc3RyRW1wdHkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oLyUvZywgbXVsdCArIChtYXhTY3JvbGwgKiAoaXNSVExpc1ggJiYgX3J0bFNjcm9sbEJlaGF2aW9yLm4gPyAtMSA6IDEpIC8gMTAwLjApKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0clJlcGxhY2VdKC92dy9nLCBtdWx0ICsgX3ZpZXdwb3J0U2l6ZS53KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0clJlcGxhY2VdKC92aC9nLCBtdWx0ICsgX3ZpZXdwb3J0U2l6ZS5oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFtb3VudCA9IHBhcnNlVG9aZXJvT3JOdW1iZXIoaXNOYU4ocmF3U2Nyb2xsKSA/IHBhcnNlVG9aZXJvT3JOdW1iZXIoZXZhbEZ1bmMocmF3U2Nyb2xsKSwgdHJ1ZSkudG9GaXhlZCgpIDogcmF3U2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFtb3VudCA9IHJhd1Njcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFtb3VudCAhPT0gdW5kZWZpbmVkICYmICFpc05hTihhbW91bnQpICYmIHR5cGUoYW1vdW50KSA9PSBUWVBFUy5uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9ybWFsaXplSXNSVExpc1ggPSBub3JtYWxpemVSVEwgJiYgaXNSVExpc1g7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3BlcmF0b3JDdXJyU2Nyb2xsID0gY3VyclNjcm9sbCAqIChub3JtYWxpemVJc1JUTGlzWCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IubiA/IC0xIDogMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW52ZXJ0ID0gbm9ybWFsaXplSXNSVExpc1ggJiYgX3J0bFNjcm9sbEJlaGF2aW9yLmk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmVnYXRlID0gbm9ybWFsaXplSXNSVExpc1ggJiYgX3J0bFNjcm9sbEJlaGF2aW9yLm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvckN1cnJTY3JvbGwgPSBpbnZlcnQgPyAobWF4U2Nyb2xsIC0gb3BlcmF0b3JDdXJyU2Nyb2xsKSA6IG9wZXJhdG9yQ3VyclNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAob3BlcmF0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICcrPSc6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsVmFsdWUgPSBvcGVyYXRvckN1cnJTY3JvbGwgKyBhbW91bnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJy09JzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxWYWx1ZSA9IG9wZXJhdG9yQ3VyclNjcm9sbCAtIGFtb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnKj0nOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlID0gb3BlcmF0b3JDdXJyU2Nyb2xsICogYW1vdW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICcvPSc6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsVmFsdWUgPSBvcGVyYXRvckN1cnJTY3JvbGwgLyBhbW91bnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsVmFsdWUgPSBhbW91bnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxWYWx1ZSA9IGludmVydCA/IG1heFNjcm9sbCAtIGZpbmFsVmFsdWUgOiBmaW5hbFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxWYWx1ZSAqPSBuZWdhdGUgPyAtMSA6IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlID0gaXNSVExpc1ggJiYgX3J0bFNjcm9sbEJlaGF2aW9yLm4gPyBNQVRILm1pbigwLCBNQVRILm1heChtYXhTY3JvbGwsIGZpbmFsVmFsdWUpKSA6IE1BVEgubWF4KDAsIE1BVEgubWluKG1heFNjcm9sbCwgZmluYWxWYWx1ZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaW5hbFZhbHVlID09PSBjdXJyU2Nyb2xsID8gdW5kZWZpbmVkIDogZmluYWxWYWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0UGVyQXhpc1ZhbHVlKHZhbHVlLCB2YWx1ZUludGVybmFsVHlwZSwgZGVmYXVsdFZhbHVlLCBhbGxvd2VkVmFsdWVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHREZWZhdWx0ID0gW2RlZmF1bHRWYWx1ZSwgZGVmYXVsdFZhbHVlXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlVHlwZSA9IHR5cGUodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWVBcnJMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZUFyckl0ZW07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3ZhbHVlIGNhbiBiZSBbIHN0cmluZywgb3IgYXJyYXkgb2YgdHdvIHN0cmluZ3MgXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWVUeXBlID09IHZhbHVlSW50ZXJuYWxUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IFt2YWx1ZSwgdmFsdWVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlVHlwZSA9PSBUWVBFUy5hKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZUFyckxlbmd0aCA9IHZhbHVlW3N0ckxlbmd0aF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWVBcnJMZW5ndGggPiAyIHx8IHZhbHVlQXJyTGVuZ3RoIDwgMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHJlc3VsdERlZmF1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWVBcnJMZW5ndGggPT09IDEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlWzFdID0gZGVmYXVsdFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZUFyckxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlQXJySXRlbSA9IHZhbHVlW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSh2YWx1ZUFyckl0ZW0pICE9IHZhbHVlSW50ZXJuYWxUeXBlIHx8ICFjaGVja1NldHRpbmdzU3RyaW5nVmFsdWUodmFsdWVBcnJJdGVtLCBhbGxvd2VkVmFsdWVzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSByZXN1bHREZWZhdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWVUeXBlID09IFRZUEVTLm8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IFt2YWx1ZVtfc3RyWF0gfHwgZGVmYXVsdFZhbHVlLCB2YWx1ZVtfc3RyWV0gfHwgZGVmYXVsdFZhbHVlXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSByZXN1bHREZWZhdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyB4OiB2YWx1ZVswXSwgeTogdmFsdWVbMV0gfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2VuZXJhdGVNYXJnaW4obWFyZ2luVG9wUmlnaHRCb3R0b21MZWZ0QXJyYXkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyclZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyclZhbHVlVHlwZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlRGlyZWN0aW9ucyA9IFtfc3RyVG9wLCBfc3RyUmlnaHQsIF9zdHJCb3R0b20sIF9zdHJMZWZ0XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG1hcmdpblRvcFJpZ2h0Qm90dG9tTGVmdEFycmF5W3N0ckxlbmd0aF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT09IHZhbHVlRGlyZWN0aW9uc1tzdHJMZW5ndGhdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyclZhbHVlID0gbWFyZ2luVG9wUmlnaHRCb3R0b21MZWZ0QXJyYXlbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyVmFsdWVUeXBlID0gdHlwZShjdXJyVmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJWYWx1ZVR5cGUgPT0gVFlQRVMuYilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChjdXJyVmFsdWUgPyBwYXJzZVRvWmVyb09yTnVtYmVyKGZpbmFsRWxlbWVudC5jc3MoX3N0ck1hcmdpbk1pbnVzICsgdmFsdWVEaXJlY3Rpb25zW2ldKSkgOiAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChjdXJyVmFsdWVUeXBlID09IFRZUEVTLm4gPyBjdXJyVmFsdWUgOiAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBvc3NpYmxlRWxlbWVudElzSlF1ZXJ5IHx8IHBvc3NpYmxlRWxlbWVudElzSFRNTEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9nZXQgc2V0dGluZ3NcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1hcmdpbiA9IGNvb3JkaW5hdGVzSXNFbGVtZW50T2JqID8gY29vcmRpbmF0ZXMubWFyZ2luIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGF4aXMgPSBjb29yZGluYXRlc0lzRWxlbWVudE9iaiA/IGNvb3JkaW5hdGVzLmF4aXMgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsID0gY29vcmRpbmF0ZXNJc0VsZW1lbnRPYmogPyBjb29yZGluYXRlcy5zY3JvbGwgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYmxvY2sgPSBjb29yZGluYXRlc0lzRWxlbWVudE9iaiA/IGNvb3JkaW5hdGVzLmJsb2NrIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1hcmdpbkRlZmF1bHQgPSBbMCwgMCwgMCwgMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtYXJnaW5UeXBlID0gdHlwZShtYXJnaW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWFyZ2luTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbEVsZW1lbnQgPSBwb3NzaWJsZUVsZW1lbnRJc0pRdWVyeSA/IHBvc3NpYmxlRWxlbWVudCA6IEZSQU1FV09SSyhwb3NzaWJsZUVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsRWxlbWVudFtzdHJMZW5ndGhdID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9tYXJnaW4gY2FuIGJlIFsgYm9vbGVhbiwgbnVtYmVyLCBhcnJheSBvZiAyLCBhcnJheSBvZiA0LCBvYmplY3QgXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hcmdpblR5cGUgPT0gVFlQRVMubiB8fCBtYXJnaW5UeXBlID09IFRZUEVTLmIpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gZ2VuZXJhdGVNYXJnaW4oW21hcmdpbiwgbWFyZ2luLCBtYXJnaW4sIG1hcmdpbl0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobWFyZ2luVHlwZSA9PSBUWVBFUy5hKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luTGVuZ3RoID0gbWFyZ2luW3N0ckxlbmd0aF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hcmdpbkxlbmd0aCA9PT0gMilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gZ2VuZXJhdGVNYXJnaW4oW21hcmdpblswXSwgbWFyZ2luWzFdLCBtYXJnaW5bMF0sIG1hcmdpblsxXV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKG1hcmdpbkxlbmd0aCA+PSA0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBnZW5lcmF0ZU1hcmdpbihtYXJnaW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gbWFyZ2luRGVmYXVsdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKG1hcmdpblR5cGUgPT0gVFlQRVMubylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBnZW5lcmF0ZU1hcmdpbihbbWFyZ2luW19zdHJUb3BdLCBtYXJnaW5bX3N0clJpZ2h0XSwgbWFyZ2luW19zdHJCb3R0b21dLCBtYXJnaW5bX3N0ckxlZnRdXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gbWFyZ2luRGVmYXVsdDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2Jsb2NrID0gdHlwZShibG9jaykgPT09IFRZUEVTLmIgPyBibG9jayA/IFsgc3RyTmVhcmVzdCwgc3RyQmVnaW4gXSA6IFsgc3RyTmVhcmVzdCwgc3RyRW5kIF0gOiBibG9jaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHRpbmdzQXhpcyA9IGNoZWNrU2V0dGluZ3NTdHJpbmdWYWx1ZShheGlzLCBlbGVtZW50T2JqU2V0dGluZ3NBeGlzVmFsdWVzKSA/IGF4aXMgOiAneHknO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3NTY3JvbGwgPSBnZXRQZXJBeGlzVmFsdWUoc2Nyb2xsLCBUWVBFUy5zLCBzdHJBbHdheXMsIGVsZW1lbnRPYmpTZXR0aW5nc1Njcm9sbFZhbHVlcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5nc0Jsb2NrID0gZ2V0UGVyQXhpc1ZhbHVlKGJsb2NrLCBUWVBFUy5zLCBzdHJCZWdpbiwgZWxlbWVudE9ialNldHRpbmdzQmxvY2tWYWx1ZXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3NNYXJnaW4gPSBtYXJnaW47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZpZXdwb3J0U2Nyb2xsID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGw6IF9zY3JvbGxIb3Jpem9udGFsSW5mby5fY3VycmVudFNjcm9sbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0OiBfc2Nyb2xsVmVydGljYWxJbmZvLl9jdXJyZW50U2Nyb2xsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXNlIHBhZGRpbmcgZWxlbWVudCBpbnN0ZWFkIG9mIHZpZXdwb3J0IGVsZW1lbnQgYmVjYXVzZSBwYWRkaW5nIGVsZW1lbnQgaGFzIG5ldmVyIHBhZGRpbmcsIG1hcmdpbiBvciBwb3NpdGlvbiBhcHBsaWVkLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZpZXdwb3J0T2Zmc2V0ID0gX3BhZGRpbmdFbGVtZW50Lm9mZnNldCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZ2V0IGNvb3JkaW5hdGVzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudE9mZnNldCA9IGZpbmFsRWxlbWVudC5vZmZzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkb05vdFNjcm9sbCA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBzZXR0aW5nc1Njcm9sbC54ID09IHN0ck5ldmVyIHx8IHNldHRpbmdzQXhpcyA9PSBfc3RyWSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBzZXR0aW5nc1Njcm9sbC55ID09IHN0ck5ldmVyIHx8IHNldHRpbmdzQXhpcyA9PSBfc3RyWFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRPZmZzZXRbX3N0clRvcF0gLT0gc2V0dGluZ3NNYXJnaW5bMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50T2Zmc2V0W19zdHJMZWZ0XSAtPSBzZXR0aW5nc01hcmdpblszXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50U2Nyb2xsQ29vcmRpbmF0ZXMgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogTUFUSC5yb3VuZChlbGVtZW50T2Zmc2V0W19zdHJMZWZ0XSAtIHZpZXdwb3J0T2Zmc2V0W19zdHJMZWZ0XSArIHZpZXdwb3J0U2Nyb2xsLmwpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IE1BVEgucm91bmQoZWxlbWVudE9mZnNldFtfc3RyVG9wXSAtIHZpZXdwb3J0T2Zmc2V0W19zdHJUb3BdICsgdmlld3BvcnRTY3JvbGwudClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzUlRMKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfcnRsU2Nyb2xsQmVoYXZpb3IubiAmJiAhX3J0bFNjcm9sbEJlaGF2aW9yLmkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTY3JvbGxDb29yZGluYXRlcy54ID0gTUFUSC5yb3VuZCh2aWV3cG9ydE9mZnNldFtfc3RyTGVmdF0gLSBlbGVtZW50T2Zmc2V0W19zdHJMZWZ0XSArIHZpZXdwb3J0U2Nyb2xsLmwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfcnRsU2Nyb2xsQmVoYXZpb3IubiAmJiBub3JtYWxpemVSVEwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTY3JvbGxDb29yZGluYXRlcy54ICo9IC0xO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfcnRsU2Nyb2xsQmVoYXZpb3IuaSAmJiBub3JtYWxpemVSVEwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTY3JvbGxDb29yZGluYXRlcy54ID0gTUFUSC5yb3VuZCh2aWV3cG9ydE9mZnNldFtfc3RyTGVmdF0gLSBlbGVtZW50T2Zmc2V0W19zdHJMZWZ0XSArIChfc2Nyb2xsSG9yaXpvbnRhbEluZm8uX21heFNjcm9sbCAtIHZpZXdwb3J0U2Nyb2xsLmwpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL21lYXN1cmluZyBpcyByZXF1aXJlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzQmxvY2sueCAhPSBzdHJCZWdpbiB8fCBzZXR0aW5nc0Jsb2NrLnkgIT0gc3RyQmVnaW4gfHwgc2V0dGluZ3NTY3JvbGwueCA9PSBzdHJJZk5lZWRlZCB8fCBzZXR0aW5nc1Njcm9sbC55ID09IHN0cklmTmVlZGVkIHx8IF9pc1JUTCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtZWFzdXJpbmdFbG0gPSBmaW5hbEVsZW1lbnRbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJhd0VsZW1lbnRTaXplID0gX3N1cHBvcnRUcmFuc2Zvcm0gPyBtZWFzdXJpbmdFbG1bTEVYSUNPTi5iQ1JdKCkgOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBtZWFzdXJpbmdFbG1bTEVYSUNPTi5vV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogbWVhc3VyaW5nRWxtW0xFWElDT04ub0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IHJhd0VsZW1lbnRTaXplW19zdHJXaWR0aF0gKyBzZXR0aW5nc01hcmdpblszXSArIHNldHRpbmdzTWFyZ2luWzFdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiByYXdFbGVtZW50U2l6ZVtfc3RySGVpZ2h0XSArIHNldHRpbmdzTWFyZ2luWzBdICsgc2V0dGluZ3NNYXJnaW5bMl1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmaW5hbGl6ZUJsb2NrID0gZnVuY3Rpb24gKGlzWCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFycyA9IGdldFNjcm9sbGJhclZhcnMoaXNYKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHdoID0gdmFycy5fd19oO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbHQgPSB2YXJzLl9sZWZ0X3RvcDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHh5ID0gdmFycy5feF95O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYmxvY2tJc0VuZCA9IHNldHRpbmdzQmxvY2tbeHldID09IChpc1ggPyBfaXNSVEwgPyBzdHJCZWdpbiA6IHN0ckVuZCA6IHN0ckVuZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBibG9ja0lzQ2VudGVyID0gc2V0dGluZ3NCbG9ja1t4eV0gPT0gc3RyQ2VudGVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYmxvY2tJc05lYXJlc3QgPSBzZXR0aW5nc0Jsb2NrW3h5XSA9PSBzdHJOZWFyZXN0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsTmV2ZXIgPSBzZXR0aW5nc1Njcm9sbFt4eV0gPT0gc3RyTmV2ZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxJZk5lZWRlZCA9IHNldHRpbmdzU2Nyb2xsW3h5XSA9PSBzdHJJZk5lZWRlZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZwU2l6ZSA9IF92aWV3cG9ydFNpemVbd2hdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdnBPZmZzZXQgPSB2aWV3cG9ydE9mZnNldFtsdF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbFNpemUgPSBlbGVtZW50U2l6ZVt3aF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbE9mZnNldCA9IGVsZW1lbnRPZmZzZXRbbHRdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGl2aWRlID0gYmxvY2tJc0NlbnRlciA/IDIgOiAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudENlbnRlck9mZnNldCA9IGVsT2Zmc2V0ICsgKGVsU2l6ZSAvIDIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRDZW50ZXJPZmZzZXQgPSB2cE9mZnNldCArICh2cFNpemUgLyAyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzSW5WaWV3ID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsU2l6ZSA8PSB2cFNpemVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGVsT2Zmc2V0ID49IHZwT2Zmc2V0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBlbE9mZnNldCArIGVsU2l6ZSA8PSB2cE9mZnNldCArIHZwU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzY3JvbGxOZXZlcilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvTm90U2Nyb2xsW3h5XSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFkb05vdFNjcm9sbFt4eV0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja0lzTmVhcmVzdCB8fCBzY3JvbGxJZk5lZWRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvTm90U2Nyb2xsW3h5XSA9IHNjcm9sbElmTmVlZGVkID8gaXNJblZpZXcgOiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBibG9ja0lzRW5kID0gZWxTaXplIDwgdnBTaXplID8gZWxlbWVudENlbnRlck9mZnNldCA+IHZpZXdwb3J0Q2VudGVyT2Zmc2V0IDogZWxlbWVudENlbnRlck9mZnNldCA8IHZpZXdwb3J0Q2VudGVyT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFNjcm9sbENvb3JkaW5hdGVzW3h5XSAtPSBibG9ja0lzRW5kIHx8IGJsb2NrSXNDZW50ZXIgPyAoKHZwU2l6ZSAvIGRpdmlkZSkgLSAoZWxTaXplIC8gZGl2aWRlKSkgKiAoaXNYICYmIF9pc1JUTCAmJiBub3JtYWxpemVSVEwgPyAtMSA6IDEpIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxpemVCbG9jayh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbGl6ZUJsb2NrKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9Ob3RTY3JvbGwueSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgZWxlbWVudFNjcm9sbENvb3JkaW5hdGVzLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9Ob3RTY3JvbGwueClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgZWxlbWVudFNjcm9sbENvb3JkaW5hdGVzLng7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMgPSBlbGVtZW50U2Nyb2xsQ29vcmRpbmF0ZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZpbmFsU2Nyb2xsW19zdHJTY3JvbGxMZWZ0XSA9IGdldEZpbmFsU2Nyb2xsKHRydWUsIGdldFJhd1Njcm9sbCh0cnVlLCBjb29yZGluYXRlcykpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZpbmFsU2Nyb2xsW19zdHJTY3JvbGxUb3BdID0gZ2V0RmluYWxTY3JvbGwoZmFsc2UsIGdldFJhd1Njcm9sbChmYWxzZSwgY29vcmRpbmF0ZXMpKTtcclxuICAgICAgICAgICAgICAgICAgICBkb1Njcm9sbExlZnQgPSBmaW5hbFNjcm9sbFtfc3RyU2Nyb2xsTGVmdF0gIT09IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgICAgICBkb1Njcm9sbFRvcCA9IGZpbmFsU2Nyb2xsW19zdHJTY3JvbGxUb3BdICE9PSB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICgoZG9TY3JvbGxMZWZ0IHx8IGRvU2Nyb2xsVG9wKSAmJiAoZHVyYXRpb24gPiAwIHx8IGR1cmF0aW9uSXNPYmplY3QpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkdXJhdGlvbklzT2JqZWN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbi5jb21wbGV0ZSA9IHByb3h5Q29tcGxldGVDYWxsYmFjaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuYW5pbWF0ZShmaW5hbFNjcm9sbCwgZHVyYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uT3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbjogZHVyYXRpb24sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGU6IHByb3h5Q29tcGxldGVDYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChDT01QQVRJQklMSVRZLmlzQShlYXNpbmcpIHx8IEZSQU1FV09SSy5pc1BsYWluT2JqZWN0KGVhc2luZykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWFsRWFzaW5nW19zdHJTY3JvbGxMZWZ0XSA9IGVhc2luZ1swXSB8fCBlYXNpbmcueDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWFsRWFzaW5nW19zdHJTY3JvbGxUb3BdID0gZWFzaW5nWzFdIHx8IGVhc2luZy55O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbk9wdGlvbnMuc3BlY2lhbEVhc2luZyA9IHNwZWNpYWxFYXNpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25PcHRpb25zLmVhc2luZyA9IGVhc2luZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuYW5pbWF0ZShmaW5hbFNjcm9sbCwgYW5pbWF0aW9uT3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1Njcm9sbExlZnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XShmaW5hbFNjcm9sbFtfc3RyU2Nyb2xsTGVmdF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9TY3JvbGxUb3ApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50W19zdHJTY3JvbGxUb3BdKGZpbmFsU2Nyb2xsW19zdHJTY3JvbGxUb3BdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlU2Nyb2xsYmFySW5mb3MoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogU3RvcHMgYWxsIHNjcm9sbCBhbmltYXRpb25zLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMgeyp9IFRoZSBjdXJyZW50IE92ZXJsYXlTY3JvbGxiYXJzIGluc3RhbmNlIChmb3IgY2hhaW5pbmcpLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5zY3JvbGxTdG9wID0gZnVuY3Rpb24gKHBhcmFtMSwgcGFyYW0yLCBwYXJhbTMpIHtcclxuICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50LnN0b3AocGFyYW0xLCBwYXJhbTIsIHBhcmFtMyk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9iYXNlO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJldHVybnMgYWxsIHJlbGV2YW50IGVsZW1lbnRzLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGVsZW1lbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IHdoaWNoIHNoYWxsIGJlIHJldHVybmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3t0YXJnZXQ6ICosIGhvc3Q6ICosIHBhZGRpbmc6ICosIHZpZXdwb3J0OiAqLCBjb250ZW50OiAqLCBzY3JvbGxiYXJIb3Jpem9udGFsOiB7c2Nyb2xsYmFyOiAqLCB0cmFjazogKiwgaGFuZGxlOiAqfSwgc2Nyb2xsYmFyVmVydGljYWw6IHtzY3JvbGxiYXI6ICosIHRyYWNrOiAqLCBoYW5kbGU6ICp9LCBzY3JvbGxiYXJDb3JuZXI6ICp9IHwgKn1cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgX2Jhc2UuZ2V0RWxlbWVudHMgPSBmdW5jdGlvbiAoZWxlbWVudE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb2JqID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQ6IF90YXJnZXRFbGVtZW50TmF0aXZlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBob3N0OiBfaG9zdEVsZW1lbnROYXRpdmUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhZGRpbmc6IF9wYWRkaW5nRWxlbWVudE5hdGl2ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnQ6IF92aWV3cG9ydEVsZW1lbnROYXRpdmUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IF9jb250ZW50RWxlbWVudE5hdGl2ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFySG9yaXpvbnRhbDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyOiBfc2Nyb2xsYmFySG9yaXpvbnRhbEVsZW1lbnRbMF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFjazogX3Njcm9sbGJhckhvcml6b250YWxUcmFja0VsZW1lbnRbMF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGU6IF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudFswXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJWZXJ0aWNhbDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyOiBfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50WzBdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2s6IF9zY3JvbGxiYXJWZXJ0aWNhbFRyYWNrRWxlbWVudFswXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZTogX3Njcm9sbGJhclZlcnRpY2FsSGFuZGxlRWxlbWVudFswXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJDb3JuZXI6IF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50WzBdXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHlwZShlbGVtZW50TmFtZSkgPT0gVFlQRVMucyA/IGdldE9iamVjdFByb3BWYWwob2JqLCBlbGVtZW50TmFtZSkgOiBvYmo7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyBhIG9iamVjdCB3aGljaCBkZXNjcmliZXMgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhpcyBpbnN0YW5jZS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBzdGF0ZVByb3BlcnR5IEEgc3BlY2lmaWMgcHJvcGVydHkgZnJvbSB0aGUgc3RhdGUgb2JqZWN0IHdoaWNoIHNoYWxsIGJlIHJldHVybmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3t3aWR0aEF1dG8sIGhlaWdodEF1dG8sIG92ZXJmbG93QW1vdW50LCBoaWRlT3ZlcmZsb3csIGhhc092ZXJmbG93LCBjb250ZW50U2Nyb2xsU2l6ZSwgdmlld3BvcnRTaXplLCBob3N0U2l6ZSwgYXV0b1VwZGF0ZX0gfCAqfVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5nZXRTdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZVByb3BlcnR5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gcHJlcGFyZShvYmopIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFGUkFNRVdPUksuaXNQbGFpbk9iamVjdChvYmopKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9iajtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGV4dGVuZGVkID0gZXh0ZW5kRGVlcCh7fSwgb2JqKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoYW5nZVByb3BlcnR5TmFtZSA9IGZ1bmN0aW9uIChmcm9tLCB0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV4dGVuZGVkW0xFWElDT04uaE9QXShmcm9tKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuZGVkW3RvXSA9IGV4dGVuZGVkW2Zyb21dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBleHRlbmRlZFtmcm9tXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlUHJvcGVydHlOYW1lKCd3JywgX3N0cldpZHRoKTsgLy9jaGFuZ2UgdyB0byB3aWR0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VQcm9wZXJ0eU5hbWUoJ2gnLCBfc3RySGVpZ2h0KTsgLy9jaGFuZ2UgaCB0byBoZWlnaHRcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGV4dGVuZGVkLmM7IC8vZGVsZXRlIGMgKHRoZSAnY2hhbmdlZCcgcHJvcClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV4dGVuZGVkO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9iaiA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVzdHJveWVkOiAhIXByZXBhcmUoX2Rlc3Ryb3llZCksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNsZWVwaW5nOiAhIXByZXBhcmUoX3NsZWVwaW5nKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b1VwZGF0ZTogcHJlcGFyZSghX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGhBdXRvOiBwcmVwYXJlKF93aWR0aEF1dG9DYWNoZSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodEF1dG86IHByZXBhcmUoX2hlaWdodEF1dG9DYWNoZSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhZGRpbmc6IHByZXBhcmUoX2Nzc1BhZGRpbmdDYWNoZSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJmbG93QW1vdW50OiBwcmVwYXJlKF9vdmVyZmxvd0Ftb3VudENhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGlkZU92ZXJmbG93OiBwcmVwYXJlKF9oaWRlT3ZlcmZsb3dDYWNoZSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc092ZXJmbG93OiBwcmVwYXJlKF9oYXNPdmVyZmxvd0NhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFNjcm9sbFNpemU6IHByZXBhcmUoX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGUpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydFNpemU6IHByZXBhcmUoX3ZpZXdwb3J0U2l6ZSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RTaXplOiBwcmVwYXJlKF9ob3N0U2l6ZUNhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnRNaXhlZDogcHJlcGFyZShfZG9jdW1lbnRNaXhlZClcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlKHN0YXRlUHJvcGVydHkpID09IFRZUEVTLnMgPyBnZXRPYmplY3RQcm9wVmFsKG9iaiwgc3RhdGVQcm9wZXJ0eSkgOiBvYmo7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyBhbGwgb3Igc3BlY2lmaWMgZXh0ZW5zaW9uIGluc3RhbmNlLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV4dE5hbWUgVGhlIG5hbWUgb2YgdGhlIGV4dGVuc2lvbiBmcm9tIHdoaWNoIHRoZSBpbnN0YW5jZSBzaGFsbCBiZSBnb3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e319IFRoZSBpbnN0YW5jZSBvZiB0aGUgZXh0ZW5zaW9uIHdpdGggdGhlIGdpdmVuIG5hbWUgb3IgdW5kZWZpbmVkIGlmIHRoZSBpbnN0YW5jZSBjb3VsZG4ndCBiZSBmb3VuZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgX2Jhc2UuZXh0ID0gZnVuY3Rpb24gKGV4dE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwcml2YXRlTWV0aG9kcyA9IF9leHRlbnNpb25zUHJpdmF0ZU1ldGhvZHMuc3BsaXQoJyAnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUoZXh0TmFtZSkgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2V4dGVuc2lvbnNbTEVYSUNPTi5oT1BdKGV4dE5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBleHRlbmREZWVwKHt9LCBfZXh0ZW5zaW9uc1tleHROYW1lXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IHByaXZhdGVNZXRob2RzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSByZXN1bHRbcHJpdmF0ZU1ldGhvZHNbaV1dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpIGluIF9leHRlbnNpb25zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2ldID0gZXh0ZW5kRGVlcCh7fSwgX2Jhc2UuZXh0KGkpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBBZGRzIGEgZXh0ZW5zaW9uIHRvIHRoaXMgaW5zdGFuY2UuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZXh0TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHdoaWNoIHNoYWxsIGJlIGFkZGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV4dGVuc2lvbk9wdGlvbnMgVGhlIGV4dGVuc2lvbiBvcHRpb25zIHdoaWNoIHNoYWxsIGJlIHVzZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e319IFRoZSBpbnN0YW5jZSBvZiB0aGUgYWRkZWQgZXh0ZW5zaW9uIG9yIHVuZGVmaW5lZCBpZiB0aGUgZXh0ZW5zaW9uIGNvdWxkbid0IGJlIGFkZGVkIHByb3Blcmx5LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5hZGRFeHQgPSBmdW5jdGlvbiAoZXh0TmFtZSwgZXh0ZW5zaW9uT3B0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWdpc3RlcmVkRXh0ZW5zaW9uT2JqID0gX3BsdWdpbi5leHRlbnNpb24oZXh0TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZUFkZGVkO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZUNvbnRyYWN0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250cmFjdFJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29udHJhY3RGdWxmaWxsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZWdpc3RlcmVkRXh0ZW5zaW9uT2JqKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2V4dGVuc2lvbnNbTEVYSUNPTi5oT1BdKGV4dE5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZSA9IHJlZ2lzdGVyZWRFeHRlbnNpb25PYmouZXh0ZW5zaW9uRmFjdG9yeS5jYWxsKF9iYXNlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuZERlZXAoe30sIHJlZ2lzdGVyZWRFeHRlbnNpb25PYmouZGVmYXVsdE9wdGlvbnMpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUNvbnRyYWN0ID0gaW5zdGFuY2UuY29udHJhY3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUoaW5zdGFuY2VDb250cmFjdCkgPT0gVFlQRVMuZikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cmFjdFJlc3VsdCA9IGluc3RhbmNlQ29udHJhY3Qod2luZG93KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJhY3RGdWxmaWxsZWQgPSB0eXBlKGNvbnRyYWN0UmVzdWx0KSA9PSBUWVBFUy5iID8gY29udHJhY3RSZXN1bHQgOiBjb250cmFjdEZ1bGZpbGxlZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRyYWN0RnVsZmlsbGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9leHRlbnNpb25zW2V4dE5hbWVdID0gaW5zdGFuY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQWRkZWQgPSBpbnN0YW5jZS5hZGRlZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUoaW5zdGFuY2VBZGRlZCkgPT0gVFlQRVMuZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQWRkZWQoZXh0ZW5zaW9uT3B0aW9ucyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2Jhc2UuZXh0KGV4dE5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2Jhc2UuZXh0KGV4dE5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIkEgZXh0ZW5zaW9uIHdpdGggdGhlIG5hbWUgXFxcIlwiICsgZXh0TmFtZSArIFwiXFxcIiBpc24ndCByZWdpc3RlcmVkLlwiKTtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZW1vdmVzIGEgZXh0ZW5zaW9uIGZyb20gdGhpcyBpbnN0YW5jZS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBleHROYW1lIFRoZSBuYW1lIG9mIHRoZSBleHRlbnNpb24gd2hpY2ggc2hhbGwgYmUgcmVtb3ZlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBleHRlbnNpb24gd2FzIHJlbW92ZWQsIGZhbHNlIG90aGVyd2lzZSBlLmcuIGlmIHRoZSBleHRlbnNpb24gd2Fzbid0IGFkZGVkIGJlZm9yZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgX2Jhc2UucmVtb3ZlRXh0ID0gZnVuY3Rpb24gKGV4dE5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2UgPSBfZXh0ZW5zaW9uc1tleHROYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2VSZW1vdmVkO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgX2V4dGVuc2lvbnNbZXh0TmFtZV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZVJlbW92ZWQgPSBpbnN0YW5jZS5yZW1vdmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShpbnN0YW5jZVJlbW92ZWQpID09IFRZUEVTLmYpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZVJlbW92ZWQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQ29uc3RydWN0cyB0aGUgcGx1Z2luLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gd2hpY2ggdGhlIHBsdWdpbiBzaGFsbCBiZSBhcHBsaWVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG9wdGlvbnMgVGhlIGluaXRpYWwgb3B0aW9ucyBvZiB0aGUgcGx1Z2luLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV4dGVuc2lvbnMgVGhlIGV4dGVuc2lvbihzKSB3aGljaCBzaGFsbCBiZSBhZGRlZCByaWdodCBhZnRlciB0aGUgaW5pdGlhbGl6YXRpb24uXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgcGx1Z2luIHdhcyBzdWNjZXNzZnVsbHkgaW5pdGlhbGl6ZWQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gY29uc3RydWN0KHRhcmdldEVsZW1lbnQsIG9wdGlvbnMsIGV4dGVuc2lvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICBfZGVmYXVsdE9wdGlvbnMgPSBnbG9iYWxzLmRlZmF1bHRPcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgIF9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nID0gZ2xvYmFscy5uYXRpdmVTY3JvbGxiYXJTdHlsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIF9uYXRpdmVTY3JvbGxiYXJTaXplID0gZXh0ZW5kRGVlcCh7fSwgZ2xvYmFscy5uYXRpdmVTY3JvbGxiYXJTaXplKTtcclxuICAgICAgICAgICAgICAgICAgICBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZCA9IGV4dGVuZERlZXAoe30sIGdsb2JhbHMubmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemUgPSBleHRlbmREZWVwKHt9LCBnbG9iYWxzLm92ZXJsYXlTY3JvbGxiYXJEdW1teVNpemUpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9ydGxTY3JvbGxCZWhhdmlvciA9IGV4dGVuZERlZXAoe30sIGdsb2JhbHMucnRsU2Nyb2xsQmVoYXZpb3IpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3BhcnNlICYgc2V0IG9wdGlvbnMgYnV0IGRvbid0IHVwZGF0ZVxyXG4gICAgICAgICAgICAgICAgICAgIHNldE9wdGlvbnMoZXh0ZW5kRGVlcCh7fSwgX2RlZmF1bHRPcHRpb25zLCBvcHRpb25zKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF9jc3NDYWxjID0gZ2xvYmFscy5jc3NDYWxjO1xyXG4gICAgICAgICAgICAgICAgICAgIF9tc2llVmVyc2lvbiA9IGdsb2JhbHMubXNpZTtcclxuICAgICAgICAgICAgICAgICAgICBfYXV0b1VwZGF0ZVJlY29tbWVuZGVkID0gZ2xvYmFscy5hdXRvVXBkYXRlUmVjb21tZW5kZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgX3N1cHBvcnRUcmFuc2l0aW9uID0gZ2xvYmFscy5zdXBwb3J0VHJhbnNpdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICBfc3VwcG9ydFRyYW5zZm9ybSA9IGdsb2JhbHMuc3VwcG9ydFRyYW5zZm9ybTtcclxuICAgICAgICAgICAgICAgICAgICBfc3VwcG9ydFBhc3NpdmVFdmVudHMgPSBnbG9iYWxzLnN1cHBvcnRQYXNzaXZlRXZlbnRzO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zdXBwb3J0UmVzaXplT2JzZXJ2ZXIgPSBnbG9iYWxzLnN1cHBvcnRSZXNpemVPYnNlcnZlcjtcclxuICAgICAgICAgICAgICAgICAgICBfc3VwcG9ydE11dGF0aW9uT2JzZXJ2ZXIgPSBnbG9iYWxzLnN1cHBvcnRNdXRhdGlvbk9ic2VydmVyO1xyXG4gICAgICAgICAgICAgICAgICAgIF9yZXN0cmljdGVkTWVhc3VyaW5nID0gZ2xvYmFscy5yZXN0cmljdGVkTWVhc3VyaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIF9kb2N1bWVudEVsZW1lbnQgPSBGUkFNRVdPUksodGFyZ2V0RWxlbWVudC5vd25lckRvY3VtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICBfZG9jdW1lbnRFbGVtZW50TmF0aXZlID0gX2RvY3VtZW50RWxlbWVudFswXTtcclxuICAgICAgICAgICAgICAgICAgICBfd2luZG93RWxlbWVudCA9IEZSQU1FV09SSyhfZG9jdW1lbnRFbGVtZW50TmF0aXZlLmRlZmF1bHRWaWV3IHx8IF9kb2N1bWVudEVsZW1lbnROYXRpdmUucGFyZW50V2luZG93KTtcclxuICAgICAgICAgICAgICAgICAgICBfd2luZG93RWxlbWVudE5hdGl2ZSA9IF93aW5kb3dFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIF9odG1sRWxlbWVudCA9IGZpbmRGaXJzdChfZG9jdW1lbnRFbGVtZW50LCAnaHRtbCcpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9ib2R5RWxlbWVudCA9IGZpbmRGaXJzdChfaHRtbEVsZW1lbnQsICdib2R5Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnQgPSBGUkFNRVdPUksodGFyZ2V0RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnROYXRpdmUgPSBfdGFyZ2V0RWxlbWVudFswXTtcclxuICAgICAgICAgICAgICAgICAgICBfaXNUZXh0YXJlYSA9IF90YXJnZXRFbGVtZW50LmlzKCd0ZXh0YXJlYScpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9pc0JvZHkgPSBfdGFyZ2V0RWxlbWVudC5pcygnYm9keScpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9kb2N1bWVudE1peGVkID0gX2RvY3VtZW50RWxlbWVudE5hdGl2ZSAhPT0gZG9jdW1lbnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8qIE9uIGEgZGl2IEVsZW1lbnQgVGhlIGlmIGNoZWNrcyBvbmx5IHdoZXRoZXI6XHJcbiAgICAgICAgICAgICAgICAgICAgICogLSB0aGUgdGFyZ2V0RWxlbWVudCBoYXMgdGhlIGNsYXNzIFwib3MtaG9zdFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICogLSB0aGUgdGFyZ2V0RWxlbWVudCBoYXMgYSBhIGNoaWxkIHdpdGggdGhlIGNsYXNzIFwib3MtcGFkZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICogXHJcbiAgICAgICAgICAgICAgICAgICAgICogSWYgdGhhdCdzIHRoZSBjYXNlLCBpdHMgYXNzdW1lZCB0aGUgRE9NIGhhcyBhbHJlYWR5IHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOlxyXG4gICAgICAgICAgICAgICAgICAgICAqIChUaGUgXCIub3MtaG9zdFwiIGVsZW1lbnQgaXMgdGhlIHRhcmdldEVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAgICAgKiAgPGRpdiBjbGFzcz1cIm9zLWhvc3RcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDxkaXYgY2xhc3M9XCJvcy1yZXNpemUtb2JzZXJ2ZXItaG9zdFwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXBhZGRpbmdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtdmlld3BvcnRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLWNvbnRlbnRcIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhciBvcy1zY3JvbGxiYXItaG9yaXpvbnRhbCBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLXRyYWNrXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItaGFuZGxlXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXIgb3Mtc2Nyb2xsYmFyLXZlcnRpY2FsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhci10cmFja1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLWhhbmRsZVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLWNvcm5lclwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICAgICAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICAgICAgICAgICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICAgICAgICAgKiBPbiBhIFRleHRhcmVhIEVsZW1lbnQgVGhlIGlmIGNoZWNrcyBvbmx5IHdoZXRoZXI6XHJcbiAgICAgICAgICAgICAgICAgICAgICogLSB0aGUgdGFyZ2V0RWxlbWVudCBoYXMgdGhlIGNsYXNzIFwib3MtdGV4dGFyZWFcIiBcclxuICAgICAgICAgICAgICAgICAgICAgKiAtIHRoZSB0YXJnZXRFbGVtZW50IGlzIGluc2lkZSBhIGVsZW1lbnQgd2l0aCB0aGUgY2xhc3MgXCJvcy1jb250ZW50XCIgXHJcbiAgICAgICAgICAgICAgICAgICAgICogXHJcbiAgICAgICAgICAgICAgICAgICAgICogSWYgdGhhdCdzIHRoZSBjYXNlLCBpdHMgYXNzdW1lZCB0aGUgRE9NIGhhcyBhbHJlYWR5IHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOlxyXG4gICAgICAgICAgICAgICAgICAgICAqIChUaGUgXCIub3MtdGV4dGFyZWFcIiAodGV4dGFyZWEpIGVsZW1lbnQgaXMgdGhlIHRhcmdldEVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAgICAgKiAgPGRpdiBjbGFzcz1cIm9zLWhvc3QtdGV4dGFyZWFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDxkaXYgY2xhc3M9XCJvcy1yZXNpemUtb2JzZXJ2ZXItaG9zdFwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXBhZGRpbmcgb3MtdGV4dC1pbmhlcml0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLXZpZXdwb3J0IG9zLXRleHQtaW5oZXJpdFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib3MtY29udGVudCBvcy10ZXh0LWluaGVyaXRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy10ZXh0YXJlYS1jb3ZlclwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIGNsYXNzPVwib3MtdGV4dGFyZWEgb3MtdGV4dC1pbmhlcml0XCI+PC90ZXh0YXJlYT5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXIgb3Mtc2Nyb2xsYmFyLWhvcml6b250YWwgXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhci10cmFja1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLWhhbmRsZVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyIG9zLXNjcm9sbGJhci12ZXJ0aWNhbFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItdHJhY2tcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhci1oYW5kbGVcIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhci1jb3JuZXJcIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgX2RvbUV4aXN0cyA9IF9pc1RleHRhcmVhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gX3RhcmdldEVsZW1lbnQuaGFzQ2xhc3MoX2NsYXNzTmFtZVRleHRhcmVhRWxlbWVudCkgJiYgX3RhcmdldEVsZW1lbnQucGFyZW50KCkuaGFzQ2xhc3MoX2NsYXNzTmFtZUNvbnRlbnRFbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6IF90YXJnZXRFbGVtZW50Lmhhc0NsYXNzKF9jbGFzc05hbWVIb3N0RWxlbWVudCkgJiYgX3RhcmdldEVsZW1lbnQuY2hpbGRyZW4oX3N0ckRvdCArIF9jbGFzc05hbWVQYWRkaW5nRWxlbWVudClbTEVYSUNPTi5sXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluaXRCb2R5U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBib2R5TW91c2VUb3VjaERvd25MaXN0ZW5lcjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9jaGVjayBpZiB0aGUgcGx1Z2luIGhhc24ndCB0byBiZSBpbml0aWFsaXplZFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkgJiYgIV9jdXJyZW50UHJlcGFyZWRPcHRpb25zLm5hdGl2ZVNjcm9sbGJhcnNPdmVybGFpZC5pbml0aWFsaXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uSW5pdGlhbGl6YXRpb25XaXRoZHJhd24nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9kb21FeGlzdHMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwU3RydWN0dXJlRE9NKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBTY3JvbGxiYXJzRE9NKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBTY3JvbGxiYXJDb3JuZXJET00odHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9kZXN0cm95ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2xlZXBpbmcgPSB0cnVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9iYXNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc0JvZHkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdEJvZHlTY3JvbGwgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdEJvZHlTY3JvbGwubCA9IE1BVEgubWF4KF90YXJnZXRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XSgpLCBfaHRtbEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKCksIF93aW5kb3dFbGVtZW50W19zdHJTY3JvbGxMZWZ0XSgpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdEJvZHlTY3JvbGwudCA9IE1BVEgubWF4KF90YXJnZXRFbGVtZW50W19zdHJTY3JvbGxUb3BdKCksIF9odG1sRWxlbWVudFtfc3RyU2Nyb2xsVG9wXSgpLCBfd2luZG93RWxlbWVudFtfc3RyU2Nyb2xsVG9wXSgpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHlNb3VzZVRvdWNoRG93bkxpc3RlbmVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudC5yZW1vdmVBdHRyKExFWElDT04udGkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfdmlld3BvcnRFbGVtZW50LCBfc3RyTW91c2VUb3VjaERvd25FdmVudCwgYm9keU1vdXNlVG91Y2hEb3duTGlzdGVuZXIsIHRydWUsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2J1aWxkIE92ZXJsYXlTY3JvbGxiYXJzIERPTVxyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU3RydWN0dXJlRE9NKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBTY3JvbGxiYXJzRE9NKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBTY3JvbGxiYXJDb3JuZXJET00oKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9jcmVhdGUgT3ZlcmxheVNjcm9sbGJhcnMgZXZlbnRzXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBTdHJ1Y3R1cmVFdmVudHMoKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhckV2ZW50cyh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhckV2ZW50cyhmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBTY3JvbGxiYXJDb3JuZXJFdmVudHMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9jcmVhdGUgbXV0YXRpb24gb2JzZXJ2ZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlTXV0YXRpb25PYnNlcnZlcnMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9idWlsZCByZXNpemUgb2JzZXJ2ZXIgZm9yIHRoZSBob3N0IGVsZW1lbnRcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc2l6ZU9ic2VydmVyKF9zaXplT2JzZXJ2ZXJFbGVtZW50LCBob3N0T25SZXNpemVkKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc0JvZHkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hcHBseSB0aGUgYm9keSBzY3JvbGwgdG8gaGFuZGxlIGl0IHJpZ2h0IGluIHRoZSB1cGRhdGUgbWV0aG9kXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKGluaXRCb2R5U2Nyb2xsLmwpW19zdHJTY3JvbGxUb3BdKGluaXRCb2R5U2Nyb2xsLnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zZXQgdGhlIGZvY3VzIG9uIHRoZSB2aWV3cG9ydCBlbGVtZW50IHNvIHlvdSBkb250IGhhdmUgdG8gY2xpY2sgb24gdGhlIHBhZ2UgdG8gdXNlIGtleWJvYXJkIGtleXMgKHVwIC8gZG93biAvIHNwYWNlKSBmb3Igc2Nyb2xsaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09IHRhcmdldEVsZW1lbnQgJiYgX3ZpZXdwb3J0RWxlbWVudE5hdGl2ZS5mb2N1cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9zZXQgYSB0YWJpbmRleCB0byBtYWtlIHRoZSB2aWV3cG9ydEVsZW1lbnQgZm9jdXNhYmxlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50LmF0dHIoTEVYSUNPTi50aSwgJy0xJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50TmF0aXZlLmZvY3VzKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdGhlIHRhYmluZGV4IGhhcyB0byBiZSByZW1vdmVkIGR1ZSB0bztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIElmIHlvdSBzZXQgdGhlIHRhYmluZGV4IGF0dHJpYnV0ZSBvbiBhbiA8ZGl2PiwgdGhlbiBpdHMgY2hpbGQgY29udGVudCBjYW5ub3QgYmUgc2Nyb2xsZWQgd2l0aCB0aGUgYXJyb3cga2V5cyB1bmxlc3MgeW91IHNldCB0YWJpbmRleCBvbiB0aGUgY29udGVudCwgdG9vXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0dsb2JhbF9hdHRyaWJ1dGVzL3RhYmluZGV4XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoX3ZpZXdwb3J0RWxlbWVudCwgX3N0ck1vdXNlVG91Y2hEb3duRXZlbnQsIGJvZHlNb3VzZVRvdWNoRG93bkxpc3RlbmVyLCBmYWxzZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vdXBkYXRlIGZvciB0aGUgZmlyc3QgdGltZSAmIGluaXRpYWxpemUgY2FjaGVcclxuICAgICAgICAgICAgICAgICAgICBfYmFzZS51cGRhdGUoX3N0ckF1dG8pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3RoZSBwbHVnaW4gaXMgaW5pdGlhbGl6ZWQgbm93IVxyXG4gICAgICAgICAgICAgICAgICAgIF9pbml0aWFsaXplZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25Jbml0aWFsaXplZCcpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NhbGwgYWxsIGNhbGxiYWNrcyB3aGljaCB3b3VsZCBmaXJlIGJlZm9yZSB0aGUgaW5pdGlhbGl6ZWQgd2FzIGNvbXBsZXRlXHJcbiAgICAgICAgICAgICAgICAgICAgZWFjaChfY2FsbGJhY2tzSW5pdFFldWV1ZSwgZnVuY3Rpb24gKGluZGV4LCB2YWx1ZSkgeyBkaXNwYXRjaENhbGxiYWNrKHZhbHVlLm4sIHZhbHVlLmEpOyB9KTtcclxuICAgICAgICAgICAgICAgICAgICBfY2FsbGJhY2tzSW5pdFFldWV1ZSA9IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2FkZCBleHRlbnNpb25zXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUoZXh0ZW5zaW9ucykgPT0gVFlQRVMucylcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9ucyA9IFtleHRlbnNpb25zXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoQ09NUEFUSUJJTElUWS5pc0EoZXh0ZW5zaW9ucykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVhY2goZXh0ZW5zaW9ucywgZnVuY3Rpb24gKGluZGV4LCB2YWx1ZSkgeyBfYmFzZS5hZGRFeHQodmFsdWUpOyB9KTtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChGUkFNRVdPUksuaXNQbGFpbk9iamVjdChleHRlbnNpb25zKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaChleHRlbnNpb25zLCBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkgeyBfYmFzZS5hZGRFeHQoa2V5LCB2YWx1ZSk7IH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2FkZCB0aGUgdHJhbnNpdGlvbiBjbGFzcyBmb3IgdHJhbnNpdGlvbnMgQUZURVIgdGhlIGZpcnN0IHVwZGF0ZSAmIEFGVEVSIHRoZSBhcHBsaWVkIGV4dGVuc2lvbnMgKGZvciBwcmV2ZW50aW5nIHVud2FudGVkIHRyYW5zaXRpb25zKVxyXG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRUcmFuc2l0aW9uICYmICFfZGVzdHJveWVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX2hvc3RFbGVtZW50LCBfY2xhc3NOYW1lSG9zdFRyYW5zaXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sIDMzMyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfYmFzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoX3BsdWdpbi52YWxpZChjb25zdHJ1Y3QocGx1Z2luVGFyZ2V0RWxlbWVudCwgb3B0aW9ucywgZXh0ZW5zaW9ucykpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgSU5TVEFOQ0VTKHBsdWdpblRhcmdldEVsZW1lbnQsIF9iYXNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gX2Jhc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ldyBPdmVybGF5U2Nyb2xsYmFyc0luc3RhbmNlIG9iamVjdCBvciBjaGFuZ2VzIG9wdGlvbnMgaWYgYWxyZWFkeSBpbml0aWFsaXplZCBvciByZXR1cm5zIHRoZSBjdXJyZW50IGluc3RhbmNlLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gcGx1Z2luVGFyZ2V0RWxlbWVudHMgVGhlIGVsZW1lbnRzIHRvIHdoaWNoIHRoZSBQbHVnaW4gc2hhbGwgYmUgaW5pdGlhbGl6ZWQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBvcHRpb25zIFRoZSBjdXN0b20gb3B0aW9ucyB3aXRoIHdoaWNoIHRoZSBwbHVnaW4gc2hhbGwgYmUgaW5pdGlhbGl6ZWQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBleHRlbnNpb25zIFRoZSBleHRlbnNpb24ocykgd2hpY2ggc2hhbGwgYmUgYWRkZWQgcmlnaHQgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uXHJcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfVxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgX3BsdWdpbiA9IHdpbmRvd1tQTFVHSU5OQU1FXSA9IGZ1bmN0aW9uIChwbHVnaW5UYXJnZXRFbGVtZW50cywgb3B0aW9ucywgZXh0ZW5zaW9ucykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3VtZW50c1tMRVhJQ09OLmxdID09PSAwKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG5cclxuICAgICAgICAgICAgICAgIHZhciBhcnIgPSBbXTtcclxuICAgICAgICAgICAgICAgIHZhciBvcHRzSXNQbGFpbk9iaiA9IEZSQU1FV09SSy5pc1BsYWluT2JqZWN0KG9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGluc3Q7XHJcbiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0O1xyXG5cclxuICAgICAgICAgICAgICAgIC8vcGx1Z2luVGFyZ2V0RWxlbWVudHMgaXMgbnVsbCBvciB1bmRlZmluZWRcclxuICAgICAgICAgICAgICAgIGlmICghcGx1Z2luVGFyZ2V0RWxlbWVudHMpXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9wdHNJc1BsYWluT2JqIHx8ICFvcHRpb25zID8gcmVzdWx0IDogYXJyO1xyXG5cclxuICAgICAgICAgICAgICAgIC8qXHJcbiAgICAgICAgICAgICAgICAgICBwbHVnaW5UYXJnZXRFbGVtZW50cyB3aWxsIGJlIGNvbnZlcnRlZCB0bzpcclxuICAgICAgICAgICAgICAgICAgIDEuIEEgalF1ZXJ5RWxlbWVudCBBcnJheVxyXG4gICAgICAgICAgICAgICAgICAgMi4gQSBIVE1MRWxlbWVudCBBcnJheVxyXG4gICAgICAgICAgICAgICAgICAgMy4gQSBBcnJheSB3aXRoIGEgc2luZ2xlIEhUTUwgRWxlbWVudFxyXG4gICAgICAgICAgICAgICAgICAgc28gcGx1Z2luVGFyZ2V0RWxlbWVudHMgaXMgYWx3YXlzIGEgYXJyYXkuXHJcbiAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgcGx1Z2luVGFyZ2V0RWxlbWVudHMgPSBwbHVnaW5UYXJnZXRFbGVtZW50c1tMRVhJQ09OLmxdICE9IHVuZGVmaW5lZCA/IHBsdWdpblRhcmdldEVsZW1lbnRzIDogW3BsdWdpblRhcmdldEVsZW1lbnRzWzBdIHx8IHBsdWdpblRhcmdldEVsZW1lbnRzXTtcclxuICAgICAgICAgICAgICAgIGluaXRPdmVybGF5U2Nyb2xsYmFyc1N0YXRpY3MoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAocGx1Z2luVGFyZ2V0RWxlbWVudHNbTEVYSUNPTi5sXSA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob3B0c0lzUGxhaW5PYmopIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLmVhY2gocGx1Z2luVGFyZ2V0RWxlbWVudHMsIGZ1bmN0aW9uIChpLCB2KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0ID0gdjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnN0ICE9PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnB1c2goT3ZlcmxheVNjcm9sbGJhcnNJbnN0YW5jZShpbnN0LCBvcHRpb25zLCBleHRlbnNpb25zLCBfcGx1Z2luc0dsb2JhbHMsIF9wbHVnaW5zQXV0b1VwZGF0ZUxvb3ApKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBGUkFNRVdPUksuZWFjaChwbHVnaW5UYXJnZXRFbGVtZW50cywgZnVuY3Rpb24gKGksIHYpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3QgPSBJTlNUQU5DRVModik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKG9wdGlvbnMgPT09ICchJyAmJiBfcGx1Z2luLnZhbGlkKGluc3QpKSB8fCAoQ09NUEFUSUJJTElUWS50eXBlKG9wdGlvbnMpID09IFRZUEVTLmYgJiYgb3B0aW9ucyh2LCBpbnN0KSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnB1c2goaW5zdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChvcHRpb25zID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnB1c2goaW5zdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBhcnJbTEVYSUNPTi5sXSA9PT0gMSA/IGFyclswXSA6IGFycjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogUmV0dXJucyBhIG9iamVjdCB3aGljaCBjb250YWlucyBnbG9iYWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBsdWdpbiBhbmQgZWFjaCBpbnN0YW5jZSBvZiBpdC5cclxuICAgICAgICAgICAgICogVGhlIHJldHVybmVkIG9iamVjdCBpcyBqdXN0IGEgY29weSwgdGhhdCBtZWFucyB0aGF0IGNoYW5nZXMgdG8gdGhlIHJldHVybmVkIG9iamVjdCB3b24ndCBoYXZlIGFueSBlZmZlY3QgdG8gdGhlIG9yaWdpbmFsIG9iamVjdC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIF9wbHVnaW4uZ2xvYmFscyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGluaXRPdmVybGF5U2Nyb2xsYmFyc1N0YXRpY3MoKTtcclxuICAgICAgICAgICAgICAgIHZhciBnbG9iYWxzID0gRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB7fSwgX3BsdWdpbnNHbG9iYWxzKTtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSBnbG9iYWxzWydtc2llJ107XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2xvYmFscztcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBHZXRzIG9yIFNldHMgdGhlIGRlZmF1bHQgb3B0aW9ucyBmb3IgZWFjaCBuZXcgcGx1Z2luIGluaXRpYWxpemF0aW9uLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gbmV3RGVmYXVsdE9wdGlvbnMgVGhlIG9iamVjdCB3aXRoIHdoaWNoIHRoZSBkZWZhdWx0IG9wdGlvbnMgc2hhbGwgYmUgZXh0ZW5kZWQuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBfcGx1Z2luLmRlZmF1bHRPcHRpb25zID0gZnVuY3Rpb24gKG5ld0RlZmF1bHRPcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICBpbml0T3ZlcmxheVNjcm9sbGJhcnNTdGF0aWNzKCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgY3VyckRlZmF1bHRPcHRpb25zID0gX3BsdWdpbnNHbG9iYWxzLmRlZmF1bHRPcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgaWYgKG5ld0RlZmF1bHRPcHRpb25zID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZSQU1FV09SSy5leHRlbmQodHJ1ZSwge30sIGN1cnJEZWZhdWx0T3B0aW9ucyk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9zZXQgdGhlIG5ldyBkZWZhdWx0IG9wdGlvbnNcclxuICAgICAgICAgICAgICAgIF9wbHVnaW5zR2xvYmFscy5kZWZhdWx0T3B0aW9ucyA9IEZSQU1FV09SSy5leHRlbmQodHJ1ZSwge30sIGN1cnJEZWZhdWx0T3B0aW9ucywgX3BsdWdpbnNPcHRpb25zLl92YWxpZGF0ZShuZXdEZWZhdWx0T3B0aW9ucywgX3BsdWdpbnNPcHRpb25zLl90ZW1wbGF0ZSwgdHJ1ZSwgY3VyckRlZmF1bHRPcHRpb25zKS5fZGVmYXVsdCk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIHBhc3NlZCBpbnN0YW5jZSBpcyBhIG5vbi1kZXN0cm95ZWQgT3ZlcmxheVNjcm9sbGJhcnMgaW5zdGFuY2UuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBvc0luc3RhbmNlIFRoZSBwb3RlbnRpYWwgT3ZlcmxheVNjcm9sbGJhcnMgaW5zdGFuY2Ugd2hpY2ggc2hhbGwgYmUgY2hlY2tlZC5cclxuICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHBhc3NlZCB2YWx1ZSBpcyBhIG5vbi1kZXN0cm95ZWQgT3ZlcmxheVNjcm9sbGJhcnMgaW5zdGFuY2UsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIF9wbHVnaW4udmFsaWQgPSBmdW5jdGlvbiAob3NJbnN0YW5jZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9zSW5zdGFuY2UgaW5zdGFuY2VvZiBfcGx1Z2luICYmICFvc0luc3RhbmNlLmdldFN0YXRlKCkuZGVzdHJveWVkO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFJlZ2lzdGVycywgVW5yZWdpc3RlcnMgb3IgcmV0dXJucyBhIGV4dGVuc2lvbi5cclxuICAgICAgICAgICAgICogUmVnaXN0ZXI6IFBhc3MgdGhlIG5hbWUgYW5kIHRoZSBleHRlbnNpb24uIChkZWZhdWx0T3B0aW9ucyBpcyBvcHRpb25hbClcclxuICAgICAgICAgICAgICogVW5yZWdpc3RlcjogUGFzcyB0aGUgbmFtZSBhbmQgYW55dGhpbmcgZXhjZXB0IGEgZnVuY3Rpb24gYXMgZXh0ZW5zaW9uIHBhcmFtZXRlci5cclxuICAgICAgICAgICAgICogR2V0IGV4dGVuc2lvbjogUGFzcyB0aGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHdoaWNoIHNoYWxsIGJlIGdvdC5cclxuICAgICAgICAgICAgICogR2V0IGFsbCBleHRlbnNpb25zOiBQYXNzIG5vIGFyZ3VtZW50cy5cclxuICAgICAgICAgICAgICogQHBhcmFtIGV4dGVuc2lvbk5hbWUgVGhlIG5hbWUgb2YgdGhlIGV4dGVuc2lvbiB3aGljaCBzaGFsbCBiZSByZWdpc3RlcmVkLCB1bnJlZ2lzdGVyZWQgb3IgcmV0dXJuZWQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBleHRlbnNpb24gQSBmdW5jdGlvbiB3aGljaCBnZW5lcmF0ZXMgdGhlIGluc3RhbmNlIG9mIHRoZSBleHRlbnNpb24gb3IgYW55dGhpbmcgb3RoZXIgdG8gcmVtb3ZlIGEgYWxyZWFkeSByZWdpc3RlcmVkIGV4dGVuc2lvbi5cclxuICAgICAgICAgICAgICogQHBhcmFtIGRlZmF1bHRPcHRpb25zIFRoZSBkZWZhdWx0IG9wdGlvbnMgd2hpY2ggc2hhbGwgYmUgdXNlZCBmb3IgdGhlIHJlZ2lzdGVyZWQgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgX3BsdWdpbi5leHRlbnNpb24gPSBmdW5jdGlvbiAoZXh0ZW5zaW9uTmFtZSwgZXh0ZW5zaW9uLCBkZWZhdWx0T3B0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgdmFyIGV4dE5hbWVUeXBlU3RyaW5nID0gQ09NUEFUSUJJTElUWS50eXBlKGV4dGVuc2lvbk5hbWUpID09IFRZUEVTLnM7XHJcbiAgICAgICAgICAgICAgICB2YXIgYXJnTGVuID0gYXJndW1lbnRzW0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICBpZiAoYXJnTGVuIDwgMSB8fCAhZXh0TmFtZVR5cGVTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL3JldHVybiBhIGNvcHkgb2YgYWxsIGV4dGVuc2lvbiBvYmplY3RzXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZSQU1FV09SSy5leHRlbmQodHJ1ZSwgeyBsZW5ndGg6IF9wbHVnaW5zRXh0ZW5zaW9uc1tMRVhJQ09OLmxdIH0sIF9wbHVnaW5zRXh0ZW5zaW9ucyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChleHROYW1lVHlwZVN0cmluZykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChDT01QQVRJQklMSVRZLnR5cGUoZXh0ZW5zaW9uKSA9PSBUWVBFUy5mKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVnaXN0ZXIgZXh0ZW5zaW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9wbHVnaW5zRXh0ZW5zaW9ucy5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IGV4dGVuc2lvbk5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25GYWN0b3J5OiBleHRlbnNpb24sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0T3B0aW9uczogZGVmYXVsdE9wdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IF9wbHVnaW5zRXh0ZW5zaW9uc1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfcGx1Z2luc0V4dGVuc2lvbnNbaV0ubmFtZSA9PT0gZXh0ZW5zaW9uTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcmdMZW4gPiAxKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcGx1Z2luc0V4dGVuc2lvbnMuc3BsaWNlKGksIDEpOyAvL3JlbW92ZSBleHRlbnNpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGUkFNRVdPUksuZXh0ZW5kKHRydWUsIHt9LCBfcGx1Z2luc0V4dGVuc2lvbnNbaV0pOyAvL3JldHVybiBleHRlbnNpb24gd2l0aCB0aGUgZ2l2ZW4gbmFtZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIF9wbHVnaW47XHJcbiAgICAgICAgfSkoKTtcclxuXHJcbiAgICAgICAgaWYgKEpRVUVSWSAmJiBKUVVFUlkuZm4pIHtcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFRoZSBqUXVlcnkgaW5pdGlhbGl6YXRpb24gaW50ZXJmYWNlLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyBUaGUgaW5pdGlhbCBvcHRpb25zIGZvciB0aGUgY29uc3RydWN0aW9uIG9mIHRoZSBwbHVnaW4uIFRvIGluaXRpYWxpemUgdGhlIHBsdWdpbiwgdGhpcyBvcHRpb24gaGFzIHRvIGJlIGEgb2JqZWN0ISBJZiBpdCBpc24ndCBhIG9iamVjdCwgdGhlIGluc3RhbmNlKHMpIGFyZSByZXR1cm5lZCBhbmQgdGhlIHBsdWdpbiB3b250IGJlIGluaXRpYWxpemVkLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gZXh0ZW5zaW9ucyBUaGUgZXh0ZW5zaW9uKHMpIHdoaWNoIHNoYWxsIGJlIGFkZGVkIHJpZ2h0IGFmdGVyIGluaXRpYWxpemF0aW9uLlxyXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn0gQWZ0ZXIgaW5pdGlhbGl6YXRpb24gaXQgcmV0dXJucyB0aGUgalF1ZXJ5IGVsZW1lbnQgYXJyYXksIGVsc2UgaXQgcmV0dXJucyB0aGUgaW5zdGFuY2Uocykgb2YgdGhlIGVsZW1lbnRzIHdoaWNoIGFyZSBzZWxlY3RlZC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIEpRVUVSWS5mbi5vdmVybGF5U2Nyb2xsYmFycyA9IGZ1bmN0aW9uIChvcHRpb25zLCBleHRlbnNpb25zKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2VsZW1lbnRzID0gdGhpcztcclxuICAgICAgICAgICAgICAgIGlmIChKUVVFUlkuaXNQbGFpbk9iamVjdChvcHRpb25zKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIEpRVUVSWS5lYWNoKF9lbGVtZW50cywgZnVuY3Rpb24gKCkgeyBQTFVHSU4odGhpcywgb3B0aW9ucywgZXh0ZW5zaW9ucyk7IH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfZWxlbWVudHM7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBMVUdJTihfZWxlbWVudHMsIG9wdGlvbnMpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gUExVR0lOO1xyXG4gICAgfVxyXG4pKTsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1084\n")}}]);
|