@preply/ds-docs 0.4.3-beta.35 → 0.4.3

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.
Files changed (30) hide show
  1. package/dist/0.338f1686.iframe.bundle.js +1 -0
  2. package/dist/10.8c9f1e0f.iframe.bundle.js +1 -0
  3. package/dist/11.eb6590ee.iframe.bundle.js +1 -1
  4. package/dist/12.14fcbdc9.iframe.bundle.js +1 -1
  5. package/dist/9.a9ad41ca.iframe.bundle.js +1 -0
  6. package/dist/iframe.html +1 -1
  7. package/dist/index.html +1 -1
  8. package/dist/main~493df0b3.3c7dd9ba.iframe.bundle.js +1 -0
  9. package/dist/{runtime~main.b9288cbc.iframe.bundle.js → runtime~main.fdfb1fa0.iframe.bundle.js} +1 -1
  10. package/dist/vendors~main.4bb5fc92cf749e8c9723.manager.bundle.js +2 -0
  11. package/dist/{vendors~main.a298dbf4b4228db7a7c0.manager.bundle.js.LICENSE.txt → vendors~main.4bb5fc92cf749e8c9723.manager.bundle.js.LICENSE.txt} +0 -0
  12. package/dist/vendors~main~253ae210.947d24a2.iframe.bundle.js +1 -0
  13. package/dist/vendors~main~4134d62c.0cd088e7.iframe.bundle.js +1 -0
  14. package/dist/vendors~main~678f84af.0dcca9fa.iframe.bundle.js +1 -0
  15. package/dist/vendors~main~a353122d.95161e35.iframe.bundle.js +1 -0
  16. package/dist/vendors~main~bdc480fb.483353aa.iframe.bundle.js +1 -0
  17. package/dist/vendors~main~d88e64ba.34fa683a.iframe.bundle.js +1 -0
  18. package/package.json +2 -2
  19. package/CHANGELOG.md +0 -46
  20. package/dist/0.3fa9c511.iframe.bundle.js +0 -1
  21. package/dist/10.cbab8b16.iframe.bundle.js +0 -1
  22. package/dist/9.50d8be07.iframe.bundle.js +0 -1
  23. package/dist/main~493df0b3.15207f51.iframe.bundle.js +0 -1
  24. package/dist/vendors~main.a298dbf4b4228db7a7c0.manager.bundle.js +0 -2
  25. package/dist/vendors~main~253ae210.4ae5c9e8.iframe.bundle.js +0 -1
  26. package/dist/vendors~main~4134d62c.1d98f7f4.iframe.bundle.js +0 -1
  27. package/dist/vendors~main~678f84af.7ab7d52f.iframe.bundle.js +0 -1
  28. package/dist/vendors~main~a353122d.312fbc2d.iframe.bundle.js +0 -1
  29. package/dist/vendors~main~bdc480fb.2ad5d7bf.iframe.bundle.js +0 -1
  30. package/dist/vendors~main~d88e64ba.a117b568.iframe.bundle.js +0 -1
@@ -1 +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/OWNkZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBa0Q7QUFDUDtBQUNLO0FBQ0Y7QUFDSjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0Q7QUFDTDtBQUNPOztBQUU3QyxxQkFBcUIsZ0RBQWdELGdCQUFnQixzQkFBc0IsT0FBTywyQkFBMkIsMEJBQTBCLHlEQUF5RCwyQkFBMkIsRUFBRSxFQUFFLEVBQUUsZUFBZSxHQUFHLHdDQUF3Qzs7QUFFM1QscURBQXFELCtCQUErQiw4REFBOEQsWUFBWSxvQ0FBb0MsNkRBQTZELFlBQVksNkJBQTZCLE9BQU8sMkJBQTJCLDBDQUEwQyx3RUFBd0UsMkJBQTJCLEVBQUUsRUFBRSxlQUFlOztBQUUxZSwwREFBMEQsK0JBQStCLGlCQUFpQixzQ0FBc0MsWUFBWSxZQUFZLHVCQUF1QixPQUFPLHFCQUFxQiwwQ0FBMEMsMkJBQTJCLEVBQUUsZUFBZTs7QUFFdlI7QUFDd0I7O0FBRWxEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQSw0Q0FBNEM7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0JBQW9CLDZDQUFLO0FBQ3pCLG1CQUFtQiw2Q0FBSztBQUN4QixFQUFFLDZDQUFLO0FBQ1AseUJBQXlCLHlEQUFpQjtBQUMxQztBQUNBO0FBQ0EsVUFBVSx5REFBaUI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRSw2Q0FBSztBQUNQLFFBQVEseURBQWlCO0FBQ3pCO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRSw2Q0FBSztBQUNQLFFBQVEseURBQWlCO0FBQ3pCO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsc0JBQXNCLDZDQUFLO0FBQzNCO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRyxnQkFBZ0IsNkNBQUs7QUFDeEI7QUFDQSxHQUFHLGdCQUFnQiw2Q0FBSztBQUN4QjtBQUNBLEdBQUcsZUFBZSw2Q0FBSztBQUN2QjtBQUNBLEdBQUcsZUFBZSw2Q0FBSztBQUN2QjtBQUNBLEdBQUcsNEJBQTRCLDZDQUFLO0FBQ3BDO0FBQ0EsR0FBRyxlQUFlLDZDQUFLO0FBQ3ZCO0FBQ0EsR0FBRyxlQUFlLDZDQUFLO0FBQ3ZCO0FBQ0EsR0FBRyxrQkFBa0IsNkNBQUs7QUFDMUI7QUFDQSxHQUFHLGVBQWUsNkNBQUs7QUFDdkI7QUFDQSxHQUFHLGVBQWUsNkNBQUs7QUFDdkI7QUFDQSxHQUFHLGtCQUFrQiw2Q0FBSztBQUMxQjtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0EsTUFBTSx5REFBaUI7QUFDdkI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVlLHlGQUEwQiIsImZpbGUiOiIxMDA1LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnJlZ2V4cC5jb25zdHJ1Y3Rvci5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnJlZ2V4cC5leGVjLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMucmVnZXhwLnRvLXN0cmluZy5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5yZXBsYWNlLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMuYXJyYXkuam9pbi5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5LmZpbHRlci5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5zcGxpdC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5tYXRjaC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5LmNvbmNhdC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLm9iamVjdC5rZXlzLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMuc3ltYm9sLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMub2JqZWN0LmFzc2lnbi5qc1wiO1xuXG5mdW5jdGlvbiBfZXh0ZW5kcygpIHsgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9OyByZXR1cm4gX2V4dGVuZHMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfVxuXG5mdW5jdGlvbiBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMoc291cmNlLCBleGNsdWRlZCkgeyBpZiAoc291cmNlID09IG51bGwpIHJldHVybiB7fTsgdmFyIHRhcmdldCA9IF9vYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlKHNvdXJjZSwgZXhjbHVkZWQpOyB2YXIga2V5LCBpOyBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykgeyB2YXIgc291cmNlU3ltYm9sS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoc291cmNlKTsgZm9yIChpID0gMDsgaSA8IHNvdXJjZVN5bWJvbEtleXMubGVuZ3RoOyBpKyspIHsga2V5ID0gc291cmNlU3ltYm9sS2V5c1tpXTsgaWYgKGV4Y2x1ZGVkLmluZGV4T2Yoa2V5KSA+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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vL2hvbWUvamVua2lucy93b3Jrc3BhY2UvZGVzaWduLXN5c3RlbV9QUi0xOS9ub2RlX21vZHVsZXMvb3ZlcmxheXNjcm9sbGJhcnMvanMvT3ZlcmxheVNjcm9sbGJhcnMuanM/MzdjYiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxRQUFRLElBQTBDO0FBQ2xELFFBQVEsbUNBQU8sYUFBYSxvREFBb0QsRUFBRTtBQUFBLG9HQUFDO0FBQ25GLFNBQVMsRUFHMkM7QUFDcEQsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQix3QkFBd0I7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsb0NBQW9DO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwwQkFBMEIsOEJBQThCO0FBQ3hELDhCQUE4QixxQ0FBcUM7QUFDbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOEJBQThCLDJCQUEyQjtBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0M7QUFDeEMsMENBQTBDLDRHQUE0Rzs7QUFFdEo7QUFDQSw4Q0FBOEM7QUFDOUM7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsY0FBYztBQUMzQztBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsY0FBYztBQUMzQztBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsNkJBQTZCO0FBQzFEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLFdBQVc7QUFDeEM7QUFDQSw4RkFBOEYsMkNBQTJDLEVBQUU7O0FBRTNJO0FBQ0E7QUFDQSw2QkFBNkIsV0FBVztBQUN4QztBQUNBLDJGQUEyRixnQ0FBZ0MsRUFBRTs7QUFFN0g7QUFDQTtBQUNBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QixzQkFBc0I7QUFDcEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsT0FBTztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsT0FBTztBQUNwQztBQUNBO0FBQ0EsbUNBQW1DLG9CQUFvQjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLE9BQU87QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7OztBQUdqQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsWUFBWTs7QUFFekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7OztBQUdUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtREFBbUQsbUJBQW1CO0FBQ3RFOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsMkNBQTJDLFdBQVc7QUFDdEQseUNBQXlDLGlDQUFpQztBQUMxRSxnREFBZ0QsT0FBTyxXQUFXO0FBQ2xFO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSwyQ0FBMkMsV0FBVztBQUN0RDtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsT0FBTyxXQUFXO0FBQ2xFO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSwyQ0FBMkMsV0FBVztBQUN0RDtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsT0FBTyxXQUFXO0FBQ2xFO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLCtCQUErQjtBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2RkFBNkY7QUFDN0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsc0JBQXNCLFlBQVk7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaUNBQWlDO0FBQ2pDO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRDQUE0QyxvQkFBb0I7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQSxrQ0FBa0M7O0FBRWxDO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDBCQUEwQixvQkFBb0I7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUNBQW1DLHNCQUFzQjtBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixZQUFZO0FBQzdCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsc0JBQXNCLDRCQUE0QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBLHlDQUF5QztBQUN6QztBQUNBOztBQUVBO0FBQ0EsK0NBQStDOztBQUUvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsNEJBQTRCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQixxQkFBcUI7QUFDL0M7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsK0JBQStCLHlCQUF5QjtBQUN4RDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQyxxQkFBcUI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLHFCQUFxQjtBQUMzRDtBQUNBO0FBQ0EseUJBQXlCLFlBQVk7QUFDckMscUJBQXFCO0FBQ3JCLGlCQUFpQjs7QUFFakI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQyxxQkFBcUI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLHFCQUFxQjtBQUMzRDtBQUNBO0FBQ0EseUJBQXlCLFlBQVk7QUFDckMscUJBQXFCO0FBQ3JCLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekIscUJBQXFCO0FBQ3JCLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckIsaUJBQWlCOztBQUVqQjs7QUFFQTtBQUNBLGtEQUFrRCxpREFBaUQsRUFBRTtBQUNyRyxpQkFBaUI7O0FBRWpCO0FBQ0Esa0RBQWtELGtEQUFrRCxFQUFFO0FBQ3RHLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0QsbURBQW1ELEVBQUU7QUFDdkcsaUJBQWlCOztBQUVqQjtBQUNBLGtEQUFrRCxnREFBZ0QsRUFBRTtBQUNwRyxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQixpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7O0FBRXJCLCtCQUErQix3QkFBd0I7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsK0JBQStCLHNCQUFzQjtBQUNyRDs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQixpQkFBaUI7O0FBRWpCO0FBQ0Esa0RBQWtELHVDQUF1QyxFQUFFO0FBQzNGLGlCQUFpQjs7O0FBR2pCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0Esa0RBQWtELGtDQUFrQyxFQUFFO0FBQ3RGLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0QsbUNBQW1DLEVBQUU7QUFDdkYsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0Esa0RBQWtELGdDQUFnQyxFQUFFO0FBQ3BGLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7OztBQUdqQjs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsbUJBQW1CO0FBQ3REO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQ0FBbUMsbUJBQW1CO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EsaUJBQWlCOztBQUVqQjs7QUFFQTtBQUNBO0FBQ0EsK0JBQStCLHFCQUFxQjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQ0FBbUMsdUJBQXVCO0FBQzFEO0FBQ0EscUJBQXFCOztBQUVyQjtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBLGlCQUFpQjs7O0FBR2pCOztBQUVBO0FBQ0Esa0RBQWtELGtEQUFrRCxFQUFFO0FBQ3RHLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0QsMEJBQTBCLEVBQUU7QUFDOUU7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLE9BQU87QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOERBQThEO0FBQzlEOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0VBQWtFO0FBQ2xFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0ZBQW9GOztBQUVwRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBLG1EQUFtRCw4QkFBOEI7QUFDakY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRCw0Q0FBNEM7QUFDdkc7QUFDQTtBQUNBO0FBQ0EsK0RBQStELHlEQUF5RDtBQUN4SDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRFQUE0RTs7QUFFNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0RBQW9EOztBQUVwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLGFBQWE7O0FBRXRDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EscUJBQXFCO0FBQ3JCLGdEQUFnRCxlQUFlO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLG1EQUFtRCx1RUFBdUU7QUFDMUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEZBQTBGO0FBQzFGO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3Qix5QkFBeUIsWUFBWTtBQUNyQztBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDO0FBQ3JDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkMsbUNBQW1DO0FBQzlFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQyxpQ0FBaUM7QUFDakMsNkNBQTZDO0FBQzdDLHlDQUF5QztBQUN6QyxvQ0FBb0M7QUFDcEMscUNBQXFDO0FBQ3JDLG9DQUFvQztBQUNwQywyQ0FBMkM7QUFDM0Msd0NBQXdDO0FBQ3hDLDBDQUEwQztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7O0FBRXJCO0FBQ0EsOEJBQThCLDJCQUEyQjtBQUN6RDtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsdUJBQXVCO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QjtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RCxxREFBcUQ7QUFDOUc7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRUFBaUUsa0VBQWtFLGdCQUFnQjtBQUNuSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEZBQTBGO0FBQzFGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQztBQUNyQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQ0FBaUM7O0FBRWpDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQzs7QUFFakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCOztBQUV6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5Qjs7QUFFekI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyx5QkFBeUI7QUFDN0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0NBQW9DLDRCQUE0QjtBQUNoRTtBQUNBLHFCQUFxQjtBQUNyQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1DQUFtQyxpQkFBaUI7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBLHFCQUFxQjs7QUFFckI7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1QyxvQkFBb0I7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1JQUFtSTs7QUFFbkk7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLEVBQUU7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDREQUE0RDtBQUM1RDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDhGQUE4Rjs7QUFFOUY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDhGQUE4RjtBQUM5Rjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBEQUEwRDtBQUMxRDtBQUNBO0FBQ0EsOERBQThEOztBQUU5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwrQ0FBK0M7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkZBQTZGO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0ZBQW9GO0FBQ3BGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlFQUFpRSxXQUFXO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdMQUFnTDtBQUNoTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtREFBbUQsZ0JBQWdCO0FBQ25FOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0IseUJBQXlCO0FBQ3pCO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLEVBQUU7QUFDL0I7QUFDQTtBQUNBOztBQUVBLG1EQUFtRDtBQUNuRCwyREFBMkQ7O0FBRTNEO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7O0FBRTdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3RUFBd0U7QUFDeEU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxtSEFBbUg7QUFDbkg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0SEFBNEgsaUJBQWlCO0FBQzdJLHlCQUF5Qjs7O0FBR3pCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2SEFBNkgsaUJBQWlCO0FBQzlJLHlCQUF5Qjs7O0FBR3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtKQUFrSjtBQUNsSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhFQUE4RTtBQUM5RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSx3RkFBd0Y7QUFDeEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtSEFBbUg7O0FBRW5IO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsK05BQStOO0FBQy9OO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEhBQTBIO0FBQzFILGlIQUFpSDtBQUNqSDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QiwrRUFBK0U7QUFDN0c7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0RBQStELHFDQUFxQztBQUNwRzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBLG1EQUFtRCxtQkFBbUI7QUFDdEU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsT0FBTztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwwQkFBMEIsMkJBQTJCO0FBQ3JEO0FBQ0EsbUNBQW1DLDJCQUEyQjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMkJBQTJCLFFBQVE7QUFDbkMsMkJBQTJCLFFBQVE7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLHNCQUFzQjtBQUM3RDtBQUNBLDBEQUEwRDtBQUMxRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOEJBQThCLHNCQUFzQjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLE1BQU07QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLGVBQWU7QUFDOUM7QUFDQSwrQkFBK0IsZUFBZTtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4QkFBOEIsbUdBQW1HO0FBQ2pJO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsK0JBQStCLGlDQUFpQztBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLG1CQUFtQjtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQixrQkFBa0I7QUFDNUMsb0ZBQW9GO0FBQ3BGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJCQUEyQixTQUFTO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixrQjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsZ0JBQWdCO0FBQ3BEOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQ0FBZ0MsOEJBQThCO0FBQzlEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsbUNBQW1DLGtDQUFrQztBQUNyRTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsZUFBZTtBQUN0Qyx1QkFBdUIsb0JBQW9CO0FBQzNDLHVCQUF1QixlQUFlO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxxQkFBcUI7QUFDckQsNkJBQTZCLHFCQUFxQjtBQUNsRCwyQkFBMkIscUJBQXFCO0FBQ2hELG9DQUFvQyxxQkFBcUI7QUFDekQsb0NBQW9DLHFCQUFxQjtBQUN6RCx5Q0FBeUMscUJBQXFCO0FBQzlELGtDQUFrQyxxQkFBcUI7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsOEJBQThCO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRztBQUNBLHVDQUF1QyxnQ0FBZ0M7QUFDdkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyxvQkFBb0I7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyw4Q0FBOEM7QUFDakY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLEVBQUU7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsK0VBQStFLGtDQUFrQyxzQkFBc0Isa0NBQWtDLHFCQUFxQjtBQUM1TjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLHdIQUF3SDtBQUN0SjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0RBQW9EO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRDtBQUMzRCw0REFBNEQ7QUFDNUQsMENBQTBDO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRDtBQUNsRCxrQ0FBa0MsMkJBQTJCO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRDtBQUNyRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3REFBd0Q7QUFDeEQsOERBQThEO0FBQzlELDhEQUE4RDtBQUM5RCxzREFBc0Q7O0FBRXREO0FBQ0EsNENBQTRDOztBQUU1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esd0VBQXdFLG9DQUFvQyxFQUFFO0FBQzlHOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0VBQWtFLHFCQUFxQixFQUFFO0FBQ3pGO0FBQ0EsZ0VBQWdFLDBCQUEwQixFQUFFOztBQUU1RjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjs7QUFFckI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQ7QUFDdkQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0Q7O0FBRXBEO0FBQ0EsMEVBQTBFO0FBQzFFOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixRQUFRO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1ELHdDQUF3QztBQUMzRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQSw4QkFBOEIsbUNBQW1DO0FBQ2pFO0FBQ0E7QUFDQSxvRUFBb0U7QUFDcEU7QUFDQSxvRUFBb0UseUJBQXlCO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsRUFBRTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RCxtQ0FBbUMsRUFBRTtBQUM3RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMTA4NC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qIVxyXG4gKiBPdmVybGF5U2Nyb2xsYmFyc1xyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vS2luZ1NvcmEvT3ZlcmxheVNjcm9sbGJhcnNcclxuICpcclxuICogVmVyc2lvbjogMS4xMy4wXHJcbiAqXHJcbiAqIENvcHlyaWdodCBLaW5nU29yYSB8IFJlbmUgSGFhcy5cclxuICogaHR0cHM6Ly9naXRodWIuY29tL0tpbmdTb3JhXHJcbiAqXHJcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cclxuICogRGF0ZTogMDIuMDguMjAyMFxyXG4gKi9cclxuXHJcbihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XHJcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKVxyXG4gICAgICAgIGRlZmluZShmdW5jdGlvbiAoKSB7IHJldHVybiBmYWN0b3J5KGdsb2JhbCwgZ2xvYmFsLmRvY3VtZW50LCB1bmRlZmluZWQpOyB9KTtcclxuICAgIGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gJ29iamVjdCcpXHJcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KGdsb2JhbCwgZ2xvYmFsLmRvY3VtZW50LCB1bmRlZmluZWQpO1xyXG4gICAgZWxzZVxyXG4gICAgICAgIGZhY3RvcnkoZ2xvYmFsLCBnbG9iYWwuZG9jdW1lbnQsIHVuZGVmaW5lZCk7XHJcbn0odHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0aGlzLFxyXG4gICAgZnVuY3Rpb24gKHdpbmRvdywgZG9jdW1lbnQsIHVuZGVmaW5lZCkge1xyXG4gICAgICAgICd1c2Ugc3RyaWN0JztcclxuICAgICAgICB2YXIgUExVR0lOTkFNRSA9ICdPdmVybGF5U2Nyb2xsYmFycyc7XHJcbiAgICAgICAgdmFyIFRZUEVTID0ge1xyXG4gICAgICAgICAgICBvOiAnb2JqZWN0JyxcclxuICAgICAgICAgICAgZjogJ2Z1bmN0aW9uJyxcclxuICAgICAgICAgICAgYTogJ2FycmF5JyxcclxuICAgICAgICAgICAgczogJ3N0cmluZycsXHJcbiAgICAgICAgICAgIGI6ICdib29sZWFuJyxcclxuICAgICAgICAgICAgbjogJ251bWJlcicsXHJcbiAgICAgICAgICAgIHU6ICd1bmRlZmluZWQnLFxyXG4gICAgICAgICAgICB6OiAnbnVsbCdcclxuICAgICAgICAgICAgLy9kIDogJ2RhdGUnLFxyXG4gICAgICAgICAgICAvL2UgOiAnZXJyb3InLFxyXG4gICAgICAgICAgICAvL3IgOiAncmVnZXhwJyxcclxuICAgICAgICAgICAgLy95IDogJ3N5bWJvbCdcclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciBMRVhJQ09OID0ge1xyXG4gICAgICAgICAgICBjOiAnY2xhc3MnLFxyXG4gICAgICAgICAgICBzOiAnc3R5bGUnLFxyXG4gICAgICAgICAgICBpOiAnaWQnLFxyXG4gICAgICAgICAgICBsOiAnbGVuZ3RoJyxcclxuICAgICAgICAgICAgcDogJ3Byb3RvdHlwZScsXHJcbiAgICAgICAgICAgIHRpOiAndGFiaW5kZXgnLFxyXG4gICAgICAgICAgICBvSDogJ29mZnNldEhlaWdodCcsXHJcbiAgICAgICAgICAgIGNIOiAnY2xpZW50SGVpZ2h0JyxcclxuICAgICAgICAgICAgc0g6ICdzY3JvbGxIZWlnaHQnLFxyXG4gICAgICAgICAgICBvVzogJ29mZnNldFdpZHRoJyxcclxuICAgICAgICAgICAgY1c6ICdjbGllbnRXaWR0aCcsXHJcbiAgICAgICAgICAgIHNXOiAnc2Nyb2xsV2lkdGgnLFxyXG4gICAgICAgICAgICBoT1A6ICdoYXNPd25Qcm9wZXJ0eScsXHJcbiAgICAgICAgICAgIGJDUjogJ2dldEJvdW5kaW5nQ2xpZW50UmVjdCdcclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciBWRU5ET1JTID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy9odHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL0dsb3NzYXJ5L1ZlbmRvcl9QcmVmaXhcclxuICAgICAgICAgICAgdmFyIGpzQ2FjaGUgPSB7fTtcclxuICAgICAgICAgICAgdmFyIGNzc0NhY2hlID0ge307XHJcbiAgICAgICAgICAgIHZhciBjc3NQcmVmaXhlcyA9IFsnLXdlYmtpdC0nLCAnLW1vei0nLCAnLW8tJywgJy1tcy0nXTtcclxuICAgICAgICAgICAgdmFyIGpzUHJlZml4ZXMgPSBbJ1dlYktpdCcsICdNb3onLCAnTycsICdNUyddO1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBmaXJzdExldHRlclRvVXBwZXIoc3RyKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgX2Nzc1ByZWZpeGVzOiBjc3NQcmVmaXhlcyxcclxuICAgICAgICAgICAgICAgIF9qc1ByZWZpeGVzOiBqc1ByZWZpeGVzLFxyXG4gICAgICAgICAgICAgICAgX2Nzc1Byb3BlcnR5OiBmdW5jdGlvbiAobmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBjc3NDYWNoZVtuYW1lXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNzc0NhY2hlW0xFWElDT04uaE9QXShuYW1lKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHVwcGVyY2FzZWROYW1lID0gZmlyc3RMZXR0ZXJUb1VwcGVyKG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbG1TdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpW0xFWElDT04uc107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdFBvc3NpYmlsaXRpZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyVmVuZG9yV2l0aG91dERhc2hlcztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBjc3NQcmVmaXhlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyVmVuZG9yV2l0aG91dERhc2hlcyA9IGNzc1ByZWZpeGVzW2ldLnJlcGxhY2UoLy0vZywgJycpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRQb3NzaWJpbGl0aWVzID0gW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgLy90cmFuc2l0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3NQcmVmaXhlc1tpXSArIG5hbWUsIC8vLXdlYmtpdC10cmFuc2l0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyVmVuZG9yV2l0aG91dERhc2hlcyArIHVwcGVyY2FzZWROYW1lLCAvL3dlYmtpdFRyYW5zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0TGV0dGVyVG9VcHBlcihjdXJyVmVuZG9yV2l0aG91dERhc2hlcykgKyB1cHBlcmNhc2VkTmFtZSAvL1dlYmtpdFRyYW5zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2ID0gMDsgdiA8IHJlc3VsdFBvc3NpYmlsaXRpZXNbTEVYSUNPTi5sXTsgdisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxtU3R5bGVbcmVzdWx0UG9zc2liaWxpdGllc1t2XV0gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdFBvc3NpYmlsaXRpZXNbdl07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNzc0NhY2hlW25hbWVdID0gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgX2Nzc1Byb3BlcnR5VmFsdWU6IGZ1bmN0aW9uIChwcm9wZXJ0eSwgdmFsdWVzLCBzdWZmaXgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IHByb3BlcnR5ICsgJyAnICsgdmFsdWVzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBjc3NDYWNoZVtuYW1lXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNzc0NhY2hlW0xFWElDT04uaE9QXShuYW1lKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGR1bW15U3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVtMRVhJQ09OLnNdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3NzYmxlVmFsdWVzID0gdmFsdWVzLnNwbGl0KCcgJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByZXBhcmVkU3VmZml4ID0gc3VmZml4IHx8ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdiA9IC0xO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwcm9wO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IHBvc3NibGVWYWx1ZXNbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyB2IDwgVkVORE9SUy5fY3NzUHJlZml4ZXNbTEVYSUNPTi5sXTsgdisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wID0gdiA8IDAgPyBwb3NzYmxlVmFsdWVzW2ldIDogVkVORE9SUy5fY3NzUHJlZml4ZXNbdl0gKyBwb3NzYmxlVmFsdWVzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVtbXlTdHlsZS5jc3NUZXh0ID0gcHJvcGVydHkgKyAnOicgKyBwcm9wICsgcHJlcGFyZWRTdWZmaXg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZHVtbXlTdHlsZVtMRVhJQ09OLmxdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcHJvcDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY3NzQ2FjaGVbbmFtZV0gPSByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBfanNBUEk6IGZ1bmN0aW9uIChuYW1lLCBpc0ludGVyZmFjZSwgZmFsbGJhY2spIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGpzQ2FjaGVbbmFtZV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghanNDYWNoZVtMRVhJQ09OLmhPUF0obmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gd2luZG93W25hbWVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGpzUHJlZml4ZXNbTEVYSUNPTi5sXTsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0IHx8IHdpbmRvd1soaXNJbnRlcmZhY2UgPyBqc1ByZWZpeGVzW2ldIDoganNQcmVmaXhlc1tpXS50b0xvd2VyQ2FzZSgpKSArIGZpcnN0TGV0dGVyVG9VcHBlcihuYW1lKV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGpzQ2FjaGVbbmFtZV0gPSByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgfHwgZmFsbGJhY2s7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KSgpO1xyXG4gICAgICAgIHZhciBDT01QQVRJQklMSVRZID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgZnVuY3Rpb24gd2luZG93U2l6ZSh4KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4geCA/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")}}]);
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/ZmIzZiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBa0Q7QUFDUDtBQUNLO0FBQ0Y7QUFDSjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0Q7QUFDTDtBQUNPOztBQUU3QyxxQkFBcUIsZ0RBQWdELGdCQUFnQixzQkFBc0IsT0FBTywyQkFBMkIsMEJBQTBCLHlEQUF5RCwyQkFBMkIsRUFBRSxFQUFFLEVBQUUsZUFBZSxHQUFHLHdDQUF3Qzs7QUFFM1QscURBQXFELCtCQUErQiw4REFBOEQsWUFBWSxvQ0FBb0MsNkRBQTZELFlBQVksNkJBQTZCLE9BQU8sMkJBQTJCLDBDQUEwQyx3RUFBd0UsMkJBQTJCLEVBQUUsRUFBRSxlQUFlOztBQUUxZSwwREFBMEQsK0JBQStCLGlCQUFpQixzQ0FBc0MsWUFBWSxZQUFZLHVCQUF1QixPQUFPLHFCQUFxQiwwQ0FBMEMsMkJBQTJCLEVBQUUsZUFBZTs7QUFFdlI7QUFDd0I7O0FBRWxEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQSw0Q0FBNEM7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0JBQW9CLDZDQUFLO0FBQ3pCLG1CQUFtQiw2Q0FBSztBQUN4QixFQUFFLDZDQUFLO0FBQ1AseUJBQXlCLHlEQUFpQjtBQUMxQztBQUNBO0FBQ0EsVUFBVSx5REFBaUI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRSw2Q0FBSztBQUNQLFFBQVEseURBQWlCO0FBQ3pCO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRSw2Q0FBSztBQUNQLFFBQVEseURBQWlCO0FBQ3pCO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsc0JBQXNCLDZDQUFLO0FBQzNCO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRyxnQkFBZ0IsNkNBQUs7QUFDeEI7QUFDQSxHQUFHLGdCQUFnQiw2Q0FBSztBQUN4QjtBQUNBLEdBQUcsZUFBZSw2Q0FBSztBQUN2QjtBQUNBLEdBQUcsZUFBZSw2Q0FBSztBQUN2QjtBQUNBLEdBQUcsNEJBQTRCLDZDQUFLO0FBQ3BDO0FBQ0EsR0FBRyxlQUFlLDZDQUFLO0FBQ3ZCO0FBQ0EsR0FBRyxlQUFlLDZDQUFLO0FBQ3ZCO0FBQ0EsR0FBRyxrQkFBa0IsNkNBQUs7QUFDMUI7QUFDQSxHQUFHLGVBQWUsNkNBQUs7QUFDdkI7QUFDQSxHQUFHLGVBQWUsNkNBQUs7QUFDdkI7QUFDQSxHQUFHLGtCQUFrQiw2Q0FBSztBQUMxQjtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0EsTUFBTSx5REFBaUI7QUFDdkI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVlLHlGQUEwQiIsImZpbGUiOiIxMDA1LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnJlZ2V4cC5jb25zdHJ1Y3Rvci5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnJlZ2V4cC5leGVjLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMucmVnZXhwLnRvLXN0cmluZy5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5yZXBsYWNlLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMuYXJyYXkuam9pbi5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5LmZpbHRlci5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5zcGxpdC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5tYXRjaC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5LmNvbmNhdC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLm9iamVjdC5rZXlzLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMuc3ltYm9sLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMub2JqZWN0LmFzc2lnbi5qc1wiO1xuXG5mdW5jdGlvbiBfZXh0ZW5kcygpIHsgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9OyByZXR1cm4gX2V4dGVuZHMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfVxuXG5mdW5jdGlvbiBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMoc291cmNlLCBleGNsdWRlZCkgeyBpZiAoc291cmNlID09IG51bGwpIHJldHVybiB7fTsgdmFyIHRhcmdldCA9IF9vYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlKHNvdXJjZSwgZXhjbHVkZWQpOyB2YXIga2V5LCBpOyBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykgeyB2YXIgc291cmNlU3ltYm9sS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoc291cmNlKTsgZm9yIChpID0gMDsgaSA8IHNvdXJjZVN5bWJvbEtleXMubGVuZ3RoOyBpKyspIHsga2V5ID0gc291cmNlU3ltYm9sS2V5c1tpXTsgaWYgKGV4Y2x1ZGVkLmluZGV4T2Yoa2V5KSA+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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vL2hvbWUvamVua2lucy93b3Jrc3BhY2UvZGVzaWduLXN5c3RlbV9tYWluL25vZGVfbW9kdWxlcy9vdmVybGF5c2Nyb2xsYmFycy9qcy9PdmVybGF5U2Nyb2xsYmFycy5qcz83ODhiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFFBQVEsSUFBMEM7QUFDbEQsUUFBUSxtQ0FBTyxhQUFhLG9EQUFvRCxFQUFFO0FBQUEsb0dBQUM7QUFDbkYsU0FBUyxFQUcyQztBQUNwRCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMEJBQTBCLHdCQUF3QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxvQ0FBb0M7QUFDdkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQiw4QkFBOEI7QUFDeEQsOEJBQThCLHFDQUFxQztBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4QkFBOEIsMkJBQTJCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QztBQUN4QywwQ0FBMEMsNEdBQTRHOztBQUV0SjtBQUNBLDhDQUE4QztBQUM5Qzs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixjQUFjO0FBQzNDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QixjQUFjO0FBQzNDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLDZCQUE2QjtBQUMxRDtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsV0FBVztBQUN4QztBQUNBLDhGQUE4RiwyQ0FBMkMsRUFBRTs7QUFFM0k7QUFDQTtBQUNBLDZCQUE2QixXQUFXO0FBQ3hDO0FBQ0EsMkZBQTJGLGdDQUFnQyxFQUFFOztBQUU3SDtBQUNBO0FBQ0EsNkJBQTZCLE9BQU87QUFDcEM7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLHNCQUFzQjtBQUNwRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7QUFDQSxtQ0FBbUMsb0JBQW9CO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkM7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsT0FBTztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7O0FBR2pCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixZQUFZOztBQUV6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7O0FBR1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1EQUFtRCxtQkFBbUI7QUFDdEU7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSwyQ0FBMkMsV0FBVztBQUN0RCx5Q0FBeUMsaUNBQWlDO0FBQzFFLGdEQUFnRCxPQUFPLFdBQVc7QUFDbEU7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBLDJDQUEyQyxXQUFXO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCxPQUFPLFdBQVc7QUFDbEU7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBLDJDQUEyQyxXQUFXO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCxPQUFPLFdBQVc7QUFDbEU7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsK0JBQStCO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZGQUE2RjtBQUM3RjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxzQkFBc0IsWUFBWTtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQ0FBaUM7QUFDakM7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNENBQTRDLG9CQUFvQjtBQUNoRTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBLGtDQUFrQzs7QUFFbEM7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCLG9CQUFvQjtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQ0FBbUMsc0JBQXNCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFlBQVk7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxzQkFBc0IsNEJBQTRCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0EseUNBQXlDO0FBQ3pDO0FBQ0E7O0FBRUE7QUFDQSwrQ0FBK0M7O0FBRS9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQiw0QkFBNEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMEJBQTBCLHFCQUFxQjtBQUMvQztBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0IseUJBQXlCO0FBQ3hEOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLHFCQUFxQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MscUJBQXFCO0FBQzNEO0FBQ0E7QUFDQSx5QkFBeUIsWUFBWTtBQUNyQyxxQkFBcUI7QUFDckIsaUJBQWlCOztBQUVqQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLHFCQUFxQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MscUJBQXFCO0FBQzNEO0FBQ0E7QUFDQSx5QkFBeUIsWUFBWTtBQUNyQyxxQkFBcUI7QUFDckIsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QixxQkFBcUI7QUFDckIsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQixpQkFBaUI7O0FBRWpCOztBQUVBO0FBQ0Esa0RBQWtELGlEQUFpRCxFQUFFO0FBQ3JHLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0Qsa0RBQWtELEVBQUU7QUFDdEcsaUJBQWlCOztBQUVqQjtBQUNBLGtEQUFrRCxtREFBbUQsRUFBRTtBQUN2RyxpQkFBaUI7O0FBRWpCO0FBQ0Esa0RBQWtELGdEQUFnRCxFQUFFO0FBQ3BHLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjs7QUFFckIsK0JBQStCLHdCQUF3QjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0Isc0JBQXNCO0FBQ3JEOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0QsdUNBQXVDLEVBQUU7QUFDM0YsaUJBQWlCOzs7QUFHakI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0Qsa0NBQWtDLEVBQUU7QUFDdEYsaUJBQWlCOztBQUVqQjtBQUNBLGtEQUFrRCxtQ0FBbUMsRUFBRTtBQUN2RixpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0QsZ0NBQWdDLEVBQUU7QUFDcEYsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7O0FBR2pCOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxtQkFBbUI7QUFDdEQ7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1DQUFtQyxtQkFBbUI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxpQkFBaUI7O0FBRWpCOztBQUVBO0FBQ0E7QUFDQSwrQkFBK0IscUJBQXFCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1DQUFtQyx1QkFBdUI7QUFDMUQ7QUFDQSxxQkFBcUI7O0FBRXJCO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0EsaUJBQWlCOzs7QUFHakI7O0FBRUE7QUFDQSxrREFBa0Qsa0RBQWtELEVBQUU7QUFDdEcsaUJBQWlCOztBQUVqQjtBQUNBLGtEQUFrRCwwQkFBMEIsRUFBRTtBQUM5RTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsT0FBTztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQ7QUFDOUQ7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRUFBa0U7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxvRkFBb0Y7O0FBRXBGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QztBQUN6QztBQUNBO0FBQ0EsbURBQW1ELDhCQUE4QjtBQUNqRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMkRBQTJELDRDQUE0QztBQUN2RztBQUNBO0FBQ0E7QUFDQSwrREFBK0QseURBQXlEO0FBQ3hIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEVBQTRFOztBQUU1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxvREFBb0Q7O0FBRXBEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsYUFBYTs7QUFFdEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUI7QUFDckIsZ0RBQWdELGVBQWU7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EsbURBQW1ELHVFQUF1RTtBQUMxSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRkFBMEY7QUFDMUY7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCLHlCQUF5QixZQUFZO0FBQ3JDO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyxtQ0FBbUM7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLGlDQUFpQztBQUNqQyw2Q0FBNkM7QUFDN0MseUNBQXlDO0FBQ3pDLG9DQUFvQztBQUNwQyxxQ0FBcUM7QUFDckMsb0NBQW9DO0FBQ3BDLDJDQUEyQztBQUMzQyx3Q0FBd0M7QUFDeEMsMENBQTBDO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjs7QUFFckI7QUFDQSw4QkFBOEIsMkJBQTJCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBLDhCQUE4Qix1QkFBdUI7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlELHFEQUFxRDtBQUM5RztBQUNBO0FBQ0E7QUFDQTtBQUNBLGlFQUFpRSxrRUFBa0UsZ0JBQWdCO0FBQ25KO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRkFBMEY7QUFDMUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkM7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlDQUFpQzs7QUFFakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDOztBQUVqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7O0FBRXpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCOztBQUV6QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLHlCQUF5QjtBQUM3RDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQ0FBb0MsNEJBQTRCO0FBQ2hFO0FBQ0EscUJBQXFCO0FBQ3JCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUNBQW1DLGlCQUFpQjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0EscUJBQXFCOztBQUVyQjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLG9CQUFvQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUlBQW1JOztBQUVuSTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0MsRUFBRTtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNERBQTREO0FBQzVEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOEZBQThGOztBQUU5RjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOEZBQThGO0FBQzlGOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMERBQTBEO0FBQzFEO0FBQ0E7QUFDQSw4REFBOEQ7O0FBRTlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2RkFBNkY7QUFDN0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvRkFBb0Y7QUFDcEY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUVBQWlFLFdBQVc7QUFDNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0xBQWdMO0FBQ2hMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLG1EQUFtRCxnQkFBZ0I7QUFDbkU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3Qix5QkFBeUI7QUFDekI7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7O0FBRUEsbURBQW1EO0FBQ25ELDJEQUEyRDs7QUFFM0Q7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qjs7QUFFN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdFQUF3RTtBQUN4RTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1IQUFtSDtBQUNuSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRIQUE0SCxpQkFBaUI7QUFDN0kseUJBQXlCOzs7QUFHekI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZIQUE2SCxpQkFBaUI7QUFDOUkseUJBQXlCOzs7QUFHekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0pBQWtKO0FBQ2xKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEVBQThFO0FBQzlFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLHdGQUF3RjtBQUN4RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1IQUFtSDs7QUFFbkg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwrTkFBK047QUFDL047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwSEFBMEg7QUFDMUgsaUhBQWlIO0FBQ2pIOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLCtFQUErRTtBQUM3RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrREFBK0QscUNBQXFDO0FBQ3BHOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0EsbURBQW1ELG1CQUFtQjtBQUN0RTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDBCQUEwQiwyQkFBMkI7QUFDckQ7QUFDQSxtQ0FBbUMsMkJBQTJCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwyQkFBMkIsUUFBUTtBQUNuQywyQkFBMkIsUUFBUTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsc0JBQXNCO0FBQzdEO0FBQ0EsMERBQTBEO0FBQzFEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4QkFBOEIsc0JBQXNCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsTUFBTTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IsZUFBZTtBQUM5QztBQUNBLCtCQUErQixlQUFlO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDhCQUE4QixtR0FBbUc7QUFDakk7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwrQkFBK0IsaUNBQWlDO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QixFQUFFO0FBQy9CO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLE9BQU87QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixFQUFFO0FBQy9CO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixFQUFFO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsbUJBQW1CO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLGtCQUFrQjtBQUM1QyxvRkFBb0Y7QUFDcEY7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMkJBQTJCLFNBQVM7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixFQUFFO0FBQy9CO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLGtCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxnQkFBZ0I7QUFDcEQ7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdDQUFnQyw4QkFBOEI7QUFDOUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxtQ0FBbUMsa0NBQWtDO0FBQ3JFO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixlQUFlO0FBQ3RDLHVCQUF1QixvQkFBb0I7QUFDM0MsdUJBQXVCLGVBQWU7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHFCQUFxQjtBQUNyRCw2QkFBNkIscUJBQXFCO0FBQ2xELDJCQUEyQixxQkFBcUI7QUFDaEQsb0NBQW9DLHFCQUFxQjtBQUN6RCxvQ0FBb0MscUJBQXFCO0FBQ3pELHlDQUF5QyxxQkFBcUI7QUFDOUQsa0NBQWtDLHFCQUFxQjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyw4QkFBOEI7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJHO0FBQ0EsdUNBQXVDLGdDQUFnQztBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLG9CQUFvQjtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLDhDQUE4QztBQUNqRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QiwrRUFBK0Usa0NBQWtDLHNCQUFzQixrQ0FBa0MscUJBQXFCO0FBQzVOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsd0hBQXdIO0FBQ3RKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0Q7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJEO0FBQzNELDREQUE0RDtBQUM1RCwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0RBQWtEO0FBQ2xELGtDQUFrQywyQkFBMkI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFEO0FBQ3JEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RDtBQUN4RCw4REFBOEQ7QUFDOUQsOERBQThEO0FBQzlELHNEQUFzRDs7QUFFdEQ7QUFDQSw0Q0FBNEM7O0FBRTVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx3RUFBd0Usb0NBQW9DLEVBQUU7QUFDOUc7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRUFBa0UscUJBQXFCLEVBQUU7QUFDekY7QUFDQSxnRUFBZ0UsMEJBQTBCLEVBQUU7O0FBRTVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCOztBQUVyQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEQUF1RDtBQUN2RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRDs7QUFFcEQ7QUFDQSwwRUFBMEU7QUFDMUU7O0FBRUE7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLFFBQVE7QUFDakM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtREFBbUQsd0NBQXdDO0FBQzNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBLDhCQUE4QixtQ0FBbUM7QUFDakU7QUFDQTtBQUNBLG9FQUFvRTtBQUNwRTtBQUNBLG9FQUFvRSx5QkFBeUI7QUFDN0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixFQUFFO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0RBQXdELG1DQUFtQyxFQUFFO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiIxMDg0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyohXHJcbiAqIE92ZXJsYXlTY3JvbGxiYXJzXHJcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9LaW5nU29yYS9PdmVybGF5U2Nyb2xsYmFyc1xyXG4gKlxyXG4gKiBWZXJzaW9uOiAxLjEzLjBcclxuICpcclxuICogQ29weXJpZ2h0IEtpbmdTb3JhIHwgUmVuZSBIYWFzLlxyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vS2luZ1NvcmFcclxuICpcclxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxyXG4gKiBEYXRlOiAwMi4wOC4yMDIwXHJcbiAqL1xyXG5cclxuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcclxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXHJcbiAgICAgICAgZGVmaW5lKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZhY3RvcnkoZ2xvYmFsLCBnbG9iYWwuZG9jdW1lbnQsIHVuZGVmaW5lZCk7IH0pO1xyXG4gICAgZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZS5leHBvcnRzID09PSAnb2JqZWN0JylcclxuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoZ2xvYmFsLCBnbG9iYWwuZG9jdW1lbnQsIHVuZGVmaW5lZCk7XHJcbiAgICBlbHNlXHJcbiAgICAgICAgZmFjdG9yeShnbG9iYWwsIGdsb2JhbC5kb2N1bWVudCwgdW5kZWZpbmVkKTtcclxufSh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHRoaXMsXHJcbiAgICBmdW5jdGlvbiAod2luZG93LCBkb2N1bWVudCwgdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgJ3VzZSBzdHJpY3QnO1xyXG4gICAgICAgIHZhciBQTFVHSU5OQU1FID0gJ092ZXJsYXlTY3JvbGxiYXJzJztcclxuICAgICAgICB2YXIgVFlQRVMgPSB7XHJcbiAgICAgICAgICAgIG86ICdvYmplY3QnLFxyXG4gICAgICAgICAgICBmOiAnZnVuY3Rpb24nLFxyXG4gICAgICAgICAgICBhOiAnYXJyYXknLFxyXG4gICAgICAgICAgICBzOiAnc3RyaW5nJyxcclxuICAgICAgICAgICAgYjogJ2Jvb2xlYW4nLFxyXG4gICAgICAgICAgICBuOiAnbnVtYmVyJyxcclxuICAgICAgICAgICAgdTogJ3VuZGVmaW5lZCcsXHJcbiAgICAgICAgICAgIHo6ICdudWxsJ1xyXG4gICAgICAgICAgICAvL2QgOiAnZGF0ZScsXHJcbiAgICAgICAgICAgIC8vZSA6ICdlcnJvcicsXHJcbiAgICAgICAgICAgIC8vciA6ICdyZWdleHAnLFxyXG4gICAgICAgICAgICAvL3kgOiAnc3ltYm9sJ1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIExFWElDT04gPSB7XHJcbiAgICAgICAgICAgIGM6ICdjbGFzcycsXHJcbiAgICAgICAgICAgIHM6ICdzdHlsZScsXHJcbiAgICAgICAgICAgIGk6ICdpZCcsXHJcbiAgICAgICAgICAgIGw6ICdsZW5ndGgnLFxyXG4gICAgICAgICAgICBwOiAncHJvdG90eXBlJyxcclxuICAgICAgICAgICAgdGk6ICd0YWJpbmRleCcsXHJcbiAgICAgICAgICAgIG9IOiAnb2Zmc2V0SGVpZ2h0JyxcclxuICAgICAgICAgICAgY0g6ICdjbGllbnRIZWlnaHQnLFxyXG4gICAgICAgICAgICBzSDogJ3Njcm9sbEhlaWdodCcsXHJcbiAgICAgICAgICAgIG9XOiAnb2Zmc2V0V2lkdGgnLFxyXG4gICAgICAgICAgICBjVzogJ2NsaWVudFdpZHRoJyxcclxuICAgICAgICAgICAgc1c6ICdzY3JvbGxXaWR0aCcsXHJcbiAgICAgICAgICAgIGhPUDogJ2hhc093blByb3BlcnR5JyxcclxuICAgICAgICAgICAgYkNSOiAnZ2V0Qm91bmRpbmdDbGllbnRSZWN0J1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIFZFTkRPUlMgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvL2h0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvR2xvc3NhcnkvVmVuZG9yX1ByZWZpeFxyXG4gICAgICAgICAgICB2YXIganNDYWNoZSA9IHt9O1xyXG4gICAgICAgICAgICB2YXIgY3NzQ2FjaGUgPSB7fTtcclxuICAgICAgICAgICAgdmFyIGNzc1ByZWZpeGVzID0gWyctd2Via2l0LScsICctbW96LScsICctby0nLCAnLW1zLSddO1xyXG4gICAgICAgICAgICB2YXIganNQcmVmaXhlcyA9IFsnV2ViS2l0JywgJ01veicsICdPJywgJ01TJ107XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGZpcnN0TGV0dGVyVG9VcHBlcihzdHIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzdHIuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHIuc2xpY2UoMSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBfY3NzUHJlZml4ZXM6IGNzc1ByZWZpeGVzLFxyXG4gICAgICAgICAgICAgICAgX2pzUHJlZml4ZXM6IGpzUHJlZml4ZXMsXHJcbiAgICAgICAgICAgICAgICBfY3NzUHJvcGVydHk6IGZ1bmN0aW9uIChuYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGNzc0NhY2hlW25hbWVdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY3NzQ2FjaGVbTEVYSUNPTi5oT1BdKG5hbWUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgdXBwZXJjYXNlZE5hbWUgPSBmaXJzdExldHRlclRvVXBwZXIobmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsbVN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylbTEVYSUNPTi5zXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0UG9zc2liaWxpdGllcztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHY7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJWZW5kb3JXaXRob3V0RGFzaGVzO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGNzc1ByZWZpeGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJWZW5kb3JXaXRob3V0RGFzaGVzID0gY3NzUHJlZml4ZXNbaV0ucmVwbGFjZSgvLS9nLCAnJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFBvc3NpYmlsaXRpZXMgPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCAvL3RyYW5zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1ByZWZpeGVzW2ldICsgbmFtZSwgLy8td2Via2l0LXRyYW5zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJWZW5kb3JXaXRob3V0RGFzaGVzICsgdXBwZXJjYXNlZE5hbWUsIC8vd2Via2l0VHJhbnNpdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RMZXR0ZXJUb1VwcGVyKGN1cnJWZW5kb3JXaXRob3V0RGFzaGVzKSArIHVwcGVyY2FzZWROYW1lIC8vV2Via2l0VHJhbnNpdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHYgPSAwOyB2IDwgcmVzdWx0UG9zc2liaWxpdGllc1tMRVhJQ09OLmxdOyB2KyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbG1TdHlsZVtyZXN1bHRQb3NzaWJpbGl0aWVzW3ZdXSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0UG9zc2liaWxpdGllc1t2XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY3NzQ2FjaGVbbmFtZV0gPSByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBfY3NzUHJvcGVydHlWYWx1ZTogZnVuY3Rpb24gKHByb3BlcnR5LCB2YWx1ZXMsIHN1ZmZpeCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBuYW1lID0gcHJvcGVydHkgKyAnICcgKyB2YWx1ZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGNzc0NhY2hlW25hbWVdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY3NzQ2FjaGVbTEVYSUNPTi5oT1BdKG5hbWUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgZHVtbXlTdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpW0xFWElDT04uc107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvc3NibGVWYWx1ZXMgPSB2YWx1ZXMuc3BsaXQoJyAnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcHJlcGFyZWRTdWZmaXggPSBzdWZmaXggfHwgJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2ID0gLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByb3A7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgcG9zc2JsZVZhbHVlc1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IHYgPCBWRU5ET1JTLl9jc3NQcmVmaXhlc1tMRVhJQ09OLmxdOyB2KyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3AgPSB2IDwgMCA/IHBvc3NibGVWYWx1ZXNbaV0gOiBWRU5ET1JTLl9jc3NQcmVmaXhlc1t2XSArIHBvc3NibGVWYWx1ZXNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdW1teVN0eWxlLmNzc1RleHQgPSBwcm9wZXJ0eSArICc6JyArIHByb3AgKyBwcmVwYXJlZFN1ZmZpeDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkdW1teVN0eWxlW0xFWElDT04ubF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBwcm9wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBjc3NDYWNoZVtuYW1lXSA9IHJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIF9qc0FQSTogZnVuY3Rpb24gKG5hbWUsIGlzSW50ZXJmYWNlLCBmYWxsYmFjaykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0ganNDYWNoZVtuYW1lXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFqc0NhY2hlW0xFWElDT04uaE9QXShuYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB3aW5kb3dbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwganNQcmVmaXhlc1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgfHwgd2luZG93Wyhpc0ludGVyZmFjZSA/IGpzUHJlZml4ZXNbaV0gOiBqc1ByZWZpeGVzW2ldLnRvTG93ZXJDYXNlKCkpICsgZmlyc3RMZXR0ZXJUb1VwcGVyKG5hbWUpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAganNDYWNoZVtuYW1lXSA9IHJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCB8fCBmYWxsYmFjaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pKCk7XHJcbiAgICAgICAgdmFyIENPTVBBVElCSUxJVFkgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBmdW5jdGlvbiB3aW5kb3dTaXplKHgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB4ID8gd2luZG93LmlubmVyV2lkdGggfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50W0xFWElDT04uY1ddIHx8IGRvY3VtZW50LmJvZHlbTEVYSUNPTi5jV10gOiB3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50W0xFWElDT04uY0hdIHx8IGRvY3VtZW50LmJvZHlbTEVYSUNPTi5jSF07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZnVuY3Rpb24gYmluZChmdW5jLCB0aGlzT2JqKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gVFlQRVMuZikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFwiQ2FuJ3QgYmluZCBmdW5jdGlvbiFcIjtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjbG9zZXN0IHRoaW5nIHBvc3NpYmxlIHRvIHRoZSBFQ01BU2NyaXB0IDVcclxuICAgICAgICAgICAgICAgICAgICAvLyBpbnRlcm5hbCBJc0NhbGxhYmxlIGZ1bmN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgLy90aHJvdyBuZXcgVHlwZUVycm9yKCdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCAtIHdoYXQgaXMgdHJ5aW5nIHRvIGJlIGJvdW5kIGlzIG5vdCBjYWxsYWJsZScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIHByb3RvID0gTEVYSUNPTi5wO1xyXG4gICAgICAgICAgICAgICAgdmFyIGFBcmdzID0gQXJyYXlbcHJvdG9dLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcclxuICAgICAgICAgICAgICAgIHZhciBmTk9QID0gZnVuY3Rpb24gKCkgeyB9O1xyXG4gICAgICAgICAgICAgICAgdmFyIGZCb3VuZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcyBpbnN0YW5jZW9mIGZOT1AgPyB0aGlzIDogdGhpc09iaiwgYUFyZ3MuY29uY2F0KEFycmF5W3Byb3RvXS5zbGljZS5jYWxsKGFyZ3VtZW50cykpKTsgfTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoZnVuY1twcm90b10pXHJcbiAgICAgICAgICAgICAgICAgICAgZk5PUFtwcm90b10gPSBmdW5jW3Byb3RvXTsgLy8gRnVuY3Rpb24ucHJvdG90eXBlIGRvZXNuJ3QgaGF2ZSBhIHByb3RvdHlwZSBwcm9wZXJ0eVxyXG4gICAgICAgICAgICAgICAgZkJvdW5kW3Byb3RvXSA9IG5ldyBmTk9QKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZCb3VuZDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgY3VycmVudCB3aW5kb3cgd2lkdGguXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7TnVtYmVyfG51bWJlcn0gVGhlIGN1cnJlbnQgd2luZG93IHdpZHRoIGluIHBpeGVsLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICB3VzogYmluZCh3aW5kb3dTaXplLCAwLCB0cnVlKSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIGN1cnJlbnQgd2luZG93IGhlaWdodC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtOdW1iZXJ8bnVtYmVyfSBUaGUgY3VycmVudCB3aW5kb3cgaGVpZ2h0IGluIHBpeGVsLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICB3SDogYmluZCh3aW5kb3dTaXplLCAwKSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIE11dGF0aW9uT2JzZXJ2ZXIgT2JqZWN0IG9yIHVuZGVmaW5lZCBpZiBub3Qgc3VwcG9ydGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge011dGF0aW9uT2JzZXJ2ZXJ8Knx1bmRlZmluZWR9IFRoZSBNdXRhdGlvbnNPYnNlcnZlciBPYmplY3Qgb3IgdW5kZWZpbmVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBtTzogYmluZChWRU5ET1JTLl9qc0FQSSwgMCwgJ011dGF0aW9uT2JzZXJ2ZXInLCB0cnVlKSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIFJlc2l6ZU9ic2VydmVyIE9iamVjdCBvciB1bmRlZmluZWQgaWYgbm90IHN1cHBvcnRlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtNdXRhdGlvbk9ic2VydmVyfCp8dW5kZWZpbmVkfSBUaGUgUmVzaXplT2JzZXJ2ZXIgT2JqZWN0IG9yIHVuZGVmaW5lZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgck86IGJpbmQoVkVORE9SUy5fanNBUEksIDAsICdSZXNpemVPYnNlcnZlcicsIHRydWUpLFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgUmVxdWVzdEFuaW1hdGlvbkZyYW1lIG1ldGhvZCBvciBpdCdzIGNvcnJlc3BvbmRpbmcgcG9seWZpbGwuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7KnxGdW5jdGlvbn0gVGhlIFJlcXVlc3RBbmltYXRpb25GcmFtZSBtZXRob2Qgb3IgaXQncyBjb3JyZXNwb25kaW5nIHBvbHlmaWxsLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICByQUY6IGJpbmQoVkVORE9SUy5fanNBUEksIDAsICdyZXF1ZXN0QW5pbWF0aW9uRnJhbWUnLCBmYWxzZSwgZnVuY3Rpb24gKGZ1bmMpIHsgcmV0dXJuIHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmMsIDEwMDAgLyA2MCk7IH0pLFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgQ2FuY2VsQW5pbWF0aW9uRnJhbWUgbWV0aG9kIG9yIGl0J3MgY29ycmVzcG9uZGluZyBwb2x5ZmlsbC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfEZ1bmN0aW9ufSBUaGUgQ2FuY2VsQW5pbWF0aW9uRnJhbWUgbWV0aG9kIG9yIGl0J3MgY29ycmVzcG9uZGluZyBwb2x5ZmlsbC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgY0FGOiBiaW5kKFZFTkRPUlMuX2pzQVBJLCAwLCAnY2FuY2VsQW5pbWF0aW9uRnJhbWUnLCBmYWxzZSwgZnVuY3Rpb24gKGlkKSB7IHJldHVybiB3aW5kb3cuY2xlYXJUaW1lb3V0KGlkKTsgfSksXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHRpbWUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgY3VycmVudCB0aW1lLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBub3c6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGF0ZS5ub3cgJiYgRGF0ZS5ub3coKSB8fCBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBTdG9wcyB0aGUgcHJvcGFnYXRpb24gb2YgdGhlIGdpdmVuIGV2ZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50IFRoZSBldmVudCBvZiB3aGljaCB0aGUgcHJvcGFnYXRpb24gc2hhbGwgYmUgc3RvcGVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBzdHBQOiBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQuc3RvcFByb3BhZ2F0aW9uKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LmNhbmNlbEJ1YmJsZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUHJldmVudHMgdGhlIGRlZmF1bHQgYWN0aW9uIG9mIHRoZSBnaXZlbiBldmVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgb2Ygd2hpY2ggdGhlIGRlZmF1bHQgYWN0aW9uIHNoYWxsIGJlIHByZXZlbnRlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgcHJ2RDogZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50LnByZXZlbnREZWZhdWx0ICYmIGV2ZW50LmNhbmNlbGFibGUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIHBhZ2VYIGFuZCBwYWdlWSB2YWx1ZXMgb2YgdGhlIGdpdmVuIG1vdXNlIGV2ZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50IFRoZSBtb3VzZSBldmVudCBvZiB3aGljaCB0aGUgcGFnZVggYW5kIHBhZ2VYIHNoYWxsIGJlIGdvdC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7eDogbnVtYmVyLCB5OiBudW1iZXJ9fSB4ID0gcGFnZVggdmFsdWUsIHkgPSBwYWdlWSB2YWx1ZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgcGFnZTogZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSBldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyUGFnZSA9ICdwYWdlJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQ2xpZW50ID0gJ2NsaWVudCc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clggPSAnWCc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clkgPSAnWSc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhcmdldCA9IGV2ZW50LnRhcmdldCB8fCBldmVudC5zcmNFbGVtZW50IHx8IGRvY3VtZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBldmVudERvYyA9IHRhcmdldC5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkb2MgPSBldmVudERvYy5kb2N1bWVudEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJvZHkgPSBldmVudERvYy5ib2R5O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lmIHRvdWNoIGV2ZW50IHJldHVybiByZXR1cm4gcGFnZVgvWSBvZiBpdFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChldmVudC50b3VjaGVzICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRvdWNoID0gZXZlbnQudG91Y2hlc1swXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IHRvdWNoW3N0clBhZ2UgKyBzdHJYXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IHRvdWNoW3N0clBhZ2UgKyBzdHJZXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgcGFnZVgvWSBpZiBub3QgbmF0aXZlIHN1cHBvcnRlZFxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZXZlbnRbc3RyUGFnZSArIHN0clhdICYmIGV2ZW50W3N0ckNsaWVudCArIHN0clhdICYmIGV2ZW50W3N0ckNsaWVudCArIHN0clhdICE9IG51bGwpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBldmVudFtzdHJDbGllbnQgKyBzdHJYXSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRvYyAmJiBkb2Muc2Nyb2xsTGVmdCB8fCBib2R5ICYmIGJvZHkuc2Nyb2xsTGVmdCB8fCAwKSAtXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRvYyAmJiBkb2MuY2xpZW50TGVmdCB8fCBib2R5ICYmIGJvZHkuY2xpZW50TGVmdCB8fCAwKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGV2ZW50W3N0ckNsaWVudCArIHN0clldICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZG9jICYmIGRvYy5zY3JvbGxUb3AgfHwgYm9keSAmJiBib2R5LnNjcm9sbFRvcCB8fCAwKSAtXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRvYyAmJiBkb2MuY2xpZW50VG9wIHx8IGJvZHkgJiYgYm9keS5jbGllbnRUb3AgfHwgMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBldmVudFtzdHJQYWdlICsgc3RyWF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IGV2ZW50W3N0clBhZ2UgKyBzdHJZXVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgY2xpY2tlZCBtb3VzZSBidXR0b24gb2YgdGhlIGdpdmVuIG1vdXNlIGV2ZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50IFRoZSBtb3VzZSBldmVudCBvZiB3aGljaCB0aGUgY2xpY2tlZCBidXR0b24gc2hhbCBiZSBnb3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIHRoZSBjbGlja2VkIG1vdXNlIGJ1dHRvbi4gKDAgOiBub25lIHwgMSA6IGxlZnRCdXR0b24gfCAyIDogbWlkZGxlQnV0dG9uIHwgMyA6IHJpZ2h0QnV0dG9uKVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBtQnRuOiBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYnV0dG9uID0gZXZlbnQuYnV0dG9uO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZXZlbnQud2hpY2ggJiYgYnV0dG9uICE9PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoYnV0dG9uICYgMSA/IDEgOiAoYnV0dG9uICYgMiA/IDMgOiAoYnV0dG9uICYgNCA/IDIgOiAwKSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LndoaWNoO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENoZWNrcyB3aGV0aGVyIGEgaXRlbSBpcyBpbiB0aGUgZ2l2ZW4gYXJyYXkgYW5kIHJldHVybnMgaXRzIGluZGV4LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGl0ZW0gVGhlIGl0ZW0gb2Ygd2hpY2ggdGhlIHBvc2l0aW9uIGluIHRoZSBhcnJheSBzaGFsbCBiZSBkZXRlcm1pbmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGFyciBUaGUgYXJyYXkuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgemVybyBiYXNlZCBpbmRleCBvZiB0aGUgaXRlbSBvciAtMSBpZiB0aGUgaXRlbSBpc24ndCBpbiB0aGUgYXJyYXkuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGluQTogZnVuY3Rpb24gKGl0ZW0sIGFycikge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyW0xFWElDT04ubF07IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9Tb21ldGllbXMgaW4gSUUgYSBcIlNDUklQVDcwXCIgUGVybWlzc2lvbiBkZW5pZWQgZXJyb3Igb2NjdXJzIGlmIEhUTUwgZWxlbWVudHMgaW4gYSBpRnJhbWUgYXJlIGNvbXBhcmVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyW2ldID09PSBpdGVtKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7IH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyBhIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGFyciBUaGUgcG90ZW50aWFsIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGdpdmVuIHZhbHVlIGlzIGEgYXJyYXksIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgaXNBOiBmdW5jdGlvbiAoYXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRlZiA9IEFycmF5LmlzQXJyYXk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZiA/IGRlZihhcnIpIDogdGhpcy50eXBlKGFycikgPT0gVFlQRVMuYTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBEZXRlcm1pbmUgdGhlIGludGVybmFsIEphdmFTY3JpcHQgW1tDbGFzc11dIG9mIHRoZSBnaXZlbiBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gb2JqIFRoZSBvYmplY3Qgb2Ygd2hpY2ggdGhlIHR5cGUgc2hhbGwgYmUgZGV0ZXJtaW5lZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSB0eXBlIG9mIHRoZSBnaXZlbiBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIHR5cGU6IGZ1bmN0aW9uIChvYmopIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob2JqID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvYmogKyAnJztcclxuICAgICAgICAgICAgICAgICAgICBpZiAob2JqID09PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2JqICsgJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9iamVjdFtMRVhJQ09OLnBdLnRvU3RyaW5nLmNhbGwob2JqKS5yZXBsYWNlKC9eXFxbb2JqZWN0ICguKylcXF0kLywgJyQxJykudG9Mb3dlckNhc2UoKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG5cclxuICAgICAgICAgICAgICAgIGJpbmQ6IGJpbmRcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIHZlbmRvci1wcmVmaXhlZCBDU1MgcHJvcGVydHkgYnkgdGhlIGdpdmVuIG5hbWUuXHJcbiAgICAgICAgICAgICAgICAgKiBGb3IgZXhhbXBsZSB0aGUgZ2l2ZW4gbmFtZSBpcyBcInRyYW5zZm9ybVwiIGFuZCB5b3UncmUgdXNpbmcgYSBvbGQgRmlyZWZveCBicm93c2VyIHRoZW4gdGhlIHJldHVybmVkIHZhbHVlIHdvdWxkIGJlIFwiLW1vei10cmFuc2Zvcm1cIi5cclxuICAgICAgICAgICAgICAgICAqIElmIHRoZSBicm93c2VyIGRvZXNuJ3QgbmVlZCBhIHZlbmRvci1wcmVmaXgsIHRoZW4gdGhlIHJldHVybmVkIHN0cmluZyBpcyB0aGUgZ2l2ZW4gbmFtZS5cclxuICAgICAgICAgICAgICAgICAqIElmIHRoZSBicm93c2VyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgZ2l2ZW4gcHJvcGVydHkgbmFtZSBhdCBhbGwgKG5vdCBldmVuIHdpdGggYSB2ZW5kb3ItcHJlZml4KSB0aGUgcmV0dXJuZWQgdmFsdWUgaXMgbnVsbC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBwcm9wTmFtZSBUaGUgdW5wcmVmaXhlZCBDU1MgcHJvcGVydHkgbmFtZS5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gVGhlIHZlbmRvci1wcmVmaXhlZCBDU1MgcHJvcGVydHkgb3IgbnVsbCBpZiB0aGUgYnJvd3NlciBkb2Vzbid0IHN1cHBvcnQgdGhlIGdpdmVuIENTUyBwcm9wZXJ0eS5cclxuXHJcbiAgICAgICAgICAgICAgICBjc3NQcm9wOiBmdW5jdGlvbihwcm9wTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBWRU5ET1JTLl9jc3NQcm9wZXJ0eShwcm9wTmFtZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSkoKTtcclxuXHJcblxyXG4gICAgICAgIHZhciBNQVRIID0gTWF0aDtcclxuICAgICAgICB2YXIgSlFVRVJZID0gd2luZG93LmpRdWVyeTtcclxuICAgICAgICB2YXIgRUFTSU5HID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIF9lYXNpbmdzTWF0aCA9IHtcclxuICAgICAgICAgICAgICAgIHA6IE1BVEguUEksXHJcbiAgICAgICAgICAgICAgICBjOiBNQVRILmNvcyxcclxuICAgICAgICAgICAgICAgIHM6IE1BVEguc2luLFxyXG4gICAgICAgICAgICAgICAgdzogTUFUSC5wb3csXHJcbiAgICAgICAgICAgICAgICB0OiBNQVRILnNxcnQsXHJcbiAgICAgICAgICAgICAgICBuOiBNQVRILmFzaW4sXHJcbiAgICAgICAgICAgICAgICBhOiBNQVRILmFicyxcclxuICAgICAgICAgICAgICAgIG86IDEuNzAxNThcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8qXHJcbiAgICAgICAgICAgICB4IDogY3VycmVudCBwZXJjZW50ICgwIC0gMSksXHJcbiAgICAgICAgICAgICB0IDogY3VycmVudCB0aW1lIChkdXJhdGlvbiAqIHBlcmNlbnQpLFxyXG4gICAgICAgICAgICAgYiA6IHN0YXJ0IHZhbHVlIChmcm9tKSxcclxuICAgICAgICAgICAgIGMgOiBlbmQgdmFsdWUgKHRvKSxcclxuICAgICAgICAgICAgIGQgOiBkdXJhdGlvblxyXG5cclxuICAgICAgICAgICAgIGVhc2luZ05hbWUgOiBmdW5jdGlvbih4LCB0LCBiLCBjLCBkKSB7IHJldHVybiBlYXNlZFZhbHVlOyB9XHJcbiAgICAgICAgICAgICAqL1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIHN3aW5nOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAwLjUgLSBfZWFzaW5nc01hdGguYyh4ICogX2Vhc2luZ3NNYXRoLnApIC8gMjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBsaW5lYXI6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHg7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluUXVhZDogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqICh0IC89IGQpICogdCArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dFF1YWQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC1jICogKHQgLz0gZCkgKiAodCAtIDIpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5PdXRRdWFkOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKHQgLz0gZCAvIDIpIDwgMSkgPyBjIC8gMiAqIHQgKiB0ICsgYiA6IC1jIC8gMiAqICgoLS10KSAqICh0IC0gMikgLSAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluQ3ViaWM6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAodCAvPSBkKSAqIHQgKiB0ICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlT3V0Q3ViaWM6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAoKHQgPSB0IC8gZCAtIDEpICogdCAqIHQgKyAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0Q3ViaWM6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgodCAvPSBkIC8gMikgPCAxKSA/IGMgLyAyICogdCAqIHQgKiB0ICsgYiA6IGMgLyAyICogKCh0IC09IDIpICogdCAqIHQgKyAyKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluUXVhcnQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAodCAvPSBkKSAqIHQgKiB0ICogdCArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dFF1YXJ0OiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtYyAqICgodCA9IHQgLyBkIC0gMSkgKiB0ICogdCAqIHQgLSAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0UXVhcnQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgodCAvPSBkIC8gMikgPCAxKSA/IGMgLyAyICogdCAqIHQgKiB0ICogdCArIGIgOiAtYyAvIDIgKiAoKHQgLT0gMikgKiB0ICogdCAqIHQgLSAyKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluUXVpbnQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAodCAvPSBkKSAqIHQgKiB0ICogdCAqIHQgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRRdWludDogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqICgodCA9IHQgLyBkIC0gMSkgKiB0ICogdCAqIHQgKiB0ICsgMSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbk91dFF1aW50OiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKHQgLz0gZCAvIDIpIDwgMSkgPyBjIC8gMiAqIHQgKiB0ICogdCAqIHQgKiB0ICsgYiA6IGMgLyAyICogKCh0IC09IDIpICogdCAqIHQgKiB0ICogdCArIDIpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5TaW5lOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtYyAqIF9lYXNpbmdzTWF0aC5jKHQgLyBkICogKF9lYXNpbmdzTWF0aC5wIC8gMikpICsgYyArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dFNpbmU6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiBfZWFzaW5nc01hdGgucyh0IC8gZCAqIChfZWFzaW5nc01hdGgucCAvIDIpKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0U2luZTogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLWMgLyAyICogKF9lYXNpbmdzTWF0aC5jKF9lYXNpbmdzTWF0aC5wICogdCAvIGQpIC0gMSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbkV4cG86IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh0ID09IDApID8gYiA6IGMgKiBfZWFzaW5nc01hdGgudygyLCAxMCAqICh0IC8gZCAtIDEpKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dEV4cG86IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh0ID09IGQpID8gYiArIGMgOiBjICogKC1fZWFzaW5nc01hdGgudygyLCAtMTAgKiB0IC8gZCkgKyAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0RXhwbzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSAwKSByZXR1cm4gYjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSBkKSByZXR1cm4gYiArIGM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCh0IC89IGQgLyAyKSA8IDEpIHJldHVybiBjIC8gMiAqIF9lYXNpbmdzTWF0aC53KDIsIDEwICogKHQgLSAxKSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjIC8gMiAqICgtX2Vhc2luZ3NNYXRoLncoMiwgLTEwICogLS10KSArIDIpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5DaXJjOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtYyAqIChfZWFzaW5nc01hdGgudCgxIC0gKHQgLz0gZCkgKiB0KSAtIDEpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlT3V0Q2lyYzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqIF9lYXNpbmdzTWF0aC50KDEgLSAodCA9IHQgLyBkIC0gMSkgKiB0KSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0Q2lyYzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCh0IC89IGQgLyAyKSA8IDEpID8gLWMgLyAyICogKF9lYXNpbmdzTWF0aC50KDEgLSB0ICogdCkgLSAxKSArIGIgOiBjIC8gMiAqIChfZWFzaW5nc01hdGgudCgxIC0gKHQgLT0gMikgKiB0KSArIDEpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5FbGFzdGljOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzID0gX2Vhc2luZ3NNYXRoLm87IHZhciBwID0gMDsgdmFyIGEgPSBjO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ID09IDApIHJldHVybiBiOyBpZiAoKHQgLz0gZCkgPT0gMSkgcmV0dXJuIGIgKyBjOyBpZiAoIXApIHAgPSBkICogLjM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGEgPCBfZWFzaW5nc01hdGguYShjKSkgeyBhID0gYzsgcyA9IHAgLyA0OyB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBzID0gcCAvICgyICogX2Vhc2luZ3NNYXRoLnApICogX2Vhc2luZ3NNYXRoLm4oYyAvIGEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtKGEgKiBfZWFzaW5nc01hdGgudygyLCAxMCAqICh0IC09IDEpKSAqIF9lYXNpbmdzTWF0aC5zKCh0ICogZCAtIHMpICogKDIgKiBfZWFzaW5nc01hdGgucCkgLyBwKSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRFbGFzdGljOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzID0gX2Vhc2luZ3NNYXRoLm87IHZhciBwID0gMDsgdmFyIGEgPSBjO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ID09IDApIHJldHVybiBiO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgodCAvPSBkKSA9PSAxKSByZXR1cm4gYiArIGM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFwKSBwID0gZCAqIC4zO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhIDwgX2Vhc2luZ3NNYXRoLmEoYykpIHsgYSA9IGM7IHMgPSBwIC8gNDsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgcyA9IHAgLyAoMiAqIF9lYXNpbmdzTWF0aC5wKSAqIF9lYXNpbmdzTWF0aC5uKGMgLyBhKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYSAqIF9lYXNpbmdzTWF0aC53KDIsIC0xMCAqIHQpICogX2Vhc2luZ3NNYXRoLnMoKHQgKiBkIC0gcykgKiAoMiAqIF9lYXNpbmdzTWF0aC5wKSAvIHApICsgYyArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0RWxhc3RpYzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcyA9IF9lYXNpbmdzTWF0aC5vOyB2YXIgcCA9IDA7IHZhciBhID0gYztcclxuICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSAwKSByZXR1cm4gYjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKHQgLz0gZCAvIDIpID09IDIpIHJldHVybiBiICsgYztcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXApIHAgPSBkICogKC4zICogMS41KTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYSA8IF9lYXNpbmdzTWF0aC5hKGMpKSB7IGEgPSBjOyBzID0gcCAvIDQ7IH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHMgPSBwIC8gKDIgKiBfZWFzaW5nc01hdGgucCkgKiBfZWFzaW5nc01hdGgubihjIC8gYSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgPCAxKSByZXR1cm4gLS41ICogKGEgKiBfZWFzaW5nc01hdGgudygyLCAxMCAqICh0IC09IDEpKSAqIF9lYXNpbmdzTWF0aC5zKCh0ICogZCAtIHMpICogKDIgKiBfZWFzaW5nc01hdGgucCkgLyBwKSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhICogX2Vhc2luZ3NNYXRoLncoMiwgLTEwICogKHQgLT0gMSkpICogX2Vhc2luZ3NNYXRoLnMoKHQgKiBkIC0gcykgKiAoMiAqIF9lYXNpbmdzTWF0aC5wKSAvIHApICogLjUgKyBjICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5CYWNrOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCwgcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHMgPSBzIHx8IF9lYXNpbmdzTWF0aC5vO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogKHQgLz0gZCkgKiB0ICogKChzICsgMSkgKiB0IC0gcykgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRCYWNrOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCwgcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHMgPSBzIHx8IF9lYXNpbmdzTWF0aC5vO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogKCh0ID0gdCAvIGQgLSAxKSAqIHQgKiAoKHMgKyAxKSAqIHQgKyBzKSArIDEpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5PdXRCYWNrOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCwgcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHMgPSBzIHx8IF9lYXNpbmdzTWF0aC5vO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKHQgLz0gZCAvIDIpIDwgMSkgPyBjIC8gMiAqICh0ICogdCAqICgoKHMgKj0gKDEuNTI1KSkgKyAxKSAqIHQgLSBzKSkgKyBiIDogYyAvIDIgKiAoKHQgLT0gMikgKiB0ICogKCgocyAqPSAoMS41MjUpKSArIDEpICogdCArIHMpICsgMikgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbkJvdW5jZTogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAtIHRoaXMuZWFzZU91dEJvdW5jZSh4LCBkIC0gdCwgMCwgYywgZCkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRCb3VuY2U6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG8gPSA3LjU2MjU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCh0IC89IGQpIDwgKDEgLyAyLjc1KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqIChvICogdCAqIHQpICsgYjtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHQgPCAoMiAvIDIuNzUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogKG8gKiAodCAtPSAoMS41IC8gMi43NSkpICogdCArIC43NSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodCA8ICgyLjUgLyAyLjc1KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqIChvICogKHQgLT0gKDIuMjUgLyAyLjc1KSkgKiB0ICsgLjkzNzUpICsgYjtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqIChvICogKHQgLT0gKDIuNjI1IC8gMi43NSkpICogdCArIC45ODQzNzUpICsgYjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0Qm91bmNlOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAodCA8IGQgLyAyKSA/IHRoaXMuZWFzZUluQm91bmNlKHgsIHQgKiAyLCAwLCBjLCBkKSAqIC41ICsgYiA6IHRoaXMuZWFzZU91dEJvdW5jZSh4LCB0ICogMiAtIGQsIDAsIGMsIGQpICogLjUgKyBjICogLjUgKyBiO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAvKlxyXG4gICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgKiBURVJNUyBPRiBVU0UgLSBFQVNJTkcgRVFVQVRJT05TXHJcbiAgICAgICAgICAgICAqIFxyXG4gICAgICAgICAgICAgKiBPcGVuIHNvdXJjZSB1bmRlciB0aGUgQlNEIExpY2Vuc2UuIFxyXG4gICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICogQ29weXJpZ2h0IMOCwqkgMjAwMSBSb2JlcnQgUGVubmVyXHJcbiAgICAgICAgICAgICAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbiAgICAgICAgICAgICAqIFxyXG4gICAgICAgICAgICAgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLCBcclxuICAgICAgICAgICAgICogYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxyXG4gICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgXHJcbiAgICAgICAgICAgICAqIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cclxuICAgICAgICAgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3QgXHJcbiAgICAgICAgICAgICAqIG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIFxyXG4gICAgICAgICAgICAgKiBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXHJcbiAgICAgICAgICAgICAqIFxyXG4gICAgICAgICAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBhdXRob3Igbm9yIHRoZSBuYW1lcyBvZiBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBcclxuICAgICAgICAgICAgICogb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cclxuICAgICAgICAgICAgICogXHJcbiAgICAgICAgICAgICAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORCBBTlkgXHJcbiAgICAgICAgICAgICAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRlxyXG4gICAgICAgICAgICAgKiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcclxuICAgICAgICAgICAgICogIENPUFlSSUdIVCBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCxcclxuICAgICAgICAgICAgICogIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURVxyXG4gICAgICAgICAgICAgKiAgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIFxyXG4gICAgICAgICAgICAgKiBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElOR1xyXG4gICAgICAgICAgICAgKiAgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgXHJcbiAgICAgICAgICAgICAqIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4gXHJcbiAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgIH0pKCk7XHJcbiAgICAgICAgdmFyIEZSQU1FV09SSyA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBfcm5vdGh0bWx3aGl0ZSA9ICgvW15cXHgyMFxcdFxcclxcblxcZl0rL2cpO1xyXG4gICAgICAgICAgICB2YXIgX3N0clNwYWNlID0gJyAnO1xyXG4gICAgICAgICAgICB2YXIgX3N0ckVtcHR5ID0gJyc7XHJcbiAgICAgICAgICAgIHZhciBfc3RyU2Nyb2xsTGVmdCA9ICdzY3JvbGxMZWZ0JztcclxuICAgICAgICAgICAgdmFyIF9zdHJTY3JvbGxUb3AgPSAnc2Nyb2xsVG9wJztcclxuICAgICAgICAgICAgdmFyIF9hbmltYXRpb25zID0gW107XHJcbiAgICAgICAgICAgIHZhciBfdHlwZSA9IENPTVBBVElCSUxJVFkudHlwZTtcclxuICAgICAgICAgICAgdmFyIF9jc3NOdW1iZXIgPSB7XHJcbiAgICAgICAgICAgICAgICBhbmltYXRpb25JdGVyYXRpb25Db3VudDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGNvbHVtbkNvdW50OiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgZmlsbE9wYWNpdHk6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBmbGV4R3JvdzogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGZsZXhTaHJpbms6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgbGluZUhlaWdodDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBvcmRlcjogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIG9ycGhhbnM6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB3aWRvd3M6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB6SW5kZXg6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB6b29tOiB0cnVlXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBleHRlbmQoKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgc3JjLCBjb3B5SXNBcnJheSwgY29weSwgbmFtZSwgb3B0aW9ucywgY2xvbmUsIHRhcmdldCA9IGFyZ3VtZW50c1swXSB8fCB7fSxcclxuICAgICAgICAgICAgICAgICAgICBpID0gMSxcclxuICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSBhcmd1bWVudHNbTEVYSUNPTi5sXSxcclxuICAgICAgICAgICAgICAgICAgICBkZWVwID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gSGFuZGxlIGEgZGVlcCBjb3B5IHNpdHVhdGlvblxyXG4gICAgICAgICAgICAgICAgaWYgKF90eXBlKHRhcmdldCkgPT0gVFlQRVMuYikge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZXAgPSB0YXJnZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gYXJndW1lbnRzWzFdIHx8IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHNraXAgdGhlIGJvb2xlYW4gYW5kIHRoZSB0YXJnZXRcclxuICAgICAgICAgICAgICAgICAgICBpID0gMjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBIYW5kbGUgY2FzZSB3aGVuIHRhcmdldCBpcyBhIHN0cmluZyBvciBzb21ldGhpbmcgKHBvc3NpYmxlIGluIGRlZXAgY29weSlcclxuICAgICAgICAgICAgICAgIGlmIChfdHlwZSh0YXJnZXQpICE9IFRZUEVTLm8gJiYgIV90eXBlKHRhcmdldCkgPT0gVFlQRVMuZikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIGV4dGVuZCBqUXVlcnkgaXRzZWxmIGlmIG9ubHkgb25lIGFyZ3VtZW50IGlzIHBhc3NlZFxyXG4gICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA9PT0gaSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IEZha2VqUXVlcnk7XHJcbiAgICAgICAgICAgICAgICAgICAgLS1pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGRlYWwgd2l0aCBub24tbnVsbC91bmRlZmluZWQgdmFsdWVzXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChvcHRpb25zID0gYXJndW1lbnRzW2ldKSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV4dGVuZCB0aGUgYmFzZSBvYmplY3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChuYW1lIGluIG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyYyA9IHRhcmdldFtuYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHkgPSBvcHRpb25zW25hbWVdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFByZXZlbnQgbmV2ZXItZW5kaW5nIGxvb3BcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQgPT09IGNvcHkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZWN1cnNlIGlmIHdlJ3JlIG1lcmdpbmcgcGxhaW4gb2JqZWN0cyBvciBhcnJheXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZWVwICYmIGNvcHkgJiYgKGlzUGxhaW5PYmplY3QoY29weSkgfHwgKGNvcHlJc0FycmF5ID0gQ09NUEFUSUJJTElUWS5pc0EoY29weSkpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb3B5SXNBcnJheSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5SXNBcnJheSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9uZSA9IHNyYyAmJiBDT01QQVRJQklMSVRZLmlzQShzcmMpID8gc3JjIDogW107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb25lID0gc3JjICYmIGlzUGxhaW5PYmplY3Qoc3JjKSA/IHNyYyA6IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTmV2ZXIgbW92ZSBvcmlnaW5hbCBvYmplY3RzLCBjbG9uZSB0aGVtXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W25hbWVdID0gZXh0ZW5kKGRlZXAsIGNsb25lLCBjb3B5KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG9uJ3QgYnJpbmcgaW4gdW5kZWZpbmVkIHZhbHVlc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb3B5ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRbbmFtZV0gPSBjb3B5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIFJldHVybiB0aGUgbW9kaWZpZWQgb2JqZWN0XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0O1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gaW5BcnJheShpdGVtLCBhcnIsIGZyb21JbmRleCkge1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IGZyb21JbmRleCB8fCAwOyBpIDwgYXJyW0xFWElDT04ubF07IGkrKylcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXJyW2ldID09PSBpdGVtKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcclxuICAgICAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gaXNGdW5jdGlvbihvYmopIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBfdHlwZShvYmopID09IFRZUEVTLmY7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBpc0VtcHR5T2JqZWN0KG9iaikge1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBvYmopXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBpc1BsYWluT2JqZWN0KG9iaikge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFvYmogfHwgX3R5cGUob2JqKSAhPSBUWVBFUy5vKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICB2YXIga2V5O1xyXG4gICAgICAgICAgICAgICAgdmFyIHByb3RvID0gTEVYSUNPTi5wO1xyXG4gICAgICAgICAgICAgICAgdmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0W3Byb3RvXS5oYXNPd25Qcm9wZXJ0eTtcclxuICAgICAgICAgICAgICAgIHZhciBoYXNPd25Db25zdHJ1Y3RvciA9IGhhc093blByb3BlcnR5LmNhbGwob2JqLCAnY29uc3RydWN0b3InKTtcclxuICAgICAgICAgICAgICAgIHZhciBoYXNJc1Byb3RvdHlwZU9mID0gb2JqLmNvbnN0cnVjdG9yICYmIG9iai5jb25zdHJ1Y3Rvcltwcm90b10gJiYgaGFzT3duUHJvcGVydHkuY2FsbChvYmouY29uc3RydWN0b3JbcHJvdG9dLCAnaXNQcm90b3R5cGVPZicpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChvYmouY29uc3RydWN0b3IgJiYgIWhhc093bkNvbnN0cnVjdG9yICYmICFoYXNJc1Byb3RvdHlwZU9mKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiBvYmopIHsgLyoqLyB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIF90eXBlKGtleSkgPT0gVFlQRVMudSB8fCBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGVhY2gob2JqLCBjYWxsYmFjaykge1xyXG4gICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChpc0FycmF5TGlrZShvYmopKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBvYmpbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjay5jYWxsKG9ialtpXSwgaSwgb2JqW2ldKSA9PT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgaW4gb2JqKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjay5jYWxsKG9ialtpXSwgaSwgb2JqW2ldKSA9PT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iajtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGlzQXJyYXlMaWtlKG9iaikge1xyXG4gICAgICAgICAgICAgICAgdmFyIGxlbmd0aCA9ICEhb2JqICYmIFtMRVhJQ09OLmxdIGluIG9iaiAmJiBvYmpbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgIHZhciB0ID0gX3R5cGUob2JqKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKHQpID8gZmFsc2UgOiAodCA9PSBUWVBFUy5hIHx8IGxlbmd0aCA9PT0gMCB8fCBfdHlwZShsZW5ndGgpID09IFRZUEVTLm4gJiYgbGVuZ3RoID4gMCAmJiAobGVuZ3RoIC0gMSkgaW4gb2JqKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gc3RyaXBBbmRDb2xsYXBzZSh2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHRva2VucyA9IHZhbHVlLm1hdGNoKF9ybm90aHRtbHdoaXRlKSB8fCBbXTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0b2tlbnMuam9pbihfc3RyU3BhY2UpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBtYXRjaGVzKGVsZW0sIHNlbGVjdG9yKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbm9kZUxpc3QgPSAoZWxlbS5wYXJlbnROb2RlIHx8IGRvY3VtZW50KS5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSB8fCBbXTtcclxuICAgICAgICAgICAgICAgIHZhciBpID0gbm9kZUxpc3RbTEVYSUNPTi5sXTtcclxuXHJcbiAgICAgICAgICAgICAgICB3aGlsZSAoaS0tKVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlTGlzdFtpXSA9PSBlbGVtKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGluc2VydEFkamFjZW50RWxlbWVudChlbCwgc3RyYXRlZ3ksIGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoQ09NUEFUSUJJTElUWS5pc0EoY2hpbGQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZFtMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydEFkamFjZW50RWxlbWVudChlbCwgc3RyYXRlZ3ksIGNoaWxkW2ldKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKF90eXBlKGNoaWxkKSA9PSBUWVBFUy5zKVxyXG4gICAgICAgICAgICAgICAgICAgIGVsLmluc2VydEFkamFjZW50SFRNTChzdHJhdGVneSwgY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIGVsLmluc2VydEFkamFjZW50RWxlbWVudChzdHJhdGVneSwgY2hpbGQubm9kZVR5cGUgPyBjaGlsZCA6IGNoaWxkWzBdKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gc2V0Q1NTVmFsKGVsLCBwcm9wLCB2YWwpIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVsW0xFWElDT04uc11bcHJvcF0gIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxbTEVYSUNPTi5zXVtwcm9wXSA9IHBhcnNlQ1NTVmFsKHByb3AsIHZhbCk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7IH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gcGFyc2VDU1NWYWwocHJvcCwgdmFsKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIV9jc3NOdW1iZXJbcHJvcC50b0xvd2VyQ2FzZSgpXSAmJiBfdHlwZSh2YWwpID09IFRZUEVTLm4pXHJcbiAgICAgICAgICAgICAgICAgICAgdmFsICs9ICdweCc7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBzdGFydE5leHRBbmltYXRpb25JblEoYW5pbU9iaiwgcmVtb3ZlRnJvbVEpIHtcclxuICAgICAgICAgICAgICAgIHZhciBpbmRleDtcclxuICAgICAgICAgICAgICAgIHZhciBuZXh0QW5pbTtcclxuICAgICAgICAgICAgICAgIGlmIChyZW1vdmVGcm9tUSAhPT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgYW5pbU9iai5xLnNwbGljZSgwLCAxKTtcclxuICAgICAgICAgICAgICAgIGlmIChhbmltT2JqLnFbTEVYSUNPTi5sXSA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBuZXh0QW5pbSA9IGFuaW1PYmoucVswXTtcclxuICAgICAgICAgICAgICAgICAgICBhbmltYXRlKGFuaW1PYmouZWwsIG5leHRBbmltLnByb3BzLCBuZXh0QW5pbS5kdXJhdGlvbiwgbmV4dEFuaW0uZWFzaW5nLCBuZXh0QW5pbS5jb21wbGV0ZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpbmRleCA9IGluQXJyYXkoYW5pbU9iaiwgX2FuaW1hdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYW5pbWF0aW9ucy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBzZXRBbmltYXRpb25WYWx1ZShlbCwgcHJvcCwgdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIGlmIChwcm9wID09PSBfc3RyU2Nyb2xsTGVmdCB8fCBwcm9wID09PSBfc3RyU2Nyb2xsVG9wKVxyXG4gICAgICAgICAgICAgICAgICAgIGVsW3Byb3BdID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0Q1NTVmFsKGVsLCBwcm9wLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGFuaW1hdGUoZWwsIHByb3BzLCBvcHRpb25zLCBlYXNpbmcsIGNvbXBsZXRlLCBndWFyYW50ZWVkTmV4dCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGhhc09wdGlvbnMgPSBpc1BsYWluT2JqZWN0KG9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGZyb20gPSB7fTtcclxuICAgICAgICAgICAgICAgIHZhciB0byA9IHt9O1xyXG4gICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgdmFyIGtleTtcclxuICAgICAgICAgICAgICAgIHZhciBhbmltT2JqO1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0YXJ0O1xyXG4gICAgICAgICAgICAgICAgdmFyIHByb2dyZXNzO1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0ZXA7XHJcbiAgICAgICAgICAgICAgICB2YXIgc3BlY2lhbEVhc2luZztcclxuICAgICAgICAgICAgICAgIHZhciBkdXJhdGlvbjtcclxuICAgICAgICAgICAgICAgIGlmIChoYXNPcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWFzaW5nID0gb3B0aW9ucy5lYXNpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnQgPSBvcHRpb25zLnN0YXJ0O1xyXG4gICAgICAgICAgICAgICAgICAgIHByb2dyZXNzID0gb3B0aW9ucy5wcm9ncmVzcztcclxuICAgICAgICAgICAgICAgICAgICBzdGVwID0gb3B0aW9ucy5zdGVwO1xyXG4gICAgICAgICAgICAgICAgICAgIHNwZWNpYWxFYXNpbmcgPSBvcHRpb25zLnNwZWNpYWxFYXNpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGUgPSBvcHRpb25zLmNvbXBsZXRlO1xyXG4gICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gb3B0aW9ucy5kdXJhdGlvbjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IG9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICBzcGVjaWFsRWFzaW5nID0gc3BlY2lhbEVhc2luZyB8fCB7fTtcclxuICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gZHVyYXRpb24gfHwgNDAwO1xyXG4gICAgICAgICAgICAgICAgZWFzaW5nID0gZWFzaW5nIHx8ICdzd2luZyc7XHJcbiAgICAgICAgICAgICAgICBndWFyYW50ZWVkTmV4dCA9IGd1YXJhbnRlZWROZXh0IHx8IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgX2FuaW1hdGlvbnNbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9hbmltYXRpb25zW2ldLmVsID09PSBlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhbmltT2JqID0gX2FuaW1hdGlvbnNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWFuaW1PYmopIHtcclxuICAgICAgICAgICAgICAgICAgICBhbmltT2JqID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbDogZWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHE6IFtdXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBfYW5pbWF0aW9ucy5wdXNoKGFuaW1PYmopO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGZvciAoa2V5IGluIHByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gX3N0clNjcm9sbExlZnQgfHwga2V5ID09PSBfc3RyU2Nyb2xsVG9wKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmcm9tW2tleV0gPSBlbFtrZXldO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgZnJvbVtrZXldID0gRmFrZWpRdWVyeShlbCkuY3NzKGtleSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gZnJvbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmcm9tW2tleV0gIT09IHByb3BzW2tleV0gJiYgcHJvcHNba2V5XSAhPT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b1trZXldID0gcHJvcHNba2V5XTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWlzRW1wdHlPYmplY3QodG8pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRpbWVOb3c7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVuZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGVyY2VudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZnJvbVZhbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdG9WYWw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVhc2VkVmFsO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0aW1lU3RhcnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZyYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGFwc2VkO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBxUG9zID0gZ3VhcmFudGVlZE5leHQgPyAwIDogaW5BcnJheShxT2JqLCBhbmltT2JqLnEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBxT2JqID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wczogdG8sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBoYXNPcHRpb25zID8gb3B0aW9ucyA6IGR1cmF0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlYXNpbmc6IGVhc2luZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGU6IGNvbXBsZXRlXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocVBvcyA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcVBvcyA9IGFuaW1PYmoucVtMRVhJQ09OLmxdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhbmltT2JqLnEucHVzaChxT2JqKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChxUG9zID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkdXJhdGlvbiA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVTdGFydCA9IENPTVBBVElCSUxJVFkubm93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lTm93ID0gQ09NUEFUSUJJTElUWS5ub3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGFwc2VkID0gKHRpbWVOb3cgLSB0aW1lU3RhcnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZCA9IHFPYmouc3RvcCB8fCBlbGFwc2VkID49IGR1cmF0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlbnQgPSAxIC0gKChNQVRILm1heCgwLCB0aW1lU3RhcnQgKyBkdXJhdGlvbiAtIHRpbWVOb3cpIC8gZHVyYXRpb24pIHx8IDApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiB0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tVmFsID0gcGFyc2VGbG9hdChmcm9tW2tleV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1ZhbCA9IHBhcnNlRmxvYXQodG9ba2V5XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhc2VkVmFsID0gKHRvVmFsIC0gZnJvbVZhbCkgKiBFQVNJTkdbc3BlY2lhbEVhc2luZ1trZXldIHx8IGVhc2luZ10ocGVyY2VudCwgcGVyY2VudCAqIGR1cmF0aW9uLCAwLCAxLCBkdXJhdGlvbikgKyBmcm9tVmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRBbmltYXRpb25WYWx1ZShlbCwga2V5LCBlYXNlZFZhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHN0ZXApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKGVhc2VkVmFsLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbTogZWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcDoga2V5LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0OiBmcm9tVmFsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdzogZWFzZWRWYWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kOiB0b1ZhbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3M6IHBlcmNlbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYXNpbmc6IGVhc2luZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlYWNpYWxFYXNpbmc6IHNwZWNpYWxFYXNpbmcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBkdXJhdGlvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGU6IGNvbXBsZXRlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwOiBzdGVwXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydFRpbWU6IHRpbWVTdGFydFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHByb2dyZXNzKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3Moe30sIHBlcmNlbnQsIE1BVEgubWF4KDAsIGR1cmF0aW9uIC0gZWxhcHNlZCkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0TmV4dEFuaW1hdGlvbkluUShhbmltT2JqKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24oY29tcGxldGUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxT2JqLmZyYW1lID0gQ09NUEFUSUJJTElUWS5yQUYoKShmcmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcU9iai5mcmFtZSA9IENPTVBBVElCSUxJVFkuckFGKCkoZnJhbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gdG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0QW5pbWF0aW9uVmFsdWUoZWwsIGtleSwgdG9ba2V5XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydE5leHRBbmltYXRpb25JblEoYW5pbU9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChndWFyYW50ZWVkTmV4dClcclxuICAgICAgICAgICAgICAgICAgICBzdGFydE5leHRBbmltYXRpb25JblEoYW5pbU9iaik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIHN0b3AoZWwsIGNsZWFyUSwganVtcFRvRW5kKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgYW5pbU9iajtcclxuICAgICAgICAgICAgICAgIHZhciBxT2JqO1xyXG4gICAgICAgICAgICAgICAgdmFyIGtleTtcclxuICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgX2FuaW1hdGlvbnNbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYW5pbU9iaiA9IF9hbmltYXRpb25zW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhbmltT2JqLmVsID09PSBlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW5pbU9iai5xW0xFWElDT04ubF0gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBxT2JqID0gYW5pbU9iai5xWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcU9iai5zdG9wID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuY0FGKCkocU9iai5mcmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltT2JqLnEuc3BsaWNlKDAsIDEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqdW1wVG9FbmQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gcU9iai5wcm9wcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0QW5pbWF0aW9uVmFsdWUoZWwsIGtleSwgcU9iai5wcm9wc1trZXldKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2xlYXJRKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1PYmoucSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0TmV4dEFuaW1hdGlvbkluUShhbmltT2JqLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBlbGVtZW50SXNWaXNpYmxlKGVsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gISEoZWxbTEVYSUNPTi5vV10gfHwgZWxbTEVYSUNPTi5vSF0gfHwgZWwuZ2V0Q2xpZW50UmVjdHMoKVtMRVhJQ09OLmxdKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gRmFrZWpRdWVyeShzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3VtZW50c1tMRVhJQ09OLmxdID09PSAwKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG5cclxuICAgICAgICAgICAgICAgIHZhciBiYXNlID0gbmV3IEZha2VqUXVlcnkoKTtcclxuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50cyA9IHNlbGVjdG9yO1xyXG4gICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgdmFyIGVsbXM7XHJcbiAgICAgICAgICAgICAgICB2YXIgZWw7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKF90eXBlKHNlbGVjdG9yKSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IuY2hhckF0KDApID09PSAnPCcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwuaW5uZXJIVE1MID0gc2VsZWN0b3I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsbXMgPSBlbC5jaGlsZHJlbjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsbXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgZWxtc1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goZWxtc1tpXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90eXBlKGVsZW1lbnRzKSAhPSBUWVBFUy5zICYmICghaXNBcnJheUxpa2UoZWxlbWVudHMpIHx8IGVsZW1lbnRzID09PSB3aW5kb3cgfHwgZWxlbWVudHMgPT09IGVsZW1lbnRzLnNlbGYpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50cyA9IFtlbGVtZW50c107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBlbGVtZW50c1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VbaV0gPSBlbGVtZW50c1tpXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYmFzZVtMRVhJQ09OLmxdID0gZWxlbWVudHNbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYmFzZTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIEZha2VqUXVlcnlbTEVYSUNPTi5wXSA9IHtcclxuXHJcbiAgICAgICAgICAgICAgICAvL0VWRU5UUzpcclxuXHJcbiAgICAgICAgICAgICAgICBvbjogZnVuY3Rpb24gKGV2ZW50TmFtZSwgaGFuZGxlcikge1xyXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50TmFtZSA9IChldmVudE5hbWUgfHwgX3N0ckVtcHR5KS5tYXRjaChfcm5vdGh0bWx3aGl0ZSkgfHwgW19zdHJFbXB0eV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBldmVudE5hbWVMZW5ndGggPSBldmVudE5hbWVbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbCA9IHRoaXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWwuYWRkRXZlbnRMaXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgZXZlbnROYW1lTGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lW2ldLCBoYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVsLmRldGFjaEV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBldmVudE5hbWVMZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwuYXR0YWNoRXZlbnQoJ29uJyArIGV2ZW50TmFtZVtpXSwgaGFuZGxlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBvZmY6IGZ1bmN0aW9uIChldmVudE5hbWUsIGhhbmRsZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICBldmVudE5hbWUgPSAoZXZlbnROYW1lIHx8IF9zdHJFbXB0eSkubWF0Y2goX3Jub3RodG1sd2hpdGUpIHx8IFtfc3RyRW1wdHldO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnROYW1lTGVuZ3RoID0gZXZlbnROYW1lW0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGV2ZW50TmFtZUxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZVtpXSwgaGFuZGxlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlbC5kZXRhY2hFdmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgZXZlbnROYW1lTGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLmRldGFjaEV2ZW50KCdvbicgKyBldmVudE5hbWVbaV0sIGhhbmRsZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7IH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgb25lOiBmdW5jdGlvbiAoZXZlbnROYW1lLCBoYW5kbGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXZlbnROYW1lID0gKGV2ZW50TmFtZSB8fCBfc3RyRW1wdHkpLm1hdGNoKF9ybm90aHRtbHdoaXRlKSB8fCBbX3N0ckVtcHR5XTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsID0gRmFrZWpRdWVyeSh0aGlzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgRmFrZWpRdWVyeS5lYWNoKGV2ZW50TmFtZSwgZnVuY3Rpb24gKGksIG9uZUV2ZW50TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9uZUhhbmRsZXIgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5vZmYob25lRXZlbnROYW1lLCBvbmVIYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5vbihvbmVFdmVudE5hbWUsIG9uZUhhbmRsZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgdHJpZ2dlcjogZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LmNyZWF0ZUV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdIVE1MRXZlbnRzJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5pbml0RXZlbnQoZXZlbnROYW1lLCB0cnVlLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLmZpcmVFdmVudCgnb24nICsgZXZlbnROYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICAvL0RPTSBOT0RFIElOU0VSVElORyAvIFJFTU9WSU5HOlxyXG5cclxuICAgICAgICAgICAgICAgIGFwcGVuZDogZnVuY3Rpb24gKGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IGluc2VydEFkamFjZW50RWxlbWVudCh0aGlzLCAnYmVmb3JlZW5kJywgY2hpbGQpOyB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgcHJlcGVuZDogZnVuY3Rpb24gKGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IGluc2VydEFkamFjZW50RWxlbWVudCh0aGlzLCAnYWZ0ZXJiZWdpbicsIGNoaWxkKTsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIGJlZm9yZTogZnVuY3Rpb24gKGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IGluc2VydEFkamFjZW50RWxlbWVudCh0aGlzLCAnYmVmb3JlYmVnaW4nLCBjaGlsZCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBhZnRlcjogZnVuY3Rpb24gKGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IGluc2VydEFkamFjZW50RWxlbWVudCh0aGlzLCAnYWZ0ZXJlbmQnLCBjaGlsZCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICByZW1vdmU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudE5vZGUgPSBlbC5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50Tm9kZSAhPSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHVud3JhcDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnRzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IHRoaXMucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkocGFyZW50LCBwYXJlbnRzKSA9PT0gLSAxKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50cy5wdXNoKHBhcmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXJlbnRzW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbCA9IHBhcmVudHNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IGVsLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbC5maXJzdENoaWxkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShlbC5maXJzdENoaWxkLCBlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgd3JhcEFsbDogZnVuY3Rpb24gKHdyYXBwZXJIVE1MKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGVzID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd3JhcHBlciA9IEZha2VqUXVlcnkod3JhcHBlckhUTUwpWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkZWVwZXN0ID0gd3JhcHBlcjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50ID0gbm9kZXNbMF0ucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcHJldmlvdXNTaWJsaW5nID0gbm9kZXNbMF0ucHJldmlvdXNTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChkZWVwZXN0LmNoaWxkTm9kZXNbTEVYSUNPTi5sXSA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZXBlc3QgPSBkZWVwZXN0LmNoaWxkTm9kZXNbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IG5vZGVzW0xFWElDT04ubF0gLSBpOyBkZWVwZXN0LmZpcnN0Q2hpbGQgPT09IG5vZGVzWzBdICYmIGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVlcGVzdC5hcHBlbmRDaGlsZChub2Rlc1tpXSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBuZXh0U2libGluZyA9IHByZXZpb3VzU2libGluZyA/IHByZXZpb3VzU2libGluZy5uZXh0U2libGluZyA6IHBhcmVudC5maXJzdENoaWxkO1xyXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUod3JhcHBlciwgbmV4dFNpYmxpbmcpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgd3JhcElubmVyOiBmdW5jdGlvbiAod3JhcHBlckhUTUwpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsID0gRmFrZWpRdWVyeSh0aGlzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRzID0gZWwuY29udGVudHMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50c1tMRVhJQ09OLmxdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudHMud3JhcEFsbCh3cmFwcGVySFRNTCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLmFwcGVuZCh3cmFwcGVySFRNTCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHdyYXA6IGZ1bmN0aW9uICh3cmFwcGVySFRNTCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyBGYWtlalF1ZXJ5KHRoaXMpLndyYXBBbGwod3JhcHBlckhUTUwpOyB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vRE9NIE5PREUgTUFOSVBVTEFUSU9OIC8gSU5GT1JNQVRJT046XHJcblxyXG4gICAgICAgICAgICAgICAgY3NzOiBmdW5jdGlvbiAoc3R5bGVzLCB2YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGtleTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3B0U3R5bGU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGdldENwdFN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90eXBlKHN0eWxlcykgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsID0gdGhpc1swXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwdFN0eWxlID0gZ2V0Q3B0U3R5bGUgPyBnZXRDcHRTdHlsZShlbCwgbnVsbCkgOiBlbC5jdXJyZW50U3R5bGVbc3R5bGVzXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2h0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTU0ODM5NyBjYW4gYmUgbnVsbCBzb21ldGltZXMgaWYgaWZyYW1lIHdpdGggZGlzcGxheTogbm9uZSAoZmlyZWZveCBvbmx5ISlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRDcHRTdHlsZSA/IGNwdFN0eWxlICE9IG51bGwgPyBjcHRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKHN0eWxlcykgOiBlbFtMRVhJQ09OLnNdW3N0eWxlc10gOiBjcHRTdHlsZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldENTU1ZhbCh0aGlzLCBzdHlsZXMsIHZhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiBzdHlsZXMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0Q1NTVmFsKHRoaXMsIGtleSwgc3R5bGVzW2tleV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIGhhc0NsYXNzOiBmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW0sIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc05hbWVQcmVwYXJlZCA9IF9zdHJTcGFjZSArIGNsYXNzTmFtZSArIF9zdHJTcGFjZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NMaXN0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGVsZW0gPSB0aGlzW2krK10pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTGlzdCA9IGVsZW0uY2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2xhc3NMaXN0ICYmIGNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKF9zdHJTcGFjZSArIHN0cmlwQW5kQ29sbGFwc2UoZWxlbS5jbGFzc05hbWUgKyBfc3RyRW1wdHkpICsgX3N0clNwYWNlKS5pbmRleE9mKGNsYXNzTmFtZVByZXBhcmVkKSA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIGFkZENsYXNzOiBmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN1cjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VyVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXp6O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmaW5hbFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdXBwb3J0Q2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbG1DbGFzc0xpc3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2ID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc2VzID0gY2xhc3NOYW1lLm1hdGNoKF9ybm90aHRtbHdoaXRlKSB8fCBbXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgoZWxlbSA9IHRoaXNbaSsrXSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsbUNsYXNzTGlzdCA9IGVsZW0uY2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1cHBvcnRDbGFzc0xpc3QgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0Q2xhc3NMaXN0ID0gZWxtQ2xhc3NMaXN0ICE9PSB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1cHBvcnRDbGFzc0xpc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGNsYXp6ID0gY2xhc3Nlc1t2KytdKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxtQ2xhc3NMaXN0LmFkZChjbGF6eik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJWYWx1ZSA9IGVsZW0uY2xhc3NOYW1lICsgX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1ciA9IGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKF9zdHJTcGFjZSArIHN0cmlwQW5kQ29sbGFwc2UoY3VyVmFsdWUpICsgX3N0clNwYWNlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGNsYXp6ID0gY2xhc3Nlc1t2KytdKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXIuaW5kZXhPZihfc3RyU3BhY2UgKyBjbGF6eiArIF9zdHJTcGFjZSkgPCAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1ciArPSBjbGF6eiArIF9zdHJTcGFjZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsVmFsdWUgPSBzdHJpcEFuZENvbGxhcHNlKGN1cik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJWYWx1ZSAhPT0gZmluYWxWYWx1ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0uY2xhc3NOYW1lID0gZmluYWxWYWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICByZW1vdmVDbGFzczogZnVuY3Rpb24gKGNsYXNzTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc2VzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGVtO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN1clZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGF6ejtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZmluYWxWYWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3VwcG9ydENsYXNzTGlzdDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxtQ2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdiA9IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc05hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NlcyA9IGNsYXNzTmFtZS5tYXRjaChfcm5vdGh0bWx3aGl0ZSkgfHwgW107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGVsZW0gPSB0aGlzW2krK10pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbG1DbGFzc0xpc3QgPSBlbGVtLmNsYXNzTGlzdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdXBwb3J0Q2xhc3NMaXN0ID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VwcG9ydENsYXNzTGlzdCA9IGVsbUNsYXNzTGlzdCAhPT0gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdXBwb3J0Q2xhc3NMaXN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChjbGF6eiA9IGNsYXNzZXNbdisrXSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsbUNsYXNzTGlzdC5yZW1vdmUoY2xhenopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyVmFsdWUgPSBlbGVtLmNsYXNzTmFtZSArIF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmIChfc3RyU3BhY2UgKyBzdHJpcEFuZENvbGxhcHNlKGN1clZhbHVlKSArIF9zdHJTcGFjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChjbGF6eiA9IGNsYXNzZXNbdisrXSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY3VyLmluZGV4T2YoX3N0clNwYWNlICsgY2xhenogKyBfc3RyU3BhY2UpID4gLTEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyID0gY3VyLnJlcGxhY2UoX3N0clNwYWNlICsgY2xhenogKyBfc3RyU3BhY2UsIF9zdHJTcGFjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlID0gc3RyaXBBbmRDb2xsYXBzZShjdXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyVmFsdWUgIT09IGZpbmFsVmFsdWUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLmNsYXNzTmFtZSA9IGZpbmFsVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgaGlkZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyB0aGlzW0xFWElDT04uc10uZGlzcGxheSA9ICdub25lJzsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHNob3c6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHsgdGhpc1tMRVhJQ09OLnNdLmRpc3BsYXkgPSAnYmxvY2snOyB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgYXR0cjogZnVuY3Rpb24gKGF0dHJOYW1lLCB2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGVsID0gdGhpc1tpKytdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsLmdldEF0dHJpYnV0ZShhdHRyTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShhdHRyTmFtZSwgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgcmVtb3ZlQXR0cjogZnVuY3Rpb24gKGF0dHJOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IHRoaXMucmVtb3ZlQXR0cmlidXRlKGF0dHJOYW1lKTsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIG9mZnNldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbCA9IHRoaXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlY3QgPSBlbFtMRVhJQ09OLmJDUl0oKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsTGVmdCA9IHdpbmRvdy5wYWdlWE9mZnNldCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRbX3N0clNjcm9sbExlZnRdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxUb3AgPSB3aW5kb3cucGFnZVlPZmZzZXQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50W19zdHJTY3JvbGxUb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogcmVjdC50b3AgKyBzY3JvbGxUb3AsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IHJlY3QubGVmdCArIHNjcm9sbExlZnRcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbCA9IHRoaXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wOiBlbC5vZmZzZXRUb3AsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IGVsLm9mZnNldExlZnRcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBzY3JvbGxMZWZ0OiBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbCA9IHRoaXNbaSsrXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbFtfc3RyU2Nyb2xsTGVmdF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsW19zdHJTY3JvbGxMZWZ0XSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgc2Nyb2xsVG9wOiBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbCA9IHRoaXNbaSsrXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbFtfc3RyU2Nyb2xsVG9wXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxbX3N0clNjcm9sbFRvcF0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHZhbDogZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsID0gdGhpc1swXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXZhbHVlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWwudmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgZWwudmFsdWUgPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vRE9NIFRSQVZFUlNBTCAvIEZJTFRFUklORzpcclxuXHJcbiAgICAgICAgICAgICAgICBmaXJzdDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVxKDApO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBsYXN0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXEoLTEpO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBlcTogZnVuY3Rpb24gKGluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZha2VqUXVlcnkodGhpc1tpbmRleCA+PSAwID8gaW5kZXggOiB0aGlzW0xFWElDT04ubF0gKyBpbmRleF0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBmaW5kOiBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRyZW4gPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWwgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2ggPSBlbC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNoW0xFWElDT04ubF07IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goY2hbaV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5KGNoaWxkcmVuKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgY2hpbGRyZW46IGZ1bmN0aW9uIChzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2g7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gdGhpcy5jaGlsZHJlbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNoW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSBjaFtpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZWwubWF0Y2hlcyAmJiBlbC5tYXRjaGVzKHNlbGVjdG9yKSkgfHwgbWF0Y2hlcyhlbCwgc2VsZWN0b3IpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5KGNoaWxkcmVuKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgcGFyZW50OiBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50cyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gdGhpcy5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IgPyBGYWtlalF1ZXJ5KHBhcmVudCkuaXMoc2VsZWN0b3IpIDogdHJ1ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudHMucHVzaChwYXJlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5KHBhcmVudHMpO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBpczogZnVuY3Rpb24gKHNlbGVjdG9yKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpc1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSB0aGlzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IgPT09ICc6dmlzaWJsZScpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudElzVmlzaWJsZShlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RvciA9PT0gJzpoaWRkZW4nKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICFlbGVtZW50SXNWaXNpYmxlKGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChlbC5tYXRjaGVzICYmIGVsLm1hdGNoZXMoc2VsZWN0b3IpKSB8fCBtYXRjaGVzKGVsLCBzZWxlY3RvcikpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBjb250ZW50czogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50cyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZHM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcyA9IHRoaXMuY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNoaWxkc1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50cy5wdXNoKGNoaWxkc1tpXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5KGNvbnRlbnRzKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgZWFjaDogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVhY2godGhpcywgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy9BTklNQVRJT046XHJcblxyXG4gICAgICAgICAgICAgICAgYW5pbWF0ZTogZnVuY3Rpb24gKHByb3BzLCBkdXJhdGlvbiwgZWFzaW5nLCBjb21wbGV0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyBhbmltYXRlKHRoaXMsIHByb3BzLCBkdXJhdGlvbiwgZWFzaW5nLCBjb21wbGV0ZSk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBzdG9wOiBmdW5jdGlvbiAoY2xlYXJRLCBqdW1wKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IHN0b3AodGhpcywgY2xlYXJRLCBqdW1wKTsgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBleHRlbmQoRmFrZWpRdWVyeSwge1xyXG4gICAgICAgICAgICAgICAgZXh0ZW5kOiBleHRlbmQsXHJcbiAgICAgICAgICAgICAgICBpbkFycmF5OiBpbkFycmF5LFxyXG4gICAgICAgICAgICAgICAgaXNFbXB0eU9iamVjdDogaXNFbXB0eU9iamVjdCxcclxuICAgICAgICAgICAgICAgIGlzUGxhaW5PYmplY3Q6IGlzUGxhaW5PYmplY3QsXHJcbiAgICAgICAgICAgICAgICBlYWNoOiBlYWNoXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIEZha2VqUXVlcnk7XHJcbiAgICAgICAgfSkoKTtcclxuICAgICAgICB2YXIgSU5TVEFOQ0VTID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIF90YXJnZXRzID0gW107XHJcbiAgICAgICAgICAgIHZhciBfaW5zdGFuY2VQcm9wZXJ0eVN0cmluZyA9ICdfX292ZXJsYXlTY3JvbGxiYXJzX18nO1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFJlZ2lzdGVyLCB1bnJlZ2lzdGVyIG9yIGdldCBhIGNlcnRhaW4gKG9yIGFsbCkgaW5zdGFuY2VzLlxyXG4gICAgICAgICAgICAgKiBSZWdpc3RlcjogUGFzcyB0aGUgdGFyZ2V0IGFuZCB0aGUgaW5zdGFuY2UuXHJcbiAgICAgICAgICAgICAqIFVucmVnaXN0ZXI6IFBhc3MgdGhlIHRhcmdldCBhbmQgbnVsbC5cclxuICAgICAgICAgICAgICogR2V0IEluc3RhbmNlOiBQYXNzIHRoZSB0YXJnZXQgZnJvbSB3aGljaCB0aGUgaW5zdGFuY2Ugc2hhbGwgYmUgZ290LlxyXG4gICAgICAgICAgICAgKiBHZXQgVGFyZ2V0czogUGFzcyBubyBhcmd1bWVudHMuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCB0byB3aGljaCB0aGUgaW5zdGFuY2Ugc2hhbGwgYmUgcmVnaXN0ZXJlZCAvIGZyb20gd2hpY2ggdGhlIGluc3RhbmNlIHNoYWxsIGJlIHVucmVnaXN0ZXJlZCAvIHRoZSBpbnN0YW5jZSBzaGFsbCBiZSBnb3RcclxuICAgICAgICAgICAgICogQHBhcmFtIGluc3RhbmNlIFRoZSBpbnN0YW5jZS5cclxuICAgICAgICAgICAgICogQHJldHVybnMgeyp8dm9pZH0gUmV0dXJucyB0aGUgaW5zdGFuY2UgZnJvbSB0aGUgZ2l2ZW4gdGFyZ2V0LlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgYXJnTGVuID0gYXJndW1lbnRzW0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICBpZiAoYXJnTGVuIDwgMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIGFsbCB0YXJnZXRzXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90YXJnZXRzO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVnaXN0ZXIgaW5zdGFuY2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W19pbnN0YW5jZVByb3BlcnR5U3RyaW5nXSA9IGluc3RhbmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0cy5wdXNoKHRhcmdldCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBDT01QQVRJQklMSVRZLmluQSh0YXJnZXQsIF90YXJnZXRzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcmdMZW4gPiAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy91bnJlZ2lzdGVyIGluc3RhbmNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRhcmdldFtfaW5zdGFuY2VQcm9wZXJ0eVN0cmluZ107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldHMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZ2V0IGluc3RhbmNlIGZyb20gdGFyZ2V0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90YXJnZXRzW2luZGV4XVtfaW5zdGFuY2VQcm9wZXJ0eVN0cmluZ107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KSgpO1xyXG4gICAgICAgIHZhciBQTFVHSU4gPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgX3BsdWdpbjtcclxuICAgICAgICAgICAgdmFyIF9wbHVnaW5zR2xvYmFscztcclxuICAgICAgICAgICAgdmFyIF9wbHVnaW5zQXV0b1VwZGF0ZUxvb3A7XHJcbiAgICAgICAgICAgIHZhciBfcGx1Z2luc0V4dGVuc2lvbnMgPSBbXTtcclxuICAgICAgICAgICAgdmFyIF9wbHVnaW5zT3B0aW9ucyA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgdHlwZSA9IENPTVBBVElCSUxJVFkudHlwZTtcclxuICAgICAgICAgICAgICAgIHZhciBwb3NzaWJsZVRlbXBsYXRlVHlwZXMgPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgVFlQRVMuYiwgLy9ib29sZWFuXHJcbiAgICAgICAgICAgICAgICAgICAgVFlQRVMubiwgLy9udW1iZXJcclxuICAgICAgICAgICAgICAgICAgICBUWVBFUy5zLCAvL3N0cmluZ1xyXG4gICAgICAgICAgICAgICAgICAgIFRZUEVTLmEsIC8vYXJyYXlcclxuICAgICAgICAgICAgICAgICAgICBUWVBFUy5vLCAvL29iamVjdFxyXG4gICAgICAgICAgICAgICAgICAgIFRZUEVTLmYsIC8vZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICBUWVBFUy56ICAvL251bGxcclxuICAgICAgICAgICAgICAgIF07XHJcbiAgICAgICAgICAgICAgICB2YXIgcmVzdHJpY3RlZFN0cmluZ3NTcGxpdCA9ICcgJztcclxuICAgICAgICAgICAgICAgIHZhciByZXN0cmljdGVkU3RyaW5nc1Bvc3NpYmlsaXRpZXNTcGxpdCA9ICc6JztcclxuICAgICAgICAgICAgICAgIHZhciBjbGFzc05hbWVBbGxvd2VkVmFsdWVzID0gW1RZUEVTLnosIFRZUEVTLnNdO1xyXG4gICAgICAgICAgICAgICAgdmFyIG51bWJlckFsbG93ZWRWYWx1ZXMgPSBUWVBFUy5uO1xyXG4gICAgICAgICAgICAgICAgdmFyIGJvb2xlYW5OdWxsQWxsb3dlZFZhbHVlcyA9IFtUWVBFUy56LCBUWVBFUy5iXTtcclxuICAgICAgICAgICAgICAgIHZhciBib29sZWFuVHJ1ZVRlbXBsYXRlID0gW3RydWUsIFRZUEVTLmJdO1xyXG4gICAgICAgICAgICAgICAgdmFyIGJvb2xlYW5GYWxzZVRlbXBsYXRlID0gW2ZhbHNlLCBUWVBFUy5iXTtcclxuICAgICAgICAgICAgICAgIHZhciBjYWxsYmFja1RlbXBsYXRlID0gW251bGwsIFtUWVBFUy56LCBUWVBFUy5mXV07XHJcbiAgICAgICAgICAgICAgICB2YXIgdXBkYXRlT25Mb2FkVGVtcGxhdGUgPSBbWydpbWcnXSwgW1RZUEVTLnMsIFRZUEVTLmEsIFRZUEVTLnpdXTtcclxuICAgICAgICAgICAgICAgIHZhciBpbmhlcml0ZWRBdHRyc1RlbXBsYXRlID0gW1snc3R5bGUnLCAnY2xhc3MnXSwgW1RZUEVTLnMsIFRZUEVTLmEsIFRZUEVTLnpdXTtcclxuICAgICAgICAgICAgICAgIHZhciByZXNpemVBbGxvd2VkVmFsdWVzID0gJ246bm9uZSBiOmJvdGggaDpob3Jpem9udGFsIHY6dmVydGljYWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QmVoYXZpb3JBbGxvd2VkVmFsdWVzID0gJ3YtaDp2aXNpYmxlLWhpZGRlbiB2LXM6dmlzaWJsZS1zY3JvbGwgczpzY3JvbGwgaDpoaWRkZW4nO1xyXG4gICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNWaXNpYmlsaXR5QWxsb3dlZFZhbHVlcyA9ICd2OnZpc2libGUgaDpoaWRkZW4gYTphdXRvJztcclxuICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzQXV0b0hpZGVBbGxvd2VkVmFsdWVzID0gJ246bmV2ZXIgczpzY3JvbGwgbDpsZWF2ZSBtOm1vdmUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIG9wdGlvbnNEZWZhdWx0c0FuZFRlbXBsYXRlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogWydvcy10aGVtZS1kYXJrJywgY2xhc3NOYW1lQWxsb3dlZFZhbHVlc10sICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBzdHJpbmdcclxuICAgICAgICAgICAgICAgICAgICByZXNpemU6IFsnbm9uZScsIHJlc2l6ZUFsbG93ZWRWYWx1ZXNdLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL25vbmUgfHwgYm90aCAgfHwgaG9yaXpvbnRhbCB8fCB2ZXJ0aWNhbCB8fCBuIHx8IGIgfHwgaCB8fCB2XHJcbiAgICAgICAgICAgICAgICAgICAgc2l6ZUF1dG9DYXBhYmxlOiBib29sZWFuVHJ1ZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgY2xpcEFsd2F5czogYm9vbGVhblRydWVUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplUlRMOiBib29sZWFuVHJ1ZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0Fic29sdXRlOiBib29sZWFuRmFsc2VUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgYXV0b1VwZGF0ZTogW251bGwsIGJvb2xlYW5OdWxsQWxsb3dlZFZhbHVlc10sICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlIHx8IG51bGxcclxuICAgICAgICAgICAgICAgICAgICBhdXRvVXBkYXRlSW50ZXJ2YWw6IFszMywgbnVtYmVyQWxsb3dlZFZhbHVlc10sICAgICAgICAgICAgICAgICAgICAgICAvL251bWJlclxyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZU9uTG9hZDogdXBkYXRlT25Mb2FkVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3RyaW5nIHx8IGFycmF5IHx8IG51bGxcclxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVTY3JvbGxiYXJzT3ZlcmxhaWQ6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2hvd05hdGl2ZVNjcm9sbGJhcnM6IGJvb2xlYW5GYWxzZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAvL3RydWUgfHwgZmFsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdGlhbGl6ZTogYm9vbGVhblRydWVUZW1wbGF0ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RydWUgfHwgZmFsc2VcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIG92ZXJmbG93QmVoYXZpb3I6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgeDogWydzY3JvbGwnLCBvdmVyZmxvd0JlaGF2aW9yQWxsb3dlZFZhbHVlc10sICAgICAgICAgICAgICAgICAgICAvL3Zpc2libGUtaGlkZGVuICB8fCB2aXNpYmxlLXNjcm9sbCB8fCBoaWRkZW4gfHwgc2Nyb2xsIHx8IHYtaCB8fCB2LXMgfHwgaCB8fCBzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IFsnc2Nyb2xsJywgb3ZlcmZsb3dCZWhhdmlvckFsbG93ZWRWYWx1ZXNdICAgICAgICAgICAgICAgICAgICAgLy92aXNpYmxlLWhpZGRlbiAgfHwgdmlzaWJsZS1zY3JvbGwgfHwgaGlkZGVuIHx8IHNjcm9sbCB8fCB2LWggfHwgdi1zIHx8IGggfHwgc1xyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OiBbJ2F1dG8nLCBzY3JvbGxiYXJzVmlzaWJpbGl0eUFsbG93ZWRWYWx1ZXNdLCAgICAgICAgIC8vdmlzaWJsZSB8fCBoaWRkZW4gfHwgYXV0byB8fCB2IHx8IGggfHwgYVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvSGlkZTogWyduZXZlcicsIHNjcm9sbGJhcnNBdXRvSGlkZUFsbG93ZWRWYWx1ZXNdLCAgICAgICAgICAgIC8vbmV2ZXIgfHwgc2Nyb2xsIHx8IGxlYXZlIHx8IG1vdmUgfHwgbiB8fCBzIHx8IGwgfHwgbVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvSGlkZURlbGF5OiBbODAwLCBudW1iZXJBbGxvd2VkVmFsdWVzXSwgICAgICAgICAgICAgICAgICAgICAgIC8vbnVtYmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRyYWdTY3JvbGxpbmc6IGJvb2xlYW5UcnVlVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsaWNrU2Nyb2xsaW5nOiBib29sZWFuRmFsc2VUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdWNoU3VwcG9ydDogYm9vbGVhblRydWVUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNuYXBIYW5kbGU6IGJvb2xlYW5GYWxzZVRlbXBsYXRlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYToge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkeW5XaWR0aDogYm9vbGVhbkZhbHNlVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkeW5IZWlnaHQ6IGJvb2xlYW5GYWxzZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0ZWRBdHRyczogaW5oZXJpdGVkQXR0cnNUZW1wbGF0ZSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3RyaW5nIHx8IGFycmF5IHx8IG51bGxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkluaXRpYWxpemVkOiBjYWxsYmFja1RlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkluaXRpYWxpemF0aW9uV2l0aGRyYXduOiBjYWxsYmFja1RlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkRlc3Ryb3llZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbFN0YXJ0OiBjYWxsYmFja1RlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbFN0b3A6IGNhbGxiYWNrVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbk92ZXJmbG93Q2hhbmdlZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbk92ZXJmbG93QW1vdW50Q2hhbmdlZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkRpcmVjdGlvbkNoYW5nZWQ6IGNhbGxiYWNrVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNvbnRlbnRTaXplQ2hhbmdlZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkhvc3RTaXplQ2hhbmdlZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblVwZGF0ZWQ6IGNhbGxiYWNrVGVtcGxhdGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB2YXIgY29udmVydCA9IGZ1bmN0aW9uICh0ZW1wbGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWN1cnNpdmUgPSBmdW5jdGlvbiAob2JqKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWxUeXBlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiBvYmopIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghb2JqW0xFWElDT04uaE9QXShrZXkpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsID0gb2JqW2tleV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxUeXBlID0gdHlwZSh2YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbFR5cGUgPT0gVFlQRVMuYSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHZhbFt0ZW1wbGF0ZSA/IDEgOiAwXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZhbFR5cGUgPT0gVFlQRVMubylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHJlY3Vyc2l2ZSh2YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvYmo7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVjdXJzaXZlKEZSQU1FV09SSy5leHRlbmQodHJ1ZSwge30sIG9wdGlvbnNEZWZhdWx0c0FuZFRlbXBsYXRlKSk7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgX2RlZmF1bHRzOiBjb252ZXJ0KCksXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF90ZW1wbGF0ZTogY29udmVydCh0cnVlKSxcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgICAgICogVmFsaWRhdGVzIHRoZSBwYXNzZWQgb2JqZWN0IGJ5IHRoZSBwYXNzZWQgdGVtcGxhdGUuXHJcbiAgICAgICAgICAgICAgICAgICAgICogQHBhcmFtIG9iaiBUaGUgb2JqZWN0IHdoaWNoIHNoYWxsIGJlIHZhbGlkYXRlZC5cclxuICAgICAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdGVtcGxhdGUgVGhlIHRlbXBsYXRlIHdoaWNoIGRlZmluZXMgdGhlIGFsbG93ZWQgdmFsdWVzIGFuZCB0eXBlcy5cclxuICAgICAgICAgICAgICAgICAgICAgKiBAcGFyYW0gd3JpdGVFcnJvcnMgVHJ1ZSBpZiBlcnJvcnMgc2hhbGwgYmUgbG9nZ2VkIHRvIHRoZSBjb25zb2xlLlxyXG4gICAgICAgICAgICAgICAgICAgICAqIEBwYXJhbSBkaWZmT2JqIElmIGEgb2JqZWN0IGlzIHBhc3NlZCB0aGVuIG9ubHkgdmFsaWQgZGlmZmVyZW5jZXMgdG8gdGhpcyBvYmplY3Qgd2lsbCBiZSByZXR1cm5lZC5cclxuICAgICAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e319IEEgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHR3byBvYmplY3RzIGNhbGxlZCBcImRlZmF1bHRcIiBhbmQgXCJwcmVwYXJlZFwiIHdoaWNoIGNvbnRhaW5zIG9ubHkgdGhlIHZhbGlkIHByb3BlcnRpZXMgb2YgdGhlIHBhc3NlZCBvcmlnaW5hbCBvYmplY3QgYW5kIGRpc2NhcmRzIG5vdCBkaWZmZXJlbnQgdmFsdWVzIGNvbXBhcmVkIHRvIHRoZSBwYXNzZWQgZGlmZk9iai5cclxuICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICBfdmFsaWRhdGU6IGZ1bmN0aW9uIChvYmosIHRlbXBsYXRlLCB3cml0ZUVycm9ycywgZGlmZk9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsaWRhdGVkT3B0aW9ucyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsaWRhdGVkT3B0aW9uc1ByZXBhcmVkID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvYmplY3RDb3B5ID0gRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB7fSwgb2JqKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluQXJyYXkgPSBGUkFNRVdPUksuaW5BcnJheTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzRW1wdHlPYmogPSBGUkFNRVdPUksuaXNFbXB0eU9iamVjdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoZWNrT2JqZWN0UHJvcHMgPSBmdW5jdGlvbiAoZGF0YSwgdGVtcGxhdGUsIGRpZmZEYXRhLCB2YWxpZGF0ZWRPcHRpb25zLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWQsIHByZXZQcm9wTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiB0ZW1wbGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wbGF0ZVtMRVhJQ09OLmhPUF0ocHJvcCkgJiYgZGF0YVtMRVhJQ09OLmhPUF0ocHJvcCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzVmFsaWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzRGlmZiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGVtcGxhdGVWYWx1ZSA9IHRlbXBsYXRlW3Byb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGVtcGxhdGVWYWx1ZVR5cGUgPSB0eXBlKHRlbXBsYXRlVmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGVtcGxhdGVJc0NvbXBsZXggPSB0ZW1wbGF0ZVZhbHVlVHlwZSA9PSBUWVBFUy5vO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGVtcGxhdGVUeXBlcyA9ICFDT01QQVRJQklMSVRZLmlzQSh0ZW1wbGF0ZVZhbHVlKSA/IFt0ZW1wbGF0ZVZhbHVlXSA6IHRlbXBsYXRlVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkYXRhRGlmZlZhbHVlID0gZGlmZkRhdGFbcHJvcF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkYXRhVmFsdWUgPSBkYXRhW3Byb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YVZhbHVlVHlwZSA9IHR5cGUoZGF0YVZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHByb3BQcmVmaXggPSBwcmV2UHJvcE5hbWUgPyBwcmV2UHJvcE5hbWUgKyAnLicgOiAnJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gXCJUaGUgb3B0aW9uIFxcXCJcIiArIHByb3BQcmVmaXggKyBwcm9wICsgXCJcXFwiIHdhc24ndCBzZXQsIGJlY2F1c2VcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yUG9zc2libGVUeXBlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3JSZXN0cmljdGVkU3RyaW5ncyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1NwbGl0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1Bvc3NpYmlsaXRpZXNTcGxpdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzUmVzdHJpY3RlZFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWFpblBvc3NpYmlsaXR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyclR5cGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGo7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhRGlmZlZhbHVlID0gZGF0YURpZmZWYWx1ZSA9PT0gdW5kZWZpbmVkID8ge30gOiBkYXRhRGlmZlZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiB0aGUgdGVtcGxhdGUgaGFzIGEgb2JqZWN0IGFzIHZhbHVlLCBpdCBtZWFucyB0aGF0IHRoZSBvcHRpb25zIGFyZSBjb21wbGV4ICh2ZXJzY2hhY2h0ZWx0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcGxhdGVJc0NvbXBsZXggJiYgZGF0YVZhbHVlVHlwZSA9PSBUWVBFUy5vKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRPcHRpb25zW3Byb3BdID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWRbcHJvcF0gPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrT2JqZWN0UHJvcHMoZGF0YVZhbHVlLCB0ZW1wbGF0ZVZhbHVlLCBkYXRhRGlmZlZhbHVlLCB2YWxpZGF0ZWRPcHRpb25zW3Byb3BdLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWRbcHJvcF0sIHByb3BQcmVmaXggKyBwcm9wKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSy5lYWNoKFtkYXRhLCB2YWxpZGF0ZWRPcHRpb25zLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWRdLCBmdW5jdGlvbiAoaW5kZXgsIHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRW1wdHlPYmoodmFsdWVbcHJvcF0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB2YWx1ZVtwcm9wXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghdGVtcGxhdGVJc0NvbXBsZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0ZW1wbGF0ZVR5cGVzW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJUeXBlID0gdGVtcGxhdGVUeXBlc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZVZhbHVlVHlwZSA9IHR5cGUoY3VyclR5cGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgY3VycnR5cGUgaXMgc3RyaW5nIGFuZCBzdGFydHMgd2l0aCByZXN0cmljdGVkU3RyaW5nUHJlZml4IGFuZCBlbmQgd2l0aCByZXN0cmljdGVkU3RyaW5nU3VmZml4XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNSZXN0cmljdGVkVmFsdWUgPSB0ZW1wbGF0ZVZhbHVlVHlwZSA9PSBUWVBFUy5zICYmIGluQXJyYXkoY3VyclR5cGUsIHBvc3NpYmxlVGVtcGxhdGVUeXBlcykgPT09IC0xO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1Jlc3RyaWN0ZWRWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvclBvc3NpYmxlVHlwZXMucHVzaChUWVBFUy5zKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3BsaXQgaXQgaW50byBhIGFycmF5IHdoaWNoIGNvbnRhaW5zIGFsbCBwb3NzaWJsZSB2YWx1ZXMgZm9yIGV4YW1wbGU6IFtcInk6eWVzXCIsIFwibjpub1wiLCBcIm06bWF5YmVcIl1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1NwbGl0ID0gY3VyclR5cGUuc3BsaXQocmVzdHJpY3RlZFN0cmluZ3NTcGxpdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yUmVzdHJpY3RlZFN0cmluZ3MgPSBlcnJvclJlc3RyaWN0ZWRTdHJpbmdzLmNvbmNhdChyZXN0cmljdGVkU3RyaW5nVmFsdWVzU3BsaXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHYgPSAwOyB2IDwgcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1NwbGl0W0xFWElDT04ubF07IHYrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9zcGxpdCB0aGUgcG9zc2libGUgdmFsdWVzIGludG8gdGhlaXIgcG9zc2liaWxpdGVpcyBmb3IgZXhhbXBsZTogW1wieVwiLCBcInllc1wiXSAtPiB0aGUgZmlyc3QgaXMgYWx3YXlzIHRoZSBtYWluUG9zc2liaWxpdHlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWRTdHJpbmdWYWx1ZXNQb3NzaWJpbGl0aWVzU3BsaXQgPSByZXN0cmljdGVkU3RyaW5nVmFsdWVzU3BsaXRbdl0uc3BsaXQocmVzdHJpY3RlZFN0cmluZ3NQb3NzaWJpbGl0aWVzU3BsaXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFpblBvc3NpYmlsaXR5ID0gcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1Bvc3NpYmlsaXRpZXNTcGxpdFswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCByZXN0cmljdGVkU3RyaW5nVmFsdWVzUG9zc2liaWxpdGllc1NwbGl0W0xFWElDT04ubF07IGorKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgYW55IHBvc3NpYmlsaXR5IG1hdGNoZXMgd2l0aCB0aGUgZGF0YVZhbHVlLCBpdHMgdmFsaWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YVZhbHVlID09PSByZXN0cmljdGVkU3RyaW5nVmFsdWVzUG9zc2liaWxpdGllc1NwbGl0W2pdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzVmFsaWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNWYWxpZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JQb3NzaWJsZVR5cGVzLnB1c2goY3VyclR5cGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFWYWx1ZVR5cGUgPT09IGN1cnJUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1ZhbGlkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1ZhbGlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNEaWZmID0gZGF0YVZhbHVlICE9PSBkYXRhRGlmZlZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNEaWZmKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRPcHRpb25zW3Byb3BdID0gZGF0YVZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNSZXN0cmljdGVkVmFsdWUgPyBpbkFycmF5KGRhdGFEaWZmVmFsdWUsIHJlc3RyaWN0ZWRTdHJpbmdWYWx1ZXNQb3NzaWJpbGl0aWVzU3BsaXQpIDwgMCA6IGlzRGlmZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGVkT3B0aW9uc1ByZXBhcmVkW3Byb3BdID0gaXNSZXN0cmljdGVkVmFsdWUgPyBtYWluUG9zc2liaWxpdHkgOiBkYXRhVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh3cml0ZUVycm9ycykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihlcnJvciArIFwiIGl0IGRvZXNuJ3QgYWNjZXB0IHRoZSB0eXBlIFsgXCIgKyBkYXRhVmFsdWVUeXBlLnRvVXBwZXJDYXNlKCkgKyBcIiBdIHdpdGggdGhlIHZhbHVlIG9mIFxcXCJcIiArIGRhdGFWYWx1ZSArIFwiXFxcIi5cXHJcXG5cIiArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiQWNjZXB0ZWQgdHlwZXMgYXJlOiBbIFwiICsgZXJyb3JQb3NzaWJsZVR5cGVzLmpvaW4oJywgJykudG9VcHBlckNhc2UoKSArIFwiIF0uXCIgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZXJyb3JSZXN0cmljdGVkU3RyaW5nc1tsZW5ndGhdID4gMCA/IFwiXFxyXFxuVmFsaWQgc3RyaW5ncyBhcmU6IFsgXCIgKyBlcnJvclJlc3RyaWN0ZWRTdHJpbmdzLmpvaW4oJywgJykuc3BsaXQocmVzdHJpY3RlZFN0cmluZ3NQb3NzaWJpbGl0aWVzU3BsaXQpLmpvaW4oJywgJykgKyBcIiBdLlwiIDogJycpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBkYXRhW3Byb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGVja09iamVjdFByb3BzKG9iamVjdENvcHksIHRlbXBsYXRlLCBkaWZmT2JqIHx8IHt9LCB2YWxpZGF0ZWRPcHRpb25zLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hZGQgdmFsdWVzIHdoaWNoIGFyZW4ndCBzcGVjaWZpZWQgaW4gdGhlIHRlbXBsYXRlIHRvIHRoZSBmaW5pc2hlZCB2YWxpZGF0ZWQgb2JqZWN0IHRvIHByZXZlbnQgdGhlbSBmcm9tIGJlaW5nIGRpc2NhcmRlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZihrZWVwRm9yZWlnblByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGUkFNRVdPUksuZXh0ZW5kKHRydWUsIHZhbGlkYXRlZE9wdGlvbnMsIG9iamVjdENvcHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWQsIG9iamVjdENvcHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICovXHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzRW1wdHlPYmoob2JqZWN0Q29weSkgJiYgd3JpdGVFcnJvcnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1RoZSBmb2xsb3dpbmcgb3B0aW9ucyBhcmUgZGlzY2FyZGVkIGR1ZSB0byBpbnZhbGlkaXR5OlxcclxcbicgKyB3aW5kb3cuSlNPTi5zdHJpbmdpZnkob2JqZWN0Q29weSwgbnVsbCwgMikpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9kZWZhdWx0OiB2YWxpZGF0ZWRPcHRpb25zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByZXBhcmVkOiB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0oKSk7XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgdGhlIG9iamVjdCB3aGljaCBjb250YWlucyBnbG9iYWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBsdWdpbiBhbmQgZWFjaCBpbnN0YW5jZSBvZiBpdC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGluaXRPdmVybGF5U2Nyb2xsYmFyc1N0YXRpY3MoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIV9wbHVnaW5zR2xvYmFscylcclxuICAgICAgICAgICAgICAgICAgICBfcGx1Z2luc0dsb2JhbHMgPSBuZXcgT3ZlcmxheVNjcm9sbGJhcnNHbG9iYWxzKF9wbHVnaW5zT3B0aW9ucy5fZGVmYXVsdHMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFfcGx1Z2luc0F1dG9VcGRhdGVMb29wKVxyXG4gICAgICAgICAgICAgICAgICAgIF9wbHVnaW5zQXV0b1VwZGF0ZUxvb3AgPSBuZXcgT3ZlcmxheVNjcm9sbGJhcnNBdXRvVXBkYXRlTG9vcChfcGx1Z2luc0dsb2JhbHMpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVGhlIGdsb2JhbCBvYmplY3QgZm9yIHRoZSBPdmVybGF5U2Nyb2xsYmFycyBvYmplY3RzLiBJdCBjb250YWlucyByZXNvdXJjZXMgd2hpY2ggZXZlcnkgT3ZlcmxheVNjcm9sbGJhcnMgb2JqZWN0IG5lZWRzLiBUaGlzIG9iamVjdCBpcyBpbml0aWFsaXplZCBvbmx5IG9uY2U6IGlmIHRoZSBmaXJzdCBPdmVybGF5U2Nyb2xsYmFycyBvYmplY3QgZ2V0cyBpbml0aWFsaXplZC5cclxuICAgICAgICAgICAgICogQHBhcmFtIGRlZmF1bHRPcHRpb25zXHJcbiAgICAgICAgICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgZnVuY3Rpb24gT3ZlcmxheVNjcm9sbGJhcnNHbG9iYWxzKGRlZmF1bHRPcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Jhc2UgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0ck92ZXJmbG93ID0gJ292ZXJmbG93JztcclxuICAgICAgICAgICAgICAgIHZhciBzdHJIaWRkZW4gPSAnaGlkZGVuJztcclxuICAgICAgICAgICAgICAgIHZhciBzdHJTY3JvbGwgPSAnc2Nyb2xsJztcclxuICAgICAgICAgICAgICAgIHZhciBib2R5RWxlbWVudCA9IEZSQU1FV09SSygnYm9keScpO1xyXG4gICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhckR1bW15RWxlbWVudCA9IEZSQU1FV09SSygnPGRpdiBpZD1cIm9zLWR1bW15LXNjcm9sbGJhci1zaXplXCI+PGRpdj48L2Rpdj48L2Rpdj4nKTtcclxuICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJEdW1teUVsZW1lbnQwID0gc2Nyb2xsYmFyRHVtbXlFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgdmFyIGR1bW15Q29udGFpbmVyQ2hpbGQgPSBGUkFNRVdPUksoc2Nyb2xsYmFyRHVtbXlFbGVtZW50LmNoaWxkcmVuKCdkaXYnKS5lcSgwKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgYm9keUVsZW1lbnQuYXBwZW5kKHNjcm9sbGJhckR1bW15RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuaGlkZSgpLnNob3coKTsgLy9maXggSUU4IGJ1ZyAoaW5jb3JyZWN0IG1lYXN1cmluZylcclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgbmF0aXZlU2Nyb2xsYmFyU2l6ZSA9IGNhbGNOYXRpdmVTY3JvbGxiYXJTaXplKHNjcm9sbGJhckR1bW15RWxlbWVudDApO1xyXG4gICAgICAgICAgICAgICAgdmFyIG5hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgeDogbmF0aXZlU2Nyb2xsYmFyU2l6ZS54ID09PSAwLFxyXG4gICAgICAgICAgICAgICAgICAgIHk6IG5hdGl2ZVNjcm9sbGJhclNpemUueSA9PT0gMFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHZhciBtc2llID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdWEgPSB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RySW5kZXhPZiA9ICdpbmRleE9mJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyU3ViU3RyaW5nID0gJ3N1YnN0cmluZyc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1zaWUgPSB1YVtzdHJJbmRleE9mXSgnTVNJRSAnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdHJpZGVudCA9IHVhW3N0ckluZGV4T2ZdKCdUcmlkZW50LycpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlZGdlID0gdWFbc3RySW5kZXhPZl0oJ0VkZ2UvJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJ2ID0gdWFbc3RySW5kZXhPZl0oJ3J2OicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcnNlSW50RnVuYyA9IHBhcnNlSW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBJRSAxMCBvciBvbGRlciA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXJcclxuICAgICAgICAgICAgICAgICAgICBpZiAobXNpZSA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHBhcnNlSW50RnVuYyh1YVtzdHJTdWJTdHJpbmddKG1zaWUgKyA1LCB1YVtzdHJJbmRleE9mXSgnLicsIG1zaWUpKSwgMTApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBJRSAxMSA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXJcclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0cmlkZW50ID4gMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcGFyc2VJbnRGdW5jKHVhW3N0clN1YlN0cmluZ10ocnYgKyAzLCB1YVtzdHJJbmRleE9mXSgnLicsIHJ2KSksIDEwKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gRWRnZSAoSUUgMTIrKSA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXJcclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlZGdlID4gMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcGFyc2VJbnRGdW5jKHVhW3N0clN1YlN0cmluZ10oZWRnZSArIDUsIHVhW3N0ckluZGV4T2ZdKCcuJywgZWRnZSkpLCAxMCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIG90aGVyIGJyb3dzZXJcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgfSkoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBGUkFNRVdPUksuZXh0ZW5kKF9iYXNlLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdE9wdGlvbnM6IGRlZmF1bHRPcHRpb25zLFxyXG4gICAgICAgICAgICAgICAgICAgIG1zaWU6IG1zaWUsXHJcbiAgICAgICAgICAgICAgICAgICAgYXV0b1VwZGF0ZUxvb3A6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgIGF1dG9VcGRhdGVSZWNvbW1lbmRlZDogIUNPTVBBVElCSUxJVFkubU8oKSxcclxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVTY3JvbGxiYXJTaXplOiBuYXRpdmVTY3JvbGxiYXJTaXplLFxyXG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQ6IG5hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlU2Nyb2xsYmFyU3R5bGluZzogKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuYWRkQ2xhc3MoJ29zLXZpZXdwb3J0LW5hdGl2ZS1zY3JvbGxiYXJzLWludmlzaWJsZScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gKHNjcm9sbGJhckR1bW15RWxlbWVudC5jc3MoJ3Njcm9sbGJhci13aWR0aCcpID09PSAnbm9uZScgJiYgKG1zaWUgPiA5IHx8ICFtc2llKSkgfHwgd2luZG93LmdldENvbXB1dGVkU3R5bGUoc2Nyb2xsYmFyRHVtbXlFbGVtZW50MCwgJzo6LXdlYmtpdC1zY3JvbGxiYXInKS5nZXRQcm9wZXJ0eVZhbHVlKCdkaXNwbGF5JykgPT09ICdub25lJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9maXggb3BlcmEgYnVnOiBzY3JvbGxiYXIgc3R5bGVzIHdpbGwgb25seSBhcHBlYXIgaWYgb3ZlcmZsb3cgdmFsdWUgaXMgc2Nyb2xsIG9yIGF1dG8gZHVyaW5nIHRoZSBhY3RpdmF0aW9uIG9mIHRoZSBzdHlsZS5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hbmQgc2V0IG92ZXJmbG93IHRvIHNjcm9sbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGJhckR1bW15RWxlbWVudC5jc3Moc3RyT3ZlcmZsb3csIHN0ckhpZGRlbikuaGlkZSgpLmNzcyhzdHJPdmVyZmxvdywgc3RyU2Nyb2xsKS5zaG93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIChzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04ub0hdIC0gc2Nyb2xsYmFyRHVtbXlFbGVtZW50MFtMRVhJQ09OLmNIXSkgPT09IDAgJiYgKHNjcm9sbGJhckR1bW15RWxlbWVudDBbTEVYSUNPTi5vV10gLSBzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04uY1ddKSA9PT0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfSkoKSxcclxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplOiB7IHg6IDMwLCB5OiAzMCB9LFxyXG4gICAgICAgICAgICAgICAgICAgIGNzc0NhbGM6IFZFTkRPUlMuX2Nzc1Byb3BlcnR5VmFsdWUoJ3dpZHRoJywgJ2NhbGMnLCAnKDFweCknKSB8fCBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWRNZWFzdXJpbmc6IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTQzOTMwNVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NpbmNlIDEuMTEuMCBhbHdheXMgZmFsc2UgLT4gZml4ZWQgdmlhIENTUyAoaG9wZWZ1bGx5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuY3NzKHN0ck92ZXJmbG93LCBzdHJIaWRkZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsU2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IHNjcm9sbGJhckR1bW15RWxlbWVudDBbTEVYSUNPTi5zV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04uc0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhckR1bW15RWxlbWVudC5jc3Moc3RyT3ZlcmZsb3csICd2aXNpYmxlJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxTaXplMiA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IHNjcm9sbGJhckR1bW15RWxlbWVudDBbTEVYSUNPTi5zV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04uc0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoc2Nyb2xsU2l6ZS53IC0gc2Nyb2xsU2l6ZTIudykgIT09IDAgfHwgKHNjcm9sbFNpemUuaCAtIHNjcm9sbFNpemUyLmgpICE9PSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pKCksXHJcbiAgICAgICAgICAgICAgICAgICAgcnRsU2Nyb2xsQmVoYXZpb3I6IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhckR1bW15RWxlbWVudC5jc3MoeyAnb3ZlcmZsb3cteSc6IHN0ckhpZGRlbiwgJ292ZXJmbG93LXgnOiBzdHJTY3JvbGwsICdkaXJlY3Rpb24nOiAncnRsJyB9KS5zY3JvbGxMZWZ0KDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZHVtbXlDb250YWluZXJPZmZzZXQgPSBzY3JvbGxiYXJEdW1teUVsZW1lbnQub2Zmc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkdW1teUNvbnRhaW5lckNoaWxkT2Zmc2V0ID0gZHVtbXlDb250YWluZXJDaGlsZC5vZmZzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9odHRwczovL2dpdGh1Yi5jb20vS2luZ1NvcmEvT3ZlcmxheVNjcm9sbGJhcnMvaXNzdWVzLzE4N1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuc2Nyb2xsTGVmdCgtOTk5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGR1bW15Q29udGFpbmVyQ2hpbGRPZmZzZXRBZnRlclNjcm9sbCA9IGR1bW15Q29udGFpbmVyQ2hpbGQub2Zmc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL29yaWdpbiBkaXJlY3Rpb24gPSBkZXRlcm1pbmVzIGlmIHRoZSB6ZXJvIHNjcm9sbCBwb3NpdGlvbiBpcyBvbiB0aGUgbGVmdCBvciByaWdodCBzaWRlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLydpJyBtZWFucyAnaW52ZXJ0JyAoaSA9PT0gdHJ1ZSBtZWFucyB0aGF0IHRoZSBheGlzIG11c3QgYmUgaW52ZXJ0ZWQgdG8gYmUgY29ycmVjdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSA9IG9uIHRoZSBsZWZ0IHNpZGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmFsc2UgPSBvbiB0aGUgcmlnaHQgc2lkZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaTogZHVtbXlDb250YWluZXJPZmZzZXQubGVmdCA9PT0gZHVtbXlDb250YWluZXJDaGlsZE9mZnNldC5sZWZ0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9uZWdhdGl2ZSA9IGRldGVybWluZXMgaWYgdGhlIG1heGltdW0gc2Nyb2xsIGlzIHBvc2l0aXZlIG9yIG5lZ2F0aXZlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyduJyBtZWFucyAnbmVnYXRlJyAobiA9PT0gdHJ1ZSBtZWFucyB0aGF0IHRoZSBheGlzIG11c3QgYmUgbmVnYXRlZCB0byBiZSBjb3JyZWN0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlID0gbmVnYXRpdmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmFsc2UgPSBwb3NpdGl2ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbjogZHVtbXlDb250YWluZXJDaGlsZE9mZnNldC5sZWZ0ICE9PSBkdW1teUNvbnRhaW5lckNoaWxkT2Zmc2V0QWZ0ZXJTY3JvbGwubGVmdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH0pKCksXHJcbiAgICAgICAgICAgICAgICAgICAgc3VwcG9ydFRyYW5zZm9ybTogISFWRU5ET1JTLl9jc3NQcm9wZXJ0eSgndHJhbnNmb3JtJyksXHJcbiAgICAgICAgICAgICAgICAgICAgc3VwcG9ydFRyYW5zaXRpb246ICEhVkVORE9SUy5fY3NzUHJvcGVydHkoJ3RyYW5zaXRpb24nKSxcclxuICAgICAgICAgICAgICAgICAgICBzdXBwb3J0UGFzc2l2ZUV2ZW50czogKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN1cHBvcnRzUGFzc2l2ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Rlc3QnLCBudWxsLCBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdwYXNzaXZlJywge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0c1Bhc3NpdmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgeyB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdXBwb3J0c1Bhc3NpdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSkoKSxcclxuICAgICAgICAgICAgICAgICAgICBzdXBwb3J0UmVzaXplT2JzZXJ2ZXI6ICEhQ09NUEFUSUJJTElUWS5yTygpLFxyXG4gICAgICAgICAgICAgICAgICAgIHN1cHBvcnRNdXRhdGlvbk9ic2VydmVyOiAhIUNPTVBBVElCSUxJVFkubU8oKVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgc2Nyb2xsYmFyRHVtbXlFbGVtZW50LnJlbW92ZUF0dHIoTEVYSUNPTi5zKS5yZW1vdmUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL0NhdGNoIHpvb20gZXZlbnQ6XHJcbiAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhYnMgPSBNQVRILmFicztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2luZG93V2lkdGggPSBDT01QQVRJQklMSVRZLndXKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdpbmRvd0hlaWdodCA9IENPTVBBVElCSUxJVFkud0goKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2luZG93RHByID0gZ2V0V2luZG93RFBSKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9uUmVzaXplID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoSU5TVEFOQ0VTKCkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld1cgPSBDT01QQVRJQklMSVRZLndXKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3SCA9IENPTVBBVElCSUxJVFkud0goKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZWx0YVcgPSBuZXdXIC0gd2luZG93V2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVsdGFIID0gbmV3SCAtIHdpbmRvd0hlaWdodDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVsdGFXID09PSAwICYmIGRlbHRhSCA9PT0gMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRlbHRhV1JhdGlvID0gTUFUSC5yb3VuZChuZXdXIC8gKHdpbmRvd1dpZHRoIC8gMTAwLjApKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZWx0YUhSYXRpbyA9IE1BVEgucm91bmQobmV3SCAvICh3aW5kb3dIZWlnaHQgLyAxMDAuMCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFic0RlbHRhVyA9IGFicyhkZWx0YVcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFic0RlbHRhSCA9IGFicyhkZWx0YUgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFic0RlbHRhV1JhdGlvID0gYWJzKGRlbHRhV1JhdGlvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhYnNEZWx0YUhSYXRpbyA9IGFicyhkZWx0YUhSYXRpbyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3RFBSID0gZ2V0V2luZG93RFBSKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRlbHRhSXNCaWdnZXIgPSBhYnNEZWx0YVcgPiAyICYmIGFic0RlbHRhSCA+IDI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGlmZmVyZW5jZSA9ICFkaWZmZXJlbmNlSXNCaWdnZXJUaGFuT25lKGFic0RlbHRhV1JhdGlvLCBhYnNEZWx0YUhSYXRpbyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZHByQ2hhbmdlZCA9IG5ld0RQUiAhPT0gd2luZG93RHByICYmIHdpbmRvd0RwciA+IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNab29tID0gZGVsdGFJc0JpZ2dlciAmJiBkaWZmZXJlbmNlICYmIGRwckNoYW5nZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2xkU2Nyb2xsYmFyU2l6ZSA9IF9iYXNlLm5hdGl2ZVNjcm9sbGJhclNpemU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3U2Nyb2xsYmFyU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNab29tKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9keUVsZW1lbnQuYXBwZW5kKHNjcm9sbGJhckR1bW15RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2Nyb2xsYmFyU2l6ZSA9IF9iYXNlLm5hdGl2ZVNjcm9sbGJhclNpemUgPSBjYWxjTmF0aXZlU2Nyb2xsYmFyU2l6ZShzY3JvbGxiYXJEdW1teUVsZW1lbnRbMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhckR1bW15RWxlbWVudC5yZW1vdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob2xkU2Nyb2xsYmFyU2l6ZS54ICE9PSBuZXdTY3JvbGxiYXJTaXplLnggfHwgb2xkU2Nyb2xsYmFyU2l6ZS55ICE9PSBuZXdTY3JvbGxiYXJTaXplLnkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLmVhY2goSU5TVEFOQ0VTKCksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChJTlNUQU5DRVModGhpcykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5TVEFOQ0VTKHRoaXMpLnVwZGF0ZSgnem9vbScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93V2lkdGggPSBuZXdXO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93SGVpZ2h0ID0gbmV3SDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd0RwciA9IG5ld0RQUjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRpZmZlcmVuY2VJc0JpZ2dlclRoYW5PbmUodmFsT25lLCB2YWxUd28pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFic1ZhbE9uZSA9IGFicyh2YWxPbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWJzVmFsVHdvID0gYWJzKHZhbFR3byk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAhKGFic1ZhbE9uZSA9PT0gYWJzVmFsVHdvIHx8IGFic1ZhbE9uZSArIDEgPT09IGFic1ZhbFR3byB8fCBhYnNWYWxPbmUgLSAxID09PSBhYnNWYWxUd28pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0V2luZG93RFBSKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZERQSSA9IHdpbmRvdy5zY3JlZW4uZGV2aWNlWERQSSB8fCAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc0RQSSA9IHdpbmRvdy5zY3JlZW4ubG9naWNhbFhEUEkgfHwgMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IChkRFBJIC8gc0RQSSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBGUkFNRVdPUksod2luZG93KS5vbigncmVzaXplJywgb25SZXNpemUpO1xyXG4gICAgICAgICAgICAgICAgfSkoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBjYWxjTmF0aXZlU2Nyb2xsYmFyU2l6ZShtZWFzdXJlRWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IG1lYXN1cmVFbGVtZW50W0xFWElDT04ub0hdIC0gbWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5jSF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IG1lYXN1cmVFbGVtZW50W0xFWElDT04ub1ddIC0gbWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5jV11cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVGhlIG9iamVjdCB3aGljaCBtYW5hZ2VzIHRoZSBhdXRvIHVwZGF0ZSBsb29wIGZvciBhbGwgT3ZlcmxheVNjcm9sbGJhcnMgb2JqZWN0cy4gVGhpcyBvYmplY3QgaXMgaW5pdGlhbGl6ZWQgb25seSBvbmNlOiBpZiB0aGUgZmlyc3QgT3ZlcmxheVNjcm9sbGJhcnMgb2JqZWN0IGdldHMgaW5pdGlhbGl6ZWQuXHJcbiAgICAgICAgICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgZnVuY3Rpb24gT3ZlcmxheVNjcm9sbGJhcnNBdXRvVXBkYXRlTG9vcChnbG9iYWxzKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Jhc2UgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9pbkFycmF5ID0gRlJBTUVXT1JLLmluQXJyYXk7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2dldE5vdyA9IENPTVBBVElCSUxJVFkubm93O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJBdXRvVXBkYXRlID0gJ2F1dG9VcGRhdGUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJBdXRvVXBkYXRlSW50ZXJ2YWwgPSBfc3RyQXV0b1VwZGF0ZSArICdJbnRlcnZhbCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckxlbmd0aCA9IExFWElDT04ubDtcclxuICAgICAgICAgICAgICAgIHZhciBfbG9vcGluZ0luc3RhbmNlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9sb29waW5nSW5zdGFuY2VzSW50ZXJ2YWxDYWNoZSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9sb29wSXNBY3RpdmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHZhciBfbG9vcEludGVydmFsRGVmYXVsdCA9IDMzO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9sb29wSW50ZXJ2YWwgPSBfbG9vcEludGVydmFsRGVmYXVsdDtcclxuICAgICAgICAgICAgICAgIHZhciBfbG9vcFRpbWVPbGQgPSBfZ2V0Tm93KCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2xvb3BJRDtcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBUaGUgYXV0byB1cGRhdGUgbG9vcCB3aGljaCB3aWxsIHJ1biBldmVyeSA1MCBtaWxsaXNlY29uZHMgb3IgbGVzcyBpZiB0aGUgdXBkYXRlIGludGVydmFsIG9mIGEgaW5zdGFuY2UgaXMgbG93ZXIgdGhhbiA1MCBtaWxsaXNlY29uZHMuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIHZhciBsb29wID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfbG9vcGluZ0luc3RhbmNlc1tfc3RyTGVuZ3RoXSA+IDAgJiYgX2xvb3BJc0FjdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbG9vcElEID0gQ09NUEFUSUJJTElUWS5yQUYoKShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb29wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGltZU5ldyA9IF9nZXROb3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRpbWVEZWx0YSA9IHRpbWVOZXcgLSBfbG9vcFRpbWVPbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsb3dlc3RJbnRlcnZhbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2VPcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2VBdXRvVXBkYXRlQWxsb3dlZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlQXV0b1VwZGF0ZUludGVydmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm93O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRpbWVEZWx0YSA+IF9sb29wSW50ZXJ2YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sb29wVGltZU9sZCA9IHRpbWVOZXcgLSAodGltZURlbHRhICUgX2xvb3BJbnRlcnZhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb3dlc3RJbnRlcnZhbCA9IF9sb29wSW50ZXJ2YWxEZWZhdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBfbG9vcGluZ0luc3RhbmNlc1tfc3RyTGVuZ3RoXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UgPSBfbG9vcGluZ0luc3RhbmNlc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZU9wdGlvbnMgPSBpbnN0YW5jZS5vcHRpb25zKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQXV0b1VwZGF0ZUFsbG93ZWQgPSBpbnN0YW5jZU9wdGlvbnNbX3N0ckF1dG9VcGRhdGVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUF1dG9VcGRhdGVJbnRlcnZhbCA9IE1BVEgubWF4KDEsIGluc3RhbmNlT3B0aW9uc1tfc3RyQXV0b1VwZGF0ZUludGVydmFsXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdyA9IF9nZXROb3coKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoaW5zdGFuY2VBdXRvVXBkYXRlQWxsb3dlZCA9PT0gdHJ1ZSB8fCBpbnN0YW5jZUF1dG9VcGRhdGVBbGxvd2VkID09PSBudWxsKSAmJiAobm93IC0gX2xvb3BpbmdJbnN0YW5jZXNJbnRlcnZhbENhY2hlW2ldKSA+IGluc3RhbmNlQXV0b1VwZGF0ZUludGVydmFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS51cGRhdGUoJ2F1dG8nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sb29waW5nSW5zdGFuY2VzSW50ZXJ2YWxDYWNoZVtpXSA9IG5ldyBEYXRlKG5vdyArPSBpbnN0YW5jZUF1dG9VcGRhdGVJbnRlcnZhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VzdEludGVydmFsID0gTUFUSC5tYXgoMSwgTUFUSC5taW4obG93ZXN0SW50ZXJ2YWwsIGluc3RhbmNlQXV0b1VwZGF0ZUludGVydmFsKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BJbnRlcnZhbCA9IGxvd2VzdEludGVydmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BJbnRlcnZhbCA9IF9sb29wSW50ZXJ2YWxEZWZhdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBBZGQgT3ZlcmxheVNjcm9sbGJhcnMgaW5zdGFuY2UgdG8gdGhlIGF1dG8gdXBkYXRlIGxvb3AuIE9ubHkgc3VjY2Vzc2Z1bCBpZiB0aGUgaW5zdGFuY2UgaXNuJ3QgYWxyZWFkeSBhZGRlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpbnN0YW5jZSBUaGUgaW5zdGFuY2Ugd2hpY2ggc2hhbGwgYmUgdXBkYXRlZCBpbiBhIGxvb3AgYXV0b21hdGljYWxseS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgX2Jhc2UuYWRkID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pbkFycmF5KGluc3RhbmNlLCBfbG9vcGluZ0luc3RhbmNlcykgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9sb29waW5nSW5zdGFuY2VzLnB1c2goaW5zdGFuY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbG9vcGluZ0luc3RhbmNlc0ludGVydmFsQ2FjaGUucHVzaChfZ2V0Tm93KCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2xvb3BpbmdJbnN0YW5jZXNbX3N0ckxlbmd0aF0gPiAwICYmICFfbG9vcElzQWN0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbG9vcElzQWN0aXZlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsb2JhbHMuYXV0b1VwZGF0ZUxvb3AgPSBfbG9vcElzQWN0aXZlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9vcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJlbW92ZSBPdmVybGF5U2Nyb2xsYmFycyBpbnN0YW5jZSBmcm9tIHRoZSBhdXRvIHVwZGF0ZSBsb29wLiBPbmx5IHN1Y2Nlc3NmdWwgaWYgdGhlIGluc3RhbmNlIHdhcyBhZGRlZCBiZWZvcmUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gaW5zdGFuY2UgVGhlIGluc3RhbmNlIHdoaWNoIHNoYWxsIGJlIHVwZGF0ZWQgaW4gYSBsb29wIGF1dG9tYXRpY2FsbHkuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLnJlbW92ZSA9IGZ1bmN0aW9uIChpbnN0YW5jZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IF9pbkFycmF5KGluc3RhbmNlLCBfbG9vcGluZ0luc3RhbmNlcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgZnJvbSBsb29waW5nSW5zdGFuY2VzIGxpc3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BpbmdJbnN0YW5jZXNJbnRlcnZhbENhY2hlLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9sb29waW5nSW5zdGFuY2VzLnNwbGljZShpbmRleCwgMSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2NvcnJlY3QgdXBkYXRlIGxvb3AgYmVoYXZpb3JcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9sb29waW5nSW5zdGFuY2VzW19zdHJMZW5ndGhdID09PSAwICYmIF9sb29wSXNBY3RpdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sb29wSXNBY3RpdmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsb2JhbHMuYXV0b1VwZGF0ZUxvb3AgPSBfbG9vcElzQWN0aXZlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9sb29wSUQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuY0FGKCkoX2xvb3BJRCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BJRCA9IC0xO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEEgb2JqZWN0IHdoaWNoIG1hbmFnZXMgdGhlIHNjcm9sbGJhcnMgdmlzaWJpbGl0eSBvZiB0aGUgdGFyZ2V0IGVsZW1lbnQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBwbHVnaW5UYXJnZXRFbGVtZW50IFRoZSBlbGVtZW50IGZyb20gd2hpY2ggdGhlIHNjcm9sbGJhcnMgc2hhbGwgYmUgaGlkZGVuLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyBUaGUgY3VzdG9tIG9wdGlvbnMuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBleHRlbnNpb25zIFRoZSBjdXN0b20gZXh0ZW5zaW9ucy5cclxuICAgICAgICAgICAgICogQHBhcmFtIGdsb2JhbHNcclxuICAgICAgICAgICAgICogQHBhcmFtIGF1dG9VcGRhdGVMb29wXHJcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfVxyXG4gICAgICAgICAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIE92ZXJsYXlTY3JvbGxiYXJzSW5zdGFuY2UocGx1Z2luVGFyZ2V0RWxlbWVudCwgb3B0aW9ucywgZXh0ZW5zaW9ucywgZ2xvYmFscywgYXV0b1VwZGF0ZUxvb3ApIHtcclxuICAgICAgICAgICAgICAgIC8vc2hvcnRjdXRzXHJcbiAgICAgICAgICAgICAgICB2YXIgdHlwZSA9IENPTVBBVElCSUxJVFkudHlwZTtcclxuICAgICAgICAgICAgICAgIHZhciBpbkFycmF5ID0gRlJBTUVXT1JLLmluQXJyYXk7XHJcbiAgICAgICAgICAgICAgICB2YXIgZWFjaCA9IEZSQU1FV09SSy5lYWNoO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vbWFrZSBjb3JyZWN0IGluc3RhbmNlb2ZcclxuICAgICAgICAgICAgICAgIHZhciBfYmFzZSA9IG5ldyBfcGx1Z2luKCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2ZyYW1ld29ya1Byb3RvID0gRlJBTUVXT1JLW0xFWElDT04ucF07XHJcblxyXG4gICAgICAgICAgICAgICAgLy9pZiBwYXNzZWQgZWxlbWVudCBpcyBubyBIVE1MIGVsZW1lbnQ6IHNraXAgYW5kIHJldHVyblxyXG4gICAgICAgICAgICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KHBsdWdpblRhcmdldEVsZW1lbnQpKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgICAgICAvL2lmIHBhc3NlZCBlbGVtZW50IGlzIGFscmVhZHkgaW5pdGlhbGl6ZWQ6IHNldCBwYXNzZWQgb3B0aW9ucyBpZiB0aGVyZSBhcmUgYW55IGFuZCByZXR1cm4gaXRzIGluc3RhbmNlXHJcbiAgICAgICAgICAgICAgICBpZiAoSU5TVEFOQ0VTKHBsdWdpblRhcmdldEVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3QgPSBJTlNUQU5DRVMocGx1Z2luVGFyZ2V0RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaW5zdC5vcHRpb25zKG9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnN0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vZ2xvYmFsczpcclxuICAgICAgICAgICAgICAgIHZhciBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZDtcclxuICAgICAgICAgICAgICAgIHZhciBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfcnRsU2Nyb2xsQmVoYXZpb3I7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2F1dG9VcGRhdGVSZWNvbW1lbmRlZDtcclxuICAgICAgICAgICAgICAgIHZhciBfbXNpZVZlcnNpb247XHJcbiAgICAgICAgICAgICAgICB2YXIgX25hdGl2ZVNjcm9sbGJhclN0eWxpbmc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Nzc0NhbGM7XHJcbiAgICAgICAgICAgICAgICB2YXIgX25hdGl2ZVNjcm9sbGJhclNpemU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N1cHBvcnRUcmFuc2l0aW9uO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdXBwb3J0VHJhbnNmb3JtO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdXBwb3J0UGFzc2l2ZUV2ZW50cztcclxuICAgICAgICAgICAgICAgIHZhciBfc3VwcG9ydFJlc2l6ZU9ic2VydmVyO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdXBwb3J0TXV0YXRpb25PYnNlcnZlcjtcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzdHJpY3RlZE1lYXN1cmluZztcclxuXHJcbiAgICAgICAgICAgICAgICAvL2dlbmVyYWwgcmVhZG9ubHk6XHJcbiAgICAgICAgICAgICAgICB2YXIgX2luaXRpYWxpemVkO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9kZXN0cm95ZWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2lzVGV4dGFyZWE7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2lzQm9keTtcclxuICAgICAgICAgICAgICAgIHZhciBfZG9jdW1lbnRNaXhlZDtcclxuICAgICAgICAgICAgICAgIHZhciBfZG9tRXhpc3RzO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vZ2VuZXJhbDpcclxuICAgICAgICAgICAgICAgIHZhciBfaXNCb3JkZXJCb3g7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZDtcclxuICAgICAgICAgICAgICAgIHZhciBfcGFkZGluZ1g7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3BhZGRpbmdZO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9ib3JkZXJYO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9ib3JkZXJZO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tYXJnaW5YO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tYXJnaW5ZO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9pc1JUTDtcclxuICAgICAgICAgICAgICAgIHZhciBfc2xlZXBpbmc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRCb3JkZXJTaXplID0ge307XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbEhvcml6b250YWxJbmZvID0ge307XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbFZlcnRpY2FsSW5mbyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgdmFyIF92aWV3cG9ydFNpemUgPSB7fTtcclxuICAgICAgICAgICAgICAgIHZhciBfbmF0aXZlU2Nyb2xsYmFyTWluU2l6ZSA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8vbmFtaW5nOlx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1pbnVzSGlkZGVuID0gJy1oaWRkZW4nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJNYXJnaW5NaW51cyA9ICdtYXJnaW4tJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyUGFkZGluZ01pbnVzID0gJ3BhZGRpbmctJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyQm9yZGVyTWludXMgPSAnYm9yZGVyLSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clRvcCA9ICd0b3AnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJSaWdodCA9ICdyaWdodCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckJvdHRvbSA9ICdib3R0b20nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJMZWZ0ID0gJ2xlZnQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJNaW5NaW51cyA9ICdtaW4tJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTWF4TWludXMgPSAnbWF4LSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0cldpZHRoID0gJ3dpZHRoJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RySGVpZ2h0ID0gJ2hlaWdodCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckZsb2F0ID0gJ2Zsb2F0JztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyRW1wdHkgPSAnJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyQXV0byA9ICdhdXRvJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyU3luYyA9ICdzeW5jJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyU2Nyb2xsID0gJ3Njcm9sbCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckh1bmRyZWRQZXJjZW50ID0gJzEwMCUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJYID0gJ3gnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJZID0gJ3knO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJEb3QgPSAnLic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clNwYWNlID0gJyAnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJTY3JvbGxiYXIgPSAnc2Nyb2xsYmFyJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTWludXNIb3Jpem9udGFsID0gJy1ob3Jpem9udGFsJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTWludXNWZXJ0aWNhbCA9ICctdmVydGljYWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJTY3JvbGxMZWZ0ID0gX3N0clNjcm9sbCArICdMZWZ0JztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyU2Nyb2xsVG9wID0gX3N0clNjcm9sbCArICdUb3AnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJNb3VzZVRvdWNoRG93bkV2ZW50ID0gJ21vdXNlZG93biB0b3VjaHN0YXJ0JztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTW91c2VUb3VjaFVwRXZlbnQgPSAnbW91c2V1cCB0b3VjaGVuZCB0b3VjaGNhbmNlbCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1vdXNlVG91Y2hNb3ZlRXZlbnQgPSAnbW91c2Vtb3ZlIHRvdWNobW92ZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1vdXNlRW50ZXIgPSAnbW91c2VlbnRlcic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1vdXNlTGVhdmUgPSAnbW91c2VsZWF2ZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0cktleURvd25FdmVudCA9ICdrZXlkb3duJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyS2V5VXBFdmVudCA9ICdrZXl1cCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clNlbGVjdFN0YXJ0RXZlbnQgPSAnc2VsZWN0c3RhcnQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJUcmFuc2l0aW9uRW5kRXZlbnQgPSAndHJhbnNpdGlvbmVuZCB3ZWJraXRUcmFuc2l0aW9uRW5kIG9UcmFuc2l0aW9uRW5kJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyUmVzaXplT2JzZXJ2ZXJQcm9wZXJ0eSA9ICdfX292ZXJsYXlTY3JvbGxiYXJzUk9fXyc7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9jbGFzcyBuYW1lczpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9jYXNzTmFtZXNQcmVmaXggPSAnb3MtJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSFRNTEVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ2h0bWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0RWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAnaG9zdCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RFbGVtZW50Rm9yZWlnbiA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctZm9yZWlnbic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RUZXh0YXJlYUVsZW1lbnQgPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLXRleHRhcmVhJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdFNjcm9sbGJhckhvcml6b250YWxIaWRkZW4gPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLScgKyBfc3RyU2Nyb2xsYmFyICsgX3N0ck1pbnVzSG9yaXpvbnRhbCArIF9zdHJNaW51c0hpZGRlbjtcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdFNjcm9sbGJhclZlcnRpY2FsSGlkZGVuID0gX2NsYXNzTmFtZUhvc3RFbGVtZW50ICsgJy0nICsgX3N0clNjcm9sbGJhciArIF9zdHJNaW51c1ZlcnRpY2FsICsgX3N0ck1pbnVzSGlkZGVuO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0VHJhbnNpdGlvbiA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctdHJhbnNpdGlvbic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RSVEwgPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLXJ0bCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RSZXNpemVEaXNhYmxlZCA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctcmVzaXplLWRpc2FibGVkJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdFNjcm9sbGluZyA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctc2Nyb2xsaW5nJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdE92ZXJmbG93ID0gX2NsYXNzTmFtZUhvc3RFbGVtZW50ICsgJy1vdmVyZmxvdyc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RPdmVyZmxvdyA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctb3ZlcmZsb3cnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3dYID0gX2NsYXNzTmFtZUhvc3RPdmVyZmxvdyArICcteCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RPdmVyZmxvd1kgPSBfY2xhc3NOYW1lSG9zdE92ZXJmbG93ICsgJy15JztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50ID0gX2Nhc3NOYW1lc1ByZWZpeCArICd0ZXh0YXJlYSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVRleHRhcmVhQ292ZXJFbGVtZW50ID0gX2NsYXNzTmFtZVRleHRhcmVhRWxlbWVudCArICctY292ZXInO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVQYWRkaW5nRWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAncGFkZGluZyc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVZpZXdwb3J0RWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAndmlld3BvcnQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVWaWV3cG9ydE5hdGl2ZVNjcm9sbGJhcnNJbnZpc2libGUgPSBfY2xhc3NOYW1lVmlld3BvcnRFbGVtZW50ICsgJy1uYXRpdmUtc2Nyb2xsYmFycy1pbnZpc2libGUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVWaWV3cG9ydE5hdGl2ZVNjcm9sbGJhcnNPdmVybGFpZCA9IF9jbGFzc05hbWVWaWV3cG9ydEVsZW1lbnQgKyAnLW5hdGl2ZS1zY3JvbGxiYXJzLW92ZXJsYWlkJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lQ29udGVudEVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ2NvbnRlbnQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVDb250ZW50QXJyYW5nZUVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ2NvbnRlbnQtYXJyYW5nZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUNvbnRlbnRHbHVlRWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAnY29udGVudC1nbHVlJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ3NpemUtYXV0by1vYnNlcnZlcic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAncmVzaXplLW9ic2VydmVyJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJJdGVtRWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAncmVzaXplLW9ic2VydmVyLWl0ZW0nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckl0ZW1GaW5hbEVsZW1lbnQgPSBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJJdGVtRWxlbWVudCArICctZmluYWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVUZXh0SW5oZXJpdCA9IF9jYXNzTmFtZXNQcmVmaXggKyAndGV4dC1pbmhlcml0JztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFyID0gX2Nhc3NOYW1lc1ByZWZpeCArIF9zdHJTY3JvbGxiYXI7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhclRyYWNrID0gX2NsYXNzTmFtZVNjcm9sbGJhciArICctdHJhY2snO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJUcmFja09mZiA9IF9jbGFzc05hbWVTY3JvbGxiYXJUcmFjayArICctb2ZmJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFySGFuZGxlID0gX2NsYXNzTmFtZVNjcm9sbGJhciArICctaGFuZGxlJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFySGFuZGxlT2ZmID0gX2NsYXNzTmFtZVNjcm9sbGJhckhhbmRsZSArICctb2ZmJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFyVW51c2FibGUgPSBfY2xhc3NOYW1lU2Nyb2xsYmFyICsgJy11bnVzYWJsZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckF1dG9IaWRkZW4gPSBfY2xhc3NOYW1lU2Nyb2xsYmFyICsgJy0nICsgX3N0ckF1dG8gKyBfc3RyTWludXNIaWRkZW47XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lciA9IF9jbGFzc05hbWVTY3JvbGxiYXIgKyAnLWNvcm5lcic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZSA9IF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXIgKyAnLXJlc2l6ZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZUIgPSBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplICsgJy1ib3RoJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplSCA9IF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemUgKyBfc3RyTWludXNIb3Jpem9udGFsO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemVWID0gX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZSArIF9zdHJNaW51c1ZlcnRpY2FsO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJIb3Jpem9udGFsID0gX2NsYXNzTmFtZVNjcm9sbGJhciArIF9zdHJNaW51c0hvcml6b250YWw7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhclZlcnRpY2FsID0gX2NsYXNzTmFtZVNjcm9sbGJhciArIF9zdHJNaW51c1ZlcnRpY2FsO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVEcmFnZ2luZyA9IF9jYXNzTmFtZXNQcmVmaXggKyAnZHJhZ2dpbmcnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVUaGVtZU5vbmUgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ3RoZW1lLW5vbmUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVzRHluYW1pY0Rlc3Ryb3kgPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVZpZXdwb3J0TmF0aXZlU2Nyb2xsYmFyc0ludmlzaWJsZSxcclxuICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lVmlld3BvcnROYXRpdmVTY3JvbGxiYXJzT3ZlcmxhaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhclRyYWNrT2ZmLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJIYW5kbGVPZmYsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhclVudXNhYmxlLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJBdXRvSGlkZGVuLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemUsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZUIsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZUgsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZVYsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZURyYWdnaW5nXS5qb2luKF9zdHJTcGFjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9jYWxsYmFja3M6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfY2FsbGJhY2tzSW5pdFFldWV1ZSA9IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vYXR0cnMgdmlld3BvcnQgc2hhbGwgaW5oZXJpdCBmcm9tIHRhcmdldFx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3ZpZXdwb3J0QXR0cnNGcm9tVGFyZ2V0ID0gW0xFWElDT04udGldO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vb3B0aW9uczpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9kZWZhdWx0T3B0aW9ucztcclxuICAgICAgICAgICAgICAgIHZhciBfY3VycmVudE9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnM7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9leHRlbnNpb25zOlx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2V4dGVuc2lvbnMgPSB7fTtcclxuICAgICAgICAgICAgICAgIHZhciBfZXh0ZW5zaW9uc1ByaXZhdGVNZXRob2RzID0gJ2FkZGVkIHJlbW92ZWQgb24gY29udHJhY3QnO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vdXBkYXRlXHRcclxuICAgICAgICAgICAgICAgIHZhciBfbGFzdFVwZGF0ZVRpbWU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N3YWxsb3dlZFVwZGF0ZUhpbnRzID0ge307XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N3YWxsb3dlZFVwZGF0ZVRpbWVvdXQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N3YWxsb3dVcGRhdGVMYWcgPSA0MjtcclxuICAgICAgICAgICAgICAgIHZhciBfdXBkYXRlT25Mb2FkRXZlbnROYW1lID0gJ2xvYWQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF91cGRhdGVPbkxvYWRFbG1zID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgLy9ET00gZWxlbWVudHM6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfd2luZG93RWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfZG9jdW1lbnRFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9odG1sRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfYm9keUVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RhcmdldEVsZW1lbnQ7ICAgICAgICAgICAgICAgICAgICAgLy90aGUgdGFyZ2V0IGVsZW1lbnQgb2YgdGhpcyBPdmVybGF5U2Nyb2xsYmFycyBvYmplY3RcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9ob3N0RWxlbWVudDsgICAgICAgICAgICAgICAgICAgICAgIC8vdGhlIGhvc3QgZWxlbWVudCBvZiB0aGlzIE92ZXJsYXlTY3JvbGxiYXJzIG9iamVjdCAtPiBtYXkgYmUgdGhlIHNhbWUgYXMgdGFyZ2V0RWxlbWVudFx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50OyAgICAgICAgICAgLy9vYnNlcnZlcyBzaXplIGF1dG8gY2hhbmdlc1x0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3NpemVPYnNlcnZlckVsZW1lbnQ7ICAgICAgICAgICAgICAgLy9vYnNlcnZlcyBzaXplIGFuZCBwYWRkaW5nIGNoYW5nZXNcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9wYWRkaW5nRWxlbWVudDsgICAgICAgICAgICAgICAgICAgIC8vbWFuYWdlcyB0aGUgcGFkZGluZ1x0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3ZpZXdwb3J0RWxlbWVudDsgICAgICAgICAgICAgICAgICAgLy9pcyB0aGUgdmlld3BvcnQgb2Ygb3VyIHNjcm9sbGJhciBtb2RlbFx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRFbGVtZW50OyAgICAgICAgICAgICAgICAgICAgLy90aGUgZWxlbWVudCB3aGljaCBob2xkcyB0aGUgY29udGVudFx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRBcnJhbmdlRWxlbWVudDsgICAgICAgICAgICAgLy9pcyBuZWVkZWQgZm9yIGNvcnJlY3Qgc2l6aW5nIG9mIHRoZSBjb250ZW50IGVsZW1lbnQgKG9ubHkgaWYgbmF0aXZlIHNjcm9sbGJhcnMgYXJlIG92ZXJsYXlzKVx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRHbHVlRWxlbWVudDsgICAgICAgICAgICAgICAgLy9oYXMgYWx3YXlzIHRoZSBzaXplIG9mIHRoZSBjb250ZW50IGVsZW1lbnRcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF90ZXh0YXJlYUNvdmVyRWxlbWVudDsgICAgICAgICAgICAgIC8vb25seSBhcHBsaWVkIGlmIHRhcmdldCBpcyBhIHRleHRhcmVhIGVsZW1lbnQuIFVzZWQgZm9yIGNvcnJlY3Qgc2l6ZSBjYWxjdWxhdGlvbiBhbmQgZm9yIHByZXZlbnRpb24gb2YgdW5jb250cm9sbGVkIHNjcm9sbGluZ1x0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhckNvcm5lckVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhckhvcml6b250YWxFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJIb3Jpem9udGFsVHJhY2tFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJWZXJ0aWNhbFRyYWNrRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyVmVydGljYWxIYW5kbGVFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF93aW5kb3dFbGVtZW50TmF0aXZlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9kb2N1bWVudEVsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RhcmdldEVsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2hvc3RFbGVtZW50TmF0aXZlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zaXplQXV0b09ic2VydmVyRWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2l6ZU9ic2VydmVyRWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfcGFkZGluZ0VsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3ZpZXdwb3J0RWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfY29udGVudEVsZW1lbnROYXRpdmU7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9DYWNoZTpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9ob3N0U2l6ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jb250ZW50U2Nyb2xsU2l6ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9hcnJhbmdlQ29udGVudFNpemVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfaGFzT3ZlcmZsb3dDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfaGlkZU92ZXJmbG93Q2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3dpZHRoQXV0b0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9oZWlnaHRBdXRvQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Nzc0JveFNpemluZ0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jc3NQYWRkaW5nQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Nzc0JvcmRlckNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jc3NNYXJnaW5DYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfY3NzRGlyZWN0aW9uQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Nzc0RpcmVjdGlvbkRldGVjdGVkQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3BhZGRpbmdBYnNvbHV0ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGlwQWx3YXlzQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRHbHVlU2l6ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9vdmVyZmxvd0JlaGF2aW9yQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX292ZXJmbG93QW1vdW50Q2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2lnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfYXV0b1VwZGF0ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zaXplQXV0b0NhcGFibGVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfY29udGVudEVsZW1lbnRTY3JvbGxTaXplQ2hhbmdlRGV0ZWN0ZWRDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfaG9zdEVsZW1lbnRTaXplQ2hhbmdlRGV0ZWN0ZWRDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc1Zpc2liaWxpdHlDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0F1dG9IaWRlQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzRHJhZ1Njcm9sbGluZ0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9yZXNpemVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfbm9ybWFsaXplUlRMQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9vbGRDbGFzc05hbWU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RleHRhcmVhQXV0b1dyYXBwaW5nQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RleHRhcmVhSW5mb0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF90ZXh0YXJlYVNpemVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfdGV4dGFyZWFEeW5IZWlnaHRDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfdGV4dGFyZWFEeW5XaWR0aENhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9ib2R5TWluU2l6ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF91cGRhdGVBdXRvQ2FjaGUgPSB7fTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL011dGF0aW9uT2JzZXJ2ZXI6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfbXV0YXRpb25PYnNlcnZlckhvc3Q7XHJcbiAgICAgICAgICAgICAgICB2YXIgX211dGF0aW9uT2JzZXJ2ZXJDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tdXRhdGlvbk9ic2VydmVySG9zdENhbGxiYWNrO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tdXRhdGlvbk9ic2VydmVyQ29udGVudENhbGxiYWNrO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tdXRhdGlvbk9ic2VydmVyc0Nvbm5lY3RlZDtcclxuICAgICAgICAgICAgICAgIHZhciBfbXV0YXRpb25PYnNlcnZlckF0dHJzVGV4dGFyZWEgPSBbJ3dyYXAnLCAnY29scycsICdyb3dzJ107XHJcbiAgICAgICAgICAgICAgICB2YXIgX211dGF0aW9uT2JzZXJ2ZXJBdHRyc0hvc3QgPSBbTEVYSUNPTi5pLCBMRVhJQ09OLmMsIExFWElDT04ucywgJ29wZW4nXS5jb25jYXQoX3ZpZXdwb3J0QXR0cnNGcm9tVGFyZ2V0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL2V2ZW50czpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9kZXN0cm95RXZlbnRzID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgLy90ZXh0YXJlYTpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF90ZXh0YXJlYUhhc0ZvY3VzO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vc2Nyb2xsYmFyczpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVUaW1lb3V0SWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmVUaW1lb3V0SWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNBdXRvSGlkZURlbGF5O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVOZXZlcjtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0F1dG9IaWRlU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVMZWF2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0hhbmRsZUhvdmVyZWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vcmVzaXplXHRcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzaXplTm9uZTtcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzaXplQm90aDtcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzaXplSG9yaXpvbnRhbDtcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzaXplVmVydGljYWw7XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBFdmVudCBMaXN0ZW5lciA9PT09Ly9cdFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlx0XHJcbiAgICAgICAgICAgICAgICAgKiBBZGRzIG9yIHJlbW92ZXMgYSBldmVudCBsaXN0ZW5lciBmcm9tIHRoZSBnaXZlbiBlbGVtZW50LiBcdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gd2hpY2ggdGhlIGV2ZW50IGxpc3RlbmVyIHNoYWxsIGJlIGFwcGxpZWQgb3IgcmVtb3ZlZC5cdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50TmFtZXMgVGhlIG5hbWUocykgb2YgdGhlIGV2ZW50cy5cdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGxpc3RlbmVyIFRoZSBtZXRob2Qgd2hpY2ggc2hhbGwgYmUgY2FsbGVkLlx0XHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gcmVtb3ZlIFRydWUgaWYgdGhlIGhhbmRsZXIgc2hhbGwgYmUgcmVtb3ZlZCwgZmFsc2Ugb3IgdW5kZWZpbmVkIGlmIHRoZSBoYW5kbGVyIHNoYWxsIGJlIGFkZGVkLlx0XHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gcGFzc2l2ZU9yT3B0aW9ucyBUaGUgb3B0aW9ucyBmb3IgdGhlIGV2ZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKGVsZW1lbnQsIGV2ZW50TmFtZXMsIGxpc3RlbmVyLCByZW1vdmUsIHBhc3NpdmVPck9wdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29sbGVjdGVkID0gQ09NUEFUSUJJTElUWS5pc0EoZXZlbnROYW1lcykgJiYgQ09NUEFUSUJJTElUWS5pc0EobGlzdGVuZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtZXRob2QgPSByZW1vdmUgPyAncmVtb3ZlRXZlbnRMaXN0ZW5lcicgOiAnYWRkRXZlbnRMaXN0ZW5lcic7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9uT2ZmID0gcmVtb3ZlID8gJ29mZicgOiAnb24nO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBldmVudHMgPSBjb2xsZWN0ZWQgPyBmYWxzZSA6IGV2ZW50TmFtZXMuc3BsaXQoX3N0clNwYWNlKVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhc3NpdmVPck9wdGlvbnNJc09iaiA9IEZSQU1FV09SSy5pc1BsYWluT2JqZWN0KHBhc3NpdmVPck9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXNzaXZlID0gKF9zdXBwb3J0UGFzc2l2ZUV2ZW50cyAmJiAocGFzc2l2ZU9yT3B0aW9uc0lzT2JqID8gKHBhc3NpdmVPck9wdGlvbnMuX3Bhc3NpdmUpIDogcGFzc2l2ZU9yT3B0aW9ucykpIHx8IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjYXB0dXJlID0gcGFzc2l2ZU9yT3B0aW9uc0lzT2JqICYmIChwYXNzaXZlT3JPcHRpb25zLl9jYXB0dXJlIHx8IGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbmF0aXZlUGFyYW0gPSBfc3VwcG9ydFBhc3NpdmVFdmVudHMgPyB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3NpdmU6IHBhc3NpdmUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhcHR1cmU6IGNhcHR1cmUsXHJcbiAgICAgICAgICAgICAgICAgICAgfSA6IGNhcHR1cmU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb2xsZWN0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBldmVudE5hbWVzW0xFWElDT04ubF07IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoZWxlbWVudCwgZXZlbnROYW1lc1tpXSwgbGlzdGVuZXJbaV0sIHJlbW92ZSwgcGFzc2l2ZU9yT3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGV2ZW50c1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKF9zdXBwb3J0UGFzc2l2ZUV2ZW50cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRbMF1bbWV0aG9kXShldmVudHNbaV0sIGxpc3RlbmVyLCBuYXRpdmVQYXJhbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50W29uT2ZmXShldmVudHNbaV0sIGxpc3RlbmVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihlbGVtZW50LCBldmVudE5hbWVzLCBsaXN0ZW5lciwgcGFzc2l2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoZWxlbWVudCwgZXZlbnROYW1lcywgbGlzdGVuZXIsIGZhbHNlLCBwYXNzaXZlKTtcclxuICAgICAgICAgICAgICAgICAgICBfZGVzdHJveUV2ZW50cy5wdXNoKENPTVBBVElCSUxJVFkuYmluZChzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyLCAwLCBlbGVtZW50LCBldmVudE5hbWVzLCBsaXN0ZW5lciwgdHJ1ZSwgcGFzc2l2ZSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBSZXNpemUgT2JzZXJ2ZXIgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBBZGRzIG9yIHJlbW92ZXMgYSByZXNpemUgb2JzZXJ2ZXIgZnJvbSB0aGUgZ2l2ZW4gZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IFRoZSBlbGVtZW50IHRvIHdoaWNoIHRoZSByZXNpemUgb2JzZXJ2ZXIgc2hhbGwgYmUgYWRkZWQgb3IgcmVtb3ZlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBvbkVsZW1lbnRSZXNpemVkQ2FsbGJhY2sgVGhlIGNhbGxiYWNrIHdoaWNoIGlzIGZpcmVkIGV2ZXJ5IHRpbWUgdGhlIHJlc2l6ZSBvYnNlcnZlciByZWdpc3RlcnMgYSBzaXplIGNoYW5nZSBvciBmYWxzZSAvIHVuZGVmaW5lZCBpZiB0aGUgcmVzaXplT2JzZXJ2ZXIgc2hhbGwgYmUgcmVtb3ZlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBSZXNpemVPYnNlcnZlcih0YXJnZXRFbGVtZW50LCBvbkVsZW1lbnRSZXNpemVkQ2FsbGJhY2spIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0RWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzaXplT2JzZXJ2ZXIgPSBDT01QQVRJQklMSVRZLnJPKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJBbmltYXRpb25TdGFydEV2ZW50ID0gJ2FuaW1hdGlvbnN0YXJ0IG1vekFuaW1hdGlvblN0YXJ0IHdlYmtpdEFuaW1hdGlvblN0YXJ0IE1TQW5pbWF0aW9uU3RhcnQnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQ2hpbGROb2RlcyA9ICdjaGlsZE5vZGVzJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnN0U2Nyb2xsID0gMzMzMzMzMztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudFtfc3RyU2Nyb2xsVG9wXShjb25zdFNjcm9sbClbX3N0clNjcm9sbExlZnRdKF9pc1JUTCA/IF9ydGxTY3JvbGxCZWhhdmlvci5uID8gLWNvbnN0U2Nyb2xsIDogX3J0bFNjcm9sbEJlaGF2aW9yLmkgPyAwIDogY29uc3RTY3JvbGwgOiBjb25zdFNjcm9sbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkVsZW1lbnRSZXNpemVkQ2FsbGJhY2soKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hZGQgcmVzaXplIG9ic2VydmVyOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob25FbGVtZW50UmVzaXplZENhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRSZXNpemVPYnNlcnZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gdGFyZ2V0RWxlbWVudC5hZGRDbGFzcygnb2JzZXJ2ZWQnKS5hcHBlbmQoZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCkpLmNvbnRlbnRzKClbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9ic2VydmVyID0gZWxlbWVudFtfc3RyUmVzaXplT2JzZXJ2ZXJQcm9wZXJ0eV0gPSBuZXcgcmVzaXplT2JzZXJ2ZXIoY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9ic2VydmUoZWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX21zaWVWZXJzaW9uID4gOSB8fCAhX2F1dG9VcGRhdGVSZWNvbW1lbmRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50LnByZXBlbmQoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZURpdihfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRlRGl2KHsgYzogX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVySXRlbUVsZW1lbnQsIGRpcjogJ2x0cicgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVySXRlbUVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZURpdihfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJJdGVtRmluYWxFbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVySXRlbUVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZURpdih7IGM6IF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckl0ZW1GaW5hbEVsZW1lbnQsIHN0eWxlOiAnd2lkdGg6IDIwMCU7IGhlaWdodDogMjAwJScgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvYnNlcnZlckVsZW1lbnQgPSB0YXJnZXRFbGVtZW50WzBdW3N0ckNoaWxkTm9kZXNdWzBdW3N0ckNoaWxkTm9kZXNdWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2hyaW5rRWxlbWVudCA9IEZSQU1FV09SSyhvYnNlcnZlckVsZW1lbnRbc3RyQ2hpbGROb2Rlc11bMV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXhwYW5kRWxlbWVudCA9IEZSQU1FV09SSyhvYnNlcnZlckVsZW1lbnRbc3RyQ2hpbGROb2Rlc11bMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXhwYW5kRWxlbWVudENoaWxkID0gRlJBTUVXT1JLKGV4cGFuZEVsZW1lbnRbMF1bc3RyQ2hpbGROb2Rlc11bMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2lkdGhDYWNoZSA9IG9ic2VydmVyRWxlbWVudFtMRVhJQ09OLm9XXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhlaWdodENhY2hlID0gb2JzZXJ2ZXJFbGVtZW50W0xFWElDT04ub0hdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNEaXJ0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJBRklkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VycldpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyckhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZhY3RvciA9IDI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuYXRpdmVTY3JvbGxiYXJTaXplID0gZ2xvYmFscy5uYXRpdmVTY3JvbGxiYXJTaXplOyAvL2NhcmUgZG9uJ3QgbWFrZSBjaGFuZ2VzIHRvIHRoaXMgb2JqZWN0ISEhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNldCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVSZXNldFdpZHRoID0gb2JzZXJ2ZXJFbGVtZW50W0xFWElDT04ub1ddICsgbmF0aXZlU2Nyb2xsYmFyU2l6ZS54ICogZmFjdG9yICsgbmF0aXZlU2Nyb2xsYmFyU2l6ZS55ICogZmFjdG9yICsgX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemUueCArIF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVSZXNldEhlaWdodCA9IG9ic2VydmVyRWxlbWVudFtMRVhJQ09OLm9IXSArIG5hdGl2ZVNjcm9sbGJhclNpemUueCAqIGZhY3RvciArIG5hdGl2ZVNjcm9sbGJhclNpemUueSAqIGZhY3RvciArIF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplLnggKyBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZS55O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleHBhbmRDaGlsZENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZENoaWxkQ1NTW19zdHJXaWR0aF0gPSBzaXplUmVzZXRXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRDaGlsZENTU1tfc3RySGVpZ2h0XSA9IHNpemVSZXNldEhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRFbGVtZW50Q2hpbGQuY3NzKGV4cGFuZENoaWxkQ1NTKTtcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKHNpemVSZXNldFdpZHRoKVtfc3RyU2Nyb2xsVG9wXShzaXplUmVzZXRIZWlnaHQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNocmlua0VsZW1lbnRbX3N0clNjcm9sbExlZnRdKHNpemVSZXNldFdpZHRoKVtfc3RyU2Nyb2xsVG9wXShzaXplUmVzZXRIZWlnaHQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XShjb25zdFNjcm9sbClbX3N0clNjcm9sbFRvcF0oY29uc3RTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hyaW5rRWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oY29uc3RTY3JvbGwpW19zdHJTY3JvbGxUb3BdKGNvbnN0U2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9uUmVzaXplZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJBRklkID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNEaXJ0eSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGhDYWNoZSA9IGN1cnJXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodENhY2hlID0gY3VyckhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvblNjcm9sbCA9IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycldpZHRoID0gb2JzZXJ2ZXJFbGVtZW50W0xFWElDT04ub1ddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyckhlaWdodCA9IG9ic2VydmVyRWxlbWVudFtMRVhJQ09OLm9IXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzRGlydHkgPSBjdXJyV2lkdGggIT0gd2lkdGhDYWNoZSB8fCBjdXJySGVpZ2h0ICE9IGhlaWdodENhY2hlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudCAmJiBpc0RpcnR5ICYmICFyQUZJZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuY0FGKCkockFGSWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJBRklkID0gQ09NUEFUSUJJTElUWS5yQUYoKShvblJlc2l6ZWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoIWV2ZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uUmVzaXplZCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnBydkQoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuc3RwUChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleHBhbmRDaGlsZENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2JzZXJ2ZXJFbGVtZW50Q1NTID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUb3BSaWdodEJvdHRvbUxlZnQob2JzZXJ2ZXJFbGVtZW50Q1NTLCBfc3RyRW1wdHksIFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0oKG5hdGl2ZVNjcm9sbGJhclNpemUueSArIDEpICogZmFjdG9yKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZVNjcm9sbGJhclNpemUueCAqIC1mYWN0b3IsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVTY3JvbGxiYXJTaXplLnkgKiAtZmFjdG9yLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSgobmF0aXZlU2Nyb2xsYmFyU2l6ZS54ICsgMSkgKiBmYWN0b3IpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLKG9ic2VydmVyRWxlbWVudCkuY3NzKG9ic2VydmVyRWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZEVsZW1lbnQub24oX3N0clNjcm9sbCwgb25TY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaHJpbmtFbGVtZW50Lm9uKF9zdHJTY3JvbGwsIG9uU2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5vbihzdHJBbmltYXRpb25TdGFydEV2ZW50LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbChmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2xldHMgYXNzdW1lIHRoYXQgdGhlIGRpdnMgd2lsbCBuZXZlciBiZSB0aGF0IGxhcmdlIGFuZCBhIGNvbnN0YW50IHZhbHVlIGlzIGVub3VnaFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRDaGlsZENTU1tfc3RyV2lkdGhdID0gY29uc3RTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZENoaWxkQ1NTW19zdHJIZWlnaHRdID0gY29uc3RTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZEVsZW1lbnRDaGlsZC5jc3MoZXhwYW5kQ2hpbGRDU1MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRhY2hFdmVudCA9IF9kb2N1bWVudEVsZW1lbnROYXRpdmUuYXR0YWNoRXZlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpc0lFID0gX21zaWVWZXJzaW9uICE9PSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRhY2hFdmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5wcmVwZW5kKGdlbmVyYXRlRGl2KF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckVsZW1lbnQpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmRGaXJzdCh0YXJnZXRFbGVtZW50LCBfc3RyRG90ICsgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudClbMF0uYXR0YWNoRXZlbnQoJ29ucmVzaXplJywgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9iaiA9IF9kb2N1bWVudEVsZW1lbnROYXRpdmUuY3JlYXRlRWxlbWVudChUWVBFUy5vKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5zZXRBdHRyaWJ1dGUoTEVYSUNPTi50aSwgJy0xJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouc2V0QXR0cmlidXRlKExFWElDT04uYywgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmoub25sb2FkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3bmQgPSB0aGlzLmNvbnRlbnREb2N1bWVudC5kZWZhdWx0VmlldztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3bmQuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHduZC5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmoudHlwZSA9ICd0ZXh0L2h0bWwnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzSUUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5wcmVwZW5kKG9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouZGF0YSA9ICdhYm91dDpibGFuayc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzSUUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5wcmVwZW5kKG9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50Lm9uKHN0ckFuaW1hdGlvblN0YXJ0RXZlbnQsIGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0RWxlbWVudFswXSA9PT0gX3NpemVPYnNlcnZlckVsZW1lbnROYXRpdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGlyZWN0aW9uQ2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRpciA9IF9ob3N0RWxlbWVudC5jc3MoJ2RpcmVjdGlvbicpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3NzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxMZWZ0VmFsdWUgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkaXIgIT09IF9jc3NEaXJlY3Rpb25EZXRlY3RlZENhY2hlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlyID09PSAnbHRyJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyTGVmdF0gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyUmlnaHRdID0gX3N0ckF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsTGVmdFZhbHVlID0gY29uc3RTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ckxlZnRdID0gX3N0ckF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJSaWdodF0gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbExlZnRWYWx1ZSA9IF9ydGxTY3JvbGxCZWhhdmlvci5uID8gLWNvbnN0U2Nyb2xsIDogX3J0bFNjcm9sbEJlaGF2aW9yLmkgPyAwIDogY29uc3RTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2V4ZWN1dGlvbiBvcmRlciBpcyBpbXBvcnRhbnQgZm9yIElFISEhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2l6ZU9ic2VydmVyRWxlbWVudC5jaGlsZHJlbigpLmVxKDApLmNzcyhjc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVPYnNlcnZlckVsZW1lbnRbX3N0clNjcm9sbExlZnRdKHNjcm9sbExlZnRWYWx1ZSlbX3N0clNjcm9sbFRvcF0oY29uc3RTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Nzc0RpcmVjdGlvbkRldGVjdGVkQ2FjaGUgPSBkaXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb25DaGFuZ2VkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIodGFyZ2V0RWxlbWVudCwgX3N0clNjcm9sbCwgZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkaXJlY3Rpb25DaGFuZ2VkKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5wcnZEKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIHJlc2l6ZSBvYnNlcnZlcjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRSZXNpemVPYnNlcnZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gdGFyZ2V0RWxlbWVudC5jb250ZW50cygpWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNpemVPYnNlcnZlck9iaiA9IGVsZW1lbnRbX3N0clJlc2l6ZU9ic2VydmVyUHJvcGVydHldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNpemVPYnNlcnZlck9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNpemVPYnNlcnZlck9iai5kaXNjb25uZWN0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBlbGVtZW50W19zdHJSZXNpemVPYnNlcnZlclByb3BlcnR5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUodGFyZ2V0RWxlbWVudC5jaGlsZHJlbihfc3RyRG90ICsgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCkuZXEoMCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogRnJlZXplcyBvciB1bmZyZWV6ZXMgdGhlIGdpdmVuIHJlc2l6ZSBvYnNlcnZlci5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IFRoZSBlbGVtZW50IHRvIHdoaWNoIHRoZSB0YXJnZXQgcmVzaXplIG9ic2VydmVyIGlzIGFwcGxpZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZnJlZXplIFRydWUgaWYgdGhlIHJlc2l6ZSBvYnNlcnZlciBzaGFsbCBiZSBmcm96ZW4sIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGZyZWV6ZVJlc2l6ZU9ic2VydmVyKHRhcmdldEVsZW1lbnQsIGZyZWV6ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXRFbGVtZW50ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYoZnJlZXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRSZXNpemVPYnNlcnZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gdGFyZ2V0RWxlbWVudC5jb250ZW50cygpWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRbX3N0clJlc2l6ZU9ic2VydmVyUHJvcGVydHldLnVub2JzZXJ2ZShlbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQgPSB0YXJnZXRFbGVtZW50LmNoaWxkcmVuKF9zdHJEb3QgKyBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJFbGVtZW50KS5lcSgwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdyA9IHRhcmdldEVsZW1lbnQuY3NzKF9zdHJXaWR0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGggPSB0YXJnZXRFbGVtZW50LmNzcyhfc3RySGVpZ2h0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3NzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJXaWR0aF0gPSB3O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RySGVpZ2h0XSA9IGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5jc3MoY3NzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydFJlc2l6ZU9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSB0YXJnZXRFbGVtZW50LmNvbnRlbnRzKClbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFtfc3RyUmVzaXplT2JzZXJ2ZXJQcm9wZXJ0eV0ub2JzZXJ2ZShlbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjc3MgPSB7IH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJIZWlnaHRdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyV2lkdGhdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQuY2hpbGRyZW4oX3N0ckRvdCArIF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckVsZW1lbnQpLmVxKDApLmNzcyhjc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgKi9cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IE11dGF0aW9uIE9ic2VydmVycyA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENyZWF0ZXMgTXV0YXRpb25PYnNlcnZlcnMgZm9yIHRoZSBob3N0IGFuZCBjb250ZW50IEVsZW1lbnQgaWYgdGhleSBhcmUgc3VwcG9ydGVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBjcmVhdGVNdXRhdGlvbk9ic2VydmVycygpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRNdXRhdGlvbk9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtdXRhdGlvbk9ic2VydmVyQ29udGVudExhZyA9IDExO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXV0YXRpb25PYnNlcnZlciA9IENPTVBBVElCSUxJVFkubU8oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRMYXN0VXBkYXRlID0gQ09NUEFUSUJJTElUWS5ub3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uVGFyZ2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXV0YXRpb25BdHRyTmFtZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uSXNDbGFzcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9sZE11dGF0aW9uVmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3Q2xhc3NWYWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBob3N0Q2xhc3NOYW1lUmVnZXg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50VGltZW91dDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vdztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWN0aW9uO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX211dGF0aW9uT2JzZXJ2ZXJIb3N0Q2FsbGJhY2sgPSBmdW5jdGlvbiAobXV0YXRpb25zKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRvVXBkYXRlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZG9VcGRhdGVGb3JjZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0ZWRBdHRycyA9IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaW5pdGlhbGl6ZWQgJiYgIV9zbGVlcGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2gobXV0YXRpb25zLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0aW9uID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRpb25UYXJnZXQgPSBtdXRhdGlvbi50YXJnZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0aW9uQXR0ck5hbWUgPSBtdXRhdGlvbi5hdHRyaWJ1dGVOYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGlvbklzQ2xhc3MgPSBtdXRhdGlvbkF0dHJOYW1lID09PSBMRVhJQ09OLmM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZE11dGF0aW9uVmFsID0gbXV0YXRpb24ub2xkVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0NsYXNzVmFsID0gbXV0YXRpb25UYXJnZXQuY2xhc3NOYW1lO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9kb21FeGlzdHMgJiYgbXV0YXRpb25Jc0NsYXNzICYmICFkb1VwZGF0ZUZvcmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBvbGQgY2xhc3MgdmFsdWUgY29udGFpbnMgX2NsYXNzTmFtZUhvc3RFbGVtZW50Rm9yZWlnbiBhbmQgbmV3IGNsYXNzIHZhbHVlIGRvZXNuJ3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbGRNdXRhdGlvblZhbC5pbmRleE9mKF9jbGFzc05hbWVIb3N0RWxlbWVudEZvcmVpZ24pID4gLTEgJiYgbmV3Q2xhc3NWYWwuaW5kZXhPZihfY2xhc3NOYW1lSG9zdEVsZW1lbnRGb3JlaWduKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3N0Q2xhc3NOYW1lUmVnZXggPSBjcmVhdGVIb3N0Q2xhc3NOYW1lUmVnRXhwKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudE5hdGl2ZS5jbGFzc05hbWUgPSBuZXdDbGFzc1ZhbC5zcGxpdChfc3RyU3BhY2UpLmNvbmNhdChvbGRNdXRhdGlvblZhbC5zcGxpdChfc3RyU3BhY2UpLmZpbHRlcihmdW5jdGlvbiAobmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmFtZS5tYXRjaChob3N0Q2xhc3NOYW1lUmVnZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKS5qb2luKF9zdHJTcGFjZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9VcGRhdGUgPSBkb1VwZGF0ZUZvcmNlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFkb1VwZGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9VcGRhdGUgPSBtdXRhdGlvbklzQ2xhc3NcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGhvc3RDbGFzc05hbWVzQ2hhbmdlZChvbGRNdXRhdGlvblZhbCwgbmV3Q2xhc3NWYWwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBtdXRhdGlvbkF0dHJOYW1lID09PSBMRVhJQ09OLnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBvbGRNdXRhdGlvblZhbCAhPT0gbXV0YXRpb25UYXJnZXRbTEVYSUNPTi5zXS5jc3NUZXh0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlZEF0dHJzLnB1c2gobXV0YXRpb25BdHRyTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZVZpZXdwb3J0QXR0cnNGcm9tVGFyZ2V0KG11dGF0ZWRBdHRycyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1VwZGF0ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlKGRvVXBkYXRlRm9yY2UgfHwgX3N0ckF1dG8pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvVXBkYXRlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnRDYWxsYmFjayA9IGZ1bmN0aW9uIChtdXRhdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkb1VwZGF0ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaW5pdGlhbGl6ZWQgJiYgIV9zbGVlcGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2gobXV0YXRpb25zLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0aW9uID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9VcGRhdGUgPSBpc1Vua25vd25NdXRhdGlvbihtdXRhdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAhZG9VcGRhdGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1VwZGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3cgPSBDT01QQVRJQklMSVRZLm5vdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplQXV0byA9IChfaGVpZ2h0QXV0b0NhY2hlIHx8IF93aWR0aEF1dG9DYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2Rlc3Ryb3llZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRMYXN0VXBkYXRlID0gbm93O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIGNvbHMsIHJvd3Mgb3Igd3JhcCBhdHRyIHdhcyBjaGFuZ2VkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYVVwZGF0ZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlKF9zdHJBdXRvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KGNvbnRlbnRUaW1lb3V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG11dGF0aW9uT2JzZXJ2ZXJDb250ZW50TGFnIDw9IDAgfHwgbm93IC0gY29udGVudExhc3RVcGRhdGUgPiBtdXRhdGlvbk9ic2VydmVyQ29udGVudExhZyB8fCAhc2l6ZUF1dG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFRpbWVvdXQgPSBzZXRUaW1lb3V0KGFjdGlvbiwgbXV0YXRpb25PYnNlcnZlckNvbnRlbnRMYWcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkb1VwZGF0ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX211dGF0aW9uT2JzZXJ2ZXJIb3N0ID0gbmV3IG11dGF0aW9uT2JzZXJ2ZXIoX211dGF0aW9uT2JzZXJ2ZXJIb3N0Q2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnQgPSBuZXcgbXV0YXRpb25PYnNlcnZlcihfbXV0YXRpb25PYnNlcnZlckNvbnRlbnRDYWxsYmFjayk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQ29ubmVjdHMgdGhlIE11dGF0aW9uT2JzZXJ2ZXJzIGlmIHRoZXkgYXJlIHN1cHBvcnRlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXJzKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydE11dGF0aW9uT2JzZXJ2ZXIgJiYgIV9tdXRhdGlvbk9ic2VydmVyc0Nvbm5lY3RlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckhvc3Qub2JzZXJ2ZShfaG9zdEVsZW1lbnROYXRpdmUsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVPbGRWYWx1ZTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUZpbHRlcjogX211dGF0aW9uT2JzZXJ2ZXJBdHRyc0hvc3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnQub2JzZXJ2ZShfaXNUZXh0YXJlYSA/IF90YXJnZXRFbGVtZW50TmF0aXZlIDogX2NvbnRlbnRFbGVtZW50TmF0aXZlLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlT2xkVmFsdWU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0cmVlOiAhX2lzVGV4dGFyZWEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZExpc3Q6ICFfaXNUZXh0YXJlYSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlckRhdGE6ICFfaXNUZXh0YXJlYSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUZpbHRlcjogX2lzVGV4dGFyZWEgPyBfbXV0YXRpb25PYnNlcnZlckF0dHJzVGV4dGFyZWEgOiBfbXV0YXRpb25PYnNlcnZlckF0dHJzSG9zdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9tdXRhdGlvbk9ic2VydmVyc0Nvbm5lY3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogRGlzY29ubmVjdHMgdGhlIE11dGF0aW9uT2JzZXJ2ZXJzIGlmIHRoZXkgYXJlIHN1cHBvcnRlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZGlzY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXJzKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydE11dGF0aW9uT2JzZXJ2ZXIgJiYgX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9tdXRhdGlvbk9ic2VydmVySG9zdC5kaXNjb25uZWN0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9tdXRhdGlvbk9ic2VydmVyQ29udGVudC5kaXNjb25uZWN0KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBFdmVudHMgb2YgZWxlbWVudHMgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBUaGlzIG1ldGhvZCBnZXRzIGNhbGxlZCBldmVyeSB0aW1lIHRoZSBob3N0IGVsZW1lbnQgZ2V0cyByZXNpemVkLiBJTVBPUlRBTlQ6IFBhZGRpbmcgY2hhbmdlcyBhcmUgZGV0ZWN0ZWQgdG9vISFcclxuICAgICAgICAgICAgICAgICAqIEl0IHJlZnJlc2hlcyB0aGUgaG9zdFJlc2l6ZWRFdmVudEFyZ3MgYW5kIHRoZSBob3N0U2l6ZVJlc2l6ZUNhY2hlLlxyXG4gICAgICAgICAgICAgICAgICogSWYgdGhlcmUgYXJlIGFueSBzaXplIGNoYW5nZXMsIHRoZSB1cGRhdGUgbWV0aG9kIGdldHMgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBob3N0T25SZXNpemVkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghX3NsZWVwaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGFuZ2VkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBfc2l6ZU9ic2VydmVyRWxlbWVudE5hdGl2ZVtMRVhJQ09OLnNXXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IF9zaXplT2JzZXJ2ZXJFbGVtZW50TmF0aXZlW0xFWElDT04uc0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VkID0gY2hlY2tDYWNoZShob3N0U2l6ZSwgX2hvc3RFbGVtZW50U2l6ZUNoYW5nZURldGVjdGVkQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnRTaXplQ2hhbmdlRGV0ZWN0ZWRDYWNoZSA9IGhvc3RTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbmdlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZSh7IF9ob3N0U2l6ZUNoYW5nZWQ6IHRydWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVGhlIG1vdXNlIGVudGVyIGV2ZW50IG9mIHRoZSBob3N0IGVsZW1lbnQuIFRoaXMgZXZlbnQgaXMgb25seSBuZWVkZWQgZm9yIHRoZSBhdXRvSGlkZSBmZWF0dXJlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBob3N0T25Nb3VzZUVudGVyKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlTGVhdmUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBUaGUgbW91c2UgbGVhdmUgZXZlbnQgb2YgdGhlIGhvc3QgZWxlbWVudC4gVGhpcyBldmVudCBpcyBvbmx5IG5lZWRlZCBmb3IgdGhlIGF1dG9IaWRlIGZlYXR1cmUuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGhvc3RPbk1vdXNlTGVhdmUoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJzQXV0b0hpZGVMZWF2ZSAmJiAhX2JvZHlFbGVtZW50Lmhhc0NsYXNzKF9jbGFzc05hbWVEcmFnZ2luZykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVGhlIG1vdXNlIG1vdmUgZXZlbnQgb2YgdGhlIGhvc3QgZWxlbWVudC4gVGhpcyBldmVudCBpcyBvbmx5IG5lZWRlZCBmb3IgdGhlIGF1dG9IaWRlIFwibW92ZVwiIGZlYXR1cmUuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGhvc3RPbk1vdXNlTW92ZSgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlVGltZW91dElkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmVUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSAmJiAhX2Rlc3Ryb3llZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc0F1dG9IaWRlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBQcmV2ZW50cyB0ZXh0IGZyb20gZGVzZWxlY3Rpb24gaWYgYXR0YWNoZWQgdG8gdGhlIGRvY3VtZW50IGVsZW1lbnQgb24gdGhlIG1vdXNlZG93biBldmVudCBvZiBhIERPTSBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50IFRoZSBzZWxlY3Qgc3RhcnQgZXZlbnQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRvY3VtZW50T25TZWxlY3RTdGFydChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlx0XHJcbiAgICAgICAgICAgICAgICAgKiBBIGNhbGxiYWNrIHdoaWNoIHdpbGwgYmUgY2FsbGVkIGFmdGVyIGEgZWxlbWVudCBoYXMgbG9hZGVkLlx0XHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZU9uTG9hZENhbGxiYWNrKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsbSA9IEZSQU1FV09SSyhldmVudC50YXJnZXQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBlYWNoVXBkYXRlT25Mb2FkKGZ1bmN0aW9uIChpLCB1cGRhdGVPbkxvYWRTZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxtLmlzKHVwZGF0ZU9uTG9hZFNlbGVjdG9yKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKHsgX2NvbnRlbnRTaXplQ2hhbmdlZDogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgKiBBZGRzIG9yIHJlbW92ZXMgbW91c2UgJiB0b3VjaCBldmVudHMgb2YgdGhlIGhvc3QgZWxlbWVudC4gKGZvciBoYW5kbGluZyBhdXRvLWhpZGluZyBvZiB0aGUgc2Nyb2xsYmFycylcclxuICAgICAgICAgICAgICAgICogQHBhcmFtIGRlc3Ryb3kgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGV2ZW50cyBzaGFsbCBiZSBhZGRlZCBvciByZW1vdmVkLlxyXG4gICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldHVwSG9zdE1vdXNlVG91Y2hFdmVudHMoZGVzdHJveSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZGVzdHJveSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBIb3N0TW91c2VUb3VjaEV2ZW50cyh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfaG9zdEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJNb3VzZVRvdWNoTW92ZUV2ZW50LnNwbGl0KF9zdHJTcGFjZSlbMF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RPbk1vdXNlTW92ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgKCFfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSB8fCBkZXN0cm95KSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfaG9zdEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtfc3RyTW91c2VFbnRlciwgX3N0ck1vdXNlTGVhdmVdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbaG9zdE9uTW91c2VFbnRlciwgaG9zdE9uTW91c2VMZWF2ZV0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICghX3Njcm9sbGJhcnNBdXRvSGlkZUxlYXZlIHx8IGRlc3Ryb3kpLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9pZiB0aGUgcGx1Z2luIGlzIGluaXRpYWxpemVkIGFuZCB0aGUgbW91c2UgaXMgb3ZlciB0aGUgaG9zdCBlbGVtZW50LCBtYWtlIHRoZSBzY3JvbGxiYXJzIHZpc2libGVcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIV9pbml0aWFsaXplZCAmJiAhZGVzdHJveSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50Lm9uZSgnbW91c2VvdmVyJywgaG9zdE9uTW91c2VFbnRlcik7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBVcGRhdGUgRGV0ZWN0aW9uID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogTWVhc3VyZXMgdGhlIG1pbiB3aWR0aCBhbmQgbWluIGhlaWdodCBvZiB0aGUgYm9keSBlbGVtZW50IGFuZCByZWZyZXNoZXMgdGhlIHJlbGF0ZWQgY2FjaGUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgbWluIHdpZHRoIG9yIG1pbiBoZWlnaHQgaGFzIGNoYW5nZWQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gYm9keU1pblNpemVDaGFuZ2VkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBib2R5TWluU2l6ZSA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNCb2R5ICYmIF9jb250ZW50QXJyYW5nZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keU1pblNpemUudyA9IHBhcnNlVG9aZXJvT3JOdW1iZXIoX2NvbnRlbnRBcnJhbmdlRWxlbWVudC5jc3MoX3N0ck1pbk1pbnVzICsgX3N0cldpZHRoKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHlNaW5TaXplLmggPSBwYXJzZVRvWmVyb09yTnVtYmVyKF9jb250ZW50QXJyYW5nZUVsZW1lbnQuY3NzKF9zdHJNaW5NaW51cyArIF9zdHJIZWlnaHQpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keU1pblNpemUuYyA9IGNoZWNrQ2FjaGUoYm9keU1pblNpemUsIF9ib2R5TWluU2l6ZUNhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keU1pblNpemUuZiA9IHRydWU7IC8vZmxhZyBmb3IgXCJtZWFzdXJlZCBhdCBsZWFzdCBvbmNlXCJcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgX2JvZHlNaW5TaXplQ2FjaGUgPSBib2R5TWluU2l6ZTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gISFib2R5TWluU2l6ZS5jO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBjbGFzcyBuYW1lcyByZWFsbHkgY2hhbmdlZCAobmV3IGNsYXNzIHdpdGhvdXQgcGx1Z2luIGhvc3QgcHJlZml4KVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG9sZENsYXNzTmFtZXMgVGhlIG9sZCBDbGFzc05hbWUgc3RyaW5nIG9yIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG5ld0NsYXNzTmFtZXMgVGhlIG5ldyBDbGFzc05hbWUgc3RyaW5nIG9yIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGNsYXNzIG5hbWVzIGhhcyByZWFsbHkgY2hhbmdlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBob3N0Q2xhc3NOYW1lc0NoYW5nZWQob2xkQ2xhc3NOYW1lcywgbmV3Q2xhc3NOYW1lcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyQ2xhc3NlcyA9IHR5cGVvZiBuZXdDbGFzc05hbWVzID09IFRZUEVTLnMgPyBuZXdDbGFzc05hbWVzLnNwbGl0KF9zdHJTcGFjZSkgOiBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb2xkQ2xhc3NlcyA9IHR5cGVvZiBvbGRDbGFzc05hbWVzID09IFRZUEVTLnMgPyBvbGRDbGFzc05hbWVzLnNwbGl0KF9zdHJTcGFjZSkgOiBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZGlmZiA9IGdldEFycmF5RGlmZmVyZW5jZXMob2xkQ2xhc3NlcywgY3VyckNsYXNzZXMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgbm9uZSB0aGVtZSBmcm9tIGRpZmYgbGlzdCB0byBwcmV2ZW50IHVwZGF0ZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpZHggPSBpbkFycmF5KF9jbGFzc05hbWVUaGVtZU5vbmUsIGRpZmYpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWdleDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlkeCA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaWZmLnNwbGljZShpZHgsIDEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZGlmZltMRVhJQ09OLmxdID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWdleCA9IGNyZWF0ZUhvc3RDbGFzc05hbWVSZWdFeHAodHJ1ZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBkaWZmLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWRpZmZbaV0ubWF0Y2gocmVnZXgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtdXRhdGlvbiBpcyBub3QgZnJvbSBhIGZyb20gdGhlIHBsdWdpbiBnZW5lcmF0ZWQgZWxlbWVudC4gSWYgdGhlIHRhcmdldCBlbGVtZW50IGlzIGEgdGV4dGFyZWEgdGhlIG11dGF0aW9uIGlzIGFsd2F5cyB1bmtub3duLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG11dGF0aW9uIFRoZSBtdXRhdGlvbiB3aGljaCBzaGFsbCBiZSBjaGVja2VkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIG11dGF0aW9uIGlzIGZyb20gYSB1bmtub3duIGVsZW1lbnQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gaXNVbmtub3duTXV0YXRpb24obXV0YXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cmlidXRlTmFtZSA9IG11dGF0aW9uLmF0dHJpYnV0ZU5hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uVGFyZ2V0ID0gbXV0YXRpb24udGFyZ2V0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtdXRhdGlvblR5cGUgPSBtdXRhdGlvbi50eXBlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJDbG9zZXN0ID0gJ2Nsb3Nlc3QnO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAobXV0YXRpb25UYXJnZXQgPT09IF9jb250ZW50RWxlbWVudE5hdGl2ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZU5hbWUgPT09IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG11dGF0aW9uVHlwZSA9PT0gJ2F0dHJpYnV0ZXMnICYmIChhdHRyaWJ1dGVOYW1lID09PSBMRVhJQ09OLmMgfHwgYXR0cmlidXRlTmFtZSA9PT0gTEVYSUNPTi5zKSAmJiAhX2lzVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9pZ25vcmUgY2xhc3NOYW1lIGNoYW5nZXMgYnkgdGhlIHBsdWdpblx0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVOYW1lID09PSBMRVhJQ09OLmMgJiYgRlJBTUVXT1JLKG11dGF0aW9uVGFyZ2V0KS5oYXNDbGFzcyhfY2xhc3NOYW1lSG9zdEVsZW1lbnQpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhvc3RDbGFzc05hbWVzQ2hhbmdlZChtdXRhdGlvbi5vbGRWYWx1ZSwgbXV0YXRpb25UYXJnZXQuY2xhc3NOYW1lKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vb25seSBkbyBpdCBvZiBicm93c2VyIHN1cHBvcnQgaXQgbmF0aXZlbHlcdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG11dGF0aW9uVGFyZ2V0W3N0ckNsb3Nlc3RdICE9IFRZUEVTLmYpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG11dGF0aW9uVGFyZ2V0W3N0ckNsb3Nlc3RdKF9zdHJEb3QgKyBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJFbGVtZW50KSAhPT0gbnVsbCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRpb25UYXJnZXRbc3RyQ2xvc2VzdF0oX3N0ckRvdCArIF9jbGFzc05hbWVTY3JvbGxiYXIpICE9PSBudWxsIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGlvblRhcmdldFtzdHJDbG9zZXN0XShfc3RyRG90ICsgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lcikgIT09IG51bGwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBjb250ZW50IHNpemUgd2FzIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgdGltZSB0aGlzIG1ldGhvZCB3YXMgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGNvbnRlbnQgc2l6ZSB3YXMgY2hhbmdlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiB1cGRhdGVBdXRvQ29udGVudFNpemVDaGFuZ2VkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc2xlZXBpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRNZWFzdXJlRWxlbWVudCA9IGdldENvbnRlbnRNZWFzdXJlRWxlbWVudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYVZhbHVlTGVuZ3RoID0gX2lzVGV4dGFyZWEgJiYgX3dpZHRoQXV0b0NhY2hlICYmICFfdGV4dGFyZWFBdXRvV3JhcHBpbmdDYWNoZSA/IF90YXJnZXRFbGVtZW50LnZhbCgpLmxlbmd0aCA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNldENTUyA9ICFfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQgJiYgX3dpZHRoQXV0b0NhY2hlICYmICFfaXNUZXh0YXJlYTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3NzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZsb2F0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBib2R5TWluU2l6ZUM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoYW5nZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNldENTUykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmbG9hdCA9IF9jb250ZW50RWxlbWVudC5jc3MoX3N0ckZsb2F0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJGbG9hdF0gPSBfaXNSVEwgPyBfc3RyUmlnaHQgOiBfc3RyTGVmdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJXaWR0aF0gPSBfc3RyQXV0bztcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhjc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudFNjcm9sbFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHc6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNXXSArIHRleHRhcmVhVmFsdWVMZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGg6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNIXSArIHRleHRhcmVhVmFsdWVMZW5ndGhcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXRDU1MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJGbG9hdF0gPSBmbG9hdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJXaWR0aF0gPSBfc3RySHVuZHJlZFBlcmNlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoY3NzKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGJvZHlNaW5TaXplQyA9IGJvZHlNaW5TaXplQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNoYW5nZWQgPSBjaGVja0NhY2hlKGNvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZSwgX2NvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZUNoYW5nZURldGVjdGVkQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnRTY3JvbGxTaXplQ2hhbmdlRGV0ZWN0ZWRDYWNoZSA9IGNvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoYW5nZWQgfHwgYm9keU1pblNpemVDO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIHdoZW4gYSBhdHRyaWJ1dGUgd2hpY2ggdGhlIE11dGF0aW9uT2JzZXJ2ZXIgd291bGQgb2JzZXJ2ZSBoYXMgY2hhbmdlZC4gIFxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgb25lIG9mIHRoZSBhdHRyaWJ1dGVzIHdoaWNoIGEgTXV0YXRpb25PYnNlcnZlciB3b3VsZCBvYnNlcnZlIGhhcyBjaGFuZ2VkLCBmYWxzZSBvciB1bmRlZmluZWQgb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBtZWFuaW5nZnVsQXR0cnNDaGFuZ2VkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc2xlZXBpbmcgfHwgX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGVtO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjYWNoZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hhbmdlZEF0dHJzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoZWNrcyA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2VsZW06IF9ob3N0RWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9hdHRyczogX211dGF0aW9uT2JzZXJ2ZXJBdHRyc0hvc3QuY29uY2F0KCc6dmlzaWJsZScpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9lbGVtOiBfaXNUZXh0YXJlYSA/IF90YXJnZXRFbGVtZW50IDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2F0dHJzOiBfbXV0YXRpb25PYnNlcnZlckF0dHJzVGV4dGFyZWFcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGVhY2goY2hlY2tzLCBmdW5jdGlvbiAoaW5kZXgsIGNoZWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0gPSBjaGVjay5fZWxlbTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2goY2hlY2suX2F0dHJzLCBmdW5jdGlvbiAoaW5kZXgsIGF0dHIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyID0gYXR0ci5jaGFyQXQoMCkgPT09ICc6JyA/IGVsZW0uaXMoYXR0cikgOiBlbGVtLmF0dHIoYXR0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUgPSBfdXBkYXRlQXV0b0NhY2hlW2F0dHJdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hlY2tDYWNoZShjdXJyLCBjYWNoZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlZEF0dHJzLnB1c2goYXR0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdXBkYXRlQXV0b0NhY2hlW2F0dHJdID0gY3VycjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZVZpZXdwb3J0QXR0cnNGcm9tVGFyZ2V0KGNoYW5nZWRBdHRycyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjaGFuZ2VkQXR0cnNbTEVYSUNPTi5sXSA+IDA7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDaGVja3MgaXMgYSBDU1MgUHJvcGVydHkgb2YgYSBjaGlsZCBlbGVtZW50IGlzIGFmZmVjdGluZyB0aGUgc2Nyb2xsIHNpemUgb2YgdGhlIGNvbnRlbnQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lIFRoZSBDU1MgcHJvcGVydHkgbmFtZS5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBwcm9wZXJ0eSBpcyBhZmZlY3RpbmcgdGhlIGNvbnRlbnQgc2Nyb2xsIHNpemUsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gaXNTaXplQWZmZWN0aW5nQ1NTUHJvcGVydHkocHJvcGVydHlOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFfaW5pdGlhbGl6ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmbGV4R3JvdyA9ICdmbGV4LWdyb3cnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmbGV4U2hyaW5rID0gJ2ZsZXgtc2hyaW5rJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZmxleEJhc2lzID0gJ2ZsZXgtYmFzaXMnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhZmZlY3RpbmdQcm9wc1ggPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJXaWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ck1pbk1pbnVzICsgX3N0cldpZHRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWF4TWludXMgKyBfc3RyV2lkdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJNYXJnaW5NaW51cyArIF9zdHJMZWZ0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWFyZ2luTWludXMgKyBfc3RyUmlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJMZWZ0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyUmlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdmb250LXdlaWdodCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICd3b3JkLXNwYWNpbmcnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmbGV4R3JvdyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleFNocmluayxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleEJhc2lzXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWZmZWN0aW5nUHJvcHNYQ29udGVudEJveCA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0clBhZGRpbmdNaW51cyArIF9zdHJMZWZ0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyUGFkZGluZ01pbnVzICsgX3N0clJpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyQm9yZGVyTWludXMgKyBfc3RyTGVmdCArIF9zdHJXaWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ckJvcmRlck1pbnVzICsgX3N0clJpZ2h0ICsgX3N0cldpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWZmZWN0aW5nUHJvcHNZID0gW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RySGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWluTWludXMgKyBfc3RySGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWF4TWludXMgKyBfc3RySGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWFyZ2luTWludXMgKyBfc3RyVG9wLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWFyZ2luTWludXMgKyBfc3RyQm90dG9tLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyVG9wLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyQm90dG9tLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAnbGluZS1oZWlnaHQnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmbGV4R3JvdyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleFNocmluayxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleEJhc2lzXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWZmZWN0aW5nUHJvcHNZQ29udGVudEJveCA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0clBhZGRpbmdNaW51cyArIF9zdHJUb3AsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJQYWRkaW5nTWludXMgKyBfc3RyQm90dG9tLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyQm9yZGVyTWludXMgKyBfc3RyVG9wICsgX3N0cldpZHRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyQm9yZGVyTWludXMgKyBfc3RyQm90dG9tICsgX3N0cldpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgX3N0clMgPSAncyc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIF9zdHJWUyA9ICd2LXMnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGVja1ggPSBfb3ZlcmZsb3dCZWhhdmlvckNhY2hlLnggPT09IF9zdHJTIHx8IF9vdmVyZmxvd0JlaGF2aW9yQ2FjaGUueCA9PT0gX3N0clZTO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGVja1kgPSBfb3ZlcmZsb3dCZWhhdmlvckNhY2hlLnkgPT09IF9zdHJTIHx8IF9vdmVyZmxvd0JlaGF2aW9yQ2FjaGUueSA9PT0gX3N0clZTO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzaXplSXNBZmZlY3RlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGVja1Byb3BlcnR5TmFtZSA9IGZ1bmN0aW9uIChhcnIsIG5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnJbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyW2ldID09PSBuYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hlY2tZKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVJc0FmZmVjdGVkID0gY2hlY2tQcm9wZXJ0eU5hbWUoYWZmZWN0aW5nUHJvcHNZLCBwcm9wZXJ0eU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNpemVJc0FmZmVjdGVkICYmICFfaXNCb3JkZXJCb3gpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplSXNBZmZlY3RlZCA9IGNoZWNrUHJvcGVydHlOYW1lKGFmZmVjdGluZ1Byb3BzWUNvbnRlbnRCb3gsIHByb3BlcnR5TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGVja1ggJiYgIXNpemVJc0FmZmVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVJc0FmZmVjdGVkID0gY2hlY2tQcm9wZXJ0eU5hbWUoYWZmZWN0aW5nUHJvcHNYLCBwcm9wZXJ0eU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNpemVJc0FmZmVjdGVkICYmICFfaXNCb3JkZXJCb3gpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplSXNBZmZlY3RlZCA9IGNoZWNrUHJvcGVydHlOYW1lKGFmZmVjdGluZ1Byb3BzWENvbnRlbnRCb3gsIHByb3BlcnR5TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzaXplSXNBZmZlY3RlZDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IFVwZGF0ZSA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNldHMgdGhlIGF0dHJpYnV0ZSB2YWx1ZXMgb2YgdGhlIHZpZXdwb3J0IGVsZW1lbnQgdG8gdGhlIHZhbHVlcyBmcm9tIHRoZSB0YXJnZXQgZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIFRoZSB2YWx1ZSBvZiBhIGF0dHJpYnV0ZSBpcyBvbmx5IHNldCBpZiB0aGUgYXR0cmlidXRlIGlzIHdoaXRlbGlzdGVkLlxyXG4gICAgICAgICAgICAgICAgICogQGF0dHJzIGF0dHJzIFRoZSBhcnJheSBvZiBhdHRyaWJ1dGVzIHdoaWNoIHNoYWxsIGJlIHNldCBvciB1bmRlZmluZWQgaWYgYWxsIHdoaXRlbGlzdGVkIHNoYWxsIGJlIHNldC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gdXBkYXRlVmlld3BvcnRBdHRyc0Zyb21UYXJnZXQoYXR0cnMpIHtcclxuICAgICAgICAgICAgICAgICAgICBhdHRycyA9IGF0dHJzIHx8IF92aWV3cG9ydEF0dHJzRnJvbVRhcmdldDtcclxuICAgICAgICAgICAgICAgICAgICBlYWNoKGF0dHJzLCBmdW5jdGlvbiAoaW5kZXgsIGF0dHIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkuaW5BKGF0dHIsIF92aWV3cG9ydEF0dHJzRnJvbVRhcmdldCkgPiAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRhcmdldEF0dHIgPSBfdGFyZ2V0RWxlbWVudC5hdHRyKGF0dHIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUodGFyZ2V0QXR0cikgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuYXR0cihhdHRyLCB0YXJnZXRBdHRyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQucmVtb3ZlQXR0cihhdHRyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVXBkYXRlcyB0aGUgdmFyaWFibGVzIGFuZCBzaXplIG9mIHRoZSB0ZXh0YXJlYSBlbGVtZW50LCBhbmQgbWFuYWdlcyB0aGUgc2Nyb2xsIG9uIG5ldyBsaW5lIG9yIG5ldyBjaGFyYWN0ZXIuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHRleHRhcmVhVXBkYXRlKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghX3NsZWVwaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3cmFwQXR0ck9mZiA9ICFfdGV4dGFyZWFBdXRvV3JhcHBpbmdDYWNoZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1pbldpZHRoID0gX3ZpZXdwb3J0U2l6ZS53O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWluSGVpZ2h0ID0gX3ZpZXdwb3J0U2l6ZS5oO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3NzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkb01lYXN1cmUgPSBfd2lkdGhBdXRvQ2FjaGUgfHwgd3JhcEF0dHJPZmY7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcmlnV2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9yaWdIZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoZWlnaHQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc2V0IG1pbiBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyTWluTWludXMgKyBfc3RyV2lkdGhdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ck1pbk1pbnVzICsgX3N0ckhlaWdodF0gPSBfc3RyRW1wdHk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NldCB3aWR0aCBhdXRvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyV2lkdGhdID0gX3N0ckF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LmNzcyhjc3MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tZWFzdXJlIHdpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdXaWR0aCA9IF90YXJnZXRFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IGRvTWVhc3VyZSA/IE1BVEgubWF4KG9yaWdXaWR0aCwgX3RhcmdldEVsZW1lbnROYXRpdmVbTEVYSUNPTi5zV10gLSAxKSA6IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qd2lkdGggKz0gKF93aWR0aEF1dG9DYWNoZSA/IF9tYXJnaW5YICsgKCFfaXNCb3JkZXJCb3ggPyB3cmFwQXR0ck9mZiA/IDAgOiBfcGFkZGluZ1ggKyBfYm9yZGVyWCA6IDApIDogMCk7Ki9cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vc2V0IG1lYXN1cmVkIHdpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyV2lkdGhdID0gX3dpZHRoQXV0b0NhY2hlID8gX3N0ckF1dG8gLyp3aWR0aCovIDogX3N0ckh1bmRyZWRQZXJjZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ck1pbk1pbnVzICsgX3N0cldpZHRoXSA9IF9zdHJIdW5kcmVkUGVyY2VudDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vc2V0IGhlaWdodCBhdXRvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RySGVpZ2h0XSA9IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0RWxlbWVudC5jc3MoY3NzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWVhc3VyZSBoZWlnaHRcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ0hlaWdodCA9IF90YXJnZXRFbGVtZW50TmF0aXZlW0xFWElDT04ub0hdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQgPSBNQVRILm1heChvcmlnSGVpZ2h0LCBfdGFyZ2V0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLnNIXSAtIDEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hcHBlbmQgY29ycmVjdCBzaXplIHZhbHVlc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0cldpZHRoXSA9IHdpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ckhlaWdodF0gPSBoZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUNvdmVyRWxlbWVudC5jc3MoY3NzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYXBwbHkgbWluIHdpZHRoIC8gbWluIGhlaWdodCB0byBwcmV2ZW50IHRleHRhcmVhIGNvbGxhcHNpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJNaW5NaW51cyArIF9zdHJXaWR0aF0gPSBtaW5XaWR0aCAvKisgKCFfaXNCb3JkZXJCb3ggJiYgX3dpZHRoQXV0b0NhY2hlID8gX3BhZGRpbmdYICsgX2JvcmRlclggOiAwKSovO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ck1pbk1pbnVzICsgX3N0ckhlaWdodF0gPSBtaW5IZWlnaHQgLyorICghX2lzQm9yZGVyQm94ICYmIF9oZWlnaHRBdXRvQ2FjaGUgPyBfcGFkZGluZ1kgKyBfYm9yZGVyWSA6IDApKi87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LmNzcyhjc3MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9vcmlnaW5hbFdpZHRoOiBvcmlnV2lkdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfb3JpZ2luYWxIZWlnaHQ6IG9yaWdIZWlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZHluYW1pY1dpZHRoOiB3aWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9keW5hbWljSGVpZ2h0OiBoZWlnaHRcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBVcGRhdGVzIHRoZSBwbHVnaW4gYW5kIERPTSB0byB0aGUgY3VycmVudCBvcHRpb25zLlxyXG4gICAgICAgICAgICAgICAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGlmIGEgdXBkYXRlIGlzIDEwMCUgcmVxdWlyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdXBkYXRlSGludHMgQSBvYmplY3RzIHdoaWNoIGNvbnRhaW5zIGhpbnRzIGZvciB0aGlzIHVwZGF0ZTpcclxuICAgICAgICAgICAgICAgICAqIHtcclxuICAgICAgICAgICAgICAgICAqICAgX2hvc3RTaXplQ2hhbmdlZCA6IGJvb2xlYW4sXHJcbiAgICAgICAgICAgICAgICAgKiAgIF9jb250ZW50U2l6ZUNoYW5nZWQgOiBib29sZWFuLFxyXG4gICAgICAgICAgICAgICAgICogICBfZm9yY2UgOiBib29sZWFuLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT0gcHJldmVudFN3YWxsb3dpbmdcclxuICAgICAgICAgICAgICAgICAqICAgX2NoYW5nZWRPcHRpb25zIDogeyB9LCAgICAgICAgICAgICAgICAgICAgICAgID09IHByZXZlbnRTd2FsbG93aW5nICYmIHByZXZlbnRTbGVlcFxyXG4gICAgICAgICAgICAgICAgKiAgfVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiB1cGRhdGUodXBkYXRlSGludHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoX3N3YWxsb3dlZFVwZGF0ZVRpbWVvdXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZUhpbnRzID0gdXBkYXRlSGludHMgfHwge307XHJcbiAgICAgICAgICAgICAgICAgICAgX3N3YWxsb3dlZFVwZGF0ZUhpbnRzLl9ob3N0U2l6ZUNoYW5nZWQgfD0gdXBkYXRlSGludHMuX2hvc3RTaXplQ2hhbmdlZDtcclxuICAgICAgICAgICAgICAgICAgICBfc3dhbGxvd2VkVXBkYXRlSGludHMuX2NvbnRlbnRTaXplQ2hhbmdlZCB8PSB1cGRhdGVIaW50cy5fY29udGVudFNpemVDaGFuZ2VkO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zd2FsbG93ZWRVcGRhdGVIaW50cy5fZm9yY2UgfD0gdXBkYXRlSGludHMuX2ZvcmNlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgbm93ID0gQ09NUEFUSUJJTElUWS5ub3coKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdFNpemVDaGFuZ2VkID0gISFfc3dhbGxvd2VkVXBkYXRlSGludHMuX2hvc3RTaXplQ2hhbmdlZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudFNpemVDaGFuZ2VkID0gISFfc3dhbGxvd2VkVXBkYXRlSGludHMuX2NvbnRlbnRTaXplQ2hhbmdlZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZm9yY2UgPSAhIV9zd2FsbG93ZWRVcGRhdGVIaW50cy5fZm9yY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoYW5nZWRPcHRpb25zID0gdXBkYXRlSGludHMuX2NoYW5nZWRPcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzd2FsbG93ID0gX3N3YWxsb3dVcGRhdGVMYWcgPiAwICYmIF9pbml0aWFsaXplZCAmJiAhX2Rlc3Ryb3llZCAmJiAhZm9yY2UgJiYgIWNoYW5nZWRPcHRpb25zICYmIChub3cgLSBfbGFzdFVwZGF0ZVRpbWUpIDwgX3N3YWxsb3dVcGRhdGVMYWcgJiYgKCFfaGVpZ2h0QXV0b0NhY2hlICYmICFfd2lkdGhBdXRvQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkaXNwbGF5SXNIaWRkZW47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzd2FsbG93KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3dhbGxvd2VkVXBkYXRlVGltZW91dCA9IHNldFRpbWVvdXQodXBkYXRlLCBfc3dhbGxvd1VwZGF0ZUxhZyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYWJvcnQgdXBkYXRlIGR1ZSB0bzpcclxuICAgICAgICAgICAgICAgICAgICAvL2Rlc3Ryb3llZFxyXG4gICAgICAgICAgICAgICAgICAgIC8vc3dhbGxvd2luZ1xyXG4gICAgICAgICAgICAgICAgICAgIC8vc2xlZXBpbmdcclxuICAgICAgICAgICAgICAgICAgICAvL2hvc3QgaXMgaGlkZGVuIG9yIGhhcyBmYWxzZSBkaXNwbGF5XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9kZXN0cm95ZWQgfHwgc3dhbGxvdyB8fCAoX3NsZWVwaW5nICYmICFjaGFuZ2VkT3B0aW9ucykgfHwgKF9pbml0aWFsaXplZCAmJiAhZm9yY2UgJiYgKGRpc3BsYXlJc0hpZGRlbiA9IF9ob3N0RWxlbWVudC5pcygnOmhpZGRlbicpKSkgfHwgX2hvc3RFbGVtZW50LmNzcygnZGlzcGxheScpID09PSAnaW5saW5lJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBfbGFzdFVwZGF0ZVRpbWUgPSBub3c7XHJcbiAgICAgICAgICAgICAgICAgICAgX3N3YWxsb3dlZFVwZGF0ZUhpbnRzID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vaWYgc2Nyb2xsYmFyIHN0eWxpbmcgaXMgcG9zc2libGUgYW5kIG5hdGl2ZSBzY3JvbGxiYXJzIGFyZW4ndCBvdmVybGFpZCB0aGUgc2Nyb2xsYmFyIHN0eWxpbmcgd2lsbCBiZSBhcHBsaWVkIHdoaWNoIGhpZGVzIHRoZSBuYXRpdmUgc2Nyb2xsYmFycyBjb21wbGV0ZWx5LlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfbmF0aXZlU2Nyb2xsYmFyU3R5bGluZyAmJiAhKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9uYXRpdmUgc2Nyb2xsYmFycyBhcmUgaGlkZGVuLCBzbyBjaGFuZ2UgdGhlIHZhbHVlcyB0byB6ZXJvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9uYXRpdmVTY3JvbGxiYXJTaXplLnggPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbmF0aXZlU2Nyb2xsYmFyU2l6ZS55ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVmcmVzaCBuYXRpdmUgc2Nyb2xsYmFyIHNpemUgKGluIGNhc2Ugb2Ygem9vbSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgX25hdGl2ZVNjcm9sbGJhclNpemUgPSBleHRlbmREZWVwKHt9LCBnbG9iYWxzLm5hdGl2ZVNjcm9sbGJhclNpemUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gU2Nyb2xsYmFyIHBhZGRpbmcgaXMgbmVlZGVkIGZvciBmaXJlZm94LCBiZWNhdXNlIGZpcmVmb3ggaGlkZXMgc2Nyb2xsYmFyIGF1dG9tYXRpY2FsbHkgaWYgdGhlIHNpemUgb2YgdGhlIGRpdiBpcyB0b28gc21hbGwuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGNhbGN1bGF0aW9uOiBbc2Nyb2xsYmFyIHNpemUgKzMgKjNdXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gKCszIGJlY2F1c2Ugb2YgcG9zc2libGUgZGVjb3JhdGlvbiBlLmcuIGJvcmRlcnMsIG1hcmdpbnMgZXRjLiwgYnV0IG9ubHkgaWYgbmF0aXZlIHNjcm9sbGJhciBpcyBOT1QgYSBvdmVybGFpZCBzY3JvbGxiYXIpXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gKCozIGJlY2F1c2UgKDEpaW5jcmVhc2UgLyAoMilkZWNyZWFzZSAtYnV0dG9uIGFuZCAoMylyZXNpemUgaGFuZGxlKVxyXG4gICAgICAgICAgICAgICAgICAgIF9uYXRpdmVTY3JvbGxiYXJNaW5TaXplID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB4OiAoX25hdGl2ZVNjcm9sbGJhclNpemUueCArIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ID8gMCA6IDMpKSAqIDMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IChfbmF0aXZlU2Nyb2xsYmFyU2l6ZS55ICsgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkgPyAwIDogMykpICogM1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNoYW5nZWRPcHRpb25zID0gY2hhbmdlZE9wdGlvbnMgfHwge307XHJcbiAgICAgICAgICAgICAgICAgICAgLy9mcmVlemVSZXNpemVPYnNlcnZlcihfc2l6ZU9ic2VydmVyRWxlbWVudCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9mcmVlemVSZXNpemVPYnNlcnZlcihfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQsIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hlY2tDYWNoZUF1dG9Gb3JjZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoZWNrQ2FjaGUuYXBwbHkodGhpcywgW10uc2xpY2UuY2FsbChhcmd1bWVudHMpLmNvbmNhdChbZm9yY2VdKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zYXZlIGN1cnJlbnQgc2Nyb2xsIG9mZnNldFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyU2Nyb2xsID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBfdmlld3BvcnRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XSgpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBfdmlld3BvcnRFbGVtZW50W19zdHJTY3JvbGxUb3BdKClcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VycmVudFByZXBhcmVkT3B0aW9uc1Njcm9sbGJhcnMgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5zY3JvbGxiYXJzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyZW50UHJlcGFyZWRPcHRpb25zVGV4dGFyZWEgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy50ZXh0YXJlYTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxiYXJzIHZpc2liaWxpdHk6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNWaXNpYmlsaXR5ID0gY3VycmVudFByZXBhcmVkT3B0aW9uc1Njcm9sbGJhcnMudmlzaWJpbGl0eTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc1Zpc2liaWxpdHlDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShzY3JvbGxiYXJzVmlzaWJpbGl0eSwgX3Njcm9sbGJhcnNWaXNpYmlsaXR5Q2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGJhcnMgYXV0b0hpZGU6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNBdXRvSGlkZSA9IGN1cnJlbnRQcmVwYXJlZE9wdGlvbnNTY3JvbGxiYXJzLmF1dG9IaWRlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzQXV0b0hpZGVDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShzY3JvbGxiYXJzQXV0b0hpZGUsIF9zY3JvbGxiYXJzQXV0b0hpZGVDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2Nyb2xsYmFycyBjbGljayBzY3JvbGxpbmdcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc0NsaWNrU2Nyb2xsaW5nID0gY3VycmVudFByZXBhcmVkT3B0aW9uc1Njcm9sbGJhcnMuY2xpY2tTY3JvbGxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKHNjcm9sbGJhcnNDbGlja1Njcm9sbGluZywgX3Njcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxiYXJzIGRyYWcgc2Nyb2xsaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNEcmFnU2Nyb2xsaW5nID0gY3VycmVudFByZXBhcmVkT3B0aW9uc1Njcm9sbGJhcnMuZHJhZ1Njcm9sbGluZztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc0RyYWdTY3JvbGxpbmdDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShzY3JvbGxiYXJzRHJhZ1Njcm9sbGluZywgX3Njcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NsYXNzTmFtZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc05hbWUgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5jbGFzc05hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzTmFtZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGNsYXNzTmFtZSwgX2NsYXNzTmFtZUNhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZXNpemVcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzaXplID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMucmVzaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXNpemVDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShyZXNpemUsIF9yZXNpemVDYWNoZSkgJiYgIV9pc0JvZHk7IC8vYm9keSBjYW4ndCBiZSByZXNpemVkIHNpbmNlIHRoZSB3aW5kb3cgaXRzZWxmIGFjdHMgYXMgcmVzaXplIHBvc3NpYmlsaXR5LlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3BhZGRpbmdBYnNvbHV0ZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nQWJzb2x1dGUgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5wYWRkaW5nQWJzb2x1dGU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhZGRpbmdBYnNvbHV0ZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKHBhZGRpbmdBYnNvbHV0ZSwgX3BhZGRpbmdBYnNvbHV0ZUNhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9jbGlwQWx3YXlzXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsaXBBbHdheXMgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5jbGlwQWx3YXlzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGlwQWx3YXlzQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoY2xpcEFsd2F5cywgX2NsaXBBbHdheXNDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2l6ZUF1dG9DYXBhYmxlXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVBdXRvQ2FwYWJsZSA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLnNpemVBdXRvQ2FwYWJsZSAmJiAhX2lzQm9keTsgLy9ib2R5IGNhbiBuZXZlciBiZSBzaXplIGF1dG8sIGJlY2F1c2UgaXQgc2hhbGwgYmUgYWx3YXlzIGFzIGJpZyBhcyB0aGUgdmlld3BvcnQuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVBdXRvQ2FwYWJsZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKHNpemVBdXRvQ2FwYWJsZSwgX3NpemVBdXRvQ2FwYWJsZUNhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zaG93TmF0aXZlU2Nyb2xsYmFyc1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMubmF0aXZlU2Nyb2xsYmFyc092ZXJsYWlkLnNob3dOYXRpdmVTY3JvbGxiYXJzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZywgX2lnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYXV0b1VwZGF0ZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhdXRvVXBkYXRlID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMuYXV0b1VwZGF0ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXV0b1VwZGF0ZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGF1dG9VcGRhdGUsIF9hdXRvVXBkYXRlQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL292ZXJmbG93QmVoYXZpb3JcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb3ZlcmZsb3dCZWhhdmlvciA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLm92ZXJmbG93QmVoYXZpb3I7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QmVoYXZpb3JDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShvdmVyZmxvd0JlaGF2aW9yLCBfb3ZlcmZsb3dCZWhhdmlvckNhY2hlLCBmb3JjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZHluV2lkdGg6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhRHluV2lkdGggPSBjdXJyZW50UHJlcGFyZWRPcHRpb25zVGV4dGFyZWEuZHluV2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhRHluV2lkdGhDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShfdGV4dGFyZWFEeW5XaWR0aENhY2hlLCB0ZXh0YXJlYUR5bldpZHRoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9keW5IZWlnaHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhRHluSGVpZ2h0ID0gY3VycmVudFByZXBhcmVkT3B0aW9uc1RleHRhcmVhLmR5bkhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFEeW5IZWlnaHRDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShfdGV4dGFyZWFEeW5IZWlnaHRDYWNoZSwgdGV4dGFyZWFEeW5IZWlnaHQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGJhcnMgdmlzaWJpbGl0eVxyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVOZXZlciA9IHNjcm9sbGJhcnNBdXRvSGlkZSA9PT0gJ24nO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVTY3JvbGwgPSBzY3JvbGxiYXJzQXV0b0hpZGUgPT09ICdzJztcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSA9IHNjcm9sbGJhcnNBdXRvSGlkZSA9PT0gJ20nO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVMZWF2ZSA9IHNjcm9sbGJhcnNBdXRvSGlkZSA9PT0gJ2wnO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGJhcnMgYXV0b0hpZGVEZWxheVxyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVEZWxheSA9IGN1cnJlbnRQcmVwYXJlZE9wdGlvbnNTY3JvbGxiYXJzLmF1dG9IaWRlRGVsYXk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vb2xkIGNsYXNzTmFtZVxyXG4gICAgICAgICAgICAgICAgICAgIF9vbGRDbGFzc05hbWUgPSBfY2xhc3NOYW1lQ2FjaGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc2l6ZU5vbmUgPSByZXNpemUgPT09ICduJztcclxuICAgICAgICAgICAgICAgICAgICBfcmVzaXplQm90aCA9IHJlc2l6ZSA9PT0gJ2InO1xyXG4gICAgICAgICAgICAgICAgICAgIF9yZXNpemVIb3Jpem9udGFsID0gcmVzaXplID09PSAnaCc7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc2l6ZVZlcnRpY2FsID0gcmVzaXplID09PSAndic7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vbm9ybWFsaXplUlRMXHJcbiAgICAgICAgICAgICAgICAgICAgX25vcm1hbGl6ZVJUTENhY2hlID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMubm9ybWFsaXplUlRMO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lnbm9yZSBvdmVybGF5IHNjcm9sbGJhciBoaWRpbmdcclxuICAgICAgICAgICAgICAgICAgICBpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nID0gaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZyAmJiAoX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueCAmJiBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZWZyZXNoIG9wdGlvbnMgY2FjaGVcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc1Zpc2liaWxpdHlDYWNoZSA9IHNjcm9sbGJhcnNWaXNpYmlsaXR5O1xyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVDYWNoZSA9IHNjcm9sbGJhcnNBdXRvSGlkZTtcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0NsaWNrU2Nyb2xsaW5nQ2FjaGUgPSBzY3JvbGxiYXJzQ2xpY2tTY3JvbGxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2FjaGUgPSBzY3JvbGxiYXJzRHJhZ1Njcm9sbGluZztcclxuICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lQ2FjaGUgPSBjbGFzc05hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc2l6ZUNhY2hlID0gcmVzaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nQWJzb2x1dGVDYWNoZSA9IHBhZGRpbmdBYnNvbHV0ZTtcclxuICAgICAgICAgICAgICAgICAgICBfY2xpcEFsd2F5c0NhY2hlID0gY2xpcEFsd2F5cztcclxuICAgICAgICAgICAgICAgICAgICBfc2l6ZUF1dG9DYXBhYmxlQ2FjaGUgPSBzaXplQXV0b0NhcGFibGU7XHJcbiAgICAgICAgICAgICAgICAgICAgX2lnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDYWNoZSA9IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2F1dG9VcGRhdGVDYWNoZSA9IGF1dG9VcGRhdGU7XHJcbiAgICAgICAgICAgICAgICAgICAgX292ZXJmbG93QmVoYXZpb3JDYWNoZSA9IGV4dGVuZERlZXAoe30sIG92ZXJmbG93QmVoYXZpb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUR5bldpZHRoQ2FjaGUgPSB0ZXh0YXJlYUR5bldpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUR5bkhlaWdodENhY2hlID0gdGV4dGFyZWFEeW5IZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgX2hhc092ZXJmbG93Q2FjaGUgPSBfaGFzT3ZlcmZsb3dDYWNoZSB8fCB7IHg6IGZhbHNlLCB5OiBmYWxzZSB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3NldCBjb3JyZWN0IGNsYXNzIG5hbWUgdG8gdGhlIGhvc3QgZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc05hbWVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ob3N0RWxlbWVudCwgX29sZENsYXNzTmFtZSArIF9zdHJTcGFjZSArIF9jbGFzc05hbWVUaGVtZU5vbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIGNsYXNzTmFtZSAhPT0gdW5kZWZpbmVkICYmIGNsYXNzTmFtZSAhPT0gbnVsbCAmJiBjbGFzc05hbWUubGVuZ3RoID4gMCA/IGNsYXNzTmFtZSA6IF9jbGFzc05hbWVUaGVtZU5vbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zZXQgY29ycmVjdCBhdXRvIFVwZGF0ZVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhdXRvVXBkYXRlQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXV0b1VwZGF0ZSA9PT0gdHJ1ZSB8fCAoYXV0b1VwZGF0ZSA9PT0gbnVsbCAmJiBfYXV0b1VwZGF0ZVJlY29tbWVuZGVkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXJzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdXRvVXBkYXRlTG9vcC5hZGQoX2Jhc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0b1VwZGF0ZUxvb3AucmVtb3ZlKF9iYXNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3RNdXRhdGlvbk9ic2VydmVycygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2FjdGl2YXRlIG9yIGRlYWN0aXZhdGUgc2l6ZSBhdXRvIGNhcGFiaWxpdHlcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG9DYXBhYmxlQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG9DYXBhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2NvbnRlbnRHbHVlRWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRHbHVlRWxlbWVudCA9IEZSQU1FV09SSyhnZW5lcmF0ZURpdihfY2xhc3NOYW1lQ29udGVudEdsdWVFbGVtZW50KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50LmJlZm9yZShfY29udGVudEdsdWVFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2l6ZUF1dG9PYnNlcnZlckFkZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LnNob3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplQXV0b09ic2VydmVyRWxlbWVudCA9IEZSQU1FV09SSyhnZW5lcmF0ZURpdihfY2xhc3NOYW1lU2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnROYXRpdmUgPSBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnRbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuYmVmb3JlKF9zaXplQXV0b09ic2VydmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9sZFNpemUgPSB7IHc6IC0xLCBoOiAtMSB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzaXplT2JzZXJ2ZXIoX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdTaXplID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50TmF0aXZlW0xFWElDT04ub0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGVja0NhY2hlKG5ld1NpemUsIG9sZFNpemUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2luaXRpYWxpemVkICYmIChfaGVpZ2h0QXV0b0NhY2hlICYmIG5ld1NpemUuaCA+IDApIHx8IChfd2lkdGhBdXRvQ2FjaGUgJiYgbmV3U2l6ZS53ID4gMCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKF9pbml0aWFsaXplZCAmJiAoIV9oZWlnaHRBdXRvQ2FjaGUgJiYgbmV3U2l6ZS5oID09PSAwKSB8fCAoIV93aWR0aEF1dG9DYWNoZSAmJiBuZXdTaXplLncgPT09IDApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkU2l6ZSA9IG5ld1NpemU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9maXggaGVpZ2h0QXV0byBkZXRlY3RvciBidWcgaWYgaGVpZ2h0IGlzIGZpeGVkIGJ1dCBjb250ZW50SGVpZ2h0IGlzIDAuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGUgcHJvYmFiaWxpdHkgdGhpcyBidWcgd2lsbCBldmVyIGhhcHBlbiBpcyB2ZXJ5IHZlcnkgbG93LCB0aGF0cyB3aHkgaXRzIG9rIGlmIHdlIHVzZSBjYWxjIHdoaWNoIGlzbid0IHN1cHBvcnRlZCBpbiBJRTguXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9jc3NDYWxjICE9PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQuY3NzKF9zdHJIZWlnaHQsIF9jc3NDYWxjICsgJygxMDAlICsgMXB4KScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zaXplQXV0b09ic2VydmVyQWRkZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LmhpZGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfY29udGVudEdsdWVFbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuaGlkZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lmIGZvcmNlLCB1cGRhdGUgYWxsIHJlc2l6ZU9ic2VydmVycyB0b29cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZm9yY2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVPYnNlcnZlckVsZW1lbnQuZmluZCgnKicpLnRyaWdnZXIoX3N0clNjcm9sbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2l6ZUF1dG9PYnNlcnZlckFkZGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LmZpbmQoJyonKS50cmlnZ2VyKF9zdHJTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9kaXNwbGF5IGhpZGRlbjpcclxuICAgICAgICAgICAgICAgICAgICBkaXNwbGF5SXNIaWRkZW4gPSBkaXNwbGF5SXNIaWRkZW4gPT09IHVuZGVmaW5lZCA/IF9ob3N0RWxlbWVudC5pcygnOmhpZGRlbicpIDogZGlzcGxheUlzSGlkZGVuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3RleHRhcmVhIEF1dG9XcmFwcGluZzpcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFBdXRvV3JhcHBpbmcgPSBfaXNUZXh0YXJlYSA/IF90YXJnZXRFbGVtZW50LmF0dHIoJ3dyYXAnKSAhPT0gJ29mZicgOiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFBdXRvV3JhcHBpbmdDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZSh0ZXh0YXJlYUF1dG9XcmFwcGluZywgX3RleHRhcmVhQXV0b1dyYXBwaW5nQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2RldGVjdCBkaXJlY3Rpb246XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNzc0RpcmVjdGlvbiA9IF9ob3N0RWxlbWVudC5jc3MoJ2RpcmVjdGlvbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjc3NEaXJlY3Rpb25DaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShjc3NEaXJlY3Rpb24sIF9jc3NEaXJlY3Rpb25DYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZGV0ZWN0IGJveC1zaXppbmc6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJveFNpemluZyA9IF9ob3N0RWxlbWVudC5jc3MoJ2JveC1zaXppbmcnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYm94U2l6aW5nQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoYm94U2l6aW5nLCBfY3NzQm94U2l6aW5nQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2RldGVjdCBwYWRkaW5nOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nID0gZ2V0VG9wUmlnaHRCb3R0b21MZWZ0SG9zdChfc3RyUGFkZGluZ01pbnVzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy93aWR0aCArIGhlaWdodCBhdXRvIGRldGVjdGluZyB2YXI6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50QkNSZWN0O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vZXhjZXB0aW9uIG9jY3VycyBpbiBJRTggc29tZXRpbWVzICh1bmtub3duIGV4Y2VwdGlvbilcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplQXV0b09ic2VydmVyRWxlbWVudEJDUmVjdCA9IF9zaXplQXV0b09ic2VydmVyQWRkZWQgPyBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnROYXRpdmVbTEVYSUNPTi5iQ1JdKCkgOiBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF9pc1JUTCA9IGNzc0RpcmVjdGlvbiA9PT0gJ3J0bCc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2lzQm9yZGVyQm94ID0gKGJveFNpemluZyA9PT0gJ2JvcmRlci1ib3gnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaXNSVExMZWZ0ID0gX2lzUlRMID8gX3N0ckxlZnQgOiBfc3RyUmlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGlzUlRMUmlnaHQgPSBfaXNSVEwgPyBfc3RyUmlnaHQgOiBfc3RyTGVmdDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9kZXRlY3Qgd2lkdGggYXV0bzpcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2lkdGhBdXRvUmVzaXplRGV0ZWN0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdpZHRoQXV0b09ic2VydmVyRGV0ZWN0aW9uID0gKF9zaXplQXV0b09ic2VydmVyQWRkZWQgJiYgKF9ob3N0RWxlbWVudC5jc3MoX3N0ckZsb2F0KSAhPT0gJ25vbmUnIC8qfHwgX2lzVGV4dGFyZWEgKi8pKSA/IChNQVRILnJvdW5kKHNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50QkNSZWN0LnJpZ2h0IC0gc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnRCQ1JlY3QubGVmdCkgPT09IDApICYmICghcGFkZGluZ0Fic29sdXRlID8gKF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLmNXXSAtIF9wYWRkaW5nWCkgPiAwIDogdHJ1ZSkgOiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG9DYXBhYmxlICYmICF3aWR0aEF1dG9PYnNlcnZlckRldGVjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG1wQ3Vyckhvc3RXaWR0aCA9IF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9XXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRtcEN1cnJDb250ZW50R2x1ZVdpZHRoID0gX2NvbnRlbnRHbHVlRWxlbWVudC5jc3MoX3N0cldpZHRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRHbHVlRWxlbWVudC5jc3MoX3N0cldpZHRoLCBfc3RyQXV0byk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG1wTmV3SG9zdFdpZHRoID0gX2hvc3RFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEdsdWVFbGVtZW50LmNzcyhfc3RyV2lkdGgsIHRtcEN1cnJDb250ZW50R2x1ZVdpZHRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGhBdXRvUmVzaXplRGV0ZWN0aW9uID0gdG1wQ3Vyckhvc3RXaWR0aCAhPT0gdG1wTmV3SG9zdFdpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXdpZHRoQXV0b1Jlc2l6ZURldGVjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRHbHVlRWxlbWVudC5jc3MoX3N0cldpZHRoLCB0bXBDdXJySG9zdFdpZHRoICsgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXBOZXdIb3N0V2lkdGggPSBfaG9zdEVsZW1lbnROYXRpdmVbTEVYSUNPTi5vV107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEdsdWVFbGVtZW50LmNzcyhfc3RyV2lkdGgsIHRtcEN1cnJDb250ZW50R2x1ZVdpZHRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoQXV0b1Jlc2l6ZURldGVjdGlvbiA9IHRtcEN1cnJIb3N0V2lkdGggIT09IHRtcE5ld0hvc3RXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2lkdGhBdXRvID0gKHdpZHRoQXV0b09ic2VydmVyRGV0ZWN0aW9uIHx8IHdpZHRoQXV0b1Jlc2l6ZURldGVjdGlvbikgJiYgc2l6ZUF1dG9DYXBhYmxlICYmICFkaXNwbGF5SXNIaWRkZW47XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdpZHRoQXV0b0NoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKHdpZHRoQXV0bywgX3dpZHRoQXV0b0NhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2FzV2lkdGhBdXRvID0gIXdpZHRoQXV0byAmJiBfd2lkdGhBdXRvQ2FjaGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZGV0ZWN0IGhlaWdodCBhdXRvOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoZWlnaHRBdXRvID0gX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZCAmJiBzaXplQXV0b0NhcGFibGUgJiYgIWRpc3BsYXlJc0hpZGRlbiA/IChNQVRILnJvdW5kKHNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50QkNSZWN0LmJvdHRvbSAtIHNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50QkNSZWN0LnRvcCkgPT09IDApIC8qICYmICghcGFkZGluZ0Fic29sdXRlICYmIChfbXNpZVZlcnNpb24gPiA5IHx8ICFfbXNpZVZlcnNpb24pID8gdHJ1ZSA6IHRydWUpICovIDogZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhlaWdodEF1dG9DaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShoZWlnaHRBdXRvLCBfaGVpZ2h0QXV0b0NhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2FzSGVpZ2h0QXV0byA9ICFoZWlnaHRBdXRvICYmIF9oZWlnaHRBdXRvQ2FjaGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZGV0ZWN0IGJvcmRlcjpcclxuICAgICAgICAgICAgICAgICAgICAvL3dlIG5lZWQgdGhlIGJvcmRlciBvbmx5IGlmIGJvcmRlciBib3ggYW5kIGF1dG8gc2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1cGRhdGVCb3JkZXJYID0gKHdpZHRoQXV0byAmJiBfaXNCb3JkZXJCb3gpIHx8ICFfaXNCb3JkZXJCb3g7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHVwZGF0ZUJvcmRlclkgPSAoaGVpZ2h0QXV0byAmJiBfaXNCb3JkZXJCb3gpIHx8ICFfaXNCb3JkZXJCb3g7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJvcmRlciA9IGdldFRvcFJpZ2h0Qm90dG9tTGVmdEhvc3QoX3N0ckJvcmRlck1pbnVzLCAnLScgKyBfc3RyV2lkdGgsICF1cGRhdGVCb3JkZXJYLCAhdXBkYXRlQm9yZGVyWSlcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9kZXRlY3QgbWFyZ2luOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtYXJnaW4gPSBnZXRUb3BSaWdodEJvdHRvbUxlZnRIb3N0KF9zdHJNYXJnaW5NaW51cyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vdmFycyB0byBhcHBseSBjb3JyZWN0IGNzc1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50RWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50R2x1ZUVsZW1lbnRDU1MgPSB7fTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9mdW5jc1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBnZXRIb3N0U2l6ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9oYXMgdG8gYmUgY2xpZW50U2l6ZSBiZWNhdXNlIG9mZnNldFNpemUgcmVzcGVjdCBib3JkZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBfaG9zdEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBfaG9zdEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jSF1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBnZXRWaWV3cG9ydFNpemUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdmlld3BvcnQgc2l6ZSBpcyBwYWRkaW5nIGNvbnRhaW5lciBiZWNhdXNlIGl0IG5ldmVyIGhhcyBwYWRkaW5nLCBtYXJnaW4gYW5kIGEgYm9yZGVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vZGV0ZXJtaW5lIHpvb20gcm91bmRpbmcgZXJyb3IgLT4gc29tZXRpbWVzIHNjcm9sbFdpZHRoL0hlaWdodCBpcyBzbWFsbGVyIHRoYW4gY2xpZW50V2lkdGgvSGVpZ2h0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgdGhpcyBoYXBwZW5zIGFkZCB0aGUgZGlmZmVyZW5jZSB0byB0aGUgdmlld3BvcnRTaXplIHRvIGNvbXBlbnNhdGUgdGhlIHJvdW5kaW5nIGVycm9yXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBfcGFkZGluZ0VsZW1lbnROYXRpdmVbTEVYSUNPTi5vV10gKyBNQVRILm1heCgwLCBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jV10gLSBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5zV10pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogX3BhZGRpbmdFbGVtZW50TmF0aXZlW0xFWElDT04ub0hdICsgTUFUSC5tYXgoMCwgX2NvbnRlbnRFbGVtZW50TmF0aXZlW0xFWElDT04uY0hdIC0gX2NvbnRlbnRFbGVtZW50TmF0aXZlW0xFWElDT04uc0hdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2V0IGluZm8gZm9yIHBhZGRpbmdcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ0Fic29sdXRlWCA9IF9wYWRkaW5nWCA9IHBhZGRpbmcubCArIHBhZGRpbmcucjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ0Fic29sdXRlWSA9IF9wYWRkaW5nWSA9IHBhZGRpbmcudCArIHBhZGRpbmcuYjtcclxuICAgICAgICAgICAgICAgICAgICBwYWRkaW5nQWJzb2x1dGVYICo9IHBhZGRpbmdBYnNvbHV0ZSA/IDEgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHBhZGRpbmdBYnNvbHV0ZVkgKj0gcGFkZGluZ0Fic29sdXRlID8gMSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFkZGluZy5jID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShwYWRkaW5nLCBfY3NzUGFkZGluZ0NhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zZXQgaW5mbyBmb3IgYm9yZGVyXHJcbiAgICAgICAgICAgICAgICAgICAgX2JvcmRlclggPSBib3JkZXIubCArIGJvcmRlci5yO1xyXG4gICAgICAgICAgICAgICAgICAgIF9ib3JkZXJZID0gYm9yZGVyLnQgKyBib3JkZXIuYjtcclxuICAgICAgICAgICAgICAgICAgICBib3JkZXIuYyA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoYm9yZGVyLCBfY3NzQm9yZGVyQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3NldCBpbmZvIGZvciBtYXJnaW5cclxuICAgICAgICAgICAgICAgICAgICBfbWFyZ2luWCA9IG1hcmdpbi5sICsgbWFyZ2luLnI7XHJcbiAgICAgICAgICAgICAgICAgICAgX21hcmdpblkgPSBtYXJnaW4udCArIG1hcmdpbi5iO1xyXG4gICAgICAgICAgICAgICAgICAgIG1hcmdpbi5jID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShtYXJnaW4sIF9jc3NNYXJnaW5DYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVmcmVzaCBjYWNoZVxyXG4gICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUF1dG9XcmFwcGluZ0NhY2hlID0gdGV4dGFyZWFBdXRvV3JhcHBpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2Nzc0RpcmVjdGlvbkNhY2hlID0gY3NzRGlyZWN0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jc3NCb3hTaXppbmdDYWNoZSA9IGJveFNpemluZztcclxuICAgICAgICAgICAgICAgICAgICBfd2lkdGhBdXRvQ2FjaGUgPSB3aWR0aEF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgX2hlaWdodEF1dG9DYWNoZSA9IGhlaWdodEF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgX2Nzc1BhZGRpbmdDYWNoZSA9IHBhZGRpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2Nzc0JvcmRlckNhY2hlID0gYm9yZGVyO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jc3NNYXJnaW5DYWNoZSA9IG1hcmdpbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9JRUZpeCBkaXJlY3Rpb24gY2hhbmdlZFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjc3NEaXJlY3Rpb25DaGFuZ2VkICYmIF9zaXplQXV0b09ic2VydmVyQWRkZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplQXV0b09ic2VydmVyRWxlbWVudC5jc3MoX3N0ckZsb2F0LCBpc1JUTFJpZ2h0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9hcHBseSBwYWRkaW5nOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYWRkaW5nLmMgfHwgY3NzRGlyZWN0aW9uQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkIHx8IHdpZHRoQXV0b0NoYW5nZWQgfHwgaGVpZ2h0QXV0b0NoYW5nZWQgfHwgYm94U2l6aW5nQ2hhbmdlZCB8fCBzaXplQXV0b0NhcGFibGVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nRWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhZGRpbmdWYWx1ZXMgPSBbcGFkZGluZy50LCBwYWRkaW5nLnIsIHBhZGRpbmcuYiwgcGFkZGluZy5sXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRvcFJpZ2h0Qm90dG9tTGVmdChjb250ZW50R2x1ZUVsZW1lbnRDU1MsIF9zdHJNYXJnaW5NaW51cywgWy1wYWRkaW5nLnQsIC1wYWRkaW5nLnIsIC1wYWRkaW5nLmIsIC1wYWRkaW5nLmxdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhZGRpbmdBYnNvbHV0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VG9wUmlnaHRCb3R0b21MZWZ0KHBhZGRpbmdFbGVtZW50Q1NTLCBfc3RyRW1wdHksIHBhZGRpbmdWYWx1ZXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VG9wUmlnaHRCb3R0b21MZWZ0KF9pc1RleHRhcmVhID8gdGV4dGFyZWFDU1MgOiBjb250ZW50RWxlbWVudENTUywgX3N0clBhZGRpbmdNaW51cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUb3BSaWdodEJvdHRvbUxlZnQocGFkZGluZ0VsZW1lbnRDU1MsIF9zdHJFbXB0eSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUb3BSaWdodEJvdHRvbUxlZnQoX2lzVGV4dGFyZWEgPyB0ZXh0YXJlYUNTUyA6IGNvbnRlbnRFbGVtZW50Q1NTLCBfc3RyUGFkZGluZ01pbnVzLCBwYWRkaW5nVmFsdWVzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50LmNzcyhwYWRkaW5nRWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LmNzcyh0ZXh0YXJlYUNTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3ZpZXdwb3J0IHNpemUgaXMgcGFkZGluZyBjb250YWluZXIgYmVjYXVzZSBpdCBuZXZlciBoYXMgcGFkZGluZywgbWFyZ2luIGFuZCBhIGJvcmRlci5cclxuICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRTaXplID0gZ2V0Vmlld3BvcnRTaXplKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vdXBkYXRlIFRleHRhcmVhXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhU2l6ZSA9IF9pc1RleHRhcmVhID8gdGV4dGFyZWFVcGRhdGUoKSA6IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYVNpemVDaGFuZ2VkID0gX2lzVGV4dGFyZWEgJiYgY2hlY2tDYWNoZUF1dG9Gb3JjZSh0ZXh0YXJlYVNpemUsIF90ZXh0YXJlYVNpemVDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhRHluT3JpZ1NpemUgPSBfaXNUZXh0YXJlYSAmJiB0ZXh0YXJlYVNpemUgPyB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHc6IHRleHRhcmVhRHluV2lkdGggPyB0ZXh0YXJlYVNpemUuX2R5bmFtaWNXaWR0aCA6IHRleHRhcmVhU2l6ZS5fb3JpZ2luYWxXaWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaDogdGV4dGFyZWFEeW5IZWlnaHQgPyB0ZXh0YXJlYVNpemUuX2R5bmFtaWNIZWlnaHQgOiB0ZXh0YXJlYVNpemUuX29yaWdpbmFsSGVpZ2h0XHJcbiAgICAgICAgICAgICAgICAgICAgfSA6IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYVNpemVDYWNoZSA9IHRleHRhcmVhU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9maXggaGVpZ2h0IGF1dG8gLyB3aWR0aCBhdXRvIGluIGNvb3BlcmF0aW9uIHdpdGggY3VycmVudCBwYWRkaW5nICYgYm94U2l6aW5nIGJlaGF2aW9yOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChoZWlnaHRBdXRvICYmIChoZWlnaHRBdXRvQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgcGFkZGluZy5jIHx8IGJvcmRlci5jKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RySGVpZ2h0XSA9IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChoZWlnaHRBdXRvQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJIZWlnaHRdID0gX3N0ckh1bmRyZWRQZXJjZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAod2lkdGhBdXRvICYmICh3aWR0aEF1dG9DaGFuZ2VkIHx8IHBhZGRpbmdBYnNvbHV0ZUNoYW5nZWQgfHwgYm94U2l6aW5nQ2hhbmdlZCB8fCBwYWRkaW5nLmMgfHwgYm9yZGVyLmMgfHwgY3NzRGlyZWN0aW9uQ2hhbmdlZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0cldpZHRoXSA9IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1NbX3N0ck1heE1pbnVzICsgX3N0cldpZHRoXSA9IF9zdHJIdW5kcmVkUGVyY2VudDsgLy9JRSBGaXhcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAod2lkdGhBdXRvQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBfc3RySHVuZHJlZFBlcmNlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJGbG9hdF0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RyTWF4TWludXMgKyBfc3RyV2lkdGhdID0gX3N0ckVtcHR5OyAvL0lFIEZpeFxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAod2lkdGhBdXRvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdGV4dGFyZWFEeW5PcmlnU2l6ZS53IHx8IF9zdHJBdXRvIDo6IGRvZXNudCB3b3JrcyBiZWNhdXNlIGFwcGxpZWQgbWFyZ2luIHdpbGwgc2hpZnQgd2lkdGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEdsdWVFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBfc3RyQXV0bztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBWRU5ET1JTLl9jc3NQcm9wZXJ0eVZhbHVlKF9zdHJXaWR0aCwgJ21heC1jb250ZW50IGludHJpbnNpYycpIHx8IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyRmxvYXRdID0gaXNSVExSaWdodDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RyV2lkdGhdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoaGVpZ2h0QXV0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3RleHRhcmVhRHluT3JpZ1NpemUuaCB8fCBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jSF0gOjogdXNlIGZvciBhbnRpIHNjcm9sbCBqdW1waW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RySGVpZ2h0XSA9IHRleHRhcmVhRHluT3JpZ1NpemUuaCB8fCBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jSF07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1NbX3N0ckhlaWdodF0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXplQXV0b0NhcGFibGUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuY3NzKGNvbnRlbnRHbHVlRWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhjb250ZW50RWxlbWVudENTUyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vQ0hFQ0tQT0lOVCBIRVJFIH5cclxuICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTUyA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lmIFtjb250ZW50KGhvc3QpIGNsaWVudCAvIHNjcm9sbCBzaXplLCBvciB0YXJnZXQgZWxlbWVudCBkaXJlY3Rpb24sIG9yIGNvbnRlbnQoaG9zdCkgbWF4LXNpemVzXSBjaGFuZ2VkLCBvciBmb3JjZSBpcyB0cnVlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhvc3RTaXplQ2hhbmdlZCB8fCBjb250ZW50U2l6ZUNoYW5nZWQgfHwgdGV4dGFyZWFTaXplQ2hhbmdlZCB8fCBjc3NEaXJlY3Rpb25DaGFuZ2VkIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgcGFkZGluZ0Fic29sdXRlQ2hhbmdlZCB8fCB3aWR0aEF1dG9DaGFuZ2VkIHx8IHdpZHRoQXV0byB8fCBoZWlnaHRBdXRvQ2hhbmdlZCB8fCBoZWlnaHRBdXRvIHx8IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkIHx8IG92ZXJmbG93QmVoYXZpb3JDaGFuZ2VkIHx8IGNsaXBBbHdheXNDaGFuZ2VkIHx8IHJlc2l6ZUNoYW5nZWQgfHwgc2Nyb2xsYmFyc1Zpc2liaWxpdHlDaGFuZ2VkIHx8IHNjcm9sbGJhcnNBdXRvSGlkZUNoYW5nZWQgfHwgc2Nyb2xsYmFyc0RyYWdTY3JvbGxpbmdDaGFuZ2VkIHx8IHNjcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NoYW5nZWQgfHwgdGV4dGFyZWFEeW5XaWR0aENoYW5nZWQgfHwgdGV4dGFyZWFEeW5IZWlnaHRDaGFuZ2VkIHx8IHRleHRhcmVhQXV0b1dyYXBwaW5nQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyT3ZlcmZsb3cgPSAnb3ZlcmZsb3cnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyT3ZlcmZsb3dYID0gc3RyT3ZlcmZsb3cgKyAnLXgnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyT3ZlcmZsb3dZID0gc3RyT3ZlcmZsb3cgKyAnLXknO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RySGlkZGVuID0gJ2hpZGRlbic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJWaXNpYmxlID0gJ3Zpc2libGUnO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9SZXNldCB0aGUgdmlld3BvcnQgKHZlcnkgaW1wb3J0YW50IGZvciBuYXRpdmVseSBvdmVybGFpZCBzY3JvbGxiYXJzIGFuZCB6b29tIGNoYW5nZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2Rvbid0IGNoYW5nZSB0aGUgb3ZlcmZsb3cgcHJvcCBhcyBpdCBpcyB2ZXJ5IGV4cGVuc2l2ZSBhbmQgYWZmZWN0cyBwZXJmb3JtYW5jZSAhQSBMT1QhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2aWV3cG9ydEVsZW1lbnRSZXNldENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc2V0WFRtcCA9IF9oYXNPdmVyZmxvd0NhY2hlLnkgJiYgX2hpZGVPdmVyZmxvd0NhY2hlLnlzICYmICFpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nID8gKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkgPyBfdmlld3BvcnRFbGVtZW50LmNzcyhpc1JUTExlZnQpIDogLV9uYXRpdmVTY3JvbGxiYXJTaXplLnkpIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNldEJvdHRvbVRtcCA9IF9oYXNPdmVyZmxvd0NhY2hlLnggJiYgX2hpZGVPdmVyZmxvd0NhY2hlLnhzICYmICFpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nID8gKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggPyBfdmlld3BvcnRFbGVtZW50LmNzcyhfc3RyQm90dG9tKSA6IC1fbmF0aXZlU2Nyb2xsYmFyU2l6ZS54KSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUb3BSaWdodEJvdHRvbUxlZnQodmlld3BvcnRFbGVtZW50UmVzZXRDU1MsIF9zdHJFbXB0eSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50LmNzcyh2aWV3cG9ydEVsZW1lbnRSZXNldENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWVhc3VyZSBzZXZlcmFsIHNpemVzOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudE1lYXN1cmVFbGVtZW50ID0gZ2V0Q29udGVudE1lYXN1cmVFbGVtZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaW4gRmlyZWZveCBjb250ZW50IGVsZW1lbnQgaGFzIHRvIGhhdmUgb3ZlcmZsb3cgaGlkZGVuLCBlbHNlIGVsZW1lbnQgbWFyZ2lucyBhcmVuJ3QgY2FsY3VsYXRlZCBwcm9wZXJseSwgdGhpcyBlbGVtZW50IHByZXZlbnRzIHRoaXMgYnVnLCBidXQgb25seSBpZiBzY3JvbGxiYXJzIGFyZW4ndCBvdmVybGFpZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3VzZSBjbGllbnRTaXplIGJlY2F1c2UgbmF0aXZlbHkgb3ZlcmxhaWRTY3JvbGxiYXJzIGFkZCBib3JkZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiB0ZXh0YXJlYUR5bk9yaWdTaXplLncgfHwgY29udGVudE1lYXN1cmVFbGVtZW50W0xFWElDT04uY1ddLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogdGV4dGFyZWFEeW5PcmlnU2l6ZS5oIHx8IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLmNIXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsU2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNXXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNIXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hcHBseSB0aGUgY29ycmVjdCB2aWV3cG9ydCBzdHlsZSBhbmQgbWVhc3VyZSB2aWV3cG9ydCBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudFJlc2V0Q1NTW19zdHJCb3R0b21dID0gd2FzSGVpZ2h0QXV0byA/IF9zdHJFbXB0eSA6IHJlc2V0Qm90dG9tVG1wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50UmVzZXRDU1NbaXNSVExMZWZ0XSA9IHdhc1dpZHRoQXV0byA/IF9zdHJFbXB0eSA6IHJlc2V0WFRtcDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuY3NzKHZpZXdwb3J0RWxlbWVudFJlc2V0Q1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRTaXplID0gZ2V0Vmlld3BvcnRTaXplKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21lYXN1cmUgYW5kIGNvcnJlY3Qgc2V2ZXJhbCBzaXplc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdFNpemUgPSBnZXRIb3N0U2l6ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdEFic29sdXRlUmVjdFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBob3N0U2l6ZS53IC0gX21hcmdpblggLSBfYm9yZGVyWCAtIChfaXNCb3JkZXJCb3ggPyAwIDogX3BhZGRpbmdYKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IGhvc3RTaXplLmggLSBfbWFyZ2luWSAtIF9ib3JkZXJZIC0gKF9pc0JvcmRlckJveCA/IDAgOiBfcGFkZGluZ1kpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50R2x1ZVNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NsaWVudC9zY3JvbGxTaXplICsgQWJzb2x1dGVQYWRkaW5nIC0+IGJlY2F1c2UgcGFkZGluZyBpcyBvbmx5IGFwcGxpZWQgdG8gdGhlIHBhZGRpbmdFbGVtZW50IGlmIGl0cyBhYnNvbHV0ZSwgc28geW91IGhhdmUgdG8gYWRkIGl0IG1hbnVhbGx5XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2hvc3RTaXplIGlzIGNsaWVudFNpemUgLT4gc28gcGFkZGluZyBzaG91bGQgYmUgYWRkZWQgbWFudWFsbHksIHJpZ2h0PyBGQUxTRSEgQmVjYXVzZSBjb250ZW50IGdsdWUgaXMgaW5zaWRlIGhvc3RFbGVtZW50LCBzbyB3ZSBkb24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0IHBhZGRpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IE1BVEgubWF4KCh3aWR0aEF1dG8gPyBjb250ZW50U2l6ZS53IDogc2Nyb2xsU2l6ZS53KSArIHBhZGRpbmdBYnNvbHV0ZVgsIGhvc3RBYnNvbHV0ZVJlY3RTaXplLncpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogTUFUSC5tYXgoKGhlaWdodEF1dG8gPyBjb250ZW50U2l6ZS5oIDogc2Nyb2xsU2l6ZS5oKSArIHBhZGRpbmdBYnNvbHV0ZVksIGhvc3RBYnNvbHV0ZVJlY3RTaXplLmgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlU2l6ZS5jID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShjb250ZW50R2x1ZVNpemUsIF9jb250ZW50R2x1ZVNpemVDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZVNpemVDYWNoZSA9IGNvbnRlbnRHbHVlU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYXBwbHkgY29ycmVjdCBjb250ZW50R2x1ZSBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaXplQXV0b0NhcGFibGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc2l6ZSBjb250ZW50R2x1ZSBjb3JyZWN0bHkgdG8gbWFrZSBzdXJlIHRoZSBlbGVtZW50IGhhcyBjb3JyZWN0IHNpemUgaWYgdGhlIHNpemluZyBzd2l0Y2hlcyB0byBhdXRvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29udGVudEdsdWVTaXplLmMgfHwgKGhlaWdodEF1dG8gfHwgd2lkdGhBdXRvKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RyV2lkdGhdID0gY29udGVudEdsdWVTaXplLnc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEdsdWVFbGVtZW50Q1NTW19zdHJIZWlnaHRdID0gY29udGVudEdsdWVTaXplLmg7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGV4dGFyZWEtc2l6ZXMgYXJlIGFscmVhZHkgY2FsY3VsYXRlZCBjb3JyZWN0bHkgYXQgdGhpcyBwb2ludFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2lzVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3VzZSBjbGllbnRTaXplIGJlY2F1c2UgbmF0aXZlbHkgb3ZlcmxhaWRTY3JvbGxiYXJzIGFkZCBib3JkZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBjb250ZW50TWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5jV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBjb250ZW50TWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5jSF1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFDb3ZlckNTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNldENvbnRlbnRHbHVlRWxlbWVudENTU2Z1bmN0aW9uID0gZnVuY3Rpb24gKGhvcml6b250YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFycyA9IGdldFNjcm9sbGJhclZhcnMoaG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHdoID0gc2Nyb2xsYmFyVmFycy5fd19oO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJXSCA9IHNjcm9sbGJhclZhcnMuX3dpZHRoX2hlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXV0b1NpemUgPSBob3Jpem9udGFsID8gd2lkdGhBdXRvIDogaGVpZ2h0QXV0bztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYm9yZGVyU2l6ZSA9IGhvcml6b250YWwgPyBfYm9yZGVyWCA6IF9ib3JkZXJZO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nU2l6ZSA9IGhvcml6b250YWwgPyBfcGFkZGluZ1ggOiBfcGFkZGluZ1k7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1hcmdpblNpemUgPSBob3Jpem9udGFsID8gX21hcmdpblggOiBfbWFyZ2luWTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRTaXplID0gX3ZpZXdwb3J0U2l6ZVt3aF0gLSBib3JkZXJTaXplIC0gbWFyZ2luU2l6ZSAtIChfaXNCb3JkZXJCb3ggPyAwIDogcGFkZGluZ1NpemUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL21ha2UgY29udGVudEdsdWUgc2l6ZSAtMSBpZiBlbGVtZW50IGlzIG5vdCBhdXRvIHNpemVkLCB0byBtYWtlIHN1cmUgdGhhdCBhIHJlc2l6ZSBldmVudCBoYXBwZW5zIHdoZW4gdGhlIGVsZW1lbnQgc2hyaW5rc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYXV0b1NpemUgfHwgKCFhdXRvU2l6ZSAmJiBib3JkZXIuYykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tzdHJXSF0gPSBob3N0QWJzb2x1dGVSZWN0U2l6ZVt3aF0gLSAxO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIHNpemUgaXMgYXV0byBhbmQgaG9zdCBpcyBzbWFsbGVyIHRoYW4gc2l6ZSBhcyBtaW4gc2l6ZSwgbWFrZSBjb250ZW50IGdsdWUgc2l6ZSAtMSB0byBtYWtlIHN1cmUgc2l6ZSBjaGFuZ2VzIHdpbGwgYmUgZGV0ZWN0ZWQgKHRoaXMgaXMgb25seSBuZWVkZWQgaWYgcGFkZGluZyBpcyAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdXRvU2l6ZSAmJiAoY29udGVudFNpemVbd2hdIDwgdmlld3BvcnRTaXplKSAmJiAoaG9yaXpvbnRhbCAmJiBfaXNUZXh0YXJlYSA/ICF0ZXh0YXJlYUF1dG9XcmFwcGluZyA6IHRydWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRhcmVhQ292ZXJDU1Nbc3RyV0hdID0gcGFyc2VUb1plcm9Pck51bWJlcihfdGV4dGFyZWFDb3ZlckVsZW1lbnQuY3NzKHN0cldIKSkgLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1Nbc3RyV0hdIC09IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL21ha2Ugc3VyZSBjb250ZW50IGdsdWUgc2l6ZSBpcyBhdCBsZWFzdCAxXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRTaXplW3doXSA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tzdHJXSF0gPSBNQVRILm1heCgxLCBjb250ZW50R2x1ZUVsZW1lbnRDU1Nbc3RyV0hdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRDb250ZW50R2x1ZUVsZW1lbnRDU1NmdW5jdGlvbih0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldENvbnRlbnRHbHVlRWxlbWVudENTU2Z1bmN0aW9uKGZhbHNlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzVGV4dGFyZWEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RleHRhcmVhQ292ZXJFbGVtZW50LmNzcyh0ZXh0YXJlYUNvdmVyQ1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuY3NzKGNvbnRlbnRHbHVlRWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdpZHRoQXV0bylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBfc3RySHVuZHJlZFBlcmNlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3aWR0aEF1dG8gJiYgIV9pc0JvcmRlckJveCAmJiAhX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ckZsb2F0XSA9ICdub25lJztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYXBwbHkgYW5kIHJlc2V0IGNvbnRlbnQgc3R5bGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhjb250ZW50RWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21lYXN1cmUgYWdhaW4sIGJ1dCB0aGlzIHRpbWUgYWxsIGNvcnJlY3Qgc2l6ZXM6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50U2Nyb2xsU2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNXXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNIXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFNjcm9sbFNpemUuYyA9IGNvbnRlbnRTaXplQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoY29udGVudFNjcm9sbFNpemUsIF9jb250ZW50U2Nyb2xsU2l6ZUNhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGUgPSBjb250ZW50U2Nyb2xsU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVmcmVzaCB2aWV3cG9ydCBzaXplIGFmdGVyIGNvcnJlY3QgbWVhc3VyaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydFNpemUgPSBnZXRWaWV3cG9ydFNpemUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RTaXplID0gZ2V0SG9zdFNpemUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaG9zdFNpemVDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShob3N0U2l6ZSwgX2hvc3RTaXplQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfaG9zdFNpemVDYWNoZSA9IGhvc3RTaXplO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhpZGVPdmVyZmxvd0ZvcmNlVGV4dGFyZWEgPSBfaXNUZXh0YXJlYSAmJiAoX3ZpZXdwb3J0U2l6ZS53ID09PSAwIHx8IF92aWV3cG9ydFNpemUuaCA9PT0gMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcmV2aW91c092ZXJmbG93QW1vdW50ID0gX292ZXJmbG93QW1vdW50Q2FjaGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvdmVyZmxvd0JlaGF2aW9ySXNWUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3ZlcmZsb3dCZWhhdmlvcklzVkggPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QmVoYXZpb3JJc1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QW1vdW50ID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYXNPdmVyZmxvdyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGlkZU92ZXJmbG93ID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjYW5TY3JvbGwgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZpZXdwb3J0UmVjdCA9IF9wYWRkaW5nRWxlbWVudE5hdGl2ZVtMRVhJQ09OLmJDUl0oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNldE92ZXJmbG93VmFyaWFibGVzID0gZnVuY3Rpb24gKGhvcml6b250YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhob3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzSW52ZXJ0ZWQgPSBnZXRTY3JvbGxiYXJWYXJzKCFob3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4eUkgPSBzY3JvbGxiYXJWYXJzSW52ZXJ0ZWQuX3hfeTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4eSA9IHNjcm9sbGJhclZhcnMuX3hfeTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aCA9IHNjcm9sbGJhclZhcnMuX3dfaDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aWR0aEhlaWdodCA9IHNjcm9sbGJhclZhcnMuX3dpZHRoX2hlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxNYXggPSBfc3RyU2Nyb2xsICsgc2Nyb2xsYmFyVmFycy5fTGVmdF9Ub3AgKyAnTWF4JztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmcmFjdGlvbmFsT3ZlcmZsb3dBbW91bnQgPSB2aWV3cG9ydFJlY3Rbd2lkdGhIZWlnaHRdID8gTUFUSC5hYnModmlld3BvcnRSZWN0W3dpZHRoSGVpZ2h0XSAtIF92aWV3cG9ydFNpemVbd2hdKSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hlY2tGcmFjdGlvbmFsT3ZlcmZsb3dBbW91bnQgPSBwcmV2aW91c092ZXJmbG93QW1vdW50ICYmIHByZXZpb3VzT3ZlcmZsb3dBbW91bnRbeHldID4gMCAmJiBfdmlld3BvcnRFbGVtZW50TmF0aXZlW3Njcm9sbE1heF0gPT09IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0JlaGF2aW9ySXNWU1t4eV0gPSBvdmVyZmxvd0JlaGF2aW9yW3h5XSA9PT0gJ3Ytcyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0JlaGF2aW9ySXNWSFt4eV0gPSBvdmVyZmxvd0JlaGF2aW9yW3h5XSA9PT0gJ3YtaCc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0JlaGF2aW9ySXNTW3h5XSA9IG92ZXJmbG93QmVoYXZpb3JbeHldID09PSAncyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0Ftb3VudFt4eV0gPSBNQVRILm1heCgwLCBNQVRILnJvdW5kKChjb250ZW50U2Nyb2xsU2l6ZVt3aF0gLSBfdmlld3BvcnRTaXplW3doXSkgKiAxMDApIC8gMTAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJmbG93QW1vdW50W3h5XSAqPSAoaGlkZU92ZXJmbG93Rm9yY2VUZXh0YXJlYSB8fCAoY2hlY2tGcmFjdGlvbmFsT3ZlcmZsb3dBbW91bnQgJiYgZnJhY3Rpb25hbE92ZXJmbG93QW1vdW50ID4gMCAmJiBmcmFjdGlvbmFsT3ZlcmZsb3dBbW91bnQgPCAxKSkgPyAwIDogMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc092ZXJmbG93W3h5XSA9IG92ZXJmbG93QW1vdW50W3h5XSA+IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9oaWRlT3ZlcmZsb3c6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3ggfHwgeSA6IHRydWUgPT09IG92ZXJmbG93IGlzIGhpZGRlbiBieSBcIm92ZXJmbG93OiBzY3JvbGxcIiBPUiBcIm92ZXJmbG93OiBoaWRkZW5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy94cyB8fCB5cyA6IHRydWUgPT09IG92ZXJmbG93IGlzIGhpZGRlbiBieSBcIm92ZXJmbG93OiBzY3JvbGxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZU92ZXJmbG93W3h5XSA9IG92ZXJmbG93QmVoYXZpb3JJc1ZTW3h5XSB8fCBvdmVyZmxvd0JlaGF2aW9ySXNWSFt4eV0gPyAoaGFzT3ZlcmZsb3dbeHlJXSAmJiAhb3ZlcmZsb3dCZWhhdmlvcklzVlNbeHlJXSAmJiAhb3ZlcmZsb3dCZWhhdmlvcklzVkhbeHlJXSkgOiBoYXNPdmVyZmxvd1t4eV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRlT3ZlcmZsb3dbeHkgKyAncyddID0gaGlkZU92ZXJmbG93W3h5XSA/IChvdmVyZmxvd0JlaGF2aW9ySXNTW3h5XSB8fCBvdmVyZmxvd0JlaGF2aW9ySXNWU1t4eV0pIDogZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FuU2Nyb2xsW3h5XSA9IGhhc092ZXJmbG93W3h5XSAmJiBoaWRlT3ZlcmZsb3dbeHkgKyAncyddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRPdmVyZmxvd1ZhcmlhYmxlcyh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0T3ZlcmZsb3dWYXJpYWJsZXMoZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmZsb3dBbW91bnQuYyA9IGNoZWNrQ2FjaGVBdXRvRm9yY2Uob3ZlcmZsb3dBbW91bnQsIF9vdmVyZmxvd0Ftb3VudENhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX292ZXJmbG93QW1vdW50Q2FjaGUgPSBvdmVyZmxvd0Ftb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzT3ZlcmZsb3cuYyA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoaGFzT3ZlcmZsb3csIF9oYXNPdmVyZmxvd0NhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hhc092ZXJmbG93Q2FjaGUgPSBoYXNPdmVyZmxvdztcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGlkZU92ZXJmbG93LmMgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGhpZGVPdmVyZmxvdywgX2hpZGVPdmVyZmxvd0NhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hpZGVPdmVyZmxvd0NhY2hlID0gaGlkZU92ZXJmbG93O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiBuYXRpdmUgc2Nyb2xsYmFyIGlzIG92ZXJsYXkgYXQgeCBPUiB5IGF4aXMsIHByZXBhcmUgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54IHx8IF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBib3JkZXJEZXNpZ24gPSAncHggc29saWQgdHJhbnNwYXJlbnQnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRBcnJhbmdlRWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFycmFuZ2VDb250ZW50ID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXJyYW5nZUNoYW5nZWQgPSBmb3JjZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzZXRDb250ZW50RWxlbWVudENTUztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzT3ZlcmZsb3cueCB8fCBoYXNPdmVyZmxvdy55KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYW5nZUNvbnRlbnQudyA9IF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkgJiYgaGFzT3ZlcmZsb3cueSA/IGNvbnRlbnRTY3JvbGxTaXplLncgKyBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZS55IDogX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmFuZ2VDb250ZW50LmggPSBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIGhhc092ZXJmbG93LnggPyBjb250ZW50U2Nyb2xsU2l6ZS5oICsgX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemUueCA6IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoYXJyYW5nZUNvbnRlbnQsIF9hcnJhbmdlQ29udGVudFNpemVDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2FycmFuZ2VDb250ZW50U2l6ZUNhY2hlID0gYXJyYW5nZUNvbnRlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhhc092ZXJmbG93LmMgfHwgaGlkZU92ZXJmbG93LmMgfHwgY29udGVudFNjcm9sbFNpemUuYyB8fCBjc3NEaXJlY3Rpb25DaGFuZ2VkIHx8IHdpZHRoQXV0b0NoYW5nZWQgfHwgaGVpZ2h0QXV0b0NoYW5nZWQgfHwgd2lkdGhBdXRvIHx8IGhlaWdodEF1dG8gfHwgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyTWFyZ2luTWludXMgKyBpc1JUTFJpZ2h0XSA9IGNvbnRlbnRFbGVtZW50Q1NTW19zdHJCb3JkZXJNaW51cyArIGlzUlRMUmlnaHRdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldENvbnRlbnRFbGVtZW50Q1NTID0gZnVuY3Rpb24gKGhvcml6b250YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhclZhcnMgPSBnZXRTY3JvbGxiYXJWYXJzKGhvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFyc0ludmVydGVkID0gZ2V0U2Nyb2xsYmFyVmFycyghaG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4eSA9IHNjcm9sbGJhclZhcnMuX3hfeTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckRpcmVjdGlvbiA9IGhvcml6b250YWwgPyBfc3RyQm90dG9tIDogaXNSVExMZWZ0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW52ZXJ0ZWRBdXRvU2l6ZSA9IGhvcml6b250YWwgPyBoZWlnaHRBdXRvIDogd2lkdGhBdXRvO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkW3h5XSAmJiBoYXNPdmVyZmxvd1t4eV0gJiYgaGlkZU92ZXJmbG93W3h5ICsgJ3MnXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ck1hcmdpbk1pbnVzICsgc3RyRGlyZWN0aW9uXSA9IGludmVydGVkQXV0b1NpemUgPyAoaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZyA/IF9zdHJFbXB0eSA6IF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplW3h5XSkgOiBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyQm9yZGVyTWludXMgKyBzdHJEaXJlY3Rpb25dID0gKChob3Jpem9udGFsID8gIWludmVydGVkQXV0b1NpemUgOiB0cnVlKSAmJiAhaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZykgPyAoX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemVbeHldICsgYm9yZGVyRGVzaWduKSA6IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmFuZ2VDb250ZW50W3Njcm9sbGJhclZhcnNJbnZlcnRlZC5fd19oXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ck1hcmdpbk1pbnVzICsgc3RyRGlyZWN0aW9uXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ckJvcmRlck1pbnVzICsgc3RyRGlyZWN0aW9uXSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmFuZ2VDaGFuZ2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbmF0aXZlU2Nyb2xsYmFyU3R5bGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfdmlld3BvcnRFbGVtZW50LCBfY2xhc3NOYW1lVmlld3BvcnROYXRpdmVTY3JvbGxiYXJzSW52aXNpYmxlLCAhaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldENvbnRlbnRFbGVtZW50Q1NTKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRDb250ZW50RWxlbWVudENTUyhmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlQ29udGVudC53ID0gYXJyYW5nZUNvbnRlbnQuaCA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlQ2hhbmdlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyYW5nZUNoYW5nZWQgJiYgIV9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEFycmFuZ2VFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBoaWRlT3ZlcmZsb3cueSA/IGFycmFuZ2VDb250ZW50LncgOiBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEFycmFuZ2VFbGVtZW50Q1NTW19zdHJIZWlnaHRdID0gaGlkZU92ZXJmbG93LnggPyBhcnJhbmdlQ29udGVudC5oIDogX3N0ckVtcHR5O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9jb250ZW50QXJyYW5nZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRBcnJhbmdlRWxlbWVudCA9IEZSQU1FV09SSyhnZW5lcmF0ZURpdihfY2xhc3NOYW1lQ29udGVudEFycmFuZ2VFbGVtZW50KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQucHJlcGVuZChfY29udGVudEFycmFuZ2VFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRBcnJhbmdlRWxlbWVudC5jc3MoY29udGVudEFycmFuZ2VFbGVtZW50Q1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoY29udGVudEVsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRFbGVtZW50Q1NTID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nRWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2V0Vmlld3BvcnRDU1M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChob3N0U2l6ZUNoYW5nZWQgfHwgaGFzT3ZlcmZsb3cuYyB8fCBoaWRlT3ZlcmZsb3cuYyB8fCBjb250ZW50U2Nyb2xsU2l6ZS5jIHx8IG92ZXJmbG93QmVoYXZpb3JDaGFuZ2VkIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NoYW5nZWQgfHwgY3NzRGlyZWN0aW9uQ2hhbmdlZCB8fCBjbGlwQWx3YXlzQ2hhbmdlZCB8fCBoZWlnaHRBdXRvQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW2lzUlRMUmlnaHRdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0Vmlld3BvcnRDU1MgPSBmdW5jdGlvbiAoaG9yaXpvbnRhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhob3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFyc0ludmVydGVkID0gZ2V0U2Nyb2xsYmFyVmFycyghaG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHh5ID0gc2Nyb2xsYmFyVmFycy5feF95O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBYWSA9IHNjcm9sbGJhclZhcnMuX1hfWTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyRGlyZWN0aW9uID0gaG9yaXpvbnRhbCA/IF9zdHJCb3R0b20gOiBpc1JUTExlZnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNldCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW3N0ckRpcmVjdGlvbl0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50Qm9yZGVyU2l6ZVtzY3JvbGxiYXJWYXJzSW52ZXJ0ZWQuX3dfaF0gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhhc092ZXJmbG93W3h5XSAmJiBoaWRlT3ZlcmZsb3dbeHkgKyAncyddKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tzdHJPdmVyZmxvdyArIFhZXSA9IF9zdHJTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nIHx8IF9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNldCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW3N0ckRpcmVjdGlvbl0gPSAtKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkW3h5XSA/IF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplW3h5XSA6IF9uYXRpdmVTY3JvbGxiYXJTaXplW3h5XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEJvcmRlclNpemVbc2Nyb2xsYmFyVmFyc0ludmVydGVkLl93X2hdID0gX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWRbeHldID8gX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemVbc2Nyb2xsYmFyVmFyc0ludmVydGVkLl94X3ldIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tzdHJPdmVyZmxvdyArIFhZXSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0Vmlld3BvcnRDU1ModHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRWaWV3cG9ydENTUyhmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIHNjcm9sbCBjb250YWluZXIgaXMgdG9vIHNtYWxsIGFuZCBpZiB0aGVyZSBpcyBhbnkgb3ZlcmZsb3cgd2l0aCBubyBvdmVybGF5IHNjcm9sbGJhciAoYW5kIHNjcm9sbGJhciBzdHlsaW5nIGlzbid0IHBvc3NpYmxlKSwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIHZpZXdwb3J0IGVsZW1lbnQgZ3JlYXRlciBpbiBzaXplIChGaXJlZm94IGhpZGUgU2Nyb2xsYmFycyBmaXgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIGZpcmVmb3ggc3RhcnRzIGhpZGluZyBzY3JvbGxiYXJzIG9uIHRvbyBzbWFsbCBlbGVtZW50c1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2l0aCB0aGlzIGJlaGF2aW9yIHRoZSBvdmVyZmxvdyBjYWxjdWxhdGlvbiBtYXkgYmUgaW5jb3JyZWN0IG9yIHRoZSBzY3JvbGxiYXJzIHdvdWxkIGFwcGVhciBzdWRkZW5seVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjkyMjg0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKF92aWV3cG9ydFNpemUuaCA8IF9uYXRpdmVTY3JvbGxiYXJNaW5TaXplLnggfHwgX3ZpZXdwb3J0U2l6ZS53IDwgX25hdGl2ZVNjcm9sbGJhck1pblNpemUueSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAoKGhhc092ZXJmbG93LnggJiYgaGlkZU92ZXJmbG93LnggJiYgIV9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLngpIHx8IChoYXNPdmVyZmxvdy55ICYmIGhpZGVPdmVyZmxvdy55ICYmICFfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55KSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1NbX3N0clBhZGRpbmdNaW51cyArIF9zdHJUb3BdID0gX25hdGl2ZVNjcm9sbGJhck1pblNpemUueDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1NbX3N0ck1hcmdpbk1pbnVzICsgX3N0clRvcF0gPSAtX25hdGl2ZVNjcm9sbGJhck1pblNpemUueDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJQYWRkaW5nTWludXMgKyBpc1JUTFJpZ2h0XSA9IF9uYXRpdmVTY3JvbGxiYXJNaW5TaXplLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJNYXJnaW5NaW51cyArIGlzUlRMUmlnaHRdID0gLV9uYXRpdmVTY3JvbGxiYXJNaW5TaXplLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1NbX3N0clBhZGRpbmdNaW51cyArIF9zdHJUb3BdID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJNYXJnaW5NaW51cyArIF9zdHJUb3BdID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJQYWRkaW5nTWludXMgKyBpc1JUTFJpZ2h0XSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tfc3RyTWFyZ2luTWludXMgKyBpc1JUTFJpZ2h0XSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tfc3RyUGFkZGluZ01pbnVzICsgaXNSVExMZWZ0XSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJNYXJnaW5NaW51cyArIGlzUlRMTGVmdF0gPSBfc3RyRW1wdHk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiB0aGVyZSBpcyBhbnkgb3ZlcmZsb3cgKHggT1IgeSBheGlzKSBhbmQgdGhpcyBvdmVyZmxvdyBzaGFsbCBiZSBoaWRkZW4sIG1ha2Ugb3ZlcmZsb3cgaGlkZGVuLCBlbHNlIG92ZXJmbG93IHZpc2libGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoaGFzT3ZlcmZsb3cueCAmJiBoaWRlT3ZlcmZsb3cueCkgfHwgKGhhc092ZXJmbG93LnkgJiYgaGlkZU92ZXJmbG93LnkpIHx8IGhpZGVPdmVyZmxvd0ZvcmNlVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL29ubHkgaGlkZSBpZiBpcyBUZXh0YXJlYVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSAmJiBoaWRlT3ZlcmZsb3dGb3JjZVRleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZGRpbmdFbGVtZW50Q1NTW3N0ck92ZXJmbG93WF0gPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0VsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dZXSA9IHN0ckhpZGRlbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNsaXBBbHdheXMgfHwgKG92ZXJmbG93QmVoYXZpb3JJc1ZILnggfHwgb3ZlcmZsb3dCZWhhdmlvcklzVlMueCB8fCBvdmVyZmxvd0JlaGF2aW9ySXNWSC55IHx8IG92ZXJmbG93QmVoYXZpb3JJc1ZTLnkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vb25seSB1bi1oaWRlIGlmIFRleHRhcmVhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0VsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dYXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0VsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dZXSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dYXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dZXSA9IHN0clZpc2libGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nRWxlbWVudC5jc3MocGFkZGluZ0VsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudC5jc3Modmlld3BvcnRFbGVtZW50Q1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTUyA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZm9yY2Ugc29mdCByZWRyYXcgaW4gd2Via2l0IGJlY2F1c2Ugd2l0aG91dCB0aGUgc2Nyb2xsYmFycyB3aWxsIG1heSBhcHBlYXIgYmVjYXVzZSBET00gd29udCBiZSByZWRyYXduIHVuZGVyIHNwZWNpYWwgY29uZGl0aW9uc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChoYXNPdmVyZmxvdy5jIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgd2lkdGhBdXRvQ2hhbmdlZCB8fCBoZWlnaHRBdXRvQ2hhbmdlZCkgJiYgIShfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRTdHlsZSA9IF9jb250ZW50RWxlbWVudE5hdGl2ZVtMRVhJQ09OLnNdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkdW1wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSAnc2NhbGUoMSknO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdHlsZS5kaXNwbGF5ID0gJ3J1bi1pbic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVtcCA9IF9jb250ZW50RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9IXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3R5bGUuZGlzcGxheSA9IF9zdHJFbXB0eTsgLy98fCBkdW1wOyAvL3VzZSBkdW1wIHRvIHByZXZlbnQgaXQgZnJvbSBkZWxldGlvbiBpZiBtaW5pZnlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3R5bGUud2Via2l0VHJhbnNmb3JtID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLypcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZm9yY2UgaGFyZCByZWRyYXcgaW4gd2Via2l0IGlmIG5hdGl2ZSBvdmVybGFpZCBzY3JvbGxiYXJzIHNoYWxsIGFwcGVhclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkICYmIGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnQuaGlkZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkdW1wID0gX2hvc3RFbGVtZW50TmF0aXZlW0xFWElDT04ub0hdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudC5zaG93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2NoYW5nZSB0byBkaXJlY3Rpb24gUlRMIGFuZCB3aWR0aCBhdXRvIEJ1Z2ZpeCBpbiBXZWJraXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy93aXRob3V0IHRoaXMgZml4LCB0aGUgRE9NIHN0aWxsIHRoaW5rcyB0aGUgc2Nyb2xsYmFyIGlzIExUUiBhbmQgdGh1cyB0aGUgY29udGVudCBpcyBzaGlmdGVkIHRvIHRoZSBsZWZ0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjc3NEaXJlY3Rpb25DaGFuZ2VkIHx8IHdpZHRoQXV0b0NoYW5nZWQgfHwgaGVpZ2h0QXV0b0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNSVEwgJiYgd2lkdGhBdXRvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZsb2F0VG1wID0gX2NvbnRlbnRFbGVtZW50LmNzcyhfc3RyRmxvYXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3NMZWZ0V2l0aG91dEZsb2F0ID0gTUFUSC5yb3VuZChfY29udGVudEVsZW1lbnQuY3NzKF9zdHJGbG9hdCwgX3N0ckVtcHR5KS5jc3MoX3N0ckxlZnQsIF9zdHJFbXB0eSkucG9zaXRpb24oKS5sZWZ0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnQuY3NzKF9zdHJGbG9hdCwgZmxvYXRUbXApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3NMZWZ0V2l0aEZsb2F0ID0gTUFUSC5yb3VuZChfY29udGVudEVsZW1lbnQucG9zaXRpb24oKS5sZWZ0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBvc0xlZnRXaXRob3V0RmxvYXQgIT09IHBvc0xlZnRXaXRoRmxvYXQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJMZWZ0XSA9IHBvc0xlZnRXaXRob3V0RmxvYXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyTGVmdF0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhjb250ZW50RWxlbWVudENTUyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2hhbmRsZSBzY3JvbGwgcG9zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhICYmIGNvbnRlbnRTaXplQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhSW5mbyA9IGdldFRleHRhcmVhSW5mbygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRleHRhcmVhSW5mbykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYVJvd3NDaGFuZ2VkID0gX3RleHRhcmVhSW5mb0NhY2hlID09PSB1bmRlZmluZWQgPyB0cnVlIDogdGV4dGFyZWFJbmZvLl9yb3dzICE9PSBfdGV4dGFyZWFJbmZvQ2FjaGUuX3Jvd3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnNvclJvdyA9IHRleHRhcmVhSW5mby5fY3Vyc29yUm93O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JDb2wgPSB0ZXh0YXJlYUluZm8uX2N1cnNvckNvbHVtbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2lkZXN0Um93ID0gdGV4dGFyZWFJbmZvLl93aWRlc3RSb3c7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxhc3RSb3cgPSB0ZXh0YXJlYUluZm8uX3Jvd3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxhc3RDb2wgPSB0ZXh0YXJlYUluZm8uX2NvbHVtbnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnNvclBvcyA9IHRleHRhcmVhSW5mby5fY3Vyc29yUG9zaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnNvck1heCA9IHRleHRhcmVhSW5mby5fY3Vyc29yTWF4O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JJc0xhc3RQb3NpdGlvbiA9IChjdXJzb3JQb3MgPj0gY3Vyc29yTWF4ICYmIF90ZXh0YXJlYUhhc0ZvY3VzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFTY3JvbGxBbW91bnQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6ICghdGV4dGFyZWFBdXRvV3JhcHBpbmcgJiYgKGN1cnNvckNvbCA9PT0gbGFzdENvbCAmJiBjdXJzb3JSb3cgPT09IHdpZGVzdFJvdykpID8gX292ZXJmbG93QW1vdW50Q2FjaGUueCA6IC0xLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiAodGV4dGFyZWFBdXRvV3JhcHBpbmcgPyBjdXJzb3JJc0xhc3RQb3NpdGlvbiB8fCB0ZXh0YXJlYVJvd3NDaGFuZ2VkICYmIChwcmV2aW91c092ZXJmbG93QW1vdW50ID8gKGN1cnJTY3JvbGwueSA9PT0gcHJldmlvdXNPdmVyZmxvd0Ftb3VudC55KSA6IGZhbHNlKSA6IChjdXJzb3JJc0xhc3RQb3NpdGlvbiB8fCB0ZXh0YXJlYVJvd3NDaGFuZ2VkKSAmJiBjdXJzb3JSb3cgPT09IGxhc3RSb3cpID8gX292ZXJmbG93QW1vdW50Q2FjaGUueSA6IC0xXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyU2Nyb2xsLnggPSB0ZXh0YXJlYVNjcm9sbEFtb3VudC54ID4gLTEgPyAoX2lzUlRMICYmIF9ub3JtYWxpemVSVExDYWNoZSAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IuaSA/IDAgOiB0ZXh0YXJlYVNjcm9sbEFtb3VudC54KSA6IGN1cnJTY3JvbGwueDsgLy9pZiBpbnZlcnRlZCwgc2Nyb2xsIHRvIDAgLT4gbm9ybWFsaXplZCB0aGlzIG1lYW5zIHRvIG1heCBzY3JvbGwgb2Zmc2V0LlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJTY3JvbGwueSA9IHRleHRhcmVhU2Nyb2xsQW1vdW50LnkgPiAtMSA/IHRleHRhcmVhU2Nyb2xsQW1vdW50LnkgOiBjdXJyU2Nyb2xsLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGV4dGFyZWFJbmZvQ2FjaGUgPSB0ZXh0YXJlYUluZm87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1JUTCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IuaSAmJiBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55ICYmIGhhc092ZXJmbG93LnggJiYgX25vcm1hbGl6ZVJUTENhY2hlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyclNjcm9sbC54ICs9IF9jb250ZW50Qm9yZGVyU2l6ZS53IHx8IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3aWR0aEF1dG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGVpZ2h0QXV0bylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudFtfc3RyU2Nyb2xsVG9wXSgwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oY3VyclNjcm9sbC54KVtfc3RyU2Nyb2xsVG9wXShjdXJyU2Nyb2xsLnkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxiYXJzIG1hbmFnZW1lbnQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzVmlzaWJpbGl0eVZpc2libGUgPSBzY3JvbGxiYXJzVmlzaWJpbGl0eSA9PT0gJ3YnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc1Zpc2liaWxpdHlIaWRkZW4gPSBzY3JvbGxiYXJzVmlzaWJpbGl0eSA9PT0gJ2gnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc1Zpc2liaWxpdHlBdXRvID0gc2Nyb2xsYmFyc1Zpc2liaWxpdHkgPT09ICdhJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlZnJlc2hTY3JvbGxiYXJzVmlzaWJpbGl0eSA9IGZ1bmN0aW9uIChzaG93WCwgc2hvd1kpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3dZID0gc2hvd1kgPT09IHVuZGVmaW5lZCA/IHNob3dYIDogc2hvd1k7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyQXBwZWFyYW5jZSh0cnVlLCBzaG93WCwgY2FuU2Nyb2xsLngpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyQXBwZWFyYW5jZShmYWxzZSwgc2hvd1ksIGNhblNjcm9sbC55KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2UgY2xhc3MgbmFtZSB3aGljaCBpbmRpY2F0ZXMgc2Nyb2xsYWJsZSBvdmVyZmxvd1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3csIGhpZGVPdmVyZmxvdy54IHx8IGhpZGVPdmVyZmxvdy55KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBfY2xhc3NOYW1lSG9zdE92ZXJmbG93WCwgaGlkZU92ZXJmbG93LngpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3dZLCBoaWRlT3ZlcmZsb3cueSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2FkZCBvciByZW1vdmUgcnRsIGNsYXNzIG5hbWUgZm9yIHN0eWxpbmcgcHVycG9zZXMgZXhjZXB0IHdoZW4gaXRzIGJvZHksIHRoZW4gdGhlIHNjcm9sbGJhciBzdGF5c1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3NzRGlyZWN0aW9uQ2hhbmdlZCAmJiAhX2lzQm9keSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBfY2xhc3NOYW1lSG9zdFJUTCwgX2lzUlRMKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2UgdGhlIHJlc2l6ZSBmZWF0dXJlIChDU1MzIHJlc2l6ZSBcInBvbHlmaWxsXCIgZm9yIHRoaXMgcGx1Z2luKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF9ob3N0RWxlbWVudCwgX2NsYXNzTmFtZUhvc3RSZXNpemVEaXNhYmxlZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNpemVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0UmVzaXplRGlzYWJsZWQsIF9yZXNpemVOb25lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFJlbW92ZUNsYXNzKF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplLCAhX3Jlc2l6ZU5vbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQsIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemVCLCBfcmVzaXplQm90aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCwgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZUgsIF9yZXNpemVIb3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFJlbW92ZUNsYXNzKF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplViwgX3Jlc2l6ZVZlcnRpY2FsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2UgdGhlIHNjcm9sbGJhcnMgZ2VuZXJhbCB2aXNpYmlsaXR5ICsgdGhlIHNjcm9sbGJhciBpbnRlcmFjdGl2aXR5ICh1bnVzYWJsZSBjbGFzcyBuYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2Nyb2xsYmFyc1Zpc2liaWxpdHlDaGFuZ2VkIHx8IG92ZXJmbG93QmVoYXZpb3JDaGFuZ2VkIHx8IGhpZGVPdmVyZmxvdy5jIHx8IGhhc092ZXJmbG93LmMgfHwgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ob3N0RWxlbWVudCwgX2NsYXNzTmFtZUhvc3RTY3JvbGxpbmcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNWaXNpYmlsaXR5KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHNjcm9sbGJhcnNWaXNpYmlsaXR5QXV0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzVmlzaWJpbGl0eShjYW5TY3JvbGwueCwgY2FuU2Nyb2xsLnkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoc2Nyb2xsYmFyc1Zpc2liaWxpdHlWaXNpYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNWaXNpYmlsaXR5KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoc2Nyb2xsYmFyc1Zpc2liaWxpdHlIaWRkZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc1Zpc2liaWxpdHkoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21hbmFnZSB0aGUgc2Nyb2xsYmFycyBhdXRvIGhpZGUgZmVhdHVyZSAoYXV0byBoaWRlIHRoZW0gYWZ0ZXIgc3BlY2lmaWMgYWN0aW9ucylcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbGJhcnNBdXRvSGlkZUNoYW5nZWQgfHwgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwSG9zdE1vdXNlVG91Y2hFdmVudHMoIV9zY3JvbGxiYXJzQXV0b0hpZGVMZWF2ZSAmJiAhX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZShfc2Nyb2xsYmFyc0F1dG9IaWRlTmV2ZXIsICFfc2Nyb2xsYmFyc0F1dG9IaWRlTmV2ZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21hbmFnZSBzY3JvbGxiYXJzIGhhbmRsZSBsZW5ndGggJiBvZmZzZXQgLSBkb24ndCByZW1vdmUhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChob3N0U2l6ZUNoYW5nZWQgfHwgb3ZlcmZsb3dBbW91bnQuYyB8fCBoZWlnaHRBdXRvQ2hhbmdlZCB8fCB3aWR0aEF1dG9DaGFuZ2VkIHx8IHJlc2l6ZUNoYW5nZWQgfHwgYm94U2l6aW5nQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkIHx8IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkIHx8IGNzc0RpcmVjdGlvbkNoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVMZW5ndGgodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZUxlbmd0aChmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2UgaW50ZXJhY3Rpdml0eVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2Nyb2xsYmFyc0NsaWNrU2Nyb2xsaW5nQ2hhbmdlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzSW50ZXJhY3RpdmUodHJ1ZSwgc2Nyb2xsYmFyc0NsaWNrU2Nyb2xsaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2hhbmdlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzSW50ZXJhY3RpdmUoZmFsc2UsIHNjcm9sbGJhcnNEcmFnU2Nyb2xsaW5nKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vY2FsbGJhY2tzOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvbkRpcmVjdGlvbkNoYW5nZWQnLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1JUTDogX2lzUlRMLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlyOiBjc3NEaXJlY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgY3NzRGlyZWN0aW9uQ2hhbmdlZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uSG9zdFNpemVDaGFuZ2VkJywge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IF9ob3N0U2l6ZUNhY2hlLncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IF9ob3N0U2l6ZUNhY2hlLmhcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgaG9zdFNpemVDaGFuZ2VkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25Db250ZW50U2l6ZUNoYW5nZWQnLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGUudyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGUuaFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBjb250ZW50U2l6ZUNoYW5nZWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvbk92ZXJmbG93Q2hhbmdlZCcsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGhhc092ZXJmbG93LngsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBoYXNPdmVyZmxvdy55LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeFNjcm9sbGFibGU6IGhpZGVPdmVyZmxvdy54cyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlTY3JvbGxhYmxlOiBoaWRlT3ZlcmZsb3cueXMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGlwcGVkOiBoaWRlT3ZlcmZsb3cueCB8fCBoaWRlT3ZlcmZsb3cueVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBoYXNPdmVyZmxvdy5jIHx8IGhpZGVPdmVyZmxvdy5jKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25PdmVyZmxvd0Ftb3VudENoYW5nZWQnLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBvdmVyZmxvd0Ftb3VudC54LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogb3ZlcmZsb3dBbW91bnQueVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBvdmVyZmxvd0Ftb3VudC5jKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZml4IGJvZHkgbWluIHNpemVcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSAmJiBfYm9keU1pblNpemVDYWNoZSAmJiAoX2hhc092ZXJmbG93Q2FjaGUuYyB8fCBfYm9keU1pblNpemVDYWNoZS5jKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2l0cyBwb3NzaWJsZSB0aGF0IG5vIG1pbiBzaXplIHdhcyBtZWFzdXJlZCB1bnRpbCBub3csIGJlY2F1c2UgdGhlIGNvbnRlbnQgYXJyYW5nZSBlbGVtZW50IHdhcyBqdXN0IGFkZGVkIG5vdywgaW4gdGhpcyBjYXNlLCBtZWFzdXJlIG5vdyB0aGUgbWluIHNpemUuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2JvZHlNaW5TaXplQ2FjaGUuZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvZHlNaW5TaXplQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSAmJiBfaGFzT3ZlcmZsb3dDYWNoZS54KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhfc3RyTWluTWludXMgKyBfc3RyV2lkdGgsIF9ib2R5TWluU2l6ZUNhY2hlLncgKyBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZS55KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgX2hhc092ZXJmbG93Q2FjaGUueSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoX3N0ck1pbk1pbnVzICsgX3N0ckhlaWdodCwgX2JvZHlNaW5TaXplQ2FjaGUuaCArIF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplLngpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYm9keU1pblNpemVDYWNoZS5jID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2luaXRpYWxpemVkICYmIGNoYW5nZWRPcHRpb25zLnVwZGF0ZU9uTG9hZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVFbGVtZW50c09uTG9hZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9mcmVlemVSZXNpemVPYnNlcnZlcihfc2l6ZU9ic2VydmVyRWxlbWVudCwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vZnJlZXplUmVzaXplT2JzZXJ2ZXIoX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LCBmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uVXBkYXRlZCcsIHsgZm9yY2VkOiBmb3JjZSB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFVwZGF0ZXMgdGhlIGZvdW5kIGVsZW1lbnRzIG9mIHdoaWNoIHRoZSBsb2FkIGV2ZW50IHNoYWxsIGJlIGhhbmRsZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZUVsZW1lbnRzT25Mb2FkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghX2lzVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaFVwZGF0ZU9uTG9hZChmdW5jdGlvbiAoaSwgdXBkYXRlT25Mb2FkU2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5maW5kKHVwZGF0ZU9uTG9hZFNlbGVjdG9yKS5lYWNoKGZ1bmN0aW9uIChpLCBlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIGVsZW1lbnQgZG9lc24ndCBoYXZlIGEgdXBkYXRlT25Mb2FkQ2FsbGJhY2sgYXBwbGllZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChDT01QQVRJQklMSVRZLmluQShlbCwgX3VwZGF0ZU9uTG9hZEVsbXMpIDwgMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdXBkYXRlT25Mb2FkRWxtcy5wdXNoKGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLKGVsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9mZihfdXBkYXRlT25Mb2FkRXZlbnROYW1lLCB1cGRhdGVPbkxvYWRDYWxsYmFjaylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbihfdXBkYXRlT25Mb2FkRXZlbnROYW1lLCB1cGRhdGVPbkxvYWRDYWxsYmFjayk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gT3B0aW9ucyA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNldHMgbmV3IG9wdGlvbnMgYnV0IGRvZXNuJ3QgY2FsbCB0aGUgdXBkYXRlIG1ldGhvZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBuZXdPcHRpb25zIFRoZSBvYmplY3Qgd2hpY2ggY29udGFpbnMgdGhlIG5ldyBvcHRpb25zLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMgeyp9IEEgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBjaGFuZ2VkIG9wdGlvbnMuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldE9wdGlvbnMobmV3T3B0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWxpZGF0ZWRPcHRzID0gX3BsdWdpbnNPcHRpb25zLl92YWxpZGF0ZShuZXdPcHRpb25zLCBfcGx1Z2luc09wdGlvbnMuX3RlbXBsYXRlLCB0cnVlLCBfY3VycmVudE9wdGlvbnMpXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF9jdXJyZW50T3B0aW9ucyA9IGV4dGVuZERlZXAoe30sIF9jdXJyZW50T3B0aW9ucywgdmFsaWRhdGVkT3B0cy5fZGVmYXVsdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMgPSBleHRlbmREZWVwKHt9LCBfY3VycmVudFByZXBhcmVkT3B0aW9ucywgdmFsaWRhdGVkT3B0cy5fcHJlcGFyZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsaWRhdGVkT3B0cy5fcHJlcGFyZWQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBTdHJ1Y3R1cmUgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBCdWlsZHMgb3IgZGVzdHJveXMgdGhlIHdyYXBwZXIgYW5kIGhlbHBlciBET00gZWxlbWVudHMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZGVzdHJveSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgRE9NIHNoYWxsIGJlIGJ1aWxkIG9yIGRlc3Ryb3llZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBCdWlsZHMgb3IgZGVzdHJveXMgdGhlIHdyYXBwZXIgYW5kIGhlbHBlciBET00gZWxlbWVudHMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZGVzdHJveSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgRE9NIHNoYWxsIGJlIGJ1aWxkIG9yIGRlc3Ryb3llZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBTdHJ1Y3R1cmVET00oZGVzdHJveSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJQYXJlbnQgPSAncGFyZW50JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJIb3N0ID0gJ29zLXJlc2l6ZS1vYnNlcnZlci1ob3N0JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50RnVsbCA9IF9jbGFzc05hbWVUZXh0YXJlYUVsZW1lbnQgKyBfc3RyU3BhY2UgKyBfY2xhc3NOYW1lVGV4dEluaGVyaXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhQ2xhc3MgPSBfaXNUZXh0YXJlYSA/IF9zdHJTcGFjZSArIF9jbGFzc05hbWVUZXh0SW5oZXJpdCA6IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWRvcHRBdHRycyA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLnRleHRhcmVhLmluaGVyaXRlZEF0dHJzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhZG9wdEF0dHJzTWFwID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFwcGx5QWRvcHRlZEF0dHJzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXBwbHlBZG9wdGVkQXR0cnNFbG0gPSBkZXN0cm95ID8gX3RhcmdldEVsZW1lbnQgOiBfaG9zdEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVhY2goYWRvcHRBdHRyc01hcCwgZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKHZhbHVlKSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleSA9PSBMRVhJQ09OLmMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGx5QWRvcHRlZEF0dHJzRWxtLmFkZENsYXNzKHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGx5QWRvcHRlZEF0dHJzRWxtLmF0dHIoa2V5LCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhvc3RFbGVtZW50Q2xhc3NOYW1lcyA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lSG9zdEVsZW1lbnRGb3JlaWduLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lSG9zdFRleHRhcmVhRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RSZXNpemVEaXNhYmxlZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RSVEwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVIb3N0U2Nyb2xsYmFySG9yaXpvbnRhbEhpZGRlbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RTY3JvbGxiYXJWZXJ0aWNhbEhpZGRlbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RUcmFuc2l0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lSG9zdFNjcm9sbGluZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RPdmVyZmxvdyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RPdmVyZmxvd1gsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3dZLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lVGhlbWVOb25lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lVGV4dEluaGVyaXQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVDYWNoZV0uam9pbihfc3RyU3BhY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBob3N0RWxlbWVudENTUyA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2dldCBob3N0IGVsZW1lbnQgYXMgZmlyc3QgZWxlbWVudCwgYmVjYXVzZSB0aGF0J3MgdGhlIG1vc3QgdXBwZXIgZWxlbWVudCBhbmQgcmVxdWlyZWQgZm9yIHRoZSBvdGhlciBlbGVtZW50c1xyXG4gICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudCA9IF9ob3N0RWxlbWVudCB8fCAoX2lzVGV4dGFyZWEgPyAoX2RvbUV4aXN0cyA/IF90YXJnZXRFbGVtZW50W3N0clBhcmVudF0oKVtzdHJQYXJlbnRdKClbc3RyUGFyZW50XSgpW3N0clBhcmVudF0oKSA6IEZSQU1FV09SSyhnZW5lcmF0ZURpdihfY2xhc3NOYW1lSG9zdFRleHRhcmVhRWxlbWVudCkpKSA6IF90YXJnZXRFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnQgPSBfY29udGVudEVsZW1lbnQgfHwgc2VsZWN0T3JHZW5lcmF0ZURpdkJ5Q2xhc3MoX2NsYXNzTmFtZUNvbnRlbnRFbGVtZW50ICsgdGV4dGFyZWFDbGFzcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudCA9IF92aWV3cG9ydEVsZW1lbnQgfHwgc2VsZWN0T3JHZW5lcmF0ZURpdkJ5Q2xhc3MoX2NsYXNzTmFtZVZpZXdwb3J0RWxlbWVudCArIHRleHRhcmVhQ2xhc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nRWxlbWVudCA9IF9wYWRkaW5nRWxlbWVudCB8fCBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lUGFkZGluZ0VsZW1lbnQgKyB0ZXh0YXJlYUNsYXNzKTtcclxuICAgICAgICAgICAgICAgICAgICBfc2l6ZU9ic2VydmVyRWxlbWVudCA9IF9zaXplT2JzZXJ2ZXJFbGVtZW50IHx8IHNlbGVjdE9yR2VuZXJhdGVEaXZCeUNsYXNzKGNsYXNzTmFtZVJlc2l6ZU9ic2VydmVySG9zdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RleHRhcmVhQ292ZXJFbGVtZW50ID0gX3RleHRhcmVhQ292ZXJFbGVtZW50IHx8IChfaXNUZXh0YXJlYSA/IHNlbGVjdE9yR2VuZXJhdGVEaXZCeUNsYXNzKF9jbGFzc05hbWVUZXh0YXJlYUNvdmVyRWxlbWVudCkgOiB1bmRlZmluZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2FkZCB0aGlzIGNsYXNzIHRvIHdvcmthcm91bmQgY2xhc3MgY2hhbmdpbmcgaXNzdWVzIHdpdGggVUkgZnJhbWV3b3JrcyBlc3BlY2lhbGx5IFZ1ZVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfZG9tRXhpc3RzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0RWxlbWVudEZvcmVpZ24pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL29uIGRlc3Ryb3ksIHJlbW92ZSBhbGwgZ2VuZXJhdGVkIGNsYXNzIG5hbWVzIGZyb20gdGhlIGhvc3QgZWxlbWVudCBiZWZvcmUgY29sbGVjdGluZyB0aGUgYWRvcHRlZCBhdHRyaWJ1dGVzIFxyXG4gICAgICAgICAgICAgICAgICAgIC8vdG8gcHJldmVudCBhZG9wdGluZyBnZW5lcmF0ZWQgY2xhc3MgbmFtZXNcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZGVzdHJveSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBob3N0RWxlbWVudENsYXNzTmFtZXMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NvbGxlY3QgYWxsIGFkb3B0ZWQgYXR0cmlidXRlc1xyXG4gICAgICAgICAgICAgICAgICAgIGFkb3B0QXR0cnMgPSB0eXBlKGFkb3B0QXR0cnMpID09IFRZUEVTLnMgPyBhZG9wdEF0dHJzLnNwbGl0KF9zdHJTcGFjZSkgOiBhZG9wdEF0dHJzO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChDT01QQVRJQklMSVRZLmlzQShhZG9wdEF0dHJzKSAmJiBfaXNUZXh0YXJlYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlYWNoKGFkb3B0QXR0cnMsIGZ1bmN0aW9uIChpLCB2KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSh2KSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRvcHRBdHRyc01hcFt2XSA9IGRlc3Ryb3kgPyBfaG9zdEVsZW1lbnQuYXR0cih2KSA6IF90YXJnZXRFbGVtZW50LmF0dHIodik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfY3VycmVudFByZXBhcmVkT3B0aW9ucy5zaXplQXV0b0NhcGFibGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3N0RWxlbWVudENTU1tfc3RyV2lkdGhdID0gX3RhcmdldEVsZW1lbnQuY3NzKF9zdHJXaWR0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zdEVsZW1lbnRDU1NbX3N0ckhlaWdodF0gPSBfdGFyZ2V0RWxlbWVudC5jc3MoX3N0ckhlaWdodCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfZG9tRXhpc3RzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LmFkZENsYXNzKF9jbGFzc05hbWVUZXh0SW5oZXJpdCkud3JhcChfaG9zdEVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8valF1ZXJ5IGNsb25lcyBlbGVtZW50cyBpbiB3cmFwIGZ1bmN0aW9ucywgc28gd2UgaGF2ZSB0byBzZWxlY3QgdGhlbSBhZ2FpblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50ID0gX3RhcmdldEVsZW1lbnRbc3RyUGFyZW50XSgpLmNzcyhob3N0RWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2RvbUV4aXN0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9hZGQgdGhlIGNvcnJlY3QgY2xhc3MgdG8gdGhlIHRhcmdldCBlbGVtZW50XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfdGFyZ2V0RWxlbWVudCwgX2lzVGV4dGFyZWEgPyBjbGFzc05hbWVUZXh0YXJlYUVsZW1lbnRGdWxsIDogX2NsYXNzTmFtZUhvc3RFbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3dyYXAgdGhlIGNvbnRlbnQgaW50byB0aGUgZ2VuZXJhdGVkIGVsZW1lbnRzIHRvIGNyZWF0ZSB0aGUgcmVxdWlyZWQgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnQud3JhcElubmVyKF9jb250ZW50RWxlbWVudClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAud3JhcElubmVyKF92aWV3cG9ydEVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndyYXBJbm5lcihfcGFkZGluZ0VsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnByZXBlbmQoX3NpemVPYnNlcnZlckVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8valF1ZXJ5IGNsb25lcyBlbGVtZW50cyBpbiB3cmFwIGZ1bmN0aW9ucywgc28gd2UgaGF2ZSB0byBzZWxlY3QgdGhlbSBhZ2FpblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50ID0gZmluZEZpcnN0KF9ob3N0RWxlbWVudCwgX3N0ckRvdCArIF9jbGFzc05hbWVDb250ZW50RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50ID0gZmluZEZpcnN0KF9ob3N0RWxlbWVudCwgX3N0ckRvdCArIF9jbGFzc05hbWVWaWV3cG9ydEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50ID0gZmluZEZpcnN0KF9ob3N0RWxlbWVudCwgX3N0ckRvdCArIF9jbGFzc05hbWVQYWRkaW5nRWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LnByZXBlbmQoX3RleHRhcmVhQ292ZXJFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBseUFkb3B0ZWRBdHRycygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfdmlld3BvcnRFbGVtZW50LCBfY2xhc3NOYW1lVmlld3BvcnROYXRpdmVTY3JvbGxiYXJzSW52aXNpYmxlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF92aWV3cG9ydEVsZW1lbnQsIF9jbGFzc05hbWVWaWV3cG9ydE5hdGl2ZVNjcm9sbGJhcnNPdmVybGFpZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNCb2R5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX2h0bWxFbGVtZW50LCBfY2xhc3NOYW1lSFRNTEVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVPYnNlcnZlckVsZW1lbnROYXRpdmUgPSBfc2l6ZU9ic2VydmVyRWxlbWVudFswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50TmF0aXZlID0gX2hvc3RFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfcGFkZGluZ0VsZW1lbnROYXRpdmUgPSBfcGFkZGluZ0VsZW1lbnRbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnROYXRpdmUgPSBfdmlld3BvcnRFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnROYXRpdmUgPSBfY29udGVudEVsZW1lbnRbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVWaWV3cG9ydEF0dHJzRnJvbVRhcmdldCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9kb21FeGlzdHMgJiYgX2luaXRpYWxpemVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NsZWFyIHNpemUgb2JzZXJ2ZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplT2JzZXJ2ZXJFbGVtZW50LmNoaWxkcmVuKCkucmVtb3ZlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgdGhlIHN0eWxlIHByb3BlcnR5IGFuZCBjbGFzc2VzIGZyb20gYWxyZWFkeSBnZW5lcmF0ZWQgZWxlbWVudHNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2goW19wYWRkaW5nRWxlbWVudCwgX3ZpZXdwb3J0RWxlbWVudCwgX2NvbnRlbnRFbGVtZW50LCBfdGV4dGFyZWFDb3ZlckVsZW1lbnRdLCBmdW5jdGlvbiAoaSwgZWxtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsbSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhlbG0ucmVtb3ZlQXR0cihMRVhJQ09OLnMpLCBfY2xhc3NOYW1lc0R5bmFtaWNEZXN0cm95KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2FkZCBjbGFzc2VzIHRvIHRoZSBob3N0IGVsZW1lbnQgd2hpY2ggd2FzIHJlbW92ZWQgcHJldmlvdXNseSB0byBtYXRjaCB0aGUgZXhwZWN0ZWQgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIF9pc1RleHRhcmVhID8gX2NsYXNzTmFtZUhvc3RUZXh0YXJlYUVsZW1lbnQgOiBfY2xhc3NOYW1lSG9zdEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgc2l6ZSBvYnNlcnZlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKF9zaXplT2JzZXJ2ZXJFbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3Vud3JhcCB0aGUgY29udGVudCB0byByZXN0b3JlIERPTVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNvbnRlbnRzKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudW53cmFwKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudW53cmFwKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudW53cmFwKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnQudW53cmFwKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKF9ob3N0RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKF90ZXh0YXJlYUNvdmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwbHlBZG9wdGVkQXR0cnMoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnQucmVtb3ZlQXR0cihMRVhJQ09OLnMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc0JvZHkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhfaHRtbEVsZW1lbnQsIF9jbGFzc05hbWVIVE1MRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQWRkcyBvciByZW1vdmVzIGFsbCB3cmFwcGVyIGVsZW1lbnRzIGludGVyYWN0aXZpdHkgZXZlbnRzLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlc3Ryb3kgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIEV2ZW50cyBzaGFsbCBiZSBhZGRlZCBvciByZW1vdmVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXR1cFN0cnVjdHVyZUV2ZW50cygpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFLZXlEb3duUmVzdHJpY3RlZEtleUNvZGVzID0gW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMywgICAgLy9GMSB0byBGMTJcclxuICAgICAgICAgICAgICAgICAgICAgICAgMzMsIDM0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcGFnZSB1cCwgcGFnZSBkb3duXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDM3LCAzOCwgMzksIDQwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2xlZnQsIHVwLCByaWdodCwgZG93biBhcnJvd3NcclxuICAgICAgICAgICAgICAgICAgICAgICAgMTYsIDE3LCAxOCwgMTksIDIwLCAxNDQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vU2hpZnQsIEN0cmwsIEFsdCwgUGF1c2UsIENhcHNMb2NrLCBOdW1Mb2NrXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhVXBkYXRlSW50ZXJ2YWxJRDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsU3RvcFRpbWVvdXRJZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsU3RvcERlbGF5ID0gMTc1O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJGb2N1cyA9ICdmb2N1cyc7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVRleHRhcmVhKGRvQ2xlYXJJbnRlcnZhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYVVwZGF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS51cGRhdGUoX3N0ckF1dG8pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9DbGVhckludGVydmFsICYmIF9hdXRvVXBkYXRlUmVjb21tZW5kZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKHRleHRhcmVhVXBkYXRlSW50ZXJ2YWxJRCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHRleHRhcmVhT25TY3JvbGwoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKF9ydGxTY3JvbGxCZWhhdmlvci5pICYmIF9ub3JtYWxpemVSVExDYWNoZSA/IDk5OTk5OTkgOiAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnRbX3N0clNjcm9sbFRvcF0oMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuc3RwUChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gdGV4dGFyZWFPbkRyb3AoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9kZXN0cm95ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlVGV4dGFyZWEoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiB0ZXh0YXJlYU9uRm9jdXMoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUhhc0ZvY3VzID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX2hvc3RFbGVtZW50LCBzdHJGb2N1cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHRleHRhcmVhT25Gb2N1c291dCgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RleHRhcmVhSGFzRm9jdXMgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ob3N0RWxlbWVudCwgc3RyRm9jdXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVUZXh0YXJlYSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gdGV4dGFyZWFPbktleURvd24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGtleUNvZGUgPSBldmVudC5rZXlDb2RlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkoa2V5Q29kZSwgdGV4dGFyZWFLZXlEb3duUmVzdHJpY3RlZEtleUNvZGVzKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0W0xFWElDT04ubF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVUZXh0YXJlYSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRhcmVhVXBkYXRlSW50ZXJ2YWxJRCA9IHNldEludGVydmFsKHVwZGF0ZVRleHRhcmVhLCAxMDAwIC8gNjApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkoa2V5Q29kZSwgdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0KSA8IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0LnB1c2goa2V5Q29kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gdGV4dGFyZWFPbktleVVwKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXlDb2RlID0gZXZlbnQua2V5Q29kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gaW5BcnJheShrZXlDb2RlLCB0ZXh0YXJlYUtleURvd25LZXlDb2Rlc0xpc3QpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkoa2V5Q29kZSwgdGV4dGFyZWFLZXlEb3duUmVzdHJpY3RlZEtleUNvZGVzKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRhcmVhS2V5RG93bktleUNvZGVzTGlzdC5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0ZXh0YXJlYUtleURvd25LZXlDb2Rlc0xpc3RbTEVYSUNPTi5sXSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVUZXh0YXJlYSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBjb250ZW50T25UcmFuc2l0aW9uRW5kKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfYXV0b1VwZGF0ZUNhY2hlID09PSB0cnVlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQgfHwgZXZlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1NpemVBZmZlY3RpbmdDU1NQcm9wZXJ0eShldmVudC5wcm9wZXJ0eU5hbWUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlKF9zdHJBdXRvKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gdmlld3BvcnRPblNjcm9sbChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9zbGVlcGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbFN0b3BUaW1lb3V0SWQgIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoc2Nyb2xsU3RvcFRpbWVvdXRJZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZSh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFuYXRpdmVPdmVybGF5U2Nyb2xsYmFyc0FyZUFjdGl2ZSgpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0U2Nyb2xsaW5nKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25TY3JvbGxTdGFydCcsIGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIGEgc2Nyb2xsYmFycyBoYW5kbGUgZ2V0cyBkcmFnZ2VkLCB0aGUgbW91c2Vtb3ZlIGV2ZW50IGlzIHJlc3BvbnNpYmxlIGZvciByZWZyZXNoaW5nIHRoZSBoYW5kbGUgb2Zmc2V0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2JlY2F1c2UgaWYgQ1NTIHNjcm9sbC1zbmFwIGlzIHVzZWQsIHRoZSBoYW5kbGUgb2Zmc2V0IGdldHMgb25seSByZWZyZXNoZWQgb24gZXZlcnkgc25hcCBwb2ludFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzIGxvb2tzIGxhZ2d5ICYgY2x1bmt5LCBpdCBsb29rcyBtdWNoIGJldHRlciBpZiB0aGUgb2Zmc2V0IHJlZnJlc2hlcyB3aXRoIHRoZSBtb3VzZW1vdmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldCh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uU2Nyb2xsJywgZXZlbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFN0b3BUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9kZXN0cm95ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9PblNjcm9sbFN0b3A6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChzY3JvbGxTdG9wVGltZW91dElkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsU3RvcFRpbWVvdXRJZCA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlU2Nyb2xsIHx8IF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZShmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5hdGl2ZU92ZXJsYXlTY3JvbGxiYXJzQXJlQWN0aXZlKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0U2Nyb2xsaW5nKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uU2Nyb2xsU3RvcCcsIGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCBzY3JvbGxTdG9wRGVsYXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbXNpZVZlcnNpb24gPiA5IHx8ICFfYXV0b1VwZGF0ZVJlY29tbWVuZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihfdGFyZ2V0RWxlbWVudCwgJ2lucHV0JywgdXBkYXRlVGV4dGFyZWEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIoX3RhcmdldEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW19zdHJLZXlEb3duRXZlbnQsIF9zdHJLZXlVcEV2ZW50XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGV4dGFyZWFPbktleURvd24sIHRleHRhcmVhT25LZXlVcF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihfdGFyZ2V0RWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtfc3RyU2Nyb2xsLCAnZHJvcCcsIHN0ckZvY3VzLCBzdHJGb2N1cyArICdvdXQnXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0ZXh0YXJlYU9uU2Nyb2xsLCB0ZXh0YXJlYU9uRHJvcCwgdGV4dGFyZWFPbkZvY3VzLCB0ZXh0YXJlYU9uRm9jdXNvdXRdKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKF9jb250ZW50RWxlbWVudCwgX3N0clRyYW5zaXRpb25FbmRFdmVudCwgY29udGVudE9uVHJhbnNpdGlvbkVuZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKF92aWV3cG9ydEVsZW1lbnQsIF9zdHJTY3JvbGwsIHZpZXdwb3J0T25TY3JvbGwsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gU2Nyb2xsYmFycyA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEJ1aWxkcyBvciBkZXN0cm95cyBhbGwgc2Nyb2xsYmFyIERPTSBlbGVtZW50cyAoc2Nyb2xsYmFyLCB0cmFjaywgaGFuZGxlKVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlc3Ryb3kgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIERPTSBzaGFsbCBiZSBidWlsZCBvciBkZXN0cm95ZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldHVwU2Nyb2xsYmFyc0RPTShkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdE9yR2VuZXJhdGVTY3JvbGxiYXJET00gPSBmdW5jdGlvbiAoaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJDbGFzc05hbWUgPSBpc0hvcml6b250YWwgPyBfY2xhc3NOYW1lU2Nyb2xsYmFySG9yaXpvbnRhbCA6IF9jbGFzc05hbWVTY3JvbGxiYXJWZXJ0aWNhbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhciA9IHNlbGVjdE9yR2VuZXJhdGVEaXZCeUNsYXNzKF9jbGFzc05hbWVTY3JvbGxiYXIgKyBfc3RyU3BhY2UgKyBzY3JvbGxiYXJDbGFzc05hbWUsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhY2sgPSBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lU2Nyb2xsYmFyVHJhY2ssIHNjcm9sbGJhcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGUgPSBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lU2Nyb2xsYmFySGFuZGxlLCBzY3JvbGxiYXIpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfZG9tRXhpc3RzICYmICFkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXIuYXBwZW5kKHRyYWNrKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLmFwcGVuZChoYW5kbGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcjogc2Nyb2xsYmFyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RyYWNrOiB0cmFjayxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9oYW5kbGU6IGhhbmRsZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVzZXRTY3JvbGxiYXJET00oaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhpc0hvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyID0gc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhY2sgPSBzY3JvbGxiYXJWYXJzLl90cmFjaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZSA9IHNjcm9sbGJhclZhcnMuX2hhbmRsZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZG9tRXhpc3RzICYmIF9pbml0aWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWFjaChbc2Nyb2xsYmFyLCB0cmFjaywgaGFuZGxlXSwgZnVuY3Rpb24gKGksIGVsbSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKGVsbS5yZW1vdmVBdHRyKExFWElDT04ucyksIF9jbGFzc05hbWVzRHluYW1pY0Rlc3Ryb3kpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUoc2Nyb2xsYmFyIHx8IHNlbGVjdE9yR2VuZXJhdGVTY3JvbGxiYXJET00oaXNIb3Jpem9udGFsKS5fc2Nyb2xsYmFyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB2YXIgaG9yaXpvbnRhbEVsZW1lbnRzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2ZXJ0aWNhbEVsZW1lbnRzO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWRlc3Ryb3kpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaG9yaXpvbnRhbEVsZW1lbnRzID0gc2VsZWN0T3JHZW5lcmF0ZVNjcm9sbGJhckRPTSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmVydGljYWxFbGVtZW50cyA9IHNlbGVjdE9yR2VuZXJhdGVTY3JvbGxiYXJET00oKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJIb3Jpem9udGFsRWxlbWVudCA9IGhvcml6b250YWxFbGVtZW50cy5fc2Nyb2xsYmFyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFySG9yaXpvbnRhbFRyYWNrRWxlbWVudCA9IGhvcml6b250YWxFbGVtZW50cy5fdHJhY2s7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudCA9IGhvcml6b250YWxFbGVtZW50cy5faGFuZGxlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50ID0gdmVydGljYWxFbGVtZW50cy5fc2Nyb2xsYmFyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyVmVydGljYWxUcmFja0VsZW1lbnQgPSB2ZXJ0aWNhbEVsZW1lbnRzLl90cmFjaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhclZlcnRpY2FsSGFuZGxlRWxlbWVudCA9IHZlcnRpY2FsRWxlbWVudHMuX2hhbmRsZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2RvbUV4aXN0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50LmFmdGVyKF9zY3JvbGxiYXJWZXJ0aWNhbEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50LmFmdGVyKF9zY3JvbGxiYXJIb3Jpem9udGFsRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0U2Nyb2xsYmFyRE9NKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNldFNjcm9sbGJhckRPTSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGFsbCBzY3JvbGxiYXIgaW50ZXJhY3Rpdml0eSBldmVudHMuICh0cmFjayBhbmQgaGFuZGxlIGRyYWdnaW5nLCBjbGlja2luZywgc2Nyb2xsaW5nKVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGlzSG9yaXpvbnRhbCBUcnVlIGlmIHRoZSB0YXJnZXQgc2Nyb2xsYmFyIGlzIHRoZSBob3Jpem9udGFsIHNjcm9sbGJhciwgZmFsc2UgaWYgdGhlIHRhcmdldCBzY3JvbGxiYXIgaXMgdGhlIHZlcnRpY2FsIHNjcm9sbGJhci5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBTY3JvbGxiYXJFdmVudHMoaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhclZhcnMgPSBnZXRTY3JvbGxiYXJWYXJzKGlzSG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhclZhcnNJbmZvID0gc2Nyb2xsYmFyVmFycy5faW5mbztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaW5zaWRlSUZyYW1lID0gX3dpbmRvd0VsZW1lbnROYXRpdmUudG9wICE9PSBfd2luZG93RWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgeHkgPSBzY3JvbGxiYXJWYXJzLl94X3k7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIFhZID0gc2Nyb2xsYmFyVmFycy5fWF9ZO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGwgPSBfc3RyU2Nyb2xsICsgc2Nyb2xsYmFyVmFycy5fTGVmdF9Ub3A7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckFjdGl2ZSA9ICdhY3RpdmUnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJTbmFwSGFuZGxlID0gJ3NuYXBIYW5kbGUnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJDbGlja0V2ZW50ID0gJ2NsaWNrJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsRHVyYXRpb25GYWN0b3IgPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbmNyZWFzZURlY3JlYXNlU2Nyb2xsQW1vdW50S2V5Q29kZXMgPSBbMTYsIDE3XTsgLy9zaGlmdCwgY3RybFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFja1RpbWVvdXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1vdXNlRG93blNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbW91c2VEb3duT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtb3VzZURvd25JbnZlcnRlZFNjYWxlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRQb2ludGVyUG9zaXRpb24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9tc2llVmVyc2lvbiAmJiBpbnNpZGVJRnJhbWUgPyBldmVudFsnc2NyZWVuJyArIFhZXSA6IENPTVBBVElCSUxJVFkucGFnZShldmVudClbeHldOyAvL3VzZSBzY3JlZW4gY29vcmRpbmF0ZXMgaW4gRURHRSAmIElFIGJlY2F1c2UgdGhlIHBhZ2UgdmFsdWVzIGFyZSBpbmNvcnJlY3QgaW4gZnJhbWVzLlxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRQcmVwYXJlZFNjcm9sbGJhcnNPcHRpb24obmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMuc2Nyb2xsYmFyc1tuYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gaW5jcmVhc2VUcmFja1Njcm9sbEFtb3VudCgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsRHVyYXRpb25GYWN0b3IgPSAwLjU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRlY3JlYXNlVHJhY2tTY3JvbGxBbW91bnQoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbER1cmF0aW9uRmFjdG9yID0gMTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gc3RvcENsaWNrRXZlbnRQcm9wYWdhdGlvbihldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnN0cFAoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudEtleURvd24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkoZXZlbnQua2V5Q29kZSwgaW5jcmVhc2VEZWNyZWFzZVNjcm9sbEFtb3VudEtleUNvZGVzKSA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5jcmVhc2VUcmFja1Njcm9sbEFtb3VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudEtleVVwKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbkFycmF5KGV2ZW50LmtleUNvZGUsIGluY3JlYXNlRGVjcmVhc2VTY3JvbGxBbW91bnRLZXlDb2RlcykgPiAtMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY3JlYXNlVHJhY2tTY3JvbGxBbW91bnQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gb25Nb3VzZVRvdWNoRG93bkNvbnRpbnVlKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcmlnaW5hbEV2ZW50ID0gZXZlbnQub3JpZ2luYWxFdmVudCB8fCBldmVudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzVG91Y2hFdmVudCA9IG9yaWdpbmFsRXZlbnQudG91Y2hlcyAhPT0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3NsZWVwaW5nIHx8IF9kZXN0cm95ZWQgfHwgbmF0aXZlT3ZlcmxheVNjcm9sbGJhcnNBcmVBY3RpdmUoKSB8fCAhX3Njcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2FjaGUgfHwgKGlzVG91Y2hFdmVudCAmJiAhZ2V0UHJlcGFyZWRTY3JvbGxiYXJzT3B0aW9uKCd0b3VjaFN1cHBvcnQnKSkgPyBmYWxzZSA6IENPTVBBVElCSUxJVFkubUJ0bihldmVudCkgPT09IDEgfHwgaXNUb3VjaEV2ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudERyYWdNb3ZlKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhY2tMZW5ndGggPSBzY3JvbGxiYXJWYXJzSW5mby5fdHJhY2tMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGFuZGxlTGVuZ3RoID0gc2Nyb2xsYmFyVmFyc0luZm8uX2hhbmRsZUxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxSYW5nZSA9IHNjcm9sbGJhclZhcnNJbmZvLl9tYXhTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsUmF3ID0gKGdldFBvaW50ZXJQb3NpdGlvbihldmVudCkgLSBtb3VzZURvd25PZmZzZXQpICogbW91c2VEb3duSW52ZXJ0ZWRTY2FsZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxEZWx0YVBlcmNlbnQgPSBzY3JvbGxSYXcgLyAodHJhY2tMZW5ndGggLSBoYW5kbGVMZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbERlbHRhID0gKHNjcm9sbFJhbmdlICogc2Nyb2xsRGVsdGFQZXJjZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbERlbHRhID0gaXNGaW5pdGUoc2Nyb2xsRGVsdGEpID8gc2Nyb2xsRGVsdGEgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1JUTCAmJiBpc0hvcml6b250YWwgJiYgIV9ydGxTY3JvbGxCZWhhdmlvci5pKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbERlbHRhICo9IC0xO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbc2Nyb2xsXShNQVRILnJvdW5kKG1vdXNlRG93blNjcm9sbCArIHNjcm9sbERlbHRhKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJzSGFuZGxlc0RlZmluZVNjcm9sbFBvcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGlzSG9yaXpvbnRhbCwgbW91c2VEb3duU2Nyb2xsICsgc2Nyb2xsRGVsdGEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX3N1cHBvcnRQYXNzaXZlRXZlbnRzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnRNb3VzZVRvdWNoVXAoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudE1vdXNlVG91Y2hVcChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGV2ZW50IHx8IGV2ZW50Lm9yaWdpbmFsRXZlbnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF9kb2N1bWVudEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbX3N0ck1vdXNlVG91Y2hNb3ZlRXZlbnQsIF9zdHJNb3VzZVRvdWNoVXBFdmVudCwgX3N0cktleURvd25FdmVudCwgX3N0cktleVVwRXZlbnQsIF9zdHJTZWxlY3RTdGFydEV2ZW50XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkb2N1bWVudERyYWdNb3ZlLCBkb2N1bWVudE1vdXNlVG91Y2hVcCwgZG9jdW1lbnRLZXlEb3duLCBkb2N1bWVudEtleVVwLCBkb2N1bWVudE9uU2VsZWN0U3RhcnRdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuckFGKCkoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF9kb2N1bWVudEVsZW1lbnQsIHN0ckNsaWNrRXZlbnQsIHN0b3BDbGlja0V2ZW50UHJvcGFnYXRpb24sIHRydWUsIHsgX2NhcHR1cmU6IHRydWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldChpc0hvcml6b250YWwsIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ib2R5RWxlbWVudCwgX2NsYXNzTmFtZURyYWdnaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3Moc2Nyb2xsYmFyVmFycy5faGFuZGxlLCBzdHJBY3RpdmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhzY3JvbGxiYXJWYXJzLl90cmFjaywgc3RyQWN0aXZlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3Moc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyLCBzdHJBY3RpdmUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duU2Nyb2xsID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtb3VzZURvd25PZmZzZXQgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93bkludmVydGVkU2NhbGUgPSAxO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVjcmVhc2VUcmFja1Njcm9sbEFtb3VudCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRyYWNrVGltZW91dCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS5zY3JvbGxTdG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodHJhY2tUaW1lb3V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrVGltZW91dCA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVjdCA9IF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLmJDUl0oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtb3VzZUluc2lkZUhvc3QgPSBldmVudC5jbGllbnRYID49IHJlY3QubGVmdCAmJiBldmVudC5jbGllbnRYIDw9IHJlY3QucmlnaHQgJiYgZXZlbnQuY2xpZW50WSA+PSByZWN0LnRvcCAmJiBldmVudC5jbGllbnRZIDw9IHJlY3QuYm90dG9tO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgbW91c2UgaXMgb3V0c2lkZSBob3N0IGVsZW1lbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbW91c2VJbnNpZGVIb3N0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RPbk1vdXNlTGVhdmUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc0F1dG9IaWRlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBvbkhhbmRsZU1vdXNlVG91Y2hEb3duKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25IYW5kbGVNb3VzZVRvdWNoRG93bkFjdGlvbihldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uSGFuZGxlTW91c2VUb3VjaERvd25BY3Rpb24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duU2Nyb2xsID0gX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93blNjcm9sbCA9IGlzTmFOKG1vdXNlRG93blNjcm9sbCkgPyAwIDogbW91c2VEb3duU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzUlRMICYmIGlzSG9yaXpvbnRhbCAmJiAhX3J0bFNjcm9sbEJlaGF2aW9yLm4gfHwgIV9pc1JUTClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93blNjcm9sbCA9IG1vdXNlRG93blNjcm9sbCA8IDAgPyAwIDogbW91c2VEb3duU2Nyb2xsO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duSW52ZXJ0ZWRTY2FsZSA9IGdldEhvc3RFbGVtZW50SW52ZXJ0ZWRTY2FsZSgpW3h5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duT2Zmc2V0ID0gZ2V0UG9pbnRlclBvc2l0aW9uKGV2ZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzSGFuZGxlc0RlZmluZVNjcm9sbFBvcyA9ICFnZXRQcmVwYXJlZFNjcm9sbGJhcnNPcHRpb24oc3RyU25hcEhhbmRsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF9ib2R5RWxlbWVudCwgX2NsYXNzTmFtZURyYWdnaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3Moc2Nyb2xsYmFyVmFycy5faGFuZGxlLCBzdHJBY3RpdmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhzY3JvbGxiYXJWYXJzLl9zY3JvbGxiYXIsIHN0ckFjdGl2ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF9kb2N1bWVudEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbX3N0ck1vdXNlVG91Y2hNb3ZlRXZlbnQsIF9zdHJNb3VzZVRvdWNoVXBFdmVudCwgX3N0clNlbGVjdFN0YXJ0RXZlbnRdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RvY3VtZW50RHJhZ01vdmUsIGRvY3VtZW50TW91c2VUb3VjaFVwLCBkb2N1bWVudE9uU2VsZWN0U3RhcnRdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5yQUYoKShmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoX2RvY3VtZW50RWxlbWVudCwgc3RyQ2xpY2tFdmVudCwgc3RvcENsaWNrRXZlbnRQcm9wYWdhdGlvbiwgZmFsc2UsIHsgX2NhcHR1cmU6IHRydWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbXNpZVZlcnNpb24gfHwgIV9kb2N1bWVudE1peGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5wcnZEKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gb25UcmFja01vdXNlVG91Y2hEb3duKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGFuZGxlVG9WaWV3cG9ydFJhdGlvID0gc2Nyb2xsYmFyVmFycy5faW5mby5faGFuZGxlTGVuZ3RoIC8gTWF0aC5yb3VuZChNQVRILm1pbigxLCBfdmlld3BvcnRTaXplW3Njcm9sbGJhclZhcnMuX3dfaF0gLyBfY29udGVudFNjcm9sbFNpemVDYWNoZVtzY3JvbGxiYXJWYXJzLl93X2hdKSAqIHNjcm9sbGJhclZhcnMuX2luZm8uX3RyYWNrTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxEaXN0YW5jZSA9IE1BVEgucm91bmQoX3ZpZXdwb3J0U2l6ZVtzY3JvbGxiYXJWYXJzLl93X2hdICogaGFuZGxlVG9WaWV3cG9ydFJhdGlvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxCYXNlRHVyYXRpb24gPSAyNzAgKiBoYW5kbGVUb1ZpZXdwb3J0UmF0aW87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsRmlyc3RJdGVyYXRpb25EZWxheSA9IDQwMCAqIGhhbmRsZVRvVmlld3BvcnRSYXRpbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0cmFja09mZnNldCA9IHNjcm9sbGJhclZhcnMuX3RyYWNrLm9mZnNldCgpW3Njcm9sbGJhclZhcnMuX2xlZnRfdG9wXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdHJsS2V5ID0gZXZlbnQuY3RybEtleTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW50U2Nyb2xsID0gZXZlbnQuc2hpZnRLZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFudFNjcm9sbFRyYW5zaXRpb24gPSBpbnN0YW50U2Nyb2xsICYmIGN0cmxLZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNGaXJzdEl0ZXJhdGlvbiA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWFzaW5nID0gJ2xpbmVhcic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVjcmVhc2VTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmluaXNoZWRDb25kaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsQWN0aW9uRmluc2lzaGVkID0gZnVuY3Rpb24gKHRyYW5zaXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGlzSG9yaXpvbnRhbCwgdHJhbnNpdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbEFjdGlvbkluc3RhbnRGaW5pc2hlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxBY3Rpb25GaW5zaXNoZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkhhbmRsZU1vdXNlVG91Y2hEb3duQWN0aW9uKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsQWN0aW9uID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2Rlc3Ryb3llZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbW91c2VPZmZzZXQgPSAobW91c2VEb3duT2Zmc2V0IC0gdHJhY2tPZmZzZXQpICogbW91c2VEb3duSW52ZXJ0ZWRTY2FsZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZU9mZnNldCA9IHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0cmFja0xlbmd0aCA9IHNjcm9sbGJhclZhcnNJbmZvLl90cmFja0xlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZUxlbmd0aCA9IHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxSYW5nZSA9IHNjcm9sbGJhclZhcnNJbmZvLl9tYXhTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJyU2Nyb2xsID0gc2Nyb2xsYmFyVmFyc0luZm8uX2N1cnJlbnRTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxEdXJhdGlvbiA9IHNjcm9sbEJhc2VEdXJhdGlvbiAqIHNjcm9sbER1cmF0aW9uRmFjdG9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGltZW91dERlbGF5ID0gaXNGaXJzdEl0ZXJhdGlvbiA/IE1BVEgubWF4KHNjcm9sbEZpcnN0SXRlcmF0aW9uRGVsYXksIHNjcm9sbER1cmF0aW9uKSA6IHNjcm9sbER1cmF0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gc2Nyb2xsUmFuZ2UgKiAoKG1vdXNlT2Zmc2V0IC0gKGhhbmRsZUxlbmd0aCAvIDIpKSAvICh0cmFja0xlbmd0aCAtIGhhbmRsZUxlbmd0aCkpOyAvLyAxMDAlICogcG9zaXRpb25QZXJjZW50XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBydGxJc05vcm1hbCA9IF9pc1JUTCAmJiBpc0hvcml6b250YWwgJiYgKCghX3J0bFNjcm9sbEJlaGF2aW9yLmkgJiYgIV9ydGxTY3JvbGxCZWhhdmlvci5uKSB8fCBfbm9ybWFsaXplUlRMQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVjcmVhc2VTY3JvbGxDb25kaXRpb24gPSBydGxJc05vcm1hbCA/IGhhbmRsZU9mZnNldCA8IG1vdXNlT2Zmc2V0IDogaGFuZGxlT2Zmc2V0ID4gbW91c2VPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxPYmogPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFuaW1hdGlvbk9iaiA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhc2luZzogZWFzaW5nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcDogZnVuY3Rpb24gKG5vdykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0hhbmRsZXNEZWZpbmVTY3JvbGxQb3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKG5vdyk7IC8vaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9qcXVlcnkvaXNzdWVzLzQzNDBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldChpc0hvcml6b250YWwsIG5vdyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW50U2Nyb2xsUG9zaXRpb24gPSBpc0Zpbml0ZShpbnN0YW50U2Nyb2xsUG9zaXRpb24pID8gaW5zdGFudFNjcm9sbFBvc2l0aW9uIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gX2lzUlRMICYmIGlzSG9yaXpvbnRhbCAmJiAhX3J0bFNjcm9sbEJlaGF2aW9yLmkgPyAoc2Nyb2xsUmFuZ2UgLSBpbnN0YW50U2Nyb2xsUG9zaXRpb24pIDogaW5zdGFudFNjcm9sbFBvc2l0aW9uO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9fYmFzZS5zY3JvbGxTdG9wKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFudFNjcm9sbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKGluc3RhbnRTY3JvbGxQb3NpdGlvbik7IC8vc2Nyb2xsIGluc3RhbnRseSB0byBuZXcgcG9zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW50U2Nyb2xsVHJhbnNpdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZ2V0IHRoZSBzY3JvbGwgcG9zaXRpb24gYWZ0ZXIgaW5zdGFudCBzY3JvbGwgKGluIGNhc2UgQ1NTIFNuYXAgUG9pbnRzIGFyZSB1c2VkKSB0byBnZXQgdGhlIGNvcnJlY3Qgc25hcHBlZCBzY3JvbGwgcG9zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2FuZCB0aGUgYW5pbWF0aW9uIHN0b3BzIGF0IHRoZSBjb3JyZWN0IHBvaW50XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGwgYmFjayB0byB0aGUgcG9zaXRpb24gYmVmb3JlIGluc3RhbnQgc2Nyb2xsaW5nIHNvIGFuaW1hdGlvbiBjYW4gYmUgcGVyZm9ybWVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKGN1cnJTY3JvbGwpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW50U2Nyb2xsUG9zaXRpb24gPSBydGxJc05vcm1hbCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IuaSA/IChzY3JvbGxSYW5nZSAtIGluc3RhbnRTY3JvbGxQb3NpdGlvbikgOiBpbnN0YW50U2Nyb2xsUG9zaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gcnRsSXNOb3JtYWwgJiYgX3J0bFNjcm9sbEJlaGF2aW9yLm4gPyAtaW5zdGFudFNjcm9sbFBvc2l0aW9uIDogaW5zdGFudFNjcm9sbFBvc2l0aW9uO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxPYmpbeHldID0gaW5zdGFudFNjcm9sbFBvc2l0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9iYXNlLnNjcm9sbChzY3JvbGxPYmosIGV4dGVuZERlZXAoYW5pbWF0aW9uT2JqLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiAxMzAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOiBzY3JvbGxBY3Rpb25JbnN0YW50RmluaXNoZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsQWN0aW9uSW5zdGFudEZpbmlzaGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNyZWFzZVNjcm9sbCA9IGlzRmlyc3RJdGVyYXRpb24gPyBkZWNyZWFzZVNjcm9sbENvbmRpdGlvbiA6IGRlY3JlYXNlU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluaXNoZWRDb25kaXRpb24gPSBydGxJc05vcm1hbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gKGRlY3JlYXNlU2Nyb2xsID8gaGFuZGxlT2Zmc2V0ICsgaGFuZGxlTGVuZ3RoID49IG1vdXNlT2Zmc2V0IDogaGFuZGxlT2Zmc2V0IDw9IG1vdXNlT2Zmc2V0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKGRlY3JlYXNlU2Nyb2xsID8gaGFuZGxlT2Zmc2V0IDw9IG1vdXNlT2Zmc2V0IDogaGFuZGxlT2Zmc2V0ICsgaGFuZGxlTGVuZ3RoID49IG1vdXNlT2Zmc2V0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluaXNoZWRDb25kaXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodHJhY2tUaW1lb3V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS5zY3JvbGxTdG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2tUaW1lb3V0ID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbEFjdGlvbkZpbnNpc2hlZCh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrVGltZW91dCA9IHNldFRpbWVvdXQoc2Nyb2xsQWN0aW9uLCB0aW1lb3V0RGVsYXkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxPYmpbeHldID0gKGRlY3JlYXNlU2Nyb2xsID8gJy09JyA6ICcrPScpICsgc2Nyb2xsRGlzdGFuY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2Uuc2Nyb2xsKHNjcm9sbE9iaiwgZXh0ZW5kRGVlcChhbmltYXRpb25PYmosIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IHNjcm9sbER1cmF0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNGaXJzdEl0ZXJhdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdHJsS2V5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY3JlYXNlVHJhY2tTY3JvbGxBbW91bnQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3VzZURvd25JbnZlcnRlZFNjYWxlID0gZ2V0SG9zdEVsZW1lbnRJbnZlcnRlZFNjYWxlKClbeHldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duT2Zmc2V0ID0gQ09NUEFUSUJJTElUWS5wYWdlKGV2ZW50KVt4eV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zID0gIWdldFByZXBhcmVkU2Nyb2xsYmFyc09wdGlvbihzdHJTbmFwSGFuZGxlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF9ib2R5RWxlbWVudCwgX2NsYXNzTmFtZURyYWdnaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKHNjcm9sbGJhclZhcnMuX3RyYWNrLCBzdHJBY3RpdmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3Moc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyLCBzdHJBY3RpdmUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoX2RvY3VtZW50RWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbX3N0ck1vdXNlVG91Y2hVcEV2ZW50LCBfc3RyS2V5RG93bkV2ZW50LCBfc3RyS2V5VXBFdmVudCwgX3N0clNlbGVjdFN0YXJ0RXZlbnRdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkb2N1bWVudE1vdXNlVG91Y2hVcCwgZG9jdW1lbnRLZXlEb3duLCBkb2N1bWVudEtleVVwLCBkb2N1bWVudE9uU2VsZWN0U3RhcnRdKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxBY3Rpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnN0cFAoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uVHJhY2tNb3VzZVRvdWNoRW50ZXIoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYWtlIHN1cmUgYm90aCBzY3JvbGxiYXJzIHdpbGwgc3RheSB2aXNpYmxlIGlmIG9uZSBzY3JvbGxiYXIgaXMgaG92ZXJlZCBpZiBhdXRvSGlkZSBpcyBcInNjcm9sbFwiIG9yIFwibW92ZVwiLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0hhbmRsZUhvdmVyZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uVHJhY2tNb3VzZVRvdWNoTGVhdmUoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNIYW5kbGVIb3ZlcmVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlU2Nyb2xsIHx8IF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uU2Nyb2xsYmFyTW91c2VUb3VjaERvd24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKHNjcm9sbGJhclZhcnMuX2hhbmRsZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ck1vdXNlVG91Y2hEb3duRXZlbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uSGFuZGxlTW91c2VUb3VjaERvd24pO1xyXG4gICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKHNjcm9sbGJhclZhcnMuX3RyYWNrLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbX3N0ck1vdXNlVG91Y2hEb3duRXZlbnQsIF9zdHJNb3VzZUVudGVyLCBfc3RyTW91c2VMZWF2ZV0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtvblRyYWNrTW91c2VUb3VjaERvd24sIG9uVHJhY2tNb3VzZVRvdWNoRW50ZXIsIG9uVHJhY2tNb3VzZVRvdWNoTGVhdmVdKTtcclxuICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihzY3JvbGxiYXJWYXJzLl9zY3JvbGxiYXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJNb3VzZVRvdWNoRG93bkV2ZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbGJhck1vdXNlVG91Y2hEb3duKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9zdXBwb3J0VHJhbnNpdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihzY3JvbGxiYXJWYXJzLl9zY3JvbGxiYXIsIF9zdHJUcmFuc2l0aW9uRW5kRXZlbnQsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50LnRhcmdldCAhPT0gc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyWzBdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVMZW5ndGgoaXNIb3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVPZmZzZXQoaXNIb3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogU2hvd3Mgb3IgaGlkZXMgdGhlIGdpdmVuIHNjcm9sbGJhciBhbmQgYXBwbGllZCBhIGNsYXNzIG5hbWUgd2hpY2ggaW5kaWNhdGVzIGlmIHRoZSBzY3JvbGxiYXIgaXMgc2Nyb2xsYWJsZSBvciBub3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gaXNIb3Jpem9udGFsIFRydWUgaWYgdGhlIGhvcml6b250YWwgc2Nyb2xsYmFyIGlzIHRoZSB0YXJnZXQsIGZhbHNlIGlmIHRoZSB2ZXJ0aWNhbCBzY3JvbGxiYXIgaXMgdGhlIHRhcmdldC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBzaGFsbEJlVmlzaWJsZSBUcnVlIGlmIHRoZSBzY3JvbGxiYXIgc2hhbGwgYmUgc2hvd24sIGZhbHNlIGlmIGhpZGRlbi5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBjYW5TY3JvbGwgVHJ1ZSBpZiB0aGUgc2Nyb2xsYmFyIGlzIHNjcm9sbGFibGUsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVmcmVzaFNjcm9sbGJhckFwcGVhcmFuY2UoaXNIb3Jpem9udGFsLCBzaGFsbEJlVmlzaWJsZSwgY2FuU2Nyb2xsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhckhpZGRlbkNsYXNzTmFtZSA9IGlzSG9yaXpvbnRhbCA/IF9jbGFzc05hbWVIb3N0U2Nyb2xsYmFySG9yaXpvbnRhbEhpZGRlbiA6IF9jbGFzc05hbWVIb3N0U2Nyb2xsYmFyVmVydGljYWxIaWRkZW47XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhckVsZW1lbnQgPSBpc0hvcml6b250YWwgPyBfc2Nyb2xsYmFySG9yaXpvbnRhbEVsZW1lbnQgOiBfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIHNjcm9sbGJhckhpZGRlbkNsYXNzTmFtZSwgIXNoYWxsQmVWaXNpYmxlKTtcclxuICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhzY3JvbGxiYXJFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyVW51c2FibGUsICFjYW5TY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQXV0b3Nob3dzIC8gYXV0b2hpZGVzIGJvdGggc2Nyb2xsYmFycyB3aXRoLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHNoYWxsQmVWaXNpYmxlIFRydWUgaWYgdGhlIHNjcm9sbGJhcnMgc2hhbGwgYmUgYXV0b3Nob3duIChvbmx5IHRoZSBjYXNlIGlmIHRoZXkgYXJlIGhpZGRlbiBieSBhIGF1dG9oaWRlKSwgZmFsc2UgaWYgdGhlIHNoYWxsIGJlIGF1dG8gaGlkZGVuLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlbGF5ZnJlZSBUcnVlIGlmIHRoZSBzY3JvbGxiYXJzIHNoYWxsIGJlIGhpZGRlbiB3aXRob3V0IGEgZGVsYXksIGZhbHNlIG9yIHVuZGVmaW5lZCBvdGhlcndpc2UuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUoc2hhbGxCZVZpc2libGUsIGRlbGF5ZnJlZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChfc2Nyb2xsYmFyc0F1dG9IaWRlVGltZW91dElkKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2hhbGxCZVZpc2libGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9pZihfaGFzT3ZlcmZsb3dDYWNoZS54ICYmIF9oaWRlT3ZlcmZsb3dDYWNoZS54cylcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX3Njcm9sbGJhckhvcml6b250YWxFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQXV0b0hpZGRlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYoX2hhc092ZXJmbG93Q2FjaGUueSAmJiBfaGlkZU92ZXJmbG93Q2FjaGUueXMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9zY3JvbGxiYXJWZXJ0aWNhbEVsZW1lbnQsIF9jbGFzc05hbWVTY3JvbGxiYXJBdXRvSGlkZGVuKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhbnlBY3RpdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJBY3RpdmUgPSAnYWN0aXZlJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhpZGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9zY3JvbGxiYXJzSGFuZGxlSG92ZXJlZCAmJiAhX2Rlc3Ryb3llZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFueUFjdGl2ZSA9IF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudC5oYXNDbGFzcyhzdHJBY3RpdmUpIHx8IF9zY3JvbGxiYXJWZXJ0aWNhbEhhbmRsZUVsZW1lbnQuaGFzQ2xhc3Moc3RyQWN0aXZlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFueUFjdGl2ZSAmJiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTGVhdmUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfc2Nyb2xsYmFySG9yaXpvbnRhbEVsZW1lbnQsIF9jbGFzc05hbWVTY3JvbGxiYXJBdXRvSGlkZGVuKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFueUFjdGl2ZSAmJiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTGVhdmUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQXV0b0hpZGRlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlRGVsYXkgPiAwICYmIGRlbGF5ZnJlZSAhPT0gdHJ1ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGhpZGUsIF9zY3JvbGxiYXJzQXV0b0hpZGVEZWxheSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZGUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZWZyZXNoZXMgdGhlIGhhbmRsZSBsZW5ndGggb2YgdGhlIGdpdmVuIHNjcm9sbGJhci5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpc0hvcml6b250YWwgVHJ1ZSBpZiB0aGUgaG9yaXpvbnRhbCBzY3JvbGxiYXIgaGFuZGxlIHNoYWxsIGJlIHJlZnJlc2hlZCwgZmFsc2UgaWYgdGhlIHZlcnRpY2FsIG9uZSBzaGFsbCBiZSByZWZyZXNoZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVMZW5ndGgoaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZUNTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhpc0hvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzSW5mbyA9IHNjcm9sbGJhclZhcnMuX2luZm87XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRpZ2l0ID0gMTAwMDAwMDtcclxuICAgICAgICAgICAgICAgICAgICAvL2dldCBhbmQgYXBwbHkgaW50ZW5kZWQgaGFuZGxlIGxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVSYXRpbyA9IE1BVEgubWluKDEsIF92aWV3cG9ydFNpemVbc2Nyb2xsYmFyVmFycy5fd19oXSAvIF9jb250ZW50U2Nyb2xsU2l6ZUNhY2hlW3Njcm9sbGJhclZhcnMuX3dfaF0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZUNTU1tzY3JvbGxiYXJWYXJzLl93aWR0aF9oZWlnaHRdID0gKE1BVEguZmxvb3IoaGFuZGxlUmF0aW8gKiAxMDAgKiBkaWdpdCkgLyBkaWdpdCkgKyAnJSc7IC8vdGhlIGxhc3QgKiBkaWdpdCAvIGRpZ2l0IGlzIGZvciBmbG9vcmluZyB0byB0aGUgNHRoIGRpZ2l0XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbmF0aXZlT3ZlcmxheVNjcm9sbGJhcnNBcmVBY3RpdmUoKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFycy5faGFuZGxlLmNzcyhoYW5kbGVDU1MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL21lYXN1cmUgdGhlIGhhbmRsZSBsZW5ndGggdG8gcmVzcGVjdCBtaW4gJiBtYXggbGVuZ3RoXHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX2hhbmRsZUxlbmd0aCA9IHNjcm9sbGJhclZhcnMuX2hhbmRsZVswXVsnb2Zmc2V0JyArIHNjcm9sbGJhclZhcnMuX1dpZHRoX0hlaWdodF07XHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX2hhbmRsZUxlbmd0aFJhdGlvID0gaGFuZGxlUmF0aW87XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZWZyZXNoZXMgdGhlIGhhbmRsZSBvZmZzZXQgb2YgdGhlIGdpdmVuIHNjcm9sbGJhci5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpc0hvcml6b250YWwgVHJ1ZSBpZiB0aGUgaG9yaXpvbnRhbCBzY3JvbGxiYXIgaGFuZGxlIHNoYWxsIGJlIHJlZnJlc2hlZCwgZmFsc2UgaWYgdGhlIHZlcnRpY2FsIG9uZSBzaGFsbCBiZSByZWZyZXNoZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gc2Nyb2xsT3JUcmFuc2l0aW9uIFRoZSBzY3JvbGwgcG9zaXRpb24gb2YgdGhlIGdpdmVuIHNjcm9sbGJhciBheGlzIHRvIHdoaWNoIHRoZSBoYW5kbGUgc2hhbGwgYmUgbW92ZWQgb3IgYSBib29sZWFuIHdoaWNoIGluZGljYXRlcyB3aGV0aGVyIGEgdHJhbnNpdGlvbiBzaGFsbCBiZSBhcHBsaWVkLiBJZiB1bmRlZmluZWQgb3IgYm9vbGVhbiBpZiB0aGUgY3VycmVudCBzY3JvbGwtb2Zmc2V0IGlzIHRha2VuLiAoaWYgaXNIb3Jpem9udGFsID8gc2Nyb2xsTGVmdCA6IHNjcm9sbFRvcClcclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldChpc0hvcml6b250YWwsIHNjcm9sbE9yVHJhbnNpdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFuc2l0aW9uID0gdHlwZShzY3JvbGxPclRyYW5zaXRpb24pID09IFRZUEVTLmI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRyYW5zaXRpb25EdXJhdGlvbiA9IDI1MDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaXNSVExpc0hvcml6b250YWwgPSBfaXNSVEwgJiYgaXNIb3Jpem9udGFsO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhpc0hvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzSW5mbyA9IHNjcm9sbGJhclZhcnMuX2luZm87XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clRyYW5zbGF0ZUJyYWNlID0gJ3RyYW5zbGF0ZSgnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJUcmFuc2Zvcm0gPSBWRU5ET1JTLl9jc3NQcm9wZXJ0eSgndHJhbnNmb3JtJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clRyYW5zaXRpb24gPSBWRU5ET1JTLl9jc3NQcm9wZXJ0eSgndHJhbnNpdGlvbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBuYXRpdmVTY3JvbGwgPSBpc0hvcml6b250YWwgPyBfdmlld3BvcnRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XSgpIDogX3ZpZXdwb3J0RWxlbWVudFtfc3RyU2Nyb2xsVG9wXSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyZW50U2Nyb2xsID0gc2Nyb2xsT3JUcmFuc2l0aW9uID09PSB1bmRlZmluZWQgfHwgdHJhbnNpdGlvbiA/IG5hdGl2ZVNjcm9sbCA6IHNjcm9sbE9yVHJhbnNpdGlvbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9tZWFzdXJlIHRoZSBoYW5kbGUgbGVuZ3RoIHRvIHJlc3BlY3QgbWluICYgbWF4IGxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVMZW5ndGggPSBzY3JvbGxiYXJWYXJzSW5mby5faGFuZGxlTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFja0xlbmd0aCA9IHNjcm9sbGJhclZhcnMuX3RyYWNrWzBdWydvZmZzZXQnICsgc2Nyb2xsYmFyVmFycy5fV2lkdGhfSGVpZ2h0XTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaGFuZGxlVHJhY2tEaWZmID0gdHJhY2tMZW5ndGggLSBoYW5kbGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZUNTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFuc2Zvcm1PZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRyYW5zbGF0ZVZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL0RPTlQgdXNlIHRoZSB2YXJpYWJsZSAnX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGVbc2Nyb2xsYmFyVmFycy5fd19oXScgaW5zdGVhZCBvZiAnX3ZpZXdwb3J0RWxlbWVudFswXVsnc2Nyb2xsJyArIHNjcm9sbGJhclZhcnMuX1dpZHRoX0hlaWdodF0nXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBpdHMgYSBiaXQgYmVoaW5kIGR1cmluZyB0aGUgc21hbGwgZGVsYXkgd2hlbiBjb250ZW50IHNpemUgdXBkYXRlc1xyXG4gICAgICAgICAgICAgICAgICAgIC8vKGRlbGF5ID0gbXV0YXRpb25PYnNlcnZlckNvbnRlbnRMYWcsIGlmIGl0cyAwIHRoZW4gdGhpcyB2YXIgY291bGQgYmUgdXNlZClcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbWF4U2Nyb2xsID0gKF92aWV3cG9ydEVsZW1lbnROYXRpdmVbX3N0clNjcm9sbCArIHNjcm9sbGJhclZhcnMuX1dpZHRoX0hlaWdodF0gLSBfdmlld3BvcnRFbGVtZW50TmF0aXZlWydjbGllbnQnICsgc2Nyb2xsYmFyVmFycy5fV2lkdGhfSGVpZ2h0XSkgKiAoX3J0bFNjcm9sbEJlaGF2aW9yLm4gJiYgaXNSVExpc0hvcml6b250YWwgPyAtMSA6IDEpOyAvLyogLTEgaWYgcnRsIHNjcm9sbCBtYXggaXMgbmVnYXRpdmVcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZ2V0U2Nyb2xsUmF0aW8gPSBmdW5jdGlvbiAoYmFzZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNOYU4oYmFzZSAvIG1heFNjcm9sbCkgPyAwIDogTUFUSC5tYXgoMCwgTUFUSC5taW4oMSwgYmFzZSAvIG1heFNjcm9sbCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGdldEhhbmRsZU9mZnNldCA9IGZ1bmN0aW9uIChzY3JvbGxSYXRpbykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0ID0gaGFuZGxlVHJhY2tEaWZmICogc2Nyb2xsUmF0aW87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IGlzTmFOKG9mZnNldCkgPyAwIDogb2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAoaXNSVExpc0hvcml6b250YWwgJiYgIV9ydGxTY3JvbGxCZWhhdmlvci5pKSA/ICh0cmFja0xlbmd0aCAtIGhhbmRsZUxlbmd0aCAtIG9mZnNldCkgOiBvZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IE1BVEgubWF4KDAsIG9mZnNldCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsUmF0aW8gPSBnZXRTY3JvbGxSYXRpbyhuYXRpdmVTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1bnNuYXBwZWRTY3JvbGxSYXRpbyA9IGdldFNjcm9sbFJhdGlvKGN1cnJlbnRTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVPZmZzZXQgPSBnZXRIYW5kbGVPZmZzZXQodW5zbmFwcGVkU2Nyb2xsUmF0aW8pO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzbmFwcGVkSGFuZGxlT2Zmc2V0ID0gZ2V0SGFuZGxlT2Zmc2V0KHNjcm9sbFJhdGlvKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX21heFNjcm9sbCA9IG1heFNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJWYXJzSW5mby5fY3VycmVudFNjcm9sbCA9IG5hdGl2ZVNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJWYXJzSW5mby5fY3VycmVudFNjcm9sbFJhdGlvID0gc2Nyb2xsUmF0aW87XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydFRyYW5zZm9ybSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1PZmZzZXQgPSBpc1JUTGlzSG9yaXpvbnRhbCA/IC0odHJhY2tMZW5ndGggLSBoYW5kbGVMZW5ndGggLSBoYW5kbGVPZmZzZXQpIDogaGFuZGxlT2Zmc2V0OyAvL2luIHB4XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJhbnNmb3JtT2Zmc2V0ID0gKHRyYW5zZm9ybU9mZnNldCAvIHRyYWNrTGVuZ3RoICogMTAwKSAqICh0cmFja0xlbmd0aCAvIGhhbmRsZUxlbmd0aCk7IC8vaW4gJVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGVWYWx1ZSA9IGlzSG9yaXpvbnRhbCA/IHN0clRyYW5zbGF0ZUJyYWNlICsgdHJhbnNmb3JtT2Zmc2V0ICsgJ3B4LCAwKScgOiBzdHJUcmFuc2xhdGVCcmFjZSArICcwLCAnICsgdHJhbnNmb3JtT2Zmc2V0ICsgJ3B4KSc7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVDU1Nbc3RyVHJhbnNmb3JtXSA9IHRyYW5zbGF0ZVZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hcHBseSBvciBjbGVhciB1cCB0cmFuc2l0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydFRyYW5zaXRpb24pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVDU1Nbc3RyVHJhbnNpdGlvbl0gPSB0cmFuc2l0aW9uICYmIE1BVEguYWJzKGhhbmRsZU9mZnNldCAtIHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVPZmZzZXQpID4gMSA/IGdldENTU1RyYW5zaXRpb25TdHJpbmcoc2Nyb2xsYmFyVmFycy5faGFuZGxlKSArICcsICcgKyAoc3RyVHJhbnNmb3JtICsgX3N0clNwYWNlICsgdHJhbnNpdGlvbkR1cmF0aW9uICsgJ21zJykgOiBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlQ1NTW3Njcm9sbGJhclZhcnMuX2xlZnRfdG9wXSA9IGhhbmRsZU9mZnNldDtcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vb25seSBhcHBseSBjc3MgaWYgb2Zmc2V0IGhhcyBjaGFuZ2VkIGFuZCBvdmVyZmxvdyBleGlzdHMuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuYXRpdmVPdmVybGF5U2Nyb2xsYmFyc0FyZUFjdGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnMuX2hhbmRsZS5jc3MoaGFuZGxlQ1NTKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vY2xlYXIgdXAgdHJhbnNpdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRUcmFuc2Zvcm0gJiYgX3N1cHBvcnRUcmFuc2l0aW9uICYmIHRyYW5zaXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnMuX2hhbmRsZS5vbmUoX3N0clRyYW5zaXRpb25FbmRFdmVudCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2Rlc3Ryb3llZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFycy5faGFuZGxlLmNzcyhzdHJUcmFuc2l0aW9uLCBfc3RyRW1wdHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVPZmZzZXQgPSBoYW5kbGVPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX3NuYXBwZWRIYW5kbGVPZmZzZXQgPSBzbmFwcGVkSGFuZGxlT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnNJbmZvLl90cmFja0xlbmd0aCA9IHRyYWNrTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmVmcmVzaGVzIHRoZSBpbnRlcmFjdGl2aXR5IG9mIHRoZSBnaXZlbiBzY3JvbGxiYXIgZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpc1RyYWNrIFRydWUgaWYgdGhlIHRyYWNrIGVsZW1lbnQgaXMgdGhlIHRhcmdldCwgZmFsc2UgaWYgdGhlIGhhbmRsZSBlbGVtZW50IGlzIHRoZSB0YXJnZXQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVHJ1ZSBmb3IgaW50ZXJhY3Rpdml0eSBmYWxzZSBmb3Igbm8gaW50ZXJhY3Rpdml0eS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVmcmVzaFNjcm9sbGJhcnNJbnRlcmFjdGl2ZShpc1RyYWNrLCB2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhY3Rpb24gPSB2YWx1ZSA/ICdyZW1vdmVDbGFzcycgOiAnYWRkQ2xhc3MnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50MSA9IGlzVHJhY2sgPyBfc2Nyb2xsYmFySG9yaXpvbnRhbFRyYWNrRWxlbWVudCA6IF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudDIgPSBpc1RyYWNrID8gX3Njcm9sbGJhclZlcnRpY2FsVHJhY2tFbGVtZW50IDogX3Njcm9sbGJhclZlcnRpY2FsSGFuZGxlRWxlbWVudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lID0gaXNUcmFjayA/IF9jbGFzc05hbWVTY3JvbGxiYXJUcmFja09mZiA6IF9jbGFzc05hbWVTY3JvbGxiYXJIYW5kbGVPZmY7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQxW2FjdGlvbl0oY2xhc3NOYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50MlthY3Rpb25dKGNsYXNzTmFtZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZXR1cm5zIGEgb2JqZWN0IHdoaWNoIGlzIHVzZWQgZm9yIGZhc3QgYWNjZXNzIGZvciBzcGVjaWZpYyB2YXJpYWJsZXMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gaXNIb3Jpem9udGFsIFRydWUgaWYgdGhlIGhvcml6b250YWwgc2Nyb2xsYmFyIHZhcnMgc2hhbGwgYmUgYWNjZXNzZWQsIGZhbHNlIGlmIHRoZSB2ZXJ0aWNhbCBzY3JvbGxiYXIgdmFycyBzaGFsbCBiZSBhY2Nlc3NlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7d2g6IHN0cmluZywgV0g6IHN0cmluZywgbHQ6IHN0cmluZywgX3doOiBzdHJpbmcsIF9sdDogc3RyaW5nLCB0OiAqLCBoOiAqLCBjOiB7fSwgczogKn19XHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldFNjcm9sbGJhclZhcnMoaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3dpZHRoX2hlaWdodDogaXNIb3Jpem9udGFsID8gX3N0cldpZHRoIDogX3N0ckhlaWdodCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX1dpZHRoX0hlaWdodDogaXNIb3Jpem9udGFsID8gJ1dpZHRoJyA6ICdIZWlnaHQnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbGVmdF90b3A6IGlzSG9yaXpvbnRhbCA/IF9zdHJMZWZ0IDogX3N0clRvcCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX0xlZnRfVG9wOiBpc0hvcml6b250YWwgPyAnTGVmdCcgOiAnVG9wJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3hfeTogaXNIb3Jpem9udGFsID8gX3N0clggOiBfc3RyWSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX1hfWTogaXNIb3Jpem9udGFsID8gJ1gnIDogJ1knLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfd19oOiBpc0hvcml6b250YWwgPyAndycgOiAnaCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9sX3Q6IGlzSG9yaXpvbnRhbCA/ICdsJyA6ICd0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RyYWNrOiBpc0hvcml6b250YWwgPyBfc2Nyb2xsYmFySG9yaXpvbnRhbFRyYWNrRWxlbWVudCA6IF9zY3JvbGxiYXJWZXJ0aWNhbFRyYWNrRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hhbmRsZTogaXNIb3Jpem9udGFsID8gX3Njcm9sbGJhckhvcml6b250YWxIYW5kbGVFbGVtZW50IDogX3Njcm9sbGJhclZlcnRpY2FsSGFuZGxlRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcjogaXNIb3Jpem9udGFsID8gX3Njcm9sbGJhckhvcml6b250YWxFbGVtZW50IDogX3Njcm9sbGJhclZlcnRpY2FsRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2luZm86IGlzSG9yaXpvbnRhbCA/IF9zY3JvbGxIb3Jpem9udGFsSW5mbyA6IF9zY3JvbGxWZXJ0aWNhbEluZm9cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gU2Nyb2xsYmFyIENvcm5lciA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEJ1aWxkcyBvciBkZXN0cm95cyB0aGUgc2Nyb2xsYmFyIGNvcm5lciBET00gZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBkZXN0cm95IEluZGljYXRlcyB3aGV0aGVyIHRoZSBET00gc2hhbGwgYmUgYnVpbGQgb3IgZGVzdHJveWVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXR1cFNjcm9sbGJhckNvcm5lckRPTShkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhckNvcm5lckVsZW1lbnQgPSBfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCB8fCBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2RvbUV4aXN0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50LmFwcGVuZChfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZG9tRXhpc3RzICYmIF9pbml0aWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQucmVtb3ZlQXR0cihMRVhJQ09OLnMpLCBfY2xhc3NOYW1lc0R5bmFtaWNEZXN0cm95KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZShfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBJbml0aWFsaXplcyBhbGwgc2Nyb2xsYmFyIGNvcm5lciBpbnRlcmFjdGl2aXR5IGV2ZW50cy5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBTY3JvbGxiYXJDb3JuZXJFdmVudHMoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc2lkZUlGcmFtZSA9IF93aW5kb3dFbGVtZW50TmF0aXZlLnRvcCAhPT0gX3dpbmRvd0VsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1vdXNlRG93blBvc2l0aW9uID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1vdXNlRG93blNpemUgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbW91c2VEb3duSW52ZXJ0ZWRTY2FsZSA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWNvbm5lY3RNdXRhdGlvbk9ic2VydmVyO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudERyYWdNb3ZlKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFnZU9mZnNldCA9IGdldENvb3JkaW5hdGVzKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBob3N0RWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9yZXNpemVIb3Jpem9udGFsIHx8IF9yZXNpemVCb3RoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSAobW91c2VEb3duU2l6ZS53ICsgKHBhZ2VPZmZzZXQueCAtIG1vdXNlRG93blBvc2l0aW9uLngpICogbW91c2VEb3duSW52ZXJ0ZWRTY2FsZS54KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfcmVzaXplVmVydGljYWwgfHwgX3Jlc2l6ZUJvdGgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zdEVsZW1lbnRDU1NbX3N0ckhlaWdodF0gPSAobW91c2VEb3duU2l6ZS5oICsgKHBhZ2VPZmZzZXQueSAtIG1vdXNlRG93blBvc2l0aW9uLnkpICogbW91c2VEb3duSW52ZXJ0ZWRTY2FsZS55KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudC5jc3MoaG9zdEVsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50TW91c2VUb3VjaFVwKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudE1vdXNlVG91Y2hVcChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnRJc1RydXN0ZWQgPSBldmVudCAhPT0gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfZG9jdW1lbnRFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW19zdHJTZWxlY3RTdGFydEV2ZW50LCBfc3RyTW91c2VUb3VjaE1vdmVFdmVudCwgX3N0ck1vdXNlVG91Y2hVcEV2ZW50XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkb2N1bWVudE9uU2VsZWN0U3RhcnQsIGRvY3VtZW50RHJhZ01vdmUsIGRvY3VtZW50TW91c2VUb3VjaFVwXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX2JvZHlFbGVtZW50LCBfY2xhc3NOYW1lRHJhZ2dpbmcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQucmVsZWFzZUNhcHR1cmUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudC5yZWxlYXNlQ2FwdHVyZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50SXNUcnVzdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVjb25uZWN0TXV0YXRpb25PYnNlcnZlcilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0TXV0YXRpb25PYnNlcnZlcnMoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9iYXNlLnVwZGF0ZShfc3RyQXV0byk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0TXV0YXRpb25PYnNlcnZlciA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9yaWdpbmFsRXZlbnQgPSBldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNUb3VjaEV2ZW50ID0gb3JpZ2luYWxFdmVudC50b3VjaGVzICE9PSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfc2xlZXBpbmcgfHwgX2Rlc3Ryb3llZCA/IGZhbHNlIDogQ09NUEFUSUJJTElUWS5tQnRuKGV2ZW50KSA9PT0gMSB8fCBpc1RvdWNoRXZlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldENvb3JkaW5hdGVzKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfbXNpZVZlcnNpb24gJiYgaW5zaWRlSUZyYW1lID8geyB4OiBldmVudC5zY3JlZW5YLCB5OiBldmVudC5zY3JlZW5ZIH0gOiBDT01QQVRJQklMSVRZLnBhZ2UoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQsIF9zdHJNb3VzZVRvdWNoRG93bkV2ZW50LCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9uTW91c2VUb3VjaERvd25Db250aW51ZShldmVudCkgJiYgIV9yZXNpemVOb25lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0TXV0YXRpb25PYnNlcnZlciA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXJzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duUG9zaXRpb24gPSBnZXRDb29yZGluYXRlcyhldmVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duU2l6ZS53ID0gX2hvc3RFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddIC0gKCFfaXNCb3JkZXJCb3ggPyBfcGFkZGluZ1ggOiAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93blNpemUuaCA9IF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9IXSAtICghX2lzQm9yZGVyQm94ID8gX3BhZGRpbmdZIDogMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3VzZURvd25JbnZlcnRlZFNjYWxlID0gZ2V0SG9zdEVsZW1lbnRJbnZlcnRlZFNjYWxlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfZG9jdW1lbnRFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtfc3RyU2VsZWN0U3RhcnRFdmVudCwgX3N0ck1vdXNlVG91Y2hNb3ZlRXZlbnQsIF9zdHJNb3VzZVRvdWNoVXBFdmVudF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RvY3VtZW50T25TZWxlY3RTdGFydCwgZG9jdW1lbnREcmFnTW92ZSwgZG9jdW1lbnRNb3VzZVRvdWNoVXBdKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfYm9keUVsZW1lbnQsIF9jbGFzc05hbWVEcmFnZ2luZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQuc2V0Q2FwdHVyZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudC5zZXRDYXB0dXJlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5wcnZEKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuc3RwUChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IFV0aWxzID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQ2FsbHMgdGhlIGNhbGxiYWNrIHdpdGggdGhlIGdpdmVuIG5hbWUuIFRoZSBDb250ZXh0IG9mIHRoaXMgY2FsbGJhY2sgaXMgYWx3YXlzIF9iYXNlICh0aGlzKS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgd2hpY2ggc2hhbGwgYmUgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGFyZ3MgVGhlIGFyZ3Mgd2l0aCB3aGljaCB0aGUgY2FsbGJhY2sgc2hhbGwgYmUgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlcGVuZGVudCBCb29sZWFuIHdoaWNoIGRlY2lkZXMgd2hldGhlciB0aGUgY2FsbGJhY2sgc2hhbGwgYmUgZmlyZWQsIHVuZGVmaW5lZCBpcyBsaWtlIGEgXCJ0cnVlXCIgdmFsdWUuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRpc3BhdGNoQ2FsbGJhY2sobmFtZSwgYXJncywgZGVwZW5kZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlcGVuZGVudCA9PT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2luaXRpYWxpemVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLmNhbGxiYWNrc1tuYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGV4dGVuc2lvbk9uTmFtZSA9IG5hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleHQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uT25OYW1lLnN1YnN0cigwLCAyKSA9PT0gJ29uJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbk9uTmFtZSA9IGV4dGVuc2lvbk9uTmFtZS5zdWJzdHIoMiwgMSkudG9Mb3dlckNhc2UoKSArIGV4dGVuc2lvbk9uTmFtZS5zdWJzdHIoMyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShjYWxsYmFjaykgPT0gVFlQRVMuZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwoX2Jhc2UsIGFyZ3MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaChfZXh0ZW5zaW9ucywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKGV4dC5vbikgPT0gVFlQRVMuZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHQub24oZXh0ZW5zaW9uT25OYW1lLCBhcmdzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFfZGVzdHJveWVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2FsbGJhY2tzSW5pdFFldWV1ZS5wdXNoKHsgbjogbmFtZSwgYTogYXJncyB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNldHMgdGhlIFwidG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XCIgcHJvcGVydGllcywgd2l0aCBhIGdpdmVuIHByZWZpeCwgb2YgdGhlIGdpdmVuIGNzcyBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0Q1NTT2JqZWN0IFRoZSBjc3Mgb2JqZWN0IHRvIHdoaWNoIHRoZSB2YWx1ZXMgc2hhbGwgYmUgYXBwbGllZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCBvZiB0aGUgXCJ0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRcIiBjc3MgcHJvcGVydGllcy4gKGV4YW1wbGU6ICdwYWRkaW5nLScgaXMgYSB2YWxpZCBwcmVmaXgpXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdmFsdWVzIEEgYXJyYXkgb2YgdmFsdWVzIHdoaWNoIHNoYWxsIGJlIGFwcGxpZWQgdG8gdGhlIFwidG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XCIgLXByb3BlcnRpZXMuIFRoZSBhcnJheSBvcmRlciBpcyBbdG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XS5cclxuICAgICAgICAgICAgICAgICAqIElmIHRoaXMgYXJndW1lbnQgaXMgdW5kZWZpbmVkIHRoZSB2YWx1ZSAnJyAoZW1wdHkgc3RyaW5nKSB3aWxsIGJlIGFwcGxpZWQgdG8gYWxsIHByb3BlcnRpZXMuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldFRvcFJpZ2h0Qm90dG9tTGVmdCh0YXJnZXRDU1NPYmplY3QsIHByZWZpeCwgdmFsdWVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4IHx8IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMgfHwgW19zdHJFbXB0eSwgX3N0ckVtcHR5LCBfc3RyRW1wdHksIF9zdHJFbXB0eV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldENTU09iamVjdFtwcmVmaXggKyBfc3RyVG9wXSA9IHZhbHVlc1swXTtcclxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRDU1NPYmplY3RbcHJlZml4ICsgX3N0clJpZ2h0XSA9IHZhbHVlc1sxXTtcclxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRDU1NPYmplY3RbcHJlZml4ICsgX3N0ckJvdHRvbV0gPSB2YWx1ZXNbMl07XHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Q1NTT2JqZWN0W3ByZWZpeCArIF9zdHJMZWZ0XSA9IHZhbHVlc1szXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIFwidG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XCIgQ1NTIHByb3BlcnRpZXMgb2YgdGhlIENTUyBwcm9wZXJ0eSB3aXRoIHRoZSBnaXZlbiBwcmVmaXggZnJvbSB0aGUgaG9zdCBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IG9mIHRoZSBcInRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdFwiIGNzcyBwcm9wZXJ0aWVzLiAoZXhhbXBsZTogJ3BhZGRpbmctJyBpcyBhIHZhbGlkIHByZWZpeClcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBzdWZmaXggVGhlIHN1ZmZpeCBvZiB0aGUgXCJ0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRcIiBjc3MgcHJvcGVydGllcy4gKGV4YW1wbGU6ICdib3JkZXItJyBpcyBhIHZhbGlkIHByZWZpeCB3aXRoICctd2lkdGgnIGlzIGEgdmFsaWQgc3VmZml4KVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHplcm9YIFRydWUgaWYgdGhlIHggYXhpcyBzaGFsbCBiZSAwLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHplcm9ZIFRydWUgaWYgdGhlIHkgYXhpcyBzaGFsbCBiZSAwLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3t9fSBUaGUgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBudW1iZXJzIG9mIHRoZSByZWFkIENTUyBwcm9wZXJ0aWVzLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRUb3BSaWdodEJvdHRvbUxlZnRIb3N0KHByZWZpeCwgc3VmZml4LCB6ZXJvWCwgemVyb1kpIHtcclxuICAgICAgICAgICAgICAgICAgICBzdWZmaXggPSBzdWZmaXggfHwgX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IHByZWZpeCB8fCBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdDogemVyb1kgPyAwIDogcGFyc2VUb1plcm9Pck51bWJlcihfaG9zdEVsZW1lbnQuY3NzKHByZWZpeCArIF9zdHJUb3AgKyBzdWZmaXgpKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcjogemVyb1ggPyAwIDogcGFyc2VUb1plcm9Pck51bWJlcihfaG9zdEVsZW1lbnQuY3NzKHByZWZpeCArIF9zdHJSaWdodCArIHN1ZmZpeCkpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBiOiB6ZXJvWSA/IDAgOiBwYXJzZVRvWmVyb09yTnVtYmVyKF9ob3N0RWxlbWVudC5jc3MocHJlZml4ICsgX3N0ckJvdHRvbSArIHN1ZmZpeCkpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsOiB6ZXJvWCA/IDAgOiBwYXJzZVRvWmVyb09yTnVtYmVyKF9ob3N0RWxlbWVudC5jc3MocHJlZml4ICsgX3N0ckxlZnQgKyBzdWZmaXgpKVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZXR1cm5zIHRoZSBjb21wdXRlZCBDU1MgdHJhbnNpdGlvbiBzdHJpbmcgZnJvbSB0aGUgZ2l2ZW4gZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBlbGVtZW50IFRoZSBlbGVtZW50IGZyb20gd2hpY2ggdGhlIHRyYW5zaXRpb24gc3RyaW5nIHNoYWxsIGJlIHJldHVybmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIENTUyB0cmFuc2l0aW9uIHN0cmluZyBmcm9tIHRoZSBnaXZlbiBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRDU1NUcmFuc2l0aW9uU3RyaW5nKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdHJhbnNpdGlvblN0ciA9IFZFTkRPUlMuX2Nzc1Byb3BlcnR5KCd0cmFuc2l0aW9uJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFzc2VtYmxlZFZhbHVlID0gZWxlbWVudC5jc3ModHJhbnNpdGlvblN0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFzc2VtYmxlZFZhbHVlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXNzZW1ibGVkVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlZ0V4cFN0cmluZyA9ICdcXFxccyooJyArICcoW14sKF0rKFxcXFwoLis/XFxcXCkpPykrJyArICcpW1xcXFxzLF0qJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVnRXhwTWFpbiA9IG5ldyBSZWdFeHAocmVnRXhwU3RyaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVnRXhwVmFsaWRhdGUgPSBuZXcgUmVnRXhwKCdeKCcgKyByZWdFeHBTdHJpbmcgKyAnKSskJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByb3BlcnRpZXMgPSAncHJvcGVydHkgZHVyYXRpb24gdGltaW5nLWZ1bmN0aW9uIGRlbGF5Jy5zcGxpdCgnICcpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyUmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZUFycmF5O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgajtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3BsaXRDc3NTdHlsZUJ5Q29tbWEgPSBmdW5jdGlvbiAoc3RyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0clJlc3VsdCA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXN0ci5tYXRjaChyZWdFeHBWYWxpZGF0ZSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3RyLm1hdGNoKHJlZ0V4cE1haW4pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJSZXN1bHQucHVzaChSZWdFeHAuJDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocmVnRXhwTWFpbiwgX3N0ckVtcHR5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0clJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgcHJvcGVydGllc1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVBcnJheSA9IHNwbGl0Q3NzU3R5bGVCeUNvbW1hKGVsZW1lbnQuY3NzKHRyYW5zaXRpb25TdHIgKyAnLScgKyBwcm9wZXJ0aWVzW2ldKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCB2YWx1ZUFycmF5W0xFWElDT04ubF07IGorKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFtqXSA9IChyZXN1bHRbal0gPyByZXN1bHRbal0gKyBfc3RyU3BhY2UgOiBfc3RyRW1wdHkpICsgdmFsdWVBcnJheVtqXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5qb2luKCcsICcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2VuZXJhdGVzIGEgUmVndWxhciBFeHByZXNzaW9uIHdoaWNoIG1hdGNoZXMgd2l0aCBhIHN0cmluZyB3aGljaCBzdGFydHMgd2l0aCAnb3MtaG9zdCcuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHdpdGhDdXJyQ2xhc3NOYW1lT3B0aW9uIFRoZSBSZWd1bGFyIEV4cHJlc3Npb24gYWxzbyBtYXRjaGVzIGlmIHRoZSBzdHJpbmcgaXMgdGhlIGN1cnJlbnQgQ2xhc3NOYW1lIG9wdGlvbiAobXVsdGlwbGUgdmFsdWVzIHNwbGl0dGVkIGJ5IHNwYWNlIHBvc3NpYmxlKS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gd2l0aE9sZENsYXNzTmFtZU9wdGlvbiBUaGUgUmVndWxhciBFeHByZXNzaW9uIGFsc28gbWF0Y2hlcyBpZiB0aGUgc3RyaW5nIGlzIHRoZSBvbGQgQ2xhc3NOYW1lIG9wdGlvbiAobXVsdGlwbGUgdmFsdWVzIHNwbGl0dGVkIGJ5IHNwYWNlIHBvc3NpYmxlKS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gY3JlYXRlSG9zdENsYXNzTmFtZVJlZ0V4cCh3aXRoQ3VyckNsYXNzTmFtZU9wdGlvbiwgd2l0aE9sZENsYXNzTmFtZU9wdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzcGxpdDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXBwZW5kaXg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFwcGVuZENsYXNzZXMgPSBmdW5jdGlvbiAoY2xhc3NlcywgY29uZGl0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZGl4ID0gJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb25kaXRpb24gJiYgdHlwZW9mIGNsYXNzZXMgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BsaXQgPSBjbGFzc2VzLnNwbGl0KF9zdHJTcGFjZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc3BsaXRbTEVYSUNPTi5sXTsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZGl4ICs9ICd8JyArIHNwbGl0W2ldICsgJyQnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3BsaXRbaV0ucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csICdcXFxcJCYnKSBmb3IgZXNjYXBpbmcgcmVnZXggY2hhcmFjdGVyc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhcHBlbmRpeDtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJlZ0V4cChcclxuICAgICAgICAgICAgICAgICAgICAgICAgJyheJyArIF9jbGFzc05hbWVIb3N0RWxlbWVudCArICcoWy1fXS4rfCkkKScgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRDbGFzc2VzKF9jbGFzc05hbWVDYWNoZSwgd2l0aEN1cnJDbGFzc05hbWVPcHRpb24pICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kQ2xhc3Nlcyhfb2xkQ2xhc3NOYW1lLCB3aXRoT2xkQ2xhc3NOYW1lT3B0aW9uKSwgJ2cnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENhbGN1bGF0ZXMgdGhlIGhvc3QtZWxlbWVudHMgaW52ZXJ0ZWQgc2NhbGUuIChpbnZlcnRlZFNjYWxlID0gMSAvIHNjYWxlKVxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3t4OiBudW1iZXIsIHk6IG51bWJlcn19IFRoZSBzY2FsZSBvZiB0aGUgaG9zdC1lbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRIb3N0RWxlbWVudEludmVydGVkU2NhbGUoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlY3QgPSBfcGFkZGluZ0VsZW1lbnROYXRpdmVbTEVYSUNPTi5iQ1JdKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgeDogX3N1cHBvcnRUcmFuc2Zvcm0gPyAxIC8gKE1BVEgucm91bmQocmVjdC53aWR0aCkgLyBfcGFkZGluZ0VsZW1lbnROYXRpdmVbTEVYSUNPTi5vV10pIHx8IDEgOiAxLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBfc3VwcG9ydFRyYW5zZm9ybSA/IDEgLyAoTUFUSC5yb3VuZChyZWN0LmhlaWdodCkgLyBfcGFkZGluZ0VsZW1lbnROYXRpdmVbTEVYSUNPTi5vSF0pIHx8IDEgOiAxXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBIVE1MRWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBvIFRoZSBvYmplY3Qgd2hpY2ggc2hhbGwgYmUgY2hlY2tlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBIVE1MRWxlbWVudCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBpc0hUTUxFbGVtZW50KG8pIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyT3duZXJEb2N1bWVudCA9ICdvd25lckRvY3VtZW50JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RySFRNTEVsZW1lbnQgPSAnSFRNTEVsZW1lbnQnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB3bmQgPSBvICYmIG9bc3RyT3duZXJEb2N1bWVudF0gPyAob1tzdHJPd25lckRvY3VtZW50XS5wYXJlbnRXaW5kb3cgfHwgd2luZG93KSA6IHdpbmRvdztcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2Ygd25kW3N0ckhUTUxFbGVtZW50XSA9PSBUWVBFUy5vID8gbyBpbnN0YW5jZW9mIHduZFtzdHJIVE1MRWxlbWVudF0gOiAvL0RPTTJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG8gJiYgdHlwZW9mIG8gPT0gVFlQRVMubyAmJiBvICE9PSBudWxsICYmIG8ubm9kZVR5cGUgPT09IDEgJiYgdHlwZW9mIG8ubm9kZU5hbWUgPT0gVFlQRVMuc1xyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDb21wYXJlcyAyIGFycmF5cyBhbmQgcmV0dXJucyB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGVtIGFzIGEgYXJyYXkuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gYTEgVGhlIGZpcnN0IGFycmF5IHdoaWNoIHNoYWxsIGJlIGNvbXBhcmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGEyIFRoZSBzZWNvbmQgYXJyYXkgd2hpY2ggc2hhbGwgYmUgY29tcGFyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSB0d28gYXJyYXlzLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRBcnJheURpZmZlcmVuY2VzKGExLCBhMikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRpZmYgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaztcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYTEubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFbYTFbaV1dID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYTIubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFbYTJbaV1dKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGFbYTJbaV1dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhW2EyW2ldXSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoayBpbiBhKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaWZmLnB1c2goayk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRpZmY7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZXR1cm5zIFplcm8gb3IgdGhlIG51bWJlciB0byB3aGljaCB0aGUgdmFsdWUgY2FuIGJlIHBhcnNlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgd2hpY2ggc2hhbGwgYmUgcGFyc2VkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHRvRmxvYXQgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIG51bWJlciBzaGFsbCBiZSBwYXJzZWQgdG8gYSBmbG9hdC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcGFyc2VUb1plcm9Pck51bWJlcih2YWx1ZSwgdG9GbG9hdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBudW0gPSB0b0Zsb2F0ID8gcGFyc2VGbG9hdCh2YWx1ZSkgOiBwYXJzZUludCh2YWx1ZSwgMTApO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpc05hTihudW0pID8gMCA6IG51bTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgc2V2ZXJhbCBpbmZvcm1hdGlvbiBvZiB0aGUgdGV4dGFyZWEgYW5kIHJldHVybnMgdGhlbSBhcyBhIG9iamVjdCBvciB1bmRlZmluZWQgaWYgdGhlIGJyb3dzZXIgZG9lc24ndCBzdXBwb3J0IGl0LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3tjdXJzb3JSb3c6IE51bWJlciwgY3Vyc29yQ29sLCByb3dzOiBOdW1iZXIsIGNvbHM6IG51bWJlciwgd1JvdzogbnVtYmVyLCBwb3M6IG51bWJlciwgbWF4IDogbnVtYmVyfX0gb3IgdW5kZWZpbmVkIGlmIG5vdCBzdXBwb3J0ZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldFRleHRhcmVhSW5mbygpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL3JlYWQgbmVlZGVkIHZhbHVlc1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUN1cnNvclBvc2l0aW9uID0gX3RhcmdldEVsZW1lbnROYXRpdmUuc2VsZWN0aW9uU3RhcnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRleHRhcmVhQ3Vyc29yUG9zaXRpb24gPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFWYWx1ZSA9IF90YXJnZXRFbGVtZW50LnZhbCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUxlbmd0aCA9IHRleHRhcmVhVmFsdWVbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFSb3dTcGxpdCA9IHRleHRhcmVhVmFsdWUuc3BsaXQoJ1xcbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUxhc3RSb3cgPSB0ZXh0YXJlYVJvd1NwbGl0W0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhQ3VycmVudEN1cnNvclJvd1NwbGl0ID0gdGV4dGFyZWFWYWx1ZS5zdWJzdHIoMCwgdGV4dGFyZWFDdXJzb3JQb3NpdGlvbikuc3BsaXQoJ1xcbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB3aWRlc3RSb3cgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUxhc3RDb2wgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JSb3cgPSB0ZXh0YXJlYUN1cnJlbnRDdXJzb3JSb3dTcGxpdFtMRVhJQ09OLmxdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JDb2wgPSB0ZXh0YXJlYUN1cnJlbnRDdXJzb3JSb3dTcGxpdFt0ZXh0YXJlYUN1cnJlbnRDdXJzb3JSb3dTcGxpdFtMRVhJQ09OLmxdIC0gMV1bTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcm93Q29scztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9nZXQgd2lkZXN0IFJvdyBhbmQgdGhlIGxhc3QgY29sdW1uIG9mIHRoZSB0ZXh0YXJlYVxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0ZXh0YXJlYVJvd1NwbGl0W0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByb3dDb2xzID0gdGV4dGFyZWFSb3dTcGxpdFtpXVtMRVhJQ09OLmxdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocm93Q29scyA+IHRleHRhcmVhTGFzdENvbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkZXN0Um93ID0gaSArIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYUxhc3RDb2wgPSByb3dDb2xzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY3Vyc29yUm93OiBjdXJzb3JSb3csIC8vY3Vyc29yUm93XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jdXJzb3JDb2x1bW46IGN1cnNvckNvbCwgLy9jdXJzb3JDb2xcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Jvd3M6IHRleHRhcmVhTGFzdFJvdywgLy9yb3dzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb2x1bW5zOiB0ZXh0YXJlYUxhc3RDb2wsIC8vY29sc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfd2lkZXN0Um93OiB3aWRlc3RSb3csIC8vd1Jvd1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY3Vyc29yUG9zaXRpb246IHRleHRhcmVhQ3Vyc29yUG9zaXRpb24sIC8vcG9zXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jdXJzb3JNYXg6IHRleHRhcmVhTGVuZ3RoIC8vbWF4XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIERldGVybWluZXMgd2hldGhlciBuYXRpdmUgb3ZlcmxheSBzY3JvbGxiYXJzIGFyZSBhY3RpdmUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBuYXRpdmUgb3ZlcmxheSBzY3JvbGxiYXJzIGFyZSBhY3RpdmUsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gbmF0aXZlT3ZlcmxheVNjcm9sbGJhcnNBcmVBY3RpdmUoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChfaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NhY2hlICYmIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIGVsZW1lbnQgd2hpY2ggaXMgdXNlZCB0byBtZWFzdXJlIHRoZSBjb250ZW50IHNpemUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn0gVGV4dGFyZWFDb3ZlciBpZiB0YXJnZXQgZWxlbWVudCBpcyB0ZXh0YXJlYSBlbHNlIHRoZSBDb250ZW50RWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0Q29udGVudE1lYXN1cmVFbGVtZW50KCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfaXNUZXh0YXJlYSA/IF90ZXh0YXJlYUNvdmVyRWxlbWVudFswXSA6IF9jb250ZW50RWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdlbmVyYXRlcyBhIHN0cmluZyB3aGljaCByZXByZXNlbnRzIGEgSFRNTCBkaXYgd2l0aCB0aGUgZ2l2ZW4gY2xhc3NlcyBvciBhdHRyaWJ1dGVzLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGNsYXNzZXNPckF0dHJzIFRoZSBjbGFzcyBvZiB0aGUgZGl2IGFzIHN0cmluZyBvciBhIG9iamVjdCB3aGljaCByZXByZXNlbnRzIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBkaXYuIChUaGUgY2xhc3MgYXR0cmlidXRlIGNhbiBhbHNvIGJlIHdyaXR0ZW4gYXMgXCJjbGFzc05hbWVcIi4pXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gY29udGVudCBUaGUgY29udGVudCBvZiB0aGUgZGl2IGFzIHN0cmluZy5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjb25jYXRlZCBzdHJpbmcgd2hpY2ggcmVwcmVzZW50cyBhIEhUTUwgZGl2IGFuZCBpdHMgY29udGVudC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2VuZXJhdGVEaXYoY2xhc3Nlc09yQXR0cnMsIGNvbnRlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzxkaXYgJyArIChjbGFzc2VzT3JBdHRycyA/IHR5cGUoY2xhc3Nlc09yQXR0cnMpID09IFRZUEVTLnMgP1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAnY2xhc3M9XCInICsgY2xhc3Nlc09yQXR0cnMgKyAnXCInIDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cnMgPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoRlJBTUVXT1JLLmlzUGxhaW5PYmplY3QoY2xhc3Nlc09yQXR0cnMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gY2xhc3Nlc09yQXR0cnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzICs9IChrZXkgPT09ICdjJyA/ICdjbGFzcycgOiBrZXkpICsgJz1cIicgKyBjbGFzc2VzT3JBdHRyc1trZXldICsgJ1wiICc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXR0cnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKCkgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyRW1wdHkpICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJz4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnRlbnQgfHwgX3N0ckVtcHR5KSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogU2VsZWN0cyBvciBnZW5lcmF0ZXMgYSBkaXYgd2l0aCB0aGUgZ2l2ZW4gY2xhc3MgYXR0cmlidXRlLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGNsYXNzTmFtZSBUaGUgY2xhc3MgbmFtZXMgKGRpdmlkZWQgYnkgc3BhY2VzKSBvZiB0aGUgZGl2IHdoaWNoIHNoYWxsIGJlIHNlbGVjdGVkIG9yIGdlbmVyYXRlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBzZWxlY3RQYXJlbnRPck9ubHlDaGlsZHJlbiBUaGUgcGFyZW50IGVsZW1lbnQgZnJvbSB3aGljaCBvZiB0aGUgZWxlbWVudCBzaGFsbCBiZSBzZWxlY3RlZC4gKGlmIHVuZGVmaW5lZCBvciBib29sZWFuIGl0cyBob3N0RWxlbWVudClcclxuICAgICAgICAgICAgICAgICAqIElmIGl0cyBhIGJvb2xlYW4gaXQgZGVjaWRlcyB3aGV0aGVyIG9ubHkgdGhlIGNoaWxkcmVuIG9mIHRoZSBob3N0IGVsZW1lbnQgc2hhbGwgYmUgc2VsZWN0ZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIGdlbmVyYXRlZCBvciBzZWxlY3RlZCBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhjbGFzc05hbWUsIHNlbGVjdFBhcmVudE9yT25seUNoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9ubHlDaGlsZHJlbiA9IHR5cGUoc2VsZWN0UGFyZW50T3JPbmx5Q2hpbGRyZW4pID09IFRZUEVTLmI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdFBhcmVudCA9IG9ubHlDaGlsZHJlbiA/IF9ob3N0RWxlbWVudCA6IChzZWxlY3RQYXJlbnRPck9ubHlDaGlsZHJlbiB8fCBfaG9zdEVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKF9kb21FeGlzdHMgJiYgIXNlbGVjdFBhcmVudFtMRVhJQ09OLmxdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IG51bGxcclxuICAgICAgICAgICAgICAgICAgICAgICAgOiBfZG9tRXhpc3RzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHNlbGVjdFBhcmVudFtvbmx5Q2hpbGRyZW4gPyAnY2hpbGRyZW4nIDogJ2ZpbmQnXShfc3RyRG90ICsgY2xhc3NOYW1lLnJlcGxhY2UoL1xccy9nLCBfc3RyRG90KSkuZXEoMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogRlJBTUVXT1JLKGdlbmVyYXRlRGl2KGNsYXNzTmFtZSkpXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gcHJvcGVydHkgZnJvbSB0aGUgZ2l2ZW4gb2JqZWN0LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG9iaiBUaGUgb2JqZWN0IGZyb20gd2hpY2ggdGhlIHByb3BlcnR5IHZhbHVlIHNoYWxsIGJlIGdvdC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBwYXRoIFRoZSBwcm9wZXJ0eSBvZiB3aGljaCB0aGUgdmFsdWUgc2hhbGwgYmUgZ290LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBzZWFyY2hlZCBwcm9wZXJ0eSBvciB1bmRlZmluZWQgb2YgdGhlIHByb3BlcnR5IHdhc24ndCBmb3VuZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0T2JqZWN0UHJvcFZhbChvYmosIHBhdGgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3BsaXRzID0gcGF0aC5zcGxpdChfc3RyRG90KTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbDtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IHNwbGl0cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9ialtMRVhJQ09OLmhPUF0oc3BsaXRzW2ldKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsID0gb2JqW3NwbGl0c1tpXV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpIDwgc3BsaXRzLmxlbmd0aCAmJiB0eXBlKHZhbCkgPT0gVFlQRVMubylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iaiA9IHZhbDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBwcm9wZXJ0eSBmcm9tIHRoZSBnaXZlbiBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gb2JqIFRoZSBvYmplY3QgZnJvbSB3aGljaCB0aGUgcHJvcGVydHkgdmFsdWUgc2hhbGwgYmUgc2V0LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHBhdGggVGhlIHByb3BlcnR5IG9mIHdoaWNoIHRoZSB2YWx1ZSBzaGFsbCBiZSBzZXQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdmFsIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgd2hpY2ggc2hhbGwgYmUgc2V0LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXRPYmplY3RQcm9wVmFsKG9iaiwgcGF0aCwgdmFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNwbGl0cyA9IHBhdGguc3BsaXQoX3N0ckRvdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNwbGl0c0xlbmd0aCA9IHNwbGl0cy5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBleHRlbmRPYmogPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXh0ZW5kT2JqUm9vdCA9IGV4dGVuZE9iajtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IHNwbGl0c0xlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHRlbmRPYmogPSBleHRlbmRPYmpbc3BsaXRzW2ldXSA9IGkgKyAxIDwgc3BsaXRzTGVuZ3RoID8ge30gOiB2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLmV4dGVuZChvYmosIGV4dGVuZE9ialJvb3QsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlx0XHJcbiAgICAgICAgICAgICAgICAgKiBSdW5zIGEgYWN0aW9uIGZvciBlYWNoIHNlbGVjdG9yIGluc2lkZSB0aGUgdXBkYXRlT25Mb2FkIG9wdGlvbi5cdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIFRoZSBhY3Rpb24gZm9yIGVhY2ggdXBkYXRlT25Mb2FkIHNlbGVjdG9yLCB0aGUgYXJndW1lbnRzIHRoZSBmdW5jdGlvbiB0YWtlcyBpcyB0aGUgaW5kZXggYW5kIHRoZSB2YWx1ZSAodGhlIHNlbGVjdG9yKS5cdFxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBlYWNoVXBkYXRlT25Mb2FkKGFjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1cGRhdGVPbkxvYWQgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy51cGRhdGVPbkxvYWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlT25Mb2FkID0gdHlwZSh1cGRhdGVPbkxvYWQpID09IFRZUEVTLnMgPyB1cGRhdGVPbkxvYWQuc3BsaXQoX3N0clNwYWNlKSA6IHVwZGF0ZU9uTG9hZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkuaXNBKHVwZGF0ZU9uTG9hZCkgJiYgIV9kZXN0cm95ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaCh1cGRhdGVPbkxvYWQsIGFjdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gVXRpbHMgQ2FjaGUgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDb21wYXJlcyB0d28gdmFsdWVzIG9yIG9iamVjdHMgYW5kIHJldHVybnMgdHJ1ZSBpZiB0aGV5IGFyZW4ndCBlcXVhbC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBmaXJzdCB2YWx1ZSBvciBvYmplY3Qgd2hpY2ggc2hhbGwgYmUgY29tcGFyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gY2FjaGUgVGhlIHNlY29uZCB2YWx1ZSBvciBvYmplY3Qgd2hpY2ggc2hhbGwgYmUgY29tcGFyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZm9yY2UgSWYgdHJ1ZSB0aGUgcmV0dXJuZWQgdmFsdWUgaXMgYWx3YXlzIHRydWUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBib3RoIHZhbHVlcyBvciBvYmplY3RzIGFyZW4ndCBlcXVhbCBvciBmb3JjZSBpcyB0cnVlLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGNoZWNrQ2FjaGUoY3VycmVudCwgY2FjaGUsIGZvcmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZvcmNlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZm9yY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUoY3VycmVudCkgPT0gVFlQRVMubyAmJiB0eXBlKGNhY2hlKSA9PSBUWVBFUy5vKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIHByb3AgaW4gY3VycmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb3AgIT09ICdjJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50W0xFWElDT04uaE9QXShwcm9wKSAmJiBjYWNoZVtMRVhJQ09OLmhPUF0ocHJvcCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoZWNrQ2FjaGUoY3VycmVudFtwcm9wXSwgY2FjaGVbcHJvcF0pKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50ICE9PSBjYWNoZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gU2hvcnRjdXRzID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogalF1ZXJ5IGV4dGVuZCBtZXRob2Qgc2hvcnRjdXQgd2l0aCBhIGFwcGVuZGVkIFwidHJ1ZVwiIGFzIGZpcnN0IGFyZ3VtZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBleHRlbmREZWVwKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGUkFNRVdPUksuZXh0ZW5kLmFwcGx5KHRoaXMsIFt0cnVlXS5jb25jYXQoW10uc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBqUXVlcnkgYWRkQ2xhc3MgbWV0aG9kIHNob3J0Y3V0LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBhZGRDbGFzcyhlbCwgY2xhc3Nlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfZnJhbWV3b3JrUHJvdG8uYWRkQ2xhc3MuY2FsbChlbCwgY2xhc3Nlcyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBqUXVlcnkgcmVtb3ZlQ2xhc3MgbWV0aG9kIHNob3J0Y3V0LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiByZW1vdmVDbGFzcyhlbCwgY2xhc3Nlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfZnJhbWV3b3JrUHJvdG8ucmVtb3ZlQ2xhc3MuY2FsbChlbCwgY2xhc3Nlcyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBBZGRzIG9yIHJlbW92ZXMgdGhlIGdpdmVuIGNsYXNzZXMgZGVwZW5kZW50IG9uIHRoZSBib29sZWFuIHZhbHVlLiBUcnVlIGZvciBhZGQsIGZhbHNlIGZvciByZW1vdmUuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGFkZFJlbW92ZUNsYXNzKGVsLCBjbGFzc2VzLCBkb0FkZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkb0FkZCA/IGFkZENsYXNzKGVsLCBjbGFzc2VzKSA6IHJlbW92ZUNsYXNzKGVsLCBjbGFzc2VzKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIGpRdWVyeSByZW1vdmUgbWV0aG9kIHNob3J0Y3V0LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiByZW1vdmUoZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2ZyYW1ld29ya1Byb3RvLnJlbW92ZS5jYWxsKGVsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEZpbmRzIHRoZSBmaXJzdCBjaGlsZCBlbGVtZW50IHdpdGggdGhlIGdpdmVuIHNlbGVjdG9yIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGVsIFRoZSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0aGUgc2VsZWN0b3Igc2hhbGwgYmUgdmFsaWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gc2VsZWN0b3IgVGhlIHNlbGVjdG9yIG9mIHRoZSBzZWFyY2hlZCBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMgeyp9IFRoZSBmaXJzdCBlbGVtZW50IHdoaWNoIGlzIGEgY2hpbGQgb2YgdGhlIGdpdmVuIGVsZW1lbnQgYW5kIG1hdGNoZXMgdGhlIGdpdmVucyBzZWxlY3Rvci5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZmluZEZpcnN0KGVsLCBzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfZnJhbWV3b3JrUHJvdG8uZmluZC5jYWxsKGVsLCBzZWxlY3RvcikuZXEoMCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBBUEkgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBQdXRzIHRoZSBpbnN0YW5jZSB0byBzbGVlcC4gSXQgd29udCByZXNwb25kIHRvIGFueSBjaGFuZ2VzIGluIHRoZSBET00gYW5kIHdvbid0IHVwZGF0ZS4gU2Nyb2xsYmFyIEludGVyYWN0aXZpdHkgaXMgYWxzbyBkaXNhYmxlZCBhcyB3ZWxsIGFzIHRoZSByZXNpemUgaGFuZGxlLlxyXG4gICAgICAgICAgICAgICAgICogVGhpcyBiZWhhdmlvciBjYW4gYmUgcmVzZXQgYnkgY2FsbGluZyB0aGUgdXBkYXRlIG1ldGhvZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgX2Jhc2Uuc2xlZXAgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3NsZWVwaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBVcGRhdGVzIHRoZSBwbHVnaW4gYW5kIERPTSB0byB0aGUgY3VycmVudCBvcHRpb25zLlxyXG4gICAgICAgICAgICAgICAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGlmIGEgdXBkYXRlIGlzIDEwMCUgcmVxdWlyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZm9yY2UgVHJ1ZSBpZiBldmVyeSBwcm9wZXJ0eSBzaGFsbCBiZSB1cGRhdGVkIGFuZCB0aGUgY2FjaGUgc2hhbGwgYmUgaWdub3JlZC5cclxuICAgICAgICAgICAgICAgICAqICFJTlRFUk5BTCBVU0FHRSEgOiBmb3JjZSBjYW4gYmUgYSBzdHJpbmcgXCJhdXRvXCIsIFwic3luY1wiIG9yIFwiem9vbVwiIHRvb1xyXG4gICAgICAgICAgICAgICAgICogaWYgXCJhdXRvXCIgdGhlbiBiZWZvcmUgYSByZWFsIHVwZGF0ZSB0aGUgY29udGVudCBzaXplIGFuZCBob3N0IGVsZW1lbnQgYXR0cmlidXRlcyBnZXRzIGNoZWNrZWQsIGFuZCBpZiB0aGV5IGNoYW5nZWQgb25seSB0aGVuIHRoZSB1cGRhdGUgbWV0aG9kIHdpbGwgYmUgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICogaWYgXCJzeW5jXCIgdGhlbiB0aGUgYXN5bmMgdXBkYXRlIHByb2Nlc3MgKE11dGF0aW9uT2JzZXJ2ZXIgb3IgVXBkYXRlTG9vcCkgZ2V0cyBzeW5jaHJvbml6ZWQgYW5kIGEgY29ycmVzcG9uZGluZyB1cGRhdGUgdGFrZXMgcGxhY2UgaWYgb25lIHdhcyBuZWVkZWQgZHVlIHRvIHBlbmRpbmcgY2hhbmdlcy5cclxuICAgICAgICAgICAgICAgICAqIGlmIFwiem9vbVwiIHRoZW4gYSB1cGRhdGUgdGFrZXMgcGxhY2Ugd2hlcmUgaXQncyBhc3N1bWVkIHRoYXQgY29udGVudCBhbmQgaG9zdCBzaXplIGNoYW5nZWRcclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufHVuZGVmaW5lZH0gXHJcbiAgICAgICAgICAgICAgICAgKiBJZiBmb3JjZSBpcyBcInN5bmNcIiB0aGVuIGEgYm9vbGVhbiBpcyByZXR1cm5lZCB3aGljaCBpbmRpY2F0ZXMgd2hldGhlciBhIHVwZGF0ZSB3YXMgbmVlZGVkIGR1ZSB0byBwZW5kaW5nIGNoYW5nZXMuXHJcbiAgICAgICAgICAgICAgICAgKiBJZiBmb3JjZSBpcyBcImF1dG9cIiB0aGVuIGEgYm9vbGVhbiBpcyByZXR1cm5lZCB3aGV0aGVyIGEgdXBkYXRlIHdhcyBuZWVkZWQgZHVlIHRvIGF0dHJpYnV0ZSBvciBzaXplIGNoYW5nZXMuXHJcbiAgICAgICAgICAgICAgICAgKiB1bmRlZmluZWQgb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS51cGRhdGUgPSBmdW5jdGlvbiAoZm9yY2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2Rlc3Ryb3llZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cnNDaGFuZ2VkO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50U2l6ZUM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGlzU3RyaW5nID0gdHlwZShmb3JjZSkgPT0gVFlQRVMucztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZG9VcGRhdGVBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtdXRIb3N0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtdXRDb250ZW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvcmNlID09PSBfc3RyQXV0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnNDaGFuZ2VkID0gbWVhbmluZ2Z1bEF0dHJzQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFNpemVDID0gdXBkYXRlQXV0b0NvbnRlbnRTaXplQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9VcGRhdGVBdXRvID0gYXR0cnNDaGFuZ2VkIHx8IGNvbnRlbnRTaXplQztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1VwZGF0ZUF1dG8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudFNpemVDaGFuZ2VkOiBjb250ZW50U2l6ZUMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jaGFuZ2VkT3B0aW9uczogX2luaXRpYWxpemVkID8gdW5kZWZpbmVkIDogX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChmb3JjZSA9PT0gX3N0clN5bmMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRIb3N0ID0gX211dGF0aW9uT2JzZXJ2ZXJIb3N0Q2FsbGJhY2soX211dGF0aW9uT2JzZXJ2ZXJIb3N0LnRha2VSZWNvcmRzKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dENvbnRlbnQgPSBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnRDYWxsYmFjayhfbXV0YXRpb25PYnNlcnZlckNvbnRlbnQudGFrZVJlY29yZHMoKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRIb3N0ID0gX2Jhc2UudXBkYXRlKF9zdHJBdXRvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChmb3JjZSA9PT0gJ3pvb20nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0U2l6ZUNoYW5nZWQ6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRTaXplQ2hhbmdlZDogdHJ1ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlID0gX3NsZWVwaW5nIHx8IGZvcmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2xlZXBpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfYmFzZS51cGRhdGUoX3N0clN5bmMpIHx8IGZvcmNlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKHsgX2ZvcmNlOiBmb3JjZSB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZUVsZW1lbnRzT25Mb2FkKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkb1VwZGF0ZUF1dG8gfHwgbXV0SG9zdCB8fCBtdXRDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICBHZXRzIG9yIHNldHMgdGhlIGN1cnJlbnQgb3B0aW9ucy4gVGhlIHVwZGF0ZSBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgYXV0b21hdGljYWxseSBpZiBuZXcgb3B0aW9ucyB3ZXJlIHNldC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBuZXdPcHRpb25zIElmIG5ldyBvcHRpb25zIGFyZSBnaXZlbiwgdGhlbiB0aGUgbmV3IG9wdGlvbnMgd2lsbCBiZSBzZXQsIGlmIG5ldyBvcHRpb25zIGFyZW4ndCBnaXZlbiAodW5kZWZpbmVkIG9yIGEgbm90IGEgcGxhaW4gb2JqZWN0KSB0aGVuIHRoZSBjdXJyZW50IG9wdGlvbnMgd2lsbCBiZSByZXR1cm5lZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB2YWx1ZSBJZiBuZXcgb3B0aW9ucyBpcyBhIHByb3BlcnR5IHBhdGggc3RyaW5nLCB0aGVuIHRoaXMgdmFsdWUgd2lsbCBiZSB1c2VkIHRvIHNldCB0aGUgb3B0aW9uIHRvIHdoaWNoIHRoZSBwcm9wZXJ0eSBwYXRoIHN0cmluZyBsZWFkcy5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5vcHRpb25zID0gZnVuY3Rpb24gKG5ld09wdGlvbnMsIHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9wdGlvbiA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGFuZ2VkT3BzO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JldHVybiBjdXJyZW50IG9wdGlvbnMgaWYgbmV3T3B0aW9ucyBhcmUgdW5kZWZpbmVkIG9yIGVtcHR5XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKEZSQU1FV09SSy5pc0VtcHR5T2JqZWN0KG5ld09wdGlvbnMpIHx8ICFGUkFNRVdPUksuaXNQbGFpbk9iamVjdChuZXdPcHRpb25zKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShuZXdPcHRpb25zKSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRPYmplY3RQcm9wVmFsKG9wdGlvbiwgbmV3T3B0aW9ucywgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZWRPcHMgPSBzZXRPcHRpb25zKG9wdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldE9iamVjdFByb3BWYWwoX2N1cnJlbnRPcHRpb25zLCBuZXdPcHRpb25zKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2N1cnJlbnRPcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlZE9wcyA9IHNldE9wdGlvbnMobmV3T3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIUZSQU1FV09SSy5pc0VtcHR5T2JqZWN0KGNoYW5nZWRPcHMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZSh7IF9jaGFuZ2VkT3B0aW9uczogY2hhbmdlZE9wcyB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmVzdG9yZSB0aGUgRE9NLCBkaXNjb25uZWN0cyBhbGwgb2JzZXJ2ZXJzLCByZW1vdmUgYWxsIHJlc2l6ZSBvYnNlcnZlcnMgYW5kIHB1dCB0aGUgaW5zdGFuY2UgdG8gc2xlZXAuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9kZXN0cm95ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgdGhpcyBpbnN0YW5jZSBmcm9tIGF1dG8gdXBkYXRlIGxvb3BcclxuICAgICAgICAgICAgICAgICAgICBhdXRvVXBkYXRlTG9vcC5yZW1vdmUoX2Jhc2UpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2Rpc2Nvbm5lY3QgYWxsIG11dGF0aW9uIG9ic2VydmVyc1xyXG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RNdXRhdGlvbk9ic2VydmVycygpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgcmVzaXplIG9ic2VydmVyc1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzaXplT2JzZXJ2ZXIoX3NpemVPYnNlcnZlckVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzaXplT2JzZXJ2ZXIoX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgYWxsIGV4dGVuc2lvbnNcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBleHROYW1lIGluIF9leHRlbnNpb25zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS5yZW1vdmVFeHQoZXh0TmFtZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIGFsbCAnZGVzdHJveScgZXZlbnRzXHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKF9kZXN0cm95RXZlbnRzW0xFWElDT04ubF0gPiAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfZGVzdHJveUV2ZW50cy5wb3AoKSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgZXZlbnRzIGZyb20gaG9zdCBlbGVtZW50XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBIb3N0TW91c2VUb3VjaEV2ZW50cyh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgYWxsIGhlbHBlciAvIGRldGVjdGlvbiBlbGVtZW50c1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfY29udGVudEdsdWVFbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUoX2NvbnRlbnRHbHVlRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9jb250ZW50QXJyYW5nZUVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZShfY29udGVudEFycmFuZ2VFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKF9zaXplQXV0b09ic2VydmVyRWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIGFsbCBnZW5lcmF0ZWQgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBTY3JvbGxiYXJzRE9NKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU2Nyb2xsYmFyQ29ybmVyRE9NKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU3RydWN0dXJlRE9NKHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgZ2VuZXJhdGVkIGltYWdlIGxvYWQgZXZlbnRzXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBfdXBkYXRlT25Mb2FkRWxtc1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSyhfdXBkYXRlT25Mb2FkRWxtc1tpXSkub2ZmKF91cGRhdGVPbkxvYWRFdmVudE5hbWUsIHVwZGF0ZU9uTG9hZENhbGxiYWNrKTtcclxuICAgICAgICAgICAgICAgICAgICBfdXBkYXRlT25Mb2FkRWxtcyA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgX2Rlc3Ryb3llZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgX3NsZWVwaW5nID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgdGhpcyBpbnN0YW5jZSBmcm9tIHRoZSBpbnN0YW5jZXMgbGlzdFxyXG4gICAgICAgICAgICAgICAgICAgIElOU1RBTkNFUyhwbHVnaW5UYXJnZXRFbGVtZW50LCAwKTtcclxuICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvbkRlc3Ryb3llZCcpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgcHJvcGVydGllcyBhbmQgbWV0aG9kc1xyXG4gICAgICAgICAgICAgICAgICAgIC8vZm9yICh2YXIgcHJvcGVydHkgaW4gX2Jhc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgZGVsZXRlIF9iYXNlW3Byb3BlcnR5XTtcclxuICAgICAgICAgICAgICAgICAgICAvL19iYXNlID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNjcm9sbHMgdG8gYSBnaXZlbiBwb3NpdGlvbiBvciBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGNvb3JkaW5hdGVzXHJcbiAgICAgICAgICAgICAgICAgKiAxLiBDYW4gYmUgXCJjb29yZGluYXRlc1wiIHdoaWNoIGxvb2tzIGxpa2U6XHJcbiAgICAgICAgICAgICAgICAgKiAgICB7IHggOiA/LCB5IDogPyB9IE9SICAgICAgICAgIE9iamVjdCB3aXRoIHggYW5kIHkgcHJvcGVydGllc1xyXG4gICAgICAgICAgICAgICAgICogICAgeyBsZWZ0IDogPywgdG9wIDogPyB9IE9SICAgICBPYmplY3Qgd2l0aCBsZWZ0IGFuZCB0b3AgcHJvcGVydGllc1xyXG4gICAgICAgICAgICAgICAgICogICAgeyBsIDogPywgdCA6ID8gfSBPUiAgICAgICAgICBPYmplY3Qgd2l0aCBsIGFuZCB0IHByb3BlcnRpZXNcclxuICAgICAgICAgICAgICAgICAqICAgIFsgPywgPyBdIE9SICAgICAgICAgICAgICAgICAgQXJyYXkgd2hlcmUgdGhlIGZpcnN0IHR3byBlbGVtZW50IGFyZSB0aGUgY29vcmRpbmF0ZXMgKGZpcnN0IGlzIHgsIHNlY29uZCBpcyB5KVxyXG4gICAgICAgICAgICAgICAgICogICAgPyAgICAgICAgICAgICAgICAgICAgICAgICAgICBBIHNpbmdsZSB2YWx1ZSB3aGljaCBzdGF5cyBmb3IgYm90aCBheGlzXHJcbiAgICAgICAgICAgICAgICAgKiAgICBBIHZhbHVlIGNhbiBiZSBhIG51bWJlciwgYSBzdHJpbmcgb3IgYSBjYWxjdWxhdGlvbi5cclxuICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgKiAgICBPcGVyYXRvcnM6XHJcbiAgICAgICAgICAgICAgICAgKiAgICBbTk9ORV0gIFRoZSBjdXJyZW50IHNjcm9sbCB3aWxsIGJlIG92ZXJ3cml0dGVuIGJ5IHRoZSB2YWx1ZS5cclxuICAgICAgICAgICAgICAgICAqICAgICcrPScgICAgVGhlIHZhbHVlIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGN1cnJlbnQgc2Nyb2xsIG9mZnNldFxyXG4gICAgICAgICAgICAgICAgICogICAgJy09JyAgICBUaGUgdmFsdWUgd2lsbCBiZSBzdWJ0cmFjdGVkIGZyb20gdGhlIGN1cnJlbnQgc2Nyb2xsIG9mZnNldFxyXG4gICAgICAgICAgICAgICAgICogICAgJyo9JyAgICBUaGUgY3VycmVudCBzY3JvbGwgd2lsIGJlIG11bHRpcGxpY2F0ZWQgYnkgdGhlIHZhbHVlLlxyXG4gICAgICAgICAgICAgICAgICogICAgJy89JyAgICBUaGUgY3VycmVudCBzY3JvbGwgd2lsIGJlIGRpdmlkZWQgYnkgdGhlIHZhbHVlLlxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqICAgIFVuaXRzOlxyXG4gICAgICAgICAgICAgICAgICogICAgW05PTkVdICBUaGUgdmFsdWUgaXMgdGhlIGZpbmFsIHNjcm9sbCBhbW91bnQuICAgICAgICAgICAgICAgICAgIGZpbmFsID0gKHZhbHVlICogMSlcclxuICAgICAgICAgICAgICAgICAqICAgICdweCcgICAgU2FtZSBhcyBub25lXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnJScgICAgIFRoZSB2YWx1ZSBpcyBkZXBlbmRlbnQgb24gdGhlIGN1cnJlbnQgc2Nyb2xsIHZhbHVlLiAgICAgZmluYWwgPSAoKGN1cnJlbnRTY3JvbGxWYWx1ZSAvIDEwMCkgKiB2YWx1ZSlcclxuICAgICAgICAgICAgICAgICAqICAgICd2dycgICAgVGhlIHZhbHVlIGlzIG11bHRpcGxpY2F0ZWQgYnkgdGhlIHZpZXdwb3J0IHdpZHRoLiAgICAgICBmaW5hbCA9ICh2YWx1ZSAqIHZpZXdwb3J0V2lkdGgpXHJcbiAgICAgICAgICAgICAgICAgKiAgICAndmgnICAgIFRoZSB2YWx1ZSBpcyBtdWx0aXBsaWNhdGVkIGJ5IHRoZSB2aWV3cG9ydCBoZWlnaHQuICAgICAgZmluYWwgPSAodmFsdWUgKiB2aWV3cG9ydEhlaWdodClcclxuICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgKiAgICBleGFtcGxlIGZpbmFsIHZhbHVlczpcclxuICAgICAgICAgICAgICAgICAqICAgIDIwMCwgJzIwMHB4JywgJzUwJScsICcxdncnLCAnMXZoJywgJys9MjAwJywgJy89MXZ3JywgJyo9MnB4JywgJy09NXZoJywgJys9MzMlJywgJys9IDUwJSAtIDJweCcsICctPSAxdncgLSA1MCUnXHJcbiAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICogMi4gQ2FuIGJlIGEgSFRNTCBvciBqUXVlcnkgZWxlbWVudDpcclxuICAgICAgICAgICAgICAgICAqICAgIFRoZSBmaW5hbCBzY3JvbGwgb2Zmc2V0IGlzIHRoZSBvZmZzZXQgKHdpdGhvdXQgbWFyZ2luKSBvZiB0aGUgZ2l2ZW4gSFRNTCAvIGpRdWVyeSBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqIDMuIENhbiBiZSBhIG9iamVjdCB3aXRoIGEgSFRNTCBvciBqUXVlcnkgZWxlbWVudCB3aXRoIGFkZGl0aW9uYWwgc2V0dGluZ3M6XHJcbiAgICAgICAgICAgICAgICAgKiAgICB7XHJcbiAgICAgICAgICAgICAgICAgKiAgICAgIGVsIDogW0hUTUxFbGVtZW50LCBqUXVlcnkgZWxlbWVudF0sICAgICAgICAgICAgIE1VU1QgYmUgc3BlY2lmaWVkLCBlbHNlIHRoaXMgb2JqZWN0IGlzbid0IHZhbGlkLlxyXG4gICAgICAgICAgICAgICAgICogICAgICBzY3JvbGwgOiBbc3RyaW5nLCBhcnJheSwgb2JqZWN0XSwgICAgICAgICAgICAgICBEZWZhdWx0IHZhbHVlIGlzICdhbHdheXMnLlxyXG4gICAgICAgICAgICAgICAgICogICAgICBibG9jayA6IFtzdHJpbmcsIGFycmF5LCBvYmplY3RdLCAgICAgICAgICAgICAgICBEZWZhdWx0IHZhbHVlIGlzICdiZWdpbicuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAgIG1hcmdpbiA6IFtudW1iZXIsIGJvb2xlYW4sIGFycmF5LCBvYmplY3RdICAgICAgIERlZmF1bHQgdmFsdWUgaXMgZmFsc2UuXHJcbiAgICAgICAgICAgICAgICAgKiAgICB9XHJcbiAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICogICAgUG9zc2libGUgc2Nyb2xsIHNldHRpbmdzIGFyZTpcclxuICAgICAgICAgICAgICAgICAqICAgICdhbHdheXMnICAgICAgU2Nyb2xscyBhbHdheXMuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnaWZuZWVkZWQnICAgIFNjcm9sbHMgb25seSBpZiB0aGUgZWxlbWVudCBpc250IGZ1bGx5IGluIHZpZXcuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnbmV2ZXInICAgICAgIFNjcm9sbHMgbmV2ZXIuXHJcbiAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICogICAgUG9zc2libGUgYmxvY2sgc2V0dGluZ3MgYXJlOlxyXG4gICAgICAgICAgICAgICAgICogICAgJ2JlZ2luJyAgIEJvdGggYXhpcyBzaGFsbCBiZSBkb2NrZWQgdG8gdGhlIFwiYmVnaW5cIiBlZGdlLiAtIFRoZSBlbGVtZW50IHdpbGwgYmUgZG9ja2VkIHRvIHRoZSB0b3AgYW5kIGxlZnQgZWRnZSBvZiB0aGUgdmlld3BvcnQuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnZW5kJyAgICAgQm90aCBheGlzIHNoYWxsIGJlIGRvY2tlZCB0byB0aGUgXCJlbmRcIiBlZGdlLiAtIFRoZSBlbGVtZW50IHdpbGwgYmUgZG9ja2VkIHRvIHRoZSBib3R0b20gYW5kIHJpZ2h0IGVkZ2Ugb2YgdGhlIHZpZXdwb3J0LiAoSWYgZGlyZWN0aW9uIGlzIFJUTCB0byB0aGUgYm90dG9tIGFuZCBsZWZ0IGVkZ2UuKVxyXG4gICAgICAgICAgICAgICAgICogICAgJ2NlbnRlcicgIEJvdGggYXhpcyBzaGFsbCBiZSBkb2NrZWQgdG8gXCJjZW50ZXJcIi4gLSBUaGUgZWxlbWVudCB3aWxsIGJlIGNlbnRlcmVkIGluIHRoZSB2aWV3cG9ydC5cclxuICAgICAgICAgICAgICAgICAqICAgICduZWFyZXN0JyBUaGUgZWxlbWVudCB3aWxsIGJlIGRvY2tlZCB0byB0aGUgbmVhcmVzdCBlZGdlKHMpLlxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqICAgIFBvc3NpYmxlIG1hcmdpbiBzZXR0aW5ncyBhcmU6IC0tIFRoZSBhY3R1YWwgbWFyZ2luIG9mIHRoZSBlbGVtZW50IHdvbnQgYmUgYWZmZWN0LCB0aGlzIG9wdGlvbiBhZmZlY3RzIG9ubHkgdGhlIGZpbmFsIHNjcm9sbCBvZmZzZXQuXHJcbiAgICAgICAgICAgICAgICAgKiAgICBbQk9PTEVBTl0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIHRydWUgdGhlIGNzcyBtYXJnaW4gb2YgdGhlIGVsZW1lbnQgd2lsbCBiZSB1c2VkLCBpZiBmYWxzZSBubyBtYXJnaW4gd2lsbCBiZSB1c2VkLlxyXG4gICAgICAgICAgICAgICAgICogICAgW05VTUJFUl0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGUgbWFyZ2luIHdpbGwgYmUgdXNlZCBmb3IgYWxsIGVkZ2VzLlxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBkdXJhdGlvbiBUaGUgZHVyYXRpb24gb2YgdGhlIHNjcm9sbCBhbmltYXRpb24sIE9SIGEgalF1ZXJ5IGFuaW1hdGlvbiBjb25maWd1cmF0aW9uIG9iamVjdC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBlYXNpbmcgVGhlIGFuaW1hdGlvbiBlYXNpbmcuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gY29tcGxldGUgVGhlIGFuaW1hdGlvbiBjb21wbGV0ZSBjYWxsYmFjay5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7XHJcbiAgICAgICAgICAgICAgICAgKiAgIHBvc2l0aW9uOiB7eDogbnVtYmVyLCB5OiBudW1iZXJ9LFxyXG4gICAgICAgICAgICAgICAgICogICByYXRpbzoge3g6IG51bWJlciwgeTogbnVtYmVyfSxcclxuICAgICAgICAgICAgICAgICAqICAgbWF4OiB7eDogbnVtYmVyLCB5OiBudW1iZXJ9LFxyXG4gICAgICAgICAgICAgICAgICogICBoYW5kbGVPZmZzZXQ6IHt4OiBudW1iZXIsIHk6IG51bWJlcn0sXHJcbiAgICAgICAgICAgICAgICAgKiAgIGhhbmRsZUxlbmd0aDoge3g6IG51bWJlciwgeTogbnVtYmVyfSxcclxuICAgICAgICAgICAgICAgICAqICAgaGFuZGxlTGVuZ3RoUmF0aW86IHt4OiBudW1iZXIsIHk6IG51bWJlcn0sIHRcclxuICAgICAgICAgICAgICAgICAqICAgcmFja0xlbmd0aDoge3g6IG51bWJlciwgeTogbnVtYmVyfSxcclxuICAgICAgICAgICAgICAgICAqICAgaXNSVEw6IGJvb2xlYW4sXHJcbiAgICAgICAgICAgICAgICAgKiAgIGlzUlRMTm9ybWFsaXplZDogYm9vbGVhblxyXG4gICAgICAgICAgICAgICAgICogIH19XHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLnNjcm9sbCA9IGZ1bmN0aW9uIChjb29yZGluYXRlcywgZHVyYXRpb24sIGVhc2luZywgY29tcGxldGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCB8fCBjb29yZGluYXRlcyA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbmZvWCA9IF9zY3JvbGxIb3Jpem9udGFsSW5mbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluZm9ZID0gX3Njcm9sbFZlcnRpY2FsSW5mbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vcm1hbGl6ZUludmVydCA9IF9ub3JtYWxpemVSVExDYWNoZSAmJiBfaXNSVEwgJiYgX3J0bFNjcm9sbEJlaGF2aW9yLmk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub3JtYWxpemVOZWdhdGUgPSBfbm9ybWFsaXplUlRMQ2FjaGUgJiYgX2lzUlRMICYmIF9ydGxTY3JvbGxCZWhhdmlvci5uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsWCA9IGluZm9YLl9jdXJyZW50U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsWFJhdGlvID0gaW5mb1guX2N1cnJlbnRTY3JvbGxSYXRpbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1heFNjcm9sbFggPSBpbmZvWC5fbWF4U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxYUmF0aW8gPSBub3JtYWxpemVJbnZlcnQgPyAxIC0gc2Nyb2xsWFJhdGlvIDogc2Nyb2xsWFJhdGlvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxYID0gbm9ybWFsaXplSW52ZXJ0ID8gbWF4U2Nyb2xsWCAtIHNjcm9sbFggOiBzY3JvbGxYO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxYICo9IG5vcm1hbGl6ZU5lZ2F0ZSA/IC0xIDogMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4U2Nyb2xsWCAqPSBub3JtYWxpemVOZWdhdGUgPyAtMSA6IDE7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBzY3JvbGxYLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGluZm9ZLl9jdXJyZW50U2Nyb2xsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF0aW86IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBzY3JvbGxYUmF0aW8sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaW5mb1kuX2N1cnJlbnRTY3JvbGxSYXRpb1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IG1heFNjcm9sbFgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaW5mb1kuX21heFNjcm9sbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZU9mZnNldDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGluZm9YLl9oYW5kbGVPZmZzZXQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaW5mb1kuX2hhbmRsZU9mZnNldFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUxlbmd0aDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGluZm9YLl9oYW5kbGVMZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaW5mb1kuX2hhbmRsZUxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUxlbmd0aFJhdGlvOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogaW5mb1guX2hhbmRsZUxlbmd0aFJhdGlvLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGluZm9ZLl9oYW5kbGVMZW5ndGhSYXRpb1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrTGVuZ3RoOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogaW5mb1guX3RyYWNrTGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGluZm9ZLl90cmFja0xlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNuYXBwZWRIYW5kbGVPZmZzZXQ6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBpbmZvWC5fc25hcHBlZEhhbmRsZU9mZnNldCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBpbmZvWS5fc25hcHBlZEhhbmRsZU9mZnNldFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzUlRMOiBfaXNSVEwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1JUTE5vcm1hbGl6ZWQ6IF9ub3JtYWxpemVSVExDYWNoZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlKF9zdHJTeW5jKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5vcm1hbGl6ZVJUTCA9IF9ub3JtYWxpemVSVExDYWNoZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZXNYQXhpc1Byb3BzID0gW19zdHJYLCBfc3RyTGVmdCwgJ2wnXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZXNZQXhpc1Byb3BzID0gW19zdHJZLCBfc3RyVG9wLCAndCddO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb29yZGluYXRlc09wZXJhdG9ycyA9IFsnKz0nLCAnLT0nLCAnKj0nLCAnLz0nXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZHVyYXRpb25Jc09iamVjdCA9IHR5cGUoZHVyYXRpb24pID09IFRZUEVTLm87XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbXBsZXRlQ2FsbGJhY2sgPSBkdXJhdGlvbklzT2JqZWN0ID8gZHVyYXRpb24uY29tcGxldGUgOiBjb21wbGV0ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZmluYWxTY3JvbGwgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3BlY2lhbEVhc2luZyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkb1Njcm9sbExlZnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRvU2Nyb2xsVG9wO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhbmltYXRpb25PcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJFbmQgPSAnZW5kJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQmVnaW4gPSAnYmVnaW4nO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJDZW50ZXIgPSAnY2VudGVyJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyTmVhcmVzdCA9ICduZWFyZXN0JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQWx3YXlzID0gJ2Fsd2F5cyc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ck5ldmVyID0gJ25ldmVyJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RySWZOZWVkZWQgPSAnaWZuZWVkZWQnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJMZW5ndGggPSBMRVhJQ09OLmw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNldHRpbmdzQXhpcztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2V0dGluZ3NTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNldHRpbmdzQmxvY2s7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNldHRpbmdzTWFyZ2luO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmaW5hbEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRPYmpTZXR0aW5nc0F4aXNWYWx1ZXMgPSBbX3N0clgsIF9zdHJZLCAneHknLCAneXgnXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudE9ialNldHRpbmdzQmxvY2tWYWx1ZXMgPSBbc3RyQmVnaW4sIHN0ckVuZCwgc3RyQ2VudGVyLCBzdHJOZWFyZXN0XTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudE9ialNldHRpbmdzU2Nyb2xsVmFsdWVzID0gW3N0ckFsd2F5cywgc3RyTmV2ZXIsIHN0cklmTmVlZGVkXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZXNJc0VsZW1lbnRPYmogPSBjb29yZGluYXRlc1tMRVhJQ09OLmhPUF0oJ2VsJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvc3NpYmxlRWxlbWVudCA9IGNvb3JkaW5hdGVzSXNFbGVtZW50T2JqID8gY29vcmRpbmF0ZXMuZWwgOiBjb29yZGluYXRlcztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcG9zc2libGVFbGVtZW50SXNKUXVlcnkgPSBwb3NzaWJsZUVsZW1lbnQgaW5zdGFuY2VvZiBGUkFNRVdPUksgfHwgSlFVRVJZID8gcG9zc2libGVFbGVtZW50IGluc3RhbmNlb2YgSlFVRVJZIDogZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvc3NpYmxlRWxlbWVudElzSFRNTEVsZW1lbnQgPSBwb3NzaWJsZUVsZW1lbnRJc0pRdWVyeSA/IGZhbHNlIDogaXNIVE1MRWxlbWVudChwb3NzaWJsZUVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1cGRhdGVTY3JvbGxiYXJJbmZvcyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvU2Nyb2xsTGVmdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVPZmZzZXQodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1Njcm9sbFRvcClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVPZmZzZXQoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByb3h5Q29tcGxldGVDYWxsYmFjayA9IHR5cGUoY29tcGxldGVDYWxsYmFjaykgIT0gVFlQRVMuZiA/IHVuZGVmaW5lZCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlU2Nyb2xsYmFySW5mb3MoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGVDYWxsYmFjaygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gY2hlY2tTZXR0aW5nc1N0cmluZ1ZhbHVlKGN1cnJWYWx1ZSwgYWxsb3dlZFZhbHVlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYWxsb3dlZFZhbHVlc1tzdHJMZW5ndGhdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyVmFsdWUgPT09IGFsbG93ZWRWYWx1ZXNbaV0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRSYXdTY3JvbGwoaXNYLCBjb29yZGluYXRlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZVByb3BzID0gaXNYID8gY29vcmRpbmF0ZXNYQXhpc1Byb3BzIDogY29vcmRpbmF0ZXNZQXhpc1Byb3BzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlcyA9IHR5cGUoY29vcmRpbmF0ZXMpID09IFRZUEVTLnMgfHwgdHlwZShjb29yZGluYXRlcykgPT0gVFlQRVMubiA/IFtjb29yZGluYXRlcywgY29vcmRpbmF0ZXNdIDogY29vcmRpbmF0ZXM7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoQ09NUEFUSUJJTElUWS5pc0EoY29vcmRpbmF0ZXMpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlzWCA/IGNvb3JkaW5hdGVzWzBdIDogY29vcmRpbmF0ZXNbMV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUoY29vcmRpbmF0ZXMpID09IFRZUEVTLm8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZGVjaWRlcyBSVEwgbm9ybWFsaXphdGlvbiBcImhhY2tcIiB3aXRoIC5uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL25vcm1hbGl6ZVJUTCA9IHR5cGUoY29vcmRpbmF0ZXMubikgPT0gVFlQRVMuYiA/IGNvb3JkaW5hdGVzLm4gOiBub3JtYWxpemVSVEw7IFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb3JkaW5hdGVQcm9wc1tzdHJMZW5ndGhdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvb3JkaW5hdGVQcm9wc1tpXSBpbiBjb29yZGluYXRlcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvb3JkaW5hdGVzW2Nvb3JkaW5hdGVQcm9wc1tpXV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0RmluYWxTY3JvbGwoaXNYLCByYXdTY3JvbGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzU3RyaW5nID0gdHlwZShyYXdTY3JvbGwpID09IFRZUEVTLnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcGVyYXRvcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFtb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbEluZm8gPSBpc1ggPyBfc2Nyb2xsSG9yaXpvbnRhbEluZm8gOiBfc2Nyb2xsVmVydGljYWxJbmZvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyclNjcm9sbCA9IHNjcm9sbEluZm8uX2N1cnJlbnRTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtYXhTY3JvbGwgPSBzY3JvbGxJbmZvLl9tYXhTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtdWx0ID0gJyAqICc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmaW5hbFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNSVExpc1ggPSBfaXNSVEwgJiYgaXNYO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9ybWFsaXplU2hvcnRjdXRzID0gaXNSVExpc1ggJiYgX3J0bFNjcm9sbEJlaGF2aW9yLm4gJiYgIW5vcm1hbGl6ZVJUTDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0clJlcGxhY2UgPSAncmVwbGFjZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBldmFsRnVuYyA9IGV2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3NzaWJsZU9wZXJhdG9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY2hlY2sgb3BlcmF0b3JcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyYXdTY3JvbGxbc3RyTGVuZ3RoXSA+IDIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NzaWJsZU9wZXJhdG9yID0gcmF3U2Nyb2xsLnN1YnN0cigwLCAyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5BcnJheShwb3NzaWJsZU9wZXJhdG9yLCBjb29yZGluYXRlc09wZXJhdG9ycykgPiAtMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0b3IgPSBwb3NzaWJsZU9wZXJhdG9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY2FsY3VsYXRlIHVuaXRzIGFuZCBzaG9ydGN1dHNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd1Njcm9sbCA9IG9wZXJhdG9yID8gcmF3U2Nyb2xsLnN1YnN0cigyKSA6IHJhd1Njcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd1Njcm9sbCA9IHJhd1Njcm9sbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0clJlcGxhY2VdKC9taW4vZywgMCkgLy8nbWluJyA9IDAlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oLzwvZywgMCkgICAvLyc8JyAgID0gMCVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHJSZXBsYWNlXSgvbWF4L2csIChub3JtYWxpemVTaG9ydGN1dHMgPyAnLScgOiBfc3RyRW1wdHkpICsgX3N0ckh1bmRyZWRQZXJjZW50KSAgICAvLydtYXgnID0gMTAwJVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0clJlcGxhY2VdKC8+L2csIChub3JtYWxpemVTaG9ydGN1dHMgPyAnLScgOiBfc3RyRW1wdHkpICsgX3N0ckh1bmRyZWRQZXJjZW50KSAgICAgIC8vJz4nICAgPSAxMDAlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oL3B4L2csIF9zdHJFbXB0eSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHJSZXBsYWNlXSgvJS9nLCBtdWx0ICsgKG1heFNjcm9sbCAqIChpc1JUTGlzWCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IubiA/IC0xIDogMSkgLyAxMDAuMCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oL3Z3L2csIG11bHQgKyBfdmlld3BvcnRTaXplLncpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oL3ZoL2csIG11bHQgKyBfdmlld3BvcnRTaXplLmgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW1vdW50ID0gcGFyc2VUb1plcm9Pck51bWJlcihpc05hTihyYXdTY3JvbGwpID8gcGFyc2VUb1plcm9Pck51bWJlcihldmFsRnVuYyhyYXdTY3JvbGwpLCB0cnVlKS50b0ZpeGVkKCkgOiByYXdTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW1vdW50ID0gcmF3U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW1vdW50ICE9PSB1bmRlZmluZWQgJiYgIWlzTmFOKGFtb3VudCkgJiYgdHlwZShhbW91bnQpID09IFRZUEVTLm4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub3JtYWxpemVJc1JUTGlzWCA9IG5vcm1hbGl6ZVJUTCAmJiBpc1JUTGlzWDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcGVyYXRvckN1cnJTY3JvbGwgPSBjdXJyU2Nyb2xsICogKG5vcm1hbGl6ZUlzUlRMaXNYICYmIF9ydGxTY3JvbGxCZWhhdmlvci5uID8gLTEgOiAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbnZlcnQgPSBub3JtYWxpemVJc1JUTGlzWCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IuaTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZWdhdGUgPSBub3JtYWxpemVJc1JUTGlzWCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IubjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yQ3VyclNjcm9sbCA9IGludmVydCA/IChtYXhTY3JvbGwgLSBvcGVyYXRvckN1cnJTY3JvbGwpIDogb3BlcmF0b3JDdXJyU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChvcGVyYXRvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJys9JzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxWYWx1ZSA9IG9wZXJhdG9yQ3VyclNjcm9sbCArIGFtb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnLT0nOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlID0gb3BlcmF0b3JDdXJyU2Nyb2xsIC0gYW1vdW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICcqPSc6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsVmFsdWUgPSBvcGVyYXRvckN1cnJTY3JvbGwgKiBhbW91bnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJy89JzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxWYWx1ZSA9IG9wZXJhdG9yQ3VyclNjcm9sbCAvIGFtb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxWYWx1ZSA9IGFtb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlID0gaW52ZXJ0ID8gbWF4U2Nyb2xsIC0gZmluYWxWYWx1ZSA6IGZpbmFsVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlICo9IG5lZ2F0ZSA/IC0xIDogMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsVmFsdWUgPSBpc1JUTGlzWCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IubiA/IE1BVEgubWluKDAsIE1BVEgubWF4KG1heFNjcm9sbCwgZmluYWxWYWx1ZSkpIDogTUFUSC5tYXgoMCwgTUFUSC5taW4obWF4U2Nyb2xsLCBmaW5hbFZhbHVlKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbmFsVmFsdWUgPT09IGN1cnJTY3JvbGwgPyB1bmRlZmluZWQgOiBmaW5hbFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRQZXJBeGlzVmFsdWUodmFsdWUsIHZhbHVlSW50ZXJuYWxUeXBlLCBkZWZhdWx0VmFsdWUsIGFsbG93ZWRWYWx1ZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdERlZmF1bHQgPSBbZGVmYXVsdFZhbHVlLCBkZWZhdWx0VmFsdWVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWVUeXBlID0gdHlwZSh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZUFyckxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlQXJySXRlbTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdmFsdWUgY2FuIGJlIFsgc3RyaW5nLCBvciBhcnJheSBvZiB0d28gc3RyaW5ncyBdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZVR5cGUgPT0gdmFsdWVJbnRlcm5hbFR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gW3ZhbHVlLCB2YWx1ZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWVUeXBlID09IFRZUEVTLmEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlQXJyTGVuZ3RoID0gdmFsdWVbc3RyTGVuZ3RoXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZUFyckxlbmd0aCA+IDIgfHwgdmFsdWVBcnJMZW5ndGggPCAxKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gcmVzdWx0RGVmYXVsdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZUFyckxlbmd0aCA9PT0gMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVbMV0gPSBkZWZhdWx0VmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHZhbHVlQXJyTGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVBcnJJdGVtID0gdmFsdWVbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKHZhbHVlQXJySXRlbSkgIT0gdmFsdWVJbnRlcm5hbFR5cGUgfHwgIWNoZWNrU2V0dGluZ3NTdHJpbmdWYWx1ZSh2YWx1ZUFyckl0ZW0sIGFsbG93ZWRWYWx1ZXMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHJlc3VsdERlZmF1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZVR5cGUgPT0gVFlQRVMubylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gW3ZhbHVlW19zdHJYXSB8fCBkZWZhdWx0VmFsdWUsIHZhbHVlW19zdHJZXSB8fCBkZWZhdWx0VmFsdWVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHJlc3VsdERlZmF1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IHg6IHZhbHVlWzBdLCB5OiB2YWx1ZVsxXSB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZW5lcmF0ZU1hcmdpbihtYXJnaW5Ub3BSaWdodEJvdHRvbUxlZnRBcnJheSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJyVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJyVmFsdWVUeXBlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWVEaXJlY3Rpb25zID0gW19zdHJUb3AsIF9zdHJSaWdodCwgX3N0ckJvdHRvbSwgX3N0ckxlZnRdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbWFyZ2luVG9wUmlnaHRCb3R0b21MZWZ0QXJyYXlbc3RyTGVuZ3RoXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PT0gdmFsdWVEaXJlY3Rpb25zW3N0ckxlbmd0aF0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyVmFsdWUgPSBtYXJnaW5Ub3BSaWdodEJvdHRvbUxlZnRBcnJheVtpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJWYWx1ZVR5cGUgPSB0eXBlKGN1cnJWYWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyclZhbHVlVHlwZSA9PSBUWVBFUy5iKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGN1cnJWYWx1ZSA/IHBhcnNlVG9aZXJvT3JOdW1iZXIoZmluYWxFbGVtZW50LmNzcyhfc3RyTWFyZ2luTWludXMgKyB2YWx1ZURpcmVjdGlvbnNbaV0pKSA6IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGN1cnJWYWx1ZVR5cGUgPT0gVFlQRVMubiA/IGN1cnJWYWx1ZSA6IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAocG9zc2libGVFbGVtZW50SXNKUXVlcnkgfHwgcG9zc2libGVFbGVtZW50SXNIVE1MRWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2dldCBzZXR0aW5nc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWFyZ2luID0gY29vcmRpbmF0ZXNJc0VsZW1lbnRPYmogPyBjb29yZGluYXRlcy5tYXJnaW4gOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXhpcyA9IGNvb3JkaW5hdGVzSXNFbGVtZW50T2JqID8gY29vcmRpbmF0ZXMuYXhpcyA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGwgPSBjb29yZGluYXRlc0lzRWxlbWVudE9iaiA/IGNvb3JkaW5hdGVzLnNjcm9sbCA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBibG9jayA9IGNvb3JkaW5hdGVzSXNFbGVtZW50T2JqID8gY29vcmRpbmF0ZXMuYmxvY2sgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWFyZ2luRGVmYXVsdCA9IFswLCAwLCAwLCAwXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1hcmdpblR5cGUgPSB0eXBlKG1hcmdpbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtYXJnaW5MZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsRWxlbWVudCA9IHBvc3NpYmxlRWxlbWVudElzSlF1ZXJ5ID8gcG9zc2libGVFbGVtZW50IDogRlJBTUVXT1JLKHBvc3NpYmxlRWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluYWxFbGVtZW50W3N0ckxlbmd0aF0gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL21hcmdpbiBjYW4gYmUgWyBib29sZWFuLCBudW1iZXIsIGFycmF5IG9mIDIsIGFycmF5IG9mIDQsIG9iamVjdCBdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWFyZ2luVHlwZSA9PSBUWVBFUy5uIHx8IG1hcmdpblR5cGUgPT0gVFlQRVMuYilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBnZW5lcmF0ZU1hcmdpbihbbWFyZ2luLCBtYXJnaW4sIG1hcmdpbiwgbWFyZ2luXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChtYXJnaW5UeXBlID09IFRZUEVTLmEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW5MZW5ndGggPSBtYXJnaW5bc3RyTGVuZ3RoXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWFyZ2luTGVuZ3RoID09PSAyKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBnZW5lcmF0ZU1hcmdpbihbbWFyZ2luWzBdLCBtYXJnaW5bMV0sIG1hcmdpblswXSwgbWFyZ2luWzFdXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobWFyZ2luTGVuZ3RoID49IDQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IGdlbmVyYXRlTWFyZ2luKG1hcmdpbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBtYXJnaW5EZWZhdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobWFyZ2luVHlwZSA9PSBUWVBFUy5vKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IGdlbmVyYXRlTWFyZ2luKFttYXJnaW5bX3N0clRvcF0sIG1hcmdpbltfc3RyUmlnaHRdLCBtYXJnaW5bX3N0ckJvdHRvbV0sIG1hcmdpbltfc3RyTGVmdF1dKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBtYXJnaW5EZWZhdWx0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vYmxvY2sgPSB0eXBlKGJsb2NrKSA9PT0gVFlQRVMuYiA/IGJsb2NrID8gWyBzdHJOZWFyZXN0LCBzdHJCZWdpbiBdIDogWyBzdHJOZWFyZXN0LCBzdHJFbmQgXSA6IGJsb2NrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3NBeGlzID0gY2hlY2tTZXR0aW5nc1N0cmluZ1ZhbHVlKGF4aXMsIGVsZW1lbnRPYmpTZXR0aW5nc0F4aXNWYWx1ZXMpID8gYXhpcyA6ICd4eSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5nc1Njcm9sbCA9IGdldFBlckF4aXNWYWx1ZShzY3JvbGwsIFRZUEVTLnMsIHN0ckFsd2F5cywgZWxlbWVudE9ialNldHRpbmdzU2Nyb2xsVmFsdWVzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHRpbmdzQmxvY2sgPSBnZXRQZXJBeGlzVmFsdWUoYmxvY2ssIFRZUEVTLnMsIHN0ckJlZ2luLCBlbGVtZW50T2JqU2V0dGluZ3NCbG9ja1ZhbHVlcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5nc01hcmdpbiA9IG1hcmdpbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRTY3JvbGwgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbDogX3Njcm9sbEhvcml6b250YWxJbmZvLl9jdXJyZW50U2Nyb2xsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQ6IF9zY3JvbGxWZXJ0aWNhbEluZm8uX2N1cnJlbnRTY3JvbGxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2UgcGFkZGluZyBlbGVtZW50IGluc3RlYWQgb2Ygdmlld3BvcnQgZWxlbWVudCBiZWNhdXNlIHBhZGRpbmcgZWxlbWVudCBoYXMgbmV2ZXIgcGFkZGluZywgbWFyZ2luIG9yIHBvc2l0aW9uIGFwcGxpZWQuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRPZmZzZXQgPSBfcGFkZGluZ0VsZW1lbnQub2Zmc2V0KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9nZXQgY29vcmRpbmF0ZXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50T2Zmc2V0ID0gZmluYWxFbGVtZW50Lm9mZnNldCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRvTm90U2Nyb2xsID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IHNldHRpbmdzU2Nyb2xsLnggPT0gc3RyTmV2ZXIgfHwgc2V0dGluZ3NBeGlzID09IF9zdHJZLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IHNldHRpbmdzU2Nyb2xsLnkgPT0gc3RyTmV2ZXIgfHwgc2V0dGluZ3NBeGlzID09IF9zdHJYXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudE9mZnNldFtfc3RyVG9wXSAtPSBzZXR0aW5nc01hcmdpblswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRPZmZzZXRbX3N0ckxlZnRdIC09IHNldHRpbmdzTWFyZ2luWzNdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRTY3JvbGxDb29yZGluYXRlcyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBNQVRILnJvdW5kKGVsZW1lbnRPZmZzZXRbX3N0ckxlZnRdIC0gdmlld3BvcnRPZmZzZXRbX3N0ckxlZnRdICsgdmlld3BvcnRTY3JvbGwubCksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogTUFUSC5yb3VuZChlbGVtZW50T2Zmc2V0W19zdHJUb3BdIC0gdmlld3BvcnRPZmZzZXRbX3N0clRvcF0gKyB2aWV3cG9ydFNjcm9sbC50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNSVEwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9ydGxTY3JvbGxCZWhhdmlvci5uICYmICFfcnRsU2Nyb2xsQmVoYXZpb3IuaSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFNjcm9sbENvb3JkaW5hdGVzLnggPSBNQVRILnJvdW5kKHZpZXdwb3J0T2Zmc2V0W19zdHJMZWZ0XSAtIGVsZW1lbnRPZmZzZXRbX3N0ckxlZnRdICsgdmlld3BvcnRTY3JvbGwubCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9ydGxTY3JvbGxCZWhhdmlvci5uICYmIG5vcm1hbGl6ZVJUTClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFNjcm9sbENvb3JkaW5hdGVzLnggKj0gLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9ydGxTY3JvbGxCZWhhdmlvci5pICYmIG5vcm1hbGl6ZVJUTClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFNjcm9sbENvb3JkaW5hdGVzLnggPSBNQVRILnJvdW5kKHZpZXdwb3J0T2Zmc2V0W19zdHJMZWZ0XSAtIGVsZW1lbnRPZmZzZXRbX3N0ckxlZnRdICsgKF9zY3JvbGxIb3Jpem9udGFsSW5mby5fbWF4U2Nyb2xsIC0gdmlld3BvcnRTY3JvbGwubCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbWVhc3VyaW5nIGlzIHJlcXVpcmVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2V0dGluZ3NCbG9jay54ICE9IHN0ckJlZ2luIHx8IHNldHRpbmdzQmxvY2sueSAhPSBzdHJCZWdpbiB8fCBzZXR0aW5nc1Njcm9sbC54ID09IHN0cklmTmVlZGVkIHx8IHNldHRpbmdzU2Nyb2xsLnkgPT0gc3RySWZOZWVkZWQgfHwgX2lzUlRMKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1lYXN1cmluZ0VsbSA9IGZpbmFsRWxlbWVudFswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmF3RWxlbWVudFNpemUgPSBfc3VwcG9ydFRyYW5zZm9ybSA/IG1lYXN1cmluZ0VsbVtMRVhJQ09OLmJDUl0oKSA6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG1lYXN1cmluZ0VsbVtMRVhJQ09OLm9XXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBtZWFzdXJpbmdFbG1bTEVYSUNPTi5vSF1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50U2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogcmF3RWxlbWVudFNpemVbX3N0cldpZHRoXSArIHNldHRpbmdzTWFyZ2luWzNdICsgc2V0dGluZ3NNYXJnaW5bMV0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IHJhd0VsZW1lbnRTaXplW19zdHJIZWlnaHRdICsgc2V0dGluZ3NNYXJnaW5bMF0gKyBzZXR0aW5nc01hcmdpblsyXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZpbmFsaXplQmxvY2sgPSBmdW5jdGlvbiAoaXNYKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhpc1gpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2ggPSB2YXJzLl93X2g7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsdCA9IHZhcnMuX2xlZnRfdG9wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgeHkgPSB2YXJzLl94X3k7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBibG9ja0lzRW5kID0gc2V0dGluZ3NCbG9ja1t4eV0gPT0gKGlzWCA/IF9pc1JUTCA/IHN0ckJlZ2luIDogc3RyRW5kIDogc3RyRW5kKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGJsb2NrSXNDZW50ZXIgPSBzZXR0aW5nc0Jsb2NrW3h5XSA9PSBzdHJDZW50ZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBibG9ja0lzTmVhcmVzdCA9IHNldHRpbmdzQmxvY2tbeHldID09IHN0ck5lYXJlc3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxOZXZlciA9IHNldHRpbmdzU2Nyb2xsW3h5XSA9PSBzdHJOZXZlcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbElmTmVlZGVkID0gc2V0dGluZ3NTY3JvbGxbeHldID09IHN0cklmTmVlZGVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdnBTaXplID0gX3ZpZXdwb3J0U2l6ZVt3aF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2cE9mZnNldCA9IHZpZXdwb3J0T2Zmc2V0W2x0XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsU2l6ZSA9IGVsZW1lbnRTaXplW3doXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsT2Zmc2V0ID0gZWxlbWVudE9mZnNldFtsdF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkaXZpZGUgPSBibG9ja0lzQ2VudGVyID8gMiA6IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50Q2VudGVyT2Zmc2V0ID0gZWxPZmZzZXQgKyAoZWxTaXplIC8gMik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2aWV3cG9ydENlbnRlck9mZnNldCA9IHZwT2Zmc2V0ICsgKHZwU2l6ZSAvIDIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNJblZpZXcgPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxTaXplIDw9IHZwU2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgZWxPZmZzZXQgPj0gdnBPZmZzZXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGVsT2Zmc2V0ICsgZWxTaXplIDw9IHZwT2Zmc2V0ICsgdnBTaXplO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbE5ldmVyKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9Ob3RTY3JvbGxbeHldID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoIWRvTm90U2Nyb2xsW3h5XSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJsb2NrSXNOZWFyZXN0IHx8IHNjcm9sbElmTmVlZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9Ob3RTY3JvbGxbeHldID0gc2Nyb2xsSWZOZWVkZWQgPyBpc0luVmlldyA6IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrSXNFbmQgPSBlbFNpemUgPCB2cFNpemUgPyBlbGVtZW50Q2VudGVyT2Zmc2V0ID4gdmlld3BvcnRDZW50ZXJPZmZzZXQgOiBlbGVtZW50Q2VudGVyT2Zmc2V0IDwgdmlld3BvcnRDZW50ZXJPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U2Nyb2xsQ29vcmRpbmF0ZXNbeHldIC09IGJsb2NrSXNFbmQgfHwgYmxvY2tJc0NlbnRlciA/ICgodnBTaXplIC8gZGl2aWRlKSAtIChlbFNpemUgLyBkaXZpZGUpKSAqIChpc1ggJiYgX2lzUlRMICYmIG5vcm1hbGl6ZVJUTCA/IC0xIDogMSkgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbGl6ZUJsb2NrKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsaXplQmxvY2soZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb05vdFNjcm9sbC55KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBlbGVtZW50U2Nyb2xsQ29vcmRpbmF0ZXMueTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb05vdFNjcm9sbC54KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBlbGVtZW50U2Nyb2xsQ29vcmRpbmF0ZXMueDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlcyA9IGVsZW1lbnRTY3JvbGxDb29yZGluYXRlcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZmluYWxTY3JvbGxbX3N0clNjcm9sbExlZnRdID0gZ2V0RmluYWxTY3JvbGwodHJ1ZSwgZ2V0UmF3U2Nyb2xsKHRydWUsIGNvb3JkaW5hdGVzKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZmluYWxTY3JvbGxbX3N0clNjcm9sbFRvcF0gPSBnZXRGaW5hbFNjcm9sbChmYWxzZSwgZ2V0UmF3U2Nyb2xsKGZhbHNlLCBjb29yZGluYXRlcykpO1xyXG4gICAgICAgICAgICAgICAgICAgIGRvU2Nyb2xsTGVmdCA9IGZpbmFsU2Nyb2xsW19zdHJTY3JvbGxMZWZ0XSAhPT0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgIGRvU2Nyb2xsVG9wID0gZmluYWxTY3JvbGxbX3N0clNjcm9sbFRvcF0gIT09IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChkb1Njcm9sbExlZnQgfHwgZG9TY3JvbGxUb3ApICYmIChkdXJhdGlvbiA+IDAgfHwgZHVyYXRpb25Jc09iamVjdCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGR1cmF0aW9uSXNPYmplY3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uLmNvbXBsZXRlID0gcHJveHlDb21wbGV0ZUNhbGxiYWNrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudC5hbmltYXRlKGZpbmFsU2Nyb2xsLCBkdXJhdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25PcHRpb25zID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBkdXJhdGlvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZTogcHJveHlDb21wbGV0ZUNhbGxiYWNrXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkuaXNBKGVhc2luZykgfHwgRlJBTUVXT1JLLmlzUGxhaW5PYmplY3QoZWFzaW5nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpYWxFYXNpbmdbX3N0clNjcm9sbExlZnRdID0gZWFzaW5nWzBdIHx8IGVhc2luZy54O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpYWxFYXNpbmdbX3N0clNjcm9sbFRvcF0gPSBlYXNpbmdbMV0gfHwgZWFzaW5nLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uT3B0aW9ucy5zcGVjaWFsRWFzaW5nID0gc3BlY2lhbEVhc2luZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbk9wdGlvbnMuZWFzaW5nID0gZWFzaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudC5hbmltYXRlKGZpbmFsU2Nyb2xsLCBhbmltYXRpb25PcHRpb25zKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvU2Nyb2xsTGVmdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKGZpbmFsU2Nyb2xsW19zdHJTY3JvbGxMZWZ0XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1Njcm9sbFRvcClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbX3N0clNjcm9sbFRvcF0oZmluYWxTY3JvbGxbX3N0clNjcm9sbFRvcF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVTY3JvbGxiYXJJbmZvcygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBTdG9wcyBhbGwgc2Nyb2xsIGFuaW1hdGlvbnMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIGN1cnJlbnQgT3ZlcmxheVNjcm9sbGJhcnMgaW5zdGFuY2UgKGZvciBjaGFpbmluZykuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLnNjcm9sbFN0b3AgPSBmdW5jdGlvbiAocGFyYW0xLCBwYXJhbTIsIHBhcmFtMykge1xyXG4gICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuc3RvcChwYXJhbTEsIHBhcmFtMiwgcGFyYW0zKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2Jhc2U7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyBhbGwgcmVsZXZhbnQgZWxlbWVudHMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQgd2hpY2ggc2hhbGwgYmUgcmV0dXJuZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e3RhcmdldDogKiwgaG9zdDogKiwgcGFkZGluZzogKiwgdmlld3BvcnQ6ICosIGNvbnRlbnQ6ICosIHNjcm9sbGJhckhvcml6b250YWw6IHtzY3JvbGxiYXI6ICosIHRyYWNrOiAqLCBoYW5kbGU6ICp9LCBzY3JvbGxiYXJWZXJ0aWNhbDoge3Njcm9sbGJhcjogKiwgdHJhY2s6ICosIGhhbmRsZTogKn0sIHNjcm9sbGJhckNvcm5lcjogKn0gfCAqfVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5nZXRFbGVtZW50cyA9IGZ1bmN0aW9uIChlbGVtZW50TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvYmogPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldDogX3RhcmdldEVsZW1lbnROYXRpdmUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvc3Q6IF9ob3N0RWxlbWVudE5hdGl2ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogX3BhZGRpbmdFbGVtZW50TmF0aXZlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydDogX3ZpZXdwb3J0RWxlbWVudE5hdGl2ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogX2NvbnRlbnRFbGVtZW50TmF0aXZlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJIb3Jpem9udGFsOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXI6IF9zY3JvbGxiYXJIb3Jpem9udGFsRWxlbWVudFswXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrOiBfc2Nyb2xsYmFySG9yaXpvbnRhbFRyYWNrRWxlbWVudFswXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZTogX3Njcm9sbGJhckhvcml6b250YWxIYW5kbGVFbGVtZW50WzBdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZlcnRpY2FsOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXI6IF9zY3JvbGxiYXJWZXJ0aWNhbEVsZW1lbnRbMF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFjazogX3Njcm9sbGJhclZlcnRpY2FsVHJhY2tFbGVtZW50WzBdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlOiBfc2Nyb2xsYmFyVmVydGljYWxIYW5kbGVFbGVtZW50WzBdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhckNvcm5lcjogX3Njcm9sbGJhckNvcm5lckVsZW1lbnRbMF1cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlKGVsZW1lbnROYW1lKSA9PSBUWVBFUy5zID8gZ2V0T2JqZWN0UHJvcFZhbChvYmosIGVsZW1lbnROYW1lKSA6IG9iajtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZXR1cm5zIGEgb2JqZWN0IHdoaWNoIGRlc2NyaWJlcyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGlzIGluc3RhbmNlLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHN0YXRlUHJvcGVydHkgQSBzcGVjaWZpYyBwcm9wZXJ0eSBmcm9tIHRoZSBzdGF0ZSBvYmplY3Qgd2hpY2ggc2hhbGwgYmUgcmV0dXJuZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e3dpZHRoQXV0bywgaGVpZ2h0QXV0bywgb3ZlcmZsb3dBbW91bnQsIGhpZGVPdmVyZmxvdywgaGFzT3ZlcmZsb3csIGNvbnRlbnRTY3JvbGxTaXplLCB2aWV3cG9ydFNpemUsIGhvc3RTaXplLCBhdXRvVXBkYXRlfSB8ICp9XHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLmdldFN0YXRlID0gZnVuY3Rpb24gKHN0YXRlUHJvcGVydHkpIHtcclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBwcmVwYXJlKG9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUZSQU1FV09SSy5pc1BsYWluT2JqZWN0KG9iaikpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2JqO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXh0ZW5kZWQgPSBleHRlbmREZWVwKHt9LCBvYmopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hhbmdlUHJvcGVydHlOYW1lID0gZnVuY3Rpb24gKGZyb20sIHRvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXh0ZW5kZWRbTEVYSUNPTi5oT1BdKGZyb20pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kZWRbdG9dID0gZXh0ZW5kZWRbZnJvbV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGV4dGVuZGVkW2Zyb21dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VQcm9wZXJ0eU5hbWUoJ3cnLCBfc3RyV2lkdGgpOyAvL2NoYW5nZSB3IHRvIHdpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZVByb3BlcnR5TmFtZSgnaCcsIF9zdHJIZWlnaHQpOyAvL2NoYW5nZSBoIHRvIGhlaWdodFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgZXh0ZW5kZWQuYzsgLy9kZWxldGUgYyAodGhlICdjaGFuZ2VkJyBwcm9wKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXh0ZW5kZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb2JqID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZXN0cm95ZWQ6ICEhcHJlcGFyZShfZGVzdHJveWVkKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2xlZXBpbmc6ICEhcHJlcGFyZShfc2xlZXBpbmcpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvVXBkYXRlOiBwcmVwYXJlKCFfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aEF1dG86IHByZXBhcmUoX3dpZHRoQXV0b0NhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0QXV0bzogcHJlcGFyZShfaGVpZ2h0QXV0b0NhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogcHJlcGFyZShfY3NzUGFkZGluZ0NhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmZsb3dBbW91bnQ6IHByZXBhcmUoX292ZXJmbG93QW1vdW50Q2FjaGUpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBoaWRlT3ZlcmZsb3c6IHByZXBhcmUoX2hpZGVPdmVyZmxvd0NhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzT3ZlcmZsb3c6IHByZXBhcmUoX2hhc092ZXJmbG93Q2FjaGUpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50U2Nyb2xsU2l6ZTogcHJlcGFyZShfY29udGVudFNjcm9sbFNpemVDYWNoZSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0U2l6ZTogcHJlcGFyZShfdmlld3BvcnRTaXplKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaG9zdFNpemU6IHByZXBhcmUoX2hvc3RTaXplQ2FjaGUpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudE1peGVkOiBwcmVwYXJlKF9kb2N1bWVudE1peGVkKVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHR5cGUoc3RhdGVQcm9wZXJ0eSkgPT0gVFlQRVMucyA/IGdldE9iamVjdFByb3BWYWwob2JqLCBzdGF0ZVByb3BlcnR5KSA6IG9iajtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIGFsbCBvciBzcGVjaWZpYyBleHRlbnNpb24gaW5zdGFuY2UuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZXh0TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIGZyb20gd2hpY2ggdGhlIGluc3RhbmNlIHNoYWxsIGJlIGdvdC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIGluc3RhbmNlIG9mIHRoZSBleHRlbnNpb24gd2l0aCB0aGUgZ2l2ZW4gbmFtZSBvciB1bmRlZmluZWQgaWYgdGhlIGluc3RhbmNlIGNvdWxkbid0IGJlIGZvdW5kLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5leHQgPSBmdW5jdGlvbiAoZXh0TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByaXZhdGVNZXRob2RzID0gX2V4dGVuc2lvbnNQcml2YXRlTWV0aG9kcy5zcGxpdCgnICcpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShleHROYW1lKSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZXh0ZW5zaW9uc1tMRVhJQ09OLmhPUF0oZXh0TmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGV4dGVuZERlZXAoe30sIF9leHRlbnNpb25zW2V4dE5hbWVdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgcHJpdmF0ZU1ldGhvZHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHJlc3VsdFtwcml2YXRlTWV0aG9kc1tpXV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgaW4gX2V4dGVuc2lvbnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSBleHRlbmREZWVwKHt9LCBfYmFzZS5leHQoaSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEFkZHMgYSBleHRlbnNpb24gdG8gdGhpcyBpbnN0YW5jZS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBleHROYW1lIFRoZSBuYW1lIG9mIHRoZSBleHRlbnNpb24gd2hpY2ggc2hhbGwgYmUgYWRkZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZXh0ZW5zaW9uT3B0aW9ucyBUaGUgZXh0ZW5zaW9uIG9wdGlvbnMgd2hpY2ggc2hhbGwgYmUgdXNlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIGluc3RhbmNlIG9mIHRoZSBhZGRlZCBleHRlbnNpb24gb3IgdW5kZWZpbmVkIGlmIHRoZSBleHRlbnNpb24gY291bGRuJ3QgYmUgYWRkZWQgcHJvcGVybHkuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLmFkZEV4dCA9IGZ1bmN0aW9uIChleHROYW1lLCBleHRlbnNpb25PcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlZ2lzdGVyZWRFeHRlbnNpb25PYmogPSBfcGx1Z2luLmV4dGVuc2lvbihleHROYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlQWRkZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlQ29udHJhY3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRyYWN0UmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250cmFjdEZ1bGZpbGxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlZ2lzdGVyZWRFeHRlbnNpb25PYmopIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfZXh0ZW5zaW9uc1tMRVhJQ09OLmhPUF0oZXh0TmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlID0gcmVnaXN0ZXJlZEV4dGVuc2lvbk9iai5leHRlbnNpb25GYWN0b3J5LmNhbGwoX2Jhc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kRGVlcCh7fSwgcmVnaXN0ZXJlZEV4dGVuc2lvbk9iai5kZWZhdWx0T3B0aW9ucyksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQ29udHJhY3QgPSBpbnN0YW5jZS5jb250cmFjdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShpbnN0YW5jZUNvbnRyYWN0KSA9PSBUWVBFUy5mKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyYWN0UmVzdWx0ID0gaW5zdGFuY2VDb250cmFjdCh3aW5kb3cpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cmFjdEZ1bGZpbGxlZCA9IHR5cGUoY29udHJhY3RSZXN1bHQpID09IFRZUEVTLmIgPyBjb250cmFjdFJlc3VsdCA6IGNvbnRyYWN0RnVsZmlsbGVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29udHJhY3RGdWxmaWxsZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2V4dGVuc2lvbnNbZXh0TmFtZV0gPSBpbnN0YW5jZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VBZGRlZCA9IGluc3RhbmNlLmFkZGVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShpbnN0YW5jZUFkZGVkKSA9PSBUWVBFUy5mKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VBZGRlZChleHRlbnNpb25PcHRpb25zKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfYmFzZS5leHQoZXh0TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfYmFzZS5leHQoZXh0TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiQSBleHRlbnNpb24gd2l0aCB0aGUgbmFtZSBcXFwiXCIgKyBleHROYW1lICsgXCJcXFwiIGlzbid0IHJlZ2lzdGVyZWQuXCIpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJlbW92ZXMgYSBleHRlbnNpb24gZnJvbSB0aGlzIGluc3RhbmNlLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV4dE5hbWUgVGhlIG5hbWUgb2YgdGhlIGV4dGVuc2lvbiB3aGljaCBzaGFsbCBiZSByZW1vdmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGV4dGVuc2lvbiB3YXMgcmVtb3ZlZCwgZmFsc2Ugb3RoZXJ3aXNlIGUuZy4gaWYgdGhlIGV4dGVuc2lvbiB3YXNuJ3QgYWRkZWQgYmVmb3JlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5yZW1vdmVFeHQgPSBmdW5jdGlvbiAoZXh0TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZSA9IF9leHRlbnNpb25zW2V4dE5hbWVdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZVJlbW92ZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBfZXh0ZW5zaW9uc1tleHROYW1lXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlUmVtb3ZlZCA9IGluc3RhbmNlLnJlbW92ZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKGluc3RhbmNlUmVtb3ZlZCkgPT0gVFlQRVMuZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlUmVtb3ZlZCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDb25zdHJ1Y3RzIHRoZSBwbHVnaW4uXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0RWxlbWVudCBUaGUgZWxlbWVudCB0byB3aGljaCB0aGUgcGx1Z2luIHNoYWxsIGJlIGFwcGxpZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyBUaGUgaW5pdGlhbCBvcHRpb25zIG9mIHRoZSBwbHVnaW4uXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZXh0ZW5zaW9ucyBUaGUgZXh0ZW5zaW9uKHMpIHdoaWNoIHNoYWxsIGJlIGFkZGVkIHJpZ2h0IGFmdGVyIHRoZSBpbml0aWFsaXphdGlvbi5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBwbHVnaW4gd2FzIHN1Y2Nlc3NmdWxseSBpbml0aWFsaXplZCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBjb25zdHJ1Y3QodGFyZ2V0RWxlbWVudCwgb3B0aW9ucywgZXh0ZW5zaW9ucykge1xyXG4gICAgICAgICAgICAgICAgICAgIF9kZWZhdWx0T3B0aW9ucyA9IGdsb2JhbHMuZGVmYXVsdE9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICAgICAgX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcgPSBnbG9iYWxzLm5hdGl2ZVNjcm9sbGJhclN0eWxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX25hdGl2ZVNjcm9sbGJhclNpemUgPSBleHRlbmREZWVwKHt9LCBnbG9iYWxzLm5hdGl2ZVNjcm9sbGJhclNpemUpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkID0gZXh0ZW5kRGVlcCh7fSwgZ2xvYmFscy5uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkKTtcclxuICAgICAgICAgICAgICAgICAgICBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZSA9IGV4dGVuZERlZXAoe30sIGdsb2JhbHMub3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3J0bFNjcm9sbEJlaGF2aW9yID0gZXh0ZW5kRGVlcCh7fSwgZ2xvYmFscy5ydGxTY3JvbGxCZWhhdmlvcik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcGFyc2UgJiBzZXQgb3B0aW9ucyBidXQgZG9uJ3QgdXBkYXRlXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0T3B0aW9ucyhleHRlbmREZWVwKHt9LCBfZGVmYXVsdE9wdGlvbnMsIG9wdGlvbnMpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgX2Nzc0NhbGMgPSBnbG9iYWxzLmNzc0NhbGM7XHJcbiAgICAgICAgICAgICAgICAgICAgX21zaWVWZXJzaW9uID0gZ2xvYmFscy5tc2llO1xyXG4gICAgICAgICAgICAgICAgICAgIF9hdXRvVXBkYXRlUmVjb21tZW5kZWQgPSBnbG9iYWxzLmF1dG9VcGRhdGVSZWNvbW1lbmRlZDtcclxuICAgICAgICAgICAgICAgICAgICBfc3VwcG9ydFRyYW5zaXRpb24gPSBnbG9iYWxzLnN1cHBvcnRUcmFuc2l0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zdXBwb3J0VHJhbnNmb3JtID0gZ2xvYmFscy5zdXBwb3J0VHJhbnNmb3JtO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zdXBwb3J0UGFzc2l2ZUV2ZW50cyA9IGdsb2JhbHMuc3VwcG9ydFBhc3NpdmVFdmVudHM7XHJcbiAgICAgICAgICAgICAgICAgICAgX3N1cHBvcnRSZXNpemVPYnNlcnZlciA9IGdsb2JhbHMuc3VwcG9ydFJlc2l6ZU9ic2VydmVyO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zdXBwb3J0TXV0YXRpb25PYnNlcnZlciA9IGdsb2JhbHMuc3VwcG9ydE11dGF0aW9uT2JzZXJ2ZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc3RyaWN0ZWRNZWFzdXJpbmcgPSBnbG9iYWxzLnJlc3RyaWN0ZWRNZWFzdXJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2RvY3VtZW50RWxlbWVudCA9IEZSQU1FV09SSyh0YXJnZXRFbGVtZW50Lm93bmVyRG9jdW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9kb2N1bWVudEVsZW1lbnROYXRpdmUgPSBfZG9jdW1lbnRFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIF93aW5kb3dFbGVtZW50ID0gRlJBTUVXT1JLKF9kb2N1bWVudEVsZW1lbnROYXRpdmUuZGVmYXVsdFZpZXcgfHwgX2RvY3VtZW50RWxlbWVudE5hdGl2ZS5wYXJlbnRXaW5kb3cpO1xyXG4gICAgICAgICAgICAgICAgICAgIF93aW5kb3dFbGVtZW50TmF0aXZlID0gX3dpbmRvd0VsZW1lbnRbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgX2h0bWxFbGVtZW50ID0gZmluZEZpcnN0KF9kb2N1bWVudEVsZW1lbnQsICdodG1sJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2JvZHlFbGVtZW50ID0gZmluZEZpcnN0KF9odG1sRWxlbWVudCwgJ2JvZHknKTtcclxuICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0RWxlbWVudCA9IEZSQU1FV09SSyh0YXJnZXRFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0RWxlbWVudE5hdGl2ZSA9IF90YXJnZXRFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIF9pc1RleHRhcmVhID0gX3RhcmdldEVsZW1lbnQuaXMoJ3RleHRhcmVhJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2lzQm9keSA9IF90YXJnZXRFbGVtZW50LmlzKCdib2R5Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2RvY3VtZW50TWl4ZWQgPSBfZG9jdW1lbnRFbGVtZW50TmF0aXZlICE9PSBkb2N1bWVudDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLyogT24gYSBkaXYgRWxlbWVudCBUaGUgaWYgY2hlY2tzIG9ubHkgd2hldGhlcjpcclxuICAgICAgICAgICAgICAgICAgICAgKiAtIHRoZSB0YXJnZXRFbGVtZW50IGhhcyB0aGUgY2xhc3MgXCJvcy1ob3N0XCJcclxuICAgICAgICAgICAgICAgICAgICAgKiAtIHRoZSB0YXJnZXRFbGVtZW50IGhhcyBhIGEgY2hpbGQgd2l0aCB0aGUgY2xhc3MgXCJvcy1wYWRkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICAgICAgICAgKiBJZiB0aGF0J3MgdGhlIGNhc2UsIGl0cyBhc3N1bWVkIHRoZSBET00gaGFzIGFscmVhZHkgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6XHJcbiAgICAgICAgICAgICAgICAgICAgICogKFRoZSBcIi5vcy1ob3N0XCIgZWxlbWVudCBpcyB0aGUgdGFyZ2V0RWxlbWVudClcclxuICAgICAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICAgICAqICA8ZGl2IGNsYXNzPVwib3MtaG9zdFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXJlc2l6ZS1vYnNlcnZlci1ob3N0XCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3MtcGFkZGluZ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy12aWV3cG9ydFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib3MtY29udGVudFwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyIG9zLXNjcm9sbGJhci1ob3Jpem9udGFsIFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItdHJhY2tcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhci1oYW5kbGVcIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhciBvcy1zY3JvbGxiYXItdmVydGljYWxcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLXRyYWNrXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItaGFuZGxlXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItY29ybmVyXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgICAgICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gICAgICAgICAgICAgICAgICAgICAqIFxyXG4gICAgICAgICAgICAgICAgICAgICAqIE9uIGEgVGV4dGFyZWEgRWxlbWVudCBUaGUgaWYgY2hlY2tzIG9ubHkgd2hldGhlcjpcclxuICAgICAgICAgICAgICAgICAgICAgKiAtIHRoZSB0YXJnZXRFbGVtZW50IGhhcyB0aGUgY2xhc3MgXCJvcy10ZXh0YXJlYVwiIFxyXG4gICAgICAgICAgICAgICAgICAgICAqIC0gdGhlIHRhcmdldEVsZW1lbnQgaXMgaW5zaWRlIGEgZWxlbWVudCB3aXRoIHRoZSBjbGFzcyBcIm9zLWNvbnRlbnRcIiBcclxuICAgICAgICAgICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICAgICAgICAgKiBJZiB0aGF0J3MgdGhlIGNhc2UsIGl0cyBhc3N1bWVkIHRoZSBET00gaGFzIGFscmVhZHkgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6XHJcbiAgICAgICAgICAgICAgICAgICAgICogKFRoZSBcIi5vcy10ZXh0YXJlYVwiICh0ZXh0YXJlYSkgZWxlbWVudCBpcyB0aGUgdGFyZ2V0RWxlbWVudClcclxuICAgICAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICAgICAqICA8ZGl2IGNsYXNzPVwib3MtaG9zdC10ZXh0YXJlYVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXJlc2l6ZS1vYnNlcnZlci1ob3N0XCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3MtcGFkZGluZyBvcy10ZXh0LWluaGVyaXRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtdmlld3BvcnQgb3MtdGV4dC1pbmhlcml0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1jb250ZW50IG9zLXRleHQtaW5oZXJpdFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLXRleHRhcmVhLWNvdmVyXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgICA8dGV4dGFyZWEgY2xhc3M9XCJvcy10ZXh0YXJlYSBvcy10ZXh0LWluaGVyaXRcIj48L3RleHRhcmVhPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhciBvcy1zY3JvbGxiYXItaG9yaXpvbnRhbCBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLXRyYWNrXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItaGFuZGxlXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXIgb3Mtc2Nyb2xsYmFyLXZlcnRpY2FsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhci10cmFja1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLWhhbmRsZVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLWNvcm5lclwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICBfZG9tRXhpc3RzID0gX2lzVGV4dGFyZWFcclxuICAgICAgICAgICAgICAgICAgICAgICAgPyBfdGFyZ2V0RWxlbWVudC5oYXNDbGFzcyhfY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50KSAmJiBfdGFyZ2V0RWxlbWVudC5wYXJlbnQoKS5oYXNDbGFzcyhfY2xhc3NOYW1lQ29udGVudEVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogX3RhcmdldEVsZW1lbnQuaGFzQ2xhc3MoX2NsYXNzTmFtZUhvc3RFbGVtZW50KSAmJiBfdGFyZ2V0RWxlbWVudC5jaGlsZHJlbihfc3RyRG90ICsgX2NsYXNzTmFtZVBhZGRpbmdFbGVtZW50KVtMRVhJQ09OLmxdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgaW5pdEJvZHlTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJvZHlNb3VzZVRvdWNoRG93bkxpc3RlbmVyO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NoZWNrIGlmIHRoZSBwbHVnaW4gaGFzbid0IHRvIGJlIGluaXRpYWxpemVkXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSAmJiAhX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMubmF0aXZlU2Nyb2xsYmFyc092ZXJsYWlkLmluaXRpYWxpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25Jbml0aWFsaXphdGlvbldpdGhkcmF3bicpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2RvbUV4aXN0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBTdHJ1Y3R1cmVET00odHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhcnNET00odHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhckNvcm5lckRPTSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Rlc3Ryb3llZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zbGVlcGluZyA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2Jhc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0Qm9keVNjcm9sbCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0Qm9keVNjcm9sbC5sID0gTUFUSC5tYXgoX3RhcmdldEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKCksIF9odG1sRWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oKSwgX3dpbmRvd0VsZW1lbnRbX3N0clNjcm9sbExlZnRdKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0Qm9keVNjcm9sbC50ID0gTUFUSC5tYXgoX3RhcmdldEVsZW1lbnRbX3N0clNjcm9sbFRvcF0oKSwgX2h0bWxFbGVtZW50W19zdHJTY3JvbGxUb3BdKCksIF93aW5kb3dFbGVtZW50W19zdHJTY3JvbGxUb3BdKCkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keU1vdXNlVG91Y2hEb3duTGlzdGVuZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50LnJlbW92ZUF0dHIoTEVYSUNPTi50aSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF92aWV3cG9ydEVsZW1lbnQsIF9zdHJNb3VzZVRvdWNoRG93bkV2ZW50LCBib2R5TW91c2VUb3VjaERvd25MaXN0ZW5lciwgdHJ1ZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYnVpbGQgT3ZlcmxheVNjcm9sbGJhcnMgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBTdHJ1Y3R1cmVET00oKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhcnNET00oKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhckNvcm5lckRPTSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NyZWF0ZSBPdmVybGF5U2Nyb2xsYmFycyBldmVudHNcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFN0cnVjdHVyZUV2ZW50cygpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU2Nyb2xsYmFyRXZlbnRzKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU2Nyb2xsYmFyRXZlbnRzKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhckNvcm5lckV2ZW50cygpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NyZWF0ZSBtdXRhdGlvbiBvYnNlcnZlcnNcclxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVNdXRhdGlvbk9ic2VydmVycygpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2J1aWxkIHJlc2l6ZSBvYnNlcnZlciBmb3IgdGhlIGhvc3QgZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzaXplT2JzZXJ2ZXIoX3NpemVPYnNlcnZlckVsZW1lbnQsIGhvc3RPblJlc2l6ZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2FwcGx5IHRoZSBib2R5IHNjcm9sbCB0byBoYW5kbGUgaXQgcmlnaHQgaW4gdGhlIHVwZGF0ZSBtZXRob2RcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oaW5pdEJvZHlTY3JvbGwubClbX3N0clNjcm9sbFRvcF0oaW5pdEJvZHlTY3JvbGwudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NldCB0aGUgZm9jdXMgb24gdGhlIHZpZXdwb3J0IGVsZW1lbnQgc28geW91IGRvbnQgaGF2ZSB0byBjbGljayBvbiB0aGUgcGFnZSB0byB1c2Uga2V5Ym9hcmQga2V5cyAodXAgLyBkb3duIC8gc3BhY2UpIGZvciBzY3JvbGxpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT0gdGFyZ2V0RWxlbWVudCAmJiBfdmlld3BvcnRFbGVtZW50TmF0aXZlLmZvY3VzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3NldCBhIHRhYmluZGV4IHRvIG1ha2UgdGhlIHZpZXdwb3J0RWxlbWVudCBmb2N1c2FibGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuYXR0cihMRVhJQ09OLnRpLCAnLTEnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnROYXRpdmUuZm9jdXMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0aGUgdGFiaW5kZXggaGFzIHRvIGJlIHJlbW92ZWQgZHVlIHRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogSWYgeW91IHNldCB0aGUgdGFiaW5kZXggYXR0cmlidXRlIG9uIGFuIDxkaXY+LCB0aGVuIGl0cyBjaGlsZCBjb250ZW50IGNhbm5vdCBiZSBzY3JvbGxlZCB3aXRoIHRoZSBhcnJvdyBrZXlzIHVubGVzcyB5b3Ugc2V0IHRhYmluZGV4IG9uIHRoZSBjb250ZW50LCB0b29cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvR2xvYmFsX2F0dHJpYnV0ZXMvdGFiaW5kZXhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfdmlld3BvcnRFbGVtZW50LCBfc3RyTW91c2VUb3VjaERvd25FdmVudCwgYm9keU1vdXNlVG91Y2hEb3duTGlzdGVuZXIsIGZhbHNlLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy91cGRhdGUgZm9yIHRoZSBmaXJzdCB0aW1lICYgaW5pdGlhbGl6ZSBjYWNoZVxyXG4gICAgICAgICAgICAgICAgICAgIF9iYXNlLnVwZGF0ZShfc3RyQXV0byk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vdGhlIHBsdWdpbiBpcyBpbml0aWFsaXplZCBub3chXHJcbiAgICAgICAgICAgICAgICAgICAgX2luaXRpYWxpemVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvbkluaXRpYWxpemVkJyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vY2FsbCBhbGwgY2FsbGJhY2tzIHdoaWNoIHdvdWxkIGZpcmUgYmVmb3JlIHRoZSBpbml0aWFsaXplZCB3YXMgY29tcGxldGVcclxuICAgICAgICAgICAgICAgICAgICBlYWNoKF9jYWxsYmFja3NJbml0UWV1ZXVlLCBmdW5jdGlvbiAoaW5kZXgsIHZhbHVlKSB7IGRpc3BhdGNoQ2FsbGJhY2sodmFsdWUubiwgdmFsdWUuYSk7IH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jYWxsYmFja3NJbml0UWV1ZXVlID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYWRkIGV4dGVuc2lvbnNcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShleHRlbnNpb25zKSA9PSBUWVBFUy5zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zID0gW2V4dGVuc2lvbnNdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChDT01QQVRJQklMSVRZLmlzQShleHRlbnNpb25zKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaChleHRlbnNpb25zLCBmdW5jdGlvbiAoaW5kZXgsIHZhbHVlKSB7IF9iYXNlLmFkZEV4dCh2YWx1ZSk7IH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKEZSQU1FV09SSy5pc1BsYWluT2JqZWN0KGV4dGVuc2lvbnMpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlYWNoKGV4dGVuc2lvbnMsIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7IF9iYXNlLmFkZEV4dChrZXksIHZhbHVlKTsgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYWRkIHRoZSB0cmFuc2l0aW9uIGNsYXNzIGZvciB0cmFuc2l0aW9ucyBBRlRFUiB0aGUgZmlyc3QgdXBkYXRlICYgQUZURVIgdGhlIGFwcGxpZWQgZXh0ZW5zaW9ucyAoZm9yIHByZXZlbnRpbmcgdW53YW50ZWQgdHJhbnNpdGlvbnMpXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydFRyYW5zaXRpb24gJiYgIV9kZXN0cm95ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0VHJhbnNpdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgMzMzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9iYXNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChfcGx1Z2luLnZhbGlkKGNvbnN0cnVjdChwbHVnaW5UYXJnZXRFbGVtZW50LCBvcHRpb25zLCBleHRlbnNpb25zKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBJTlNUQU5DRVMocGx1Z2luVGFyZ2V0RWxlbWVudCwgX2Jhc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBfYmFzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3IE92ZXJsYXlTY3JvbGxiYXJzSW5zdGFuY2Ugb2JqZWN0IG9yIGNoYW5nZXMgb3B0aW9ucyBpZiBhbHJlYWR5IGluaXRpYWxpemVkIG9yIHJldHVybnMgdGhlIGN1cnJlbnQgaW5zdGFuY2UuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBwbHVnaW5UYXJnZXRFbGVtZW50cyBUaGUgZWxlbWVudHMgdG8gd2hpY2ggdGhlIFBsdWdpbiBzaGFsbCBiZSBpbml0aWFsaXplZC5cclxuICAgICAgICAgICAgICogQHBhcmFtIG9wdGlvbnMgVGhlIGN1c3RvbSBvcHRpb25zIHdpdGggd2hpY2ggdGhlIHBsdWdpbiBzaGFsbCBiZSBpbml0aWFsaXplZC5cclxuICAgICAgICAgICAgICogQHBhcmFtIGV4dGVuc2lvbnMgVGhlIGV4dGVuc2lvbihzKSB3aGljaCBzaGFsbCBiZSBhZGRlZCByaWdodCBhZnRlciBpbml0aWFsaXphdGlvbi5cclxuICAgICAgICAgICAgICogQHJldHVybnMgeyp9XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBfcGx1Z2luID0gd2luZG93W1BMVUdJTk5BTUVdID0gZnVuY3Rpb24gKHBsdWdpblRhcmdldEVsZW1lbnRzLCBvcHRpb25zLCBleHRlbnNpb25zKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzW0xFWElDT04ubF0gPT09IDApXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcblxyXG4gICAgICAgICAgICAgICAgdmFyIGFyciA9IFtdO1xyXG4gICAgICAgICAgICAgICAgdmFyIG9wdHNJc1BsYWluT2JqID0gRlJBTUVXT1JLLmlzUGxhaW5PYmplY3Qob3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICB2YXIgaW5zdDtcclxuICAgICAgICAgICAgICAgIHZhciByZXN1bHQ7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9wbHVnaW5UYXJnZXRFbGVtZW50cyBpcyBudWxsIG9yIHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICAgaWYgKCFwbHVnaW5UYXJnZXRFbGVtZW50cylcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3B0c0lzUGxhaW5PYmogfHwgIW9wdGlvbnMgPyByZXN1bHQgOiBhcnI7XHJcblxyXG4gICAgICAgICAgICAgICAgLypcclxuICAgICAgICAgICAgICAgICAgIHBsdWdpblRhcmdldEVsZW1lbnRzIHdpbGwgYmUgY29udmVydGVkIHRvOlxyXG4gICAgICAgICAgICAgICAgICAgMS4gQSBqUXVlcnlFbGVtZW50IEFycmF5XHJcbiAgICAgICAgICAgICAgICAgICAyLiBBIEhUTUxFbGVtZW50IEFycmF5XHJcbiAgICAgICAgICAgICAgICAgICAzLiBBIEFycmF5IHdpdGggYSBzaW5nbGUgSFRNTCBFbGVtZW50XHJcbiAgICAgICAgICAgICAgICAgICBzbyBwbHVnaW5UYXJnZXRFbGVtZW50cyBpcyBhbHdheXMgYSBhcnJheS5cclxuICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBwbHVnaW5UYXJnZXRFbGVtZW50cyA9IHBsdWdpblRhcmdldEVsZW1lbnRzW0xFWElDT04ubF0gIT0gdW5kZWZpbmVkID8gcGx1Z2luVGFyZ2V0RWxlbWVudHMgOiBbcGx1Z2luVGFyZ2V0RWxlbWVudHNbMF0gfHwgcGx1Z2luVGFyZ2V0RWxlbWVudHNdO1xyXG4gICAgICAgICAgICAgICAgaW5pdE92ZXJsYXlTY3JvbGxiYXJzU3RhdGljcygpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChwbHVnaW5UYXJnZXRFbGVtZW50c1tMRVhJQ09OLmxdID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRzSXNQbGFpbk9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBGUkFNRVdPUksuZWFjaChwbHVnaW5UYXJnZXRFbGVtZW50cywgZnVuY3Rpb24gKGksIHYpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3QgPSB2O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluc3QgIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChPdmVybGF5U2Nyb2xsYmFyc0luc3RhbmNlKGluc3QsIG9wdGlvbnMsIGV4dGVuc2lvbnMsIF9wbHVnaW5zR2xvYmFscywgX3BsdWdpbnNBdXRvVXBkYXRlTG9vcCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSy5lYWNoKHBsdWdpblRhcmdldEVsZW1lbnRzLCBmdW5jdGlvbiAoaSwgdikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdCA9IElOU1RBTkNFUyh2KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgob3B0aW9ucyA9PT0gJyEnICYmIF9wbHVnaW4udmFsaWQoaW5zdCkpIHx8IChDT01QQVRJQklMSVRZLnR5cGUob3B0aW9ucykgPT0gVFlQRVMuZiAmJiBvcHRpb25zKHYsIGluc3QpKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChpbnN0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChpbnN0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGFycltMRVhJQ09OLmxdID09PSAxID8gYXJyWzBdIDogYXJyO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBSZXR1cm5zIGEgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIGdsb2JhbCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGx1Z2luIGFuZCBlYWNoIGluc3RhbmNlIG9mIGl0LlxyXG4gICAgICAgICAgICAgKiBUaGUgcmV0dXJuZWQgb2JqZWN0IGlzIGp1c3QgYSBjb3B5LCB0aGF0IG1lYW5zIHRoYXQgY2hhbmdlcyB0byB0aGUgcmV0dXJuZWQgb2JqZWN0IHdvbid0IGhhdmUgYW55IGVmZmVjdCB0byB0aGUgb3JpZ2luYWwgb2JqZWN0LlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgX3BsdWdpbi5nbG9iYWxzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaW5pdE92ZXJsYXlTY3JvbGxiYXJzU3RhdGljcygpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGdsb2JhbHMgPSBGUkFNRVdPUksuZXh0ZW5kKHRydWUsIHt9LCBfcGx1Z2luc0dsb2JhbHMpO1xyXG4gICAgICAgICAgICAgICAgZGVsZXRlIGdsb2JhbHNbJ21zaWUnXTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBnbG9iYWxzO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEdldHMgb3IgU2V0cyB0aGUgZGVmYXVsdCBvcHRpb25zIGZvciBlYWNoIG5ldyBwbHVnaW4gaW5pdGlhbGl6YXRpb24uXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBuZXdEZWZhdWx0T3B0aW9ucyBUaGUgb2JqZWN0IHdpdGggd2hpY2ggdGhlIGRlZmF1bHQgb3B0aW9ucyBzaGFsbCBiZSBleHRlbmRlZC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIF9wbHVnaW4uZGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAobmV3RGVmYXVsdE9wdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgIGluaXRPdmVybGF5U2Nyb2xsYmFyc1N0YXRpY3MoKTtcclxuICAgICAgICAgICAgICAgIHZhciBjdXJyRGVmYXVsdE9wdGlvbnMgPSBfcGx1Z2luc0dsb2JhbHMuZGVmYXVsdE9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICBpZiAobmV3RGVmYXVsdE9wdGlvbnMgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB7fSwgY3VyckRlZmF1bHRPcHRpb25zKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL3NldCB0aGUgbmV3IGRlZmF1bHQgb3B0aW9uc1xyXG4gICAgICAgICAgICAgICAgX3BsdWdpbnNHbG9iYWxzLmRlZmF1bHRPcHRpb25zID0gRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB7fSwgY3VyckRlZmF1bHRPcHRpb25zLCBfcGx1Z2luc09wdGlvbnMuX3ZhbGlkYXRlKG5ld0RlZmF1bHRPcHRpb25zLCBfcGx1Z2luc09wdGlvbnMuX3RlbXBsYXRlLCB0cnVlLCBjdXJyRGVmYXVsdE9wdGlvbnMpLl9kZWZhdWx0KTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgcGFzc2VkIGluc3RhbmNlIGlzIGEgbm9uLWRlc3Ryb3llZCBPdmVybGF5U2Nyb2xsYmFycyBpbnN0YW5jZS5cclxuICAgICAgICAgICAgICogQHBhcmFtIG9zSW5zdGFuY2UgVGhlIHBvdGVudGlhbCBPdmVybGF5U2Nyb2xsYmFycyBpbnN0YW5jZSB3aGljaCBzaGFsbCBiZSBjaGVja2VkLlxyXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgcGFzc2VkIHZhbHVlIGlzIGEgbm9uLWRlc3Ryb3llZCBPdmVybGF5U2Nyb2xsYmFycyBpbnN0YW5jZSwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgX3BsdWdpbi52YWxpZCA9IGZ1bmN0aW9uIChvc0luc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gb3NJbnN0YW5jZSBpbnN0YW5jZW9mIF9wbHVnaW4gJiYgIW9zSW5zdGFuY2UuZ2V0U3RhdGUoKS5kZXN0cm95ZWQ7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogUmVnaXN0ZXJzLCBVbnJlZ2lzdGVycyBvciByZXR1cm5zIGEgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAgICAgKiBSZWdpc3RlcjogUGFzcyB0aGUgbmFtZSBhbmQgdGhlIGV4dGVuc2lvbi4gKGRlZmF1bHRPcHRpb25zIGlzIG9wdGlvbmFsKVxyXG4gICAgICAgICAgICAgKiBVbnJlZ2lzdGVyOiBQYXNzIHRoZSBuYW1lIGFuZCBhbnl0aGluZyBleGNlcHQgYSBmdW5jdGlvbiBhcyBleHRlbnNpb24gcGFyYW1ldGVyLlxyXG4gICAgICAgICAgICAgKiBHZXQgZXh0ZW5zaW9uOiBQYXNzIHRoZSBuYW1lIG9mIHRoZSBleHRlbnNpb24gd2hpY2ggc2hhbGwgYmUgZ290LlxyXG4gICAgICAgICAgICAgKiBHZXQgYWxsIGV4dGVuc2lvbnM6IFBhc3Mgbm8gYXJndW1lbnRzLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gZXh0ZW5zaW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHdoaWNoIHNoYWxsIGJlIHJlZ2lzdGVyZWQsIHVucmVnaXN0ZXJlZCBvciByZXR1cm5lZC5cclxuICAgICAgICAgICAgICogQHBhcmFtIGV4dGVuc2lvbiBBIGZ1bmN0aW9uIHdoaWNoIGdlbmVyYXRlcyB0aGUgaW5zdGFuY2Ugb2YgdGhlIGV4dGVuc2lvbiBvciBhbnl0aGluZyBvdGhlciB0byByZW1vdmUgYSBhbHJlYWR5IHJlZ2lzdGVyZWQgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gZGVmYXVsdE9wdGlvbnMgVGhlIGRlZmF1bHQgb3B0aW9ucyB3aGljaCBzaGFsbCBiZSB1c2VkIGZvciB0aGUgcmVnaXN0ZXJlZCBleHRlbnNpb24uXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBfcGx1Z2luLmV4dGVuc2lvbiA9IGZ1bmN0aW9uIChleHRlbnNpb25OYW1lLCBleHRlbnNpb24sIGRlZmF1bHRPcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZXh0TmFtZVR5cGVTdHJpbmcgPSBDT01QQVRJQklMSVRZLnR5cGUoZXh0ZW5zaW9uTmFtZSkgPT0gVFlQRVMucztcclxuICAgICAgICAgICAgICAgIHZhciBhcmdMZW4gPSBhcmd1bWVudHNbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgIGlmIChhcmdMZW4gPCAxIHx8ICFleHROYW1lVHlwZVN0cmluZykge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIGEgY29weSBvZiBhbGwgZXh0ZW5zaW9uIG9iamVjdHNcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB7IGxlbmd0aDogX3BsdWdpbnNFeHRlbnNpb25zW0xFWElDT04ubF0gfSwgX3BsdWdpbnNFeHRlbnNpb25zKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGV4dE5hbWVUeXBlU3RyaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkudHlwZShleHRlbnNpb24pID09IFRZUEVTLmYpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9yZWdpc3RlciBleHRlbnNpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3BsdWdpbnNFeHRlbnNpb25zLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogZXh0ZW5zaW9uTmFtZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbkZhY3Rvcnk6IGV4dGVuc2lvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRPcHRpb25zOiBkZWZhdWx0T3B0aW9uc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgX3BsdWdpbnNFeHRlbnNpb25zW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9wbHVnaW5zRXh0ZW5zaW9uc1tpXS5uYW1lID09PSBleHRlbnNpb25OYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ0xlbiA+IDEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wbHVnaW5zRXh0ZW5zaW9ucy5zcGxpY2UoaSwgMSk7IC8vcmVtb3ZlIGV4dGVuc2lvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZSQU1FV09SSy5leHRlbmQodHJ1ZSwge30sIF9wbHVnaW5zRXh0ZW5zaW9uc1tpXSk7IC8vcmV0dXJuIGV4dGVuc2lvbiB3aXRoIHRoZSBnaXZlbiBuYW1lXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gX3BsdWdpbjtcclxuICAgICAgICB9KSgpO1xyXG5cclxuICAgICAgICBpZiAoSlFVRVJZICYmIEpRVUVSWS5mbikge1xyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVGhlIGpRdWVyeSBpbml0aWFsaXphdGlvbiBpbnRlcmZhY2UuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBvcHRpb25zIFRoZSBpbml0aWFsIG9wdGlvbnMgZm9yIHRoZSBjb25zdHJ1Y3Rpb24gb2YgdGhlIHBsdWdpbi4gVG8gaW5pdGlhbGl6ZSB0aGUgcGx1Z2luLCB0aGlzIG9wdGlvbiBoYXMgdG8gYmUgYSBvYmplY3QhIElmIGl0IGlzbid0IGEgb2JqZWN0LCB0aGUgaW5zdGFuY2UocykgYXJlIHJldHVybmVkIGFuZCB0aGUgcGx1Z2luIHdvbnQgYmUgaW5pdGlhbGl6ZWQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBleHRlbnNpb25zIFRoZSBleHRlbnNpb24ocykgd2hpY2ggc2hhbGwgYmUgYWRkZWQgcmlnaHQgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uXHJcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfSBBZnRlciBpbml0aWFsaXphdGlvbiBpdCByZXR1cm5zIHRoZSBqUXVlcnkgZWxlbWVudCBhcnJheSwgZWxzZSBpdCByZXR1cm5zIHRoZSBpbnN0YW5jZShzKSBvZiB0aGUgZWxlbWVudHMgd2hpY2ggYXJlIHNlbGVjdGVkLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgSlFVRVJZLmZuLm92ZXJsYXlTY3JvbGxiYXJzID0gZnVuY3Rpb24gKG9wdGlvbnMsIGV4dGVuc2lvbnMpIHtcclxuICAgICAgICAgICAgICAgIHZhciBfZWxlbWVudHMgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgaWYgKEpRVUVSWS5pc1BsYWluT2JqZWN0KG9wdGlvbnMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgSlFVRVJZLmVhY2goX2VsZW1lbnRzLCBmdW5jdGlvbiAoKSB7IFBMVUdJTih0aGlzLCBvcHRpb25zLCBleHRlbnNpb25zKTsgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9lbGVtZW50cztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUExVR0lOKF9lbGVtZW50cywgb3B0aW9ucyk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBQTFVHSU47XHJcbiAgICB9XHJcbikpOyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1084\n")}}]);